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
--- 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