diff options
author | Tony Hutter <hutter2@llnl.gov> | 2021-08-27 09:26:49 -0700 |
---|---|---|
committer | Brian Behlendorf <behlendorf1@llnl.gov> | 2021-08-31 10:30:21 -0700 |
commit | 2b7855ae6b7272b4a372c106b528e28d378d7fbd (patch) | |
tree | c055e4d8908f32422117395e4e39b6e98cb3a1e4 | |
parent | 9b418a96b3bda317b190e57c4b92fb5c6894f1f9 (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.c | 36 |
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; |