From 4a283c7f77eb5065e9f03b122bf8ead4f4a1e2be Mon Sep 17 00:00:00 2001 From: Tony Hutter Date: Fri, 19 May 2017 12:30:16 -0700 Subject: Force fault a vdev with 'zpool offline -f' This patch adds a '-f' option to 'zpool offline' to fault a vdev instead of bringing it offline. Unlike the OFFLINE state, the FAULTED state will trigger the FMA code, allowing for things like autoreplace and triggering the slot fault LED. The -f faults persist across imports, unless they were set with the temporary (-t) flag. Both persistent and temporary faults can be cleared with zpool clear. Reviewed-by: Brian Behlendorf Signed-off-by: Tony Hutter Closes #6094 --- cmd/zpool/zpool_main.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'cmd/zpool') diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 6a54c92c3..0d06dcc05 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -326,7 +326,7 @@ get_usage(zpool_help_t idx) return (gettext("\tlist [-gHLpPv] [-o property[,...]] " "[-T d|u] [pool] ... [interval [count]]\n")); case HELP_OFFLINE: - return (gettext("\toffline [-t] ...\n")); + return (gettext("\toffline [-f] [-t] ...\n")); case HELP_ONLINE: return (gettext("\tonline ...\n")); case HELP_REPLACE: @@ -5437,11 +5437,9 @@ zpool_do_online(int argc, char **argv) /* * zpool offline [-ft] ... * - * -f Force the device into the offline state, even if doing - * so would appear to compromise pool availability. - * (not supported yet) + * -f Force the device into a faulted state. * - * -t Only take the device off-line temporarily. The offline + * -t Only take the device off-line temporarily. The offline/faulted * state will not be persistent across reboots. */ /* ARGSUSED */ @@ -5453,14 +5451,17 @@ zpool_do_offline(int argc, char **argv) zpool_handle_t *zhp; int ret = 0; boolean_t istmp = B_FALSE; + boolean_t fault = B_FALSE; /* check options */ while ((c = getopt(argc, argv, "ft")) != -1) { switch (c) { + case 'f': + fault = B_TRUE; + break; case 't': istmp = B_TRUE; break; - case 'f': case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); @@ -5487,8 +5488,22 @@ zpool_do_offline(int argc, char **argv) return (1); for (i = 1; i < argc; i++) { - if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) - ret = 1; + if (fault) { + uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]); + vdev_aux_t aux; + if (istmp == B_FALSE) { + /* Force the fault to persist across imports */ + aux = VDEV_AUX_EXTERNAL_PERSIST; + } else { + aux = VDEV_AUX_EXTERNAL; + } + + if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0) + ret = 1; + } else { + if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) + ret = 1; + } } zpool_close(zhp); -- cgit v1.2.3