7870 beadm create fails if a zone has a dataset with a non-legacy mountpoint
authorEvan Layton <Evan.Layton@Sun.COM>
Fri, 26 Mar 2010 10:40:19 -0600
changeset 786 a2ca7710e99e
parent 785 4275d4db607b
child 787 8ceafab5c775
7870 beadm create fails if a zone has a dataset with a non-legacy mountpoint 9949 beadm unmount fails when filesystems shared between BEs are also mounted. 12360 beadm activate hits name collision if renamed BE's original name is reused 14096 be_destroy_zones does not honor forced unmount 14998 beadm create should clean up entries in menu.lst if corresponding BE doesn't exist and the entry can't be reused. 15245 beadm create -p can core dump if there are zones
usr/src/lib/libbe/be_create.c
usr/src/lib/libbe/be_list.c
usr/src/lib/libbe/be_mount.c
usr/src/lib/libbe/be_utils.c
usr/src/lib/libbe/libbe.h
--- a/usr/src/lib/libbe/be_create.c	Fri Mar 26 15:06:46 2010 +0100
+++ b/usr/src/lib/libbe/be_create.c	Fri Mar 26 10:40:19 2010 -0600
@@ -794,45 +794,22 @@
 		}
 	} else {
 		/*
-		 * Else snapshot name was not provided, if we're creating
-		 * an auto named BE, generate an auto named snapshot to
-		 * use as its origin, otherwise just use the new BE name
-		 * as the snapshot name.
+		 * Else snapshot name was not provided, generate an
+		 * auto named snapshot to use as its origin.
 		 */
-		if (autoname) {
-			if ((ret = _be_create_snapshot(bt.obe_name,
-			    &bt.obe_snap_name, bt.policy)) != BE_SUCCESS) {
-				be_print_err(gettext("be_copy: "
-				    "failed to create auto named snapshot\n"));
-				goto done;
-			}
+		if ((ret = _be_create_snapshot(bt.obe_name,
+		    &bt.obe_snap_name, bt.policy)) != BE_SUCCESS) {
+			be_print_err(gettext("be_copy: "
+			    "failed to create auto named snapshot\n"));
+			goto done;
+		}
 
-			if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME,
-			    bt.obe_snap_name) != 0) {
-				be_print_err(gettext("be_copy: "
-				    "failed to add snap name to be_attrs\n"));
-				ret = BE_ERR_NOMEM;
-				goto done;
-			}
-		} else {
-			bt.obe_snap_name = bt.nbe_name;
-
-			/*
-			 * Generate the string for the snapshot to take.
-			 */
-			(void) snprintf(ss, sizeof (ss), "%s@%s",
-			    bt.obe_root_ds, bt.obe_snap_name);
-
-			/*
-			 * Take a recursive snapshot of the original BE.
-			 */
-			if (zfs_snapshot(g_zfs, ss, B_TRUE, NULL)) {
-				be_print_err(gettext("be_copy: "
-				    "failed to snapshot BE (%s): %s\n"),
-				    ss, libzfs_error_description(g_zfs));
-				ret = zfs_err_to_be_err(g_zfs);
-				goto done;
-			}
+		if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME,
+		    bt.obe_snap_name) != 0) {
+			be_print_err(gettext("be_copy: "
+			    "failed to add snap name to be_attrs\n"));
+			ret = BE_ERR_NOMEM;
+			goto done;
 		}
 	}
 
@@ -1531,6 +1508,7 @@
 {
 	int		i;
 	int		ret = BE_SUCCESS;
+	int		force_umnt = BE_UNMOUNT_FLAG_NULL;
 	char		*zonepath = NULL;
 	char		*zonename = NULL;
 	char		*zonepath_ds = NULL;
@@ -1588,7 +1566,9 @@
 	}
 
 	/* Unmount the BE before destroying the zones in it. */
-	if ((ret = _be_unmount(be_name, 0)) != BE_SUCCESS) {
+	if (dd->force_unmount)
+		force_umnt = BE_UNMOUNT_FLAG_FORCE;
+	if ((ret = _be_unmount(be_name, force_umnt)) != BE_SUCCESS) {
 		be_print_err(gettext("be_destroy_zones: failed to "
 		    "unmount the BE (%s)\n"), be_name);
 		goto done;
@@ -2192,11 +2172,32 @@
 {
 	be_transaction_data_t	*bt = data;
 	zfs_handle_t	*zhp_ss = NULL;
+	char		prop_buf[MAXPATHLEN];
 	char		zhp_name[ZFS_MAXNAMELEN];
 	char		clone_ds[MAXPATHLEN];
 	char		ss[MAXPATHLEN];
 	int		ret = 0;
 
+	if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop_buf,
+	    ZFS_MAXPROPLEN, NULL, NULL, 0, B_FALSE) != 0) {
+		be_print_err(gettext("be_clone_fs_callback: "
+		    "failed to get dataset mountpoint (%s): %s\n"),
+		    zfs_get_name(zhp), libzfs_error_description(g_zfs));
+		ret = zfs_err_to_be_err(g_zfs);
+		ZFS_CLOSE(zhp);
+		return (ret);
+	}
+
+	if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) != 0 &&
+	    strcmp(prop_buf, "legacy") != 0) {
+		/*
+		 * Since zfs can't currently handle setting the
+		 * mountpoint for a zoned dataset we'll have to skip
+		 * this dataset. This is because the mountpoint is not
+		 * set to "legacy".
+		 */
+		goto zoned;
+	}
 	/*
 	 * Get a copy of the dataset name from the zfs handle
 	 */
@@ -2245,6 +2246,7 @@
 
 	ZFS_CLOSE(zhp_ss);
 
+zoned:
 	/*
 	 * Iterate through zhp's children datasets (if any)
 	 * and clone them accordingly.
--- a/usr/src/lib/libbe/be_list.c	Fri Mar 26 15:06:46 2010 +0100
+++ b/usr/src/lib/libbe/be_list.c	Fri Mar 26 10:40:19 2010 -0600
@@ -282,8 +282,6 @@
 	be_transaction_data_t bt = { 0 };
 	int ret = BE_SUCCESS;
 
-	zone_be = B_TRUE;
-
 	if (zbe_nodes == NULL)
 		return (BE_ERR_INVAL);
 
@@ -292,13 +290,15 @@
 		return (BE_ERR_BE_NOENT);
 	}
 
+	zone_be = B_TRUE;
+
 	if ((zhp = zfs_open(g_zfs, zone_be_contianer_ds,
 	    ZFS_TYPE_FILESYSTEM)) == NULL) {
-		be_print_err(gettext("be_get_list_callback: failed to open "
+		be_print_err(gettext("be_get_zone_be_list: failed to open "
 		    "the zone BE dataset %s: %s\n"), zone_be_contianer_ds,
 		    libzfs_error_description(g_zfs));
 		ret = zfs_err_to_be_err(g_zfs);
-		return (ret);
+		goto cleanup;
 	}
 
 	strcpy(be_container_ds, zone_be_contianer_ds);
@@ -307,7 +307,7 @@
 		if ((cb.be_nodes_head = be_list_alloc(&ret,
 		    sizeof (be_node_list_t))) == NULL) {
 			ZFS_CLOSE(zhp);
-			return (ret);
+			goto cleanup;
 		}
 		cb.be_nodes = cb.be_nodes_head;
 	}
@@ -317,6 +317,9 @@
 
 	*zbe_nodes = cb.be_nodes_head;
 
+cleanup:
+	zone_be = B_FALSE;
+
 	return (ret);
 }
 
@@ -813,7 +816,7 @@
 		be_node->be_active = B_FALSE;
 
 	be_node->be_rpool = strdup(rpool);
-	if ((err = errno) != 0 || be_node->be_rpool == NULL) {
+	if (be_node->be_rpool == NULL || (err = errno) != 0) {
 		be_print_err(gettext("be_get_node_data: failed to "
 		    "copy root pool name\n"));
 		return (errno_to_be_err(err));
--- a/usr/src/lib/libbe/be_mount.c	Fri Mar 26 15:06:46 2010 +0100
+++ b/usr/src/lib/libbe/be_mount.c	Fri Mar 26 10:40:19 2010 -0600
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1687,6 +1687,8 @@
 	int		altroot_len;
 	int		err = 0;
 
+	errno = 0;
+
 	/* Read in the mnttab into a table */
 	if ((fp = fopen(MNTTAB, "r")) == NULL) {
 		err = errno;
@@ -1733,10 +1735,20 @@
 		    entp->mnt_mountp[altroot_len] == '/') {
 			if (umount(entp->mnt_mountp) != 0) {
 				err = errno;
-				be_print_err(gettext("unmount_shared_fs: "
-				    "failed to unmount shared file system %s: "
-				    "%s\n"), entp->mnt_mountp, strerror(err));
-				return (errno_to_be_err(err));
+				if (err == EBUSY) {
+					sleep(1);
+					err = errno = 0;
+					if (umount(entp->mnt_mountp) != 0)
+						err = errno;
+				}
+				if (err != 0) {
+					be_print_err(gettext(
+					    "unmount_shared_fs: "
+					    "failed to unmount shared file "
+					    "system %s: %s\n"),
+					    entp->mnt_mountp, strerror(err));
+					return (errno_to_be_err(err));
+				}
 			}
 		}
 	}
--- a/usr/src/lib/libbe/be_utils.c	Fri Mar 26 15:06:46 2010 +0100
+++ b/usr/src/lib/libbe/be_utils.c	Fri Mar 26 10:40:19 2010 -0600
@@ -497,11 +497,14 @@
 			ret = BE_SUCCESS;
 			goto cleanup;
 		} else {
-			be_print_err(gettext("be_append_menu: "
-			    "BE entry '%s' already exists in grub menu, "
-			    "skipping ...\n"), be_name);
-			ret = BE_ERR_BE_EXISTS;
-			goto cleanup;
+			if (be_remove_menu(be_name, be_root_pool,
+			    boot_pool) != BE_SUCCESS) {
+				be_print_err(gettext("be_append_menu: "
+				    "Failed to remove existing unusable "
+				    "entry '%s' in boot menu.\n"), be_name);
+				ret = BE_ERR_BE_EXISTS;
+				goto cleanup;
+			}
 		}
 	}
 
--- a/usr/src/lib/libbe/libbe.h	Fri Mar 26 15:06:46 2010 +0100
+++ b/usr/src/lib/libbe/libbe.h	Fri Mar 26 10:40:19 2010 -0600
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -181,9 +181,11 @@
 #define	BE_MOUNT_FLAG_NO_ZONES		0x00000004
 
 /* Flags used with unmounting a BE */
+#define	BE_UNMOUNT_FLAG_NULL		0x00000000
 #define	BE_UNMOUNT_FLAG_FORCE		0x00000001
 
 /* Flags used with destroying a BE */
+#define	BE_DESTROY_FLAG_NULL		0x00000000
 #define	BE_DESTROY_FLAG_SNAPSHOTS	0x00000001
 #define	BE_DESTROY_FLAG_FORCE_UNMOUNT	0x00000002