mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 19:04:45 +03:00
Add trim support to zpool wait
Manual trims fall into the category of long-running pool activities which people might want to wait synchronously for. This change adds support to 'zpool wait' for waiting for manual trim operations to complete. It also adds a '-w' flag to 'zpool trim' which can be used to turn 'zpool trim' into a synchronous operation. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> Signed-off-by: John Gallagher <john.gallagher@delphix.com> Closes #10071
This commit is contained in:
+34
-9
@@ -395,7 +395,7 @@ get_usage(zpool_help_t idx)
|
||||
case HELP_RESILVER:
|
||||
return (gettext("\tresilver <pool> ...\n"));
|
||||
case HELP_TRIM:
|
||||
return (gettext("\ttrim [-d] [-r <rate>] [-c | -s] <pool> "
|
||||
return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> "
|
||||
"[<device> ...]\n"));
|
||||
case HELP_STATUS:
|
||||
return (gettext("\tstatus [-c [script1,script2,...]] "
|
||||
@@ -6979,6 +6979,7 @@ zpool_do_resilver(int argc, char **argv)
|
||||
* -r <rate> Sets the TRIM rate in bytes (per second). Supports
|
||||
* adding a multiplier suffix such as 'k' or 'm'.
|
||||
* -s Suspend. TRIM can then be restarted with no flags.
|
||||
* -w Wait. Blocks until trimming has completed.
|
||||
*/
|
||||
int
|
||||
zpool_do_trim(int argc, char **argv)
|
||||
@@ -6988,15 +6989,17 @@ zpool_do_trim(int argc, char **argv)
|
||||
{"secure", no_argument, NULL, 'd'},
|
||||
{"rate", required_argument, NULL, 'r'},
|
||||
{"suspend", no_argument, NULL, 's'},
|
||||
{"wait", no_argument, NULL, 'w'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
pool_trim_func_t cmd_type = POOL_TRIM_START;
|
||||
uint64_t rate = 0;
|
||||
boolean_t secure = B_FALSE;
|
||||
boolean_t wait = B_FALSE;
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "cdr:s", long_options, NULL))
|
||||
while ((c = getopt_long(argc, argv, "cdr:sw", long_options, NULL))
|
||||
!= -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
@@ -7037,6 +7040,9 @@ zpool_do_trim(int argc, char **argv)
|
||||
}
|
||||
cmd_type = POOL_TRIM_SUSPEND;
|
||||
break;
|
||||
case 'w':
|
||||
wait = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
if (optopt != 0) {
|
||||
(void) fprintf(stderr,
|
||||
@@ -7059,6 +7065,12 @@ zpool_do_trim(int argc, char **argv)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (wait && (cmd_type != POOL_TRIM_START)) {
|
||||
(void) fprintf(stderr, gettext("-w cannot be used with -c or "
|
||||
"-s\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
char *poolname = argv[0];
|
||||
zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
|
||||
if (zhp == NULL)
|
||||
@@ -7067,6 +7079,7 @@ zpool_do_trim(int argc, char **argv)
|
||||
trimflags_t trim_flags = {
|
||||
.secure = secure,
|
||||
.rate = rate,
|
||||
.wait = wait,
|
||||
};
|
||||
|
||||
nvlist_t *vdevs = fnvlist_alloc();
|
||||
@@ -9466,21 +9479,30 @@ zpool_do_set(int argc, char **argv)
|
||||
|
||||
return (error);
|
||||
}
|
||||
/* Add up the total number of bytes left to initialize across all vdevs */
|
||||
|
||||
/* Add up the total number of bytes left to initialize/trim across all vdevs */
|
||||
static uint64_t
|
||||
vdev_initialize_remaining(nvlist_t *nv)
|
||||
vdev_activity_remaining(nvlist_t *nv, zpool_wait_activity_t activity)
|
||||
{
|
||||
uint64_t bytes_remaining;
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
vdev_stat_t *vs;
|
||||
|
||||
assert(activity == ZPOOL_WAIT_INITIALIZE ||
|
||||
activity == ZPOOL_WAIT_TRIM);
|
||||
|
||||
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
|
||||
(uint64_t **)&vs, &c) == 0);
|
||||
|
||||
if (vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE)
|
||||
if (activity == ZPOOL_WAIT_INITIALIZE &&
|
||||
vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE)
|
||||
bytes_remaining = vs->vs_initialize_bytes_est -
|
||||
vs->vs_initialize_bytes_done;
|
||||
else if (activity == ZPOOL_WAIT_TRIM &&
|
||||
vs->vs_trim_state == VDEV_TRIM_ACTIVE)
|
||||
bytes_remaining = vs->vs_trim_bytes_est -
|
||||
vs->vs_trim_bytes_done;
|
||||
else
|
||||
bytes_remaining = 0;
|
||||
|
||||
@@ -9489,7 +9511,7 @@ vdev_initialize_remaining(nvlist_t *nv)
|
||||
children = 0;
|
||||
|
||||
for (c = 0; c < children; c++)
|
||||
bytes_remaining += vdev_initialize_remaining(child[c]);
|
||||
bytes_remaining += vdev_activity_remaining(child[c], activity);
|
||||
|
||||
return (bytes_remaining);
|
||||
}
|
||||
@@ -9547,7 +9569,7 @@ print_wait_status_row(wait_data_t *wd, zpool_handle_t *zhp, int row)
|
||||
pool_scan_stat_t *pss = NULL;
|
||||
pool_removal_stat_t *prs = NULL;
|
||||
char *headers[] = {"DISCARD", "FREE", "INITIALIZE", "REPLACE",
|
||||
"REMOVE", "RESILVER", "SCRUB"};
|
||||
"REMOVE", "RESILVER", "SCRUB", "TRIM"};
|
||||
int col_widths[ZPOOL_WAIT_NUM_ACTIVITIES];
|
||||
|
||||
/* Calculate the width of each column */
|
||||
@@ -9603,7 +9625,10 @@ print_wait_status_row(wait_data_t *wd, zpool_handle_t *zhp, int row)
|
||||
bytes_rem[ZPOOL_WAIT_RESILVER] = rem;
|
||||
}
|
||||
|
||||
bytes_rem[ZPOOL_WAIT_INITIALIZE] = vdev_initialize_remaining(nvroot);
|
||||
bytes_rem[ZPOOL_WAIT_INITIALIZE] =
|
||||
vdev_activity_remaining(nvroot, ZPOOL_WAIT_INITIALIZE);
|
||||
bytes_rem[ZPOOL_WAIT_TRIM] =
|
||||
vdev_activity_remaining(nvroot, ZPOOL_WAIT_TRIM);
|
||||
|
||||
/*
|
||||
* A replace finishes after resilvering finishes, so the amount of work
|
||||
@@ -9731,7 +9756,7 @@ zpool_do_wait(int argc, char **argv)
|
||||
{
|
||||
static char *col_subopts[] = { "discard", "free",
|
||||
"initialize", "replace", "remove", "resilver",
|
||||
"scrub", NULL };
|
||||
"scrub", "trim", NULL };
|
||||
|
||||
/* Reset activities array */
|
||||
bzero(&wd.wd_enabled, sizeof (wd.wd_enabled));
|
||||
|
||||
Reference in New Issue
Block a user