summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Hutter <hutter2@llnl.gov>2021-08-27 09:26:49 -0700
committerBrian Behlendorf <behlendorf1@llnl.gov>2021-08-31 10:30:21 -0700
commit2b7855ae6b7272b4a372c106b528e28d378d7fbd (patch)
treec055e4d8908f32422117395e4e39b6e98cb3a1e4
parent9b418a96b3bda317b190e57c4b92fb5c6894f1f9 (diff)
Make 'zpool labelclear -f' work on offlined disks
This patch allows you to clear the label on offlined disks in an active pool with `-f`. Previously, labelclear wouldn't let you do that. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com> Signed-off-by: Tony Hutter <hutter2@llnl.gov> Closes #12511
-rw-r--r--cmd/zpool/zpool_main.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index 87cb28ef8..f95aece95 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -1216,6 +1216,26 @@ zpool_do_remove(int argc, char **argv)
}
/*
+ * Return 1 if a vdev is active (being used in a pool)
+ * Return 0 if a vdev is inactive (offlined or faulted, or not in active pool)
+ *
+ * This is useful for checking if a disk in an active pool is offlined or
+ * faulted.
+ */
+static int
+vdev_is_active(char *vdev_path)
+{
+ int fd;
+ fd = open(vdev_path, O_EXCL);
+ if (fd < 0) {
+ return (1); /* cant open O_EXCL - disk is active */
+ }
+
+ close(fd);
+ return (0); /* disk is inactive in the pool */
+}
+
+/*
* zpool labelclear [-f] <vdev>
*
* -f Force clearing the label for the vdevs which are members of
@@ -1324,9 +1344,23 @@ zpool_do_labelclear(int argc, char **argv)
case POOL_STATE_ACTIVE:
case POOL_STATE_SPARE:
case POOL_STATE_L2CACHE:
+ /*
+ * We allow the user to call 'zpool offline -f'
+ * on an offlined disk in an active pool. We can check if
+ * the disk is online by calling vdev_is_active().
+ */
+ if (force && !vdev_is_active(vdev))
+ break;
+
(void) fprintf(stderr, gettext(
- "%s is a member (%s) of pool \"%s\"\n"),
+ "%s is a member (%s) of pool \"%s\""),
vdev, zpool_pool_state_to_name(state), name);
+
+ if (force) {
+ (void) fprintf(stderr, gettext(
+ ". Offline the disk first to clear its label."));
+ }
+ printf("\n");
ret = 1;
goto errout;