X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=cmd%2Fzpool%2Fzpool_main.c;h=da9f3e1a337bb8169e116a5d4e4b4653e0d056d9;hb=131cc95ca78b8552c13555d2cded791808008ff3;hp=19f1f28a9ed8eab5d6d917c128c9e281d302ad0c;hpb=51a3ae72d23d89d35a4a67059b39e870d66a2495;p=zfs.git diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 19f1f28..da9f3e1 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -63,6 +63,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 **); @@ -123,6 +124,7 @@ typedef enum { HELP_HISTORY, HELP_IMPORT, HELP_IOSTAT, + HELP_LABELCLEAR, HELP_LIST, HELP_OFFLINE, HELP_ONLINE, @@ -162,6 +164,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 }, @@ -233,6 +237,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")); @@ -642,6 +648,127 @@ zpool_do_remove(int argc, char **argv) } /* + * 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 destroyed 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 [-fnd] [-o property=value] ... * [-O file-system-property=value] ... * [-R root] [-m mountpoint] ...