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