From 871adc5a5b4d6cb56c154a6a2f28784bc359d99a Mon Sep 17 00:00:00 2001 From: mm Date: Thu, 5 Jan 2012 10:24:06 +0000 Subject: [PATCH] MFC r224171 (gibbs): Add the "zpool labelclear" command. This command can be used to wipe the label data from a drive that is not active in a pool. The optional "-f" argument can be used to treat an exported or foreign vdev as "inactive" thus allowing its label information to be cleared. git-svn-id: svn://svn.freebsd.org/base/stable/8@229570 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- cddl/contrib/opensolaris/cmd/zpool/zpool.8 | 27 ++++ .../opensolaris/cmd/zpool/zpool_main.c | 125 ++++++++++++++++++ .../lib/libzfs/common/libzfs_import.c | 4 +- 3 files changed, 154 insertions(+), 2 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8 index ff71dff16..c700b7f53 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8 @@ -80,6 +80,11 @@ zpool \- configures ZFS storage pools \fBzpool iostat\fR [\fB-T\fR u | d ] [\fB-v\fR] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]] .fi +.LP +.nf +\fBzpool labelclear\fR [\fB-f\fR] \fIdevice\fR +.fi + .LP .nf \fBzpool list\fR [\fB-H\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fIpool\fR] ... @@ -1201,6 +1206,28 @@ Verbose statistics. Reports usage statistics for individual \fIvdevs\fR within t .RE +.sp +.ne 2 +.mk +.na +\fB\fBzpool labelclear\fR [\fB-f\fR] \fIdevice\fR +.ad +.sp .6 +.RS 4n +Removes ZFS label information from the specified device. The device must not be part of an active pool configuration. +.sp +.ne 2 +.mk +.na +\fB\fB-f\fR\fR +.ad +.RS 12n +.rt +Treat exported or foreign devices as inactive. +.RE + +.RE + .sp .ne 2 .mk diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c index 27dcf4c88..9ac94a7d8 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c @@ -58,6 +58,7 @@ static int zpool_do_destroy(int, char **); static int zpool_do_add(int, char **); static int zpool_do_remove(int, char **); +static int zpool_do_labelclear(int, char **); static int zpool_do_list(int, char **); static int zpool_do_iostat(int, char **); @@ -114,6 +115,7 @@ typedef enum { HELP_HISTORY, HELP_IMPORT, HELP_IOSTAT, + HELP_LABELCLEAR, HELP_LIST, HELP_OFFLINE, HELP_ONLINE, @@ -150,6 +152,8 @@ static zpool_command_t command_table[] = { { "add", zpool_do_add, HELP_ADD }, { "remove", zpool_do_remove, HELP_REMOVE }, { NULL }, + { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, + { NULL }, { "list", zpool_do_list, HELP_LIST }, { "iostat", zpool_do_iostat, HELP_IOSTAT }, { "status", zpool_do_status, HELP_STATUS }, @@ -216,6 +220,8 @@ get_usage(zpool_help_t idx) { case HELP_IOSTAT: return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval " "[count]]\n")); + case HELP_LABELCLEAR: + return (gettext("\tlabelclear [-f] \n")); case HELP_LIST: return (gettext("\tlist [-H] [-o property[,...]] " "[-T d|u] [pool] ... [interval [count]]\n")); @@ -560,6 +566,125 @@ zpool_do_remove(int argc, char **argv) return (ret); } +/* + * zpool labelclear + * + * Verifies that the vdev is not active and zeros out the label information + * on the device. + */ +int +zpool_do_labelclear(int argc, char **argv) +{ + char *vdev, *name; + int c, fd = -1, ret = 0; + pool_state_t state; + boolean_t inuse = B_FALSE; + boolean_t force = B_FALSE; + + /* check options */ + while ((c = getopt(argc, argv, "f")) != -1) { + switch (c) { + case 'f': + force = B_TRUE; + break; + default: + (void) fprintf(stderr, gettext("invalid option '%c'\n"), + optopt); + usage(B_FALSE); + } + } + + argc -= optind; + argv += optind; + + /* get vdev name */ + if (argc < 1) { + (void) fprintf(stderr, gettext("missing vdev device name\n")); + usage(B_FALSE); + } + + vdev = argv[0]; + if ((fd = open(vdev, O_RDWR)) < 0) { + (void) fprintf(stderr, gettext("Unable to open %s\n"), vdev); + return (B_FALSE); + } + + name = NULL; + if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0) { + if (force) + goto wipe_label; + + (void) fprintf(stderr, + gettext("Unable to determine pool state for %s\n" + "Use -f to force the clearing any label data\n"), vdev); + + return (1); + } + + if (inuse) { + switch (state) { + default: + case POOL_STATE_ACTIVE: + case POOL_STATE_SPARE: + case POOL_STATE_L2CACHE: + (void) fprintf(stderr, +gettext("labelclear operation failed.\n" + "\tVdev %s is a member (%s), of pool \"%s\".\n" + "\tTo remove label information from this device, export or destroy\n" + "\tthe pool, or remove %s from the configuration of this pool\n" + "\tand retry the labelclear operation\n"), + vdev, zpool_pool_state_to_name(state), name, vdev); + ret = 1; + goto errout; + + case POOL_STATE_EXPORTED: + if (force) + break; + + (void) fprintf(stderr, +gettext("labelclear operation failed.\n" + "\tVdev %s is a member of the exported pool \"%s\".\n" + "\tUse \"zpool labelclear -f %s\" to force the removal of label\n" + "\tinformation.\n"), + vdev, name, vdev); + ret = 1; + goto errout; + + case POOL_STATE_POTENTIALLY_ACTIVE: + if (force) + break; + + (void) fprintf(stderr, +gettext("labelclear operation failed.\n" + "\tVdev %s is a member of the pool \"%s\".\n" + "\tThis pool is unknown to this system, but may be active on\n" + "\tanother system. Use \'zpool labelclear -f %s\' to force the\n" + "\tremoval of label information.\n"), + vdev, name, vdev); + ret = 1; + goto errout; + + case POOL_STATE_DESTROYED: + /* inuse should never be set for a destoryed pool... */ + break; + } + } + +wipe_label: + if (zpool_clear_label(fd) != 0) { + (void) fprintf(stderr, + gettext("Label clear failed on vdev %s\n"), vdev); + ret = 1; + } + +errout: + close(fd); + if (name != NULL) + free(name); + + return (ret); +} + /* * zpool create [-fn] [-o property=value] ... * [-O file-system-property=value] ... diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index 4c31e56cf..cafb981d1 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -1084,8 +1084,8 @@ zpool_open_func(void *arg) /* * Given a file descriptor, clear (zero) the label information. This function - * is currently only used in the appliance stack as part of the ZFS sysevent - * module. + * is used in the appliance stack as part of the ZFS sysevent module and + * to implement the "zpool labelclear" command. */ int zpool_clear_label(int fd) -- 2.45.0