changeset 13527:4b5bd4534d91

1699 beadm destroy complains "device busy" if hampered by snapshots Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Garrett D'Amore <garrett@nexenta.com> Reviewed by: Gordon Ross <gwr@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Alexander Eremin <a.eremin@nexenta.com>
date Thu, 17 Nov 2011 14:34:33 +0300
parents 5a529e25e724
children d5dc5fc5db60
files usr/src/cmd/beadm/beadm.c usr/src/lib/libbe/common/be_create.c usr/src/man/man1m/beadm.1m
diffstat 3 files changed, 55 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/beadm/beadm.c	Fri Nov 18 18:32:51 2011 -0500
+++ b/usr/src/cmd/beadm/beadm.c	Thu Nov 17 14:34:33 2011 +0300
@@ -1046,6 +1046,11 @@
 		(void) fprintf(stderr, _("You have insufficient privileges to "
 		    "execute this command.\n"));
 		break;
+	case BE_ERR_SS_EXISTS:
+		(void) fprintf(stderr, _("Unable to destroy %s: "
+		    "BE has snapshots.\nUse 'beadm destroy -s %s' or "
+		    "'zfs -r destroy <dataset>'.\n"), be_name, be_name);
+		break;
 	default:
 		(void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
 		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
--- a/usr/src/lib/libbe/common/be_create.c	Fri Nov 18 18:32:51 2011 -0500
+++ b/usr/src/lib/libbe/common/be_create.c	Thu Nov 17 14:34:33 2011 +0300
@@ -65,6 +65,7 @@
 static int be_send_fs_callback(zfs_handle_t *, void *);
 static int be_demote_callback(zfs_handle_t *, void *);
 static int be_demote_find_clone_callback(zfs_handle_t *, void *);
+static int be_has_snapshot_callback(zfs_handle_t *, void *);
 static int be_demote_get_one_clone(zfs_handle_t *, void *);
 static int be_get_snap(char *, char **);
 static int be_prep_clone_send_fs(zfs_handle_t *, be_transaction_data_t *,
@@ -386,6 +387,7 @@
 	be_destroy_data_t	dd = { 0 };
 	int			ret = BE_SUCCESS;
 	uint16_t		flags = 0;
+	boolean_t		bs_found = B_FALSE;
 	int			zret;
 	char			obe_root_ds[MAXPATHLEN];
 	char			*mp = NULL;
@@ -469,6 +471,16 @@
 		return (zfs_err_to_be_err(g_zfs));
 	}
 
+	/*
+	 * Check if BE has snapshots and BE_DESTROY_FLAG_SNAPSHOTS
+	 * is not set.
+	 */
+	(void) zfs_iter_snapshots(zhp, be_has_snapshot_callback, &bs_found);
+	if (!dd.destroy_snaps && bs_found) {
+		ZFS_CLOSE(zhp);
+		return (BE_ERR_SS_EXISTS);
+	}
+
 	/* Get the UUID of the global BE */
 	if (be_get_uuid(zfs_get_name(zhp), &dd.gz_be_uuid) != BE_SUCCESS) {
 		be_print_err(gettext("be_destroy: BE has no UUID (%s)\n"),
@@ -1232,6 +1244,32 @@
 }
 
 /*
+ * Function:	be_has_snapshots_callback
+ * Description:	Callback function used to find out if a BE has snapshots.
+ * Parameters:
+ *		zlp - zpool_handle_t pointer to the current pool being
+ *			looked at.
+ *		data - be_snap_found_t pointer.
+ * Return:
+ *		1 - BE has no snapshots.
+ *		0 - BE has snapshots.
+ * Scope:
+ *		Private
+ */
+static int
+be_has_snapshot_callback(zfs_handle_t *zhp, void *data)
+{
+	boolean_t *bs = data;
+	if (zfs_get_name(zhp) == NULL) {
+		zfs_close(zhp);
+		return (1);
+	}
+	*bs = B_TRUE;
+	zfs_close(zhp);
+	return (0);
+}
+
+/*
  * Function:	be_set_uuid
  * Description:	This function generates a uuid, unparses it into
  *		string representation, and sets that string into
--- a/usr/src/man/man1m/beadm.1m	Fri Nov 18 18:32:51 2011 -0500
+++ b/usr/src/man/man1m/beadm.1m	Thu Nov 17 14:34:33 2011 +0300
@@ -18,7 +18,7 @@
 
 .LP
 .nf
-\fBbeadm\fR \fBdestroy\fR [\fB-fF\fR] \fIbeName\fR | \fIbeName@snapshot\fR
+\fBbeadm\fR \fBdestroy\fR [\fB-fFs\fR] \fIbeName\fR | \fIbeName@snapshot\fR
 .fi
 
 .LP
@@ -254,7 +254,7 @@
 .sp
 .ne 2
 .na
-\fBbeadm\fR \fBdestroy\fR [\fB-fF\fR] \fIbeName\fR | \fIbeName@snapshot\fR
+\fBbeadm\fR \fBdestroy\fR [\fB-fFs\fR] \fIbeName\fR | \fIbeName@snapshot\fR
 .ad
 .sp .6
 .RS 4n
@@ -284,6 +284,16 @@
 Force the action without prompting to verify the destruction of the boot
 environment.
 .RE
+.sp
+.ne 2
+.na
+\fB-s\fR
+.ad
+.sp .6
+.RS 4n
+Destroy all snapshots of the boot
+environment.
+.RE
 .RE
 
 .sp