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