+ * zpool labelclear <vdev>
+ *
+ * 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);
+}
+
+/*