]> git.proxmox.com Git - mirror_zfs.git/blob - cmd/zpool/zpool_main.c
Restore identification of VDEVs using non-native block size
[mirror_zfs.git] / cmd / zpool / zpool_main.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
26 * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
27 * Copyright (c) 2012 by Cyril Plisko. All rights reserved.
28 * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
29 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
30 * Copyright (c) 2017 Datto Inc.
31 * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
32 * Copyright (c) 2017, Intel Corporation.
33 * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
34 */
35
36 #include <assert.h>
37 #include <ctype.h>
38 #include <dirent.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <getopt.h>
42 #include <libgen.h>
43 #include <libintl.h>
44 #include <libuutil.h>
45 #include <locale.h>
46 #include <pthread.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <strings.h>
51 #include <time.h>
52 #include <unistd.h>
53 #include <pwd.h>
54 #include <zone.h>
55 #include <sys/wait.h>
56 #include <zfs_prop.h>
57 #include <sys/fs/zfs.h>
58 #include <sys/stat.h>
59 #include <sys/systeminfo.h>
60 #include <sys/fm/fs/zfs.h>
61 #include <sys/fm/util.h>
62 #include <sys/fm/protocol.h>
63 #include <sys/zfs_ioctl.h>
64 #include <sys/mount.h>
65 #include <sys/sysmacros.h>
66
67 #include <math.h>
68
69 #include <libzfs.h>
70 #include <libzutil.h>
71
72 #include "zpool_util.h"
73 #include "zfs_comutil.h"
74 #include "zfeature_common.h"
75
76 #include "statcommon.h"
77
78 libzfs_handle_t *g_zfs;
79
80 static int zpool_do_create(int, char **);
81 static int zpool_do_destroy(int, char **);
82
83 static int zpool_do_add(int, char **);
84 static int zpool_do_remove(int, char **);
85 static int zpool_do_labelclear(int, char **);
86
87 static int zpool_do_checkpoint(int, char **);
88
89 static int zpool_do_list(int, char **);
90 static int zpool_do_iostat(int, char **);
91 static int zpool_do_status(int, char **);
92
93 static int zpool_do_online(int, char **);
94 static int zpool_do_offline(int, char **);
95 static int zpool_do_clear(int, char **);
96 static int zpool_do_reopen(int, char **);
97
98 static int zpool_do_reguid(int, char **);
99
100 static int zpool_do_attach(int, char **);
101 static int zpool_do_detach(int, char **);
102 static int zpool_do_replace(int, char **);
103 static int zpool_do_split(int, char **);
104
105 static int zpool_do_initialize(int, char **);
106 static int zpool_do_scrub(int, char **);
107 static int zpool_do_resilver(int, char **);
108 static int zpool_do_trim(int, char **);
109
110 static int zpool_do_import(int, char **);
111 static int zpool_do_export(int, char **);
112
113 static int zpool_do_upgrade(int, char **);
114
115 static int zpool_do_history(int, char **);
116 static int zpool_do_events(int, char **);
117
118 static int zpool_do_get(int, char **);
119 static int zpool_do_set(int, char **);
120
121 static int zpool_do_sync(int, char **);
122
123 static int zpool_do_version(int, char **);
124
125 static int zpool_do_wait(int, char **);
126
127 /*
128 * These libumem hooks provide a reasonable set of defaults for the allocator's
129 * debugging facilities.
130 */
131
132 #ifdef DEBUG
133 const char *
134 _umem_debug_init(void)
135 {
136 return ("default,verbose"); /* $UMEM_DEBUG setting */
137 }
138
139 const char *
140 _umem_logging_init(void)
141 {
142 return ("fail,contents"); /* $UMEM_LOGGING setting */
143 }
144 #endif
145
146 typedef enum {
147 HELP_ADD,
148 HELP_ATTACH,
149 HELP_CLEAR,
150 HELP_CREATE,
151 HELP_CHECKPOINT,
152 HELP_DESTROY,
153 HELP_DETACH,
154 HELP_EXPORT,
155 HELP_HISTORY,
156 HELP_IMPORT,
157 HELP_IOSTAT,
158 HELP_LABELCLEAR,
159 HELP_LIST,
160 HELP_OFFLINE,
161 HELP_ONLINE,
162 HELP_REPLACE,
163 HELP_REMOVE,
164 HELP_INITIALIZE,
165 HELP_SCRUB,
166 HELP_RESILVER,
167 HELP_TRIM,
168 HELP_STATUS,
169 HELP_UPGRADE,
170 HELP_EVENTS,
171 HELP_GET,
172 HELP_SET,
173 HELP_SPLIT,
174 HELP_SYNC,
175 HELP_REGUID,
176 HELP_REOPEN,
177 HELP_VERSION,
178 HELP_WAIT
179 } zpool_help_t;
180
181
182 /*
183 * Flags for stats to display with "zpool iostats"
184 */
185 enum iostat_type {
186 IOS_DEFAULT = 0,
187 IOS_LATENCY = 1,
188 IOS_QUEUES = 2,
189 IOS_L_HISTO = 3,
190 IOS_RQ_HISTO = 4,
191 IOS_COUNT, /* always last element */
192 };
193
194 /* iostat_type entries as bitmasks */
195 #define IOS_DEFAULT_M (1ULL << IOS_DEFAULT)
196 #define IOS_LATENCY_M (1ULL << IOS_LATENCY)
197 #define IOS_QUEUES_M (1ULL << IOS_QUEUES)
198 #define IOS_L_HISTO_M (1ULL << IOS_L_HISTO)
199 #define IOS_RQ_HISTO_M (1ULL << IOS_RQ_HISTO)
200
201 /* Mask of all the histo bits */
202 #define IOS_ANYHISTO_M (IOS_L_HISTO_M | IOS_RQ_HISTO_M)
203
204 /*
205 * Lookup table for iostat flags to nvlist names. Basically a list
206 * of all the nvlists a flag requires. Also specifies the order in
207 * which data gets printed in zpool iostat.
208 */
209 static const char *vsx_type_to_nvlist[IOS_COUNT][13] = {
210 [IOS_L_HISTO] = {
211 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
212 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
213 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
214 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
215 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
216 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
217 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
218 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
219 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
220 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
221 NULL},
222 [IOS_LATENCY] = {
223 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
224 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
225 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
226 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
227 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
228 NULL},
229 [IOS_QUEUES] = {
230 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
231 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
232 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
233 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
234 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
235 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE,
236 NULL},
237 [IOS_RQ_HISTO] = {
238 ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO,
239 ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO,
240 ZPOOL_CONFIG_VDEV_SYNC_IND_W_HISTO,
241 ZPOOL_CONFIG_VDEV_SYNC_AGG_W_HISTO,
242 ZPOOL_CONFIG_VDEV_ASYNC_IND_R_HISTO,
243 ZPOOL_CONFIG_VDEV_ASYNC_AGG_R_HISTO,
244 ZPOOL_CONFIG_VDEV_ASYNC_IND_W_HISTO,
245 ZPOOL_CONFIG_VDEV_ASYNC_AGG_W_HISTO,
246 ZPOOL_CONFIG_VDEV_IND_SCRUB_HISTO,
247 ZPOOL_CONFIG_VDEV_AGG_SCRUB_HISTO,
248 ZPOOL_CONFIG_VDEV_IND_TRIM_HISTO,
249 ZPOOL_CONFIG_VDEV_AGG_TRIM_HISTO,
250 NULL},
251 };
252
253
254 /*
255 * Given a cb->cb_flags with a histogram bit set, return the iostat_type.
256 * Right now, only one histo bit is ever set at one time, so we can
257 * just do a highbit64(a)
258 */
259 #define IOS_HISTO_IDX(a) (highbit64(a & IOS_ANYHISTO_M) - 1)
260
261 typedef struct zpool_command {
262 const char *name;
263 int (*func)(int, char **);
264 zpool_help_t usage;
265 } zpool_command_t;
266
267 /*
268 * Master command table. Each ZFS command has a name, associated function, and
269 * usage message. The usage messages need to be internationalized, so we have
270 * to have a function to return the usage message based on a command index.
271 *
272 * These commands are organized according to how they are displayed in the usage
273 * message. An empty command (one with a NULL name) indicates an empty line in
274 * the generic usage message.
275 */
276 static zpool_command_t command_table[] = {
277 { "version", zpool_do_version, HELP_VERSION },
278 { NULL },
279 { "create", zpool_do_create, HELP_CREATE },
280 { "destroy", zpool_do_destroy, HELP_DESTROY },
281 { NULL },
282 { "add", zpool_do_add, HELP_ADD },
283 { "remove", zpool_do_remove, HELP_REMOVE },
284 { NULL },
285 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR },
286 { NULL },
287 { "checkpoint", zpool_do_checkpoint, HELP_CHECKPOINT },
288 { NULL },
289 { "list", zpool_do_list, HELP_LIST },
290 { "iostat", zpool_do_iostat, HELP_IOSTAT },
291 { "status", zpool_do_status, HELP_STATUS },
292 { NULL },
293 { "online", zpool_do_online, HELP_ONLINE },
294 { "offline", zpool_do_offline, HELP_OFFLINE },
295 { "clear", zpool_do_clear, HELP_CLEAR },
296 { "reopen", zpool_do_reopen, HELP_REOPEN },
297 { NULL },
298 { "attach", zpool_do_attach, HELP_ATTACH },
299 { "detach", zpool_do_detach, HELP_DETACH },
300 { "replace", zpool_do_replace, HELP_REPLACE },
301 { "split", zpool_do_split, HELP_SPLIT },
302 { NULL },
303 { "initialize", zpool_do_initialize, HELP_INITIALIZE },
304 { "resilver", zpool_do_resilver, HELP_RESILVER },
305 { "scrub", zpool_do_scrub, HELP_SCRUB },
306 { "trim", zpool_do_trim, HELP_TRIM },
307 { NULL },
308 { "import", zpool_do_import, HELP_IMPORT },
309 { "export", zpool_do_export, HELP_EXPORT },
310 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
311 { "reguid", zpool_do_reguid, HELP_REGUID },
312 { NULL },
313 { "history", zpool_do_history, HELP_HISTORY },
314 { "events", zpool_do_events, HELP_EVENTS },
315 { NULL },
316 { "get", zpool_do_get, HELP_GET },
317 { "set", zpool_do_set, HELP_SET },
318 { "sync", zpool_do_sync, HELP_SYNC },
319 { NULL },
320 { "wait", zpool_do_wait, HELP_WAIT },
321 };
322
323 #define NCOMMAND (ARRAY_SIZE(command_table))
324
325 #define VDEV_ALLOC_CLASS_LOGS "logs"
326
327 static zpool_command_t *current_command;
328 static char history_str[HIS_MAX_RECORD_LEN];
329 static boolean_t log_history = B_TRUE;
330 static uint_t timestamp_fmt = NODATE;
331
332 static const char *
333 get_usage(zpool_help_t idx)
334 {
335 switch (idx) {
336 case HELP_ADD:
337 return (gettext("\tadd [-fgLnP] [-o property=value] "
338 "<pool> <vdev> ...\n"));
339 case HELP_ATTACH:
340 return (gettext("\tattach [-fsw] [-o property=value] "
341 "<pool> <device> <new-device>\n"));
342 case HELP_CLEAR:
343 return (gettext("\tclear [-nF] <pool> [device]\n"));
344 case HELP_CREATE:
345 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
346 "\t [-O file-system-property=value] ... \n"
347 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
348 case HELP_CHECKPOINT:
349 return (gettext("\tcheckpoint [-d [-w]] <pool> ...\n"));
350 case HELP_DESTROY:
351 return (gettext("\tdestroy [-f] <pool>\n"));
352 case HELP_DETACH:
353 return (gettext("\tdetach <pool> <device>\n"));
354 case HELP_EXPORT:
355 return (gettext("\texport [-af] <pool> ...\n"));
356 case HELP_HISTORY:
357 return (gettext("\thistory [-il] [<pool>] ...\n"));
358 case HELP_IMPORT:
359 return (gettext("\timport [-d dir] [-D]\n"
360 "\timport [-o mntopts] [-o property=value] ... \n"
361 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
362 "[-R root] [-F [-n]] -a\n"
363 "\timport [-o mntopts] [-o property=value] ... \n"
364 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
365 "[-R root] [-F [-n]]\n"
366 "\t [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
367 case HELP_IOSTAT:
368 return (gettext("\tiostat [[[-c [script1,script2,...]"
369 "[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
370 "\t [[pool ...]|[pool vdev ...]|[vdev ...]]"
371 " [[-n] interval [count]]\n"));
372 case HELP_LABELCLEAR:
373 return (gettext("\tlabelclear [-f] <vdev>\n"));
374 case HELP_LIST:
375 return (gettext("\tlist [-gHLpPv] [-o property[,...]] "
376 "[-T d|u] [pool] ... \n"
377 "\t [interval [count]]\n"));
378 case HELP_OFFLINE:
379 return (gettext("\toffline [-f] [-t] <pool> <device> ...\n"));
380 case HELP_ONLINE:
381 return (gettext("\tonline [-e] <pool> <device> ...\n"));
382 case HELP_REPLACE:
383 return (gettext("\treplace [-fsw] [-o property=value] "
384 "<pool> <device> [new-device]\n"));
385 case HELP_REMOVE:
386 return (gettext("\tremove [-npsw] <pool> <device> ...\n"));
387 case HELP_REOPEN:
388 return (gettext("\treopen [-n] <pool>\n"));
389 case HELP_INITIALIZE:
390 return (gettext("\tinitialize [-c | -s] [-w] <pool> "
391 "[<device> ...]\n"));
392 case HELP_SCRUB:
393 return (gettext("\tscrub [-s | -p] [-w] <pool> ...\n"));
394 case HELP_RESILVER:
395 return (gettext("\tresilver <pool> ...\n"));
396 case HELP_TRIM:
397 return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> "
398 "[<device> ...]\n"));
399 case HELP_STATUS:
400 return (gettext("\tstatus [-c [script1,script2,...]] "
401 "[-igLpPstvxD] [-T d|u] [pool] ... \n"
402 "\t [interval [count]]\n"));
403 case HELP_UPGRADE:
404 return (gettext("\tupgrade\n"
405 "\tupgrade -v\n"
406 "\tupgrade [-V version] <-a | pool ...>\n"));
407 case HELP_EVENTS:
408 return (gettext("\tevents [-vHf [pool] | -c]\n"));
409 case HELP_GET:
410 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
411 "<\"all\" | property[,...]> <pool> ...\n"));
412 case HELP_SET:
413 return (gettext("\tset <property=value> <pool> \n"));
414 case HELP_SPLIT:
415 return (gettext("\tsplit [-gLnPl] [-R altroot] [-o mntopts]\n"
416 "\t [-o property=value] <pool> <newpool> "
417 "[<device> ...]\n"));
418 case HELP_REGUID:
419 return (gettext("\treguid <pool>\n"));
420 case HELP_SYNC:
421 return (gettext("\tsync [pool] ...\n"));
422 case HELP_VERSION:
423 return (gettext("\tversion\n"));
424 case HELP_WAIT:
425 return (gettext("\twait [-Hp] [-T d|u] [-t <activity>[,...]] "
426 "<pool> [interval]\n"));
427 }
428
429 abort();
430 /* NOTREACHED */
431 }
432
433 static void
434 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
435 {
436 uint_t children = 0;
437 nvlist_t **child;
438 uint_t i;
439
440 (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
441 &child, &children);
442
443 if (children == 0) {
444 char *path = zpool_vdev_name(g_zfs, zhp, nvroot,
445 VDEV_NAME_PATH);
446
447 if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
448 strcmp(path, VDEV_TYPE_HOLE) != 0)
449 fnvlist_add_boolean(res, path);
450
451 free(path);
452 return;
453 }
454
455 for (i = 0; i < children; i++) {
456 zpool_collect_leaves(zhp, child[i], res);
457 }
458 }
459
460 /*
461 * Callback routine that will print out a pool property value.
462 */
463 static int
464 print_prop_cb(int prop, void *cb)
465 {
466 FILE *fp = cb;
467
468 (void) fprintf(fp, "\t%-19s ", zpool_prop_to_name(prop));
469
470 if (zpool_prop_readonly(prop))
471 (void) fprintf(fp, " NO ");
472 else
473 (void) fprintf(fp, " YES ");
474
475 if (zpool_prop_values(prop) == NULL)
476 (void) fprintf(fp, "-\n");
477 else
478 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
479
480 return (ZPROP_CONT);
481 }
482
483 /*
484 * Display usage message. If we're inside a command, display only the usage for
485 * that command. Otherwise, iterate over the entire command table and display
486 * a complete usage message.
487 */
488 static void
489 usage(boolean_t requested)
490 {
491 FILE *fp = requested ? stdout : stderr;
492
493 if (current_command == NULL) {
494 int i;
495
496 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
497 (void) fprintf(fp,
498 gettext("where 'command' is one of the following:\n\n"));
499
500 for (i = 0; i < NCOMMAND; i++) {
501 if (command_table[i].name == NULL)
502 (void) fprintf(fp, "\n");
503 else
504 (void) fprintf(fp, "%s",
505 get_usage(command_table[i].usage));
506 }
507 } else {
508 (void) fprintf(fp, gettext("usage:\n"));
509 (void) fprintf(fp, "%s", get_usage(current_command->usage));
510 }
511
512 if (current_command != NULL &&
513 ((strcmp(current_command->name, "set") == 0) ||
514 (strcmp(current_command->name, "get") == 0) ||
515 (strcmp(current_command->name, "list") == 0))) {
516
517 (void) fprintf(fp,
518 gettext("\nthe following properties are supported:\n"));
519
520 (void) fprintf(fp, "\n\t%-19s %s %s\n\n",
521 "PROPERTY", "EDIT", "VALUES");
522
523 /* Iterate over all properties */
524 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
525 ZFS_TYPE_POOL);
526
527 (void) fprintf(fp, "\t%-19s ", "feature@...");
528 (void) fprintf(fp, "YES disabled | enabled | active\n");
529
530 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
531 "appended with a feature name.\nSee zpool-features(5).\n"));
532 }
533
534 /*
535 * See comments at end of main().
536 */
537 if (getenv("ZFS_ABORT") != NULL) {
538 (void) printf("dumping core by request\n");
539 abort();
540 }
541
542 exit(requested ? 0 : 2);
543 }
544
545 /*
546 * zpool initialize [-c | -s] [-w] <pool> [<vdev> ...]
547 * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
548 * if none specified.
549 *
550 * -c Cancel. Ends active initializing.
551 * -s Suspend. Initializing can then be restarted with no flags.
552 * -w Wait. Blocks until initializing has completed.
553 */
554 int
555 zpool_do_initialize(int argc, char **argv)
556 {
557 int c;
558 char *poolname;
559 zpool_handle_t *zhp;
560 nvlist_t *vdevs;
561 int err = 0;
562 boolean_t wait = B_FALSE;
563
564 struct option long_options[] = {
565 {"cancel", no_argument, NULL, 'c'},
566 {"suspend", no_argument, NULL, 's'},
567 {"wait", no_argument, NULL, 'w'},
568 {0, 0, 0, 0}
569 };
570
571 pool_initialize_func_t cmd_type = POOL_INITIALIZE_START;
572 while ((c = getopt_long(argc, argv, "csw", long_options, NULL)) != -1) {
573 switch (c) {
574 case 'c':
575 if (cmd_type != POOL_INITIALIZE_START &&
576 cmd_type != POOL_INITIALIZE_CANCEL) {
577 (void) fprintf(stderr, gettext("-c cannot be "
578 "combined with other options\n"));
579 usage(B_FALSE);
580 }
581 cmd_type = POOL_INITIALIZE_CANCEL;
582 break;
583 case 's':
584 if (cmd_type != POOL_INITIALIZE_START &&
585 cmd_type != POOL_INITIALIZE_SUSPEND) {
586 (void) fprintf(stderr, gettext("-s cannot be "
587 "combined with other options\n"));
588 usage(B_FALSE);
589 }
590 cmd_type = POOL_INITIALIZE_SUSPEND;
591 break;
592 case 'w':
593 wait = B_TRUE;
594 break;
595 case '?':
596 if (optopt != 0) {
597 (void) fprintf(stderr,
598 gettext("invalid option '%c'\n"), optopt);
599 } else {
600 (void) fprintf(stderr,
601 gettext("invalid option '%s'\n"),
602 argv[optind - 1]);
603 }
604 usage(B_FALSE);
605 }
606 }
607
608 argc -= optind;
609 argv += optind;
610
611 if (argc < 1) {
612 (void) fprintf(stderr, gettext("missing pool name argument\n"));
613 usage(B_FALSE);
614 return (-1);
615 }
616
617 if (wait && (cmd_type != POOL_INITIALIZE_START)) {
618 (void) fprintf(stderr, gettext("-w cannot be used with -c or "
619 "-s\n"));
620 usage(B_FALSE);
621 }
622
623 poolname = argv[0];
624 zhp = zpool_open(g_zfs, poolname);
625 if (zhp == NULL)
626 return (-1);
627
628 vdevs = fnvlist_alloc();
629 if (argc == 1) {
630 /* no individual leaf vdevs specified, so add them all */
631 nvlist_t *config = zpool_get_config(zhp, NULL);
632 nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
633 ZPOOL_CONFIG_VDEV_TREE);
634 zpool_collect_leaves(zhp, nvroot, vdevs);
635 } else {
636 for (int i = 1; i < argc; i++) {
637 fnvlist_add_boolean(vdevs, argv[i]);
638 }
639 }
640
641 if (wait)
642 err = zpool_initialize_wait(zhp, cmd_type, vdevs);
643 else
644 err = zpool_initialize(zhp, cmd_type, vdevs);
645
646 fnvlist_free(vdevs);
647 zpool_close(zhp);
648
649 return (err);
650 }
651
652 /*
653 * print a pool vdev config for dry runs
654 */
655 static void
656 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
657 const char *match, int name_flags)
658 {
659 nvlist_t **child;
660 uint_t c, children;
661 char *vname;
662 boolean_t printed = B_FALSE;
663
664 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
665 &child, &children) != 0) {
666 if (name != NULL)
667 (void) printf("\t%*s%s\n", indent, "", name);
668 return;
669 }
670
671 for (c = 0; c < children; c++) {
672 uint64_t is_log = B_FALSE;
673 char *class = "";
674
675 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
676 &is_log);
677 if (is_log)
678 class = VDEV_ALLOC_BIAS_LOG;
679 (void) nvlist_lookup_string(child[c],
680 ZPOOL_CONFIG_ALLOCATION_BIAS, &class);
681 if (strcmp(match, class) != 0)
682 continue;
683
684 if (!printed && name != NULL) {
685 (void) printf("\t%*s%s\n", indent, "", name);
686 printed = B_TRUE;
687 }
688 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
689 print_vdev_tree(zhp, vname, child[c], indent + 2, "",
690 name_flags);
691 free(vname);
692 }
693 }
694
695 static boolean_t
696 prop_list_contains_feature(nvlist_t *proplist)
697 {
698 nvpair_t *nvp;
699 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
700 nvp = nvlist_next_nvpair(proplist, nvp)) {
701 if (zpool_prop_feature(nvpair_name(nvp)))
702 return (B_TRUE);
703 }
704 return (B_FALSE);
705 }
706
707 /*
708 * Add a property pair (name, string-value) into a property nvlist.
709 */
710 static int
711 add_prop_list(const char *propname, char *propval, nvlist_t **props,
712 boolean_t poolprop)
713 {
714 zpool_prop_t prop = ZPOOL_PROP_INVAL;
715 nvlist_t *proplist;
716 const char *normnm;
717 char *strval;
718
719 if (*props == NULL &&
720 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
721 (void) fprintf(stderr,
722 gettext("internal error: out of memory\n"));
723 return (1);
724 }
725
726 proplist = *props;
727
728 if (poolprop) {
729 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
730
731 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL &&
732 !zpool_prop_feature(propname)) {
733 (void) fprintf(stderr, gettext("property '%s' is "
734 "not a valid pool property\n"), propname);
735 return (2);
736 }
737
738 /*
739 * feature@ properties and version should not be specified
740 * at the same time.
741 */
742 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) &&
743 nvlist_exists(proplist, vname)) ||
744 (prop == ZPOOL_PROP_VERSION &&
745 prop_list_contains_feature(proplist))) {
746 (void) fprintf(stderr, gettext("'feature@' and "
747 "'version' properties cannot be specified "
748 "together\n"));
749 return (2);
750 }
751
752
753 if (zpool_prop_feature(propname))
754 normnm = propname;
755 else
756 normnm = zpool_prop_to_name(prop);
757 } else {
758 zfs_prop_t fsprop = zfs_name_to_prop(propname);
759
760 if (zfs_prop_valid_for_type(fsprop, ZFS_TYPE_FILESYSTEM,
761 B_FALSE)) {
762 normnm = zfs_prop_to_name(fsprop);
763 } else if (zfs_prop_user(propname) ||
764 zfs_prop_userquota(propname)) {
765 normnm = propname;
766 } else {
767 (void) fprintf(stderr, gettext("property '%s' is "
768 "not a valid filesystem property\n"), propname);
769 return (2);
770 }
771 }
772
773 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
774 prop != ZPOOL_PROP_CACHEFILE) {
775 (void) fprintf(stderr, gettext("property '%s' "
776 "specified multiple times\n"), propname);
777 return (2);
778 }
779
780 if (nvlist_add_string(proplist, normnm, propval) != 0) {
781 (void) fprintf(stderr, gettext("internal "
782 "error: out of memory\n"));
783 return (1);
784 }
785
786 return (0);
787 }
788
789 /*
790 * Set a default property pair (name, string-value) in a property nvlist
791 */
792 static int
793 add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
794 boolean_t poolprop)
795 {
796 char *pval;
797
798 if (nvlist_lookup_string(*props, propname, &pval) == 0)
799 return (0);
800
801 return (add_prop_list(propname, propval, props, B_TRUE));
802 }
803
804 /*
805 * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
806 *
807 * -f Force addition of devices, even if they appear in use
808 * -g Display guid for individual vdev name.
809 * -L Follow links when resolving vdev path name.
810 * -n Do not add the devices, but display the resulting layout if
811 * they were to be added.
812 * -o Set property=value.
813 * -P Display full path for vdev name.
814 *
815 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
816 * handled by make_root_vdev(), which constructs the nvlist needed to pass to
817 * libzfs.
818 */
819 int
820 zpool_do_add(int argc, char **argv)
821 {
822 boolean_t force = B_FALSE;
823 boolean_t dryrun = B_FALSE;
824 int name_flags = 0;
825 int c;
826 nvlist_t *nvroot;
827 char *poolname;
828 int ret;
829 zpool_handle_t *zhp;
830 nvlist_t *config;
831 nvlist_t *props = NULL;
832 char *propval;
833
834 /* check options */
835 while ((c = getopt(argc, argv, "fgLno:P")) != -1) {
836 switch (c) {
837 case 'f':
838 force = B_TRUE;
839 break;
840 case 'g':
841 name_flags |= VDEV_NAME_GUID;
842 break;
843 case 'L':
844 name_flags |= VDEV_NAME_FOLLOW_LINKS;
845 break;
846 case 'n':
847 dryrun = B_TRUE;
848 break;
849 case 'o':
850 if ((propval = strchr(optarg, '=')) == NULL) {
851 (void) fprintf(stderr, gettext("missing "
852 "'=' for -o option\n"));
853 usage(B_FALSE);
854 }
855 *propval = '\0';
856 propval++;
857
858 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
859 (add_prop_list(optarg, propval, &props, B_TRUE)))
860 usage(B_FALSE);
861 break;
862 case 'P':
863 name_flags |= VDEV_NAME_PATH;
864 break;
865 case '?':
866 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
867 optopt);
868 usage(B_FALSE);
869 }
870 }
871
872 argc -= optind;
873 argv += optind;
874
875 /* get pool name and check number of arguments */
876 if (argc < 1) {
877 (void) fprintf(stderr, gettext("missing pool name argument\n"));
878 usage(B_FALSE);
879 }
880 if (argc < 2) {
881 (void) fprintf(stderr, gettext("missing vdev specification\n"));
882 usage(B_FALSE);
883 }
884
885 poolname = argv[0];
886
887 argc--;
888 argv++;
889
890 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
891 return (1);
892
893 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
894 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
895 poolname);
896 zpool_close(zhp);
897 return (1);
898 }
899
900 /* unless manually specified use "ashift" pool property (if set) */
901 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
902 int intval;
903 zprop_source_t src;
904 char strval[ZPOOL_MAXPROPLEN];
905
906 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
907 if (src != ZPROP_SRC_DEFAULT) {
908 (void) sprintf(strval, "%" PRId32, intval);
909 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
910 &props, B_TRUE) == 0);
911 }
912 }
913
914 /* pass off to make_root_vdev for processing */
915 nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
916 argc, argv);
917 if (nvroot == NULL) {
918 zpool_close(zhp);
919 return (1);
920 }
921
922 if (dryrun) {
923 nvlist_t *poolnvroot;
924 nvlist_t **l2child;
925 uint_t l2children, c;
926 char *vname;
927 boolean_t hadcache = B_FALSE;
928
929 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
930 &poolnvroot) == 0);
931
932 (void) printf(gettext("would update '%s' to the following "
933 "configuration:\n"), zpool_get_name(zhp));
934
935 /* print original main pool and new tree */
936 print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
937 name_flags | VDEV_NAME_TYPE_ID);
938 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags);
939
940 /* print other classes: 'dedup', 'special', and 'log' */
941 if (zfs_special_devs(poolnvroot, VDEV_ALLOC_BIAS_DEDUP)) {
942 print_vdev_tree(zhp, "dedup", poolnvroot, 0,
943 VDEV_ALLOC_BIAS_DEDUP, name_flags);
944 print_vdev_tree(zhp, NULL, nvroot, 0,
945 VDEV_ALLOC_BIAS_DEDUP, name_flags);
946 } else if (zfs_special_devs(nvroot, VDEV_ALLOC_BIAS_DEDUP)) {
947 print_vdev_tree(zhp, "dedup", nvroot, 0,
948 VDEV_ALLOC_BIAS_DEDUP, name_flags);
949 }
950
951 if (zfs_special_devs(poolnvroot, VDEV_ALLOC_BIAS_SPECIAL)) {
952 print_vdev_tree(zhp, "special", poolnvroot, 0,
953 VDEV_ALLOC_BIAS_SPECIAL, name_flags);
954 print_vdev_tree(zhp, NULL, nvroot, 0,
955 VDEV_ALLOC_BIAS_SPECIAL, name_flags);
956 } else if (zfs_special_devs(nvroot, VDEV_ALLOC_BIAS_SPECIAL)) {
957 print_vdev_tree(zhp, "special", nvroot, 0,
958 VDEV_ALLOC_BIAS_SPECIAL, name_flags);
959 }
960
961 if (num_logs(poolnvroot) > 0) {
962 print_vdev_tree(zhp, "logs", poolnvroot, 0,
963 VDEV_ALLOC_BIAS_LOG, name_flags);
964 print_vdev_tree(zhp, NULL, nvroot, 0,
965 VDEV_ALLOC_BIAS_LOG, name_flags);
966 } else if (num_logs(nvroot) > 0) {
967 print_vdev_tree(zhp, "logs", nvroot, 0,
968 VDEV_ALLOC_BIAS_LOG, name_flags);
969 }
970
971 /* Do the same for the caches */
972 if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_L2CACHE,
973 &l2child, &l2children) == 0 && l2children) {
974 hadcache = B_TRUE;
975 (void) printf(gettext("\tcache\n"));
976 for (c = 0; c < l2children; c++) {
977 vname = zpool_vdev_name(g_zfs, NULL,
978 l2child[c], name_flags);
979 (void) printf("\t %s\n", vname);
980 free(vname);
981 }
982 }
983 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
984 &l2child, &l2children) == 0 && l2children) {
985 if (!hadcache)
986 (void) printf(gettext("\tcache\n"));
987 for (c = 0; c < l2children; c++) {
988 vname = zpool_vdev_name(g_zfs, NULL,
989 l2child[c], name_flags);
990 (void) printf("\t %s\n", vname);
991 free(vname);
992 }
993 }
994
995 ret = 0;
996 } else {
997 ret = (zpool_add(zhp, nvroot) != 0);
998 }
999
1000 nvlist_free(props);
1001 nvlist_free(nvroot);
1002 zpool_close(zhp);
1003
1004 return (ret);
1005 }
1006
1007 /*
1008 * zpool remove [-npsw] <pool> <vdev> ...
1009 *
1010 * Removes the given vdev from the pool.
1011 */
1012 int
1013 zpool_do_remove(int argc, char **argv)
1014 {
1015 char *poolname;
1016 int i, ret = 0;
1017 zpool_handle_t *zhp = NULL;
1018 boolean_t stop = B_FALSE;
1019 int c;
1020 boolean_t noop = B_FALSE;
1021 boolean_t parsable = B_FALSE;
1022 boolean_t wait = B_FALSE;
1023
1024 /* check options */
1025 while ((c = getopt(argc, argv, "npsw")) != -1) {
1026 switch (c) {
1027 case 'n':
1028 noop = B_TRUE;
1029 break;
1030 case 'p':
1031 parsable = B_TRUE;
1032 break;
1033 case 's':
1034 stop = B_TRUE;
1035 break;
1036 case 'w':
1037 wait = B_TRUE;
1038 break;
1039 case '?':
1040 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1041 optopt);
1042 usage(B_FALSE);
1043 }
1044 }
1045
1046 argc -= optind;
1047 argv += optind;
1048
1049 /* get pool name and check number of arguments */
1050 if (argc < 1) {
1051 (void) fprintf(stderr, gettext("missing pool name argument\n"));
1052 usage(B_FALSE);
1053 }
1054
1055 poolname = argv[0];
1056
1057 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
1058 return (1);
1059
1060 if (stop && noop) {
1061 (void) fprintf(stderr, gettext("stop request ignored\n"));
1062 return (0);
1063 }
1064
1065 if (stop) {
1066 if (argc > 1) {
1067 (void) fprintf(stderr, gettext("too many arguments\n"));
1068 usage(B_FALSE);
1069 }
1070 if (zpool_vdev_remove_cancel(zhp) != 0)
1071 ret = 1;
1072 if (wait) {
1073 (void) fprintf(stderr, gettext("invalid option "
1074 "combination: -w cannot be used with -s\n"));
1075 usage(B_FALSE);
1076 }
1077 } else {
1078 if (argc < 2) {
1079 (void) fprintf(stderr, gettext("missing device\n"));
1080 usage(B_FALSE);
1081 }
1082
1083 for (i = 1; i < argc; i++) {
1084 if (noop) {
1085 uint64_t size;
1086
1087 if (zpool_vdev_indirect_size(zhp, argv[i],
1088 &size) != 0) {
1089 ret = 1;
1090 break;
1091 }
1092 if (parsable) {
1093 (void) printf("%s %llu\n",
1094 argv[i], (unsigned long long)size);
1095 } else {
1096 char valstr[32];
1097 zfs_nicenum(size, valstr,
1098 sizeof (valstr));
1099 (void) printf("Memory that will be "
1100 "used after removing %s: %s\n",
1101 argv[i], valstr);
1102 }
1103 } else {
1104 if (zpool_vdev_remove(zhp, argv[i]) != 0)
1105 ret = 1;
1106 }
1107 }
1108
1109 if (ret == 0 && wait)
1110 ret = zpool_wait(zhp, ZPOOL_WAIT_REMOVE);
1111 }
1112 zpool_close(zhp);
1113
1114 return (ret);
1115 }
1116
1117 /*
1118 * zpool labelclear [-f] <vdev>
1119 *
1120 * -f Force clearing the label for the vdevs which are members of
1121 * the exported or foreign pools.
1122 *
1123 * Verifies that the vdev is not active and zeros out the label information
1124 * on the device.
1125 */
1126 int
1127 zpool_do_labelclear(int argc, char **argv)
1128 {
1129 char vdev[MAXPATHLEN];
1130 char *name = NULL;
1131 struct stat st;
1132 int c, fd = -1, ret = 0;
1133 nvlist_t *config;
1134 pool_state_t state;
1135 boolean_t inuse = B_FALSE;
1136 boolean_t force = B_FALSE;
1137
1138 /* check options */
1139 while ((c = getopt(argc, argv, "f")) != -1) {
1140 switch (c) {
1141 case 'f':
1142 force = B_TRUE;
1143 break;
1144 default:
1145 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1146 optopt);
1147 usage(B_FALSE);
1148 }
1149 }
1150
1151 argc -= optind;
1152 argv += optind;
1153
1154 /* get vdev name */
1155 if (argc < 1) {
1156 (void) fprintf(stderr, gettext("missing vdev name\n"));
1157 usage(B_FALSE);
1158 }
1159 if (argc > 1) {
1160 (void) fprintf(stderr, gettext("too many arguments\n"));
1161 usage(B_FALSE);
1162 }
1163
1164 /*
1165 * Check if we were given absolute path and use it as is.
1166 * Otherwise if the provided vdev name doesn't point to a file,
1167 * try prepending expected disk paths and partition numbers.
1168 */
1169 (void) strlcpy(vdev, argv[0], sizeof (vdev));
1170 if (vdev[0] != '/' && stat(vdev, &st) != 0) {
1171 int error;
1172
1173 error = zfs_resolve_shortname(argv[0], vdev, MAXPATHLEN);
1174 if (error == 0 && zfs_dev_is_whole_disk(vdev)) {
1175 if (zfs_append_partition(vdev, MAXPATHLEN) == -1)
1176 error = ENOENT;
1177 }
1178
1179 if (error || (stat(vdev, &st) != 0)) {
1180 (void) fprintf(stderr, gettext(
1181 "failed to find device %s, try specifying absolute "
1182 "path instead\n"), argv[0]);
1183 return (1);
1184 }
1185 }
1186
1187 if ((fd = open(vdev, O_RDWR)) < 0) {
1188 (void) fprintf(stderr, gettext("failed to open %s: %s\n"),
1189 vdev, strerror(errno));
1190 return (1);
1191 }
1192
1193 /*
1194 * Flush all dirty pages for the block device. This should not be
1195 * fatal when the device does not support BLKFLSBUF as would be the
1196 * case for a file vdev.
1197 */
1198 if ((zfs_dev_flush(fd) != 0) && (errno != ENOTTY))
1199 (void) fprintf(stderr, gettext("failed to invalidate "
1200 "cache for %s: %s\n"), vdev, strerror(errno));
1201
1202 if (zpool_read_label(fd, &config, NULL) != 0) {
1203 (void) fprintf(stderr,
1204 gettext("failed to read label from %s\n"), vdev);
1205 ret = 1;
1206 goto errout;
1207 }
1208 nvlist_free(config);
1209
1210 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
1211 if (ret != 0) {
1212 (void) fprintf(stderr,
1213 gettext("failed to check state for %s\n"), vdev);
1214 ret = 1;
1215 goto errout;
1216 }
1217
1218 if (!inuse)
1219 goto wipe_label;
1220
1221 switch (state) {
1222 default:
1223 case POOL_STATE_ACTIVE:
1224 case POOL_STATE_SPARE:
1225 case POOL_STATE_L2CACHE:
1226 (void) fprintf(stderr, gettext(
1227 "%s is a member (%s) of pool \"%s\"\n"),
1228 vdev, zpool_pool_state_to_name(state), name);
1229 ret = 1;
1230 goto errout;
1231
1232 case POOL_STATE_EXPORTED:
1233 if (force)
1234 break;
1235 (void) fprintf(stderr, gettext(
1236 "use '-f' to override the following error:\n"
1237 "%s is a member of exported pool \"%s\"\n"),
1238 vdev, name);
1239 ret = 1;
1240 goto errout;
1241
1242 case POOL_STATE_POTENTIALLY_ACTIVE:
1243 if (force)
1244 break;
1245 (void) fprintf(stderr, gettext(
1246 "use '-f' to override the following error:\n"
1247 "%s is a member of potentially active pool \"%s\"\n"),
1248 vdev, name);
1249 ret = 1;
1250 goto errout;
1251
1252 case POOL_STATE_DESTROYED:
1253 /* inuse should never be set for a destroyed pool */
1254 assert(0);
1255 break;
1256 }
1257
1258 wipe_label:
1259 ret = zpool_clear_label(fd);
1260 if (ret != 0) {
1261 (void) fprintf(stderr,
1262 gettext("failed to clear label for %s\n"), vdev);
1263 }
1264
1265 errout:
1266 free(name);
1267 (void) close(fd);
1268
1269 return (ret);
1270 }
1271
1272 /*
1273 * zpool create [-fnd] [-o property=value] ...
1274 * [-O file-system-property=value] ...
1275 * [-R root] [-m mountpoint] <pool> <dev> ...
1276 *
1277 * -f Force creation, even if devices appear in use
1278 * -n Do not create the pool, but display the resulting layout if it
1279 * were to be created.
1280 * -R Create a pool under an alternate root
1281 * -m Set default mountpoint for the root dataset. By default it's
1282 * '/<pool>'
1283 * -o Set property=value.
1284 * -o Set feature@feature=enabled|disabled.
1285 * -d Don't automatically enable all supported pool features
1286 * (individual features can be enabled with -o).
1287 * -O Set fsproperty=value in the pool's root file system
1288 *
1289 * Creates the named pool according to the given vdev specification. The
1290 * bulk of the vdev processing is done in make_root_vdev() in zpool_vdev.c.
1291 * Once we get the nvlist back from make_root_vdev(), we either print out the
1292 * contents (if '-n' was specified), or pass it to libzfs to do the creation.
1293 */
1294 int
1295 zpool_do_create(int argc, char **argv)
1296 {
1297 boolean_t force = B_FALSE;
1298 boolean_t dryrun = B_FALSE;
1299 boolean_t enable_all_pool_feat = B_TRUE;
1300 int c;
1301 nvlist_t *nvroot = NULL;
1302 char *poolname;
1303 char *tname = NULL;
1304 int ret = 1;
1305 char *altroot = NULL;
1306 char *mountpoint = NULL;
1307 nvlist_t *fsprops = NULL;
1308 nvlist_t *props = NULL;
1309 char *propval;
1310
1311 /* check options */
1312 while ((c = getopt(argc, argv, ":fndR:m:o:O:t:")) != -1) {
1313 switch (c) {
1314 case 'f':
1315 force = B_TRUE;
1316 break;
1317 case 'n':
1318 dryrun = B_TRUE;
1319 break;
1320 case 'd':
1321 enable_all_pool_feat = B_FALSE;
1322 break;
1323 case 'R':
1324 altroot = optarg;
1325 if (add_prop_list(zpool_prop_to_name(
1326 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1327 goto errout;
1328 if (add_prop_list_default(zpool_prop_to_name(
1329 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1330 goto errout;
1331 break;
1332 case 'm':
1333 /* Equivalent to -O mountpoint=optarg */
1334 mountpoint = optarg;
1335 break;
1336 case 'o':
1337 if ((propval = strchr(optarg, '=')) == NULL) {
1338 (void) fprintf(stderr, gettext("missing "
1339 "'=' for -o option\n"));
1340 goto errout;
1341 }
1342 *propval = '\0';
1343 propval++;
1344
1345 if (add_prop_list(optarg, propval, &props, B_TRUE))
1346 goto errout;
1347
1348 /*
1349 * If the user is creating a pool that doesn't support
1350 * feature flags, don't enable any features.
1351 */
1352 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
1353 char *end;
1354 u_longlong_t ver;
1355
1356 ver = strtoull(propval, &end, 10);
1357 if (*end == '\0' &&
1358 ver < SPA_VERSION_FEATURES) {
1359 enable_all_pool_feat = B_FALSE;
1360 }
1361 }
1362 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
1363 altroot = propval;
1364 break;
1365 case 'O':
1366 if ((propval = strchr(optarg, '=')) == NULL) {
1367 (void) fprintf(stderr, gettext("missing "
1368 "'=' for -O option\n"));
1369 goto errout;
1370 }
1371 *propval = '\0';
1372 propval++;
1373
1374 /*
1375 * Mountpoints are checked and then added later.
1376 * Uniquely among properties, they can be specified
1377 * more than once, to avoid conflict with -m.
1378 */
1379 if (0 == strcmp(optarg,
1380 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
1381 mountpoint = propval;
1382 } else if (add_prop_list(optarg, propval, &fsprops,
1383 B_FALSE)) {
1384 goto errout;
1385 }
1386 break;
1387 case 't':
1388 /*
1389 * Sanity check temporary pool name.
1390 */
1391 if (strchr(optarg, '/') != NULL) {
1392 (void) fprintf(stderr, gettext("cannot create "
1393 "'%s': invalid character '/' in temporary "
1394 "name\n"), optarg);
1395 (void) fprintf(stderr, gettext("use 'zfs "
1396 "create' to create a dataset\n"));
1397 goto errout;
1398 }
1399
1400 if (add_prop_list(zpool_prop_to_name(
1401 ZPOOL_PROP_TNAME), optarg, &props, B_TRUE))
1402 goto errout;
1403 if (add_prop_list_default(zpool_prop_to_name(
1404 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1405 goto errout;
1406 tname = optarg;
1407 break;
1408 case ':':
1409 (void) fprintf(stderr, gettext("missing argument for "
1410 "'%c' option\n"), optopt);
1411 goto badusage;
1412 case '?':
1413 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1414 optopt);
1415 goto badusage;
1416 }
1417 }
1418
1419 argc -= optind;
1420 argv += optind;
1421
1422 /* get pool name and check number of arguments */
1423 if (argc < 1) {
1424 (void) fprintf(stderr, gettext("missing pool name argument\n"));
1425 goto badusage;
1426 }
1427 if (argc < 2) {
1428 (void) fprintf(stderr, gettext("missing vdev specification\n"));
1429 goto badusage;
1430 }
1431
1432 poolname = argv[0];
1433
1434 /*
1435 * As a special case, check for use of '/' in the name, and direct the
1436 * user to use 'zfs create' instead.
1437 */
1438 if (strchr(poolname, '/') != NULL) {
1439 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
1440 "character '/' in pool name\n"), poolname);
1441 (void) fprintf(stderr, gettext("use 'zfs create' to "
1442 "create a dataset\n"));
1443 goto errout;
1444 }
1445
1446 /* pass off to make_root_vdev for bulk processing */
1447 nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
1448 argc - 1, argv + 1);
1449 if (nvroot == NULL)
1450 goto errout;
1451
1452 /* make_root_vdev() allows 0 toplevel children if there are spares */
1453 if (!zfs_allocatable_devs(nvroot)) {
1454 (void) fprintf(stderr, gettext("invalid vdev "
1455 "specification: at least one toplevel vdev must be "
1456 "specified\n"));
1457 goto errout;
1458 }
1459
1460 if (altroot != NULL && altroot[0] != '/') {
1461 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
1462 "must be an absolute path\n"), altroot);
1463 goto errout;
1464 }
1465
1466 /*
1467 * Check the validity of the mountpoint and direct the user to use the
1468 * '-m' mountpoint option if it looks like its in use.
1469 */
1470 if (mountpoint == NULL ||
1471 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
1472 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
1473 char buf[MAXPATHLEN];
1474 DIR *dirp;
1475
1476 if (mountpoint && mountpoint[0] != '/') {
1477 (void) fprintf(stderr, gettext("invalid mountpoint "
1478 "'%s': must be an absolute path, 'legacy', or "
1479 "'none'\n"), mountpoint);
1480 goto errout;
1481 }
1482
1483 if (mountpoint == NULL) {
1484 if (altroot != NULL)
1485 (void) snprintf(buf, sizeof (buf), "%s/%s",
1486 altroot, poolname);
1487 else
1488 (void) snprintf(buf, sizeof (buf), "/%s",
1489 poolname);
1490 } else {
1491 if (altroot != NULL)
1492 (void) snprintf(buf, sizeof (buf), "%s%s",
1493 altroot, mountpoint);
1494 else
1495 (void) snprintf(buf, sizeof (buf), "%s",
1496 mountpoint);
1497 }
1498
1499 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
1500 (void) fprintf(stderr, gettext("mountpoint '%s' : "
1501 "%s\n"), buf, strerror(errno));
1502 (void) fprintf(stderr, gettext("use '-m' "
1503 "option to provide a different default\n"));
1504 goto errout;
1505 } else if (dirp) {
1506 int count = 0;
1507
1508 while (count < 3 && readdir(dirp) != NULL)
1509 count++;
1510 (void) closedir(dirp);
1511
1512 if (count > 2) {
1513 (void) fprintf(stderr, gettext("mountpoint "
1514 "'%s' exists and is not empty\n"), buf);
1515 (void) fprintf(stderr, gettext("use '-m' "
1516 "option to provide a "
1517 "different default\n"));
1518 goto errout;
1519 }
1520 }
1521 }
1522
1523 /*
1524 * Now that the mountpoint's validity has been checked, ensure that
1525 * the property is set appropriately prior to creating the pool.
1526 */
1527 if (mountpoint != NULL) {
1528 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1529 mountpoint, &fsprops, B_FALSE);
1530 if (ret != 0)
1531 goto errout;
1532 }
1533
1534 ret = 1;
1535 if (dryrun) {
1536 /*
1537 * For a dry run invocation, print out a basic message and run
1538 * through all the vdevs in the list and print out in an
1539 * appropriate hierarchy.
1540 */
1541 (void) printf(gettext("would create '%s' with the "
1542 "following layout:\n\n"), poolname);
1543
1544 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0);
1545 print_vdev_tree(NULL, "dedup", nvroot, 0,
1546 VDEV_ALLOC_BIAS_DEDUP, 0);
1547 print_vdev_tree(NULL, "special", nvroot, 0,
1548 VDEV_ALLOC_BIAS_SPECIAL, 0);
1549 print_vdev_tree(NULL, "logs", nvroot, 0,
1550 VDEV_ALLOC_BIAS_LOG, 0);
1551
1552 ret = 0;
1553 } else {
1554 /*
1555 * Hand off to libzfs.
1556 */
1557 spa_feature_t i;
1558 for (i = 0; i < SPA_FEATURES; i++) {
1559 char propname[MAXPATHLEN];
1560 char *propval;
1561 zfeature_info_t *feat = &spa_feature_table[i];
1562
1563 (void) snprintf(propname, sizeof (propname),
1564 "feature@%s", feat->fi_uname);
1565
1566 /*
1567 * Only features contained in props will be enabled:
1568 * remove from the nvlist every ZFS_FEATURE_DISABLED
1569 * value and add every missing ZFS_FEATURE_ENABLED if
1570 * enable_all_pool_feat is set.
1571 */
1572 if (!nvlist_lookup_string(props, propname, &propval)) {
1573 if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
1574 (void) nvlist_remove_all(props,
1575 propname);
1576 } else if (enable_all_pool_feat) {
1577 ret = add_prop_list(propname,
1578 ZFS_FEATURE_ENABLED, &props, B_TRUE);
1579 if (ret != 0)
1580 goto errout;
1581 }
1582 }
1583
1584 ret = 1;
1585 if (zpool_create(g_zfs, poolname,
1586 nvroot, props, fsprops) == 0) {
1587 zfs_handle_t *pool = zfs_open(g_zfs,
1588 tname ? tname : poolname, ZFS_TYPE_FILESYSTEM);
1589 if (pool != NULL) {
1590 if (zfs_mount(pool, NULL, 0) == 0) {
1591 ret = zfs_shareall(pool);
1592 zfs_commit_all_shares();
1593 }
1594 zfs_close(pool);
1595 }
1596 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1597 (void) fprintf(stderr, gettext("pool name may have "
1598 "been omitted\n"));
1599 }
1600 }
1601
1602 errout:
1603 nvlist_free(nvroot);
1604 nvlist_free(fsprops);
1605 nvlist_free(props);
1606 return (ret);
1607 badusage:
1608 nvlist_free(fsprops);
1609 nvlist_free(props);
1610 usage(B_FALSE);
1611 return (2);
1612 }
1613
1614 /*
1615 * zpool destroy <pool>
1616 *
1617 * -f Forcefully unmount any datasets
1618 *
1619 * Destroy the given pool. Automatically unmounts any datasets in the pool.
1620 */
1621 int
1622 zpool_do_destroy(int argc, char **argv)
1623 {
1624 boolean_t force = B_FALSE;
1625 int c;
1626 char *pool;
1627 zpool_handle_t *zhp;
1628 int ret;
1629
1630 /* check options */
1631 while ((c = getopt(argc, argv, "f")) != -1) {
1632 switch (c) {
1633 case 'f':
1634 force = B_TRUE;
1635 break;
1636 case '?':
1637 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1638 optopt);
1639 usage(B_FALSE);
1640 }
1641 }
1642
1643 argc -= optind;
1644 argv += optind;
1645
1646 /* check arguments */
1647 if (argc < 1) {
1648 (void) fprintf(stderr, gettext("missing pool argument\n"));
1649 usage(B_FALSE);
1650 }
1651 if (argc > 1) {
1652 (void) fprintf(stderr, gettext("too many arguments\n"));
1653 usage(B_FALSE);
1654 }
1655
1656 pool = argv[0];
1657
1658 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1659 /*
1660 * As a special case, check for use of '/' in the name, and
1661 * direct the user to use 'zfs destroy' instead.
1662 */
1663 if (strchr(pool, '/') != NULL)
1664 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
1665 "destroy a dataset\n"));
1666 return (1);
1667 }
1668
1669 if (zpool_disable_datasets(zhp, force) != 0) {
1670 (void) fprintf(stderr, gettext("could not destroy '%s': "
1671 "could not unmount datasets\n"), zpool_get_name(zhp));
1672 zpool_close(zhp);
1673 return (1);
1674 }
1675
1676 /* The history must be logged as part of the export */
1677 log_history = B_FALSE;
1678
1679 ret = (zpool_destroy(zhp, history_str) != 0);
1680
1681 zpool_close(zhp);
1682
1683 return (ret);
1684 }
1685
1686 typedef struct export_cbdata {
1687 boolean_t force;
1688 boolean_t hardforce;
1689 } export_cbdata_t;
1690
1691 /*
1692 * Export one pool
1693 */
1694 static int
1695 zpool_export_one(zpool_handle_t *zhp, void *data)
1696 {
1697 export_cbdata_t *cb = data;
1698
1699 if (zpool_disable_datasets(zhp, cb->force) != 0)
1700 return (1);
1701
1702 /* The history must be logged as part of the export */
1703 log_history = B_FALSE;
1704
1705 if (cb->hardforce) {
1706 if (zpool_export_force(zhp, history_str) != 0)
1707 return (1);
1708 } else if (zpool_export(zhp, cb->force, history_str) != 0) {
1709 return (1);
1710 }
1711
1712 return (0);
1713 }
1714
1715 /*
1716 * zpool export [-f] <pool> ...
1717 *
1718 * -a Export all pools
1719 * -f Forcefully unmount datasets
1720 *
1721 * Export the given pools. By default, the command will attempt to cleanly
1722 * unmount any active datasets within the pool. If the '-f' flag is specified,
1723 * then the datasets will be forcefully unmounted.
1724 */
1725 int
1726 zpool_do_export(int argc, char **argv)
1727 {
1728 export_cbdata_t cb;
1729 boolean_t do_all = B_FALSE;
1730 boolean_t force = B_FALSE;
1731 boolean_t hardforce = B_FALSE;
1732 int c, ret;
1733
1734 /* check options */
1735 while ((c = getopt(argc, argv, "afF")) != -1) {
1736 switch (c) {
1737 case 'a':
1738 do_all = B_TRUE;
1739 break;
1740 case 'f':
1741 force = B_TRUE;
1742 break;
1743 case 'F':
1744 hardforce = B_TRUE;
1745 break;
1746 case '?':
1747 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1748 optopt);
1749 usage(B_FALSE);
1750 }
1751 }
1752
1753 cb.force = force;
1754 cb.hardforce = hardforce;
1755 argc -= optind;
1756 argv += optind;
1757
1758 if (do_all) {
1759 if (argc != 0) {
1760 (void) fprintf(stderr, gettext("too many arguments\n"));
1761 usage(B_FALSE);
1762 }
1763
1764 return (for_each_pool(argc, argv, B_TRUE, NULL,
1765 zpool_export_one, &cb));
1766 }
1767
1768 /* check arguments */
1769 if (argc < 1) {
1770 (void) fprintf(stderr, gettext("missing pool argument\n"));
1771 usage(B_FALSE);
1772 }
1773
1774 ret = for_each_pool(argc, argv, B_TRUE, NULL, zpool_export_one, &cb);
1775
1776 return (ret);
1777 }
1778
1779 /*
1780 * Given a vdev configuration, determine the maximum width needed for the device
1781 * name column.
1782 */
1783 static int
1784 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
1785 int name_flags)
1786 {
1787 char *name;
1788 nvlist_t **child;
1789 uint_t c, children;
1790 int ret;
1791
1792 name = zpool_vdev_name(g_zfs, zhp, nv, name_flags);
1793 if (strlen(name) + depth > max)
1794 max = strlen(name) + depth;
1795
1796 free(name);
1797
1798 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1799 &child, &children) == 0) {
1800 for (c = 0; c < children; c++)
1801 if ((ret = max_width(zhp, child[c], depth + 2,
1802 max, name_flags)) > max)
1803 max = ret;
1804 }
1805
1806 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1807 &child, &children) == 0) {
1808 for (c = 0; c < children; c++)
1809 if ((ret = max_width(zhp, child[c], depth + 2,
1810 max, name_flags)) > max)
1811 max = ret;
1812 }
1813
1814 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1815 &child, &children) == 0) {
1816 for (c = 0; c < children; c++)
1817 if ((ret = max_width(zhp, child[c], depth + 2,
1818 max, name_flags)) > max)
1819 max = ret;
1820 }
1821
1822 return (max);
1823 }
1824
1825 typedef struct spare_cbdata {
1826 uint64_t cb_guid;
1827 zpool_handle_t *cb_zhp;
1828 } spare_cbdata_t;
1829
1830 static boolean_t
1831 find_vdev(nvlist_t *nv, uint64_t search)
1832 {
1833 uint64_t guid;
1834 nvlist_t **child;
1835 uint_t c, children;
1836
1837 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1838 search == guid)
1839 return (B_TRUE);
1840
1841 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1842 &child, &children) == 0) {
1843 for (c = 0; c < children; c++)
1844 if (find_vdev(child[c], search))
1845 return (B_TRUE);
1846 }
1847
1848 return (B_FALSE);
1849 }
1850
1851 static int
1852 find_spare(zpool_handle_t *zhp, void *data)
1853 {
1854 spare_cbdata_t *cbp = data;
1855 nvlist_t *config, *nvroot;
1856
1857 config = zpool_get_config(zhp, NULL);
1858 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1859 &nvroot) == 0);
1860
1861 if (find_vdev(nvroot, cbp->cb_guid)) {
1862 cbp->cb_zhp = zhp;
1863 return (1);
1864 }
1865
1866 zpool_close(zhp);
1867 return (0);
1868 }
1869
1870 typedef struct status_cbdata {
1871 int cb_count;
1872 int cb_name_flags;
1873 int cb_namewidth;
1874 boolean_t cb_allpools;
1875 boolean_t cb_verbose;
1876 boolean_t cb_literal;
1877 boolean_t cb_explain;
1878 boolean_t cb_first;
1879 boolean_t cb_dedup_stats;
1880 boolean_t cb_print_status;
1881 boolean_t cb_print_slow_ios;
1882 boolean_t cb_print_vdev_init;
1883 boolean_t cb_print_vdev_trim;
1884 vdev_cmd_data_list_t *vcdl;
1885 } status_cbdata_t;
1886
1887 /* Return 1 if string is NULL, empty, or whitespace; return 0 otherwise. */
1888 static int
1889 is_blank_str(char *str)
1890 {
1891 while (str != NULL && *str != '\0') {
1892 if (!isblank(*str))
1893 return (0);
1894 str++;
1895 }
1896 return (1);
1897 }
1898
1899 /* Print command output lines for specific vdev in a specific pool */
1900 static void
1901 zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, char *path)
1902 {
1903 vdev_cmd_data_t *data;
1904 int i, j;
1905 char *val;
1906
1907 for (i = 0; i < vcdl->count; i++) {
1908 if ((strcmp(vcdl->data[i].path, path) != 0) ||
1909 (strcmp(vcdl->data[i].pool, pool) != 0)) {
1910 /* Not the vdev we're looking for */
1911 continue;
1912 }
1913
1914 data = &vcdl->data[i];
1915 /* Print out all the output values for this vdev */
1916 for (j = 0; j < vcdl->uniq_cols_cnt; j++) {
1917 val = NULL;
1918 /* Does this vdev have values for this column? */
1919 for (int k = 0; k < data->cols_cnt; k++) {
1920 if (strcmp(data->cols[k],
1921 vcdl->uniq_cols[j]) == 0) {
1922 /* yes it does, record the value */
1923 val = data->lines[k];
1924 break;
1925 }
1926 }
1927 /*
1928 * Mark empty values with dashes to make output
1929 * awk-able.
1930 */
1931 if (is_blank_str(val))
1932 val = "-";
1933
1934 printf("%*s", vcdl->uniq_cols_width[j], val);
1935 if (j < vcdl->uniq_cols_cnt - 1)
1936 printf(" ");
1937 }
1938
1939 /* Print out any values that aren't in a column at the end */
1940 for (j = data->cols_cnt; j < data->lines_cnt; j++) {
1941 /* Did we have any columns? If so print a spacer. */
1942 if (vcdl->uniq_cols_cnt > 0)
1943 printf(" ");
1944
1945 val = data->lines[j];
1946 printf("%s", val ? val : "");
1947 }
1948 break;
1949 }
1950 }
1951
1952 /*
1953 * Print vdev initialization status for leaves
1954 */
1955 static void
1956 print_status_initialize(vdev_stat_t *vs, boolean_t verbose)
1957 {
1958 if (verbose) {
1959 if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE ||
1960 vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED ||
1961 vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) &&
1962 !vs->vs_scan_removing) {
1963 char zbuf[1024];
1964 char tbuf[256];
1965 struct tm zaction_ts;
1966
1967 time_t t = vs->vs_initialize_action_time;
1968 int initialize_pct = 100;
1969 if (vs->vs_initialize_state !=
1970 VDEV_INITIALIZE_COMPLETE) {
1971 initialize_pct = (vs->vs_initialize_bytes_done *
1972 100 / (vs->vs_initialize_bytes_est + 1));
1973 }
1974
1975 (void) localtime_r(&t, &zaction_ts);
1976 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
1977
1978 switch (vs->vs_initialize_state) {
1979 case VDEV_INITIALIZE_SUSPENDED:
1980 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1981 gettext("suspended, started at"), tbuf);
1982 break;
1983 case VDEV_INITIALIZE_ACTIVE:
1984 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1985 gettext("started at"), tbuf);
1986 break;
1987 case VDEV_INITIALIZE_COMPLETE:
1988 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
1989 gettext("completed at"), tbuf);
1990 break;
1991 }
1992
1993 (void) printf(gettext(" (%d%% initialized%s)"),
1994 initialize_pct, zbuf);
1995 } else {
1996 (void) printf(gettext(" (uninitialized)"));
1997 }
1998 } else if (vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) {
1999 (void) printf(gettext(" (initializing)"));
2000 }
2001 }
2002
2003 /*
2004 * Print vdev TRIM status for leaves
2005 */
2006 static void
2007 print_status_trim(vdev_stat_t *vs, boolean_t verbose)
2008 {
2009 if (verbose) {
2010 if ((vs->vs_trim_state == VDEV_TRIM_ACTIVE ||
2011 vs->vs_trim_state == VDEV_TRIM_SUSPENDED ||
2012 vs->vs_trim_state == VDEV_TRIM_COMPLETE) &&
2013 !vs->vs_scan_removing) {
2014 char zbuf[1024];
2015 char tbuf[256];
2016 struct tm zaction_ts;
2017
2018 time_t t = vs->vs_trim_action_time;
2019 int trim_pct = 100;
2020 if (vs->vs_trim_state != VDEV_TRIM_COMPLETE) {
2021 trim_pct = (vs->vs_trim_bytes_done *
2022 100 / (vs->vs_trim_bytes_est + 1));
2023 }
2024
2025 (void) localtime_r(&t, &zaction_ts);
2026 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
2027
2028 switch (vs->vs_trim_state) {
2029 case VDEV_TRIM_SUSPENDED:
2030 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
2031 gettext("suspended, started at"), tbuf);
2032 break;
2033 case VDEV_TRIM_ACTIVE:
2034 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
2035 gettext("started at"), tbuf);
2036 break;
2037 case VDEV_TRIM_COMPLETE:
2038 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s",
2039 gettext("completed at"), tbuf);
2040 break;
2041 }
2042
2043 (void) printf(gettext(" (%d%% trimmed%s)"),
2044 trim_pct, zbuf);
2045 } else if (vs->vs_trim_notsup) {
2046 (void) printf(gettext(" (trim unsupported)"));
2047 } else {
2048 (void) printf(gettext(" (untrimmed)"));
2049 }
2050 } else if (vs->vs_trim_state == VDEV_TRIM_ACTIVE) {
2051 (void) printf(gettext(" (trimming)"));
2052 }
2053 }
2054
2055 /*
2056 * Return the color associated with a health string. This includes returning
2057 * NULL for no color change.
2058 */
2059 static char *
2060 health_str_to_color(const char *health)
2061 {
2062 if (strcmp(health, gettext("FAULTED")) == 0 ||
2063 strcmp(health, gettext("SUSPENDED")) == 0 ||
2064 strcmp(health, gettext("UNAVAIL")) == 0) {
2065 return (ANSI_RED);
2066 }
2067
2068 if (strcmp(health, gettext("OFFLINE")) == 0 ||
2069 strcmp(health, gettext("DEGRADED")) == 0 ||
2070 strcmp(health, gettext("REMOVED")) == 0) {
2071 return (ANSI_YELLOW);
2072 }
2073
2074 return (NULL);
2075 }
2076
2077 /*
2078 * Print out configuration state as requested by status_callback.
2079 */
2080 static void
2081 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
2082 nvlist_t *nv, int depth, boolean_t isspare, vdev_rebuild_stat_t *vrs)
2083 {
2084 nvlist_t **child, *root;
2085 uint_t c, i, vsc, children;
2086 pool_scan_stat_t *ps = NULL;
2087 vdev_stat_t *vs;
2088 char rbuf[6], wbuf[6], cbuf[6];
2089 char *vname;
2090 uint64_t notpresent;
2091 spare_cbdata_t spare_cb;
2092 const char *state;
2093 char *type;
2094 char *path = NULL;
2095 char *rcolor = NULL, *wcolor = NULL, *ccolor = NULL;
2096
2097 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2098 &child, &children) != 0)
2099 children = 0;
2100
2101 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
2102 (uint64_t **)&vs, &vsc) == 0);
2103
2104 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
2105
2106 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0)
2107 return;
2108
2109 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2110
2111 if (isspare) {
2112 /*
2113 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2114 * online drives.
2115 */
2116 if (vs->vs_aux == VDEV_AUX_SPARED)
2117 state = gettext("INUSE");
2118 else if (vs->vs_state == VDEV_STATE_HEALTHY)
2119 state = gettext("AVAIL");
2120 }
2121
2122 printf_color(health_str_to_color(state),
2123 "\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
2124 name, state);
2125
2126 if (!isspare) {
2127 if (vs->vs_read_errors)
2128 rcolor = ANSI_RED;
2129
2130 if (vs->vs_write_errors)
2131 wcolor = ANSI_RED;
2132
2133 if (vs->vs_checksum_errors)
2134 ccolor = ANSI_RED;
2135
2136 if (cb->cb_literal) {
2137 printf(" ");
2138 printf_color(rcolor, "%5llu",
2139 (u_longlong_t)vs->vs_read_errors);
2140 printf(" ");
2141 printf_color(wcolor, "%5llu",
2142 (u_longlong_t)vs->vs_write_errors);
2143 printf(" ");
2144 printf_color(ccolor, "%5llu",
2145 (u_longlong_t)vs->vs_checksum_errors);
2146 } else {
2147 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2148 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2149 zfs_nicenum(vs->vs_checksum_errors, cbuf,
2150 sizeof (cbuf));
2151 printf(" ");
2152 printf_color(rcolor, "%5s", rbuf);
2153 printf(" ");
2154 printf_color(wcolor, "%5s", wbuf);
2155 printf(" ");
2156 printf_color(ccolor, "%5s", cbuf);
2157 }
2158 if (cb->cb_print_slow_ios) {
2159 if (children == 0) {
2160 /* Only leafs vdevs have slow IOs */
2161 zfs_nicenum(vs->vs_slow_ios, rbuf,
2162 sizeof (rbuf));
2163 } else {
2164 snprintf(rbuf, sizeof (rbuf), "-");
2165 }
2166
2167 if (cb->cb_literal)
2168 printf(" %5llu", (u_longlong_t)vs->vs_slow_ios);
2169 else
2170 printf(" %5s", rbuf);
2171 }
2172 }
2173
2174 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2175 &notpresent) == 0) {
2176 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2177 (void) printf(" %s %s", gettext("was"), path);
2178 } else if (vs->vs_aux != 0) {
2179 (void) printf(" ");
2180 color_start(ANSI_RED);
2181 switch (vs->vs_aux) {
2182 case VDEV_AUX_OPEN_FAILED:
2183 (void) printf(gettext("cannot open"));
2184 break;
2185
2186 case VDEV_AUX_BAD_GUID_SUM:
2187 (void) printf(gettext("missing device"));
2188 break;
2189
2190 case VDEV_AUX_NO_REPLICAS:
2191 (void) printf(gettext("insufficient replicas"));
2192 break;
2193
2194 case VDEV_AUX_VERSION_NEWER:
2195 (void) printf(gettext("newer version"));
2196 break;
2197
2198 case VDEV_AUX_UNSUP_FEAT:
2199 (void) printf(gettext("unsupported feature(s)"));
2200 break;
2201
2202 case VDEV_AUX_ASHIFT_TOO_BIG:
2203 (void) printf(gettext("unsupported minimum blocksize"));
2204 break;
2205
2206 case VDEV_AUX_SPARED:
2207 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2208 &spare_cb.cb_guid) == 0);
2209 if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) {
2210 if (strcmp(zpool_get_name(spare_cb.cb_zhp),
2211 zpool_get_name(zhp)) == 0)
2212 (void) printf(gettext("currently in "
2213 "use"));
2214 else
2215 (void) printf(gettext("in use by "
2216 "pool '%s'"),
2217 zpool_get_name(spare_cb.cb_zhp));
2218 zpool_close(spare_cb.cb_zhp);
2219 } else {
2220 (void) printf(gettext("currently in use"));
2221 }
2222 break;
2223
2224 case VDEV_AUX_ERR_EXCEEDED:
2225 (void) printf(gettext("too many errors"));
2226 break;
2227
2228 case VDEV_AUX_IO_FAILURE:
2229 (void) printf(gettext("experienced I/O failures"));
2230 break;
2231
2232 case VDEV_AUX_BAD_LOG:
2233 (void) printf(gettext("bad intent log"));
2234 break;
2235
2236 case VDEV_AUX_EXTERNAL:
2237 (void) printf(gettext("external device fault"));
2238 break;
2239
2240 case VDEV_AUX_SPLIT_POOL:
2241 (void) printf(gettext("split into new pool"));
2242 break;
2243
2244 case VDEV_AUX_ACTIVE:
2245 (void) printf(gettext("currently in use"));
2246 break;
2247
2248 case VDEV_AUX_CHILDREN_OFFLINE:
2249 (void) printf(gettext("all children offline"));
2250 break;
2251
2252 default:
2253 (void) printf(gettext("corrupted data"));
2254 break;
2255 }
2256 color_end();
2257 } else if (children == 0 && !isspare &&
2258 getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") == NULL &&
2259 VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
2260 vs->vs_configured_ashift < vs->vs_physical_ashift) {
2261 (void) printf(
2262 gettext(" block size: %dB configured, %dB native"),
2263 1 << vs->vs_configured_ashift, 1 << vs->vs_physical_ashift);
2264 }
2265
2266 /* The root vdev has the scrub/resilver stats */
2267 root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
2268 ZPOOL_CONFIG_VDEV_TREE);
2269 (void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
2270 (uint64_t **)&ps, &c);
2271
2272 if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) {
2273 if (vs->vs_scan_processed != 0) {
2274 (void) printf(gettext(" (%s)"),
2275 (ps->pss_func == POOL_SCAN_RESILVER) ?
2276 "resilvering" : "repairing");
2277 } else if (vs->vs_resilver_deferred) {
2278 (void) printf(gettext(" (awaiting resilver)"));
2279 }
2280 }
2281
2282 /* The top-level vdevs have the rebuild stats */
2283 if (vrs != NULL && vrs->vrs_state == VDEV_REBUILD_ACTIVE &&
2284 children == 0) {
2285 if (vs->vs_rebuild_processed != 0) {
2286 (void) printf(gettext(" (resilvering)"));
2287 }
2288 }
2289
2290 if (cb->vcdl != NULL) {
2291 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
2292 printf(" ");
2293 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path);
2294 }
2295 }
2296
2297 /* Display vdev initialization and trim status for leaves */
2298 if (children == 0) {
2299 print_status_initialize(vs, cb->cb_print_vdev_init);
2300 print_status_trim(vs, cb->cb_print_vdev_trim);
2301 }
2302
2303 (void) printf("\n");
2304
2305 for (c = 0; c < children; c++) {
2306 uint64_t islog = B_FALSE, ishole = B_FALSE;
2307
2308 /* Don't print logs or holes here */
2309 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2310 &islog);
2311 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
2312 &ishole);
2313 if (islog || ishole)
2314 continue;
2315 /* Only print normal classes here */
2316 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
2317 continue;
2318
2319 /* Provide vdev_rebuild_stats to children if available */
2320 if (vrs == NULL) {
2321 (void) nvlist_lookup_uint64_array(nv,
2322 ZPOOL_CONFIG_REBUILD_STATS,
2323 (uint64_t **)&vrs, &i);
2324 }
2325
2326 vname = zpool_vdev_name(g_zfs, zhp, child[c],
2327 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2328 print_status_config(zhp, cb, vname, child[c], depth + 2,
2329 isspare, vrs);
2330 free(vname);
2331 }
2332 }
2333
2334 /*
2335 * Print the configuration of an exported pool. Iterate over all vdevs in the
2336 * pool, printing out the name and status for each one.
2337 */
2338 static void
2339 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv,
2340 int depth)
2341 {
2342 nvlist_t **child;
2343 uint_t c, children;
2344 vdev_stat_t *vs;
2345 char *type, *vname;
2346
2347 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
2348 if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
2349 strcmp(type, VDEV_TYPE_HOLE) == 0)
2350 return;
2351
2352 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
2353 (uint64_t **)&vs, &c) == 0);
2354
2355 (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name);
2356 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
2357
2358 if (vs->vs_aux != 0) {
2359 (void) printf(" ");
2360
2361 switch (vs->vs_aux) {
2362 case VDEV_AUX_OPEN_FAILED:
2363 (void) printf(gettext("cannot open"));
2364 break;
2365
2366 case VDEV_AUX_BAD_GUID_SUM:
2367 (void) printf(gettext("missing device"));
2368 break;
2369
2370 case VDEV_AUX_NO_REPLICAS:
2371 (void) printf(gettext("insufficient replicas"));
2372 break;
2373
2374 case VDEV_AUX_VERSION_NEWER:
2375 (void) printf(gettext("newer version"));
2376 break;
2377
2378 case VDEV_AUX_UNSUP_FEAT:
2379 (void) printf(gettext("unsupported feature(s)"));
2380 break;
2381
2382 case VDEV_AUX_ERR_EXCEEDED:
2383 (void) printf(gettext("too many errors"));
2384 break;
2385
2386 case VDEV_AUX_ACTIVE:
2387 (void) printf(gettext("currently in use"));
2388 break;
2389
2390 case VDEV_AUX_CHILDREN_OFFLINE:
2391 (void) printf(gettext("all children offline"));
2392 break;
2393
2394 default:
2395 (void) printf(gettext("corrupted data"));
2396 break;
2397 }
2398 }
2399 (void) printf("\n");
2400
2401 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2402 &child, &children) != 0)
2403 return;
2404
2405 for (c = 0; c < children; c++) {
2406 uint64_t is_log = B_FALSE;
2407
2408 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2409 &is_log);
2410 if (is_log)
2411 continue;
2412 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
2413 continue;
2414
2415 vname = zpool_vdev_name(g_zfs, NULL, child[c],
2416 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2417 print_import_config(cb, vname, child[c], depth + 2);
2418 free(vname);
2419 }
2420
2421 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2422 &child, &children) == 0) {
2423 (void) printf(gettext("\tcache\n"));
2424 for (c = 0; c < children; c++) {
2425 vname = zpool_vdev_name(g_zfs, NULL, child[c],
2426 cb->cb_name_flags);
2427 (void) printf("\t %s\n", vname);
2428 free(vname);
2429 }
2430 }
2431
2432 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
2433 &child, &children) == 0) {
2434 (void) printf(gettext("\tspares\n"));
2435 for (c = 0; c < children; c++) {
2436 vname = zpool_vdev_name(g_zfs, NULL, child[c],
2437 cb->cb_name_flags);
2438 (void) printf("\t %s\n", vname);
2439 free(vname);
2440 }
2441 }
2442 }
2443
2444 /*
2445 * Print specialized class vdevs.
2446 *
2447 * These are recorded as top level vdevs in the main pool child array
2448 * but with "is_log" set to 1 or an "alloc_bias" string. We use either
2449 * print_status_config() or print_import_config() to print the top level
2450 * class vdevs then any of their children (eg mirrored slogs) are printed
2451 * recursively - which works because only the top level vdev is marked.
2452 */
2453 static void
2454 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
2455 const char *class)
2456 {
2457 uint_t c, children;
2458 nvlist_t **child;
2459 boolean_t printed = B_FALSE;
2460
2461 assert(zhp != NULL || !cb->cb_verbose);
2462
2463 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
2464 &children) != 0)
2465 return;
2466
2467 for (c = 0; c < children; c++) {
2468 uint64_t is_log = B_FALSE;
2469 char *bias = NULL;
2470 char *type = NULL;
2471
2472 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2473 &is_log);
2474
2475 if (is_log) {
2476 bias = VDEV_ALLOC_CLASS_LOGS;
2477 } else {
2478 (void) nvlist_lookup_string(child[c],
2479 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
2480 (void) nvlist_lookup_string(child[c],
2481 ZPOOL_CONFIG_TYPE, &type);
2482 }
2483
2484 if (bias == NULL || strcmp(bias, class) != 0)
2485 continue;
2486 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
2487 continue;
2488
2489 if (!printed) {
2490 (void) printf("\t%s\t\n", gettext(class));
2491 printed = B_TRUE;
2492 }
2493
2494 char *name = zpool_vdev_name(g_zfs, zhp, child[c],
2495 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
2496 if (cb->cb_print_status)
2497 print_status_config(zhp, cb, name, child[c], 2,
2498 B_FALSE, NULL);
2499 else
2500 print_import_config(cb, name, child[c], 2);
2501 free(name);
2502 }
2503 }
2504
2505 /*
2506 * Display the status for the given pool.
2507 */
2508 static void
2509 show_import(nvlist_t *config)
2510 {
2511 uint64_t pool_state;
2512 vdev_stat_t *vs;
2513 char *name;
2514 uint64_t guid;
2515 uint64_t hostid = 0;
2516 char *msgid;
2517 char *hostname = "unknown";
2518 nvlist_t *nvroot, *nvinfo;
2519 zpool_status_t reason;
2520 zpool_errata_t errata;
2521 const char *health;
2522 uint_t vsc;
2523 char *comment;
2524 status_cbdata_t cb = { 0 };
2525
2526 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
2527 &name) == 0);
2528 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
2529 &guid) == 0);
2530 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2531 &pool_state) == 0);
2532 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2533 &nvroot) == 0);
2534
2535 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
2536 (uint64_t **)&vs, &vsc) == 0);
2537 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2538
2539 reason = zpool_import_status(config, &msgid, &errata);
2540
2541 (void) printf(gettext(" pool: %s\n"), name);
2542 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
2543 (void) printf(gettext(" state: %s"), health);
2544 if (pool_state == POOL_STATE_DESTROYED)
2545 (void) printf(gettext(" (DESTROYED)"));
2546 (void) printf("\n");
2547
2548 switch (reason) {
2549 case ZPOOL_STATUS_MISSING_DEV_R:
2550 case ZPOOL_STATUS_MISSING_DEV_NR:
2551 case ZPOOL_STATUS_BAD_GUID_SUM:
2552 printf_color(ANSI_BOLD, gettext("status: "));
2553 printf_color(ANSI_YELLOW, gettext("One or more devices are "
2554 "missing from the system.\n"));
2555 break;
2556
2557 case ZPOOL_STATUS_CORRUPT_LABEL_R:
2558 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2559 printf_color(ANSI_BOLD, gettext("status: "));
2560 printf_color(ANSI_YELLOW, gettext("One or more devices contains"
2561 " corrupted data.\n"));
2562 break;
2563
2564 case ZPOOL_STATUS_CORRUPT_DATA:
2565 (void) printf(
2566 gettext(" status: The pool data is corrupted.\n"));
2567 break;
2568
2569 case ZPOOL_STATUS_OFFLINE_DEV:
2570 printf_color(ANSI_BOLD, gettext("status: "));
2571 printf_color(ANSI_YELLOW, gettext("One or more devices "
2572 "are offlined.\n"));
2573 break;
2574
2575 case ZPOOL_STATUS_CORRUPT_POOL:
2576 printf_color(ANSI_BOLD, gettext("status: "));
2577 printf_color(ANSI_YELLOW, gettext("The pool metadata is "
2578 "corrupted.\n"));
2579 break;
2580
2581 case ZPOOL_STATUS_VERSION_OLDER:
2582 printf_color(ANSI_BOLD, gettext("status: "));
2583 printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
2584 "a legacy on-disk version.\n"));
2585 break;
2586
2587 case ZPOOL_STATUS_VERSION_NEWER:
2588 printf_color(ANSI_BOLD, gettext("status: "));
2589 printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
2590 "an incompatible version.\n"));
2591 break;
2592
2593 case ZPOOL_STATUS_FEAT_DISABLED:
2594 printf_color(ANSI_BOLD, gettext("status: "));
2595 printf_color(ANSI_YELLOW, gettext("Some supported features are "
2596 "not enabled on the pool.\n"));
2597 break;
2598
2599 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2600 printf_color(ANSI_BOLD, gettext("status: "));
2601 printf_color(ANSI_YELLOW, gettext("The pool uses the following "
2602 "feature(s) not supported on this system:\n"));
2603 color_start(ANSI_YELLOW);
2604 zpool_print_unsup_feat(config);
2605 color_end();
2606 break;
2607
2608 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2609 printf_color(ANSI_BOLD, gettext("status: "));
2610 printf_color(ANSI_YELLOW, gettext("The pool can only be "
2611 "accessed in read-only mode on this system. It\n\tcannot be"
2612 " accessed in read-write mode because it uses the "
2613 "following\n\tfeature(s) not supported on this system:\n"));
2614 color_start(ANSI_YELLOW);
2615 zpool_print_unsup_feat(config);
2616 color_end();
2617 break;
2618
2619 case ZPOOL_STATUS_HOSTID_ACTIVE:
2620 printf_color(ANSI_BOLD, gettext("status: "));
2621 printf_color(ANSI_YELLOW, gettext("The pool is currently "
2622 "imported by another system.\n"));
2623 break;
2624
2625 case ZPOOL_STATUS_HOSTID_REQUIRED:
2626 printf_color(ANSI_BOLD, gettext("status: "));
2627 printf_color(ANSI_YELLOW, gettext("The pool has the "
2628 "multihost property on. It cannot\n\tbe safely imported "
2629 "when the system hostid is not set.\n"));
2630 break;
2631
2632 case ZPOOL_STATUS_HOSTID_MISMATCH:
2633 printf_color(ANSI_BOLD, gettext("status: "));
2634 printf_color(ANSI_YELLOW, gettext("The pool was last accessed "
2635 "by another system.\n"));
2636 break;
2637
2638 case ZPOOL_STATUS_FAULTED_DEV_R:
2639 case ZPOOL_STATUS_FAULTED_DEV_NR:
2640 printf_color(ANSI_BOLD, gettext("status: "));
2641 printf_color(ANSI_YELLOW, gettext("One or more devices are "
2642 "faulted.\n"));
2643 break;
2644
2645 case ZPOOL_STATUS_BAD_LOG:
2646 printf_color(ANSI_BOLD, gettext("status: "));
2647 printf_color(ANSI_YELLOW, gettext("An intent log record cannot "
2648 "be read.\n"));
2649 break;
2650
2651 case ZPOOL_STATUS_RESILVERING:
2652 case ZPOOL_STATUS_REBUILDING:
2653 printf_color(ANSI_BOLD, gettext("status: "));
2654 printf_color(ANSI_YELLOW, gettext("One or more devices were "
2655 "being resilvered.\n"));
2656 break;
2657
2658 case ZPOOL_STATUS_ERRATA:
2659 printf_color(ANSI_BOLD, gettext("status: "));
2660 printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"),
2661 errata);
2662 break;
2663
2664 case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
2665 printf_color(ANSI_BOLD, gettext("status: "));
2666 printf_color(ANSI_YELLOW, gettext("One or more devices are "
2667 "configured to use a non-native block size.\n"
2668 "\tExpect reduced performance.\n"));
2669 break;
2670
2671 default:
2672 /*
2673 * No other status can be seen when importing pools.
2674 */
2675 assert(reason == ZPOOL_STATUS_OK);
2676 }
2677
2678 /*
2679 * Print out an action according to the overall state of the pool.
2680 */
2681 if (vs->vs_state == VDEV_STATE_HEALTHY) {
2682 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
2683 reason == ZPOOL_STATUS_FEAT_DISABLED) {
2684 (void) printf(gettext(" action: The pool can be "
2685 "imported using its name or numeric identifier, "
2686 "though\n\tsome features will not be available "
2687 "without an explicit 'zpool upgrade'.\n"));
2688 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
2689 (void) printf(gettext(" action: The pool can be "
2690 "imported using its name or numeric "
2691 "identifier and\n\tthe '-f' flag.\n"));
2692 } else if (reason == ZPOOL_STATUS_ERRATA) {
2693 switch (errata) {
2694 case ZPOOL_ERRATA_NONE:
2695 break;
2696
2697 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
2698 (void) printf(gettext(" action: The pool can "
2699 "be imported using its name or numeric "
2700 "identifier,\n\thowever there is a compat"
2701 "ibility issue which should be corrected"
2702 "\n\tby running 'zpool scrub'\n"));
2703 break;
2704
2705 case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
2706 (void) printf(gettext(" action: The pool can"
2707 "not be imported with this version of ZFS "
2708 "due to\n\tan active asynchronous destroy. "
2709 "Revert to an earlier version\n\tand "
2710 "allow the destroy to complete before "
2711 "updating.\n"));
2712 break;
2713
2714 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
2715 (void) printf(gettext(" action: Existing "
2716 "encrypted datasets contain an on-disk "
2717 "incompatibility, which\n\tneeds to be "
2718 "corrected. Backup these datasets to new "
2719 "encrypted datasets\n\tand destroy the "
2720 "old ones.\n"));
2721 break;
2722
2723 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
2724 (void) printf(gettext(" action: Existing "
2725 "encrypted snapshots and bookmarks contain "
2726 "an on-disk\n\tincompatibility. This may "
2727 "cause on-disk corruption if they are used"
2728 "\n\twith 'zfs recv'. To correct the "
2729 "issue, enable the bookmark_v2 feature.\n\t"
2730 "No additional action is needed if there "
2731 "are no encrypted snapshots or\n\t"
2732 "bookmarks. If preserving the encrypted "
2733 "snapshots and bookmarks is\n\trequired, "
2734 "use a non-raw send to backup and restore "
2735 "them. Alternately,\n\tthey may be removed"
2736 " to resolve the incompatibility.\n"));
2737 break;
2738 default:
2739 /*
2740 * All errata must contain an action message.
2741 */
2742 assert(0);
2743 }
2744 } else {
2745 (void) printf(gettext(" action: The pool can be "
2746 "imported using its name or numeric "
2747 "identifier.\n"));
2748 }
2749 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
2750 (void) printf(gettext(" action: The pool can be imported "
2751 "despite missing or damaged devices. The\n\tfault "
2752 "tolerance of the pool may be compromised if imported.\n"));
2753 } else {
2754 switch (reason) {
2755 case ZPOOL_STATUS_VERSION_NEWER:
2756 (void) printf(gettext(" action: The pool cannot be "
2757 "imported. Access the pool on a system running "
2758 "newer\n\tsoftware, or recreate the pool from "
2759 "backup.\n"));
2760 break;
2761 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2762 printf_color(ANSI_BOLD, gettext("action: "));
2763 printf_color(ANSI_YELLOW, gettext("The pool cannot be "
2764 "imported. Access the pool on a system that "
2765 "supports\n\tthe required feature(s), or recreate "
2766 "the pool from backup.\n"));
2767 break;
2768 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2769 printf_color(ANSI_BOLD, gettext("action: "));
2770 printf_color(ANSI_YELLOW, gettext("The pool cannot be "
2771 "imported in read-write mode. Import the pool "
2772 "with\n"
2773 "\t\"-o readonly=on\", access the pool on a system "
2774 "that supports the\n\trequired feature(s), or "
2775 "recreate the pool from backup.\n"));
2776 break;
2777 case ZPOOL_STATUS_MISSING_DEV_R:
2778 case ZPOOL_STATUS_MISSING_DEV_NR:
2779 case ZPOOL_STATUS_BAD_GUID_SUM:
2780 (void) printf(gettext(" action: The pool cannot be "
2781 "imported. Attach the missing\n\tdevices and try "
2782 "again.\n"));
2783 break;
2784 case ZPOOL_STATUS_HOSTID_ACTIVE:
2785 VERIFY0(nvlist_lookup_nvlist(config,
2786 ZPOOL_CONFIG_LOAD_INFO, &nvinfo));
2787
2788 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2789 hostname = fnvlist_lookup_string(nvinfo,
2790 ZPOOL_CONFIG_MMP_HOSTNAME);
2791
2792 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2793 hostid = fnvlist_lookup_uint64(nvinfo,
2794 ZPOOL_CONFIG_MMP_HOSTID);
2795
2796 (void) printf(gettext(" action: The pool must be "
2797 "exported from %s (hostid=%lx)\n\tbefore it "
2798 "can be safely imported.\n"), hostname,
2799 (unsigned long) hostid);
2800 break;
2801 case ZPOOL_STATUS_HOSTID_REQUIRED:
2802 (void) printf(gettext(" action: Set a unique system "
2803 "hostid with the zgenhostid(8) command.\n"));
2804 break;
2805 default:
2806 (void) printf(gettext(" action: The pool cannot be "
2807 "imported due to damaged devices or data.\n"));
2808 }
2809 }
2810
2811 /* Print the comment attached to the pool. */
2812 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
2813 (void) printf(gettext("comment: %s\n"), comment);
2814
2815 /*
2816 * If the state is "closed" or "can't open", and the aux state
2817 * is "corrupt data":
2818 */
2819 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
2820 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
2821 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
2822 if (pool_state == POOL_STATE_DESTROYED)
2823 (void) printf(gettext("\tThe pool was destroyed, "
2824 "but can be imported using the '-Df' flags.\n"));
2825 else if (pool_state != POOL_STATE_EXPORTED)
2826 (void) printf(gettext("\tThe pool may be active on "
2827 "another system, but can be imported using\n\t"
2828 "the '-f' flag.\n"));
2829 }
2830
2831 if (msgid != NULL) {
2832 (void) printf(gettext(
2833 " see: https://openzfs.github.io/openzfs-docs/msg/%s\n"),
2834 msgid);
2835 }
2836
2837 (void) printf(gettext(" config:\n\n"));
2838
2839 cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name),
2840 VDEV_NAME_TYPE_ID);
2841 if (cb.cb_namewidth < 10)
2842 cb.cb_namewidth = 10;
2843
2844 print_import_config(&cb, name, nvroot, 0);
2845
2846 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP);
2847 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
2848 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
2849
2850 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
2851 (void) printf(gettext("\n\tAdditional devices are known to "
2852 "be part of this pool, though their\n\texact "
2853 "configuration cannot be determined.\n"));
2854 }
2855 }
2856
2857 static boolean_t
2858 zfs_force_import_required(nvlist_t *config)
2859 {
2860 uint64_t state;
2861 uint64_t hostid = 0;
2862 nvlist_t *nvinfo;
2863
2864 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2865 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
2866
2867 if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid())
2868 return (B_TRUE);
2869
2870 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2871 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) {
2872 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo,
2873 ZPOOL_CONFIG_MMP_STATE);
2874
2875 if (mmp_state != MMP_STATE_INACTIVE)
2876 return (B_TRUE);
2877 }
2878
2879 return (B_FALSE);
2880 }
2881
2882 /*
2883 * Perform the import for the given configuration. This passes the heavy
2884 * lifting off to zpool_import_props(), and then mounts the datasets contained
2885 * within the pool.
2886 */
2887 static int
2888 do_import(nvlist_t *config, const char *newname, const char *mntopts,
2889 nvlist_t *props, int flags)
2890 {
2891 int ret = 0;
2892 zpool_handle_t *zhp;
2893 char *name;
2894 uint64_t version;
2895
2896 name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2897 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2898
2899 if (!SPA_VERSION_IS_SUPPORTED(version)) {
2900 (void) fprintf(stderr, gettext("cannot import '%s': pool "
2901 "is formatted using an unsupported ZFS version\n"), name);
2902 return (1);
2903 } else if (zfs_force_import_required(config) &&
2904 !(flags & ZFS_IMPORT_ANY_HOST)) {
2905 mmp_state_t mmp_state = MMP_STATE_INACTIVE;
2906 nvlist_t *nvinfo;
2907
2908 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2909 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE))
2910 mmp_state = fnvlist_lookup_uint64(nvinfo,
2911 ZPOOL_CONFIG_MMP_STATE);
2912
2913 if (mmp_state == MMP_STATE_ACTIVE) {
2914 char *hostname = "<unknown>";
2915 uint64_t hostid = 0;
2916
2917 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2918 hostname = fnvlist_lookup_string(nvinfo,
2919 ZPOOL_CONFIG_MMP_HOSTNAME);
2920
2921 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2922 hostid = fnvlist_lookup_uint64(nvinfo,
2923 ZPOOL_CONFIG_MMP_HOSTID);
2924
2925 (void) fprintf(stderr, gettext("cannot import '%s': "
2926 "pool is imported on %s (hostid: "
2927 "0x%lx)\nExport the pool on the other system, "
2928 "then run 'zpool import'.\n"),
2929 name, hostname, (unsigned long) hostid);
2930 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2931 (void) fprintf(stderr, gettext("Cannot import '%s': "
2932 "pool has the multihost property on and the\n"
2933 "system's hostid is not set. Set a unique hostid "
2934 "with the zgenhostid(8) command.\n"), name);
2935 } else {
2936 char *hostname = "<unknown>";
2937 uint64_t timestamp = 0;
2938 uint64_t hostid = 0;
2939
2940 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME))
2941 hostname = fnvlist_lookup_string(config,
2942 ZPOOL_CONFIG_HOSTNAME);
2943
2944 if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP))
2945 timestamp = fnvlist_lookup_uint64(config,
2946 ZPOOL_CONFIG_TIMESTAMP);
2947
2948 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID))
2949 hostid = fnvlist_lookup_uint64(config,
2950 ZPOOL_CONFIG_HOSTID);
2951
2952 (void) fprintf(stderr, gettext("cannot import '%s': "
2953 "pool was previously in use from another system.\n"
2954 "Last accessed by %s (hostid=%lx) at %s"
2955 "The pool can be imported, use 'zpool import -f' "
2956 "to import the pool.\n"), name, hostname,
2957 (unsigned long)hostid, ctime((time_t *)&timestamp));
2958 }
2959
2960 return (1);
2961 }
2962
2963 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2964 return (1);
2965
2966 if (newname != NULL)
2967 name = (char *)newname;
2968
2969 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2970 return (1);
2971
2972 /*
2973 * Loading keys is best effort. We don't want to return immediately
2974 * if it fails but we do want to give the error to the caller.
2975 */
2976 if (flags & ZFS_IMPORT_LOAD_KEYS) {
2977 ret = zfs_crypto_attempt_load_keys(g_zfs, name);
2978 if (ret != 0)
2979 ret = 1;
2980 }
2981
2982 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2983 !(flags & ZFS_IMPORT_ONLY) &&
2984 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2985 zpool_close(zhp);
2986 return (1);
2987 }
2988
2989 zpool_close(zhp);
2990 return (ret);
2991 }
2992
2993 typedef struct target_exists_args {
2994 const char *poolname;
2995 uint64_t poolguid;
2996 } target_exists_args_t;
2997
2998 static int
2999 name_or_guid_exists(zpool_handle_t *zhp, void *data)
3000 {
3001 target_exists_args_t *args = data;
3002 nvlist_t *config = zpool_get_config(zhp, NULL);
3003 int found = 0;
3004
3005 if (config == NULL)
3006 return (0);
3007
3008 if (args->poolname != NULL) {
3009 char *pool_name;
3010
3011 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
3012 &pool_name) == 0);
3013 if (strcmp(pool_name, args->poolname) == 0)
3014 found = 1;
3015 } else {
3016 uint64_t pool_guid;
3017
3018 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
3019 &pool_guid) == 0);
3020 if (pool_guid == args->poolguid)
3021 found = 1;
3022 }
3023 zpool_close(zhp);
3024
3025 return (found);
3026 }
3027 /*
3028 * zpool checkpoint <pool>
3029 * checkpoint --discard <pool>
3030 *
3031 * -d Discard the checkpoint from a checkpointed
3032 * --discard pool.
3033 *
3034 * -w Wait for discarding a checkpoint to complete.
3035 * --wait
3036 *
3037 * Checkpoints the specified pool, by taking a "snapshot" of its
3038 * current state. A pool can only have one checkpoint at a time.
3039 */
3040 int
3041 zpool_do_checkpoint(int argc, char **argv)
3042 {
3043 boolean_t discard, wait;
3044 char *pool;
3045 zpool_handle_t *zhp;
3046 int c, err;
3047
3048 struct option long_options[] = {
3049 {"discard", no_argument, NULL, 'd'},
3050 {"wait", no_argument, NULL, 'w'},
3051 {0, 0, 0, 0}
3052 };
3053
3054 discard = B_FALSE;
3055 wait = B_FALSE;
3056 while ((c = getopt_long(argc, argv, ":dw", long_options, NULL)) != -1) {
3057 switch (c) {
3058 case 'd':
3059 discard = B_TRUE;
3060 break;
3061 case 'w':
3062 wait = B_TRUE;
3063 break;
3064 case '?':
3065 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3066 optopt);
3067 usage(B_FALSE);
3068 }
3069 }
3070
3071 if (wait && !discard) {
3072 (void) fprintf(stderr, gettext("--wait only valid when "
3073 "--discard also specified\n"));
3074 usage(B_FALSE);
3075 }
3076
3077 argc -= optind;
3078 argv += optind;
3079
3080 if (argc < 1) {
3081 (void) fprintf(stderr, gettext("missing pool argument\n"));
3082 usage(B_FALSE);
3083 }
3084
3085 if (argc > 1) {
3086 (void) fprintf(stderr, gettext("too many arguments\n"));
3087 usage(B_FALSE);
3088 }
3089
3090 pool = argv[0];
3091
3092 if ((zhp = zpool_open(g_zfs, pool)) == NULL) {
3093 /* As a special case, check for use of '/' in the name */
3094 if (strchr(pool, '/') != NULL)
3095 (void) fprintf(stderr, gettext("'zpool checkpoint' "
3096 "doesn't work on datasets. To save the state "
3097 "of a dataset from a specific point in time "
3098 "please use 'zfs snapshot'\n"));
3099 return (1);
3100 }
3101
3102 if (discard) {
3103 err = (zpool_discard_checkpoint(zhp) != 0);
3104 if (err == 0 && wait)
3105 err = zpool_wait(zhp, ZPOOL_WAIT_CKPT_DISCARD);
3106 } else {
3107 err = (zpool_checkpoint(zhp) != 0);
3108 }
3109
3110 zpool_close(zhp);
3111
3112 return (err);
3113 }
3114
3115 #define CHECKPOINT_OPT 1024
3116
3117 /*
3118 * zpool import [-d dir] [-D]
3119 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
3120 * [-d dir | -c cachefile] [-f] -a
3121 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
3122 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
3123 *
3124 * -c Read pool information from a cachefile instead of searching
3125 * devices.
3126 *
3127 * -d Scan in a specific directory, other than /dev/. More than
3128 * one directory can be specified using multiple '-d' options.
3129 *
3130 * -D Scan for previously destroyed pools or import all or only
3131 * specified destroyed pools.
3132 *
3133 * -R Temporarily import the pool, with all mountpoints relative to
3134 * the given root. The pool will remain exported when the machine
3135 * is rebooted.
3136 *
3137 * -V Import even in the presence of faulted vdevs. This is an
3138 * intentionally undocumented option for testing purposes, and
3139 * treats the pool configuration as complete, leaving any bad
3140 * vdevs in the FAULTED state. In other words, it does verbatim
3141 * import.
3142 *
3143 * -f Force import, even if it appears that the pool is active.
3144 *
3145 * -F Attempt rewind if necessary.
3146 *
3147 * -n See if rewind would work, but don't actually rewind.
3148 *
3149 * -N Import the pool but don't mount datasets.
3150 *
3151 * -T Specify a starting txg to use for import. This option is
3152 * intentionally undocumented option for testing purposes.
3153 *
3154 * -a Import all pools found.
3155 *
3156 * -l Load encryption keys while importing.
3157 *
3158 * -o Set property=value and/or temporary mount options (without '=').
3159 *
3160 * -s Scan using the default search path, the libblkid cache will
3161 * not be consulted.
3162 *
3163 * --rewind-to-checkpoint
3164 * Import the pool and revert back to the checkpoint.
3165 *
3166 * The import command scans for pools to import, and import pools based on pool
3167 * name and GUID. The pool can also be renamed as part of the import process.
3168 */
3169 int
3170 zpool_do_import(int argc, char **argv)
3171 {
3172 char **searchdirs = NULL;
3173 char *env, *envdup = NULL;
3174 int nsearch = 0;
3175 int c;
3176 int err = 0;
3177 nvlist_t *pools = NULL;
3178 boolean_t do_all = B_FALSE;
3179 boolean_t do_destroyed = B_FALSE;
3180 char *mntopts = NULL;
3181 nvpair_t *elem;
3182 nvlist_t *config;
3183 uint64_t searchguid = 0;
3184 char *searchname = NULL;
3185 char *propval;
3186 nvlist_t *found_config;
3187 nvlist_t *policy = NULL;
3188 nvlist_t *props = NULL;
3189 boolean_t first;
3190 int flags = ZFS_IMPORT_NORMAL;
3191 uint32_t rewind_policy = ZPOOL_NO_REWIND;
3192 boolean_t dryrun = B_FALSE;
3193 boolean_t do_rewind = B_FALSE;
3194 boolean_t xtreme_rewind = B_FALSE;
3195 boolean_t do_scan = B_FALSE;
3196 boolean_t pool_exists = B_FALSE;
3197 uint64_t pool_state, txg = -1ULL;
3198 char *cachefile = NULL;
3199 importargs_t idata = { 0 };
3200 char *endptr;
3201
3202 struct option long_options[] = {
3203 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT},
3204 {0, 0, 0, 0}
3205 };
3206
3207 /* check options */
3208 while ((c = getopt_long(argc, argv, ":aCc:d:DEfFlmnNo:R:stT:VX",
3209 long_options, NULL)) != -1) {
3210 switch (c) {
3211 case 'a':
3212 do_all = B_TRUE;
3213 break;
3214 case 'c':
3215 cachefile = optarg;
3216 break;
3217 case 'd':
3218 if (searchdirs == NULL) {
3219 searchdirs = safe_malloc(sizeof (char *));
3220 } else {
3221 char **tmp = safe_malloc((nsearch + 1) *
3222 sizeof (char *));
3223 bcopy(searchdirs, tmp, nsearch *
3224 sizeof (char *));
3225 free(searchdirs);
3226 searchdirs = tmp;
3227 }
3228 searchdirs[nsearch++] = optarg;
3229 break;
3230 case 'D':
3231 do_destroyed = B_TRUE;
3232 break;
3233 case 'f':
3234 flags |= ZFS_IMPORT_ANY_HOST;
3235 break;
3236 case 'F':
3237 do_rewind = B_TRUE;
3238 break;
3239 case 'l':
3240 flags |= ZFS_IMPORT_LOAD_KEYS;
3241 break;
3242 case 'm':
3243 flags |= ZFS_IMPORT_MISSING_LOG;
3244 break;
3245 case 'n':
3246 dryrun = B_TRUE;
3247 break;
3248 case 'N':
3249 flags |= ZFS_IMPORT_ONLY;
3250 break;
3251 case 'o':
3252 if ((propval = strchr(optarg, '=')) != NULL) {
3253 *propval = '\0';
3254 propval++;
3255 if (add_prop_list(optarg, propval,
3256 &props, B_TRUE))
3257 goto error;
3258 } else {
3259 mntopts = optarg;
3260 }
3261 break;
3262 case 'R':
3263 if (add_prop_list(zpool_prop_to_name(
3264 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
3265 goto error;
3266 if (add_prop_list_default(zpool_prop_to_name(
3267 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
3268 goto error;
3269 break;
3270 case 's':
3271 do_scan = B_TRUE;
3272 break;
3273 case 't':
3274 flags |= ZFS_IMPORT_TEMP_NAME;
3275 if (add_prop_list_default(zpool_prop_to_name(
3276 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
3277 goto error;
3278 break;
3279
3280 case 'T':
3281 errno = 0;
3282 txg = strtoull(optarg, &endptr, 0);
3283 if (errno != 0 || *endptr != '\0') {
3284 (void) fprintf(stderr,
3285 gettext("invalid txg value\n"));
3286 usage(B_FALSE);
3287 }
3288 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
3289 break;
3290 case 'V':
3291 flags |= ZFS_IMPORT_VERBATIM;
3292 break;
3293 case 'X':
3294 xtreme_rewind = B_TRUE;
3295 break;
3296 case CHECKPOINT_OPT:
3297 flags |= ZFS_IMPORT_CHECKPOINT;
3298 break;
3299 case ':':
3300 (void) fprintf(stderr, gettext("missing argument for "
3301 "'%c' option\n"), optopt);
3302 usage(B_FALSE);
3303 break;
3304 case '?':
3305 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3306 optopt);
3307 usage(B_FALSE);
3308 }
3309 }
3310
3311 argc -= optind;
3312 argv += optind;
3313
3314 if (cachefile && nsearch != 0) {
3315 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
3316 usage(B_FALSE);
3317 }
3318
3319 if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
3320 (void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
3321 usage(B_FALSE);
3322 }
3323
3324 if ((flags & ZFS_IMPORT_LOAD_KEYS) && !do_all && argc == 0) {
3325 (void) fprintf(stderr, gettext("-l is only meaningful during "
3326 "an import\n"));
3327 usage(B_FALSE);
3328 }
3329
3330 if ((dryrun || xtreme_rewind) && !do_rewind) {
3331 (void) fprintf(stderr,
3332 gettext("-n or -X only meaningful with -F\n"));
3333 usage(B_FALSE);
3334 }
3335 if (dryrun)
3336 rewind_policy = ZPOOL_TRY_REWIND;
3337 else if (do_rewind)
3338 rewind_policy = ZPOOL_DO_REWIND;
3339 if (xtreme_rewind)
3340 rewind_policy |= ZPOOL_EXTREME_REWIND;
3341
3342 /* In the future, we can capture further policy and include it here */
3343 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3344 nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 ||
3345 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
3346 rewind_policy) != 0)
3347 goto error;
3348
3349 /* check argument count */
3350 if (do_all) {
3351 if (argc != 0) {
3352 (void) fprintf(stderr, gettext("too many arguments\n"));
3353 usage(B_FALSE);
3354 }
3355 } else {
3356 if (argc > 2) {
3357 (void) fprintf(stderr, gettext("too many arguments\n"));
3358 usage(B_FALSE);
3359 }
3360 }
3361
3362 /*
3363 * Check for the effective uid. We do this explicitly here because
3364 * otherwise any attempt to discover pools will silently fail.
3365 */
3366 if (argc == 0 && geteuid() != 0) {
3367 (void) fprintf(stderr, gettext("cannot "
3368 "discover pools: permission denied\n"));
3369 if (searchdirs != NULL)
3370 free(searchdirs);
3371
3372 nvlist_free(props);
3373 nvlist_free(policy);
3374 return (1);
3375 }
3376
3377 /*
3378 * Depending on the arguments given, we do one of the following:
3379 *
3380 * <none> Iterate through all pools and display information about
3381 * each one.
3382 *
3383 * -a Iterate through all pools and try to import each one.
3384 *
3385 * <id> Find the pool that corresponds to the given GUID/pool
3386 * name and import that one.
3387 *
3388 * -D Above options applies only to destroyed pools.
3389 */
3390 if (argc != 0) {
3391 char *endptr;
3392
3393 errno = 0;
3394 searchguid = strtoull(argv[0], &endptr, 10);
3395 if (errno != 0 || *endptr != '\0') {
3396 searchname = argv[0];
3397 searchguid = 0;
3398 }
3399 found_config = NULL;
3400
3401 /*
3402 * User specified a name or guid. Ensure it's unique.
3403 */
3404 target_exists_args_t search = {searchname, searchguid};
3405 pool_exists = zpool_iter(g_zfs, name_or_guid_exists, &search);
3406 }
3407
3408 /*
3409 * Check the environment for the preferred search path.
3410 */
3411 if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) {
3412 char *dir;
3413
3414 envdup = strdup(env);
3415
3416 dir = strtok(envdup, ":");
3417 while (dir != NULL) {
3418 if (searchdirs == NULL) {
3419 searchdirs = safe_malloc(sizeof (char *));
3420 } else {
3421 char **tmp = safe_malloc((nsearch + 1) *
3422 sizeof (char *));
3423 bcopy(searchdirs, tmp, nsearch *
3424 sizeof (char *));
3425 free(searchdirs);
3426 searchdirs = tmp;
3427 }
3428 searchdirs[nsearch++] = dir;
3429 dir = strtok(NULL, ":");
3430 }
3431 }
3432
3433 idata.path = searchdirs;
3434 idata.paths = nsearch;
3435 idata.poolname = searchname;
3436 idata.guid = searchguid;
3437 idata.cachefile = cachefile;
3438 idata.scan = do_scan;
3439 idata.policy = policy;
3440
3441 pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
3442
3443 if (pools != NULL && pool_exists &&
3444 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
3445 (void) fprintf(stderr, gettext("cannot import '%s': "
3446 "a pool with that name already exists\n"),
3447 argv[0]);
3448 (void) fprintf(stderr, gettext("use the form '%s "
3449 "<pool | id> <newpool>' to give it a new name\n"),
3450 "zpool import");
3451 err = 1;
3452 } else if (pools == NULL && pool_exists) {
3453 (void) fprintf(stderr, gettext("cannot import '%s': "
3454 "a pool with that name is already created/imported,\n"),
3455 argv[0]);
3456 (void) fprintf(stderr, gettext("and no additional pools "
3457 "with that name were found\n"));
3458 err = 1;
3459 } else if (pools == NULL) {
3460 if (argc != 0) {
3461 (void) fprintf(stderr, gettext("cannot import '%s': "
3462 "no such pool available\n"), argv[0]);
3463 }
3464 err = 1;
3465 }
3466
3467 if (err == 1) {
3468 if (searchdirs != NULL)
3469 free(searchdirs);
3470 if (envdup != NULL)
3471 free(envdup);
3472 nvlist_free(policy);
3473 nvlist_free(pools);
3474 nvlist_free(props);
3475 return (1);
3476 }
3477
3478 /*
3479 * At this point we have a list of import candidate configs. Even if
3480 * we were searching by pool name or guid, we still need to
3481 * post-process the list to deal with pool state and possible
3482 * duplicate names.
3483 */
3484 err = 0;
3485 elem = NULL;
3486 first = B_TRUE;
3487 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
3488
3489 verify(nvpair_value_nvlist(elem, &config) == 0);
3490
3491 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
3492 &pool_state) == 0);
3493 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
3494 continue;
3495 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
3496 continue;
3497
3498 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
3499 policy) == 0);
3500
3501 if (argc == 0) {
3502 if (first)
3503 first = B_FALSE;
3504 else if (!do_all)
3505 (void) printf("\n");
3506
3507 if (do_all) {
3508 err |= do_import(config, NULL, mntopts,
3509 props, flags);
3510 } else {
3511 show_import(config);
3512 }
3513 } else if (searchname != NULL) {
3514 char *name;
3515
3516 /*
3517 * We are searching for a pool based on name.
3518 */
3519 verify(nvlist_lookup_string(config,
3520 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
3521
3522 if (strcmp(name, searchname) == 0) {
3523 if (found_config != NULL) {
3524 (void) fprintf(stderr, gettext(
3525 "cannot import '%s': more than "
3526 "one matching pool\n"), searchname);
3527 (void) fprintf(stderr, gettext(
3528 "import by numeric ID instead\n"));
3529 err = B_TRUE;
3530 }
3531 found_config = config;
3532 }
3533 } else {
3534 uint64_t guid;
3535
3536 /*
3537 * Search for a pool by guid.
3538 */
3539 verify(nvlist_lookup_uint64(config,
3540 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
3541
3542 if (guid == searchguid)
3543 found_config = config;
3544 }
3545 }
3546
3547 /*
3548 * If we were searching for a specific pool, verify that we found a
3549 * pool, and then do the import.
3550 */
3551 if (argc != 0 && err == 0) {
3552 if (found_config == NULL) {
3553 (void) fprintf(stderr, gettext("cannot import '%s': "
3554 "no such pool available\n"), argv[0]);
3555 err = B_TRUE;
3556 } else {
3557 err |= do_import(found_config, argc == 1 ? NULL :
3558 argv[1], mntopts, props, flags);
3559 }
3560 }
3561
3562 /*
3563 * If we were just looking for pools, report an error if none were
3564 * found.
3565 */
3566 if (argc == 0 && first)
3567 (void) fprintf(stderr,
3568 gettext("no pools available to import\n"));
3569
3570 error:
3571 nvlist_free(props);
3572 nvlist_free(pools);
3573 nvlist_free(policy);
3574 if (searchdirs != NULL)
3575 free(searchdirs);
3576 if (envdup != NULL)
3577 free(envdup);
3578
3579 return (err ? 1 : 0);
3580 }
3581
3582 /*
3583 * zpool sync [-f] [pool] ...
3584 *
3585 * -f (undocumented) force uberblock (and config including zpool cache file)
3586 * update.
3587 *
3588 * Sync the specified pool(s).
3589 * Without arguments "zpool sync" will sync all pools.
3590 * This command initiates TXG sync(s) and will return after the TXG(s) commit.
3591 *
3592 */
3593 static int
3594 zpool_do_sync(int argc, char **argv)
3595 {
3596 int ret;
3597 boolean_t force = B_FALSE;
3598
3599 /* check options */
3600 while ((ret = getopt(argc, argv, "f")) != -1) {
3601 switch (ret) {
3602 case 'f':
3603 force = B_TRUE;
3604 break;
3605 case '?':
3606 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3607 optopt);
3608 usage(B_FALSE);
3609 }
3610 }
3611
3612 argc -= optind;
3613 argv += optind;
3614
3615 /* if argc == 0 we will execute zpool_sync_one on all pools */
3616 ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
3617
3618 return (ret);
3619 }
3620
3621 typedef struct iostat_cbdata {
3622 uint64_t cb_flags;
3623 int cb_name_flags;
3624 int cb_namewidth;
3625 int cb_iteration;
3626 char **cb_vdev_names; /* Only show these vdevs */
3627 unsigned int cb_vdev_names_count;
3628 boolean_t cb_verbose;
3629 boolean_t cb_literal;
3630 boolean_t cb_scripted;
3631 zpool_list_t *cb_list;
3632 vdev_cmd_data_list_t *vcdl;
3633 } iostat_cbdata_t;
3634
3635 /* iostat labels */
3636 typedef struct name_and_columns {
3637 const char *name; /* Column name */
3638 unsigned int columns; /* Center name to this number of columns */
3639 } name_and_columns_t;
3640
3641 #define IOSTAT_MAX_LABELS 13 /* Max number of labels on one line */
3642
3643 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] =
3644 {
3645 [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2},
3646 {NULL}},
3647 [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
3648 {"asyncq_wait", 2}, {"scrub", 1}, {"trim", 1}, {NULL}},
3649 [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2},
3650 {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2},
3651 {"trimq_write", 2}, {NULL}},
3652 [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
3653 {"asyncq_wait", 2}, {NULL}},
3654 [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2},
3655 {"async_read", 2}, {"async_write", 2}, {"scrub", 2},
3656 {"trim", 2}, {NULL}},
3657 };
3658
3659 /* Shorthand - if "columns" field not set, default to 1 column */
3660 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] =
3661 {
3662 [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"},
3663 {"write"}, {NULL}},
3664 [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
3665 {"write"}, {"read"}, {"write"}, {"wait"}, {"wait"}, {NULL}},
3666 [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"},
3667 {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"},
3668 {"pend"}, {"activ"}, {NULL}},
3669 [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
3670 {"write"}, {"read"}, {"write"}, {"scrub"}, {"trim"}, {NULL}},
3671 [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"},
3672 {"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}},
3673 };
3674
3675 static const char *histo_to_title[] = {
3676 [IOS_L_HISTO] = "latency",
3677 [IOS_RQ_HISTO] = "req_size",
3678 };
3679
3680 /*
3681 * Return the number of labels in a null-terminated name_and_columns_t
3682 * array.
3683 *
3684 */
3685 static unsigned int
3686 label_array_len(const name_and_columns_t *labels)
3687 {
3688 int i = 0;
3689
3690 while (labels[i].name)
3691 i++;
3692
3693 return (i);
3694 }
3695
3696 /*
3697 * Return the number of strings in a null-terminated string array.
3698 * For example:
3699 *
3700 * const char foo[] = {"bar", "baz", NULL}
3701 *
3702 * returns 2
3703 */
3704 static uint64_t
3705 str_array_len(const char *array[])
3706 {
3707 uint64_t i = 0;
3708 while (array[i])
3709 i++;
3710
3711 return (i);
3712 }
3713
3714
3715 /*
3716 * Return a default column width for default/latency/queue columns. This does
3717 * not include histograms, which have their columns autosized.
3718 */
3719 static unsigned int
3720 default_column_width(iostat_cbdata_t *cb, enum iostat_type type)
3721 {
3722 unsigned long column_width = 5; /* Normal niceprint */
3723 static unsigned long widths[] = {
3724 /*
3725 * Choose some sane default column sizes for printing the
3726 * raw numbers.
3727 */
3728 [IOS_DEFAULT] = 15, /* 1PB capacity */
3729 [IOS_LATENCY] = 10, /* 1B ns = 10sec */
3730 [IOS_QUEUES] = 6, /* 1M queue entries */
3731 [IOS_L_HISTO] = 10, /* 1B ns = 10sec */
3732 [IOS_RQ_HISTO] = 6, /* 1M queue entries */
3733 };
3734
3735 if (cb->cb_literal)
3736 column_width = widths[type];
3737
3738 return (column_width);
3739 }
3740
3741 /*
3742 * Print the column labels, i.e:
3743 *
3744 * capacity operations bandwidth
3745 * alloc free read write read write ...
3746 *
3747 * If force_column_width is set, use it for the column width. If not set, use
3748 * the default column width.
3749 */
3750 static void
3751 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width,
3752 const name_and_columns_t labels[][IOSTAT_MAX_LABELS])
3753 {
3754 int i, idx, s;
3755 int text_start, rw_column_width, spaces_to_end;
3756 uint64_t flags = cb->cb_flags;
3757 uint64_t f;
3758 unsigned int column_width = force_column_width;
3759
3760 /* For each bit set in flags */
3761 for (f = flags; f; f &= ~(1ULL << idx)) {
3762 idx = lowbit64(f) - 1;
3763 if (!force_column_width)
3764 column_width = default_column_width(cb, idx);
3765 /* Print our top labels centered over "read write" label. */
3766 for (i = 0; i < label_array_len(labels[idx]); i++) {
3767 const char *name = labels[idx][i].name;
3768 /*
3769 * We treat labels[][].columns == 0 as shorthand
3770 * for one column. It makes writing out the label
3771 * tables more concise.
3772 */
3773 unsigned int columns = MAX(1, labels[idx][i].columns);
3774 unsigned int slen = strlen(name);
3775
3776 rw_column_width = (column_width * columns) +
3777 (2 * (columns - 1));
3778
3779 text_start = (int)((rw_column_width) / columns -
3780 slen / columns);
3781 if (text_start < 0)
3782 text_start = 0;
3783
3784 printf(" "); /* Two spaces between columns */
3785
3786 /* Space from beginning of column to label */
3787 for (s = 0; s < text_start; s++)
3788 printf(" ");
3789
3790 printf("%s", name);
3791
3792 /* Print space after label to end of column */
3793 spaces_to_end = rw_column_width - text_start - slen;
3794 if (spaces_to_end < 0)
3795 spaces_to_end = 0;
3796
3797 for (s = 0; s < spaces_to_end; s++)
3798 printf(" ");
3799 }
3800 }
3801 }
3802
3803
3804 /*
3805 * print_cmd_columns - Print custom column titles from -c
3806 *
3807 * If the user specified the "zpool status|iostat -c" then print their custom
3808 * column titles in the header. For example, print_cmd_columns() would print
3809 * the " col1 col2" part of this:
3810 *
3811 * $ zpool iostat -vc 'echo col1=val1; echo col2=val2'
3812 * ...
3813 * capacity operations bandwidth
3814 * pool alloc free read write read write col1 col2
3815 * ---------- ----- ----- ----- ----- ----- ----- ---- ----
3816 * mypool 269K 1008M 0 0 107 946
3817 * mirror 269K 1008M 0 0 107 946
3818 * sdb - - 0 0 102 473 val1 val2
3819 * sdc - - 0 0 5 473 val1 val2
3820 * ---------- ----- ----- ----- ----- ----- ----- ---- ----
3821 */
3822 static void
3823 print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes)
3824 {
3825 int i, j;
3826 vdev_cmd_data_t *data = &vcdl->data[0];
3827
3828 if (vcdl->count == 0 || data == NULL)
3829 return;
3830
3831 /*
3832 * Each vdev cmd should have the same column names unless the user did
3833 * something weird with their cmd. Just take the column names from the
3834 * first vdev and assume it works for all of them.
3835 */
3836 for (i = 0; i < vcdl->uniq_cols_cnt; i++) {
3837 printf(" ");
3838 if (use_dashes) {
3839 for (j = 0; j < vcdl->uniq_cols_width[i]; j++)
3840 printf("-");
3841 } else {
3842 printf_color(ANSI_BOLD, "%*s", vcdl->uniq_cols_width[i],
3843 vcdl->uniq_cols[i]);
3844 }
3845 }
3846 }
3847
3848
3849 /*
3850 * Utility function to print out a line of dashes like:
3851 *
3852 * -------------------------------- ----- ----- ----- ----- -----
3853 *
3854 * ...or a dashed named-row line like:
3855 *
3856 * logs - - - - -
3857 *
3858 * @cb: iostat data
3859 *
3860 * @force_column_width If non-zero, use the value as the column width.
3861 * Otherwise use the default column widths.
3862 *
3863 * @name: Print a dashed named-row line starting
3864 * with @name. Otherwise, print a regular
3865 * dashed line.
3866 */
3867 static void
3868 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width,
3869 const char *name)
3870 {
3871 int i;
3872 unsigned int namewidth;
3873 uint64_t flags = cb->cb_flags;
3874 uint64_t f;
3875 int idx;
3876 const name_and_columns_t *labels;
3877 const char *title;
3878
3879
3880 if (cb->cb_flags & IOS_ANYHISTO_M) {
3881 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3882 } else if (cb->cb_vdev_names_count) {
3883 title = "vdev";
3884 } else {
3885 title = "pool";
3886 }
3887
3888 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3889 name ? strlen(name) : 0);
3890
3891
3892 if (name) {
3893 printf("%-*s", namewidth, name);
3894 } else {
3895 for (i = 0; i < namewidth; i++)
3896 (void) printf("-");
3897 }
3898
3899 /* For each bit in flags */
3900 for (f = flags; f; f &= ~(1ULL << idx)) {
3901 unsigned int column_width;
3902 idx = lowbit64(f) - 1;
3903 if (force_column_width)
3904 column_width = force_column_width;
3905 else
3906 column_width = default_column_width(cb, idx);
3907
3908 labels = iostat_bottom_labels[idx];
3909 for (i = 0; i < label_array_len(labels); i++) {
3910 if (name)
3911 printf(" %*s-", column_width - 1, " ");
3912 else
3913 printf(" %.*s", column_width,
3914 "--------------------");
3915 }
3916 }
3917 }
3918
3919
3920 static void
3921 print_iostat_separator_impl(iostat_cbdata_t *cb,
3922 unsigned int force_column_width)
3923 {
3924 print_iostat_dashes(cb, force_column_width, NULL);
3925 }
3926
3927 static void
3928 print_iostat_separator(iostat_cbdata_t *cb)
3929 {
3930 print_iostat_separator_impl(cb, 0);
3931 }
3932
3933 static void
3934 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
3935 const char *histo_vdev_name)
3936 {
3937 unsigned int namewidth;
3938 const char *title;
3939
3940 if (cb->cb_flags & IOS_ANYHISTO_M) {
3941 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3942 } else if (cb->cb_vdev_names_count) {
3943 title = "vdev";
3944 } else {
3945 title = "pool";
3946 }
3947
3948 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3949 histo_vdev_name ? strlen(histo_vdev_name) : 0);
3950
3951 if (histo_vdev_name)
3952 printf("%-*s", namewidth, histo_vdev_name);
3953 else
3954 printf("%*s", namewidth, "");
3955
3956
3957 print_iostat_labels(cb, force_column_width, iostat_top_labels);
3958 printf("\n");
3959
3960 printf("%-*s", namewidth, title);
3961
3962 print_iostat_labels(cb, force_column_width, iostat_bottom_labels);
3963 if (cb->vcdl != NULL)
3964 print_cmd_columns(cb->vcdl, 0);
3965
3966 printf("\n");
3967
3968 print_iostat_separator_impl(cb, force_column_width);
3969
3970 if (cb->vcdl != NULL)
3971 print_cmd_columns(cb->vcdl, 1);
3972
3973 printf("\n");
3974 }
3975
3976 static void
3977 print_iostat_header(iostat_cbdata_t *cb)
3978 {
3979 print_iostat_header_impl(cb, 0, NULL);
3980 }
3981
3982
3983 /*
3984 * Display a single statistic.
3985 */
3986 static void
3987 print_one_stat(uint64_t value, enum zfs_nicenum_format format,
3988 unsigned int column_size, boolean_t scripted)
3989 {
3990 char buf[64];
3991
3992 zfs_nicenum_format(value, buf, sizeof (buf), format);
3993
3994 if (scripted)
3995 printf("\t%s", buf);
3996 else
3997 printf(" %*s", column_size, buf);
3998 }
3999
4000 /*
4001 * Calculate the default vdev stats
4002 *
4003 * Subtract oldvs from newvs, apply a scaling factor, and save the resulting
4004 * stats into calcvs.
4005 */
4006 static void
4007 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs,
4008 vdev_stat_t *calcvs)
4009 {
4010 int i;
4011
4012 memcpy(calcvs, newvs, sizeof (*calcvs));
4013 for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++)
4014 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]);
4015
4016 for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++)
4017 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]);
4018 }
4019
4020 /*
4021 * Internal representation of the extended iostats data.
4022 *
4023 * The extended iostat stats are exported in nvlists as either uint64_t arrays
4024 * or single uint64_t's. We make both look like arrays to make them easier
4025 * to process. In order to make single uint64_t's look like arrays, we set
4026 * __data to the stat data, and then set *data = &__data with count = 1. Then,
4027 * we can just use *data and count.
4028 */
4029 struct stat_array {
4030 uint64_t *data;
4031 uint_t count; /* Number of entries in data[] */
4032 uint64_t __data; /* Only used when data is a single uint64_t */
4033 };
4034
4035 static uint64_t
4036 stat_histo_max(struct stat_array *nva, unsigned int len)
4037 {
4038 uint64_t max = 0;
4039 int i;
4040 for (i = 0; i < len; i++)
4041 max = MAX(max, array64_max(nva[i].data, nva[i].count));
4042
4043 return (max);
4044 }
4045
4046 /*
4047 * Helper function to lookup a uint64_t array or uint64_t value and store its
4048 * data as a stat_array. If the nvpair is a single uint64_t value, then we make
4049 * it look like a one element array to make it easier to process.
4050 */
4051 static int
4052 nvpair64_to_stat_array(nvlist_t *nvl, const char *name,
4053 struct stat_array *nva)
4054 {
4055 nvpair_t *tmp;
4056 int ret;
4057
4058 verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0);
4059 switch (nvpair_type(tmp)) {
4060 case DATA_TYPE_UINT64_ARRAY:
4061 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count);
4062 break;
4063 case DATA_TYPE_UINT64:
4064 ret = nvpair_value_uint64(tmp, &nva->__data);
4065 nva->data = &nva->__data;
4066 nva->count = 1;
4067 break;
4068 default:
4069 /* Not a uint64_t */
4070 ret = EINVAL;
4071 break;
4072 }
4073
4074 return (ret);
4075 }
4076
4077 /*
4078 * Given a list of nvlist names, look up the extended stats in newnv and oldnv,
4079 * subtract them, and return the results in a newly allocated stat_array.
4080 * You must free the returned array after you are done with it with
4081 * free_calc_stats().
4082 *
4083 * Additionally, you can set "oldnv" to NULL if you simply want the newnv
4084 * values.
4085 */
4086 static struct stat_array *
4087 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv,
4088 nvlist_t *newnv)
4089 {
4090 nvlist_t *oldnvx = NULL, *newnvx;
4091 struct stat_array *oldnva, *newnva, *calcnva;
4092 int i, j;
4093 unsigned int alloc_size = (sizeof (struct stat_array)) * len;
4094
4095 /* Extract our extended stats nvlist from the main list */
4096 verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX,
4097 &newnvx) == 0);
4098 if (oldnv) {
4099 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX,
4100 &oldnvx) == 0);
4101 }
4102
4103 newnva = safe_malloc(alloc_size);
4104 oldnva = safe_malloc(alloc_size);
4105 calcnva = safe_malloc(alloc_size);
4106
4107 for (j = 0; j < len; j++) {
4108 verify(nvpair64_to_stat_array(newnvx, names[j],
4109 &newnva[j]) == 0);
4110 calcnva[j].count = newnva[j].count;
4111 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]);
4112 calcnva[j].data = safe_malloc(alloc_size);
4113 memcpy(calcnva[j].data, newnva[j].data, alloc_size);
4114
4115 if (oldnvx) {
4116 verify(nvpair64_to_stat_array(oldnvx, names[j],
4117 &oldnva[j]) == 0);
4118 for (i = 0; i < oldnva[j].count; i++)
4119 calcnva[j].data[i] -= oldnva[j].data[i];
4120 }
4121 }
4122 free(newnva);
4123 free(oldnva);
4124 return (calcnva);
4125 }
4126
4127 static void
4128 free_calc_stats(struct stat_array *nva, unsigned int len)
4129 {
4130 int i;
4131 for (i = 0; i < len; i++)
4132 free(nva[i].data);
4133
4134 free(nva);
4135 }
4136
4137 static void
4138 print_iostat_histo(struct stat_array *nva, unsigned int len,
4139 iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth,
4140 double scale)
4141 {
4142 int i, j;
4143 char buf[6];
4144 uint64_t val;
4145 enum zfs_nicenum_format format;
4146 unsigned int buckets;
4147 unsigned int start_bucket;
4148
4149 if (cb->cb_literal)
4150 format = ZFS_NICENUM_RAW;
4151 else
4152 format = ZFS_NICENUM_1024;
4153
4154 /* All these histos are the same size, so just use nva[0].count */
4155 buckets = nva[0].count;
4156
4157 if (cb->cb_flags & IOS_RQ_HISTO_M) {
4158 /* Start at 512 - req size should never be lower than this */
4159 start_bucket = 9;
4160 } else {
4161 start_bucket = 0;
4162 }
4163
4164 for (j = start_bucket; j < buckets; j++) {
4165 /* Print histogram bucket label */
4166 if (cb->cb_flags & IOS_L_HISTO_M) {
4167 /* Ending range of this bucket */
4168 val = (1UL << (j + 1)) - 1;
4169 zfs_nicetime(val, buf, sizeof (buf));
4170 } else {
4171 /* Request size (starting range of bucket) */
4172 val = (1UL << j);
4173 zfs_nicenum(val, buf, sizeof (buf));
4174 }
4175
4176 if (cb->cb_scripted)
4177 printf("%llu", (u_longlong_t)val);
4178 else
4179 printf("%-*s", namewidth, buf);
4180
4181 /* Print the values on the line */
4182 for (i = 0; i < len; i++) {
4183 print_one_stat(nva[i].data[j] * scale, format,
4184 column_width, cb->cb_scripted);
4185 }
4186 printf("\n");
4187 }
4188 }
4189
4190 static void
4191 print_solid_separator(unsigned int length)
4192 {
4193 while (length--)
4194 printf("-");
4195 printf("\n");
4196 }
4197
4198 static void
4199 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv,
4200 nvlist_t *newnv, double scale, const char *name)
4201 {
4202 unsigned int column_width;
4203 unsigned int namewidth;
4204 unsigned int entire_width;
4205 enum iostat_type type;
4206 struct stat_array *nva;
4207 const char **names;
4208 unsigned int names_len;
4209
4210 /* What type of histo are we? */
4211 type = IOS_HISTO_IDX(cb->cb_flags);
4212
4213 /* Get NULL-terminated array of nvlist names for our histo */
4214 names = vsx_type_to_nvlist[type];
4215 names_len = str_array_len(names); /* num of names */
4216
4217 nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv);
4218
4219 if (cb->cb_literal) {
4220 column_width = MAX(5,
4221 (unsigned int) log10(stat_histo_max(nva, names_len)) + 1);
4222 } else {
4223 column_width = 5;
4224 }
4225
4226 namewidth = MAX(cb->cb_namewidth,
4227 strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]));
4228
4229 /*
4230 * Calculate the entire line width of what we're printing. The
4231 * +2 is for the two spaces between columns:
4232 */
4233 /* read write */
4234 /* ----- ----- */
4235 /* |___| <---------- column_width */
4236 /* */
4237 /* |__________| <--- entire_width */
4238 /* */
4239 entire_width = namewidth + (column_width + 2) *
4240 label_array_len(iostat_bottom_labels[type]);
4241
4242 if (cb->cb_scripted)
4243 printf("%s\n", name);
4244 else
4245 print_iostat_header_impl(cb, column_width, name);
4246
4247 print_iostat_histo(nva, names_len, cb, column_width,
4248 namewidth, scale);
4249
4250 free_calc_stats(nva, names_len);
4251 if (!cb->cb_scripted)
4252 print_solid_separator(entire_width);
4253 }
4254
4255 /*
4256 * Calculate the average latency of a power-of-two latency histogram
4257 */
4258 static uint64_t
4259 single_histo_average(uint64_t *histo, unsigned int buckets)
4260 {
4261 int i;
4262 uint64_t count = 0, total = 0;
4263
4264 for (i = 0; i < buckets; i++) {
4265 /*
4266 * Our buckets are power-of-two latency ranges. Use the
4267 * midpoint latency of each bucket to calculate the average.
4268 * For example:
4269 *
4270 * Bucket Midpoint
4271 * 8ns-15ns: 12ns
4272 * 16ns-31ns: 24ns
4273 * ...
4274 */
4275 if (histo[i] != 0) {
4276 total += histo[i] * (((1UL << i) + ((1UL << i)/2)));
4277 count += histo[i];
4278 }
4279 }
4280
4281 /* Prevent divide by zero */
4282 return (count == 0 ? 0 : total / count);
4283 }
4284
4285 static void
4286 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv,
4287 nvlist_t *newnv)
4288 {
4289 int i;
4290 uint64_t val;
4291 const char *names[] = {
4292 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE,
4293 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
4294 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE,
4295 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
4296 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE,
4297 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
4298 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE,
4299 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
4300 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE,
4301 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
4302 ZPOOL_CONFIG_VDEV_TRIM_PEND_QUEUE,
4303 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE,
4304 };
4305
4306 struct stat_array *nva;
4307
4308 unsigned int column_width = default_column_width(cb, IOS_QUEUES);
4309 enum zfs_nicenum_format format;
4310
4311 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv);
4312
4313 if (cb->cb_literal)
4314 format = ZFS_NICENUM_RAW;
4315 else
4316 format = ZFS_NICENUM_1024;
4317
4318 for (i = 0; i < ARRAY_SIZE(names); i++) {
4319 val = nva[i].data[0];
4320 print_one_stat(val, format, column_width, cb->cb_scripted);
4321 }
4322
4323 free_calc_stats(nva, ARRAY_SIZE(names));
4324 }
4325
4326 static void
4327 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv,
4328 nvlist_t *newnv)
4329 {
4330 int i;
4331 uint64_t val;
4332 const char *names[] = {
4333 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
4334 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
4335 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
4336 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
4337 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
4338 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
4339 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
4340 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
4341 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
4342 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO,
4343 };
4344 struct stat_array *nva;
4345
4346 unsigned int column_width = default_column_width(cb, IOS_LATENCY);
4347 enum zfs_nicenum_format format;
4348
4349 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv);
4350
4351 if (cb->cb_literal)
4352 format = ZFS_NICENUM_RAWTIME;
4353 else
4354 format = ZFS_NICENUM_TIME;
4355
4356 /* Print our avg latencies on the line */
4357 for (i = 0; i < ARRAY_SIZE(names); i++) {
4358 /* Compute average latency for a latency histo */
4359 val = single_histo_average(nva[i].data, nva[i].count);
4360 print_one_stat(val, format, column_width, cb->cb_scripted);
4361 }
4362 free_calc_stats(nva, ARRAY_SIZE(names));
4363 }
4364
4365 /*
4366 * Print default statistics (capacity/operations/bandwidth)
4367 */
4368 static void
4369 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale)
4370 {
4371 unsigned int column_width = default_column_width(cb, IOS_DEFAULT);
4372 enum zfs_nicenum_format format;
4373 char na; /* char to print for "not applicable" values */
4374
4375 if (cb->cb_literal) {
4376 format = ZFS_NICENUM_RAW;
4377 na = '0';
4378 } else {
4379 format = ZFS_NICENUM_1024;
4380 na = '-';
4381 }
4382
4383 /* only toplevel vdevs have capacity stats */
4384 if (vs->vs_space == 0) {
4385 if (cb->cb_scripted)
4386 printf("\t%c\t%c", na, na);
4387 else
4388 printf(" %*c %*c", column_width, na, column_width,
4389 na);
4390 } else {
4391 print_one_stat(vs->vs_alloc, format, column_width,
4392 cb->cb_scripted);
4393 print_one_stat(vs->vs_space - vs->vs_alloc, format,
4394 column_width, cb->cb_scripted);
4395 }
4396
4397 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale),
4398 format, column_width, cb->cb_scripted);
4399 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale),
4400 format, column_width, cb->cb_scripted);
4401 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale),
4402 format, column_width, cb->cb_scripted);
4403 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale),
4404 format, column_width, cb->cb_scripted);
4405 }
4406
4407 static const char *class_name[] = {
4408 VDEV_ALLOC_BIAS_DEDUP,
4409 VDEV_ALLOC_BIAS_SPECIAL,
4410 VDEV_ALLOC_CLASS_LOGS
4411 };
4412
4413 /*
4414 * Print out all the statistics for the given vdev. This can either be the
4415 * toplevel configuration, or called recursively. If 'name' is NULL, then this
4416 * is a verbose output, and we don't want to display the toplevel pool stats.
4417 *
4418 * Returns the number of stat lines printed.
4419 */
4420 static unsigned int
4421 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
4422 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
4423 {
4424 nvlist_t **oldchild, **newchild;
4425 uint_t c, children, oldchildren;
4426 vdev_stat_t *oldvs, *newvs, *calcvs;
4427 vdev_stat_t zerovs = { 0 };
4428 char *vname;
4429 int i;
4430 int ret = 0;
4431 uint64_t tdelta;
4432 double scale;
4433
4434 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
4435 return (ret);
4436
4437 calcvs = safe_malloc(sizeof (*calcvs));
4438
4439 if (oldnv != NULL) {
4440 verify(nvlist_lookup_uint64_array(oldnv,
4441 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
4442 } else {
4443 oldvs = &zerovs;
4444 }
4445
4446 /* Do we only want to see a specific vdev? */
4447 for (i = 0; i < cb->cb_vdev_names_count; i++) {
4448 /* Yes we do. Is this the vdev? */
4449 if (strcmp(name, cb->cb_vdev_names[i]) == 0) {
4450 /*
4451 * This is our vdev. Since it is the only vdev we
4452 * will be displaying, make depth = 0 so that it
4453 * doesn't get indented.
4454 */
4455 depth = 0;
4456 break;
4457 }
4458 }
4459
4460 if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) {
4461 /* Couldn't match the name */
4462 goto children;
4463 }
4464
4465
4466 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
4467 (uint64_t **)&newvs, &c) == 0);
4468
4469 /*
4470 * Print the vdev name unless it's is a histogram. Histograms
4471 * display the vdev name in the header itself.
4472 */
4473 if (!(cb->cb_flags & IOS_ANYHISTO_M)) {
4474 if (cb->cb_scripted) {
4475 printf("%s", name);
4476 } else {
4477 if (strlen(name) + depth > cb->cb_namewidth)
4478 (void) printf("%*s%s", depth, "", name);
4479 else
4480 (void) printf("%*s%s%*s", depth, "", name,
4481 (int)(cb->cb_namewidth - strlen(name) -
4482 depth), "");
4483 }
4484 }
4485
4486 /* Calculate our scaling factor */
4487 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
4488 if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) {
4489 /*
4490 * If we specify printing histograms with no time interval, then
4491 * print the histogram numbers over the entire lifetime of the
4492 * vdev.
4493 */
4494 scale = 1;
4495 } else {
4496 if (tdelta == 0)
4497 scale = 1.0;
4498 else
4499 scale = (double)NANOSEC / tdelta;
4500 }
4501
4502 if (cb->cb_flags & IOS_DEFAULT_M) {
4503 calc_default_iostats(oldvs, newvs, calcvs);
4504 print_iostat_default(calcvs, cb, scale);
4505 }
4506 if (cb->cb_flags & IOS_LATENCY_M)
4507 print_iostat_latency(cb, oldnv, newnv);
4508 if (cb->cb_flags & IOS_QUEUES_M)
4509 print_iostat_queues(cb, oldnv, newnv);
4510 if (cb->cb_flags & IOS_ANYHISTO_M) {
4511 printf("\n");
4512 print_iostat_histos(cb, oldnv, newnv, scale, name);
4513 }
4514
4515 if (cb->vcdl != NULL) {
4516 char *path;
4517 if (nvlist_lookup_string(newnv, ZPOOL_CONFIG_PATH,
4518 &path) == 0) {
4519 printf(" ");
4520 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path);
4521 }
4522 }
4523
4524 if (!(cb->cb_flags & IOS_ANYHISTO_M))
4525 printf("\n");
4526
4527 ret++;
4528
4529 children:
4530
4531 free(calcvs);
4532
4533 if (!cb->cb_verbose)
4534 return (ret);
4535
4536 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
4537 &newchild, &children) != 0)
4538 return (ret);
4539
4540 if (oldnv) {
4541 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
4542 &oldchild, &oldchildren) != 0)
4543 return (ret);
4544
4545 children = MIN(oldchildren, children);
4546 }
4547
4548 /*
4549 * print normal top-level devices
4550 */
4551 for (c = 0; c < children; c++) {
4552 uint64_t ishole = B_FALSE, islog = B_FALSE;
4553
4554 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
4555 &ishole);
4556
4557 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
4558 &islog);
4559
4560 if (ishole || islog)
4561 continue;
4562
4563 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
4564 continue;
4565
4566 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4567 cb->cb_name_flags);
4568 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
4569 newchild[c], cb, depth + 2);
4570 free(vname);
4571 }
4572
4573 /*
4574 * print all other top-level devices
4575 */
4576 for (uint_t n = 0; n < 3; n++) {
4577 boolean_t printed = B_FALSE;
4578
4579 for (c = 0; c < children; c++) {
4580 uint64_t islog = B_FALSE;
4581 char *bias = NULL;
4582 char *type = NULL;
4583
4584 (void) nvlist_lookup_uint64(newchild[c],
4585 ZPOOL_CONFIG_IS_LOG, &islog);
4586 if (islog) {
4587 bias = VDEV_ALLOC_CLASS_LOGS;
4588 } else {
4589 (void) nvlist_lookup_string(newchild[c],
4590 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
4591 (void) nvlist_lookup_string(newchild[c],
4592 ZPOOL_CONFIG_TYPE, &type);
4593 }
4594 if (bias == NULL || strcmp(bias, class_name[n]) != 0)
4595 continue;
4596 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
4597 continue;
4598
4599 if (!printed) {
4600 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) &&
4601 !cb->cb_scripted && !cb->cb_vdev_names) {
4602 print_iostat_dashes(cb, 0,
4603 class_name[n]);
4604 }
4605 printf("\n");
4606 printed = B_TRUE;
4607 }
4608
4609 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4610 cb->cb_name_flags);
4611 ret += print_vdev_stats(zhp, vname, oldnv ?
4612 oldchild[c] : NULL, newchild[c], cb, depth + 2);
4613 free(vname);
4614 }
4615 }
4616
4617 /*
4618 * Include level 2 ARC devices in iostat output
4619 */
4620 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
4621 &newchild, &children) != 0)
4622 return (ret);
4623
4624 if (oldnv) {
4625 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
4626 &oldchild, &oldchildren) != 0)
4627 return (ret);
4628
4629 children = MIN(oldchildren, children);
4630 }
4631
4632 if (children > 0) {
4633 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
4634 !cb->cb_vdev_names) {
4635 print_iostat_dashes(cb, 0, "cache");
4636 }
4637 printf("\n");
4638
4639 for (c = 0; c < children; c++) {
4640 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
4641 cb->cb_name_flags);
4642 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c]
4643 : NULL, newchild[c], cb, depth + 2);
4644 free(vname);
4645 }
4646 }
4647
4648 return (ret);
4649 }
4650
4651 static int
4652 refresh_iostat(zpool_handle_t *zhp, void *data)
4653 {
4654 iostat_cbdata_t *cb = data;
4655 boolean_t missing;
4656
4657 /*
4658 * If the pool has disappeared, remove it from the list and continue.
4659 */
4660 if (zpool_refresh_stats(zhp, &missing) != 0)
4661 return (-1);
4662
4663 if (missing)
4664 pool_list_remove(cb->cb_list, zhp);
4665
4666 return (0);
4667 }
4668
4669 /*
4670 * Callback to print out the iostats for the given pool.
4671 */
4672 static int
4673 print_iostat(zpool_handle_t *zhp, void *data)
4674 {
4675 iostat_cbdata_t *cb = data;
4676 nvlist_t *oldconfig, *newconfig;
4677 nvlist_t *oldnvroot, *newnvroot;
4678 int ret;
4679
4680 newconfig = zpool_get_config(zhp, &oldconfig);
4681
4682 if (cb->cb_iteration == 1)
4683 oldconfig = NULL;
4684
4685 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
4686 &newnvroot) == 0);
4687
4688 if (oldconfig == NULL)
4689 oldnvroot = NULL;
4690 else
4691 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
4692 &oldnvroot) == 0);
4693
4694 ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot,
4695 cb, 0);
4696 if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) &&
4697 !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) {
4698 print_iostat_separator(cb);
4699 if (cb->vcdl != NULL) {
4700 print_cmd_columns(cb->vcdl, 1);
4701 }
4702 printf("\n");
4703 }
4704
4705 return (ret);
4706 }
4707
4708 static int
4709 get_columns(void)
4710 {
4711 struct winsize ws;
4712 int columns = 80;
4713 int error;
4714
4715 if (isatty(STDOUT_FILENO)) {
4716 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
4717 if (error == 0)
4718 columns = ws.ws_col;
4719 } else {
4720 columns = 999;
4721 }
4722
4723 return (columns);
4724 }
4725
4726 /*
4727 * Return the required length of the pool/vdev name column. The minimum
4728 * allowed width and output formatting flags must be provided.
4729 */
4730 static int
4731 get_namewidth(zpool_handle_t *zhp, int min_width, int flags, boolean_t verbose)
4732 {
4733 nvlist_t *config, *nvroot;
4734 int width = min_width;
4735
4736 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
4737 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4738 &nvroot) == 0);
4739 unsigned int poolname_len = strlen(zpool_get_name(zhp));
4740 if (verbose == B_FALSE) {
4741 width = MAX(poolname_len, min_width);
4742 } else {
4743 width = MAX(poolname_len,
4744 max_width(zhp, nvroot, 0, min_width, flags));
4745 }
4746 }
4747
4748 return (width);
4749 }
4750
4751 /*
4752 * Parse the input string, get the 'interval' and 'count' value if there is one.
4753 */
4754 static void
4755 get_interval_count(int *argcp, char **argv, float *iv,
4756 unsigned long *cnt)
4757 {
4758 float interval = 0;
4759 unsigned long count = 0;
4760 int argc = *argcp;
4761
4762 /*
4763 * Determine if the last argument is an integer or a pool name
4764 */
4765 if (argc > 0 && zfs_isnumber(argv[argc - 1])) {
4766 char *end;
4767
4768 errno = 0;
4769 interval = strtof(argv[argc - 1], &end);
4770
4771 if (*end == '\0' && errno == 0) {
4772 if (interval == 0) {
4773 (void) fprintf(stderr, gettext("interval "
4774 "cannot be zero\n"));
4775 usage(B_FALSE);
4776 }
4777 /*
4778 * Ignore the last parameter
4779 */
4780 argc--;
4781 } else {
4782 /*
4783 * If this is not a valid number, just plow on. The
4784 * user will get a more informative error message later
4785 * on.
4786 */
4787 interval = 0;
4788 }
4789 }
4790
4791 /*
4792 * If the last argument is also an integer, then we have both a count
4793 * and an interval.
4794 */
4795 if (argc > 0 && zfs_isnumber(argv[argc - 1])) {
4796 char *end;
4797
4798 errno = 0;
4799 count = interval;
4800 interval = strtof(argv[argc - 1], &end);
4801
4802 if (*end == '\0' && errno == 0) {
4803 if (interval == 0) {
4804 (void) fprintf(stderr, gettext("interval "
4805 "cannot be zero\n"));
4806 usage(B_FALSE);
4807 }
4808
4809 /*
4810 * Ignore the last parameter
4811 */
4812 argc--;
4813 } else {
4814 interval = 0;
4815 }
4816 }
4817
4818 *iv = interval;
4819 *cnt = count;
4820 *argcp = argc;
4821 }
4822
4823 static void
4824 get_timestamp_arg(char c)
4825 {
4826 if (c == 'u')
4827 timestamp_fmt = UDATE;
4828 else if (c == 'd')
4829 timestamp_fmt = DDATE;
4830 else
4831 usage(B_FALSE);
4832 }
4833
4834 /*
4835 * Return stat flags that are supported by all pools by both the module and
4836 * zpool iostat. "*data" should be initialized to all 0xFFs before running.
4837 * It will get ANDed down until only the flags that are supported on all pools
4838 * remain.
4839 */
4840 static int
4841 get_stat_flags_cb(zpool_handle_t *zhp, void *data)
4842 {
4843 uint64_t *mask = data;
4844 nvlist_t *config, *nvroot, *nvx;
4845 uint64_t flags = 0;
4846 int i, j;
4847
4848 config = zpool_get_config(zhp, NULL);
4849 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4850 &nvroot) == 0);
4851
4852 /* Default stats are always supported, but for completeness.. */
4853 if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS))
4854 flags |= IOS_DEFAULT_M;
4855
4856 /* Get our extended stats nvlist from the main list */
4857 if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX,
4858 &nvx) != 0) {
4859 /*
4860 * No extended stats; they're probably running an older
4861 * module. No big deal, we support that too.
4862 */
4863 goto end;
4864 }
4865
4866 /* For each extended stat, make sure all its nvpairs are supported */
4867 for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) {
4868 if (!vsx_type_to_nvlist[j][0])
4869 continue;
4870
4871 /* Start off by assuming the flag is supported, then check */
4872 flags |= (1ULL << j);
4873 for (i = 0; vsx_type_to_nvlist[j][i]; i++) {
4874 if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) {
4875 /* flag isn't supported */
4876 flags = flags & ~(1ULL << j);
4877 break;
4878 }
4879 }
4880 }
4881 end:
4882 *mask = *mask & flags;
4883 return (0);
4884 }
4885
4886 /*
4887 * Return a bitmask of stats that are supported on all pools by both the module
4888 * and zpool iostat.
4889 */
4890 static uint64_t
4891 get_stat_flags(zpool_list_t *list)
4892 {
4893 uint64_t mask = -1;
4894
4895 /*
4896 * get_stat_flags_cb() will lop off bits from "mask" until only the
4897 * flags that are supported on all pools remain.
4898 */
4899 pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
4900 return (mask);
4901 }
4902
4903 /*
4904 * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
4905 */
4906 static int
4907 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
4908 {
4909 iostat_cbdata_t *cb = cb_data;
4910 char *name = NULL;
4911 int ret = 0;
4912
4913 name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
4914
4915 if (strcmp(name, cb->cb_vdev_names[0]) == 0)
4916 ret = 1; /* match */
4917 free(name);
4918
4919 return (ret);
4920 }
4921
4922 /*
4923 * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise.
4924 */
4925 static int
4926 is_vdev(zpool_handle_t *zhp, void *cb_data)
4927 {
4928 return (for_each_vdev(zhp, is_vdev_cb, cb_data));
4929 }
4930
4931 /*
4932 * Check if vdevs are in a pool
4933 *
4934 * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise
4935 * return 0. If pool_name is NULL, then search all pools.
4936 */
4937 static int
4938 are_vdevs_in_pool(int argc, char **argv, char *pool_name,
4939 iostat_cbdata_t *cb)
4940 {
4941 char **tmp_name;
4942 int ret = 0;
4943 int i;
4944 int pool_count = 0;
4945
4946 if ((argc == 0) || !*argv)
4947 return (0);
4948
4949 if (pool_name)
4950 pool_count = 1;
4951
4952 /* Temporarily hijack cb_vdev_names for a second... */
4953 tmp_name = cb->cb_vdev_names;
4954
4955 /* Go though our list of prospective vdev names */
4956 for (i = 0; i < argc; i++) {
4957 cb->cb_vdev_names = argv + i;
4958
4959 /* Is this name a vdev in our pools? */
4960 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL,
4961 is_vdev, cb);
4962 if (!ret) {
4963 /* No match */
4964 break;
4965 }
4966 }
4967
4968 cb->cb_vdev_names = tmp_name;
4969
4970 return (ret);
4971 }
4972
4973 static int
4974 is_pool_cb(zpool_handle_t *zhp, void *data)
4975 {
4976 char *name = data;
4977 if (strcmp(name, zpool_get_name(zhp)) == 0)
4978 return (1);
4979
4980 return (0);
4981 }
4982
4983 /*
4984 * Do we have a pool named *name? If so, return 1, otherwise 0.
4985 */
4986 static int
4987 is_pool(char *name)
4988 {
4989 return (for_each_pool(0, NULL, B_TRUE, NULL, is_pool_cb, name));
4990 }
4991
4992 /* Are all our argv[] strings pool names? If so return 1, 0 otherwise. */
4993 static int
4994 are_all_pools(int argc, char **argv)
4995 {
4996 if ((argc == 0) || !*argv)
4997 return (0);
4998
4999 while (--argc >= 0)
5000 if (!is_pool(argv[argc]))
5001 return (0);
5002
5003 return (1);
5004 }
5005
5006 /*
5007 * Helper function to print out vdev/pool names we can't resolve. Used for an
5008 * error message.
5009 */
5010 static void
5011 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name,
5012 iostat_cbdata_t *cb)
5013 {
5014 int i;
5015 char *name;
5016 char *str;
5017 for (i = 0; i < argc; i++) {
5018 name = argv[i];
5019
5020 if (is_pool(name))
5021 str = gettext("pool");
5022 else if (are_vdevs_in_pool(1, &name, pool_name, cb))
5023 str = gettext("vdev in this pool");
5024 else if (are_vdevs_in_pool(1, &name, NULL, cb))
5025 str = gettext("vdev in another pool");
5026 else
5027 str = gettext("unknown");
5028
5029 fprintf(stderr, "\t%s (%s)\n", name, str);
5030 }
5031 }
5032
5033 /*
5034 * Same as get_interval_count(), but with additional checks to not misinterpret
5035 * guids as interval/count values. Assumes VDEV_NAME_GUID is set in
5036 * cb.cb_name_flags.
5037 */
5038 static void
5039 get_interval_count_filter_guids(int *argc, char **argv, float *interval,
5040 unsigned long *count, iostat_cbdata_t *cb)
5041 {
5042 char **tmpargv = argv;
5043 int argc_for_interval = 0;
5044
5045 /* Is the last arg an interval value? Or a guid? */
5046 if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) {
5047 /*
5048 * The last arg is not a guid, so it's probably an
5049 * interval value.
5050 */
5051 argc_for_interval++;
5052
5053 if (*argc >= 2 &&
5054 !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) {
5055 /*
5056 * The 2nd to last arg is not a guid, so it's probably
5057 * an interval value.
5058 */
5059 argc_for_interval++;
5060 }
5061 }
5062
5063 /* Point to our list of possible intervals */
5064 tmpargv = &argv[*argc - argc_for_interval];
5065
5066 *argc = *argc - argc_for_interval;
5067 get_interval_count(&argc_for_interval, tmpargv,
5068 interval, count);
5069 }
5070
5071 /*
5072 * Floating point sleep(). Allows you to pass in a floating point value for
5073 * seconds.
5074 */
5075 static void
5076 fsleep(float sec)
5077 {
5078 struct timespec req;
5079 req.tv_sec = floor(sec);
5080 req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
5081 nanosleep(&req, NULL);
5082 }
5083
5084 /*
5085 * Terminal height, in rows. Returns -1 if stdout is not connected to a TTY or
5086 * if we were unable to determine its size.
5087 */
5088 static int
5089 terminal_height(void)
5090 {
5091 struct winsize win;
5092
5093 if (isatty(STDOUT_FILENO) == 0)
5094 return (-1);
5095
5096 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 && win.ws_row > 0)
5097 return (win.ws_row);
5098
5099 return (-1);
5100 }
5101
5102 /*
5103 * Run one of the zpool status/iostat -c scripts with the help (-h) option and
5104 * print the result.
5105 *
5106 * name: Short name of the script ('iostat').
5107 * path: Full path to the script ('/usr/local/etc/zfs/zpool.d/iostat');
5108 */
5109 static void
5110 print_zpool_script_help(char *name, char *path)
5111 {
5112 char *argv[] = {path, "-h", NULL};
5113 char **lines = NULL;
5114 int lines_cnt = 0;
5115 int rc;
5116
5117 rc = libzfs_run_process_get_stdout_nopath(path, argv, NULL, &lines,
5118 &lines_cnt);
5119 if (rc != 0 || lines == NULL || lines_cnt <= 0) {
5120 if (lines != NULL)
5121 libzfs_free_str_array(lines, lines_cnt);
5122 return;
5123 }
5124
5125 for (int i = 0; i < lines_cnt; i++)
5126 if (!is_blank_str(lines[i]))
5127 printf(" %-14s %s\n", name, lines[i]);
5128
5129 libzfs_free_str_array(lines, lines_cnt);
5130 }
5131
5132 /*
5133 * Go though the zpool status/iostat -c scripts in the user's path, run their
5134 * help option (-h), and print out the results.
5135 */
5136 static void
5137 print_zpool_dir_scripts(char *dirpath)
5138 {
5139 DIR *dir;
5140 struct dirent *ent;
5141 char fullpath[MAXPATHLEN];
5142 struct stat dir_stat;
5143
5144 if ((dir = opendir(dirpath)) != NULL) {
5145 /* print all the files and directories within directory */
5146 while ((ent = readdir(dir)) != NULL) {
5147 sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
5148
5149 /* Print the scripts */
5150 if (stat(fullpath, &dir_stat) == 0)
5151 if (dir_stat.st_mode & S_IXUSR &&
5152 S_ISREG(dir_stat.st_mode))
5153 print_zpool_script_help(ent->d_name,
5154 fullpath);
5155 }
5156 closedir(dir);
5157 }
5158 }
5159
5160 /*
5161 * Print out help text for all zpool status/iostat -c scripts.
5162 */
5163 static void
5164 print_zpool_script_list(char *subcommand)
5165 {
5166 char *dir, *sp;
5167
5168 printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand);
5169
5170 sp = zpool_get_cmd_search_path();
5171 if (sp == NULL)
5172 return;
5173
5174 dir = strtok(sp, ":");
5175 while (dir != NULL) {
5176 print_zpool_dir_scripts(dir);
5177 dir = strtok(NULL, ":");
5178 }
5179
5180 free(sp);
5181 }
5182
5183 /*
5184 * Set the minimum pool/vdev name column width. The width must be at least 10,
5185 * but may be as large as the column width - 42 so it still fits on one line.
5186 * NOTE: 42 is the width of the default capacity/operations/bandwidth output
5187 */
5188 static int
5189 get_namewidth_iostat(zpool_handle_t *zhp, void *data)
5190 {
5191 iostat_cbdata_t *cb = data;
5192 int width, available_width;
5193
5194 /*
5195 * get_namewidth() returns the maximum width of any name in that column
5196 * for any pool/vdev/device line that will be output.
5197 */
5198 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
5199 cb->cb_verbose);
5200
5201 /*
5202 * The width we are calculating is the width of the header and also the
5203 * padding width for names that are less than maximum width. The stats
5204 * take up 42 characters, so the width available for names is:
5205 */
5206 available_width = get_columns() - 42;
5207
5208 /*
5209 * If the maximum width fits on a screen, then great! Make everything
5210 * line up by justifying all lines to the same width. If that max
5211 * width is larger than what's available, the name plus stats won't fit
5212 * on one line, and justifying to that width would cause every line to
5213 * wrap on the screen. We only want lines with long names to wrap.
5214 * Limit the padding to what won't wrap.
5215 */
5216 if (width > available_width)
5217 width = available_width;
5218
5219 /*
5220 * And regardless of whatever the screen width is (get_columns can
5221 * return 0 if the width is not known or less than 42 for a narrow
5222 * terminal) have the width be a minimum of 10.
5223 */
5224 if (width < 10)
5225 width = 10;
5226
5227 /* Save the calculated width */
5228 cb->cb_namewidth = width;
5229
5230 return (0);
5231 }
5232
5233 /*
5234 * zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name]
5235 * [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]]
5236 * [interval [count]]
5237 *
5238 * -c CMD For each vdev, run command CMD
5239 * -g Display guid for individual vdev name.
5240 * -L Follow links when resolving vdev path name.
5241 * -P Display full path for vdev name.
5242 * -v Display statistics for individual vdevs
5243 * -h Display help
5244 * -p Display values in parsable (exact) format.
5245 * -H Scripted mode. Don't display headers, and separate properties
5246 * by a single tab.
5247 * -l Display average latency
5248 * -q Display queue depths
5249 * -w Display latency histograms
5250 * -r Display request size histogram
5251 * -T Display a timestamp in date(1) or Unix format
5252 * -n Only print headers once
5253 *
5254 * This command can be tricky because we want to be able to deal with pool
5255 * creation/destruction as well as vdev configuration changes. The bulk of this
5256 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
5257 * on pool_list_update() to detect the addition of new pools. Configuration
5258 * changes are all handled within libzfs.
5259 */
5260 int
5261 zpool_do_iostat(int argc, char **argv)
5262 {
5263 int c;
5264 int ret;
5265 int npools;
5266 float interval = 0;
5267 unsigned long count = 0;
5268 int winheight = 24;
5269 zpool_list_t *list;
5270 boolean_t verbose = B_FALSE;
5271 boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
5272 boolean_t queues = B_FALSE, parsable = B_FALSE, scripted = B_FALSE;
5273 boolean_t omit_since_boot = B_FALSE;
5274 boolean_t guid = B_FALSE;
5275 boolean_t follow_links = B_FALSE;
5276 boolean_t full_name = B_FALSE;
5277 boolean_t headers_once = B_FALSE;
5278 iostat_cbdata_t cb = { 0 };
5279 char *cmd = NULL;
5280
5281 /* Used for printing error message */
5282 const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q',
5283 [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'};
5284
5285 uint64_t unsupported_flags;
5286
5287 /* check options */
5288 while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwnH")) != -1) {
5289 switch (c) {
5290 case 'c':
5291 if (cmd != NULL) {
5292 fprintf(stderr,
5293 gettext("Can't set -c flag twice\n"));
5294 exit(1);
5295 }
5296
5297 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
5298 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
5299 fprintf(stderr, gettext(
5300 "Can't run -c, disabled by "
5301 "ZPOOL_SCRIPTS_ENABLED.\n"));
5302 exit(1);
5303 }
5304
5305 if ((getuid() <= 0 || geteuid() <= 0) &&
5306 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
5307 fprintf(stderr, gettext(
5308 "Can't run -c with root privileges "
5309 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
5310 exit(1);
5311 }
5312 cmd = optarg;
5313 verbose = B_TRUE;
5314 break;
5315 case 'g':
5316 guid = B_TRUE;
5317 break;
5318 case 'L':
5319 follow_links = B_TRUE;
5320 break;
5321 case 'P':
5322 full_name = B_TRUE;
5323 break;
5324 case 'T':
5325 get_timestamp_arg(*optarg);
5326 break;
5327 case 'v':
5328 verbose = B_TRUE;
5329 break;
5330 case 'p':
5331 parsable = B_TRUE;
5332 break;
5333 case 'l':
5334 latency = B_TRUE;
5335 break;
5336 case 'q':
5337 queues = B_TRUE;
5338 break;
5339 case 'H':
5340 scripted = B_TRUE;
5341 break;
5342 case 'w':
5343 l_histo = B_TRUE;
5344 break;
5345 case 'r':
5346 rq_histo = B_TRUE;
5347 break;
5348 case 'y':
5349 omit_since_boot = B_TRUE;
5350 break;
5351 case 'n':
5352 headers_once = B_TRUE;
5353 break;
5354 case 'h':
5355 usage(B_FALSE);
5356 break;
5357 case '?':
5358 if (optopt == 'c') {
5359 print_zpool_script_list("iostat");
5360 exit(0);
5361 } else {
5362 fprintf(stderr,
5363 gettext("invalid option '%c'\n"), optopt);
5364 }
5365 usage(B_FALSE);
5366 }
5367 }
5368
5369 argc -= optind;
5370 argv += optind;
5371
5372 cb.cb_literal = parsable;
5373 cb.cb_scripted = scripted;
5374
5375 if (guid)
5376 cb.cb_name_flags |= VDEV_NAME_GUID;
5377 if (follow_links)
5378 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
5379 if (full_name)
5380 cb.cb_name_flags |= VDEV_NAME_PATH;
5381 cb.cb_iteration = 0;
5382 cb.cb_namewidth = 0;
5383 cb.cb_verbose = verbose;
5384
5385 /* Get our interval and count values (if any) */
5386 if (guid) {
5387 get_interval_count_filter_guids(&argc, argv, &interval,
5388 &count, &cb);
5389 } else {
5390 get_interval_count(&argc, argv, &interval, &count);
5391 }
5392
5393 if (argc == 0) {
5394 /* No args, so just print the defaults. */
5395 } else if (are_all_pools(argc, argv)) {
5396 /* All the args are pool names */
5397 } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) {
5398 /* All the args are vdevs */
5399 cb.cb_vdev_names = argv;
5400 cb.cb_vdev_names_count = argc;
5401 argc = 0; /* No pools to process */
5402 } else if (are_all_pools(1, argv)) {
5403 /* The first arg is a pool name */
5404 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) {
5405 /* ...and the rest are vdev names */
5406 cb.cb_vdev_names = argv + 1;
5407 cb.cb_vdev_names_count = argc - 1;
5408 argc = 1; /* One pool to process */
5409 } else {
5410 fprintf(stderr, gettext("Expected either a list of "));
5411 fprintf(stderr, gettext("pools, or list of vdevs in"));
5412 fprintf(stderr, " \"%s\", ", argv[0]);
5413 fprintf(stderr, gettext("but got:\n"));
5414 error_list_unresolved_vdevs(argc - 1, argv + 1,
5415 argv[0], &cb);
5416 fprintf(stderr, "\n");
5417 usage(B_FALSE);
5418 return (1);
5419 }
5420 } else {
5421 /*
5422 * The args don't make sense. The first arg isn't a pool name,
5423 * nor are all the args vdevs.
5424 */
5425 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n"));
5426 fprintf(stderr, "\n");
5427 return (1);
5428 }
5429
5430 if (cb.cb_vdev_names_count != 0) {
5431 /*
5432 * If user specified vdevs, it implies verbose.
5433 */
5434 cb.cb_verbose = B_TRUE;
5435 }
5436
5437 /*
5438 * Construct the list of all interesting pools.
5439 */
5440 ret = 0;
5441 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
5442 return (1);
5443
5444 if (pool_list_count(list) == 0 && argc != 0) {
5445 pool_list_free(list);
5446 return (1);
5447 }
5448
5449 if (pool_list_count(list) == 0 && interval == 0) {
5450 pool_list_free(list);
5451 (void) fprintf(stderr, gettext("no pools available\n"));
5452 return (1);
5453 }
5454
5455 if ((l_histo || rq_histo) && (cmd != NULL || latency || queues)) {
5456 pool_list_free(list);
5457 (void) fprintf(stderr,
5458 gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n"));
5459 usage(B_FALSE);
5460 return (1);
5461 }
5462
5463 if (l_histo && rq_histo) {
5464 pool_list_free(list);
5465 (void) fprintf(stderr,
5466 gettext("Only one of [-r|-w] can be passed at a time\n"));
5467 usage(B_FALSE);
5468 return (1);
5469 }
5470
5471 /*
5472 * Enter the main iostat loop.
5473 */
5474 cb.cb_list = list;
5475
5476 if (l_histo) {
5477 /*
5478 * Histograms tables look out of place when you try to display
5479 * them with the other stats, so make a rule that you can only
5480 * print histograms by themselves.
5481 */
5482 cb.cb_flags = IOS_L_HISTO_M;
5483 } else if (rq_histo) {
5484 cb.cb_flags = IOS_RQ_HISTO_M;
5485 } else {
5486 cb.cb_flags = IOS_DEFAULT_M;
5487 if (latency)
5488 cb.cb_flags |= IOS_LATENCY_M;
5489 if (queues)
5490 cb.cb_flags |= IOS_QUEUES_M;
5491 }
5492
5493 /*
5494 * See if the module supports all the stats we want to display.
5495 */
5496 unsupported_flags = cb.cb_flags & ~get_stat_flags(list);
5497 if (unsupported_flags) {
5498 uint64_t f;
5499 int idx;
5500 fprintf(stderr,
5501 gettext("The loaded zfs module doesn't support:"));
5502
5503 /* for each bit set in unsupported_flags */
5504 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) {
5505 idx = lowbit64(f) - 1;
5506 fprintf(stderr, " -%c", flag_to_arg[idx]);
5507 }
5508
5509 fprintf(stderr, ". Try running a newer module.\n");
5510 pool_list_free(list);
5511
5512 return (1);
5513 }
5514
5515 for (;;) {
5516 if ((npools = pool_list_count(list)) == 0)
5517 (void) fprintf(stderr, gettext("no pools available\n"));
5518 else {
5519 /*
5520 * If this is the first iteration and -y was supplied
5521 * we skip any printing.
5522 */
5523 boolean_t skip = (omit_since_boot &&
5524 cb.cb_iteration == 0);
5525
5526 /*
5527 * Refresh all statistics. This is done as an
5528 * explicit step before calculating the maximum name
5529 * width, so that any * configuration changes are
5530 * properly accounted for.
5531 */
5532 (void) pool_list_iter(list, B_FALSE, refresh_iostat,
5533 &cb);
5534
5535 /*
5536 * Iterate over all pools to determine the maximum width
5537 * for the pool / device name column across all pools.
5538 */
5539 cb.cb_namewidth = 0;
5540 (void) pool_list_iter(list, B_FALSE,
5541 get_namewidth_iostat, &cb);
5542
5543 if (timestamp_fmt != NODATE)
5544 print_timestamp(timestamp_fmt);
5545
5546 if (cmd != NULL && cb.cb_verbose &&
5547 !(cb.cb_flags & IOS_ANYHISTO_M)) {
5548 cb.vcdl = all_pools_for_each_vdev_run(argc,
5549 argv, cmd, g_zfs, cb.cb_vdev_names,
5550 cb.cb_vdev_names_count, cb.cb_name_flags);
5551 } else {
5552 cb.vcdl = NULL;
5553 }
5554
5555
5556 /*
5557 * Check terminal size so we can print headers
5558 * even when terminal window has its height
5559 * changed.
5560 */
5561 winheight = terminal_height();
5562 /*
5563 * Are we connected to TTY? If not, headers_once
5564 * should be true, to avoid breaking scripts.
5565 */
5566 if (winheight < 0)
5567 headers_once = B_TRUE;
5568
5569 /*
5570 * If it's the first time and we're not skipping it,
5571 * or either skip or verbose mode, print the header.
5572 *
5573 * The histogram code explicitly prints its header on
5574 * every vdev, so skip this for histograms.
5575 */
5576 if (((++cb.cb_iteration == 1 && !skip) ||
5577 (skip != verbose) ||
5578 (!headers_once &&
5579 (cb.cb_iteration % winheight) == 0)) &&
5580 (!(cb.cb_flags & IOS_ANYHISTO_M)) &&
5581 !cb.cb_scripted)
5582 print_iostat_header(&cb);
5583
5584 if (skip) {
5585 (void) fsleep(interval);
5586 continue;
5587 }
5588
5589 pool_list_iter(list, B_FALSE, print_iostat, &cb);
5590
5591 /*
5592 * If there's more than one pool, and we're not in
5593 * verbose mode (which prints a separator for us),
5594 * then print a separator.
5595 *
5596 * In addition, if we're printing specific vdevs then
5597 * we also want an ending separator.
5598 */
5599 if (((npools > 1 && !verbose &&
5600 !(cb.cb_flags & IOS_ANYHISTO_M)) ||
5601 (!(cb.cb_flags & IOS_ANYHISTO_M) &&
5602 cb.cb_vdev_names_count)) &&
5603 !cb.cb_scripted) {
5604 print_iostat_separator(&cb);
5605 if (cb.vcdl != NULL)
5606 print_cmd_columns(cb.vcdl, 1);
5607 printf("\n");
5608 }
5609
5610 if (cb.vcdl != NULL)
5611 free_vdev_cmd_data_list(cb.vcdl);
5612
5613 }
5614
5615 /*
5616 * Flush the output so that redirection to a file isn't buffered
5617 * indefinitely.
5618 */
5619 (void) fflush(stdout);
5620
5621 if (interval == 0)
5622 break;
5623
5624 if (count != 0 && --count == 0)
5625 break;
5626
5627 (void) fsleep(interval);
5628 }
5629
5630 pool_list_free(list);
5631
5632 return (ret);
5633 }
5634
5635 typedef struct list_cbdata {
5636 boolean_t cb_verbose;
5637 int cb_name_flags;
5638 int cb_namewidth;
5639 boolean_t cb_scripted;
5640 zprop_list_t *cb_proplist;
5641 boolean_t cb_literal;
5642 } list_cbdata_t;
5643
5644
5645 /*
5646 * Given a list of columns to display, output appropriate headers for each one.
5647 */
5648 static void
5649 print_header(list_cbdata_t *cb)
5650 {
5651 zprop_list_t *pl = cb->cb_proplist;
5652 char headerbuf[ZPOOL_MAXPROPLEN];
5653 const char *header;
5654 boolean_t first = B_TRUE;
5655 boolean_t right_justify;
5656 size_t width = 0;
5657
5658 for (; pl != NULL; pl = pl->pl_next) {
5659 width = pl->pl_width;
5660 if (first && cb->cb_verbose) {
5661 /*
5662 * Reset the width to accommodate the verbose listing
5663 * of devices.
5664 */
5665 width = cb->cb_namewidth;
5666 }
5667
5668 if (!first)
5669 (void) printf(" ");
5670 else
5671 first = B_FALSE;
5672
5673 right_justify = B_FALSE;
5674 if (pl->pl_prop != ZPROP_INVAL) {
5675 header = zpool_prop_column_name(pl->pl_prop);
5676 right_justify = zpool_prop_align_right(pl->pl_prop);
5677 } else {
5678 int i;
5679
5680 for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
5681 headerbuf[i] = toupper(pl->pl_user_prop[i]);
5682 headerbuf[i] = '\0';
5683 header = headerbuf;
5684 }
5685
5686 if (pl->pl_next == NULL && !right_justify)
5687 (void) printf("%s", header);
5688 else if (right_justify)
5689 (void) printf("%*s", (int)width, header);
5690 else
5691 (void) printf("%-*s", (int)width, header);
5692 }
5693
5694 (void) printf("\n");
5695 }
5696
5697 /*
5698 * Given a pool and a list of properties, print out all the properties according
5699 * to the described layout. Used by zpool_do_list().
5700 */
5701 static void
5702 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
5703 {
5704 zprop_list_t *pl = cb->cb_proplist;
5705 boolean_t first = B_TRUE;
5706 char property[ZPOOL_MAXPROPLEN];
5707 char *propstr;
5708 boolean_t right_justify;
5709 size_t width;
5710
5711 for (; pl != NULL; pl = pl->pl_next) {
5712
5713 width = pl->pl_width;
5714 if (first && cb->cb_verbose) {
5715 /*
5716 * Reset the width to accommodate the verbose listing
5717 * of devices.
5718 */
5719 width = cb->cb_namewidth;
5720 }
5721
5722 if (!first) {
5723 if (cb->cb_scripted)
5724 (void) printf("\t");
5725 else
5726 (void) printf(" ");
5727 } else {
5728 first = B_FALSE;
5729 }
5730
5731 right_justify = B_FALSE;
5732 if (pl->pl_prop != ZPROP_INVAL) {
5733 if (zpool_get_prop(zhp, pl->pl_prop, property,
5734 sizeof (property), NULL, cb->cb_literal) != 0)
5735 propstr = "-";
5736 else
5737 propstr = property;
5738
5739 right_justify = zpool_prop_align_right(pl->pl_prop);
5740 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
5741 zpool_prop_unsupported(pl->pl_user_prop)) &&
5742 zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
5743 sizeof (property)) == 0) {
5744 propstr = property;
5745 } else {
5746 propstr = "-";
5747 }
5748
5749
5750 /*
5751 * If this is being called in scripted mode, or if this is the
5752 * last column and it is left-justified, don't include a width
5753 * format specifier.
5754 */
5755 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
5756 (void) printf("%s", propstr);
5757 else if (right_justify)
5758 (void) printf("%*s", (int)width, propstr);
5759 else
5760 (void) printf("%-*s", (int)width, propstr);
5761 }
5762
5763 (void) printf("\n");
5764 }
5765
5766 static void
5767 print_one_column(zpool_prop_t prop, uint64_t value, const char *str,
5768 boolean_t scripted, boolean_t valid, enum zfs_nicenum_format format)
5769 {
5770 char propval[64];
5771 boolean_t fixed;
5772 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
5773
5774 switch (prop) {
5775 case ZPOOL_PROP_EXPANDSZ:
5776 case ZPOOL_PROP_CHECKPOINT:
5777 case ZPOOL_PROP_DEDUPRATIO:
5778 if (value == 0)
5779 (void) strlcpy(propval, "-", sizeof (propval));
5780 else
5781 zfs_nicenum_format(value, propval, sizeof (propval),
5782 format);
5783 break;
5784 case ZPOOL_PROP_FRAGMENTATION:
5785 if (value == ZFS_FRAG_INVALID) {
5786 (void) strlcpy(propval, "-", sizeof (propval));
5787 } else if (format == ZFS_NICENUM_RAW) {
5788 (void) snprintf(propval, sizeof (propval), "%llu",
5789 (unsigned long long)value);
5790 } else {
5791 (void) snprintf(propval, sizeof (propval), "%llu%%",
5792 (unsigned long long)value);
5793 }
5794 break;
5795 case ZPOOL_PROP_CAPACITY:
5796 /* capacity value is in parts-per-10,000 (aka permyriad) */
5797 if (format == ZFS_NICENUM_RAW)
5798 (void) snprintf(propval, sizeof (propval), "%llu",
5799 (unsigned long long)value / 100);
5800 else
5801 (void) snprintf(propval, sizeof (propval),
5802 value < 1000 ? "%1.2f%%" : value < 10000 ?
5803 "%2.1f%%" : "%3.0f%%", value / 100.0);
5804 break;
5805 case ZPOOL_PROP_HEALTH:
5806 width = 8;
5807 snprintf(propval, sizeof (propval), "%-*s", (int)width, str);
5808 break;
5809 default:
5810 zfs_nicenum_format(value, propval, sizeof (propval), format);
5811 }
5812
5813 if (!valid)
5814 (void) strlcpy(propval, "-", sizeof (propval));
5815
5816 if (scripted)
5817 (void) printf("\t%s", propval);
5818 else
5819 (void) printf(" %*s", (int)width, propval);
5820 }
5821
5822 /*
5823 * print static default line per vdev
5824 * not compatible with '-o' <proplist> option
5825 */
5826 static void
5827 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
5828 list_cbdata_t *cb, int depth, boolean_t isspare)
5829 {
5830 nvlist_t **child;
5831 vdev_stat_t *vs;
5832 uint_t c, children;
5833 char *vname;
5834 boolean_t scripted = cb->cb_scripted;
5835 uint64_t islog = B_FALSE;
5836 char *dashes = "%-*s - - - - "
5837 "- - - - -\n";
5838
5839 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
5840 (uint64_t **)&vs, &c) == 0);
5841
5842 if (name != NULL) {
5843 boolean_t toplevel = (vs->vs_space != 0);
5844 uint64_t cap;
5845 enum zfs_nicenum_format format;
5846 const char *state;
5847
5848 if (cb->cb_literal)
5849 format = ZFS_NICENUM_RAW;
5850 else
5851 format = ZFS_NICENUM_1024;
5852
5853 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
5854 return;
5855
5856 if (scripted)
5857 (void) printf("\t%s", name);
5858 else if (strlen(name) + depth > cb->cb_namewidth)
5859 (void) printf("%*s%s", depth, "", name);
5860 else
5861 (void) printf("%*s%s%*s", depth, "", name,
5862 (int)(cb->cb_namewidth - strlen(name) - depth), "");
5863
5864 /*
5865 * Print the properties for the individual vdevs. Some
5866 * properties are only applicable to toplevel vdevs. The
5867 * 'toplevel' boolean value is passed to the print_one_column()
5868 * to indicate that the value is valid.
5869 */
5870 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL, scripted,
5871 toplevel, format);
5872 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
5873 scripted, toplevel, format);
5874 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
5875 NULL, scripted, toplevel, format);
5876 print_one_column(ZPOOL_PROP_CHECKPOINT,
5877 vs->vs_checkpoint_space, NULL, scripted, toplevel, format);
5878 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL,
5879 scripted, B_TRUE, format);
5880 print_one_column(ZPOOL_PROP_FRAGMENTATION,
5881 vs->vs_fragmentation, NULL, scripted,
5882 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
5883 format);
5884 cap = (vs->vs_space == 0) ? 0 :
5885 (vs->vs_alloc * 10000 / vs->vs_space);
5886 print_one_column(ZPOOL_PROP_CAPACITY, cap, NULL,
5887 scripted, toplevel, format);
5888 print_one_column(ZPOOL_PROP_DEDUPRATIO, 0, NULL,
5889 scripted, toplevel, format);
5890 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
5891 if (isspare) {
5892 if (vs->vs_aux == VDEV_AUX_SPARED)
5893 state = "INUSE";
5894 else if (vs->vs_state == VDEV_STATE_HEALTHY)
5895 state = "AVAIL";
5896 }
5897 print_one_column(ZPOOL_PROP_HEALTH, 0, state, scripted,
5898 B_TRUE, format);
5899 (void) printf("\n");
5900 }
5901
5902 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
5903 &child, &children) != 0)
5904 return;
5905
5906 /* list the normal vdevs first */
5907 for (c = 0; c < children; c++) {
5908 uint64_t ishole = B_FALSE;
5909
5910 if (nvlist_lookup_uint64(child[c],
5911 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
5912 continue;
5913
5914 if (nvlist_lookup_uint64(child[c],
5915 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog)
5916 continue;
5917
5918 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
5919 continue;
5920
5921 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5922 cb->cb_name_flags);
5923 print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE);
5924 free(vname);
5925 }
5926
5927 /* list the classes: 'logs', 'dedup', and 'special' */
5928 for (uint_t n = 0; n < 3; n++) {
5929 boolean_t printed = B_FALSE;
5930
5931 for (c = 0; c < children; c++) {
5932 char *bias = NULL;
5933 char *type = NULL;
5934
5935 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
5936 &islog) == 0 && islog) {
5937 bias = VDEV_ALLOC_CLASS_LOGS;
5938 } else {
5939 (void) nvlist_lookup_string(child[c],
5940 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
5941 (void) nvlist_lookup_string(child[c],
5942 ZPOOL_CONFIG_TYPE, &type);
5943 }
5944 if (bias == NULL || strcmp(bias, class_name[n]) != 0)
5945 continue;
5946 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
5947 continue;
5948
5949 if (!printed) {
5950 /* LINTED E_SEC_PRINTF_VAR_FMT */
5951 (void) printf(dashes, cb->cb_namewidth,
5952 class_name[n]);
5953 printed = B_TRUE;
5954 }
5955 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5956 cb->cb_name_flags);
5957 print_list_stats(zhp, vname, child[c], cb, depth + 2,
5958 B_FALSE);
5959 free(vname);
5960 }
5961 }
5962
5963 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
5964 &child, &children) == 0 && children > 0) {
5965 /* LINTED E_SEC_PRINTF_VAR_FMT */
5966 (void) printf(dashes, cb->cb_namewidth, "cache");
5967 for (c = 0; c < children; c++) {
5968 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5969 cb->cb_name_flags);
5970 print_list_stats(zhp, vname, child[c], cb, depth + 2,
5971 B_FALSE);
5972 free(vname);
5973 }
5974 }
5975
5976 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
5977 &children) == 0 && children > 0) {
5978 /* LINTED E_SEC_PRINTF_VAR_FMT */
5979 (void) printf(dashes, cb->cb_namewidth, "spare");
5980 for (c = 0; c < children; c++) {
5981 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5982 cb->cb_name_flags);
5983 print_list_stats(zhp, vname, child[c], cb, depth + 2,
5984 B_TRUE);
5985 free(vname);
5986 }
5987 }
5988 }
5989
5990 /*
5991 * Generic callback function to list a pool.
5992 */
5993 static int
5994 list_callback(zpool_handle_t *zhp, void *data)
5995 {
5996 list_cbdata_t *cbp = data;
5997
5998 print_pool(zhp, cbp);
5999
6000 if (cbp->cb_verbose) {
6001 nvlist_t *config, *nvroot;
6002
6003 config = zpool_get_config(zhp, NULL);
6004 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
6005 &nvroot) == 0);
6006 print_list_stats(zhp, NULL, nvroot, cbp, 0, B_FALSE);
6007 }
6008
6009 return (0);
6010 }
6011
6012 /*
6013 * Set the minimum pool/vdev name column width. The width must be at least 9,
6014 * but may be as large as needed.
6015 */
6016 static int
6017 get_namewidth_list(zpool_handle_t *zhp, void *data)
6018 {
6019 list_cbdata_t *cb = data;
6020 int width;
6021
6022 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags,
6023 cb->cb_verbose);
6024
6025 if (width < 9)
6026 width = 9;
6027
6028 cb->cb_namewidth = width;
6029
6030 return (0);
6031 }
6032
6033 /*
6034 * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
6035 *
6036 * -g Display guid for individual vdev name.
6037 * -H Scripted mode. Don't display headers, and separate properties
6038 * by a single tab.
6039 * -L Follow links when resolving vdev path name.
6040 * -o List of properties to display. Defaults to
6041 * "name,size,allocated,free,expandsize,fragmentation,capacity,"
6042 * "dedupratio,health,altroot"
6043 * -p Display values in parsable (exact) format.
6044 * -P Display full path for vdev name.
6045 * -T Display a timestamp in date(1) or Unix format
6046 *
6047 * List all pools in the system, whether or not they're healthy. Output space
6048 * statistics for each one, as well as health status summary.
6049 */
6050 int
6051 zpool_do_list(int argc, char **argv)
6052 {
6053 int c;
6054 int ret = 0;
6055 list_cbdata_t cb = { 0 };
6056 static char default_props[] =
6057 "name,size,allocated,free,checkpoint,expandsize,fragmentation,"
6058 "capacity,dedupratio,health,altroot";
6059 char *props = default_props;
6060 float interval = 0;
6061 unsigned long count = 0;
6062 zpool_list_t *list;
6063 boolean_t first = B_TRUE;
6064
6065 /* check options */
6066 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) {
6067 switch (c) {
6068 case 'g':
6069 cb.cb_name_flags |= VDEV_NAME_GUID;
6070 break;
6071 case 'H':
6072 cb.cb_scripted = B_TRUE;
6073 break;
6074 case 'L':
6075 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
6076 break;
6077 case 'o':
6078 props = optarg;
6079 break;
6080 case 'P':
6081 cb.cb_name_flags |= VDEV_NAME_PATH;
6082 break;
6083 case 'p':
6084 cb.cb_literal = B_TRUE;
6085 break;
6086 case 'T':
6087 get_timestamp_arg(*optarg);
6088 break;
6089 case 'v':
6090 cb.cb_verbose = B_TRUE;
6091 cb.cb_namewidth = 8; /* 8 until precalc is avail */
6092 break;
6093 case ':':
6094 (void) fprintf(stderr, gettext("missing argument for "
6095 "'%c' option\n"), optopt);
6096 usage(B_FALSE);
6097 break;
6098 case '?':
6099 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6100 optopt);
6101 usage(B_FALSE);
6102 }
6103 }
6104
6105 argc -= optind;
6106 argv += optind;
6107
6108 get_interval_count(&argc, argv, &interval, &count);
6109
6110 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
6111 usage(B_FALSE);
6112
6113 for (;;) {
6114 if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
6115 &ret)) == NULL)
6116 return (1);
6117
6118 if (pool_list_count(list) == 0)
6119 break;
6120
6121 cb.cb_namewidth = 0;
6122 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb);
6123
6124 if (timestamp_fmt != NODATE)
6125 print_timestamp(timestamp_fmt);
6126
6127 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
6128 print_header(&cb);
6129 first = B_FALSE;
6130 }
6131 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
6132
6133 if (interval == 0)
6134 break;
6135
6136 if (count != 0 && --count == 0)
6137 break;
6138
6139 pool_list_free(list);
6140 (void) fsleep(interval);
6141 }
6142
6143 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
6144 (void) printf(gettext("no pools available\n"));
6145 ret = 0;
6146 }
6147
6148 pool_list_free(list);
6149 zprop_free_list(cb.cb_proplist);
6150 return (ret);
6151 }
6152
6153 static int
6154 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
6155 {
6156 boolean_t force = B_FALSE;
6157 boolean_t rebuild = B_FALSE;
6158 boolean_t wait = B_FALSE;
6159 int c;
6160 nvlist_t *nvroot;
6161 char *poolname, *old_disk, *new_disk;
6162 zpool_handle_t *zhp;
6163 nvlist_t *props = NULL;
6164 char *propval;
6165 int ret;
6166
6167 /* check options */
6168 while ((c = getopt(argc, argv, "fo:sw")) != -1) {
6169 switch (c) {
6170 case 'f':
6171 force = B_TRUE;
6172 break;
6173 case 'o':
6174 if ((propval = strchr(optarg, '=')) == NULL) {
6175 (void) fprintf(stderr, gettext("missing "
6176 "'=' for -o option\n"));
6177 usage(B_FALSE);
6178 }
6179 *propval = '\0';
6180 propval++;
6181
6182 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
6183 (add_prop_list(optarg, propval, &props, B_TRUE)))
6184 usage(B_FALSE);
6185 break;
6186 case 's':
6187 rebuild = B_TRUE;
6188 break;
6189 case 'w':
6190 wait = B_TRUE;
6191 break;
6192 case '?':
6193 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6194 optopt);
6195 usage(B_FALSE);
6196 }
6197 }
6198
6199 argc -= optind;
6200 argv += optind;
6201
6202 /* get pool name and check number of arguments */
6203 if (argc < 1) {
6204 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6205 usage(B_FALSE);
6206 }
6207
6208 poolname = argv[0];
6209
6210 if (argc < 2) {
6211 (void) fprintf(stderr,
6212 gettext("missing <device> specification\n"));
6213 usage(B_FALSE);
6214 }
6215
6216 old_disk = argv[1];
6217
6218 if (argc < 3) {
6219 if (!replacing) {
6220 (void) fprintf(stderr,
6221 gettext("missing <new_device> specification\n"));
6222 usage(B_FALSE);
6223 }
6224 new_disk = old_disk;
6225 argc -= 1;
6226 argv += 1;
6227 } else {
6228 new_disk = argv[2];
6229 argc -= 2;
6230 argv += 2;
6231 }
6232
6233 if (argc > 1) {
6234 (void) fprintf(stderr, gettext("too many arguments\n"));
6235 usage(B_FALSE);
6236 }
6237
6238 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
6239 nvlist_free(props);
6240 return (1);
6241 }
6242
6243 if (zpool_get_config(zhp, NULL) == NULL) {
6244 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
6245 poolname);
6246 zpool_close(zhp);
6247 nvlist_free(props);
6248 return (1);
6249 }
6250
6251 /* unless manually specified use "ashift" pool property (if set) */
6252 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
6253 int intval;
6254 zprop_source_t src;
6255 char strval[ZPOOL_MAXPROPLEN];
6256
6257 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
6258 if (src != ZPROP_SRC_DEFAULT) {
6259 (void) sprintf(strval, "%" PRId32, intval);
6260 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
6261 &props, B_TRUE) == 0);
6262 }
6263 }
6264
6265 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE,
6266 argc, argv);
6267 if (nvroot == NULL) {
6268 zpool_close(zhp);
6269 nvlist_free(props);
6270 return (1);
6271 }
6272
6273 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing,
6274 rebuild);
6275
6276 if (ret == 0 && wait)
6277 ret = zpool_wait(zhp,
6278 replacing ? ZPOOL_WAIT_REPLACE : ZPOOL_WAIT_RESILVER);
6279
6280 nvlist_free(props);
6281 nvlist_free(nvroot);
6282 zpool_close(zhp);
6283
6284 return (ret);
6285 }
6286
6287 /*
6288 * zpool replace [-fsw] [-o property=value] <pool> <device> <new_device>
6289 *
6290 * -f Force attach, even if <new_device> appears to be in use.
6291 * -s Use sequential instead of healing reconstruction for resilver.
6292 * -o Set property=value.
6293 * -w Wait for replacing to complete before returning
6294 *
6295 * Replace <device> with <new_device>.
6296 */
6297 /* ARGSUSED */
6298 int
6299 zpool_do_replace(int argc, char **argv)
6300 {
6301 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
6302 }
6303
6304 /*
6305 * zpool attach [-fsw] [-o property=value] <pool> <device> <new_device>
6306 *
6307 * -f Force attach, even if <new_device> appears to be in use.
6308 * -s Use sequential instead of healing reconstruction for resilver.
6309 * -o Set property=value.
6310 * -w Wait for resilvering to complete before returning
6311 *
6312 * Attach <new_device> to the mirror containing <device>. If <device> is not
6313 * part of a mirror, then <device> will be transformed into a mirror of
6314 * <device> and <new_device>. In either case, <new_device> will begin life
6315 * with a DTL of [0, now], and will immediately begin to resilver itself.
6316 */
6317 int
6318 zpool_do_attach(int argc, char **argv)
6319 {
6320 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
6321 }
6322
6323 /*
6324 * zpool detach [-f] <pool> <device>
6325 *
6326 * -f Force detach of <device>, even if DTLs argue against it
6327 * (not supported yet)
6328 *
6329 * Detach a device from a mirror. The operation will be refused if <device>
6330 * is the last device in the mirror, or if the DTLs indicate that this device
6331 * has the only valid copy of some data.
6332 */
6333 /* ARGSUSED */
6334 int
6335 zpool_do_detach(int argc, char **argv)
6336 {
6337 int c;
6338 char *poolname, *path;
6339 zpool_handle_t *zhp;
6340 int ret;
6341
6342 /* check options */
6343 while ((c = getopt(argc, argv, "")) != -1) {
6344 switch (c) {
6345 case '?':
6346 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6347 optopt);
6348 usage(B_FALSE);
6349 }
6350 }
6351
6352 argc -= optind;
6353 argv += optind;
6354
6355 /* get pool name and check number of arguments */
6356 if (argc < 1) {
6357 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6358 usage(B_FALSE);
6359 }
6360
6361 if (argc < 2) {
6362 (void) fprintf(stderr,
6363 gettext("missing <device> specification\n"));
6364 usage(B_FALSE);
6365 }
6366
6367 poolname = argv[0];
6368 path = argv[1];
6369
6370 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6371 return (1);
6372
6373 ret = zpool_vdev_detach(zhp, path);
6374
6375 zpool_close(zhp);
6376
6377 return (ret);
6378 }
6379
6380 /*
6381 * zpool split [-gLnP] [-o prop=val] ...
6382 * [-o mntopt] ...
6383 * [-R altroot] <pool> <newpool> [<device> ...]
6384 *
6385 * -g Display guid for individual vdev name.
6386 * -L Follow links when resolving vdev path name.
6387 * -n Do not split the pool, but display the resulting layout if
6388 * it were to be split.
6389 * -o Set property=value, or set mount options.
6390 * -P Display full path for vdev name.
6391 * -R Mount the split-off pool under an alternate root.
6392 * -l Load encryption keys while importing.
6393 *
6394 * Splits the named pool and gives it the new pool name. Devices to be split
6395 * off may be listed, provided that no more than one device is specified
6396 * per top-level vdev mirror. The newly split pool is left in an exported
6397 * state unless -R is specified.
6398 *
6399 * Restrictions: the top-level of the pool pool must only be made up of
6400 * mirrors; all devices in the pool must be healthy; no device may be
6401 * undergoing a resilvering operation.
6402 */
6403 int
6404 zpool_do_split(int argc, char **argv)
6405 {
6406 char *srcpool, *newpool, *propval;
6407 char *mntopts = NULL;
6408 splitflags_t flags;
6409 int c, ret = 0;
6410 boolean_t loadkeys = B_FALSE;
6411 zpool_handle_t *zhp;
6412 nvlist_t *config, *props = NULL;
6413
6414 flags.dryrun = B_FALSE;
6415 flags.import = B_FALSE;
6416 flags.name_flags = 0;
6417
6418 /* check options */
6419 while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) {
6420 switch (c) {
6421 case 'g':
6422 flags.name_flags |= VDEV_NAME_GUID;
6423 break;
6424 case 'L':
6425 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
6426 break;
6427 case 'R':
6428 flags.import = B_TRUE;
6429 if (add_prop_list(
6430 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
6431 &props, B_TRUE) != 0) {
6432 nvlist_free(props);
6433 usage(B_FALSE);
6434 }
6435 break;
6436 case 'l':
6437 loadkeys = B_TRUE;
6438 break;
6439 case 'n':
6440 flags.dryrun = B_TRUE;
6441 break;
6442 case 'o':
6443 if ((propval = strchr(optarg, '=')) != NULL) {
6444 *propval = '\0';
6445 propval++;
6446 if (add_prop_list(optarg, propval,
6447 &props, B_TRUE) != 0) {
6448 nvlist_free(props);
6449 usage(B_FALSE);
6450 }
6451 } else {
6452 mntopts = optarg;
6453 }
6454 break;
6455 case 'P':
6456 flags.name_flags |= VDEV_NAME_PATH;
6457 break;
6458 case ':':
6459 (void) fprintf(stderr, gettext("missing argument for "
6460 "'%c' option\n"), optopt);
6461 usage(B_FALSE);
6462 break;
6463 case '?':
6464 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6465 optopt);
6466 usage(B_FALSE);
6467 break;
6468 }
6469 }
6470
6471 if (!flags.import && mntopts != NULL) {
6472 (void) fprintf(stderr, gettext("setting mntopts is only "
6473 "valid when importing the pool\n"));
6474 usage(B_FALSE);
6475 }
6476
6477 if (!flags.import && loadkeys) {
6478 (void) fprintf(stderr, gettext("loading keys is only "
6479 "valid when importing the pool\n"));
6480 usage(B_FALSE);
6481 }
6482
6483 argc -= optind;
6484 argv += optind;
6485
6486 if (argc < 1) {
6487 (void) fprintf(stderr, gettext("Missing pool name\n"));
6488 usage(B_FALSE);
6489 }
6490 if (argc < 2) {
6491 (void) fprintf(stderr, gettext("Missing new pool name\n"));
6492 usage(B_FALSE);
6493 }
6494
6495 srcpool = argv[0];
6496 newpool = argv[1];
6497
6498 argc -= 2;
6499 argv += 2;
6500
6501 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) {
6502 nvlist_free(props);
6503 return (1);
6504 }
6505
6506 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
6507 if (config == NULL) {
6508 ret = 1;
6509 } else {
6510 if (flags.dryrun) {
6511 (void) printf(gettext("would create '%s' with the "
6512 "following layout:\n\n"), newpool);
6513 print_vdev_tree(NULL, newpool, config, 0, "",
6514 flags.name_flags);
6515 }
6516 }
6517
6518 zpool_close(zhp);
6519
6520 if (ret != 0 || flags.dryrun || !flags.import) {
6521 nvlist_free(config);
6522 nvlist_free(props);
6523 return (ret);
6524 }
6525
6526 /*
6527 * The split was successful. Now we need to open the new
6528 * pool and import it.
6529 */
6530 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) {
6531 nvlist_free(config);
6532 nvlist_free(props);
6533 return (1);
6534 }
6535
6536 if (loadkeys) {
6537 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool);
6538 if (ret != 0)
6539 ret = 1;
6540 }
6541
6542 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
6543 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
6544 ret = 1;
6545 (void) fprintf(stderr, gettext("Split was successful, but "
6546 "the datasets could not all be mounted\n"));
6547 (void) fprintf(stderr, gettext("Try doing '%s' with a "
6548 "different altroot\n"), "zpool import");
6549 }
6550 zpool_close(zhp);
6551 nvlist_free(config);
6552 nvlist_free(props);
6553
6554 return (ret);
6555 }
6556
6557
6558
6559 /*
6560 * zpool online <pool> <device> ...
6561 */
6562 int
6563 zpool_do_online(int argc, char **argv)
6564 {
6565 int c, i;
6566 char *poolname;
6567 zpool_handle_t *zhp;
6568 int ret = 0;
6569 vdev_state_t newstate;
6570 int flags = 0;
6571
6572 /* check options */
6573 while ((c = getopt(argc, argv, "e")) != -1) {
6574 switch (c) {
6575 case 'e':
6576 flags |= ZFS_ONLINE_EXPAND;
6577 break;
6578 case '?':
6579 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6580 optopt);
6581 usage(B_FALSE);
6582 }
6583 }
6584
6585 argc -= optind;
6586 argv += optind;
6587
6588 /* get pool name and check number of arguments */
6589 if (argc < 1) {
6590 (void) fprintf(stderr, gettext("missing pool name\n"));
6591 usage(B_FALSE);
6592 }
6593 if (argc < 2) {
6594 (void) fprintf(stderr, gettext("missing device name\n"));
6595 usage(B_FALSE);
6596 }
6597
6598 poolname = argv[0];
6599
6600 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6601 return (1);
6602
6603 for (i = 1; i < argc; i++) {
6604 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
6605 if (newstate != VDEV_STATE_HEALTHY) {
6606 (void) printf(gettext("warning: device '%s' "
6607 "onlined, but remains in faulted state\n"),
6608 argv[i]);
6609 if (newstate == VDEV_STATE_FAULTED)
6610 (void) printf(gettext("use 'zpool "
6611 "clear' to restore a faulted "
6612 "device\n"));
6613 else
6614 (void) printf(gettext("use 'zpool "
6615 "replace' to replace devices "
6616 "that are no longer present\n"));
6617 }
6618 } else {
6619 ret = 1;
6620 }
6621 }
6622
6623 zpool_close(zhp);
6624
6625 return (ret);
6626 }
6627
6628 /*
6629 * zpool offline [-ft] <pool> <device> ...
6630 *
6631 * -f Force the device into a faulted state.
6632 *
6633 * -t Only take the device off-line temporarily. The offline/faulted
6634 * state will not be persistent across reboots.
6635 */
6636 /* ARGSUSED */
6637 int
6638 zpool_do_offline(int argc, char **argv)
6639 {
6640 int c, i;
6641 char *poolname;
6642 zpool_handle_t *zhp;
6643 int ret = 0;
6644 boolean_t istmp = B_FALSE;
6645 boolean_t fault = B_FALSE;
6646
6647 /* check options */
6648 while ((c = getopt(argc, argv, "ft")) != -1) {
6649 switch (c) {
6650 case 'f':
6651 fault = B_TRUE;
6652 break;
6653 case 't':
6654 istmp = B_TRUE;
6655 break;
6656 case '?':
6657 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6658 optopt);
6659 usage(B_FALSE);
6660 }
6661 }
6662
6663 argc -= optind;
6664 argv += optind;
6665
6666 /* get pool name and check number of arguments */
6667 if (argc < 1) {
6668 (void) fprintf(stderr, gettext("missing pool name\n"));
6669 usage(B_FALSE);
6670 }
6671 if (argc < 2) {
6672 (void) fprintf(stderr, gettext("missing device name\n"));
6673 usage(B_FALSE);
6674 }
6675
6676 poolname = argv[0];
6677
6678 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6679 return (1);
6680
6681 for (i = 1; i < argc; i++) {
6682 if (fault) {
6683 uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
6684 vdev_aux_t aux;
6685 if (istmp == B_FALSE) {
6686 /* Force the fault to persist across imports */
6687 aux = VDEV_AUX_EXTERNAL_PERSIST;
6688 } else {
6689 aux = VDEV_AUX_EXTERNAL;
6690 }
6691
6692 if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0)
6693 ret = 1;
6694 } else {
6695 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
6696 ret = 1;
6697 }
6698 }
6699
6700 zpool_close(zhp);
6701
6702 return (ret);
6703 }
6704
6705 /*
6706 * zpool clear <pool> [device]
6707 *
6708 * Clear all errors associated with a pool or a particular device.
6709 */
6710 int
6711 zpool_do_clear(int argc, char **argv)
6712 {
6713 int c;
6714 int ret = 0;
6715 boolean_t dryrun = B_FALSE;
6716 boolean_t do_rewind = B_FALSE;
6717 boolean_t xtreme_rewind = B_FALSE;
6718 uint32_t rewind_policy = ZPOOL_NO_REWIND;
6719 nvlist_t *policy = NULL;
6720 zpool_handle_t *zhp;
6721 char *pool, *device;
6722
6723 /* check options */
6724 while ((c = getopt(argc, argv, "FnX")) != -1) {
6725 switch (c) {
6726 case 'F':
6727 do_rewind = B_TRUE;
6728 break;
6729 case 'n':
6730 dryrun = B_TRUE;
6731 break;
6732 case 'X':
6733 xtreme_rewind = B_TRUE;
6734 break;
6735 case '?':
6736 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6737 optopt);
6738 usage(B_FALSE);
6739 }
6740 }
6741
6742 argc -= optind;
6743 argv += optind;
6744
6745 if (argc < 1) {
6746 (void) fprintf(stderr, gettext("missing pool name\n"));
6747 usage(B_FALSE);
6748 }
6749
6750 if (argc > 2) {
6751 (void) fprintf(stderr, gettext("too many arguments\n"));
6752 usage(B_FALSE);
6753 }
6754
6755 if ((dryrun || xtreme_rewind) && !do_rewind) {
6756 (void) fprintf(stderr,
6757 gettext("-n or -X only meaningful with -F\n"));
6758 usage(B_FALSE);
6759 }
6760 if (dryrun)
6761 rewind_policy = ZPOOL_TRY_REWIND;
6762 else if (do_rewind)
6763 rewind_policy = ZPOOL_DO_REWIND;
6764 if (xtreme_rewind)
6765 rewind_policy |= ZPOOL_EXTREME_REWIND;
6766
6767 /* In future, further rewind policy choices can be passed along here */
6768 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
6769 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
6770 rewind_policy) != 0) {
6771 return (1);
6772 }
6773
6774 pool = argv[0];
6775 device = argc == 2 ? argv[1] : NULL;
6776
6777 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
6778 nvlist_free(policy);
6779 return (1);
6780 }
6781
6782 if (zpool_clear(zhp, device, policy) != 0)
6783 ret = 1;
6784
6785 zpool_close(zhp);
6786
6787 nvlist_free(policy);
6788
6789 return (ret);
6790 }
6791
6792 /*
6793 * zpool reguid <pool>
6794 */
6795 int
6796 zpool_do_reguid(int argc, char **argv)
6797 {
6798 int c;
6799 char *poolname;
6800 zpool_handle_t *zhp;
6801 int ret = 0;
6802
6803 /* check options */
6804 while ((c = getopt(argc, argv, "")) != -1) {
6805 switch (c) {
6806 case '?':
6807 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6808 optopt);
6809 usage(B_FALSE);
6810 }
6811 }
6812
6813 argc -= optind;
6814 argv += optind;
6815
6816 /* get pool name and check number of arguments */
6817 if (argc < 1) {
6818 (void) fprintf(stderr, gettext("missing pool name\n"));
6819 usage(B_FALSE);
6820 }
6821
6822 if (argc > 1) {
6823 (void) fprintf(stderr, gettext("too many arguments\n"));
6824 usage(B_FALSE);
6825 }
6826
6827 poolname = argv[0];
6828 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
6829 return (1);
6830
6831 ret = zpool_reguid(zhp);
6832
6833 zpool_close(zhp);
6834 return (ret);
6835 }
6836
6837
6838 /*
6839 * zpool reopen <pool>
6840 *
6841 * Reopen the pool so that the kernel can update the sizes of all vdevs.
6842 */
6843 int
6844 zpool_do_reopen(int argc, char **argv)
6845 {
6846 int c;
6847 int ret = 0;
6848 boolean_t scrub_restart = B_TRUE;
6849
6850 /* check options */
6851 while ((c = getopt(argc, argv, "n")) != -1) {
6852 switch (c) {
6853 case 'n':
6854 scrub_restart = B_FALSE;
6855 break;
6856 case '?':
6857 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6858 optopt);
6859 usage(B_FALSE);
6860 }
6861 }
6862
6863 argc -= optind;
6864 argv += optind;
6865
6866 /* if argc == 0 we will execute zpool_reopen_one on all pools */
6867 ret = for_each_pool(argc, argv, B_TRUE, NULL, zpool_reopen_one,
6868 &scrub_restart);
6869
6870 return (ret);
6871 }
6872
6873 typedef struct scrub_cbdata {
6874 int cb_type;
6875 pool_scrub_cmd_t cb_scrub_cmd;
6876 } scrub_cbdata_t;
6877
6878 static boolean_t
6879 zpool_has_checkpoint(zpool_handle_t *zhp)
6880 {
6881 nvlist_t *config, *nvroot;
6882
6883 config = zpool_get_config(zhp, NULL);
6884
6885 if (config != NULL) {
6886 pool_checkpoint_stat_t *pcs = NULL;
6887 uint_t c;
6888
6889 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
6890 (void) nvlist_lookup_uint64_array(nvroot,
6891 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
6892
6893 if (pcs == NULL || pcs->pcs_state == CS_NONE)
6894 return (B_FALSE);
6895
6896 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS ||
6897 pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
6898 return (B_TRUE);
6899 }
6900
6901 return (B_FALSE);
6902 }
6903
6904 static int
6905 scrub_callback(zpool_handle_t *zhp, void *data)
6906 {
6907 scrub_cbdata_t *cb = data;
6908 int err;
6909
6910 /*
6911 * Ignore faulted pools.
6912 */
6913 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
6914 (void) fprintf(stderr, gettext("cannot scan '%s': pool is "
6915 "currently unavailable\n"), zpool_get_name(zhp));
6916 return (1);
6917 }
6918
6919 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
6920
6921 if (err == 0 && zpool_has_checkpoint(zhp) &&
6922 cb->cb_type == POOL_SCAN_SCRUB) {
6923 (void) printf(gettext("warning: will not scrub state that "
6924 "belongs to the checkpoint of pool '%s'\n"),
6925 zpool_get_name(zhp));
6926 }
6927
6928 return (err != 0);
6929 }
6930
6931 static int
6932 wait_callback(zpool_handle_t *zhp, void *data)
6933 {
6934 zpool_wait_activity_t *act = data;
6935 return (zpool_wait(zhp, *act));
6936 }
6937
6938 /*
6939 * zpool scrub [-s | -p] [-w] <pool> ...
6940 *
6941 * -s Stop. Stops any in-progress scrub.
6942 * -p Pause. Pause in-progress scrub.
6943 * -w Wait. Blocks until scrub has completed.
6944 */
6945 int
6946 zpool_do_scrub(int argc, char **argv)
6947 {
6948 int c;
6949 scrub_cbdata_t cb;
6950 boolean_t wait = B_FALSE;
6951 int error;
6952
6953 cb.cb_type = POOL_SCAN_SCRUB;
6954 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
6955
6956 /* check options */
6957 while ((c = getopt(argc, argv, "spw")) != -1) {
6958 switch (c) {
6959 case 's':
6960 cb.cb_type = POOL_SCAN_NONE;
6961 break;
6962 case 'p':
6963 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
6964 break;
6965 case 'w':
6966 wait = B_TRUE;
6967 break;
6968 case '?':
6969 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6970 optopt);
6971 usage(B_FALSE);
6972 }
6973 }
6974
6975 if (cb.cb_type == POOL_SCAN_NONE &&
6976 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
6977 (void) fprintf(stderr, gettext("invalid option combination: "
6978 "-s and -p are mutually exclusive\n"));
6979 usage(B_FALSE);
6980 }
6981
6982 if (wait && (cb.cb_type == POOL_SCAN_NONE ||
6983 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE)) {
6984 (void) fprintf(stderr, gettext("invalid option combination: "
6985 "-w cannot be used with -p or -s\n"));
6986 usage(B_FALSE);
6987 }
6988
6989 argc -= optind;
6990 argv += optind;
6991
6992 if (argc < 1) {
6993 (void) fprintf(stderr, gettext("missing pool name argument\n"));
6994 usage(B_FALSE);
6995 }
6996
6997 error = for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb);
6998
6999 if (wait && !error) {
7000 zpool_wait_activity_t act = ZPOOL_WAIT_SCRUB;
7001 error = for_each_pool(argc, argv, B_TRUE, NULL, wait_callback,
7002 &act);
7003 }
7004
7005 return (error);
7006 }
7007
7008 /*
7009 * zpool resilver <pool> ...
7010 *
7011 * Restarts any in-progress resilver
7012 */
7013 int
7014 zpool_do_resilver(int argc, char **argv)
7015 {
7016 int c;
7017 scrub_cbdata_t cb;
7018
7019 cb.cb_type = POOL_SCAN_RESILVER;
7020 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
7021
7022 /* check options */
7023 while ((c = getopt(argc, argv, "")) != -1) {
7024 switch (c) {
7025 case '?':
7026 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7027 optopt);
7028 usage(B_FALSE);
7029 }
7030 }
7031
7032 argc -= optind;
7033 argv += optind;
7034
7035 if (argc < 1) {
7036 (void) fprintf(stderr, gettext("missing pool name argument\n"));
7037 usage(B_FALSE);
7038 }
7039
7040 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
7041 }
7042
7043 /*
7044 * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...]
7045 *
7046 * -c Cancel. Ends any in-progress trim.
7047 * -d Secure trim. Requires kernel and device support.
7048 * -r <rate> Sets the TRIM rate in bytes (per second). Supports
7049 * adding a multiplier suffix such as 'k' or 'm'.
7050 * -s Suspend. TRIM can then be restarted with no flags.
7051 * -w Wait. Blocks until trimming has completed.
7052 */
7053 int
7054 zpool_do_trim(int argc, char **argv)
7055 {
7056 struct option long_options[] = {
7057 {"cancel", no_argument, NULL, 'c'},
7058 {"secure", no_argument, NULL, 'd'},
7059 {"rate", required_argument, NULL, 'r'},
7060 {"suspend", no_argument, NULL, 's'},
7061 {"wait", no_argument, NULL, 'w'},
7062 {0, 0, 0, 0}
7063 };
7064
7065 pool_trim_func_t cmd_type = POOL_TRIM_START;
7066 uint64_t rate = 0;
7067 boolean_t secure = B_FALSE;
7068 boolean_t wait = B_FALSE;
7069
7070 int c;
7071 while ((c = getopt_long(argc, argv, "cdr:sw", long_options, NULL))
7072 != -1) {
7073 switch (c) {
7074 case 'c':
7075 if (cmd_type != POOL_TRIM_START &&
7076 cmd_type != POOL_TRIM_CANCEL) {
7077 (void) fprintf(stderr, gettext("-c cannot be "
7078 "combined with other options\n"));
7079 usage(B_FALSE);
7080 }
7081 cmd_type = POOL_TRIM_CANCEL;
7082 break;
7083 case 'd':
7084 if (cmd_type != POOL_TRIM_START) {
7085 (void) fprintf(stderr, gettext("-d cannot be "
7086 "combined with the -c or -s options\n"));
7087 usage(B_FALSE);
7088 }
7089 secure = B_TRUE;
7090 break;
7091 case 'r':
7092 if (cmd_type != POOL_TRIM_START) {
7093 (void) fprintf(stderr, gettext("-r cannot be "
7094 "combined with the -c or -s options\n"));
7095 usage(B_FALSE);
7096 }
7097 if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) {
7098 (void) fprintf(stderr,
7099 gettext("invalid value for rate\n"));
7100 usage(B_FALSE);
7101 }
7102 break;
7103 case 's':
7104 if (cmd_type != POOL_TRIM_START &&
7105 cmd_type != POOL_TRIM_SUSPEND) {
7106 (void) fprintf(stderr, gettext("-s cannot be "
7107 "combined with other options\n"));
7108 usage(B_FALSE);
7109 }
7110 cmd_type = POOL_TRIM_SUSPEND;
7111 break;
7112 case 'w':
7113 wait = B_TRUE;
7114 break;
7115 case '?':
7116 if (optopt != 0) {
7117 (void) fprintf(stderr,
7118 gettext("invalid option '%c'\n"), optopt);
7119 } else {
7120 (void) fprintf(stderr,
7121 gettext("invalid option '%s'\n"),
7122 argv[optind - 1]);
7123 }
7124 usage(B_FALSE);
7125 }
7126 }
7127
7128 argc -= optind;
7129 argv += optind;
7130
7131 if (argc < 1) {
7132 (void) fprintf(stderr, gettext("missing pool name argument\n"));
7133 usage(B_FALSE);
7134 return (-1);
7135 }
7136
7137 if (wait && (cmd_type != POOL_TRIM_START)) {
7138 (void) fprintf(stderr, gettext("-w cannot be used with -c or "
7139 "-s\n"));
7140 usage(B_FALSE);
7141 }
7142
7143 char *poolname = argv[0];
7144 zpool_handle_t *zhp = zpool_open(g_zfs, poolname);
7145 if (zhp == NULL)
7146 return (-1);
7147
7148 trimflags_t trim_flags = {
7149 .secure = secure,
7150 .rate = rate,
7151 .wait = wait,
7152 };
7153
7154 nvlist_t *vdevs = fnvlist_alloc();
7155 if (argc == 1) {
7156 /* no individual leaf vdevs specified, so add them all */
7157 nvlist_t *config = zpool_get_config(zhp, NULL);
7158 nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
7159 ZPOOL_CONFIG_VDEV_TREE);
7160 zpool_collect_leaves(zhp, nvroot, vdevs);
7161 trim_flags.fullpool = B_TRUE;
7162 } else {
7163 trim_flags.fullpool = B_FALSE;
7164 for (int i = 1; i < argc; i++) {
7165 fnvlist_add_boolean(vdevs, argv[i]);
7166 }
7167 }
7168
7169 int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags);
7170
7171 fnvlist_free(vdevs);
7172 zpool_close(zhp);
7173
7174 return (error);
7175 }
7176
7177 /*
7178 * Converts a total number of seconds to a human readable string broken
7179 * down in to days/hours/minutes/seconds.
7180 */
7181 static void
7182 secs_to_dhms(uint64_t total, char *buf)
7183 {
7184 uint64_t days = total / 60 / 60 / 24;
7185 uint64_t hours = (total / 60 / 60) % 24;
7186 uint64_t mins = (total / 60) % 60;
7187 uint64_t secs = (total % 60);
7188
7189 if (days > 0) {
7190 (void) sprintf(buf, "%llu days %02llu:%02llu:%02llu",
7191 (u_longlong_t)days, (u_longlong_t)hours,
7192 (u_longlong_t)mins, (u_longlong_t)secs);
7193 } else {
7194 (void) sprintf(buf, "%02llu:%02llu:%02llu",
7195 (u_longlong_t)hours, (u_longlong_t)mins,
7196 (u_longlong_t)secs);
7197 }
7198 }
7199
7200 /*
7201 * Print out detailed scrub status.
7202 */
7203 static void
7204 print_scan_scrub_resilver_status(pool_scan_stat_t *ps)
7205 {
7206 time_t start, end, pause;
7207 uint64_t pass_scanned, scanned, pass_issued, issued, total;
7208 uint64_t elapsed, scan_rate, issue_rate;
7209 double fraction_done;
7210 char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7];
7211 char srate_buf[7], irate_buf[7], time_buf[32];
7212
7213 printf(" ");
7214 printf_color(ANSI_BOLD, gettext("scan:"));
7215 printf(" ");
7216
7217 /* If there's never been a scan, there's not much to say. */
7218 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
7219 ps->pss_func >= POOL_SCAN_FUNCS) {
7220 (void) printf(gettext("none requested\n"));
7221 return;
7222 }
7223
7224 start = ps->pss_start_time;
7225 end = ps->pss_end_time;
7226 pause = ps->pss_pass_scrub_pause;
7227
7228 zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf));
7229
7230 assert(ps->pss_func == POOL_SCAN_SCRUB ||
7231 ps->pss_func == POOL_SCAN_RESILVER);
7232
7233 /* Scan is finished or canceled. */
7234 if (ps->pss_state == DSS_FINISHED) {
7235 secs_to_dhms(end - start, time_buf);
7236
7237 if (ps->pss_func == POOL_SCAN_SCRUB) {
7238 (void) printf(gettext("scrub repaired %s "
7239 "in %s with %llu errors on %s"), processed_buf,
7240 time_buf, (u_longlong_t)ps->pss_errors,
7241 ctime(&end));
7242 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
7243 (void) printf(gettext("resilvered %s "
7244 "in %s with %llu errors on %s"), processed_buf,
7245 time_buf, (u_longlong_t)ps->pss_errors,
7246 ctime(&end));
7247 }
7248 return;
7249 } else if (ps->pss_state == DSS_CANCELED) {
7250 if (ps->pss_func == POOL_SCAN_SCRUB) {
7251 (void) printf(gettext("scrub canceled on %s"),
7252 ctime(&end));
7253 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
7254 (void) printf(gettext("resilver canceled on %s"),
7255 ctime(&end));
7256 }
7257 return;
7258 }
7259
7260 assert(ps->pss_state == DSS_SCANNING);
7261
7262 /* Scan is in progress. Resilvers can't be paused. */
7263 if (ps->pss_func == POOL_SCAN_SCRUB) {
7264 if (pause == 0) {
7265 (void) printf(gettext("scrub in progress since %s"),
7266 ctime(&start));
7267 } else {
7268 (void) printf(gettext("scrub paused since %s"),
7269 ctime(&pause));
7270 (void) printf(gettext("\tscrub started on %s"),
7271 ctime(&start));
7272 }
7273 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
7274 (void) printf(gettext("resilver in progress since %s"),
7275 ctime(&start));
7276 }
7277
7278 scanned = ps->pss_examined;
7279 pass_scanned = ps->pss_pass_exam;
7280 issued = ps->pss_issued;
7281 pass_issued = ps->pss_pass_issued;
7282 total = ps->pss_to_examine;
7283
7284 /* we are only done with a block once we have issued the IO for it */
7285 fraction_done = (double)issued / total;
7286
7287 /* elapsed time for this pass, rounding up to 1 if it's 0 */
7288 elapsed = time(NULL) - ps->pss_pass_start;
7289 elapsed -= ps->pss_pass_scrub_spent_paused;
7290 elapsed = (elapsed != 0) ? elapsed : 1;
7291
7292 scan_rate = pass_scanned / elapsed;
7293 issue_rate = pass_issued / elapsed;
7294 uint64_t total_secs_left = (issue_rate != 0 && total >= issued) ?
7295 ((total - issued) / issue_rate) : UINT64_MAX;
7296 secs_to_dhms(total_secs_left, time_buf);
7297
7298 /* format all of the numbers we will be reporting */
7299 zfs_nicebytes(scanned, scanned_buf, sizeof (scanned_buf));
7300 zfs_nicebytes(issued, issued_buf, sizeof (issued_buf));
7301 zfs_nicebytes(total, total_buf, sizeof (total_buf));
7302 zfs_nicebytes(scan_rate, srate_buf, sizeof (srate_buf));
7303 zfs_nicebytes(issue_rate, irate_buf, sizeof (irate_buf));
7304
7305 /* do not print estimated time if we have a paused scrub */
7306 if (pause == 0) {
7307 (void) printf(gettext("\t%s scanned at %s/s, "
7308 "%s issued at %s/s, %s total\n"),
7309 scanned_buf, srate_buf, issued_buf, irate_buf, total_buf);
7310 } else {
7311 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"),
7312 scanned_buf, issued_buf, total_buf);
7313 }
7314
7315 if (ps->pss_func == POOL_SCAN_RESILVER) {
7316 (void) printf(gettext("\t%s resilvered, %.2f%% done"),
7317 processed_buf, 100 * fraction_done);
7318 } else if (ps->pss_func == POOL_SCAN_SCRUB) {
7319 (void) printf(gettext("\t%s repaired, %.2f%% done"),
7320 processed_buf, 100 * fraction_done);
7321 }
7322
7323 if (pause == 0) {
7324 if (total_secs_left != UINT64_MAX &&
7325 issue_rate >= 10 * 1024 * 1024) {
7326 (void) printf(gettext(", %s to go\n"), time_buf);
7327 } else {
7328 (void) printf(gettext(", no estimated "
7329 "completion time\n"));
7330 }
7331 } else {
7332 (void) printf(gettext("\n"));
7333 }
7334 }
7335
7336 static void
7337 print_rebuild_status_impl(vdev_rebuild_stat_t *vrs, char *vdev_name)
7338 {
7339 if (vrs == NULL || vrs->vrs_state == VDEV_REBUILD_NONE)
7340 return;
7341
7342 printf(" ");
7343 printf_color(ANSI_BOLD, gettext("scan:"));
7344 printf(" ");
7345
7346 uint64_t bytes_scanned = vrs->vrs_bytes_scanned;
7347 uint64_t bytes_issued = vrs->vrs_bytes_issued;
7348 uint64_t bytes_rebuilt = vrs->vrs_bytes_rebuilt;
7349 uint64_t bytes_est = vrs->vrs_bytes_est;
7350 uint64_t scan_rate = (vrs->vrs_pass_bytes_scanned /
7351 (vrs->vrs_pass_time_ms + 1)) * 1000;
7352 uint64_t issue_rate = (vrs->vrs_pass_bytes_issued /
7353 (vrs->vrs_pass_time_ms + 1)) * 1000;
7354 double scan_pct = MIN((double)bytes_scanned * 100 /
7355 (bytes_est + 1), 100);
7356
7357 /* Format all of the numbers we will be reporting */
7358 char bytes_scanned_buf[7], bytes_issued_buf[7];
7359 char bytes_rebuilt_buf[7], bytes_est_buf[7];
7360 char scan_rate_buf[7], issue_rate_buf[7], time_buf[32];
7361 zfs_nicebytes(bytes_scanned, bytes_scanned_buf,
7362 sizeof (bytes_scanned_buf));
7363 zfs_nicebytes(bytes_issued, bytes_issued_buf,
7364 sizeof (bytes_issued_buf));
7365 zfs_nicebytes(bytes_rebuilt, bytes_rebuilt_buf,
7366 sizeof (bytes_rebuilt_buf));
7367 zfs_nicebytes(bytes_est, bytes_est_buf, sizeof (bytes_est_buf));
7368 zfs_nicebytes(scan_rate, scan_rate_buf, sizeof (scan_rate_buf));
7369 zfs_nicebytes(issue_rate, issue_rate_buf, sizeof (issue_rate_buf));
7370
7371 time_t start = vrs->vrs_start_time;
7372 time_t end = vrs->vrs_end_time;
7373
7374 /* Rebuild is finished or canceled. */
7375 if (vrs->vrs_state == VDEV_REBUILD_COMPLETE) {
7376 secs_to_dhms(vrs->vrs_scan_time_ms / 1000, time_buf);
7377 (void) printf(gettext("resilvered (%s) %s in %s "
7378 "with %llu errors on %s"), vdev_name, bytes_rebuilt_buf,
7379 time_buf, (u_longlong_t)vrs->vrs_errors, ctime(&end));
7380 return;
7381 } else if (vrs->vrs_state == VDEV_REBUILD_CANCELED) {
7382 (void) printf(gettext("resilver (%s) canceled on %s"),
7383 vdev_name, ctime(&end));
7384 return;
7385 } else if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) {
7386 (void) printf(gettext("resilver (%s) in progress since %s"),
7387 vdev_name, ctime(&start));
7388 }
7389
7390 assert(vrs->vrs_state == VDEV_REBUILD_ACTIVE);
7391
7392 secs_to_dhms(MAX((int64_t)bytes_est - (int64_t)bytes_scanned, 0) /
7393 MAX(scan_rate, 1), time_buf);
7394
7395 (void) printf(gettext("\t%s scanned at %s/s, %s issued %s/s, "
7396 "%s total\n"), bytes_scanned_buf, scan_rate_buf,
7397 bytes_issued_buf, issue_rate_buf, bytes_est_buf);
7398 (void) printf(gettext("\t%s resilvered, %.2f%% done"),
7399 bytes_rebuilt_buf, scan_pct);
7400
7401 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) {
7402 if (scan_rate >= 10 * 1024 * 1024) {
7403 (void) printf(gettext(", %s to go\n"), time_buf);
7404 } else {
7405 (void) printf(gettext(", no estimated "
7406 "completion time\n"));
7407 }
7408 } else {
7409 (void) printf(gettext("\n"));
7410 }
7411 }
7412
7413 /*
7414 * Print rebuild status for top-level vdevs.
7415 */
7416 static void
7417 print_rebuild_status(zpool_handle_t *zhp, nvlist_t *nvroot)
7418 {
7419 nvlist_t **child;
7420 uint_t children;
7421
7422 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
7423 &child, &children) != 0)
7424 children = 0;
7425
7426 for (uint_t c = 0; c < children; c++) {
7427 vdev_rebuild_stat_t *vrs;
7428 uint_t i;
7429
7430 if (nvlist_lookup_uint64_array(child[c],
7431 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) {
7432 char *name = zpool_vdev_name(g_zfs, zhp,
7433 child[c], VDEV_NAME_TYPE_ID);
7434 print_rebuild_status_impl(vrs, name);
7435 free(name);
7436 }
7437 }
7438 }
7439
7440 /*
7441 * As we don't scrub checkpointed blocks, we want to warn the user that we
7442 * skipped scanning some blocks if a checkpoint exists or existed at any
7443 * time during the scan. If a sequential instead of healing reconstruction
7444 * was performed then the blocks were reconstructed. However, their checksums
7445 * have not been verified so we still print the warning.
7446 */
7447 static void
7448 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs)
7449 {
7450 if (ps == NULL || pcs == NULL)
7451 return;
7452
7453 if (pcs->pcs_state == CS_NONE ||
7454 pcs->pcs_state == CS_CHECKPOINT_DISCARDING)
7455 return;
7456
7457 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS);
7458
7459 if (ps->pss_state == DSS_NONE)
7460 return;
7461
7462 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) &&
7463 ps->pss_end_time < pcs->pcs_start_time)
7464 return;
7465
7466 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) {
7467 (void) printf(gettext(" scan warning: skipped blocks "
7468 "that are only referenced by the checkpoint.\n"));
7469 } else {
7470 assert(ps->pss_state == DSS_SCANNING);
7471 (void) printf(gettext(" scan warning: skipping blocks "
7472 "that are only referenced by the checkpoint.\n"));
7473 }
7474 }
7475
7476 /*
7477 * Returns B_TRUE if there is an active rebuild in progress. Otherwise,
7478 * B_FALSE is returned and 'rebuild_end_time' is set to the end time for
7479 * the last completed (or cancelled) rebuild.
7480 */
7481 static boolean_t
7482 check_rebuilding(nvlist_t *nvroot, uint64_t *rebuild_end_time)
7483 {
7484 nvlist_t **child;
7485 uint_t children;
7486 boolean_t rebuilding = B_FALSE;
7487 uint64_t end_time = 0;
7488
7489 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
7490 &child, &children) != 0)
7491 children = 0;
7492
7493 for (uint_t c = 0; c < children; c++) {
7494 vdev_rebuild_stat_t *vrs;
7495 uint_t i;
7496
7497 if (nvlist_lookup_uint64_array(child[c],
7498 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) {
7499
7500 if (vrs->vrs_end_time > end_time)
7501 end_time = vrs->vrs_end_time;
7502
7503 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) {
7504 rebuilding = B_TRUE;
7505 end_time = 0;
7506 break;
7507 }
7508 }
7509 }
7510
7511 if (rebuild_end_time != NULL)
7512 *rebuild_end_time = end_time;
7513
7514 return (rebuilding);
7515 }
7516
7517 /*
7518 * Print the scan status.
7519 */
7520 static void
7521 print_scan_status(zpool_handle_t *zhp, nvlist_t *nvroot)
7522 {
7523 uint64_t rebuild_end_time = 0, resilver_end_time = 0;
7524 boolean_t have_resilver = B_FALSE, have_scrub = B_FALSE;
7525 boolean_t active_resilver = B_FALSE;
7526 pool_checkpoint_stat_t *pcs = NULL;
7527 pool_scan_stat_t *ps = NULL;
7528 uint_t c;
7529
7530 if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
7531 (uint64_t **)&ps, &c) == 0) {
7532 if (ps->pss_func == POOL_SCAN_RESILVER) {
7533 resilver_end_time = ps->pss_end_time;
7534 active_resilver = (ps->pss_state == DSS_SCANNING);
7535 }
7536
7537 have_resilver = (ps->pss_func == POOL_SCAN_RESILVER);
7538 have_scrub = (ps->pss_func == POOL_SCAN_SCRUB);
7539 }
7540
7541 boolean_t active_rebuild = check_rebuilding(nvroot, &rebuild_end_time);
7542 boolean_t have_rebuild = (active_rebuild || (rebuild_end_time > 0));
7543
7544 /* Always print the scrub status when available. */
7545 if (have_scrub)
7546 print_scan_scrub_resilver_status(ps);
7547
7548 /*
7549 * When there is an active resilver or rebuild print its status.
7550 * Otherwise print the status of the last resilver or rebuild.
7551 */
7552 if (active_resilver || (!active_rebuild && have_resilver &&
7553 resilver_end_time && resilver_end_time > rebuild_end_time)) {
7554 print_scan_scrub_resilver_status(ps);
7555 } else if (active_rebuild || (!active_resilver && have_rebuild &&
7556 rebuild_end_time && rebuild_end_time > resilver_end_time)) {
7557 print_rebuild_status(zhp, nvroot);
7558 }
7559
7560 (void) nvlist_lookup_uint64_array(nvroot,
7561 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
7562 print_checkpoint_scan_warning(ps, pcs);
7563 }
7564
7565 /*
7566 * Print out detailed removal status.
7567 */
7568 static void
7569 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
7570 {
7571 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
7572 time_t start, end;
7573 nvlist_t *config, *nvroot;
7574 nvlist_t **child;
7575 uint_t children;
7576 char *vdev_name;
7577
7578 if (prs == NULL || prs->prs_state == DSS_NONE)
7579 return;
7580
7581 /*
7582 * Determine name of vdev.
7583 */
7584 config = zpool_get_config(zhp, NULL);
7585 nvroot = fnvlist_lookup_nvlist(config,
7586 ZPOOL_CONFIG_VDEV_TREE);
7587 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
7588 &child, &children) == 0);
7589 assert(prs->prs_removing_vdev < children);
7590 vdev_name = zpool_vdev_name(g_zfs, zhp,
7591 child[prs->prs_removing_vdev], B_TRUE);
7592
7593 (void) printf(gettext("remove: "));
7594
7595 start = prs->prs_start_time;
7596 end = prs->prs_end_time;
7597 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf));
7598
7599 /*
7600 * Removal is finished or canceled.
7601 */
7602 if (prs->prs_state == DSS_FINISHED) {
7603 uint64_t minutes_taken = (end - start) / 60;
7604
7605 (void) printf(gettext("Removal of vdev %llu copied %s "
7606 "in %lluh%um, completed on %s"),
7607 (longlong_t)prs->prs_removing_vdev,
7608 copied_buf,
7609 (u_longlong_t)(minutes_taken / 60),
7610 (uint_t)(minutes_taken % 60),
7611 ctime((time_t *)&end));
7612 } else if (prs->prs_state == DSS_CANCELED) {
7613 (void) printf(gettext("Removal of %s canceled on %s"),
7614 vdev_name, ctime(&end));
7615 } else {
7616 uint64_t copied, total, elapsed, mins_left, hours_left;
7617 double fraction_done;
7618 uint_t rate;
7619
7620 assert(prs->prs_state == DSS_SCANNING);
7621
7622 /*
7623 * Removal is in progress.
7624 */
7625 (void) printf(gettext(
7626 "Evacuation of %s in progress since %s"),
7627 vdev_name, ctime(&start));
7628
7629 copied = prs->prs_copied > 0 ? prs->prs_copied : 1;
7630 total = prs->prs_to_copy;
7631 fraction_done = (double)copied / total;
7632
7633 /* elapsed time for this pass */
7634 elapsed = time(NULL) - prs->prs_start_time;
7635 elapsed = elapsed > 0 ? elapsed : 1;
7636 rate = copied / elapsed;
7637 rate = rate > 0 ? rate : 1;
7638 mins_left = ((total - copied) / rate) / 60;
7639 hours_left = mins_left / 60;
7640
7641 zfs_nicenum(copied, examined_buf, sizeof (examined_buf));
7642 zfs_nicenum(total, total_buf, sizeof (total_buf));
7643 zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
7644
7645 /*
7646 * do not print estimated time if hours_left is more than
7647 * 30 days
7648 */
7649 (void) printf(gettext(" %s copied out of %s at %s/s, "
7650 "%.2f%% done"),
7651 examined_buf, total_buf, rate_buf, 100 * fraction_done);
7652 if (hours_left < (30 * 24)) {
7653 (void) printf(gettext(", %lluh%um to go\n"),
7654 (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
7655 } else {
7656 (void) printf(gettext(
7657 ", (copy is slow, no estimated time)\n"));
7658 }
7659 }
7660 free(vdev_name);
7661
7662 if (prs->prs_mapping_memory > 0) {
7663 char mem_buf[7];
7664 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
7665 (void) printf(gettext(" %s memory used for "
7666 "removed device mappings\n"),
7667 mem_buf);
7668 }
7669 }
7670
7671 static void
7672 print_checkpoint_status(pool_checkpoint_stat_t *pcs)
7673 {
7674 time_t start;
7675 char space_buf[7];
7676
7677 if (pcs == NULL || pcs->pcs_state == CS_NONE)
7678 return;
7679
7680 (void) printf(gettext("checkpoint: "));
7681
7682 start = pcs->pcs_start_time;
7683 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf));
7684
7685 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) {
7686 char *date = ctime(&start);
7687
7688 /*
7689 * ctime() adds a newline at the end of the generated
7690 * string, thus the weird format specifier and the
7691 * strlen() call used to chop it off from the output.
7692 */
7693 (void) printf(gettext("created %.*s, consumes %s\n"),
7694 (int)(strlen(date) - 1), date, space_buf);
7695 return;
7696 }
7697
7698 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
7699
7700 (void) printf(gettext("discarding, %s remaining.\n"),
7701 space_buf);
7702 }
7703
7704 static void
7705 print_error_log(zpool_handle_t *zhp)
7706 {
7707 nvlist_t *nverrlist = NULL;
7708 nvpair_t *elem;
7709 char *pathname;
7710 size_t len = MAXPATHLEN * 2;
7711
7712 if (zpool_get_errlog(zhp, &nverrlist) != 0)
7713 return;
7714
7715 (void) printf("errors: Permanent errors have been "
7716 "detected in the following files:\n\n");
7717
7718 pathname = safe_malloc(len);
7719 elem = NULL;
7720 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
7721 nvlist_t *nv;
7722 uint64_t dsobj, obj;
7723
7724 verify(nvpair_value_nvlist(elem, &nv) == 0);
7725 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
7726 &dsobj) == 0);
7727 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
7728 &obj) == 0);
7729 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
7730 (void) printf("%7s %s\n", "", pathname);
7731 }
7732 free(pathname);
7733 nvlist_free(nverrlist);
7734 }
7735
7736 static void
7737 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares,
7738 uint_t nspares)
7739 {
7740 uint_t i;
7741 char *name;
7742
7743 if (nspares == 0)
7744 return;
7745
7746 (void) printf(gettext("\tspares\n"));
7747
7748 for (i = 0; i < nspares; i++) {
7749 name = zpool_vdev_name(g_zfs, zhp, spares[i],
7750 cb->cb_name_flags);
7751 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE, NULL);
7752 free(name);
7753 }
7754 }
7755
7756 static void
7757 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache,
7758 uint_t nl2cache)
7759 {
7760 uint_t i;
7761 char *name;
7762
7763 if (nl2cache == 0)
7764 return;
7765
7766 (void) printf(gettext("\tcache\n"));
7767
7768 for (i = 0; i < nl2cache; i++) {
7769 name = zpool_vdev_name(g_zfs, zhp, l2cache[i],
7770 cb->cb_name_flags);
7771 print_status_config(zhp, cb, name, l2cache[i], 2,
7772 B_FALSE, NULL);
7773 free(name);
7774 }
7775 }
7776
7777 static void
7778 print_dedup_stats(nvlist_t *config)
7779 {
7780 ddt_histogram_t *ddh;
7781 ddt_stat_t *dds;
7782 ddt_object_t *ddo;
7783 uint_t c;
7784 char dspace[6], mspace[6];
7785
7786 /*
7787 * If the pool was faulted then we may not have been able to
7788 * obtain the config. Otherwise, if we have anything in the dedup
7789 * table continue processing the stats.
7790 */
7791 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
7792 (uint64_t **)&ddo, &c) != 0)
7793 return;
7794
7795 (void) printf("\n");
7796 (void) printf(gettext(" dedup: "));
7797 if (ddo->ddo_count == 0) {
7798 (void) printf(gettext("no DDT entries\n"));
7799 return;
7800 }
7801
7802 zfs_nicebytes(ddo->ddo_dspace, dspace, sizeof (dspace));
7803 zfs_nicebytes(ddo->ddo_mspace, mspace, sizeof (mspace));
7804 (void) printf("DDT entries %llu, size %s on disk, %s in core\n",
7805 (u_longlong_t)ddo->ddo_count,
7806 dspace,
7807 mspace);
7808
7809 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
7810 (uint64_t **)&dds, &c) == 0);
7811 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
7812 (uint64_t **)&ddh, &c) == 0);
7813 zpool_dump_ddt(dds, ddh);
7814 }
7815
7816 /*
7817 * Display a summary of pool status. Displays a summary such as:
7818 *
7819 * pool: tank
7820 * status: DEGRADED
7821 * reason: One or more devices ...
7822 * see: https://openzfs.github.io/openzfs-docs/msg/ZFS-xxxx-01
7823 * config:
7824 * mirror DEGRADED
7825 * c1t0d0 OK
7826 * c2t0d0 UNAVAIL
7827 *
7828 * When given the '-v' option, we print out the complete config. If the '-e'
7829 * option is specified, then we print out error rate information as well.
7830 */
7831 static int
7832 status_callback(zpool_handle_t *zhp, void *data)
7833 {
7834 status_cbdata_t *cbp = data;
7835 nvlist_t *config, *nvroot;
7836 char *msgid;
7837 zpool_status_t reason;
7838 zpool_errata_t errata;
7839 const char *health;
7840 uint_t c;
7841 vdev_stat_t *vs;
7842
7843 config = zpool_get_config(zhp, NULL);
7844 reason = zpool_get_status(zhp, &msgid, &errata);
7845
7846 cbp->cb_count++;
7847
7848 /*
7849 * If we were given 'zpool status -x', only report those pools with
7850 * problems.
7851 */
7852 if (cbp->cb_explain &&
7853 (reason == ZPOOL_STATUS_OK ||
7854 reason == ZPOOL_STATUS_VERSION_OLDER ||
7855 reason == ZPOOL_STATUS_FEAT_DISABLED)) {
7856 if (!cbp->cb_allpools) {
7857 (void) printf(gettext("pool '%s' is healthy\n"),
7858 zpool_get_name(zhp));
7859 if (cbp->cb_first)
7860 cbp->cb_first = B_FALSE;
7861 }
7862 return (0);
7863 }
7864
7865 if (cbp->cb_first)
7866 cbp->cb_first = B_FALSE;
7867 else
7868 (void) printf("\n");
7869
7870 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
7871 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
7872 (uint64_t **)&vs, &c) == 0);
7873
7874 health = zpool_get_state_str(zhp);
7875
7876 printf(" ");
7877 printf_color(ANSI_BOLD, gettext("pool:"));
7878 printf(" %s\n", zpool_get_name(zhp));
7879 printf(" ");
7880 printf_color(ANSI_BOLD, gettext("state: "));
7881
7882 printf_color(health_str_to_color(health), "%s", health);
7883
7884 printf("\n");
7885
7886 switch (reason) {
7887 case ZPOOL_STATUS_MISSING_DEV_R:
7888 printf_color(ANSI_BOLD, gettext("status: "));
7889 printf_color(ANSI_YELLOW, gettext("One or more devices could "
7890 "not be opened. Sufficient replicas exist for\n\tthe pool "
7891 "to continue functioning in a degraded state.\n"));
7892 printf_color(ANSI_BOLD, gettext("action: "));
7893 printf_color(ANSI_YELLOW, gettext("Attach the missing device "
7894 "and online it using 'zpool online'.\n"));
7895 break;
7896
7897 case ZPOOL_STATUS_MISSING_DEV_NR:
7898 printf_color(ANSI_BOLD, gettext("status: "));
7899 printf_color(ANSI_YELLOW, gettext("One or more devices could "
7900 "not be opened. There are insufficient\n\treplicas for the"
7901 " pool to continue functioning.\n"));
7902 printf_color(ANSI_BOLD, gettext("action: "));
7903 printf_color(ANSI_YELLOW, gettext("Attach the missing device "
7904 "and online it using 'zpool online'.\n"));
7905 break;
7906
7907 case ZPOOL_STATUS_CORRUPT_LABEL_R:
7908 printf_color(ANSI_BOLD, gettext("status: "));
7909 printf_color(ANSI_YELLOW, gettext("One or more devices could "
7910 "not be used because the label is missing or\n\tinvalid. "
7911 "Sufficient replicas exist for the pool to continue\n\t"
7912 "functioning in a degraded state.\n"));
7913 printf_color(ANSI_BOLD, gettext("action: "));
7914 printf_color(ANSI_YELLOW, gettext("Replace the device using "
7915 "'zpool replace'.\n"));
7916 break;
7917
7918 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
7919 printf_color(ANSI_BOLD, gettext("status: "));
7920 printf_color(ANSI_YELLOW, gettext("One or more devices could "
7921 "not be used because the label is missing \n\tor invalid. "
7922 "There are insufficient replicas for the pool to "
7923 "continue\n\tfunctioning.\n"));
7924 zpool_explain_recover(zpool_get_handle(zhp),
7925 zpool_get_name(zhp), reason, config);
7926 break;
7927
7928 case ZPOOL_STATUS_FAILING_DEV:
7929 printf_color(ANSI_BOLD, gettext("status: "));
7930 printf_color(ANSI_YELLOW, gettext("One or more devices has "
7931 "experienced an unrecoverable error. An\n\tattempt was "
7932 "made to correct the error. Applications are "
7933 "unaffected.\n"));
7934 printf_color(ANSI_BOLD, gettext("action: "));
7935 printf_color(ANSI_YELLOW, gettext("Determine if the "
7936 "device needs to be replaced, and clear the errors\n\tusing"
7937 " 'zpool clear' or replace the device with 'zpool "
7938 "replace'.\n"));
7939 break;
7940
7941 case ZPOOL_STATUS_OFFLINE_DEV:
7942 printf_color(ANSI_BOLD, gettext("status: "));
7943 printf_color(ANSI_YELLOW, gettext("One or more devices has "
7944 "been taken offline by the administrator.\n\tSufficient "
7945 "replicas exist for the pool to continue functioning in "
7946 "a\n\tdegraded state.\n"));
7947 printf_color(ANSI_BOLD, gettext("action: "));
7948 printf_color(ANSI_YELLOW, gettext("Online the device "
7949 "using 'zpool online' or replace the device with\n\t'zpool "
7950 "replace'.\n"));
7951 break;
7952
7953 case ZPOOL_STATUS_REMOVED_DEV:
7954 printf_color(ANSI_BOLD, gettext("status: "));
7955 printf_color(ANSI_YELLOW, gettext("One or more devices has "
7956 "been removed by the administrator.\n\tSufficient "
7957 "replicas exist for the pool to continue functioning in "
7958 "a\n\tdegraded state.\n"));
7959 printf_color(ANSI_BOLD, gettext("action: "));
7960 printf_color(ANSI_YELLOW, gettext("Online the device "
7961 "using zpool online' or replace the device with\n\t'zpool "
7962 "replace'.\n"));
7963 break;
7964
7965 case ZPOOL_STATUS_RESILVERING:
7966 case ZPOOL_STATUS_REBUILDING:
7967 printf_color(ANSI_BOLD, gettext("status: "));
7968 printf_color(ANSI_YELLOW, gettext("One or more devices is "
7969 "currently being resilvered. The pool will\n\tcontinue "
7970 "to function, possibly in a degraded state.\n"));
7971 printf_color(ANSI_BOLD, gettext("action: "));
7972 printf_color(ANSI_YELLOW, gettext("Wait for the resilver to "
7973 "complete.\n"));
7974 break;
7975
7976 case ZPOOL_STATUS_REBUILD_SCRUB:
7977 printf_color(ANSI_BOLD, gettext("status: "));
7978 printf_color(ANSI_YELLOW, gettext("One or more devices have "
7979 "been sequentially resilvered, scrubbing\n\tthe pool "
7980 "is recommended.\n"));
7981 printf_color(ANSI_BOLD, gettext("action: "));
7982 printf_color(ANSI_YELLOW, gettext("Use 'zpool scrub' to "
7983 "verify all data checksums.\n"));
7984 break;
7985
7986 case ZPOOL_STATUS_CORRUPT_DATA:
7987 printf_color(ANSI_BOLD, gettext("status: "));
7988 printf_color(ANSI_YELLOW, gettext("One or more devices has "
7989 "experienced an error resulting in data\n\tcorruption. "
7990 "Applications may be affected.\n"));
7991 printf_color(ANSI_BOLD, gettext("action: "));
7992 printf_color(ANSI_YELLOW, gettext("Restore the file in question"
7993 " if possible. Otherwise restore the\n\tentire pool from "
7994 "backup.\n"));
7995 break;
7996
7997 case ZPOOL_STATUS_CORRUPT_POOL:
7998 printf_color(ANSI_BOLD, gettext("status: "));
7999 printf_color(ANSI_YELLOW, gettext("The pool metadata is "
8000 "corrupted and the pool cannot be opened.\n"));
8001 zpool_explain_recover(zpool_get_handle(zhp),
8002 zpool_get_name(zhp), reason, config);
8003 break;
8004
8005 case ZPOOL_STATUS_VERSION_OLDER:
8006 printf_color(ANSI_BOLD, gettext("status: "));
8007 printf_color(ANSI_YELLOW, gettext("The pool is formatted using "
8008 "a legacy on-disk format. The pool can\n\tstill be used, "
8009 "but some features are unavailable.\n"));
8010 printf_color(ANSI_BOLD, gettext("action: "));
8011 printf_color(ANSI_YELLOW, gettext("Upgrade the pool using "
8012 "'zpool upgrade'. Once this is done, the\n\tpool will no "
8013 "longer be accessible on software that does not support\n\t"
8014 "feature flags.\n"));
8015 break;
8016
8017 case ZPOOL_STATUS_VERSION_NEWER:
8018 printf_color(ANSI_BOLD, gettext("status: "));
8019 printf_color(ANSI_YELLOW, gettext("The pool has been upgraded "
8020 "to a newer, incompatible on-disk version.\n\tThe pool "
8021 "cannot be accessed on this system.\n"));
8022 printf_color(ANSI_BOLD, gettext("action: "));
8023 printf_color(ANSI_YELLOW, gettext("Access the pool from a "
8024 "system running more recent software, or\n\trestore the "
8025 "pool from backup.\n"));
8026 break;
8027
8028 case ZPOOL_STATUS_FEAT_DISABLED:
8029 printf_color(ANSI_BOLD, gettext("status: "));
8030 printf_color(ANSI_YELLOW, gettext("Some supported features are "
8031 "not enabled on the pool. The pool can\n\tstill be used, "
8032 "but some features are unavailable.\n"));
8033 printf_color(ANSI_BOLD, gettext("action: "));
8034 printf_color(ANSI_YELLOW, gettext("Enable all features using "
8035 "'zpool upgrade'. Once this is done,\n\tthe pool may no "
8036 "longer be accessible by software that does not support\n\t"
8037 "the features. See zpool-features(5) for details.\n"));
8038 break;
8039
8040 case ZPOOL_STATUS_UNSUP_FEAT_READ:
8041 printf_color(ANSI_BOLD, gettext("status: "));
8042 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed "
8043 "on this system because it uses the\n\tfollowing feature(s)"
8044 " not supported on this system:\n"));
8045 zpool_print_unsup_feat(config);
8046 (void) printf("\n");
8047 printf_color(ANSI_BOLD, gettext("action: "));
8048 printf_color(ANSI_YELLOW, gettext("Access the pool from a "
8049 "system that supports the required feature(s),\n\tor "
8050 "restore the pool from backup.\n"));
8051 break;
8052
8053 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
8054 printf_color(ANSI_BOLD, gettext("status: "));
8055 printf_color(ANSI_YELLOW, gettext("The pool can only be "
8056 "accessed in read-only mode on this system. It\n\tcannot be"
8057 " accessed in read-write mode because it uses the "
8058 "following\n\tfeature(s) not supported on this system:\n"));
8059 zpool_print_unsup_feat(config);
8060 (void) printf("\n");
8061 printf_color(ANSI_BOLD, gettext("action: "));
8062 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed "
8063 "in read-write mode. Import the pool with\n"
8064 "\t\"-o readonly=on\", access the pool from a system that "
8065 "supports the\n\trequired feature(s), or restore the "
8066 "pool from backup.\n"));
8067 break;
8068
8069 case ZPOOL_STATUS_FAULTED_DEV_R:
8070 printf_color(ANSI_BOLD, gettext("status: "));
8071 printf_color(ANSI_YELLOW, gettext("One or more devices are "
8072 "faulted in response to persistent errors.\n\tSufficient "
8073 "replicas exist for the pool to continue functioning "
8074 "in a\n\tdegraded state.\n"));
8075 printf_color(ANSI_BOLD, gettext("action: "));
8076 printf_color(ANSI_YELLOW, gettext("Replace the faulted device, "
8077 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
8078 break;
8079
8080 case ZPOOL_STATUS_FAULTED_DEV_NR:
8081 printf_color(ANSI_BOLD, gettext("status: "));
8082 printf_color(ANSI_YELLOW, gettext("One or more devices are "
8083 "faulted in response to persistent errors. There are "
8084 "insufficient replicas for the pool to\n\tcontinue "
8085 "functioning.\n"));
8086 printf_color(ANSI_BOLD, gettext("action: "));
8087 printf_color(ANSI_YELLOW, gettext("Destroy and re-create the "
8088 "pool from a backup source. Manually marking the device\n"
8089 "\trepaired using 'zpool clear' may allow some data "
8090 "to be recovered.\n"));
8091 break;
8092
8093 case ZPOOL_STATUS_IO_FAILURE_MMP:
8094 printf_color(ANSI_BOLD, gettext("status: "));
8095 printf_color(ANSI_YELLOW, gettext("The pool is suspended "
8096 "because multihost writes failed or were delayed;\n\t"
8097 "another system could import the pool undetected.\n"));
8098 printf_color(ANSI_BOLD, gettext("action: "));
8099 printf_color(ANSI_YELLOW, gettext("Make sure the pool's devices"
8100 " are connected, then reboot your system and\n\timport the "
8101 "pool.\n"));
8102 break;
8103
8104 case ZPOOL_STATUS_IO_FAILURE_WAIT:
8105 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
8106 printf_color(ANSI_BOLD, gettext("status: "));
8107 printf_color(ANSI_YELLOW, gettext("One or more devices are "
8108 "faulted in response to IO failures.\n"));
8109 printf_color(ANSI_BOLD, gettext("action: "));
8110 printf_color(ANSI_YELLOW, gettext("Make sure the affected "
8111 "devices are connected, then run 'zpool clear'.\n"));
8112 break;
8113
8114 case ZPOOL_STATUS_BAD_LOG:
8115 printf_color(ANSI_BOLD, gettext("status: "));
8116 printf_color(ANSI_YELLOW, gettext("An intent log record "
8117 "could not be read.\n"
8118 "\tWaiting for administrator intervention to fix the "
8119 "faulted pool.\n"));
8120 printf_color(ANSI_BOLD, gettext("action: "));
8121 printf_color(ANSI_YELLOW, gettext("Either restore the affected "
8122 "device(s) and run 'zpool online',\n"
8123 "\tor ignore the intent log records by running "
8124 "'zpool clear'.\n"));
8125 break;
8126
8127 case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
8128 (void) printf(gettext("status: One or more devices are "
8129 "configured to use a non-native block size.\n"
8130 "\tExpect reduced performance.\n"));
8131 (void) printf(gettext("action: Replace affected devices with "
8132 "devices that support the\n\tconfigured block size, or "
8133 "migrate data to a properly configured\n\tpool.\n"));
8134 break;
8135
8136 case ZPOOL_STATUS_HOSTID_MISMATCH:
8137 printf_color(ANSI_BOLD, gettext("status: "));
8138 printf_color(ANSI_YELLOW, gettext("Mismatch between pool hostid"
8139 " and system hostid on imported pool.\n\tThis pool was "
8140 "previously imported into a system with a different "
8141 "hostid,\n\tand then was verbatim imported into this "
8142 "system.\n"));
8143 printf_color(ANSI_BOLD, gettext("action: "));
8144 printf_color(ANSI_YELLOW, gettext("Export this pool on all "
8145 "systems on which it is imported.\n"
8146 "\tThen import it to correct the mismatch.\n"));
8147 break;
8148
8149 case ZPOOL_STATUS_ERRATA:
8150 printf_color(ANSI_BOLD, gettext("status: "));
8151 printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"),
8152 errata);
8153
8154 switch (errata) {
8155 case ZPOOL_ERRATA_NONE:
8156 break;
8157
8158 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
8159 printf_color(ANSI_BOLD, gettext("action: "));
8160 printf_color(ANSI_YELLOW, gettext("To correct the issue"
8161 " run 'zpool scrub'.\n"));
8162 break;
8163
8164 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION:
8165 (void) printf(gettext("\tExisting encrypted datasets "
8166 "contain an on-disk incompatibility\n\twhich "
8167 "needs to be corrected.\n"));
8168 printf_color(ANSI_BOLD, gettext("action: "));
8169 printf_color(ANSI_YELLOW, gettext("To correct the issue"
8170 " backup existing encrypted datasets to new\n\t"
8171 "encrypted datasets and destroy the old ones. "
8172 "'zfs mount -o ro' can\n\tbe used to temporarily "
8173 "mount existing encrypted datasets readonly.\n"));
8174 break;
8175
8176 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION:
8177 (void) printf(gettext("\tExisting encrypted snapshots "
8178 "and bookmarks contain an on-disk\n\tincompat"
8179 "ibility. This may cause on-disk corruption if "
8180 "they are used\n\twith 'zfs recv'.\n"));
8181 printf_color(ANSI_BOLD, gettext("action: "));
8182 printf_color(ANSI_YELLOW, gettext("To correct the"
8183 "issue, enable the bookmark_v2 feature. No "
8184 "additional\n\taction is needed if there are no "
8185 "encrypted snapshots or bookmarks.\n\tIf preserving"
8186 "the encrypted snapshots and bookmarks is required,"
8187 " use\n\ta non-raw send to backup and restore them."
8188 " Alternately, they may be\n\tremoved to resolve "
8189 "the incompatibility.\n"));
8190 break;
8191
8192 default:
8193 /*
8194 * All errata which allow the pool to be imported
8195 * must contain an action message.
8196 */
8197 assert(0);
8198 }
8199 break;
8200
8201 default:
8202 /*
8203 * The remaining errors can't actually be generated, yet.
8204 */
8205 assert(reason == ZPOOL_STATUS_OK);
8206 }
8207
8208 if (msgid != NULL) {
8209 printf(" ");
8210 printf_color(ANSI_BOLD, gettext("see:"));
8211 printf(gettext(
8212 " https://openzfs.github.io/openzfs-docs/msg/%s\n"),
8213 msgid);
8214 }
8215
8216 if (config != NULL) {
8217 uint64_t nerr;
8218 nvlist_t **spares, **l2cache;
8219 uint_t nspares, nl2cache;
8220 pool_checkpoint_stat_t *pcs = NULL;
8221 pool_removal_stat_t *prs = NULL;
8222
8223 print_scan_status(zhp, nvroot);
8224
8225 (void) nvlist_lookup_uint64_array(nvroot,
8226 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c);
8227 print_removal_status(zhp, prs);
8228
8229 (void) nvlist_lookup_uint64_array(nvroot,
8230 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
8231 print_checkpoint_status(pcs);
8232
8233 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
8234 cbp->cb_name_flags | VDEV_NAME_TYPE_ID);
8235 if (cbp->cb_namewidth < 10)
8236 cbp->cb_namewidth = 10;
8237
8238 color_start(ANSI_BOLD);
8239 (void) printf(gettext("config:\n\n"));
8240 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s"),
8241 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE",
8242 "CKSUM");
8243 color_end();
8244
8245 if (cbp->cb_print_slow_ios) {
8246 printf_color(ANSI_BOLD, " %5s", gettext("SLOW"));
8247 }
8248
8249 if (cbp->vcdl != NULL)
8250 print_cmd_columns(cbp->vcdl, 0);
8251
8252 printf("\n");
8253
8254 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0,
8255 B_FALSE, NULL);
8256
8257 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP);
8258 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
8259 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS);
8260
8261 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
8262 &l2cache, &nl2cache) == 0)
8263 print_l2cache(zhp, cbp, l2cache, nl2cache);
8264
8265 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
8266 &spares, &nspares) == 0)
8267 print_spares(zhp, cbp, spares, nspares);
8268
8269 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
8270 &nerr) == 0) {
8271 nvlist_t *nverrlist = NULL;
8272
8273 /*
8274 * If the approximate error count is small, get a
8275 * precise count by fetching the entire log and
8276 * uniquifying the results.
8277 */
8278 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
8279 zpool_get_errlog(zhp, &nverrlist) == 0) {
8280 nvpair_t *elem;
8281
8282 elem = NULL;
8283 nerr = 0;
8284 while ((elem = nvlist_next_nvpair(nverrlist,
8285 elem)) != NULL) {
8286 nerr++;
8287 }
8288 }
8289 nvlist_free(nverrlist);
8290
8291 (void) printf("\n");
8292
8293 if (nerr == 0)
8294 (void) printf(gettext("errors: No known data "
8295 "errors\n"));
8296 else if (!cbp->cb_verbose)
8297 (void) printf(gettext("errors: %llu data "
8298 "errors, use '-v' for a list\n"),
8299 (u_longlong_t)nerr);
8300 else
8301 print_error_log(zhp);
8302 }
8303
8304 if (cbp->cb_dedup_stats)
8305 print_dedup_stats(config);
8306 } else {
8307 (void) printf(gettext("config: The configuration cannot be "
8308 "determined.\n"));
8309 }
8310
8311 return (0);
8312 }
8313
8314 /*
8315 * zpool status [-c [script1,script2,...]] [-igLpPstvx] [-T d|u] [pool] ...
8316 * [interval [count]]
8317 *
8318 * -c CMD For each vdev, run command CMD
8319 * -i Display vdev initialization status.
8320 * -g Display guid for individual vdev name.
8321 * -L Follow links when resolving vdev path name.
8322 * -p Display values in parsable (exact) format.
8323 * -P Display full path for vdev name.
8324 * -s Display slow IOs column.
8325 * -v Display complete error logs
8326 * -x Display only pools with potential problems
8327 * -D Display dedup status (undocumented)
8328 * -t Display vdev TRIM status.
8329 * -T Display a timestamp in date(1) or Unix format
8330 *
8331 * Describes the health status of all pools or some subset.
8332 */
8333 int
8334 zpool_do_status(int argc, char **argv)
8335 {
8336 int c;
8337 int ret;
8338 float interval = 0;
8339 unsigned long count = 0;
8340 status_cbdata_t cb = { 0 };
8341 char *cmd = NULL;
8342
8343 /* check options */
8344 while ((c = getopt(argc, argv, "c:igLpPsvxDtT:")) != -1) {
8345 switch (c) {
8346 case 'c':
8347 if (cmd != NULL) {
8348 fprintf(stderr,
8349 gettext("Can't set -c flag twice\n"));
8350 exit(1);
8351 }
8352
8353 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
8354 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
8355 fprintf(stderr, gettext(
8356 "Can't run -c, disabled by "
8357 "ZPOOL_SCRIPTS_ENABLED.\n"));
8358 exit(1);
8359 }
8360
8361 if ((getuid() <= 0 || geteuid() <= 0) &&
8362 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
8363 fprintf(stderr, gettext(
8364 "Can't run -c with root privileges "
8365 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
8366 exit(1);
8367 }
8368 cmd = optarg;
8369 break;
8370 case 'i':
8371 cb.cb_print_vdev_init = B_TRUE;
8372 break;
8373 case 'g':
8374 cb.cb_name_flags |= VDEV_NAME_GUID;
8375 break;
8376 case 'L':
8377 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
8378 break;
8379 case 'p':
8380 cb.cb_literal = B_TRUE;
8381 break;
8382 case 'P':
8383 cb.cb_name_flags |= VDEV_NAME_PATH;
8384 break;
8385 case 's':
8386 cb.cb_print_slow_ios = B_TRUE;
8387 break;
8388 case 'v':
8389 cb.cb_verbose = B_TRUE;
8390 break;
8391 case 'x':
8392 cb.cb_explain = B_TRUE;
8393 break;
8394 case 'D':
8395 cb.cb_dedup_stats = B_TRUE;
8396 break;
8397 case 't':
8398 cb.cb_print_vdev_trim = B_TRUE;
8399 break;
8400 case 'T':
8401 get_timestamp_arg(*optarg);
8402 break;
8403 case '?':
8404 if (optopt == 'c') {
8405 print_zpool_script_list("status");
8406 exit(0);
8407 } else {
8408 fprintf(stderr,
8409 gettext("invalid option '%c'\n"), optopt);
8410 }
8411 usage(B_FALSE);
8412 }
8413 }
8414
8415 argc -= optind;
8416 argv += optind;
8417
8418 get_interval_count(&argc, argv, &interval, &count);
8419
8420 if (argc == 0)
8421 cb.cb_allpools = B_TRUE;
8422
8423 cb.cb_first = B_TRUE;
8424 cb.cb_print_status = B_TRUE;
8425
8426 for (;;) {
8427 if (timestamp_fmt != NODATE)
8428 print_timestamp(timestamp_fmt);
8429
8430 if (cmd != NULL)
8431 cb.vcdl = all_pools_for_each_vdev_run(argc, argv, cmd,
8432 NULL, NULL, 0, 0);
8433
8434 ret = for_each_pool(argc, argv, B_TRUE, NULL,
8435 status_callback, &cb);
8436
8437 if (cb.vcdl != NULL)
8438 free_vdev_cmd_data_list(cb.vcdl);
8439
8440 if (argc == 0 && cb.cb_count == 0)
8441 (void) fprintf(stderr, gettext("no pools available\n"));
8442 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
8443 (void) printf(gettext("all pools are healthy\n"));
8444
8445 if (ret != 0)
8446 return (ret);
8447
8448 if (interval == 0)
8449 break;
8450
8451 if (count != 0 && --count == 0)
8452 break;
8453
8454 (void) fsleep(interval);
8455 }
8456
8457 return (0);
8458 }
8459
8460 typedef struct upgrade_cbdata {
8461 int cb_first;
8462 int cb_argc;
8463 uint64_t cb_version;
8464 char **cb_argv;
8465 } upgrade_cbdata_t;
8466
8467 static int
8468 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
8469 {
8470 int zfs_version = (int)zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
8471 int *count = (int *)unsupp_fs;
8472
8473 if (zfs_version > ZPL_VERSION) {
8474 (void) printf(gettext("%s (v%d) is not supported by this "
8475 "implementation of ZFS.\n"),
8476 zfs_get_name(zhp), zfs_version);
8477 (*count)++;
8478 }
8479
8480 zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
8481
8482 zfs_close(zhp);
8483
8484 return (0);
8485 }
8486
8487 static int
8488 upgrade_version(zpool_handle_t *zhp, uint64_t version)
8489 {
8490 int ret;
8491 nvlist_t *config;
8492 uint64_t oldversion;
8493 int unsupp_fs = 0;
8494
8495 config = zpool_get_config(zhp, NULL);
8496 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
8497 &oldversion) == 0);
8498
8499 assert(SPA_VERSION_IS_SUPPORTED(oldversion));
8500 assert(oldversion < version);
8501
8502 ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
8503 if (ret != 0)
8504 return (ret);
8505
8506 if (unsupp_fs) {
8507 (void) fprintf(stderr, gettext("Upgrade not performed due "
8508 "to %d unsupported filesystems (max v%d).\n"),
8509 unsupp_fs, (int)ZPL_VERSION);
8510 return (1);
8511 }
8512
8513 ret = zpool_upgrade(zhp, version);
8514 if (ret != 0)
8515 return (ret);
8516
8517 if (version >= SPA_VERSION_FEATURES) {
8518 (void) printf(gettext("Successfully upgraded "
8519 "'%s' from version %llu to feature flags.\n"),
8520 zpool_get_name(zhp), (u_longlong_t)oldversion);
8521 } else {
8522 (void) printf(gettext("Successfully upgraded "
8523 "'%s' from version %llu to version %llu.\n"),
8524 zpool_get_name(zhp), (u_longlong_t)oldversion,
8525 (u_longlong_t)version);
8526 }
8527
8528 return (0);
8529 }
8530
8531 static int
8532 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
8533 {
8534 int i, ret, count;
8535 boolean_t firstff = B_TRUE;
8536 nvlist_t *enabled = zpool_get_features(zhp);
8537
8538 count = 0;
8539 for (i = 0; i < SPA_FEATURES; i++) {
8540 const char *fname = spa_feature_table[i].fi_uname;
8541 const char *fguid = spa_feature_table[i].fi_guid;
8542 if (!nvlist_exists(enabled, fguid)) {
8543 char *propname;
8544 verify(-1 != asprintf(&propname, "feature@%s", fname));
8545 ret = zpool_set_prop(zhp, propname,
8546 ZFS_FEATURE_ENABLED);
8547 if (ret != 0) {
8548 free(propname);
8549 return (ret);
8550 }
8551 count++;
8552
8553 if (firstff) {
8554 (void) printf(gettext("Enabled the "
8555 "following features on '%s':\n"),
8556 zpool_get_name(zhp));
8557 firstff = B_FALSE;
8558 }
8559 (void) printf(gettext(" %s\n"), fname);
8560 free(propname);
8561 }
8562 }
8563
8564 if (countp != NULL)
8565 *countp = count;
8566 return (0);
8567 }
8568
8569 static int
8570 upgrade_cb(zpool_handle_t *zhp, void *arg)
8571 {
8572 upgrade_cbdata_t *cbp = arg;
8573 nvlist_t *config;
8574 uint64_t version;
8575 boolean_t printnl = B_FALSE;
8576 int ret;
8577
8578 config = zpool_get_config(zhp, NULL);
8579 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
8580 &version) == 0);
8581
8582 assert(SPA_VERSION_IS_SUPPORTED(version));
8583
8584 if (version < cbp->cb_version) {
8585 cbp->cb_first = B_FALSE;
8586 ret = upgrade_version(zhp, cbp->cb_version);
8587 if (ret != 0)
8588 return (ret);
8589 printnl = B_TRUE;
8590
8591 /*
8592 * If they did "zpool upgrade -a", then we could
8593 * be doing ioctls to different pools. We need
8594 * to log this history once to each pool, and bypass
8595 * the normal history logging that happens in main().
8596 */
8597 (void) zpool_log_history(g_zfs, history_str);
8598 log_history = B_FALSE;
8599 }
8600
8601 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
8602 int count;
8603 ret = upgrade_enable_all(zhp, &count);
8604 if (ret != 0)
8605 return (ret);
8606
8607 if (count > 0) {
8608 cbp->cb_first = B_FALSE;
8609 printnl = B_TRUE;
8610 }
8611 }
8612
8613 if (printnl) {
8614 (void) printf(gettext("\n"));
8615 }
8616
8617 return (0);
8618 }
8619
8620 static int
8621 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
8622 {
8623 upgrade_cbdata_t *cbp = arg;
8624 nvlist_t *config;
8625 uint64_t version;
8626
8627 config = zpool_get_config(zhp, NULL);
8628 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
8629 &version) == 0);
8630
8631 assert(SPA_VERSION_IS_SUPPORTED(version));
8632
8633 if (version < SPA_VERSION_FEATURES) {
8634 if (cbp->cb_first) {
8635 (void) printf(gettext("The following pools are "
8636 "formatted with legacy version numbers and can\n"
8637 "be upgraded to use feature flags. After "
8638 "being upgraded, these pools\nwill no "
8639 "longer be accessible by software that does not "
8640 "support feature\nflags.\n\n"));
8641 (void) printf(gettext("VER POOL\n"));
8642 (void) printf(gettext("--- ------------\n"));
8643 cbp->cb_first = B_FALSE;
8644 }
8645
8646 (void) printf("%2llu %s\n", (u_longlong_t)version,
8647 zpool_get_name(zhp));
8648 }
8649
8650 return (0);
8651 }
8652
8653 static int
8654 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
8655 {
8656 upgrade_cbdata_t *cbp = arg;
8657 nvlist_t *config;
8658 uint64_t version;
8659
8660 config = zpool_get_config(zhp, NULL);
8661 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
8662 &version) == 0);
8663
8664 if (version >= SPA_VERSION_FEATURES) {
8665 int i;
8666 boolean_t poolfirst = B_TRUE;
8667 nvlist_t *enabled = zpool_get_features(zhp);
8668
8669 for (i = 0; i < SPA_FEATURES; i++) {
8670 const char *fguid = spa_feature_table[i].fi_guid;
8671 const char *fname = spa_feature_table[i].fi_uname;
8672 if (!nvlist_exists(enabled, fguid)) {
8673 if (cbp->cb_first) {
8674 (void) printf(gettext("\nSome "
8675 "supported features are not "
8676 "enabled on the following pools. "
8677 "Once a\nfeature is enabled the "
8678 "pool may become incompatible with "
8679 "software\nthat does not support "
8680 "the feature. See "
8681 "zpool-features(5) for "
8682 "details.\n\n"));
8683 (void) printf(gettext("POOL "
8684 "FEATURE\n"));
8685 (void) printf(gettext("------"
8686 "---------\n"));
8687 cbp->cb_first = B_FALSE;
8688 }
8689
8690 if (poolfirst) {
8691 (void) printf(gettext("%s\n"),
8692 zpool_get_name(zhp));
8693 poolfirst = B_FALSE;
8694 }
8695
8696 (void) printf(gettext(" %s\n"), fname);
8697 }
8698 /*
8699 * If they did "zpool upgrade -a", then we could
8700 * be doing ioctls to different pools. We need
8701 * to log this history once to each pool, and bypass
8702 * the normal history logging that happens in main().
8703 */
8704 (void) zpool_log_history(g_zfs, history_str);
8705 log_history = B_FALSE;
8706 }
8707 }
8708
8709 return (0);
8710 }
8711
8712 /* ARGSUSED */
8713 static int
8714 upgrade_one(zpool_handle_t *zhp, void *data)
8715 {
8716 boolean_t printnl = B_FALSE;
8717 upgrade_cbdata_t *cbp = data;
8718 uint64_t cur_version;
8719 int ret;
8720
8721 if (strcmp("log", zpool_get_name(zhp)) == 0) {
8722 (void) fprintf(stderr, gettext("'log' is now a reserved word\n"
8723 "Pool 'log' must be renamed using export and import"
8724 " to upgrade.\n"));
8725 return (1);
8726 }
8727
8728 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
8729 if (cur_version > cbp->cb_version) {
8730 (void) printf(gettext("Pool '%s' is already formatted "
8731 "using more current version '%llu'.\n\n"),
8732 zpool_get_name(zhp), (u_longlong_t)cur_version);
8733 return (0);
8734 }
8735
8736 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
8737 (void) printf(gettext("Pool '%s' is already formatted "
8738 "using version %llu.\n\n"), zpool_get_name(zhp),
8739 (u_longlong_t)cbp->cb_version);
8740 return (0);
8741 }
8742
8743 if (cur_version != cbp->cb_version) {
8744 printnl = B_TRUE;
8745 ret = upgrade_version(zhp, cbp->cb_version);
8746 if (ret != 0)
8747 return (ret);
8748 }
8749
8750 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
8751 int count = 0;
8752 ret = upgrade_enable_all(zhp, &count);
8753 if (ret != 0)
8754 return (ret);
8755
8756 if (count != 0) {
8757 printnl = B_TRUE;
8758 } else if (cur_version == SPA_VERSION) {
8759 (void) printf(gettext("Pool '%s' already has all "
8760 "supported features enabled.\n"),
8761 zpool_get_name(zhp));
8762 }
8763 }
8764
8765 if (printnl) {
8766 (void) printf(gettext("\n"));
8767 }
8768
8769 return (0);
8770 }
8771
8772 /*
8773 * zpool upgrade
8774 * zpool upgrade -v
8775 * zpool upgrade [-V version] <-a | pool ...>
8776 *
8777 * With no arguments, display downrev'd ZFS pool available for upgrade.
8778 * Individual pools can be upgraded by specifying the pool, and '-a' will
8779 * upgrade all pools.
8780 */
8781 int
8782 zpool_do_upgrade(int argc, char **argv)
8783 {
8784 int c;
8785 upgrade_cbdata_t cb = { 0 };
8786 int ret = 0;
8787 boolean_t showversions = B_FALSE;
8788 boolean_t upgradeall = B_FALSE;
8789 char *end;
8790
8791
8792 /* check options */
8793 while ((c = getopt(argc, argv, ":avV:")) != -1) {
8794 switch (c) {
8795 case 'a':
8796 upgradeall = B_TRUE;
8797 break;
8798 case 'v':
8799 showversions = B_TRUE;
8800 break;
8801 case 'V':
8802 cb.cb_version = strtoll(optarg, &end, 10);
8803 if (*end != '\0' ||
8804 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
8805 (void) fprintf(stderr,
8806 gettext("invalid version '%s'\n"), optarg);
8807 usage(B_FALSE);
8808 }
8809 break;
8810 case ':':
8811 (void) fprintf(stderr, gettext("missing argument for "
8812 "'%c' option\n"), optopt);
8813 usage(B_FALSE);
8814 break;
8815 case '?':
8816 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
8817 optopt);
8818 usage(B_FALSE);
8819 }
8820 }
8821
8822 cb.cb_argc = argc;
8823 cb.cb_argv = argv;
8824 argc -= optind;
8825 argv += optind;
8826
8827 if (cb.cb_version == 0) {
8828 cb.cb_version = SPA_VERSION;
8829 } else if (!upgradeall && argc == 0) {
8830 (void) fprintf(stderr, gettext("-V option is "
8831 "incompatible with other arguments\n"));
8832 usage(B_FALSE);
8833 }
8834
8835 if (showversions) {
8836 if (upgradeall || argc != 0) {
8837 (void) fprintf(stderr, gettext("-v option is "
8838 "incompatible with other arguments\n"));
8839 usage(B_FALSE);
8840 }
8841 } else if (upgradeall) {
8842 if (argc != 0) {
8843 (void) fprintf(stderr, gettext("-a option should not "
8844 "be used along with a pool name\n"));
8845 usage(B_FALSE);
8846 }
8847 }
8848
8849 (void) printf(gettext("This system supports ZFS pool feature "
8850 "flags.\n\n"));
8851 if (showversions) {
8852 int i;
8853
8854 (void) printf(gettext("The following features are "
8855 "supported:\n\n"));
8856 (void) printf(gettext("FEAT DESCRIPTION\n"));
8857 (void) printf("----------------------------------------------"
8858 "---------------\n");
8859 for (i = 0; i < SPA_FEATURES; i++) {
8860 zfeature_info_t *fi = &spa_feature_table[i];
8861 const char *ro =
8862 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
8863 " (read-only compatible)" : "";
8864
8865 (void) printf("%-37s%s\n", fi->fi_uname, ro);
8866 (void) printf(" %s\n", fi->fi_desc);
8867 }
8868 (void) printf("\n");
8869
8870 (void) printf(gettext("The following legacy versions are also "
8871 "supported:\n\n"));
8872 (void) printf(gettext("VER DESCRIPTION\n"));
8873 (void) printf("--- -----------------------------------------"
8874 "---------------\n");
8875 (void) printf(gettext(" 1 Initial ZFS version\n"));
8876 (void) printf(gettext(" 2 Ditto blocks "
8877 "(replicated metadata)\n"));
8878 (void) printf(gettext(" 3 Hot spares and double parity "
8879 "RAID-Z\n"));
8880 (void) printf(gettext(" 4 zpool history\n"));
8881 (void) printf(gettext(" 5 Compression using the gzip "
8882 "algorithm\n"));
8883 (void) printf(gettext(" 6 bootfs pool property\n"));
8884 (void) printf(gettext(" 7 Separate intent log devices\n"));
8885 (void) printf(gettext(" 8 Delegated administration\n"));
8886 (void) printf(gettext(" 9 refquota and refreservation "
8887 "properties\n"));
8888 (void) printf(gettext(" 10 Cache devices\n"));
8889 (void) printf(gettext(" 11 Improved scrub performance\n"));
8890 (void) printf(gettext(" 12 Snapshot properties\n"));
8891 (void) printf(gettext(" 13 snapused property\n"));
8892 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
8893 (void) printf(gettext(" 15 user/group space accounting\n"));
8894 (void) printf(gettext(" 16 stmf property support\n"));
8895 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
8896 (void) printf(gettext(" 18 Snapshot user holds\n"));
8897 (void) printf(gettext(" 19 Log device removal\n"));
8898 (void) printf(gettext(" 20 Compression using zle "
8899 "(zero-length encoding)\n"));
8900 (void) printf(gettext(" 21 Deduplication\n"));
8901 (void) printf(gettext(" 22 Received properties\n"));
8902 (void) printf(gettext(" 23 Slim ZIL\n"));
8903 (void) printf(gettext(" 24 System attributes\n"));
8904 (void) printf(gettext(" 25 Improved scrub stats\n"));
8905 (void) printf(gettext(" 26 Improved snapshot deletion "
8906 "performance\n"));
8907 (void) printf(gettext(" 27 Improved snapshot creation "
8908 "performance\n"));
8909 (void) printf(gettext(" 28 Multiple vdev replacements\n"));
8910 (void) printf(gettext("\nFor more information on a particular "
8911 "version, including supported releases,\n"));
8912 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
8913 } else if (argc == 0 && upgradeall) {
8914 cb.cb_first = B_TRUE;
8915 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
8916 if (ret == 0 && cb.cb_first) {
8917 if (cb.cb_version == SPA_VERSION) {
8918 (void) printf(gettext("All pools are already "
8919 "formatted using feature flags.\n\n"));
8920 (void) printf(gettext("Every feature flags "
8921 "pool already has all supported features "
8922 "enabled.\n"));
8923 } else {
8924 (void) printf(gettext("All pools are already "
8925 "formatted with version %llu or higher.\n"),
8926 (u_longlong_t)cb.cb_version);
8927 }
8928 }
8929 } else if (argc == 0) {
8930 cb.cb_first = B_TRUE;
8931 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
8932 assert(ret == 0);
8933
8934 if (cb.cb_first) {
8935 (void) printf(gettext("All pools are formatted "
8936 "using feature flags.\n\n"));
8937 } else {
8938 (void) printf(gettext("\nUse 'zpool upgrade -v' "
8939 "for a list of available legacy versions.\n"));
8940 }
8941
8942 cb.cb_first = B_TRUE;
8943 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
8944 assert(ret == 0);
8945
8946 if (cb.cb_first) {
8947 (void) printf(gettext("Every feature flags pool has "
8948 "all supported features enabled.\n"));
8949 } else {
8950 (void) printf(gettext("\n"));
8951 }
8952 } else {
8953 ret = for_each_pool(argc, argv, B_FALSE, NULL,
8954 upgrade_one, &cb);
8955 }
8956
8957 return (ret);
8958 }
8959
8960 typedef struct hist_cbdata {
8961 boolean_t first;
8962 boolean_t longfmt;
8963 boolean_t internal;
8964 } hist_cbdata_t;
8965
8966 static void
8967 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb)
8968 {
8969 nvlist_t **records;
8970 uint_t numrecords;
8971 int i;
8972
8973 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
8974 &records, &numrecords) == 0);
8975 for (i = 0; i < numrecords; i++) {
8976 nvlist_t *rec = records[i];
8977 char tbuf[30] = "";
8978
8979 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
8980 time_t tsec;
8981 struct tm t;
8982
8983 tsec = fnvlist_lookup_uint64(records[i],
8984 ZPOOL_HIST_TIME);
8985 (void) localtime_r(&tsec, &t);
8986 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
8987 }
8988
8989 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
8990 (void) printf("%s %s", tbuf,
8991 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
8992 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
8993 int ievent =
8994 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
8995 if (!cb->internal)
8996 continue;
8997 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
8998 (void) printf("%s unrecognized record:\n",
8999 tbuf);
9000 dump_nvlist(rec, 4);
9001 continue;
9002 }
9003 (void) printf("%s [internal %s txg:%lld] %s", tbuf,
9004 zfs_history_event_names[ievent],
9005 (longlong_t)fnvlist_lookup_uint64(
9006 rec, ZPOOL_HIST_TXG),
9007 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
9008 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
9009 if (!cb->internal)
9010 continue;
9011 (void) printf("%s [txg:%lld] %s", tbuf,
9012 (longlong_t)fnvlist_lookup_uint64(
9013 rec, ZPOOL_HIST_TXG),
9014 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
9015 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
9016 (void) printf(" %s (%llu)",
9017 fnvlist_lookup_string(rec,
9018 ZPOOL_HIST_DSNAME),
9019 (u_longlong_t)fnvlist_lookup_uint64(rec,
9020 ZPOOL_HIST_DSID));
9021 }
9022 (void) printf(" %s", fnvlist_lookup_string(rec,
9023 ZPOOL_HIST_INT_STR));
9024 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
9025 if (!cb->internal)
9026 continue;
9027 (void) printf("%s ioctl %s\n", tbuf,
9028 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
9029 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
9030 (void) printf(" input:\n");
9031 dump_nvlist(fnvlist_lookup_nvlist(rec,
9032 ZPOOL_HIST_INPUT_NVL), 8);
9033 }
9034 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
9035 (void) printf(" output:\n");
9036 dump_nvlist(fnvlist_lookup_nvlist(rec,
9037 ZPOOL_HIST_OUTPUT_NVL), 8);
9038 }
9039 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
9040 (void) printf(" errno: %lld\n",
9041 (longlong_t)fnvlist_lookup_int64(rec,
9042 ZPOOL_HIST_ERRNO));
9043 }
9044 } else {
9045 if (!cb->internal)
9046 continue;
9047 (void) printf("%s unrecognized record:\n", tbuf);
9048 dump_nvlist(rec, 4);
9049 }
9050
9051 if (!cb->longfmt) {
9052 (void) printf("\n");
9053 continue;
9054 }
9055 (void) printf(" [");
9056 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
9057 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
9058 struct passwd *pwd = getpwuid(who);
9059 (void) printf("user %d ", (int)who);
9060 if (pwd != NULL)
9061 (void) printf("(%s) ", pwd->pw_name);
9062 }
9063 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
9064 (void) printf("on %s",
9065 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
9066 }
9067 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
9068 (void) printf(":%s",
9069 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
9070 }
9071
9072 (void) printf("]");
9073 (void) printf("\n");
9074 }
9075 }
9076
9077 /*
9078 * Print out the command history for a specific pool.
9079 */
9080 static int
9081 get_history_one(zpool_handle_t *zhp, void *data)
9082 {
9083 nvlist_t *nvhis;
9084 int ret;
9085 hist_cbdata_t *cb = (hist_cbdata_t *)data;
9086 uint64_t off = 0;
9087 boolean_t eof = B_FALSE;
9088
9089 cb->first = B_FALSE;
9090
9091 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
9092
9093 while (!eof) {
9094 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0)
9095 return (ret);
9096
9097 print_history_records(nvhis, cb);
9098 nvlist_free(nvhis);
9099 }
9100 (void) printf("\n");
9101
9102 return (ret);
9103 }
9104
9105 /*
9106 * zpool history <pool>
9107 *
9108 * Displays the history of commands that modified pools.
9109 */
9110 int
9111 zpool_do_history(int argc, char **argv)
9112 {
9113 hist_cbdata_t cbdata = { 0 };
9114 int ret;
9115 int c;
9116
9117 cbdata.first = B_TRUE;
9118 /* check options */
9119 while ((c = getopt(argc, argv, "li")) != -1) {
9120 switch (c) {
9121 case 'l':
9122 cbdata.longfmt = B_TRUE;
9123 break;
9124 case 'i':
9125 cbdata.internal = B_TRUE;
9126 break;
9127 case '?':
9128 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
9129 optopt);
9130 usage(B_FALSE);
9131 }
9132 }
9133 argc -= optind;
9134 argv += optind;
9135
9136 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
9137 &cbdata);
9138
9139 if (argc == 0 && cbdata.first == B_TRUE) {
9140 (void) fprintf(stderr, gettext("no pools available\n"));
9141 return (0);
9142 }
9143
9144 return (ret);
9145 }
9146
9147 typedef struct ev_opts {
9148 int verbose;
9149 int scripted;
9150 int follow;
9151 int clear;
9152 char poolname[ZFS_MAX_DATASET_NAME_LEN];
9153 } ev_opts_t;
9154
9155 static void
9156 zpool_do_events_short(nvlist_t *nvl, ev_opts_t *opts)
9157 {
9158 char ctime_str[26], str[32], *ptr;
9159 int64_t *tv;
9160 uint_t n;
9161
9162 verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
9163 memset(str, ' ', 32);
9164 (void) ctime_r((const time_t *)&tv[0], ctime_str);
9165 (void) memcpy(str, ctime_str+4, 6); /* 'Jun 30' */
9166 (void) memcpy(str+7, ctime_str+20, 4); /* '1993' */
9167 (void) memcpy(str+12, ctime_str+11, 8); /* '21:49:08' */
9168 (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */
9169 if (opts->scripted)
9170 (void) printf(gettext("%s\t"), str);
9171 else
9172 (void) printf(gettext("%s "), str);
9173
9174 verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0);
9175 (void) printf(gettext("%s\n"), ptr);
9176 }
9177
9178 static void
9179 zpool_do_events_nvprint(nvlist_t *nvl, int depth)
9180 {
9181 nvpair_t *nvp;
9182
9183 for (nvp = nvlist_next_nvpair(nvl, NULL);
9184 nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
9185
9186 data_type_t type = nvpair_type(nvp);
9187 const char *name = nvpair_name(nvp);
9188
9189 boolean_t b;
9190 uint8_t i8;
9191 uint16_t i16;
9192 uint32_t i32;
9193 uint64_t i64;
9194 char *str;
9195 nvlist_t *cnv;
9196
9197 printf(gettext("%*s%s = "), depth, "", name);
9198
9199 switch (type) {
9200 case DATA_TYPE_BOOLEAN:
9201 printf(gettext("%s"), "1");
9202 break;
9203
9204 case DATA_TYPE_BOOLEAN_VALUE:
9205 (void) nvpair_value_boolean_value(nvp, &b);
9206 printf(gettext("%s"), b ? "1" : "0");
9207 break;
9208
9209 case DATA_TYPE_BYTE:
9210 (void) nvpair_value_byte(nvp, &i8);
9211 printf(gettext("0x%x"), i8);
9212 break;
9213
9214 case DATA_TYPE_INT8:
9215 (void) nvpair_value_int8(nvp, (void *)&i8);
9216 printf(gettext("0x%x"), i8);
9217 break;
9218
9219 case DATA_TYPE_UINT8:
9220 (void) nvpair_value_uint8(nvp, &i8);
9221 printf(gettext("0x%x"), i8);
9222 break;
9223
9224 case DATA_TYPE_INT16:
9225 (void) nvpair_value_int16(nvp, (void *)&i16);
9226 printf(gettext("0x%x"), i16);
9227 break;
9228
9229 case DATA_TYPE_UINT16:
9230 (void) nvpair_value_uint16(nvp, &i16);
9231 printf(gettext("0x%x"), i16);
9232 break;
9233
9234 case DATA_TYPE_INT32:
9235 (void) nvpair_value_int32(nvp, (void *)&i32);
9236 printf(gettext("0x%x"), i32);
9237 break;
9238
9239 case DATA_TYPE_UINT32:
9240 (void) nvpair_value_uint32(nvp, &i32);
9241 printf(gettext("0x%x"), i32);
9242 break;
9243
9244 case DATA_TYPE_INT64:
9245 (void) nvpair_value_int64(nvp, (void *)&i64);
9246 printf(gettext("0x%llx"), (u_longlong_t)i64);
9247 break;
9248
9249 case DATA_TYPE_UINT64:
9250 (void) nvpair_value_uint64(nvp, &i64);
9251 /*
9252 * translate vdev state values to readable
9253 * strings to aide zpool events consumers
9254 */
9255 if (strcmp(name,
9256 FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 ||
9257 strcmp(name,
9258 FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) {
9259 printf(gettext("\"%s\" (0x%llx)"),
9260 zpool_state_to_name(i64, VDEV_AUX_NONE),
9261 (u_longlong_t)i64);
9262 } else {
9263 printf(gettext("0x%llx"), (u_longlong_t)i64);
9264 }
9265 break;
9266
9267 case DATA_TYPE_HRTIME:
9268 (void) nvpair_value_hrtime(nvp, (void *)&i64);
9269 printf(gettext("0x%llx"), (u_longlong_t)i64);
9270 break;
9271
9272 case DATA_TYPE_STRING:
9273 (void) nvpair_value_string(nvp, &str);
9274 printf(gettext("\"%s\""), str ? str : "<NULL>");
9275 break;
9276
9277 case DATA_TYPE_NVLIST:
9278 printf(gettext("(embedded nvlist)\n"));
9279 (void) nvpair_value_nvlist(nvp, &cnv);
9280 zpool_do_events_nvprint(cnv, depth + 8);
9281 printf(gettext("%*s(end %s)"), depth, "", name);
9282 break;
9283
9284 case DATA_TYPE_NVLIST_ARRAY: {
9285 nvlist_t **val;
9286 uint_t i, nelem;
9287
9288 (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
9289 printf(gettext("(%d embedded nvlists)\n"), nelem);
9290 for (i = 0; i < nelem; i++) {
9291 printf(gettext("%*s%s[%d] = %s\n"),
9292 depth, "", name, i, "(embedded nvlist)");
9293 zpool_do_events_nvprint(val[i], depth + 8);
9294 printf(gettext("%*s(end %s[%i])\n"),
9295 depth, "", name, i);
9296 }
9297 printf(gettext("%*s(end %s)\n"), depth, "", name);
9298 }
9299 break;
9300
9301 case DATA_TYPE_INT8_ARRAY: {
9302 int8_t *val;
9303 uint_t i, nelem;
9304
9305 (void) nvpair_value_int8_array(nvp, &val, &nelem);
9306 for (i = 0; i < nelem; i++)
9307 printf(gettext("0x%x "), val[i]);
9308
9309 break;
9310 }
9311
9312 case DATA_TYPE_UINT8_ARRAY: {
9313 uint8_t *val;
9314 uint_t i, nelem;
9315
9316 (void) nvpair_value_uint8_array(nvp, &val, &nelem);
9317 for (i = 0; i < nelem; i++)
9318 printf(gettext("0x%x "), val[i]);
9319
9320 break;
9321 }
9322
9323 case DATA_TYPE_INT16_ARRAY: {
9324 int16_t *val;
9325 uint_t i, nelem;
9326
9327 (void) nvpair_value_int16_array(nvp, &val, &nelem);
9328 for (i = 0; i < nelem; i++)
9329 printf(gettext("0x%x "), val[i]);
9330
9331 break;
9332 }
9333
9334 case DATA_TYPE_UINT16_ARRAY: {
9335 uint16_t *val;
9336 uint_t i, nelem;
9337
9338 (void) nvpair_value_uint16_array(nvp, &val, &nelem);
9339 for (i = 0; i < nelem; i++)
9340 printf(gettext("0x%x "), val[i]);
9341
9342 break;
9343 }
9344
9345 case DATA_TYPE_INT32_ARRAY: {
9346 int32_t *val;
9347 uint_t i, nelem;
9348
9349 (void) nvpair_value_int32_array(nvp, &val, &nelem);
9350 for (i = 0; i < nelem; i++)
9351 printf(gettext("0x%x "), val[i]);
9352
9353 break;
9354 }
9355
9356 case DATA_TYPE_UINT32_ARRAY: {
9357 uint32_t *val;
9358 uint_t i, nelem;
9359
9360 (void) nvpair_value_uint32_array(nvp, &val, &nelem);
9361 for (i = 0; i < nelem; i++)
9362 printf(gettext("0x%x "), val[i]);
9363
9364 break;
9365 }
9366
9367 case DATA_TYPE_INT64_ARRAY: {
9368 int64_t *val;
9369 uint_t i, nelem;
9370
9371 (void) nvpair_value_int64_array(nvp, &val, &nelem);
9372 for (i = 0; i < nelem; i++)
9373 printf(gettext("0x%llx "),
9374 (u_longlong_t)val[i]);
9375
9376 break;
9377 }
9378
9379 case DATA_TYPE_UINT64_ARRAY: {
9380 uint64_t *val;
9381 uint_t i, nelem;
9382
9383 (void) nvpair_value_uint64_array(nvp, &val, &nelem);
9384 for (i = 0; i < nelem; i++)
9385 printf(gettext("0x%llx "),
9386 (u_longlong_t)val[i]);
9387
9388 break;
9389 }
9390
9391 case DATA_TYPE_STRING_ARRAY: {
9392 char **str;
9393 uint_t i, nelem;
9394
9395 (void) nvpair_value_string_array(nvp, &str, &nelem);
9396 for (i = 0; i < nelem; i++)
9397 printf(gettext("\"%s\" "),
9398 str[i] ? str[i] : "<NULL>");
9399
9400 break;
9401 }
9402
9403 case DATA_TYPE_BOOLEAN_ARRAY:
9404 case DATA_TYPE_BYTE_ARRAY:
9405 case DATA_TYPE_DOUBLE:
9406 case DATA_TYPE_DONTCARE:
9407 case DATA_TYPE_UNKNOWN:
9408 printf(gettext("<unknown>"));
9409 break;
9410 }
9411
9412 printf(gettext("\n"));
9413 }
9414 }
9415
9416 static int
9417 zpool_do_events_next(ev_opts_t *opts)
9418 {
9419 nvlist_t *nvl;
9420 int zevent_fd, ret, dropped;
9421 char *pool;
9422
9423 zevent_fd = open(ZFS_DEV, O_RDWR);
9424 VERIFY(zevent_fd >= 0);
9425
9426 if (!opts->scripted)
9427 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
9428
9429 while (1) {
9430 ret = zpool_events_next(g_zfs, &nvl, &dropped,
9431 (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd);
9432 if (ret || nvl == NULL)
9433 break;
9434
9435 if (dropped > 0)
9436 (void) printf(gettext("dropped %d events\n"), dropped);
9437
9438 if (strlen(opts->poolname) > 0 &&
9439 nvlist_lookup_string(nvl, FM_FMRI_ZFS_POOL, &pool) == 0 &&
9440 strcmp(opts->poolname, pool) != 0)
9441 continue;
9442
9443 zpool_do_events_short(nvl, opts);
9444
9445 if (opts->verbose) {
9446 zpool_do_events_nvprint(nvl, 8);
9447 printf(gettext("\n"));
9448 }
9449 (void) fflush(stdout);
9450
9451 nvlist_free(nvl);
9452 }
9453
9454 VERIFY(0 == close(zevent_fd));
9455
9456 return (ret);
9457 }
9458
9459 static int
9460 zpool_do_events_clear(ev_opts_t *opts)
9461 {
9462 int count, ret;
9463
9464 ret = zpool_events_clear(g_zfs, &count);
9465 if (!ret)
9466 (void) printf(gettext("cleared %d events\n"), count);
9467
9468 return (ret);
9469 }
9470
9471 /*
9472 * zpool events [-vHf [pool] | -c]
9473 *
9474 * Displays events logs by ZFS.
9475 */
9476 int
9477 zpool_do_events(int argc, char **argv)
9478 {
9479 ev_opts_t opts = { 0 };
9480 int ret;
9481 int c;
9482
9483 /* check options */
9484 while ((c = getopt(argc, argv, "vHfc")) != -1) {
9485 switch (c) {
9486 case 'v':
9487 opts.verbose = 1;
9488 break;
9489 case 'H':
9490 opts.scripted = 1;
9491 break;
9492 case 'f':
9493 opts.follow = 1;
9494 break;
9495 case 'c':
9496 opts.clear = 1;
9497 break;
9498 case '?':
9499 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
9500 optopt);
9501 usage(B_FALSE);
9502 }
9503 }
9504 argc -= optind;
9505 argv += optind;
9506
9507 if (argc > 1) {
9508 (void) fprintf(stderr, gettext("too many arguments\n"));
9509 usage(B_FALSE);
9510 } else if (argc == 1) {
9511 (void) strlcpy(opts.poolname, argv[0], sizeof (opts.poolname));
9512 if (!zfs_name_valid(opts.poolname, ZFS_TYPE_POOL)) {
9513 (void) fprintf(stderr,
9514 gettext("invalid pool name '%s'\n"), opts.poolname);
9515 usage(B_FALSE);
9516 }
9517 }
9518
9519 if ((argc == 1 || opts.verbose || opts.scripted || opts.follow) &&
9520 opts.clear) {
9521 (void) fprintf(stderr,
9522 gettext("invalid options combined with -c\n"));
9523 usage(B_FALSE);
9524 }
9525
9526 if (opts.clear)
9527 ret = zpool_do_events_clear(&opts);
9528 else
9529 ret = zpool_do_events_next(&opts);
9530
9531 return (ret);
9532 }
9533
9534 static int
9535 get_callback(zpool_handle_t *zhp, void *data)
9536 {
9537 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
9538 char value[MAXNAMELEN];
9539 zprop_source_t srctype;
9540 zprop_list_t *pl;
9541
9542 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
9543
9544 /*
9545 * Skip the special fake placeholder. This will also skip
9546 * over the name property when 'all' is specified.
9547 */
9548 if (pl->pl_prop == ZPOOL_PROP_NAME &&
9549 pl == cbp->cb_proplist)
9550 continue;
9551
9552 if (pl->pl_prop == ZPROP_INVAL &&
9553 (zpool_prop_feature(pl->pl_user_prop) ||
9554 zpool_prop_unsupported(pl->pl_user_prop))) {
9555 srctype = ZPROP_SRC_LOCAL;
9556
9557 if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
9558 value, sizeof (value)) == 0) {
9559 zprop_print_one_property(zpool_get_name(zhp),
9560 cbp, pl->pl_user_prop, value, srctype,
9561 NULL, NULL);
9562 }
9563 } else {
9564 if (zpool_get_prop(zhp, pl->pl_prop, value,
9565 sizeof (value), &srctype, cbp->cb_literal) != 0)
9566 continue;
9567
9568 zprop_print_one_property(zpool_get_name(zhp), cbp,
9569 zpool_prop_to_name(pl->pl_prop), value, srctype,
9570 NULL, NULL);
9571 }
9572 }
9573 return (0);
9574 }
9575
9576 /*
9577 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
9578 *
9579 * -H Scripted mode. Don't display headers, and separate properties
9580 * by a single tab.
9581 * -o List of columns to display. Defaults to
9582 * "name,property,value,source".
9583 * -p Display values in parsable (exact) format.
9584 *
9585 * Get properties of pools in the system. Output space statistics
9586 * for each one as well as other attributes.
9587 */
9588 int
9589 zpool_do_get(int argc, char **argv)
9590 {
9591 zprop_get_cbdata_t cb = { 0 };
9592 zprop_list_t fake_name = { 0 };
9593 int ret;
9594 int c, i;
9595 char *value;
9596
9597 cb.cb_first = B_TRUE;
9598
9599 /*
9600 * Set up default columns and sources.
9601 */
9602 cb.cb_sources = ZPROP_SRC_ALL;
9603 cb.cb_columns[0] = GET_COL_NAME;
9604 cb.cb_columns[1] = GET_COL_PROPERTY;
9605 cb.cb_columns[2] = GET_COL_VALUE;
9606 cb.cb_columns[3] = GET_COL_SOURCE;
9607 cb.cb_type = ZFS_TYPE_POOL;
9608
9609 /* check options */
9610 while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
9611 switch (c) {
9612 case 'p':
9613 cb.cb_literal = B_TRUE;
9614 break;
9615 case 'H':
9616 cb.cb_scripted = B_TRUE;
9617 break;
9618 case 'o':
9619 bzero(&cb.cb_columns, sizeof (cb.cb_columns));
9620 i = 0;
9621 while (*optarg != '\0') {
9622 static char *col_subopts[] =
9623 { "name", "property", "value", "source",
9624 "all", NULL };
9625
9626 if (i == ZFS_GET_NCOLS) {
9627 (void) fprintf(stderr, gettext("too "
9628 "many fields given to -o "
9629 "option\n"));
9630 usage(B_FALSE);
9631 }
9632
9633 switch (getsubopt(&optarg, col_subopts,
9634 &value)) {
9635 case 0:
9636 cb.cb_columns[i++] = GET_COL_NAME;
9637 break;
9638 case 1:
9639 cb.cb_columns[i++] = GET_COL_PROPERTY;
9640 break;
9641 case 2:
9642 cb.cb_columns[i++] = GET_COL_VALUE;
9643 break;
9644 case 3:
9645 cb.cb_columns[i++] = GET_COL_SOURCE;
9646 break;
9647 case 4:
9648 if (i > 0) {
9649 (void) fprintf(stderr,
9650 gettext("\"all\" conflicts "
9651 "with specific fields "
9652 "given to -o option\n"));
9653 usage(B_FALSE);
9654 }
9655 cb.cb_columns[0] = GET_COL_NAME;
9656 cb.cb_columns[1] = GET_COL_PROPERTY;
9657 cb.cb_columns[2] = GET_COL_VALUE;
9658 cb.cb_columns[3] = GET_COL_SOURCE;
9659 i = ZFS_GET_NCOLS;
9660 break;
9661 default:
9662 (void) fprintf(stderr,
9663 gettext("invalid column name "
9664 "'%s'\n"), value);
9665 usage(B_FALSE);
9666 }
9667 }
9668 break;
9669 case '?':
9670 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
9671 optopt);
9672 usage(B_FALSE);
9673 }
9674 }
9675
9676 argc -= optind;
9677 argv += optind;
9678
9679 if (argc < 1) {
9680 (void) fprintf(stderr, gettext("missing property "
9681 "argument\n"));
9682 usage(B_FALSE);
9683 }
9684
9685 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
9686 ZFS_TYPE_POOL) != 0)
9687 usage(B_FALSE);
9688
9689 argc--;
9690 argv++;
9691
9692 if (cb.cb_proplist != NULL) {
9693 fake_name.pl_prop = ZPOOL_PROP_NAME;
9694 fake_name.pl_width = strlen(gettext("NAME"));
9695 fake_name.pl_next = cb.cb_proplist;
9696 cb.cb_proplist = &fake_name;
9697 }
9698
9699 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
9700 get_callback, &cb);
9701
9702 if (cb.cb_proplist == &fake_name)
9703 zprop_free_list(fake_name.pl_next);
9704 else
9705 zprop_free_list(cb.cb_proplist);
9706
9707 return (ret);
9708 }
9709
9710 typedef struct set_cbdata {
9711 char *cb_propname;
9712 char *cb_value;
9713 boolean_t cb_any_successful;
9714 } set_cbdata_t;
9715
9716 static int
9717 set_callback(zpool_handle_t *zhp, void *data)
9718 {
9719 int error;
9720 set_cbdata_t *cb = (set_cbdata_t *)data;
9721
9722 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
9723
9724 if (!error)
9725 cb->cb_any_successful = B_TRUE;
9726
9727 return (error);
9728 }
9729
9730 int
9731 zpool_do_set(int argc, char **argv)
9732 {
9733 set_cbdata_t cb = { 0 };
9734 int error;
9735
9736 if (argc > 1 && argv[1][0] == '-') {
9737 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
9738 argv[1][1]);
9739 usage(B_FALSE);
9740 }
9741
9742 if (argc < 2) {
9743 (void) fprintf(stderr, gettext("missing property=value "
9744 "argument\n"));
9745 usage(B_FALSE);
9746 }
9747
9748 if (argc < 3) {
9749 (void) fprintf(stderr, gettext("missing pool name\n"));
9750 usage(B_FALSE);
9751 }
9752
9753 if (argc > 3) {
9754 (void) fprintf(stderr, gettext("too many pool names\n"));
9755 usage(B_FALSE);
9756 }
9757
9758 cb.cb_propname = argv[1];
9759 cb.cb_value = strchr(cb.cb_propname, '=');
9760 if (cb.cb_value == NULL) {
9761 (void) fprintf(stderr, gettext("missing value in "
9762 "property=value argument\n"));
9763 usage(B_FALSE);
9764 }
9765
9766 *(cb.cb_value) = '\0';
9767 cb.cb_value++;
9768
9769 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
9770 set_callback, &cb);
9771
9772 return (error);
9773 }
9774
9775 /* Add up the total number of bytes left to initialize/trim across all vdevs */
9776 static uint64_t
9777 vdev_activity_remaining(nvlist_t *nv, zpool_wait_activity_t activity)
9778 {
9779 uint64_t bytes_remaining;
9780 nvlist_t **child;
9781 uint_t c, children;
9782 vdev_stat_t *vs;
9783
9784 assert(activity == ZPOOL_WAIT_INITIALIZE ||
9785 activity == ZPOOL_WAIT_TRIM);
9786
9787 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
9788 (uint64_t **)&vs, &c) == 0);
9789
9790 if (activity == ZPOOL_WAIT_INITIALIZE &&
9791 vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE)
9792 bytes_remaining = vs->vs_initialize_bytes_est -
9793 vs->vs_initialize_bytes_done;
9794 else if (activity == ZPOOL_WAIT_TRIM &&
9795 vs->vs_trim_state == VDEV_TRIM_ACTIVE)
9796 bytes_remaining = vs->vs_trim_bytes_est -
9797 vs->vs_trim_bytes_done;
9798 else
9799 bytes_remaining = 0;
9800
9801 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
9802 &child, &children) != 0)
9803 children = 0;
9804
9805 for (c = 0; c < children; c++)
9806 bytes_remaining += vdev_activity_remaining(child[c], activity);
9807
9808 return (bytes_remaining);
9809 }
9810
9811 /* Add up the total number of bytes left to rebuild across top-level vdevs */
9812 static uint64_t
9813 vdev_activity_top_remaining(nvlist_t *nv)
9814 {
9815 uint64_t bytes_remaining = 0;
9816 nvlist_t **child;
9817 uint_t children;
9818 int error;
9819
9820 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
9821 &child, &children) != 0)
9822 children = 0;
9823
9824 for (uint_t c = 0; c < children; c++) {
9825 vdev_rebuild_stat_t *vrs;
9826 uint_t i;
9827
9828 error = nvlist_lookup_uint64_array(child[c],
9829 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i);
9830 if (error == 0) {
9831 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) {
9832 bytes_remaining += (vrs->vrs_bytes_est -
9833 vrs->vrs_bytes_rebuilt);
9834 }
9835 }
9836 }
9837
9838 return (bytes_remaining);
9839 }
9840
9841 /* Whether any vdevs are 'spare' or 'replacing' vdevs */
9842 static boolean_t
9843 vdev_any_spare_replacing(nvlist_t *nv)
9844 {
9845 nvlist_t **child;
9846 uint_t c, children;
9847 char *vdev_type;
9848
9849 (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &vdev_type);
9850
9851 if (strcmp(vdev_type, VDEV_TYPE_REPLACING) == 0 ||
9852 strcmp(vdev_type, VDEV_TYPE_SPARE) == 0) {
9853 return (B_TRUE);
9854 }
9855
9856 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
9857 &child, &children) != 0)
9858 children = 0;
9859
9860 for (c = 0; c < children; c++) {
9861 if (vdev_any_spare_replacing(child[c]))
9862 return (B_TRUE);
9863 }
9864
9865 return (B_FALSE);
9866 }
9867
9868 typedef struct wait_data {
9869 char *wd_poolname;
9870 boolean_t wd_scripted;
9871 boolean_t wd_exact;
9872 boolean_t wd_headers_once;
9873 boolean_t wd_should_exit;
9874 /* Which activities to wait for */
9875 boolean_t wd_enabled[ZPOOL_WAIT_NUM_ACTIVITIES];
9876 float wd_interval;
9877 pthread_cond_t wd_cv;
9878 pthread_mutex_t wd_mutex;
9879 } wait_data_t;
9880
9881 /*
9882 * Print to stdout a single line, containing one column for each activity that
9883 * we are waiting for specifying how many bytes of work are left for that
9884 * activity.
9885 */
9886 static void
9887 print_wait_status_row(wait_data_t *wd, zpool_handle_t *zhp, int row)
9888 {
9889 nvlist_t *config, *nvroot;
9890 uint_t c;
9891 int i;
9892 pool_checkpoint_stat_t *pcs = NULL;
9893 pool_scan_stat_t *pss = NULL;
9894 pool_removal_stat_t *prs = NULL;
9895 char *headers[] = {"DISCARD", "FREE", "INITIALIZE", "REPLACE",
9896 "REMOVE", "RESILVER", "SCRUB", "TRIM"};
9897 int col_widths[ZPOOL_WAIT_NUM_ACTIVITIES];
9898
9899 /* Calculate the width of each column */
9900 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) {
9901 /*
9902 * Make sure we have enough space in the col for pretty-printed
9903 * numbers and for the column header, and then leave a couple
9904 * spaces between cols for readability.
9905 */
9906 col_widths[i] = MAX(strlen(headers[i]), 6) + 2;
9907 }
9908
9909 /* Print header if appropriate */
9910 int term_height = terminal_height();
9911 boolean_t reprint_header = (!wd->wd_headers_once && term_height > 0 &&
9912 row % (term_height-1) == 0);
9913 if (!wd->wd_scripted && (row == 0 || reprint_header)) {
9914 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) {
9915 if (wd->wd_enabled[i])
9916 (void) printf("%*s", col_widths[i], headers[i]);
9917 }
9918 (void) printf("\n");
9919 }
9920
9921 /* Bytes of work remaining in each activity */
9922 int64_t bytes_rem[ZPOOL_WAIT_NUM_ACTIVITIES] = {0};
9923
9924 bytes_rem[ZPOOL_WAIT_FREE] =
9925 zpool_get_prop_int(zhp, ZPOOL_PROP_FREEING, NULL);
9926
9927 config = zpool_get_config(zhp, NULL);
9928 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
9929
9930 (void) nvlist_lookup_uint64_array(nvroot,
9931 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
9932 if (pcs != NULL && pcs->pcs_state == CS_CHECKPOINT_DISCARDING)
9933 bytes_rem[ZPOOL_WAIT_CKPT_DISCARD] = pcs->pcs_space;
9934
9935 (void) nvlist_lookup_uint64_array(nvroot,
9936 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c);
9937 if (prs != NULL && prs->prs_state == DSS_SCANNING)
9938 bytes_rem[ZPOOL_WAIT_REMOVE] = prs->prs_to_copy -
9939 prs->prs_copied;
9940
9941 (void) nvlist_lookup_uint64_array(nvroot,
9942 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&pss, &c);
9943 if (pss != NULL && pss->pss_state == DSS_SCANNING &&
9944 pss->pss_pass_scrub_pause == 0) {
9945 int64_t rem = pss->pss_to_examine - pss->pss_issued;
9946 if (pss->pss_func == POOL_SCAN_SCRUB)
9947 bytes_rem[ZPOOL_WAIT_SCRUB] = rem;
9948 else
9949 bytes_rem[ZPOOL_WAIT_RESILVER] = rem;
9950 } else if (check_rebuilding(nvroot, NULL)) {
9951 bytes_rem[ZPOOL_WAIT_RESILVER] =
9952 vdev_activity_top_remaining(nvroot);
9953 }
9954
9955 bytes_rem[ZPOOL_WAIT_INITIALIZE] =
9956 vdev_activity_remaining(nvroot, ZPOOL_WAIT_INITIALIZE);
9957 bytes_rem[ZPOOL_WAIT_TRIM] =
9958 vdev_activity_remaining(nvroot, ZPOOL_WAIT_TRIM);
9959
9960 /*
9961 * A replace finishes after resilvering finishes, so the amount of work
9962 * left for a replace is the same as for resilvering.
9963 *
9964 * It isn't quite correct to say that if we have any 'spare' or
9965 * 'replacing' vdevs and a resilver is happening, then a replace is in
9966 * progress, like we do here. When a hot spare is used, the faulted vdev
9967 * is not removed after the hot spare is resilvered, so parent 'spare'
9968 * vdev is not removed either. So we could have a 'spare' vdev, but be
9969 * resilvering for a different reason. However, we use it as a heuristic
9970 * because we don't have access to the DTLs, which could tell us whether
9971 * or not we have really finished resilvering a hot spare.
9972 */
9973 if (vdev_any_spare_replacing(nvroot))
9974 bytes_rem[ZPOOL_WAIT_REPLACE] = bytes_rem[ZPOOL_WAIT_RESILVER];
9975
9976 if (timestamp_fmt != NODATE)
9977 print_timestamp(timestamp_fmt);
9978
9979 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) {
9980 char buf[64];
9981 if (!wd->wd_enabled[i])
9982 continue;
9983
9984 if (wd->wd_exact)
9985 (void) snprintf(buf, sizeof (buf), "%" PRIi64,
9986 bytes_rem[i]);
9987 else
9988 zfs_nicenum(bytes_rem[i], buf, sizeof (buf));
9989
9990 if (wd->wd_scripted)
9991 (void) printf(i == 0 ? "%s" : "\t%s", buf);
9992 else
9993 (void) printf(" %*s", col_widths[i] - 1, buf);
9994 }
9995 (void) printf("\n");
9996 (void) fflush(stdout);
9997 }
9998
9999 static void *
10000 wait_status_thread(void *arg)
10001 {
10002 wait_data_t *wd = (wait_data_t *)arg;
10003 zpool_handle_t *zhp;
10004
10005 if ((zhp = zpool_open(g_zfs, wd->wd_poolname)) == NULL)
10006 return (void *)(1);
10007
10008 for (int row = 0; ; row++) {
10009 boolean_t missing;
10010 struct timespec timeout;
10011 int ret = 0;
10012 (void) clock_gettime(CLOCK_REALTIME, &timeout);
10013
10014 if (zpool_refresh_stats(zhp, &missing) != 0 || missing ||
10015 zpool_props_refresh(zhp) != 0) {
10016 zpool_close(zhp);
10017 return (void *)(uintptr_t)(missing ? 0 : 1);
10018 }
10019
10020 print_wait_status_row(wd, zhp, row);
10021
10022 timeout.tv_sec += floor(wd->wd_interval);
10023 long nanos = timeout.tv_nsec +
10024 (wd->wd_interval - floor(wd->wd_interval)) * NANOSEC;
10025 if (nanos >= NANOSEC) {
10026 timeout.tv_sec++;
10027 timeout.tv_nsec = nanos - NANOSEC;
10028 } else {
10029 timeout.tv_nsec = nanos;
10030 }
10031 pthread_mutex_lock(&wd->wd_mutex);
10032 if (!wd->wd_should_exit)
10033 ret = pthread_cond_timedwait(&wd->wd_cv, &wd->wd_mutex,
10034 &timeout);
10035 pthread_mutex_unlock(&wd->wd_mutex);
10036 if (ret == 0) {
10037 break; /* signaled by main thread */
10038 } else if (ret != ETIMEDOUT) {
10039 (void) fprintf(stderr, gettext("pthread_cond_timedwait "
10040 "failed: %s\n"), strerror(ret));
10041 zpool_close(zhp);
10042 return (void *)(uintptr_t)(1);
10043 }
10044 }
10045
10046 zpool_close(zhp);
10047 return (void *)(0);
10048 }
10049
10050 int
10051 zpool_do_wait(int argc, char **argv)
10052 {
10053 boolean_t verbose = B_FALSE;
10054 char c;
10055 char *value;
10056 int i;
10057 unsigned long count;
10058 pthread_t status_thr;
10059 int error = 0;
10060 zpool_handle_t *zhp;
10061
10062 wait_data_t wd;
10063 wd.wd_scripted = B_FALSE;
10064 wd.wd_exact = B_FALSE;
10065 wd.wd_headers_once = B_FALSE;
10066 wd.wd_should_exit = B_FALSE;
10067
10068 pthread_mutex_init(&wd.wd_mutex, NULL);
10069 pthread_cond_init(&wd.wd_cv, NULL);
10070
10071 /* By default, wait for all types of activity. */
10072 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++)
10073 wd.wd_enabled[i] = B_TRUE;
10074
10075 while ((c = getopt(argc, argv, "HpT:t:")) != -1) {
10076 switch (c) {
10077 case 'H':
10078 wd.wd_scripted = B_TRUE;
10079 break;
10080 case 'n':
10081 wd.wd_headers_once = B_TRUE;
10082 break;
10083 case 'p':
10084 wd.wd_exact = B_TRUE;
10085 break;
10086 case 'T':
10087 get_timestamp_arg(*optarg);
10088 break;
10089 case 't':
10090 {
10091 static char *col_subopts[] = { "discard", "free",
10092 "initialize", "replace", "remove", "resilver",
10093 "scrub", "trim", NULL };
10094
10095 /* Reset activities array */
10096 bzero(&wd.wd_enabled, sizeof (wd.wd_enabled));
10097 while (*optarg != '\0') {
10098 int activity = getsubopt(&optarg, col_subopts,
10099 &value);
10100
10101 if (activity < 0) {
10102 (void) fprintf(stderr,
10103 gettext("invalid activity '%s'\n"),
10104 value);
10105 usage(B_FALSE);
10106 }
10107
10108 wd.wd_enabled[activity] = B_TRUE;
10109 }
10110 break;
10111 }
10112 case '?':
10113 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
10114 optopt);
10115 usage(B_FALSE);
10116 }
10117 }
10118
10119 argc -= optind;
10120 argv += optind;
10121
10122 get_interval_count(&argc, argv, &wd.wd_interval, &count);
10123 if (count != 0) {
10124 /* This subcmd only accepts an interval, not a count */
10125 (void) fprintf(stderr, gettext("too many arguments\n"));
10126 usage(B_FALSE);
10127 }
10128
10129 if (wd.wd_interval != 0)
10130 verbose = B_TRUE;
10131
10132 if (argc < 1) {
10133 (void) fprintf(stderr, gettext("missing 'pool' argument\n"));
10134 usage(B_FALSE);
10135 }
10136 if (argc > 1) {
10137 (void) fprintf(stderr, gettext("too many arguments\n"));
10138 usage(B_FALSE);
10139 }
10140
10141 wd.wd_poolname = argv[0];
10142
10143 if ((zhp = zpool_open(g_zfs, wd.wd_poolname)) == NULL)
10144 return (1);
10145
10146 if (verbose) {
10147 /*
10148 * We use a separate thread for printing status updates because
10149 * the main thread will call lzc_wait(), which blocks as long
10150 * as an activity is in progress, which can be a long time.
10151 */
10152 if (pthread_create(&status_thr, NULL, wait_status_thread, &wd)
10153 != 0) {
10154 (void) fprintf(stderr, gettext("failed to create status"
10155 "thread: %s\n"), strerror(errno));
10156 zpool_close(zhp);
10157 return (1);
10158 }
10159 }
10160
10161 /*
10162 * Loop over all activities that we are supposed to wait for until none
10163 * of them are in progress. Note that this means we can end up waiting
10164 * for more activities to complete than just those that were in progress
10165 * when we began waiting; if an activity we are interested in begins
10166 * while we are waiting for another activity, we will wait for both to
10167 * complete before exiting.
10168 */
10169 for (;;) {
10170 boolean_t missing = B_FALSE;
10171 boolean_t any_waited = B_FALSE;
10172
10173 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) {
10174 boolean_t waited;
10175
10176 if (!wd.wd_enabled[i])
10177 continue;
10178
10179 error = zpool_wait_status(zhp, i, &missing, &waited);
10180 if (error != 0 || missing)
10181 break;
10182
10183 any_waited = (any_waited || waited);
10184 }
10185
10186 if (error != 0 || missing || !any_waited)
10187 break;
10188 }
10189
10190 zpool_close(zhp);
10191
10192 if (verbose) {
10193 uintptr_t status;
10194 pthread_mutex_lock(&wd.wd_mutex);
10195 wd.wd_should_exit = B_TRUE;
10196 pthread_cond_signal(&wd.wd_cv);
10197 pthread_mutex_unlock(&wd.wd_mutex);
10198 (void) pthread_join(status_thr, (void *)&status);
10199 if (status != 0)
10200 error = status;
10201 }
10202
10203 pthread_mutex_destroy(&wd.wd_mutex);
10204 pthread_cond_destroy(&wd.wd_cv);
10205 return (error);
10206 }
10207
10208 static int
10209 find_command_idx(char *command, int *idx)
10210 {
10211 int i;
10212
10213 for (i = 0; i < NCOMMAND; i++) {
10214 if (command_table[i].name == NULL)
10215 continue;
10216
10217 if (strcmp(command, command_table[i].name) == 0) {
10218 *idx = i;
10219 return (0);
10220 }
10221 }
10222 return (1);
10223 }
10224
10225 /*
10226 * Display version message
10227 */
10228 static int
10229 zpool_do_version(int argc, char **argv)
10230 {
10231 if (zfs_version_print() == -1)
10232 return (1);
10233
10234 return (0);
10235 }
10236
10237 int
10238 main(int argc, char **argv)
10239 {
10240 int ret = 0;
10241 int i = 0;
10242 char *cmdname;
10243 char **newargv;
10244
10245 (void) setlocale(LC_ALL, "");
10246 (void) setlocale(LC_NUMERIC, "C");
10247 (void) textdomain(TEXT_DOMAIN);
10248 srand(time(NULL));
10249
10250 opterr = 0;
10251
10252 /*
10253 * Make sure the user has specified some command.
10254 */
10255 if (argc < 2) {
10256 (void) fprintf(stderr, gettext("missing command\n"));
10257 usage(B_FALSE);
10258 }
10259
10260 cmdname = argv[1];
10261
10262 /*
10263 * Special case '-?'
10264 */
10265 if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0)
10266 usage(B_TRUE);
10267
10268 /*
10269 * Special case '-V|--version'
10270 */
10271 if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0))
10272 return (zpool_do_version(argc, argv));
10273
10274 if ((g_zfs = libzfs_init()) == NULL) {
10275 (void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
10276 return (1);
10277 }
10278
10279 libzfs_print_on_error(g_zfs, B_TRUE);
10280
10281 zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
10282
10283 /*
10284 * Many commands modify input strings for string parsing reasons.
10285 * We create a copy to protect the original argv.
10286 */
10287 newargv = malloc((argc + 1) * sizeof (newargv[0]));
10288 for (i = 0; i < argc; i++)
10289 newargv[i] = strdup(argv[i]);
10290 newargv[argc] = NULL;
10291
10292 /*
10293 * Run the appropriate command.
10294 */
10295 if (find_command_idx(cmdname, &i) == 0) {
10296 current_command = &command_table[i];
10297 ret = command_table[i].func(argc - 1, newargv + 1);
10298 } else if (strchr(cmdname, '=')) {
10299 verify(find_command_idx("set", &i) == 0);
10300 current_command = &command_table[i];
10301 ret = command_table[i].func(argc, newargv);
10302 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
10303 /*
10304 * 'freeze' is a vile debugging abomination, so we treat
10305 * it as such.
10306 */
10307 zfs_cmd_t zc = {"\0"};
10308
10309 (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name));
10310 ret = zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc);
10311 if (ret != 0) {
10312 (void) fprintf(stderr,
10313 gettext("failed to freeze pool: %d\n"), errno);
10314 ret = 1;
10315 }
10316
10317 log_history = 0;
10318 } else {
10319 (void) fprintf(stderr, gettext("unrecognized "
10320 "command '%s'\n"), cmdname);
10321 usage(B_FALSE);
10322 ret = 1;
10323 }
10324
10325 for (i = 0; i < argc; i++)
10326 free(newargv[i]);
10327 free(newargv);
10328
10329 if (ret == 0 && log_history)
10330 (void) zpool_log_history(g_zfs, history_str);
10331
10332 libzfs_fini(g_zfs);
10333
10334 /*
10335 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
10336 * for the purposes of running ::findleaks.
10337 */
10338 if (getenv("ZFS_ABORT") != NULL) {
10339 (void) printf("dumping core by request\n");
10340 abort();
10341 }
10342
10343 return (ret);
10344 }