diff options
Diffstat (limited to 'sys/contrib/openzfs/cmd/zpool/zpool_main.c')
-rw-r--r-- | sys/contrib/openzfs/cmd/zpool/zpool_main.c | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c index 2311d4f046f6..a06af9aeceb4 100644 --- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c +++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c @@ -392,7 +392,7 @@ get_usage(zpool_help_t idx) case HELP_REOPEN: return (gettext("\treopen [-n] <pool>\n")); case HELP_INITIALIZE: - return (gettext("\tinitialize [-c | -s] [-w] <pool> " + return (gettext("\tinitialize [-c | -s | -u] [-w] <pool> " "[<device> ...]\n")); case HELP_SCRUB: return (gettext("\tscrub [-s | -p] [-w] <pool> ...\n")); @@ -548,12 +548,13 @@ usage(boolean_t requested) } /* - * zpool initialize [-c | -s] [-w] <pool> [<vdev> ...] + * zpool initialize [-c | -s | -u] [-w] <pool> [<vdev> ...] * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool * if none specified. * * -c Cancel. Ends active initializing. * -s Suspend. Initializing can then be restarted with no flags. + * -u Uninitialize. Clears initialization state. * -w Wait. Blocks until initializing has completed. */ int @@ -569,12 +570,14 @@ zpool_do_initialize(int argc, char **argv) struct option long_options[] = { {"cancel", no_argument, NULL, 'c'}, {"suspend", no_argument, NULL, 's'}, + {"uninit", no_argument, NULL, 'u'}, {"wait", no_argument, NULL, 'w'}, {0, 0, 0, 0} }; pool_initialize_func_t cmd_type = POOL_INITIALIZE_START; - while ((c = getopt_long(argc, argv, "csw", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "csuw", long_options, + NULL)) != -1) { switch (c) { case 'c': if (cmd_type != POOL_INITIALIZE_START && @@ -594,6 +597,15 @@ zpool_do_initialize(int argc, char **argv) } cmd_type = POOL_INITIALIZE_SUSPEND; break; + case 'u': + if (cmd_type != POOL_INITIALIZE_START && + cmd_type != POOL_INITIALIZE_UNINIT) { + (void) fprintf(stderr, gettext("-u cannot be " + "combined with other options\n")); + usage(B_FALSE); + } + cmd_type = POOL_INITIALIZE_UNINIT; + break; case 'w': wait = B_TRUE; break; @@ -620,8 +632,8 @@ zpool_do_initialize(int argc, char **argv) } if (wait && (cmd_type != POOL_INITIALIZE_START)) { - (void) fprintf(stderr, gettext("-w cannot be used with -c or " - "-s\n")); + (void) fprintf(stderr, gettext("-w cannot be used with -c, -s" + "or -u\n")); usage(B_FALSE); } @@ -6921,6 +6933,17 @@ zpool_do_online(int argc, char **argv) return (1); for (i = 1; i < argc; i++) { + vdev_state_t oldstate; + boolean_t avail_spare, l2cache; + nvlist_t *tgt = zpool_find_vdev(zhp, argv[i], &avail_spare, + &l2cache, NULL); + if (tgt == NULL) { + ret = 1; + continue; + } + uint_t vsc; + oldstate = ((vdev_stat_t *)fnvlist_lookup_uint64_array(tgt, + ZPOOL_CONFIG_VDEV_STATS, &vsc))->vs_state; if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { if (newstate != VDEV_STATE_HEALTHY) { (void) printf(gettext("warning: device '%s' " @@ -6934,6 +6957,17 @@ zpool_do_online(int argc, char **argv) (void) printf(gettext("use 'zpool " "replace' to replace devices " "that are no longer present\n")); + if ((flags & ZFS_ONLINE_EXPAND)) { + (void) printf(gettext("%s: failed " + "to expand usable space on " + "unhealthy device '%s'\n"), + (oldstate >= VDEV_STATE_DEGRADED ? + "error" : "warning"), argv[i]); + if (oldstate >= VDEV_STATE_DEGRADED) { + ret = 1; + break; + } + } } } else { ret = 1; @@ -7549,19 +7583,20 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf)); - assert(ps->pss_func == POOL_SCAN_SCRUB || - ps->pss_func == POOL_SCAN_RESILVER); + int is_resilver = ps->pss_func == POOL_SCAN_RESILVER; + int is_scrub = ps->pss_func == POOL_SCAN_SCRUB; + assert(is_resilver || is_scrub); /* Scan is finished or canceled. */ if (ps->pss_state == DSS_FINISHED) { secs_to_dhms(end - start, time_buf); - if (ps->pss_func == POOL_SCAN_SCRUB) { + if (is_scrub) { (void) printf(gettext("scrub repaired %s " "in %s with %llu errors on %s"), processed_buf, time_buf, (u_longlong_t)ps->pss_errors, ctime(&end)); - } else if (ps->pss_func == POOL_SCAN_RESILVER) { + } else if (is_resilver) { (void) printf(gettext("resilvered %s " "in %s with %llu errors on %s"), processed_buf, time_buf, (u_longlong_t)ps->pss_errors, @@ -7569,10 +7604,10 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) } return; } else if (ps->pss_state == DSS_CANCELED) { - if (ps->pss_func == POOL_SCAN_SCRUB) { + if (is_scrub) { (void) printf(gettext("scrub canceled on %s"), ctime(&end)); - } else if (ps->pss_func == POOL_SCAN_RESILVER) { + } else if (is_resilver) { (void) printf(gettext("resilver canceled on %s"), ctime(&end)); } @@ -7582,7 +7617,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) assert(ps->pss_state == DSS_SCANNING); /* Scan is in progress. Resilvers can't be paused. */ - if (ps->pss_func == POOL_SCAN_SCRUB) { + if (is_scrub) { if (pause == 0) { (void) printf(gettext("scrub in progress since %s"), ctime(&start)); @@ -7592,7 +7627,7 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) (void) printf(gettext("\tscrub started on %s"), ctime(&start)); } - } else if (ps->pss_func == POOL_SCAN_RESILVER) { + } else if (is_resilver) { (void) printf(gettext("resilver in progress since %s"), ctime(&start)); } @@ -7634,17 +7669,27 @@ print_scan_scrub_resilver_status(pool_scan_stat_t *ps) scanned_buf, issued_buf, total_buf); } - if (ps->pss_func == POOL_SCAN_RESILVER) { + if (is_resilver) { (void) printf(gettext("\t%s resilvered, %.2f%% done"), processed_buf, 100 * fraction_done); - } else if (ps->pss_func == POOL_SCAN_SCRUB) { + } else if (is_scrub) { (void) printf(gettext("\t%s repaired, %.2f%% done"), processed_buf, 100 * fraction_done); } if (pause == 0) { + /* + * Only provide an estimate iff: + * 1) the time remaining is valid, and + * 2) the issue rate exceeds 10 MB/s, and + * 3) it's either: + * a) a resilver which has started repairs, or + * b) a scrub which has entered the issue phase. + */ if (total_secs_left != UINT64_MAX && - issue_rate >= 10 * 1024 * 1024) { + issue_rate >= 10 * 1024 * 1024 && + ((is_resilver && ps->pss_processed > 0) || + (is_scrub && issued > 0))) { (void) printf(gettext(", %s to go\n"), time_buf); } else { (void) printf(gettext(", no estimated " |