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