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) 2012 by Delphix. All rights reserved.
26 * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
27 */
28
29 #include <assert.h>
30 #include <ctype.h>
31 #include <dirent.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <libgen.h>
35 #include <libintl.h>
36 #include <libuutil.h>
37 #include <locale.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <unistd.h>
43 #include <priv.h>
44 #include <pwd.h>
45 #include <zone.h>
46 #include <zfs_prop.h>
47 #include <sys/fs/zfs.h>
48 #include <sys/stat.h>
49
50 #include <libzfs.h>
51
52 #include "zpool_util.h"
53 #include "zfs_comutil.h"
54 #include "zfeature_common.h"
55
56 #include "statcommon.h"
57
58 static int zpool_do_create(int, char **);
59 static int zpool_do_destroy(int, char **);
60
61 static int zpool_do_add(int, char **);
62 static int zpool_do_remove(int, char **);
63
64 static int zpool_do_list(int, char **);
65 static int zpool_do_iostat(int, char **);
66 static int zpool_do_status(int, char **);
67
68 static int zpool_do_online(int, char **);
69 static int zpool_do_offline(int, char **);
70 static int zpool_do_clear(int, char **);
71 static int zpool_do_reopen(int, char **);
72
73 static int zpool_do_reguid(int, char **);
74
75 static int zpool_do_attach(int, char **);
76 static int zpool_do_detach(int, char **);
77 static int zpool_do_replace(int, char **);
78 static int zpool_do_split(int, char **);
79
80 static int zpool_do_scrub(int, char **);
81
82 static int zpool_do_import(int, char **);
83 static int zpool_do_export(int, char **);
84
85 static int zpool_do_upgrade(int, char **);
86
87 static int zpool_do_history(int, char **);
88
89 static int zpool_do_get(int, char **);
90 static int zpool_do_set(int, char **);
91
92 /*
93 * These libumem hooks provide a reasonable set of defaults for the allocator's
94 * debugging facilities.
95 */
96
97 #ifdef DEBUG
98 const char *
99 _umem_debug_init(void)
100 {
101 return ("default,verbose"); /* $UMEM_DEBUG setting */
102 }
103
104 const char *
105 _umem_logging_init(void)
106 {
107 return ("fail,contents"); /* $UMEM_LOGGING setting */
108 }
109 #endif
110
111 typedef enum {
112 HELP_ADD,
113 HELP_ATTACH,
114 HELP_CLEAR,
115 HELP_CREATE,
116 HELP_DESTROY,
117 HELP_DETACH,
118 HELP_EXPORT,
119 HELP_HISTORY,
120 HELP_IMPORT,
121 HELP_IOSTAT,
122 HELP_LIST,
123 HELP_OFFLINE,
124 HELP_ONLINE,
125 HELP_REPLACE,
126 HELP_REMOVE,
127 HELP_SCRUB,
128 HELP_STATUS,
129 HELP_UPGRADE,
130 HELP_GET,
131 HELP_SET,
132 HELP_SPLIT,
133 HELP_REGUID,
134 HELP_REOPEN
135 } zpool_help_t;
136
137
138 typedef struct zpool_command {
139 const char *name;
140 int (*func)(int, char **);
141 zpool_help_t usage;
142 } zpool_command_t;
143
144 /*
145 * Master command table. Each ZFS command has a name, associated function, and
146 * usage message. The usage messages need to be internationalized, so we have
147 * to have a function to return the usage message based on a command index.
148 *
149 * These commands are organized according to how they are displayed in the usage
150 * message. An empty command (one with a NULL name) indicates an empty line in
151 * the generic usage message.
152 */
153 static zpool_command_t command_table[] = {
154 { "create", zpool_do_create, HELP_CREATE },
155 { "destroy", zpool_do_destroy, HELP_DESTROY },
156 { NULL },
157 { "add", zpool_do_add, HELP_ADD },
158 { "remove", zpool_do_remove, HELP_REMOVE },
159 { NULL },
160 { "list", zpool_do_list, HELP_LIST },
161 { "iostat", zpool_do_iostat, HELP_IOSTAT },
162 { "status", zpool_do_status, HELP_STATUS },
163 { NULL },
164 { "online", zpool_do_online, HELP_ONLINE },
165 { "offline", zpool_do_offline, HELP_OFFLINE },
166 { "clear", zpool_do_clear, HELP_CLEAR },
167 { "reopen", zpool_do_reopen, HELP_REOPEN },
168 { NULL },
169 { "attach", zpool_do_attach, HELP_ATTACH },
170 { "detach", zpool_do_detach, HELP_DETACH },
171 { "replace", zpool_do_replace, HELP_REPLACE },
172 { "split", zpool_do_split, HELP_SPLIT },
173 { NULL },
174 { "scrub", zpool_do_scrub, HELP_SCRUB },
175 { NULL },
176 { "import", zpool_do_import, HELP_IMPORT },
177 { "export", zpool_do_export, HELP_EXPORT },
178 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
179 { "reguid", zpool_do_reguid, HELP_REGUID },
180 { NULL },
181 { "history", zpool_do_history, HELP_HISTORY },
182 { "get", zpool_do_get, HELP_GET },
183 { "set", zpool_do_set, HELP_SET },
184 };
185
186 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
187
188 static zpool_command_t *current_command;
189 static char history_str[HIS_MAX_RECORD_LEN];
190 static boolean_t log_history = B_TRUE;
191 static uint_t timestamp_fmt = NODATE;
192
193 static const char *
194 get_usage(zpool_help_t idx) {
195 switch (idx) {
196 case HELP_ADD:
197 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
198 case HELP_ATTACH:
199 return (gettext("\tattach [-f] <pool> <device> "
200 "<new-device>\n"));
201 case HELP_CLEAR:
202 return (gettext("\tclear [-nF] <pool> [device]\n"));
203 case HELP_CREATE:
204 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
205 "\t [-O file-system-property=value] ... \n"
206 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
207 case HELP_DESTROY:
208 return (gettext("\tdestroy [-f] <pool>\n"));
209 case HELP_DETACH:
210 return (gettext("\tdetach <pool> <device>\n"));
211 case HELP_EXPORT:
212 return (gettext("\texport [-f] <pool> ...\n"));
213 case HELP_HISTORY:
214 return (gettext("\thistory [-il] [<pool>] ...\n"));
215 case HELP_IMPORT:
216 return (gettext("\timport [-d dir] [-D]\n"
217 "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
218 "\timport [-o mntopts] [-o property=value] ... \n"
219 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
220 "[-R root] [-F [-n]] -a\n"
221 "\timport [-o mntopts] [-o property=value] ... \n"
222 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
223 "[-R root] [-F [-n]]\n"
224 "\t <pool | id> [newpool]\n"));
225 case HELP_IOSTAT:
226 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
227 "[count]]\n"));
228 case HELP_LIST:
229 return (gettext("\tlist [-H] [-o property[,...]] "
230 "[-T d|u] [pool] ... [interval [count]]\n"));
231 case HELP_OFFLINE:
232 return (gettext("\toffline [-t] <pool> <device> ...\n"));
233 case HELP_ONLINE:
234 return (gettext("\tonline <pool> <device> ...\n"));
235 case HELP_REPLACE:
236 return (gettext("\treplace [-f] <pool> <device> "
237 "[new-device]\n"));
238 case HELP_REMOVE:
239 return (gettext("\tremove <pool> <device> ...\n"));
240 case HELP_REOPEN:
241 return (gettext("\treopen <pool>\n"));
242 case HELP_SCRUB:
243 return (gettext("\tscrub [-s] <pool> ...\n"));
244 case HELP_STATUS:
245 return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
246 "[count]]\n"));
247 case HELP_UPGRADE:
248 return (gettext("\tupgrade\n"
249 "\tupgrade -v\n"
250 "\tupgrade [-V version] <-a | pool ...>\n"));
251 case HELP_GET:
252 return (gettext("\tget <\"all\" | property[,...]> "
253 "<pool> ...\n"));
254 case HELP_SET:
255 return (gettext("\tset <property=value> <pool> \n"));
256 case HELP_SPLIT:
257 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
258 "\t [-o property=value] <pool> <newpool> "
259 "[<device> ...]\n"));
260 case HELP_REGUID:
261 return (gettext("\treguid <pool>\n"));
262 }
263
264 abort();
265 /* NOTREACHED */
266 }
267
268
269 /*
270 * Callback routine that will print out a pool property value.
271 */
272 static int
273 print_prop_cb(int prop, void *cb)
274 {
275 FILE *fp = cb;
276
277 (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop));
278
279 if (zpool_prop_readonly(prop))
280 (void) fprintf(fp, " NO ");
281 else
282 (void) fprintf(fp, " YES ");
283
284 if (zpool_prop_values(prop) == NULL)
285 (void) fprintf(fp, "-\n");
286 else
287 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
288
289 return (ZPROP_CONT);
290 }
291
292 /*
293 * Display usage message. If we're inside a command, display only the usage for
294 * that command. Otherwise, iterate over the entire command table and display
295 * a complete usage message.
296 */
297 void
298 usage(boolean_t requested)
299 {
300 FILE *fp = requested ? stdout : stderr;
301
302 if (current_command == NULL) {
303 int i;
304
305 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
306 (void) fprintf(fp,
307 gettext("where 'command' is one of the following:\n\n"));
308
309 for (i = 0; i < NCOMMAND; i++) {
310 if (command_table[i].name == NULL)
311 (void) fprintf(fp, "\n");
312 else
313 (void) fprintf(fp, "%s",
314 get_usage(command_table[i].usage));
315 }
316 } else {
317 (void) fprintf(fp, gettext("usage:\n"));
318 (void) fprintf(fp, "%s", get_usage(current_command->usage));
319 }
320
321 if (current_command != NULL &&
322 ((strcmp(current_command->name, "set") == 0) ||
323 (strcmp(current_command->name, "get") == 0) ||
324 (strcmp(current_command->name, "list") == 0))) {
325
326 (void) fprintf(fp,
327 gettext("\nthe following properties are supported:\n"));
328
329 (void) fprintf(fp, "\n\t%-15s %s %s\n\n",
330 "PROPERTY", "EDIT", "VALUES");
331
332 /* Iterate over all properties */
333 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
334 ZFS_TYPE_POOL);
335
336 (void) fprintf(fp, "\t%-15s ", "feature@...");
337 (void) fprintf(fp, "YES disabled | enabled | active\n");
338
339 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
340 "appended with a feature name.\nSee zpool-features(5).\n"));
341 }
342
343 /*
344 * See comments at end of main().
345 */
346 if (getenv("ZFS_ABORT") != NULL) {
347 (void) printf("dumping core by request\n");
348 abort();
349 }
350
351 exit(requested ? 0 : 2);
352 }
353
354 void
355 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
356 boolean_t print_logs)
357 {
358 nvlist_t **child;
359 uint_t c, children;
360 char *vname;
361
362 if (name != NULL)
363 (void) printf("\t%*s%s\n", indent, "", name);
364
365 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
366 &child, &children) != 0)
367 return;
368
369 for (c = 0; c < children; c++) {
370 uint64_t is_log = B_FALSE;
371
372 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
373 &is_log);
374 if ((is_log && !print_logs) || (!is_log && print_logs))
375 continue;
376
377 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
378 print_vdev_tree(zhp, vname, child[c], indent + 2,
379 B_FALSE);
380 free(vname);
381 }
382 }
383
384 static boolean_t
385 prop_list_contains_feature(nvlist_t *proplist)
386 {
387 nvpair_t *nvp;
388 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
389 nvp = nvlist_next_nvpair(proplist, nvp)) {
390 if (zpool_prop_feature(nvpair_name(nvp)))
391 return (B_TRUE);
392 }
393 return (B_FALSE);
394 }
395
396 /*
397 * Add a property pair (name, string-value) into a property nvlist.
398 */
399 static int
400 add_prop_list(const char *propname, char *propval, nvlist_t **props,
401 boolean_t poolprop)
402 {
403 zpool_prop_t prop = ZPROP_INVAL;
404 zfs_prop_t fprop;
405 nvlist_t *proplist;
406 const char *normnm;
407 char *strval;
408
409 if (*props == NULL &&
410 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
411 (void) fprintf(stderr,
412 gettext("internal error: out of memory\n"));
413 return (1);
414 }
415
416 proplist = *props;
417
418 if (poolprop) {
419 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
420
421 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
422 !zpool_prop_feature(propname)) {
423 (void) fprintf(stderr, gettext("property '%s' is "
424 "not a valid pool property\n"), propname);
425 return (2);
426 }
427
428 /*
429 * feature@ properties and version should not be specified
430 * at the same time.
431 */
432 if ((prop == ZPROP_INVAL && zpool_prop_feature(propname) &&
433 nvlist_exists(proplist, vname)) ||
434 (prop == ZPOOL_PROP_VERSION &&
435 prop_list_contains_feature(proplist))) {
436 (void) fprintf(stderr, gettext("'feature@' and "
437 "'version' properties cannot be specified "
438 "together\n"));
439 return (2);
440 }
441
442
443 if (zpool_prop_feature(propname))
444 normnm = propname;
445 else
446 normnm = zpool_prop_to_name(prop);
447 } else {
448 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
449 normnm = zfs_prop_to_name(fprop);
450 } else {
451 normnm = propname;
452 }
453 }
454
455 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
456 prop != ZPOOL_PROP_CACHEFILE) {
457 (void) fprintf(stderr, gettext("property '%s' "
458 "specified multiple times\n"), propname);
459 return (2);
460 }
461
462 if (nvlist_add_string(proplist, normnm, propval) != 0) {
463 (void) fprintf(stderr, gettext("internal "
464 "error: out of memory\n"));
465 return (1);
466 }
467
468 return (0);
469 }
470
471 /*
472 * zpool add [-fn] <pool> <vdev> ...
473 *
474 * -f Force addition of devices, even if they appear in use
475 * -n Do not add the devices, but display the resulting layout if
476 * they were to be added.
477 *
478 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
479 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
480 * libzfs.
481 */
482 int
483 zpool_do_add(int argc, char **argv)
484 {
485 boolean_t force = B_FALSE;
486 boolean_t dryrun = B_FALSE;
487 int c;
488 nvlist_t *nvroot;
489 char *poolname;
490 int ret;
491 zpool_handle_t *zhp;
492 nvlist_t *config;
493
494 /* check options */
495 while ((c = getopt(argc, argv, "fn")) != -1) {
496 switch (c) {
497 case 'f':
498 force = B_TRUE;
499 break;
500 case 'n':
501 dryrun = B_TRUE;
502 break;
503 case '?':
504 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
505 optopt);
506 usage(B_FALSE);
507 }
508 }
509
510 argc -= optind;
511 argv += optind;
512
513 /* get pool name and check number of arguments */
514 if (argc < 1) {
515 (void) fprintf(stderr, gettext("missing pool name argument\n"));
516 usage(B_FALSE);
517 }
518 if (argc < 2) {
519 (void) fprintf(stderr, gettext("missing vdev specification\n"));
520 usage(B_FALSE);
521 }
522
523 poolname = argv[0];
524
525 argc--;
526 argv++;
527
528 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
529 return (1);
530
531 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
532 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
533 poolname);
534 zpool_close(zhp);
535 return (1);
536 }
537
538 /* pass off to get_vdev_spec for processing */
539 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
540 argc, argv);
541 if (nvroot == NULL) {
542 zpool_close(zhp);
543 return (1);
544 }
545
546 if (dryrun) {
547 nvlist_t *poolnvroot;
548
549 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
550 &poolnvroot) == 0);
551
552 (void) printf(gettext("would update '%s' to the following "
553 "configuration:\n"), zpool_get_name(zhp));
554
555 /* print original main pool and new tree */
556 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
557 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
558
559 /* Do the same for the logs */
560 if (num_logs(poolnvroot) > 0) {
561 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
562 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
563 } else if (num_logs(nvroot) > 0) {
564 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
565 }
566
567 ret = 0;
568 } else {
569 ret = (zpool_add(zhp, nvroot) != 0);
570 }
571
572 nvlist_free(nvroot);
573 zpool_close(zhp);
574
575 return (ret);
576 }
577
578 /*
579 * zpool remove <pool> <vdev> ...
580 *
581 * Removes the given vdev from the pool. Currently, this supports removing
582 * spares, cache, and log devices from the pool.
583 */
584 int
585 zpool_do_remove(int argc, char **argv)
586 {
587 char *poolname;
588 int i, ret = 0;
589 zpool_handle_t *zhp;
590
591 argc--;
592 argv++;
593
594 /* get pool name and check number of arguments */
595 if (argc < 1) {
596 (void) fprintf(stderr, gettext("missing pool name argument\n"));
597 usage(B_FALSE);
598 }
599 if (argc < 2) {
600 (void) fprintf(stderr, gettext("missing device\n"));
601 usage(B_FALSE);
602 }
603
604 poolname = argv[0];
605
606 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
607 return (1);
608
609 for (i = 1; i < argc; i++) {
610 if (zpool_vdev_remove(zhp, argv[i]) != 0)
611 ret = 1;
612 }
613
614 return (ret);
615 }
616
617 /*
618 * zpool create [-fnd] [-o property=value] ...
619 * [-O file-system-property=value] ...
620 * [-R root] [-m mountpoint] <pool> <dev> ...
621 *
622 * -f Force creation, even if devices appear in use
623 * -n Do not create the pool, but display the resulting layout if it
624 * were to be created.
625 * -R Create a pool under an alternate root
626 * -m Set default mountpoint for the root dataset. By default it's
627 * '/<pool>'
628 * -o Set property=value.
629 * -d Don't automatically enable all supported pool features
630 * (individual features can be enabled with -o).
631 * -O Set fsproperty=value in the pool's root file system
632 *
633 * Creates the named pool according to the given vdev specification. The
634 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
635 * we get the nvlist back from get_vdev_spec(), we either print out the contents
636 * (if '-n' was specified), or pass it to libzfs to do the creation.
637 */
638 int
639 zpool_do_create(int argc, char **argv)
640 {
641 boolean_t force = B_FALSE;
642 boolean_t dryrun = B_FALSE;
643 boolean_t enable_all_pool_feat = B_TRUE;
644 int c;
645 nvlist_t *nvroot = NULL;
646 char *poolname;
647 int ret = 1;
648 char *altroot = NULL;
649 char *mountpoint = NULL;
650 nvlist_t *fsprops = NULL;
651 nvlist_t *props = NULL;
652 char *propval;
653
654 /* check options */
655 while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) {
656 switch (c) {
657 case 'f':
658 force = B_TRUE;
659 break;
660 case 'n':
661 dryrun = B_TRUE;
662 break;
663 case 'd':
664 enable_all_pool_feat = B_FALSE;
665 break;
666 case 'R':
667 altroot = optarg;
668 if (add_prop_list(zpool_prop_to_name(
669 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
670 goto errout;
671 if (nvlist_lookup_string(props,
672 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
673 &propval) == 0)
674 break;
675 if (add_prop_list(zpool_prop_to_name(
676 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
677 goto errout;
678 break;
679 case 'm':
680 /* Equivalent to -O mountpoint=optarg */
681 mountpoint = optarg;
682 break;
683 case 'o':
684 if ((propval = strchr(optarg, '=')) == NULL) {
685 (void) fprintf(stderr, gettext("missing "
686 "'=' for -o option\n"));
687 goto errout;
688 }
689 *propval = '\0';
690 propval++;
691
692 if (add_prop_list(optarg, propval, &props, B_TRUE))
693 goto errout;
694
695 /*
696 * If the user is creating a pool that doesn't support
697 * feature flags, don't enable any features.
698 */
699 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
700 char *end;
701 u_longlong_t ver;
702
703 ver = strtoull(propval, &end, 10);
704 if (*end == '\0' &&
705 ver < SPA_VERSION_FEATURES) {
706 enable_all_pool_feat = B_FALSE;
707 }
708 }
709 break;
710 case 'O':
711 if ((propval = strchr(optarg, '=')) == NULL) {
712 (void) fprintf(stderr, gettext("missing "
713 "'=' for -O option\n"));
714 goto errout;
715 }
716 *propval = '\0';
717 propval++;
718
719 /*
720 * Mountpoints are checked and then added later.
721 * Uniquely among properties, they can be specified
722 * more than once, to avoid conflict with -m.
723 */
724 if (!strcmp(optarg,
725 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT)))
726 mountpoint = propval;
727 if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
728 goto errout;
729 break;
730 case ':':
731 (void) fprintf(stderr, gettext("missing argument for "
732 "'%c' option\n"), optopt);
733 goto badusage;
734 case '?':
735 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
736 optopt);
737 goto badusage;
738 }
739 }
740
741 argc -= optind;
742 argv += optind;
743
744 /* get pool name and check number of arguments */
745 if (argc < 1) {
746 (void) fprintf(stderr, gettext("missing pool name argument\n"));
747 goto badusage;
748 }
749 if (argc < 2) {
750 (void) fprintf(stderr, gettext("missing vdev specification\n"));
751 goto badusage;
752 }
753
754 poolname = argv[0];
755
756 /*
757 * As a special case, check for use of '/' in the name, and direct the
758 * user to use 'zfs create' instead.
759 */
760 if (strchr(poolname, '/') != NULL) {
761 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
762 "character '/' in pool name\n"), poolname);
763 (void) fprintf(stderr, gettext("use 'zfs create' to "
764 "create a dataset\n"));
765 goto errout;
766 }
767
768 /* pass off to get_vdev_spec for bulk processing */
769 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
770 argc - 1, argv + 1);
771 if (nvroot == NULL)
772 goto errout;
773
774 /* make_root_vdev() allows 0 toplevel children if there are spares */
775 if (!zfs_allocatable_devs(nvroot)) {
776 (void) fprintf(stderr, gettext("invalid vdev "
777 "specification: at least one toplevel vdev must be "
778 "specified\n"));
779 goto errout;
780 }
781
782 if (altroot != NULL && altroot[0] != '/') {
783 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
784 "must be an absolute path\n"), altroot);
785 goto errout;
786 }
787
788 /*
789 * Check the validity of the mountpoint and direct the user to use the
790 * '-m' mountpoint option if it looks like its in use.
791 */
792 if (mountpoint == NULL ||
793 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
794 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
795 char buf[MAXPATHLEN];
796 DIR *dirp;
797
798 if (mountpoint && mountpoint[0] != '/') {
799 (void) fprintf(stderr, gettext("invalid mountpoint "
800 "'%s': must be an absolute path, 'legacy', or "
801 "'none'\n"), mountpoint);
802 goto errout;
803 }
804
805 if (mountpoint == NULL) {
806 if (altroot != NULL)
807 (void) snprintf(buf, sizeof (buf), "%s/%s",
808 altroot, poolname);
809 else
810 (void) snprintf(buf, sizeof (buf), "/%s",
811 poolname);
812 } else {
813 if (altroot != NULL)
814 (void) snprintf(buf, sizeof (buf), "%s%s",
815 altroot, mountpoint);
816 else
817 (void) snprintf(buf, sizeof (buf), "%s",
818 mountpoint);
819 }
820
821 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
822 (void) fprintf(stderr, gettext("mountpoint '%s' : "
823 "%s\n"), buf, strerror(errno));
824 (void) fprintf(stderr, gettext("use '-m' "
825 "option to provide a different default\n"));
826 goto errout;
827 } else if (dirp) {
828 int count = 0;
829
830 while (count < 3 && readdir(dirp) != NULL)
831 count++;
832 (void) closedir(dirp);
833
834 if (count > 2) {
835 (void) fprintf(stderr, gettext("mountpoint "
836 "'%s' exists and is not empty\n"), buf);
837 (void) fprintf(stderr, gettext("use '-m' "
838 "option to provide a "
839 "different default\n"));
840 goto errout;
841 }
842 }
843 }
844
845 /*
846 * Now that the mountpoint's validity has been checked, ensure that
847 * the property is set appropriately prior to creating the pool.
848 */
849 if (mountpoint != NULL) {
850 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
851 mountpoint, &fsprops, B_FALSE);
852 if (ret != 0)
853 goto errout;
854 }
855
856 ret = 1;
857 if (dryrun) {
858 /*
859 * For a dry run invocation, print out a basic message and run
860 * through all the vdevs in the list and print out in an
861 * appropriate hierarchy.
862 */
863 (void) printf(gettext("would create '%s' with the "
864 "following layout:\n\n"), poolname);
865
866 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
867 if (num_logs(nvroot) > 0)
868 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
869
870 ret = 0;
871 } else {
872 /*
873 * Hand off to libzfs.
874 */
875 if (enable_all_pool_feat) {
876 int i;
877 for (i = 0; i < SPA_FEATURES; i++) {
878 char propname[MAXPATHLEN];
879 zfeature_info_t *feat = &spa_feature_table[i];
880
881 (void) snprintf(propname, sizeof (propname),
882 "feature@%s", feat->fi_uname);
883
884 /*
885 * Skip feature if user specified it manually
886 * on the command line.
887 */
888 if (nvlist_exists(props, propname))
889 continue;
890
891 ret = add_prop_list(propname,
892 ZFS_FEATURE_ENABLED, &props, B_TRUE);
893 if (ret != 0)
894 goto errout;
895 }
896 }
897 if (zpool_create(g_zfs, poolname,
898 nvroot, props, fsprops) == 0) {
899 zfs_handle_t *pool = zfs_open(g_zfs, poolname,
900 ZFS_TYPE_FILESYSTEM);
901 if (pool != NULL) {
902 if (zfs_mount(pool, NULL, 0) == 0)
903 ret = zfs_shareall(pool);
904 zfs_close(pool);
905 }
906 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
907 (void) fprintf(stderr, gettext("pool name may have "
908 "been omitted\n"));
909 }
910 }
911
912 errout:
913 nvlist_free(nvroot);
914 nvlist_free(fsprops);
915 nvlist_free(props);
916 return (ret);
917 badusage:
918 nvlist_free(fsprops);
919 nvlist_free(props);
920 usage(B_FALSE);
921 return (2);
922 }
923
924 /*
925 * zpool destroy <pool>
926 *
927 * -f Forcefully unmount any datasets
928 *
929 * Destroy the given pool. Automatically unmounts any datasets in the pool.
930 */
931 int
932 zpool_do_destroy(int argc, char **argv)
933 {
934 boolean_t force = B_FALSE;
935 int c;
936 char *pool;
937 zpool_handle_t *zhp;
938 int ret;
939
940 /* check options */
941 while ((c = getopt(argc, argv, "f")) != -1) {
942 switch (c) {
943 case 'f':
944 force = B_TRUE;
945 break;
946 case '?':
947 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
948 optopt);
949 usage(B_FALSE);
950 }
951 }
952
953 argc -= optind;
954 argv += optind;
955
956 /* check arguments */
957 if (argc < 1) {
958 (void) fprintf(stderr, gettext("missing pool argument\n"));
959 usage(B_FALSE);
960 }
961 if (argc > 1) {
962 (void) fprintf(stderr, gettext("too many arguments\n"));
963 usage(B_FALSE);
964 }
965
966 pool = argv[0];
967
968 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
969 /*
970 * As a special case, check for use of '/' in the name, and
971 * direct the user to use 'zfs destroy' instead.
972 */
973 if (strchr(pool, '/') != NULL)
974 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
975 "destroy a dataset\n"));
976 return (1);
977 }
978
979 if (zpool_disable_datasets(zhp, force) != 0) {
980 (void) fprintf(stderr, gettext("could not destroy '%s': "
981 "could not unmount datasets\n"), zpool_get_name(zhp));
982 return (1);
983 }
984
985 /* The history must be logged as part of the export */
986 log_history = B_FALSE;
987
988 ret = (zpool_destroy(zhp, history_str) != 0);
989
990 zpool_close(zhp);
991
992 return (ret);
993 }
994
995 /*
996 * zpool export [-f] <pool> ...
997 *
998 * -f Forcefully unmount datasets
999 *
1000 * Export the given pools. By default, the command will attempt to cleanly
1001 * unmount any active datasets within the pool. If the '-f' flag is specified,
1002 * then the datasets will be forcefully unmounted.
1003 */
1004 int
1005 zpool_do_export(int argc, char **argv)
1006 {
1007 boolean_t force = B_FALSE;
1008 boolean_t hardforce = B_FALSE;
1009 int c;
1010 zpool_handle_t *zhp;
1011 int ret;
1012 int i;
1013
1014 /* check options */
1015 while ((c = getopt(argc, argv, "fF")) != -1) {
1016 switch (c) {
1017 case 'f':
1018 force = B_TRUE;
1019 break;
1020 case 'F':
1021 hardforce = B_TRUE;
1022 break;
1023 case '?':
1024 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1025 optopt);
1026 usage(B_FALSE);
1027 }
1028 }
1029
1030 argc -= optind;
1031 argv += optind;
1032
1033 /* check arguments */
1034 if (argc < 1) {
1035 (void) fprintf(stderr, gettext("missing pool argument\n"));
1036 usage(B_FALSE);
1037 }
1038
1039 ret = 0;
1040 for (i = 0; i < argc; i++) {
1041 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
1042 ret = 1;
1043 continue;
1044 }
1045
1046 if (zpool_disable_datasets(zhp, force) != 0) {
1047 ret = 1;
1048 zpool_close(zhp);
1049 continue;
1050 }
1051
1052 /* The history must be logged as part of the export */
1053 log_history = B_FALSE;
1054
1055 if (hardforce) {
1056 if (zpool_export_force(zhp, history_str) != 0)
1057 ret = 1;
1058 } else if (zpool_export(zhp, force, history_str) != 0) {
1059 ret = 1;
1060 }
1061
1062 zpool_close(zhp);
1063 }
1064
1065 return (ret);
1066 }
1067
1068 /*
1069 * Given a vdev configuration, determine the maximum width needed for the device
1070 * name column.
1071 */
1072 static int
1073 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
1074 {
1075 char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
1076 nvlist_t **child;
1077 uint_t c, children;
1078 int ret;
1079
1080 if (strlen(name) + depth > max)
1081 max = strlen(name) + depth;
1082
1083 free(name);
1084
1085 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1086 &child, &children) == 0) {
1087 for (c = 0; c < children; c++)
1088 if ((ret = max_width(zhp, child[c], depth + 2,
1089 max)) > max)
1090 max = ret;
1091 }
1092
1093 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1094 &child, &children) == 0) {
1095 for (c = 0; c < children; c++)
1096 if ((ret = max_width(zhp, child[c], depth + 2,
1097 max)) > max)
1098 max = ret;
1099 }
1100
1101 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1102 &child, &children) == 0) {
1103 for (c = 0; c < children; c++)
1104 if ((ret = max_width(zhp, child[c], depth + 2,
1105 max)) > max)
1106 max = ret;
1107 }
1108
1109
1110 return (max);
1111 }
1112
1113 typedef struct spare_cbdata {
1114 uint64_t cb_guid;
1115 zpool_handle_t *cb_zhp;
1116 } spare_cbdata_t;
1117
1118 static boolean_t
1119 find_vdev(nvlist_t *nv, uint64_t search)
1120 {
1121 uint64_t guid;
1122 nvlist_t **child;
1123 uint_t c, children;
1124
1125 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1126 search == guid)
1127 return (B_TRUE);
1128
1129 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1130 &child, &children) == 0) {
1131 for (c = 0; c < children; c++)
1132 if (find_vdev(child[c], search))
1133 return (B_TRUE);
1134 }
1135
1136 return (B_FALSE);
1137 }
1138
1139 static int
1140 find_spare(zpool_handle_t *zhp, void *data)
1141 {
1142 spare_cbdata_t *cbp = data;
1143 nvlist_t *config, *nvroot;
1144
1145 config = zpool_get_config(zhp, NULL);
1146 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1147 &nvroot) == 0);
1148
1149 if (find_vdev(nvroot, cbp->cb_guid)) {
1150 cbp->cb_zhp = zhp;
1151 return (1);
1152 }
1153
1154 zpool_close(zhp);
1155 return (0);
1156 }
1157
1158 /*
1159 * Print out configuration state as requested by status_callback.
1160 */
1161 void
1162 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1163 int namewidth, int depth, boolean_t isspare)
1164 {
1165 nvlist_t **child;
1166 uint_t c, children;
1167 pool_scan_stat_t *ps = NULL;
1168 vdev_stat_t *vs;
1169 char rbuf[6], wbuf[6], cbuf[6];
1170 char *vname;
1171 uint64_t notpresent;
1172 spare_cbdata_t cb;
1173 char *state;
1174
1175 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1176 &child, &children) != 0)
1177 children = 0;
1178
1179 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1180 (uint64_t **)&vs, &c) == 0);
1181
1182 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1183 if (isspare) {
1184 /*
1185 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1186 * online drives.
1187 */
1188 if (vs->vs_aux == VDEV_AUX_SPARED)
1189 state = "INUSE";
1190 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1191 state = "AVAIL";
1192 }
1193
1194 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
1195 name, state);
1196
1197 if (!isspare) {
1198 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1199 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1200 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1201 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1202 }
1203
1204 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1205 ¬present) == 0) {
1206 char *path;
1207 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1208 (void) printf(" was %s", path);
1209 } else if (vs->vs_aux != 0) {
1210 (void) printf(" ");
1211
1212 switch (vs->vs_aux) {
1213 case VDEV_AUX_OPEN_FAILED:
1214 (void) printf(gettext("cannot open"));
1215 break;
1216
1217 case VDEV_AUX_BAD_GUID_SUM:
1218 (void) printf(gettext("missing device"));
1219 break;
1220
1221 case VDEV_AUX_NO_REPLICAS:
1222 (void) printf(gettext("insufficient replicas"));
1223 break;
1224
1225 case VDEV_AUX_VERSION_NEWER:
1226 (void) printf(gettext("newer version"));
1227 break;
1228
1229 case VDEV_AUX_UNSUP_FEAT:
1230 (void) printf(gettext("unsupported feature(s)"));
1231 break;
1232
1233 case VDEV_AUX_SPARED:
1234 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1235 &cb.cb_guid) == 0);
1236 if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1237 if (strcmp(zpool_get_name(cb.cb_zhp),
1238 zpool_get_name(zhp)) == 0)
1239 (void) printf(gettext("currently in "
1240 "use"));
1241 else
1242 (void) printf(gettext("in use by "
1243 "pool '%s'"),
1244 zpool_get_name(cb.cb_zhp));
1245 zpool_close(cb.cb_zhp);
1246 } else {
1247 (void) printf(gettext("currently in use"));
1248 }
1249 break;
1250
1251 case VDEV_AUX_ERR_EXCEEDED:
1252 (void) printf(gettext("too many errors"));
1253 break;
1254
1255 case VDEV_AUX_IO_FAILURE:
1256 (void) printf(gettext("experienced I/O failures"));
1257 break;
1258
1259 case VDEV_AUX_BAD_LOG:
1260 (void) printf(gettext("bad intent log"));
1261 break;
1262
1263 case VDEV_AUX_EXTERNAL:
1264 (void) printf(gettext("external device fault"));
1265 break;
1266
1267 case VDEV_AUX_SPLIT_POOL:
1268 (void) printf(gettext("split into new pool"));
1269 break;
1270
1271 default:
1272 (void) printf(gettext("corrupted data"));
1273 break;
1274 }
1275 }
1276
1277 (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1278 (uint64_t **)&ps, &c);
1279
1280 if (ps && ps->pss_state == DSS_SCANNING &&
1281 vs->vs_scan_processed != 0 && children == 0) {
1282 (void) printf(gettext(" (%s)"),
1283 (ps->pss_func == POOL_SCAN_RESILVER) ?
1284 "resilvering" : "repairing");
1285 }
1286
1287 (void) printf("\n");
1288
1289 for (c = 0; c < children; c++) {
1290 uint64_t islog = B_FALSE, ishole = B_FALSE;
1291
1292 /* Don't print logs or holes here */
1293 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1294 &islog);
1295 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1296 &ishole);
1297 if (islog || ishole)
1298 continue;
1299 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1300 print_status_config(zhp, vname, child[c],
1301 namewidth, depth + 2, isspare);
1302 free(vname);
1303 }
1304 }
1305
1306
1307 /*
1308 * Print the configuration of an exported pool. Iterate over all vdevs in the
1309 * pool, printing out the name and status for each one.
1310 */
1311 void
1312 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1313 {
1314 nvlist_t **child;
1315 uint_t c, children;
1316 vdev_stat_t *vs;
1317 char *type, *vname;
1318
1319 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1320 if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1321 strcmp(type, VDEV_TYPE_HOLE) == 0)
1322 return;
1323
1324 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1325 (uint64_t **)&vs, &c) == 0);
1326
1327 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1328 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1329
1330 if (vs->vs_aux != 0) {
1331 (void) printf(" ");
1332
1333 switch (vs->vs_aux) {
1334 case VDEV_AUX_OPEN_FAILED:
1335 (void) printf(gettext("cannot open"));
1336 break;
1337
1338 case VDEV_AUX_BAD_GUID_SUM:
1339 (void) printf(gettext("missing device"));
1340 break;
1341
1342 case VDEV_AUX_NO_REPLICAS:
1343 (void) printf(gettext("insufficient replicas"));
1344 break;
1345
1346 case VDEV_AUX_VERSION_NEWER:
1347 (void) printf(gettext("newer version"));
1348 break;
1349
1350 case VDEV_AUX_UNSUP_FEAT:
1351 (void) printf(gettext("unsupported feature(s)"));
1352 break;
1353
1354 case VDEV_AUX_ERR_EXCEEDED:
1355 (void) printf(gettext("too many errors"));
1356 break;
1357
1358 default:
1359 (void) printf(gettext("corrupted data"));
1360 break;
1361 }
1362 }
1363 (void) printf("\n");
1364
1365 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1366 &child, &children) != 0)
1367 return;
1368
1369 for (c = 0; c < children; c++) {
1370 uint64_t is_log = B_FALSE;
1371
1372 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1373 &is_log);
1374 if (is_log)
1375 continue;
1376
1377 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
1378 print_import_config(vname, child[c], namewidth, depth + 2);
1379 free(vname);
1380 }
1381
1382 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1383 &child, &children) == 0) {
1384 (void) printf(gettext("\tcache\n"));
1385 for (c = 0; c < children; c++) {
1386 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1387 (void) printf("\t %s\n", vname);
1388 free(vname);
1389 }
1390 }
1391
1392 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1393 &child, &children) == 0) {
1394 (void) printf(gettext("\tspares\n"));
1395 for (c = 0; c < children; c++) {
1396 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1397 (void) printf("\t %s\n", vname);
1398 free(vname);
1399 }
1400 }
1401 }
1402
1403 /*
1404 * Print log vdevs.
1405 * Logs are recorded as top level vdevs in the main pool child array
1406 * but with "is_log" set to 1. We use either print_status_config() or
1407 * print_import_config() to print the top level logs then any log
1408 * children (eg mirrored slogs) are printed recursively - which
1409 * works because only the top level vdev is marked "is_log"
1410 */
1411 static void
1412 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1413 {
1414 uint_t c, children;
1415 nvlist_t **child;
1416
1417 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1418 &children) != 0)
1419 return;
1420
1421 (void) printf(gettext("\tlogs\n"));
1422
1423 for (c = 0; c < children; c++) {
1424 uint64_t is_log = B_FALSE;
1425 char *name;
1426
1427 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1428 &is_log);
1429 if (!is_log)
1430 continue;
1431 name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1432 if (verbose)
1433 print_status_config(zhp, name, child[c], namewidth,
1434 2, B_FALSE);
1435 else
1436 print_import_config(name, child[c], namewidth, 2);
1437 free(name);
1438 }
1439 }
1440
1441 /*
1442 * Display the status for the given pool.
1443 */
1444 static void
1445 show_import(nvlist_t *config)
1446 {
1447 uint64_t pool_state;
1448 vdev_stat_t *vs;
1449 char *name;
1450 uint64_t guid;
1451 char *msgid;
1452 nvlist_t *nvroot;
1453 int reason;
1454 const char *health;
1455 uint_t vsc;
1456 int namewidth;
1457 char *comment;
1458
1459 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1460 &name) == 0);
1461 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1462 &guid) == 0);
1463 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1464 &pool_state) == 0);
1465 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1466 &nvroot) == 0);
1467
1468 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1469 (uint64_t **)&vs, &vsc) == 0);
1470 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1471
1472 reason = zpool_import_status(config, &msgid);
1473
1474 (void) printf(gettext(" pool: %s\n"), name);
1475 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
1476 (void) printf(gettext(" state: %s"), health);
1477 if (pool_state == POOL_STATE_DESTROYED)
1478 (void) printf(gettext(" (DESTROYED)"));
1479 (void) printf("\n");
1480
1481 switch (reason) {
1482 case ZPOOL_STATUS_MISSING_DEV_R:
1483 case ZPOOL_STATUS_MISSING_DEV_NR:
1484 case ZPOOL_STATUS_BAD_GUID_SUM:
1485 (void) printf(gettext(" status: One or more devices are "
1486 "missing from the system.\n"));
1487 break;
1488
1489 case ZPOOL_STATUS_CORRUPT_LABEL_R:
1490 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1491 (void) printf(gettext(" status: One or more devices contains "
1492 "corrupted data.\n"));
1493 break;
1494
1495 case ZPOOL_STATUS_CORRUPT_DATA:
1496 (void) printf(
1497 gettext(" status: The pool data is corrupted.\n"));
1498 break;
1499
1500 case ZPOOL_STATUS_OFFLINE_DEV:
1501 (void) printf(gettext(" status: One or more devices "
1502 "are offlined.\n"));
1503 break;
1504
1505 case ZPOOL_STATUS_CORRUPT_POOL:
1506 (void) printf(gettext(" status: The pool metadata is "
1507 "corrupted.\n"));
1508 break;
1509
1510 case ZPOOL_STATUS_VERSION_OLDER:
1511 (void) printf(gettext(" status: The pool is formatted using a "
1512 "legacy on-disk version.\n"));
1513 break;
1514
1515 case ZPOOL_STATUS_VERSION_NEWER:
1516 (void) printf(gettext(" status: The pool is formatted using an "
1517 "incompatible version.\n"));
1518 break;
1519
1520 case ZPOOL_STATUS_FEAT_DISABLED:
1521 (void) printf(gettext(" status: Some supported features are "
1522 "not enabled on the pool.\n"));
1523 break;
1524
1525 case ZPOOL_STATUS_UNSUP_FEAT_READ:
1526 (void) printf(gettext("status: The pool uses the following "
1527 "feature(s) not supported on this sytem:\n"));
1528 zpool_print_unsup_feat(config);
1529 break;
1530
1531 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1532 (void) printf(gettext("status: The pool can only be accessed "
1533 "in read-only mode on this system. It\n\tcannot be "
1534 "accessed in read-write mode because it uses the "
1535 "following\n\tfeature(s) not supported on this system:\n"));
1536 zpool_print_unsup_feat(config);
1537 break;
1538
1539 case ZPOOL_STATUS_HOSTID_MISMATCH:
1540 (void) printf(gettext(" status: The pool was last accessed by "
1541 "another system.\n"));
1542 break;
1543
1544 case ZPOOL_STATUS_FAULTED_DEV_R:
1545 case ZPOOL_STATUS_FAULTED_DEV_NR:
1546 (void) printf(gettext(" status: One or more devices are "
1547 "faulted.\n"));
1548 break;
1549
1550 case ZPOOL_STATUS_BAD_LOG:
1551 (void) printf(gettext(" status: An intent log record cannot be "
1552 "read.\n"));
1553 break;
1554
1555 case ZPOOL_STATUS_RESILVERING:
1556 (void) printf(gettext(" status: One or more devices were being "
1557 "resilvered.\n"));
1558 break;
1559
1560 default:
1561 /*
1562 * No other status can be seen when importing pools.
1563 */
1564 assert(reason == ZPOOL_STATUS_OK);
1565 }
1566
1567 /*
1568 * Print out an action according to the overall state of the pool.
1569 */
1570 if (vs->vs_state == VDEV_STATE_HEALTHY) {
1571 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
1572 reason == ZPOOL_STATUS_FEAT_DISABLED) {
1573 (void) printf(gettext(" action: The pool can be "
1574 "imported using its name or numeric identifier, "
1575 "though\n\tsome features will not be available "
1576 "without an explicit 'zpool upgrade'.\n"));
1577 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
1578 (void) printf(gettext(" action: The pool can be "
1579 "imported using its name or numeric "
1580 "identifier and\n\tthe '-f' flag.\n"));
1581 } else {
1582 (void) printf(gettext(" action: The pool can be "
1583 "imported using its name or numeric "
1584 "identifier.\n"));
1585 }
1586 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1587 (void) printf(gettext(" action: The pool can be imported "
1588 "despite missing or damaged devices. The\n\tfault "
1589 "tolerance of the pool may be compromised if imported.\n"));
1590 } else {
1591 switch (reason) {
1592 case ZPOOL_STATUS_VERSION_NEWER:
1593 (void) printf(gettext(" action: The pool cannot be "
1594 "imported. Access the pool on a system running "
1595 "newer\n\tsoftware, or recreate the pool from "
1596 "backup.\n"));
1597 break;
1598 case ZPOOL_STATUS_UNSUP_FEAT_READ:
1599 (void) printf(gettext("action: The pool cannot be "
1600 "imported. Access the pool on a system that "
1601 "supports\n\tthe required feature(s), or recreate "
1602 "the pool from backup.\n"));
1603 break;
1604 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1605 (void) printf(gettext("action: The pool cannot be "
1606 "imported in read-write mode. Import the pool "
1607 "with\n"
1608 "\t\"-o readonly=on\", access the pool on a system "
1609 "that supports the\n\trequired feature(s), or "
1610 "recreate the pool from backup.\n"));
1611 break;
1612 case ZPOOL_STATUS_MISSING_DEV_R:
1613 case ZPOOL_STATUS_MISSING_DEV_NR:
1614 case ZPOOL_STATUS_BAD_GUID_SUM:
1615 (void) printf(gettext(" action: The pool cannot be "
1616 "imported. Attach the missing\n\tdevices and try "
1617 "again.\n"));
1618 break;
1619 default:
1620 (void) printf(gettext(" action: The pool cannot be "
1621 "imported due to damaged devices or data.\n"));
1622 }
1623 }
1624
1625 /* Print the comment attached to the pool. */
1626 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1627 (void) printf(gettext("comment: %s\n"), comment);
1628
1629 /*
1630 * If the state is "closed" or "can't open", and the aux state
1631 * is "corrupt data":
1632 */
1633 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1634 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1635 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1636 if (pool_state == POOL_STATE_DESTROYED)
1637 (void) printf(gettext("\tThe pool was destroyed, "
1638 "but can be imported using the '-Df' flags.\n"));
1639 else if (pool_state != POOL_STATE_EXPORTED)
1640 (void) printf(gettext("\tThe pool may be active on "
1641 "another system, but can be imported using\n\t"
1642 "the '-f' flag.\n"));
1643 }
1644
1645 if (msgid != NULL)
1646 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
1647 msgid);
1648
1649 (void) printf(gettext(" config:\n\n"));
1650
1651 namewidth = max_width(NULL, nvroot, 0, 0);
1652 if (namewidth < 10)
1653 namewidth = 10;
1654
1655 print_import_config(name, nvroot, namewidth, 0);
1656 if (num_logs(nvroot) > 0)
1657 print_logs(NULL, nvroot, namewidth, B_FALSE);
1658
1659 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1660 (void) printf(gettext("\n\tAdditional devices are known to "
1661 "be part of this pool, though their\n\texact "
1662 "configuration cannot be determined.\n"));
1663 }
1664 }
1665
1666 /*
1667 * Perform the import for the given configuration. This passes the heavy
1668 * lifting off to zpool_import_props(), and then mounts the datasets contained
1669 * within the pool.
1670 */
1671 static int
1672 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1673 nvlist_t *props, int flags)
1674 {
1675 zpool_handle_t *zhp;
1676 char *name;
1677 uint64_t state;
1678 uint64_t version;
1679
1680 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1681 &name) == 0);
1682
1683 verify(nvlist_lookup_uint64(config,
1684 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1685 verify(nvlist_lookup_uint64(config,
1686 ZPOOL_CONFIG_VERSION, &version) == 0);
1687 if (!SPA_VERSION_IS_SUPPORTED(version)) {
1688 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1689 "is formatted using an unsupported ZFS version\n"), name);
1690 return (1);
1691 } else if (state != POOL_STATE_EXPORTED &&
1692 !(flags & ZFS_IMPORT_ANY_HOST)) {
1693 uint64_t hostid;
1694
1695 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1696 &hostid) == 0) {
1697 if ((unsigned long)hostid != gethostid()) {
1698 char *hostname;
1699 uint64_t timestamp;
1700 time_t t;
1701
1702 verify(nvlist_lookup_string(config,
1703 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1704 verify(nvlist_lookup_uint64(config,
1705 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0);
1706 t = timestamp;
1707 (void) fprintf(stderr, gettext("cannot import "
1708 "'%s': pool may be in use from other "
1709 "system, it was last accessed by %s "
1710 "(hostid: 0x%lx) on %s"), name, hostname,
1711 (unsigned long)hostid,
1712 asctime(localtime(&t)));
1713 (void) fprintf(stderr, gettext("use '-f' to "
1714 "import anyway\n"));
1715 return (1);
1716 }
1717 } else {
1718 (void) fprintf(stderr, gettext("cannot import '%s': "
1719 "pool may be in use from other system\n"), name);
1720 (void) fprintf(stderr, gettext("use '-f' to import "
1721 "anyway\n"));
1722 return (1);
1723 }
1724 }
1725
1726 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
1727 return (1);
1728
1729 if (newname != NULL)
1730 name = (char *)newname;
1731
1732 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1733 return (1);
1734
1735 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1736 !(flags & ZFS_IMPORT_ONLY) &&
1737 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1738 zpool_close(zhp);
1739 return (1);
1740 }
1741
1742 zpool_close(zhp);
1743 return (0);
1744 }
1745
1746 /*
1747 * zpool import [-d dir] [-D]
1748 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1749 * [-d dir | -c cachefile] [-f] -a
1750 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1751 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
1752 *
1753 * -c Read pool information from a cachefile instead of searching
1754 * devices.
1755 *
1756 * -d Scan in a specific directory, other than /dev/dsk. More than
1757 * one directory can be specified using multiple '-d' options.
1758 *
1759 * -D Scan for previously destroyed pools or import all or only
1760 * specified destroyed pools.
1761 *
1762 * -R Temporarily import the pool, with all mountpoints relative to
1763 * the given root. The pool will remain exported when the machine
1764 * is rebooted.
1765 *
1766 * -V Import even in the presence of faulted vdevs. This is an
1767 * intentionally undocumented option for testing purposes, and
1768 * treats the pool configuration as complete, leaving any bad
1769 * vdevs in the FAULTED state. In other words, it does verbatim
1770 * import.
1771 *
1772 * -f Force import, even if it appears that the pool is active.
1773 *
1774 * -F Attempt rewind if necessary.
1775 *
1776 * -n See if rewind would work, but don't actually rewind.
1777 *
1778 * -N Import the pool but don't mount datasets.
1779 *
1780 * -T Specify a starting txg to use for import. This option is
1781 * intentionally undocumented option for testing purposes.
1782 *
1783 * -a Import all pools found.
1784 *
1785 * -o Set property=value and/or temporary mount options (without '=').
1786 *
1787 * The import command scans for pools to import, and import pools based on pool
1788 * name and GUID. The pool can also be renamed as part of the import process.
1789 */
1790 int
1791 zpool_do_import(int argc, char **argv)
1792 {
1793 char **searchdirs = NULL;
1794 int nsearch = 0;
1795 int c;
1796 int err = 0;
1797 nvlist_t *pools = NULL;
1798 boolean_t do_all = B_FALSE;
1799 boolean_t do_destroyed = B_FALSE;
1800 char *mntopts = NULL;
1801 nvpair_t *elem;
1802 nvlist_t *config;
1803 uint64_t searchguid = 0;
1804 char *searchname = NULL;
1805 char *propval;
1806 nvlist_t *found_config;
1807 nvlist_t *policy = NULL;
1808 nvlist_t *props = NULL;
1809 boolean_t first;
1810 int flags = ZFS_IMPORT_NORMAL;
1811 uint32_t rewind_policy = ZPOOL_NO_REWIND;
1812 boolean_t dryrun = B_FALSE;
1813 boolean_t do_rewind = B_FALSE;
1814 boolean_t xtreme_rewind = B_FALSE;
1815 uint64_t pool_state, txg = -1ULL;
1816 char *cachefile = NULL;
1817 importargs_t idata = { 0 };
1818 char *endptr;
1819
1820 /* check options */
1821 while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
1822 switch (c) {
1823 case 'a':
1824 do_all = B_TRUE;
1825 break;
1826 case 'c':
1827 cachefile = optarg;
1828 break;
1829 case 'd':
1830 if (searchdirs == NULL) {
1831 searchdirs = safe_malloc(sizeof (char *));
1832 } else {
1833 char **tmp = safe_malloc((nsearch + 1) *
1834 sizeof (char *));
1835 bcopy(searchdirs, tmp, nsearch *
1836 sizeof (char *));
1837 free(searchdirs);
1838 searchdirs = tmp;
1839 }
1840 searchdirs[nsearch++] = optarg;
1841 break;
1842 case 'D':
1843 do_destroyed = B_TRUE;
1844 break;
1845 case 'f':
1846 flags |= ZFS_IMPORT_ANY_HOST;
1847 break;
1848 case 'F':
1849 do_rewind = B_TRUE;
1850 break;
1851 case 'm':
1852 flags |= ZFS_IMPORT_MISSING_LOG;
1853 break;
1854 case 'n':
1855 dryrun = B_TRUE;
1856 break;
1857 case 'N':
1858 flags |= ZFS_IMPORT_ONLY;
1859 break;
1860 case 'o':
1861 if ((propval = strchr(optarg, '=')) != NULL) {
1862 *propval = '\0';
1863 propval++;
1864 if (add_prop_list(optarg, propval,
1865 &props, B_TRUE))
1866 goto error;
1867 } else {
1868 mntopts = optarg;
1869 }
1870 break;
1871 case 'R':
1872 if (add_prop_list(zpool_prop_to_name(
1873 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1874 goto error;
1875 if (nvlist_lookup_string(props,
1876 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1877 &propval) == 0)
1878 break;
1879 if (add_prop_list(zpool_prop_to_name(
1880 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1881 goto error;
1882 break;
1883 case 'T':
1884 errno = 0;
1885 txg = strtoull(optarg, &endptr, 10);
1886 if (errno != 0 || *endptr != '\0') {
1887 (void) fprintf(stderr,
1888 gettext("invalid txg value\n"));
1889 usage(B_FALSE);
1890 }
1891 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
1892 break;
1893 case 'V':
1894 flags |= ZFS_IMPORT_VERBATIM;
1895 break;
1896 case 'X':
1897 xtreme_rewind = B_TRUE;
1898 break;
1899 case ':':
1900 (void) fprintf(stderr, gettext("missing argument for "
1901 "'%c' option\n"), optopt);
1902 usage(B_FALSE);
1903 break;
1904 case '?':
1905 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1906 optopt);
1907 usage(B_FALSE);
1908 }
1909 }
1910
1911 argc -= optind;
1912 argv += optind;
1913
1914 if (cachefile && nsearch != 0) {
1915 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1916 usage(B_FALSE);
1917 }
1918
1919 if ((dryrun || xtreme_rewind) && !do_rewind) {
1920 (void) fprintf(stderr,
1921 gettext("-n or -X only meaningful with -F\n"));
1922 usage(B_FALSE);
1923 }
1924 if (dryrun)
1925 rewind_policy = ZPOOL_TRY_REWIND;
1926 else if (do_rewind)
1927 rewind_policy = ZPOOL_DO_REWIND;
1928 if (xtreme_rewind)
1929 rewind_policy |= ZPOOL_EXTREME_REWIND;
1930
1931 /* In the future, we can capture further policy and include it here */
1932 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
1933 nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
1934 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
1935 goto error;
1936
1937 if (searchdirs == NULL) {
1938 searchdirs = safe_malloc(sizeof (char *));
1939 searchdirs[0] = "/dev/dsk";
1940 nsearch = 1;
1941 }
1942
1943 /* check argument count */
1944 if (do_all) {
1945 if (argc != 0) {
1946 (void) fprintf(stderr, gettext("too many arguments\n"));
1947 usage(B_FALSE);
1948 }
1949 } else {
1950 if (argc > 2) {
1951 (void) fprintf(stderr, gettext("too many arguments\n"));
1952 usage(B_FALSE);
1953 }
1954
1955 /*
1956 * Check for the SYS_CONFIG privilege. We do this explicitly
1957 * here because otherwise any attempt to discover pools will
1958 * silently fail.
1959 */
1960 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1961 (void) fprintf(stderr, gettext("cannot "
1962 "discover pools: permission denied\n"));
1963 free(searchdirs);
1964 nvlist_free(policy);
1965 return (1);
1966 }
1967 }
1968
1969 /*
1970 * Depending on the arguments given, we do one of the following:
1971 *
1972 * <none> Iterate through all pools and display information about
1973 * each one.
1974 *
1975 * -a Iterate through all pools and try to import each one.
1976 *
1977 * <id> Find the pool that corresponds to the given GUID/pool
1978 * name and import that one.
1979 *
1980 * -D Above options applies only to destroyed pools.
1981 */
1982 if (argc != 0) {
1983 char *endptr;
1984
1985 errno = 0;
1986 searchguid = strtoull(argv[0], &endptr, 10);
1987 if (errno != 0 || *endptr != '\0')
1988 searchname = argv[0];
1989 found_config = NULL;
1990
1991 /*
1992 * User specified a name or guid. Ensure it's unique.
1993 */
1994 idata.unique = B_TRUE;
1995 }
1996
1997
1998 idata.path = searchdirs;
1999 idata.paths = nsearch;
2000 idata.poolname = searchname;
2001 idata.guid = searchguid;
2002 idata.cachefile = cachefile;
2003
2004 pools = zpool_search_import(g_zfs, &idata);
2005
2006 if (pools != NULL && idata.exists &&
2007 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2008 (void) fprintf(stderr, gettext("cannot import '%s': "
2009 "a pool with that name already exists\n"),
2010 argv[0]);
2011 (void) fprintf(stderr, gettext("use the form '%s "
2012 "<pool | id> <newpool>' to give it a new name\n"),
2013 "zpool import");
2014 err = 1;
2015 } else if (pools == NULL && idata.exists) {
2016 (void) fprintf(stderr, gettext("cannot import '%s': "
2017 "a pool with that name is already created/imported,\n"),
2018 argv[0]);
2019 (void) fprintf(stderr, gettext("and no additional pools "
2020 "with that name were found\n"));
2021 err = 1;
2022 } else if (pools == NULL) {
2023 if (argc != 0) {
2024 (void) fprintf(stderr, gettext("cannot import '%s': "
2025 "no such pool available\n"), argv[0]);
2026 }
2027 err = 1;
2028 }
2029
2030 if (err == 1) {
2031 free(searchdirs);
2032 nvlist_free(policy);
2033 return (1);
2034 }
2035
2036 /*
2037 * At this point we have a list of import candidate configs. Even if
2038 * we were searching by pool name or guid, we still need to
2039 * post-process the list to deal with pool state and possible
2040 * duplicate names.
2041 */
2042 err = 0;
2043 elem = NULL;
2044 first = B_TRUE;
2045 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2046
2047 verify(nvpair_value_nvlist(elem, &config) == 0);
2048
2049 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2050 &pool_state) == 0);
2051 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2052 continue;
2053 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2054 continue;
2055
2056 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
2057 policy) == 0);
2058
2059 if (argc == 0) {
2060 if (first)
2061 first = B_FALSE;
2062 else if (!do_all)
2063 (void) printf("\n");
2064
2065 if (do_all) {
2066 err |= do_import(config, NULL, mntopts,
2067 props, flags);
2068 } else {
2069 show_import(config);
2070 }
2071 } else if (searchname != NULL) {
2072 char *name;
2073
2074 /*
2075 * We are searching for a pool based on name.
2076 */
2077 verify(nvlist_lookup_string(config,
2078 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2079
2080 if (strcmp(name, searchname) == 0) {
2081 if (found_config != NULL) {
2082 (void) fprintf(stderr, gettext(
2083 "cannot import '%s': more than "
2084 "one matching pool\n"), searchname);
2085 (void) fprintf(stderr, gettext(
2086 "import by numeric ID instead\n"));
2087 err = B_TRUE;
2088 }
2089 found_config = config;
2090 }
2091 } else {
2092 uint64_t guid;
2093
2094 /*
2095 * Search for a pool by guid.
2096 */
2097 verify(nvlist_lookup_uint64(config,
2098 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2099
2100 if (guid == searchguid)
2101 found_config = config;
2102 }
2103 }
2104
2105 /*
2106 * If we were searching for a specific pool, verify that we found a
2107 * pool, and then do the import.
2108 */
2109 if (argc != 0 && err == 0) {
2110 if (found_config == NULL) {
2111 (void) fprintf(stderr, gettext("cannot import '%s': "
2112 "no such pool available\n"), argv[0]);
2113 err = B_TRUE;
2114 } else {
2115 err |= do_import(found_config, argc == 1 ? NULL :
2116 argv[1], mntopts, props, flags);
2117 }
2118 }
2119
2120 /*
2121 * If we were just looking for pools, report an error if none were
2122 * found.
2123 */
2124 if (argc == 0 && first)
2125 (void) fprintf(stderr,
2126 gettext("no pools available to import\n"));
2127
2128 error:
2129 nvlist_free(props);
2130 nvlist_free(pools);
2131 nvlist_free(policy);
2132 free(searchdirs);
2133
2134 return (err ? 1 : 0);
2135 }
2136
2137 typedef struct iostat_cbdata {
2138 boolean_t cb_verbose;
2139 int cb_namewidth;
2140 int cb_iteration;
2141 zpool_list_t *cb_list;
2142 } iostat_cbdata_t;
2143
2144 static void
2145 print_iostat_separator(iostat_cbdata_t *cb)
2146 {
2147 int i = 0;
2148
2149 for (i = 0; i < cb->cb_namewidth; i++)
2150 (void) printf("-");
2151 (void) printf(" ----- ----- ----- ----- ----- -----\n");
2152 }
2153
2154 static void
2155 print_iostat_header(iostat_cbdata_t *cb)
2156 {
2157 (void) printf("%*s capacity operations bandwidth\n",
2158 cb->cb_namewidth, "");
2159 (void) printf("%-*s alloc free read write read write\n",
2160 cb->cb_namewidth, "pool");
2161 print_iostat_separator(cb);
2162 }
2163
2164 /*
2165 * Display a single statistic.
2166 */
2167 static void
2168 print_one_stat(uint64_t value)
2169 {
2170 char buf[64];
2171
2172 zfs_nicenum(value, buf, sizeof (buf));
2173 (void) printf(" %5s", buf);
2174 }
2175
2176 /*
2177 * Print out all the statistics for the given vdev. This can either be the
2178 * toplevel configuration, or called recursively. If 'name' is NULL, then this
2179 * is a verbose output, and we don't want to display the toplevel pool stats.
2180 */
2181 void
2182 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2183 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2184 {
2185 nvlist_t **oldchild, **newchild;
2186 uint_t c, children;
2187 vdev_stat_t *oldvs, *newvs;
2188 vdev_stat_t zerovs = { 0 };
2189 uint64_t tdelta;
2190 double scale;
2191 char *vname;
2192
2193 if (oldnv != NULL) {
2194 verify(nvlist_lookup_uint64_array(oldnv,
2195 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2196 } else {
2197 oldvs = &zerovs;
2198 }
2199
2200 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2201 (uint64_t **)&newvs, &c) == 0);
2202
2203 if (strlen(name) + depth > cb->cb_namewidth)
2204 (void) printf("%*s%s", depth, "", name);
2205 else
2206 (void) printf("%*s%s%*s", depth, "", name,
2207 (int)(cb->cb_namewidth - strlen(name) - depth), "");
2208
2209 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2210
2211 if (tdelta == 0)
2212 scale = 1.0;
2213 else
2214 scale = (double)NANOSEC / tdelta;
2215
2216 /* only toplevel vdevs have capacity stats */
2217 if (newvs->vs_space == 0) {
2218 (void) printf(" - -");
2219 } else {
2220 print_one_stat(newvs->vs_alloc);
2221 print_one_stat(newvs->vs_space - newvs->vs_alloc);
2222 }
2223
2224 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2225 oldvs->vs_ops[ZIO_TYPE_READ])));
2226
2227 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2228 oldvs->vs_ops[ZIO_TYPE_WRITE])));
2229
2230 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2231 oldvs->vs_bytes[ZIO_TYPE_READ])));
2232
2233 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2234 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2235
2236 (void) printf("\n");
2237
2238 if (!cb->cb_verbose)
2239 return;
2240
2241 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2242 &newchild, &children) != 0)
2243 return;
2244
2245 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2246 &oldchild, &c) != 0)
2247 return;
2248
2249 for (c = 0; c < children; c++) {
2250 uint64_t ishole = B_FALSE, islog = B_FALSE;
2251
2252 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
2253 &ishole);
2254
2255 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
2256 &islog);
2257
2258 if (ishole || islog)
2259 continue;
2260
2261 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
2262 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2263 newchild[c], cb, depth + 2);
2264 free(vname);
2265 }
2266
2267 /*
2268 * Log device section
2269 */
2270
2271 if (num_logs(newnv) > 0) {
2272 (void) printf("%-*s - - - - - "
2273 "-\n", cb->cb_namewidth, "logs");
2274
2275 for (c = 0; c < children; c++) {
2276 uint64_t islog = B_FALSE;
2277 (void) nvlist_lookup_uint64(newchild[c],
2278 ZPOOL_CONFIG_IS_LOG, &islog);
2279
2280 if (islog) {
2281 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2282 B_FALSE);
2283 print_vdev_stats(zhp, vname, oldnv ?
2284 oldchild[c] : NULL, newchild[c],
2285 cb, depth + 2);
2286 free(vname);
2287 }
2288 }
2289
2290 }
2291
2292 /*
2293 * Include level 2 ARC devices in iostat output
2294 */
2295 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
2296 &newchild, &children) != 0)
2297 return;
2298
2299 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
2300 &oldchild, &c) != 0)
2301 return;
2302
2303 if (children > 0) {
2304 (void) printf("%-*s - - - - - "
2305 "-\n", cb->cb_namewidth, "cache");
2306 for (c = 0; c < children; c++) {
2307 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2308 B_FALSE);
2309 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2310 newchild[c], cb, depth + 2);
2311 free(vname);
2312 }
2313 }
2314 }
2315
2316 static int
2317 refresh_iostat(zpool_handle_t *zhp, void *data)
2318 {
2319 iostat_cbdata_t *cb = data;
2320 boolean_t missing;
2321
2322 /*
2323 * If the pool has disappeared, remove it from the list and continue.
2324 */
2325 if (zpool_refresh_stats(zhp, &missing) != 0)
2326 return (-1);
2327
2328 if (missing)
2329 pool_list_remove(cb->cb_list, zhp);
2330
2331 return (0);
2332 }
2333
2334 /*
2335 * Callback to print out the iostats for the given pool.
2336 */
2337 int
2338 print_iostat(zpool_handle_t *zhp, void *data)
2339 {
2340 iostat_cbdata_t *cb = data;
2341 nvlist_t *oldconfig, *newconfig;
2342 nvlist_t *oldnvroot, *newnvroot;
2343
2344 newconfig = zpool_get_config(zhp, &oldconfig);
2345
2346 if (cb->cb_iteration == 1)
2347 oldconfig = NULL;
2348
2349 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2350 &newnvroot) == 0);
2351
2352 if (oldconfig == NULL)
2353 oldnvroot = NULL;
2354 else
2355 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2356 &oldnvroot) == 0);
2357
2358 /*
2359 * Print out the statistics for the pool.
2360 */
2361 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2362
2363 if (cb->cb_verbose)
2364 print_iostat_separator(cb);
2365
2366 return (0);
2367 }
2368
2369 int
2370 get_namewidth(zpool_handle_t *zhp, void *data)
2371 {
2372 iostat_cbdata_t *cb = data;
2373 nvlist_t *config, *nvroot;
2374
2375 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2376 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2377 &nvroot) == 0);
2378 if (!cb->cb_verbose)
2379 cb->cb_namewidth = strlen(zpool_get_name(zhp));
2380 else
2381 cb->cb_namewidth = max_width(zhp, nvroot, 0,
2382 cb->cb_namewidth);
2383 }
2384
2385 /*
2386 * The width must fall into the range [10,38]. The upper limit is the
2387 * maximum we can have and still fit in 80 columns.
2388 */
2389 if (cb->cb_namewidth < 10)
2390 cb->cb_namewidth = 10;
2391 if (cb->cb_namewidth > 38)
2392 cb->cb_namewidth = 38;
2393
2394 return (0);
2395 }
2396
2397 /*
2398 * Parse the input string, get the 'interval' and 'count' value if there is one.
2399 */
2400 static void
2401 get_interval_count(int *argcp, char **argv, unsigned long *iv,
2402 unsigned long *cnt)
2403 {
2404 unsigned long interval = 0, count = 0;
2405 int argc = *argcp, errno;
2406
2407 /*
2408 * Determine if the last argument is an integer or a pool name
2409 */
2410 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2411 char *end;
2412
2413 errno = 0;
2414 interval = strtoul(argv[argc - 1], &end, 10);
2415
2416 if (*end == '\0' && errno == 0) {
2417 if (interval == 0) {
2418 (void) fprintf(stderr, gettext("interval "
2419 "cannot be zero\n"));
2420 usage(B_FALSE);
2421 }
2422 /*
2423 * Ignore the last parameter
2424 */
2425 argc--;
2426 } else {
2427 /*
2428 * If this is not a valid number, just plow on. The
2429 * user will get a more informative error message later
2430 * on.
2431 */
2432 interval = 0;
2433 }
2434 }
2435
2436 /*
2437 * If the last argument is also an integer, then we have both a count
2438 * and an interval.
2439 */
2440 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2441 char *end;
2442
2443 errno = 0;
2444 count = interval;
2445 interval = strtoul(argv[argc - 1], &end, 10);
2446
2447 if (*end == '\0' && errno == 0) {
2448 if (interval == 0) {
2449 (void) fprintf(stderr, gettext("interval "
2450 "cannot be zero\n"));
2451 usage(B_FALSE);
2452 }
2453
2454 /*
2455 * Ignore the last parameter
2456 */
2457 argc--;
2458 } else {
2459 interval = 0;
2460 }
2461 }
2462
2463 *iv = interval;
2464 *cnt = count;
2465 *argcp = argc;
2466 }
2467
2468 static void
2469 get_timestamp_arg(char c)
2470 {
2471 if (c == 'u')
2472 timestamp_fmt = UDATE;
2473 else if (c == 'd')
2474 timestamp_fmt = DDATE;
2475 else
2476 usage(B_FALSE);
2477 }
2478
2479 /*
2480 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2481 *
2482 * -v Display statistics for individual vdevs
2483 * -T Display a timestamp in date(1) or Unix format
2484 *
2485 * This command can be tricky because we want to be able to deal with pool
2486 * creation/destruction as well as vdev configuration changes. The bulk of this
2487 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
2488 * on pool_list_update() to detect the addition of new pools. Configuration
2489 * changes are all handled within libzfs.
2490 */
2491 int
2492 zpool_do_iostat(int argc, char **argv)
2493 {
2494 int c;
2495 int ret;
2496 int npools;
2497 unsigned long interval = 0, count = 0;
2498 zpool_list_t *list;
2499 boolean_t verbose = B_FALSE;
2500 iostat_cbdata_t cb;
2501
2502 /* check options */
2503 while ((c = getopt(argc, argv, "T:v")) != -1) {
2504 switch (c) {
2505 case 'T':
2506 get_timestamp_arg(*optarg);
2507 break;
2508 case 'v':
2509 verbose = B_TRUE;
2510 break;
2511 case '?':
2512 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2513 optopt);
2514 usage(B_FALSE);
2515 }
2516 }
2517
2518 argc -= optind;
2519 argv += optind;
2520
2521 get_interval_count(&argc, argv, &interval, &count);
2522
2523 /*
2524 * Construct the list of all interesting pools.
2525 */
2526 ret = 0;
2527 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2528 return (1);
2529
2530 if (pool_list_count(list) == 0 && argc != 0) {
2531 pool_list_free(list);
2532 return (1);
2533 }
2534
2535 if (pool_list_count(list) == 0 && interval == 0) {
2536 pool_list_free(list);
2537 (void) fprintf(stderr, gettext("no pools available\n"));
2538 return (1);
2539 }
2540
2541 /*
2542 * Enter the main iostat loop.
2543 */
2544 cb.cb_list = list;
2545 cb.cb_verbose = verbose;
2546 cb.cb_iteration = 0;
2547 cb.cb_namewidth = 0;
2548
2549 for (;;) {
2550 pool_list_update(list);
2551
2552 if ((npools = pool_list_count(list)) == 0)
2553 break;
2554
2555 /*
2556 * Refresh all statistics. This is done as an explicit step
2557 * before calculating the maximum name width, so that any
2558 * configuration changes are properly accounted for.
2559 */
2560 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2561
2562 /*
2563 * Iterate over all pools to determine the maximum width
2564 * for the pool / device name column across all pools.
2565 */
2566 cb.cb_namewidth = 0;
2567 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2568
2569 if (timestamp_fmt != NODATE)
2570 print_timestamp(timestamp_fmt);
2571
2572 /*
2573 * If it's the first time, or verbose mode, print the header.
2574 */
2575 if (++cb.cb_iteration == 1 || verbose)
2576 print_iostat_header(&cb);
2577
2578 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2579
2580 /*
2581 * If there's more than one pool, and we're not in verbose mode
2582 * (which prints a separator for us), then print a separator.
2583 */
2584 if (npools > 1 && !verbose)
2585 print_iostat_separator(&cb);
2586
2587 if (verbose)
2588 (void) printf("\n");
2589
2590 /*
2591 * Flush the output so that redirection to a file isn't buffered
2592 * indefinitely.
2593 */
2594 (void) fflush(stdout);
2595
2596 if (interval == 0)
2597 break;
2598
2599 if (count != 0 && --count == 0)
2600 break;
2601
2602 (void) sleep(interval);
2603 }
2604
2605 pool_list_free(list);
2606
2607 return (ret);
2608 }
2609
2610 typedef struct list_cbdata {
2611 boolean_t cb_verbose;
2612 int cb_namewidth;
2613 boolean_t cb_scripted;
2614 zprop_list_t *cb_proplist;
2615 } list_cbdata_t;
2616
2617 /*
2618 * Given a list of columns to display, output appropriate headers for each one.
2619 */
2620 static void
2621 print_header(list_cbdata_t *cb)
2622 {
2623 zprop_list_t *pl = cb->cb_proplist;
2624 char headerbuf[ZPOOL_MAXPROPLEN];
2625 const char *header;
2626 boolean_t first = B_TRUE;
2627 boolean_t right_justify;
2628 size_t width = 0;
2629
2630 for (; pl != NULL; pl = pl->pl_next) {
2631 width = pl->pl_width;
2632 if (first && cb->cb_verbose) {
2633 /*
2634 * Reset the width to accommodate the verbose listing
2635 * of devices.
2636 */
2637 width = cb->cb_namewidth;
2638 }
2639
2640 if (!first)
2641 (void) printf(" ");
2642 else
2643 first = B_FALSE;
2644
2645 right_justify = B_FALSE;
2646 if (pl->pl_prop != ZPROP_INVAL) {
2647 header = zpool_prop_column_name(pl->pl_prop);
2648 right_justify = zpool_prop_align_right(pl->pl_prop);
2649 } else {
2650 int i;
2651
2652 for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
2653 headerbuf[i] = toupper(pl->pl_user_prop[i]);
2654 headerbuf[i] = '\0';
2655 header = headerbuf;
2656 }
2657
2658 if (pl->pl_next == NULL && !right_justify)
2659 (void) printf("%s", header);
2660 else if (right_justify)
2661 (void) printf("%*s", width, header);
2662 else
2663 (void) printf("%-*s", width, header);
2664
2665 }
2666
2667 (void) printf("\n");
2668 }
2669
2670 /*
2671 * Given a pool and a list of properties, print out all the properties according
2672 * to the described layout.
2673 */
2674 static void
2675 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2676 {
2677 zprop_list_t *pl = cb->cb_proplist;
2678 boolean_t first = B_TRUE;
2679 char property[ZPOOL_MAXPROPLEN];
2680 char *propstr;
2681 boolean_t right_justify;
2682 size_t width;
2683
2684 for (; pl != NULL; pl = pl->pl_next) {
2685
2686 width = pl->pl_width;
2687 if (first && cb->cb_verbose) {
2688 /*
2689 * Reset the width to accommodate the verbose listing
2690 * of devices.
2691 */
2692 width = cb->cb_namewidth;
2693 }
2694
2695 if (!first) {
2696 if (cb->cb_scripted)
2697 (void) printf("\t");
2698 else
2699 (void) printf(" ");
2700 } else {
2701 first = B_FALSE;
2702 }
2703
2704 right_justify = B_FALSE;
2705 if (pl->pl_prop != ZPROP_INVAL) {
2706 if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
2707 zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
2708 propstr = "-";
2709 else if (zpool_get_prop(zhp, pl->pl_prop, property,
2710 sizeof (property), NULL) != 0)
2711 propstr = "-";
2712 else
2713 propstr = property;
2714
2715 right_justify = zpool_prop_align_right(pl->pl_prop);
2716 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
2717 zpool_prop_unsupported(pl->pl_user_prop)) &&
2718 zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
2719 sizeof (property)) == 0) {
2720 propstr = property;
2721 } else {
2722 propstr = "-";
2723 }
2724
2725
2726 /*
2727 * If this is being called in scripted mode, or if this is the
2728 * last column and it is left-justified, don't include a width
2729 * format specifier.
2730 */
2731 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
2732 (void) printf("%s", propstr);
2733 else if (right_justify)
2734 (void) printf("%*s", width, propstr);
2735 else
2736 (void) printf("%-*s", width, propstr);
2737 }
2738
2739 (void) printf("\n");
2740 }
2741
2742 static void
2743 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted)
2744 {
2745 char propval[64];
2746 boolean_t fixed;
2747 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
2748
2749 zfs_nicenum(value, propval, sizeof (propval));
2750
2751 if (prop == ZPOOL_PROP_EXPANDSZ && value == 0)
2752 (void) strlcpy(propval, "-", sizeof (propval));
2753
2754 if (scripted)
2755 (void) printf("\t%s", propval);
2756 else
2757 (void) printf(" %*s", width, propval);
2758 }
2759
2760 void
2761 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2762 list_cbdata_t *cb, int depth)
2763 {
2764 nvlist_t **child;
2765 vdev_stat_t *vs;
2766 uint_t c, children;
2767 char *vname;
2768 boolean_t scripted = cb->cb_scripted;
2769
2770 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
2771 (uint64_t **)&vs, &c) == 0);
2772
2773 if (name != NULL) {
2774 if (scripted)
2775 (void) printf("\t%s", name);
2776 else if (strlen(name) + depth > cb->cb_namewidth)
2777 (void) printf("%*s%s", depth, "", name);
2778 else
2779 (void) printf("%*s%s%*s", depth, "", name,
2780 (int)(cb->cb_namewidth - strlen(name) - depth), "");
2781
2782 /* only toplevel vdevs have capacity stats */
2783 if (vs->vs_space == 0) {
2784 if (scripted)
2785 (void) printf("\t-\t-\t-");
2786 else
2787 (void) printf(" - - -");
2788 } else {
2789 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space,
2790 scripted);
2791 print_one_column(ZPOOL_PROP_CAPACITY, vs->vs_alloc,
2792 scripted);
2793 print_one_column(ZPOOL_PROP_FREE,
2794 vs->vs_space - vs->vs_alloc, scripted);
2795 }
2796 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize,
2797 scripted);
2798 (void) printf("\n");
2799 }
2800
2801 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2802 &child, &children) != 0)
2803 return;
2804
2805 for (c = 0; c < children; c++) {
2806 uint64_t ishole = B_FALSE;
2807
2808 if (nvlist_lookup_uint64(child[c],
2809 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
2810 continue;
2811
2812 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
2813 print_list_stats(zhp, vname, child[c], cb, depth + 2);
2814 free(vname);
2815 }
2816
2817 /*
2818 * Include level 2 ARC devices in iostat output
2819 */
2820 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2821 &child, &children) != 0)
2822 return;
2823
2824 if (children > 0) {
2825 (void) printf("%-*s - - - - - "
2826 "-\n", cb->cb_namewidth, "cache");
2827 for (c = 0; c < children; c++) {
2828 vname = zpool_vdev_name(g_zfs, zhp, child[c],
2829 B_FALSE);
2830 print_list_stats(zhp, vname, child[c], cb, depth + 2);
2831 free(vname);
2832 }
2833 }
2834 }
2835
2836
2837 /*
2838 * Generic callback function to list a pool.
2839 */
2840 int
2841 list_callback(zpool_handle_t *zhp, void *data)
2842 {
2843 list_cbdata_t *cbp = data;
2844 nvlist_t *config;
2845 nvlist_t *nvroot;
2846
2847 config = zpool_get_config(zhp, NULL);
2848
2849 print_pool(zhp, cbp);
2850 if (!cbp->cb_verbose)
2851 return (0);
2852
2853 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2854 &nvroot) == 0);
2855 print_list_stats(zhp, NULL, nvroot, cbp, 0);
2856
2857 return (0);
2858 }
2859
2860 /*
2861 * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
2862 *
2863 * -H Scripted mode. Don't display headers, and separate properties
2864 * by a single tab.
2865 * -o List of properties to display. Defaults to
2866 * "name,size,allocated,free,capacity,health,altroot"
2867 * -T Display a timestamp in date(1) or Unix format
2868 *
2869 * List all pools in the system, whether or not they're healthy. Output space
2870 * statistics for each one, as well as health status summary.
2871 */
2872 int
2873 zpool_do_list(int argc, char **argv)
2874 {
2875 int c;
2876 int ret;
2877 list_cbdata_t cb = { 0 };
2878 static char default_props[] =
2879 "name,size,allocated,free,expandsize,capacity,dedupratio,"
2880 "health,altroot";
2881 char *props = default_props;
2882 unsigned long interval = 0, count = 0;
2883 zpool_list_t *list;
2884 boolean_t first = B_TRUE;
2885
2886 /* check options */
2887 while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
2888 switch (c) {
2889 case 'H':
2890 cb.cb_scripted = B_TRUE;
2891 break;
2892 case 'o':
2893 props = optarg;
2894 break;
2895 case 'T':
2896 get_timestamp_arg(*optarg);
2897 break;
2898 case 'v':
2899 cb.cb_verbose = B_TRUE;
2900 break;
2901 case ':':
2902 (void) fprintf(stderr, gettext("missing argument for "
2903 "'%c' option\n"), optopt);
2904 usage(B_FALSE);
2905 break;
2906 case '?':
2907 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2908 optopt);
2909 usage(B_FALSE);
2910 }
2911 }
2912
2913 argc -= optind;
2914 argv += optind;
2915
2916 get_interval_count(&argc, argv, &interval, &count);
2917
2918 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2919 usage(B_FALSE);
2920
2921 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL)
2922 return (1);
2923
2924 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
2925 (void) printf(gettext("no pools available\n"));
2926 zprop_free_list(cb.cb_proplist);
2927 return (0);
2928 }
2929
2930 for (;;) {
2931 pool_list_update(list);
2932
2933 if (pool_list_count(list) == 0)
2934 break;
2935
2936 cb.cb_namewidth = 0;
2937 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2938
2939 if (timestamp_fmt != NODATE)
2940 print_timestamp(timestamp_fmt);
2941
2942 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
2943 print_header(&cb);
2944 first = B_FALSE;
2945 }
2946 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
2947
2948 if (interval == 0)
2949 break;
2950
2951 if (count != 0 && --count == 0)
2952 break;
2953
2954 (void) sleep(interval);
2955 }
2956
2957 zprop_free_list(cb.cb_proplist);
2958 return (ret);
2959 }
2960
2961 static nvlist_t *
2962 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2963 {
2964 nvlist_t **child;
2965 uint_t c, children;
2966 nvlist_t *match;
2967 char *path;
2968
2969 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2970 &child, &children) != 0) {
2971 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2972 if (strncmp(name, "/dev/dsk/", 9) == 0)
2973 name += 9;
2974 if (strncmp(path, "/dev/dsk/", 9) == 0)
2975 path += 9;
2976 if (strcmp(name, path) == 0)
2977 return (nv);
2978 return (NULL);
2979 }
2980
2981 for (c = 0; c < children; c++)
2982 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2983 return (match);
2984
2985 return (NULL);
2986 }
2987
2988 static int
2989 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2990 {
2991 boolean_t force = B_FALSE;
2992 int c;
2993 nvlist_t *nvroot;
2994 char *poolname, *old_disk, *new_disk;
2995 zpool_handle_t *zhp;
2996 int ret;
2997
2998 /* check options */
2999 while ((c = getopt(argc, argv, "f")) != -1) {
3000 switch (c) {
3001 case 'f':
3002 force = B_TRUE;
3003 break;
3004 case '?':
3005 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3006 optopt);
3007 usage(B_FALSE);
3008 }
3009 }
3010
3011 argc -= optind;
3012 argv += optind;
3013
3014 /* get pool name and check number of arguments */
3015 if (argc < 1) {
3016 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3017 usage(B_FALSE);
3018 }
3019
3020 poolname = argv[0];
3021
3022 if (argc < 2) {
3023 (void) fprintf(stderr,
3024 gettext("missing <device> specification\n"));
3025 usage(B_FALSE);
3026 }
3027
3028 old_disk = argv[1];
3029
3030 if (argc < 3) {
3031 if (!replacing) {
3032 (void) fprintf(stderr,
3033 gettext("missing <new_device> specification\n"));
3034 usage(B_FALSE);
3035 }
3036 new_disk = old_disk;
3037 argc -= 1;
3038 argv += 1;
3039 } else {
3040 new_disk = argv[2];
3041 argc -= 2;
3042 argv += 2;
3043 }
3044
3045 if (argc > 1) {
3046 (void) fprintf(stderr, gettext("too many arguments\n"));
3047 usage(B_FALSE);
3048 }
3049
3050 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3051 return (1);
3052
3053 if (zpool_get_config(zhp, NULL) == NULL) {
3054 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
3055 poolname);
3056 zpool_close(zhp);
3057 return (1);
3058 }
3059
3060 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
3061 argc, argv);
3062 if (nvroot == NULL) {
3063 zpool_close(zhp);
3064 return (1);
3065 }
3066
3067 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
3068
3069 nvlist_free(nvroot);
3070 zpool_close(zhp);
3071
3072 return (ret);
3073 }
3074
3075 /*
3076 * zpool replace [-f] <pool> <device> <new_device>
3077 *
3078 * -f Force attach, even if <new_device> appears to be in use.
3079 *
3080 * Replace <device> with <new_device>.
3081 */
3082 /* ARGSUSED */
3083 int
3084 zpool_do_replace(int argc, char **argv)
3085 {
3086 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
3087 }
3088
3089 /*
3090 * zpool attach [-f] <pool> <device> <new_device>
3091 *
3092 * -f Force attach, even if <new_device> appears to be in use.
3093 *
3094 * Attach <new_device> to the mirror containing <device>. If <device> is not
3095 * part of a mirror, then <device> will be transformed into a mirror of
3096 * <device> and <new_device>. In either case, <new_device> will begin life
3097 * with a DTL of [0, now], and will immediately begin to resilver itself.
3098 */
3099 int
3100 zpool_do_attach(int argc, char **argv)
3101 {
3102 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
3103 }
3104
3105 /*
3106 * zpool detach [-f] <pool> <device>
3107 *
3108 * -f Force detach of <device>, even if DTLs argue against it
3109 * (not supported yet)
3110 *
3111 * Detach a device from a mirror. The operation will be refused if <device>
3112 * is the last device in the mirror, or if the DTLs indicate that this device
3113 * has the only valid copy of some data.
3114 */
3115 /* ARGSUSED */
3116 int
3117 zpool_do_detach(int argc, char **argv)
3118 {
3119 int c;
3120 char *poolname, *path;
3121 zpool_handle_t *zhp;
3122 int ret;
3123
3124 /* check options */
3125 while ((c = getopt(argc, argv, "f")) != -1) {
3126 switch (c) {
3127 case 'f':
3128 case '?':
3129 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3130 optopt);
3131 usage(B_FALSE);
3132 }
3133 }
3134
3135 argc -= optind;
3136 argv += optind;
3137
3138 /* get pool name and check number of arguments */
3139 if (argc < 1) {
3140 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3141 usage(B_FALSE);
3142 }
3143
3144 if (argc < 2) {
3145 (void) fprintf(stderr,
3146 gettext("missing <device> specification\n"));
3147 usage(B_FALSE);
3148 }
3149
3150 poolname = argv[0];
3151 path = argv[1];
3152
3153 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3154 return (1);
3155
3156 ret = zpool_vdev_detach(zhp, path);
3157
3158 zpool_close(zhp);
3159
3160 return (ret);
3161 }
3162
3163 /*
3164 * zpool split [-n] [-o prop=val] ...
3165 * [-o mntopt] ...
3166 * [-R altroot] <pool> <newpool> [<device> ...]
3167 *
3168 * -n Do not split the pool, but display the resulting layout if
3169 * it were to be split.
3170 * -o Set property=value, or set mount options.
3171 * -R Mount the split-off pool under an alternate root.
3172 *
3173 * Splits the named pool and gives it the new pool name. Devices to be split
3174 * off may be listed, provided that no more than one device is specified
3175 * per top-level vdev mirror. The newly split pool is left in an exported
3176 * state unless -R is specified.
3177 *
3178 * Restrictions: the top-level of the pool pool must only be made up of
3179 * mirrors; all devices in the pool must be healthy; no device may be
3180 * undergoing a resilvering operation.
3181 */
3182 int
3183 zpool_do_split(int argc, char **argv)
3184 {
3185 char *srcpool, *newpool, *propval;
3186 char *mntopts = NULL;
3187 splitflags_t flags;
3188 int c, ret = 0;
3189 zpool_handle_t *zhp;
3190 nvlist_t *config, *props = NULL;
3191
3192 flags.dryrun = B_FALSE;
3193 flags.import = B_FALSE;
3194
3195 /* check options */
3196 while ((c = getopt(argc, argv, ":R:no:")) != -1) {
3197 switch (c) {
3198 case 'R':
3199 flags.import = B_TRUE;
3200 if (add_prop_list(
3201 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
3202 &props, B_TRUE) != 0) {
3203 if (props)
3204 nvlist_free(props);
3205 usage(B_FALSE);
3206 }
3207 break;
3208 case 'n':
3209 flags.dryrun = B_TRUE;
3210 break;
3211 case 'o':
3212 if ((propval = strchr(optarg, '=')) != NULL) {
3213 *propval = '\0';
3214 propval++;
3215 if (add_prop_list(optarg, propval,
3216 &props, B_TRUE) != 0) {
3217 if (props)
3218 nvlist_free(props);
3219 usage(B_FALSE);
3220 }
3221 } else {
3222 mntopts = optarg;
3223 }
3224 break;
3225 case ':':
3226 (void) fprintf(stderr, gettext("missing argument for "
3227 "'%c' option\n"), optopt);
3228 usage(B_FALSE);
3229 break;
3230 case '?':
3231 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3232 optopt);
3233 usage(B_FALSE);
3234 break;
3235 }
3236 }
3237
3238 if (!flags.import && mntopts != NULL) {
3239 (void) fprintf(stderr, gettext("setting mntopts is only "
3240 "valid when importing the pool\n"));
3241 usage(B_FALSE);
3242 }
3243
3244 argc -= optind;
3245 argv += optind;
3246
3247 if (argc < 1) {
3248 (void) fprintf(stderr, gettext("Missing pool name\n"));
3249 usage(B_FALSE);
3250 }
3251 if (argc < 2) {
3252 (void) fprintf(stderr, gettext("Missing new pool name\n"));
3253 usage(B_FALSE);
3254 }
3255
3256 srcpool = argv[0];
3257 newpool = argv[1];
3258
3259 argc -= 2;
3260 argv += 2;
3261
3262 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
3263 return (1);
3264
3265 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
3266 if (config == NULL) {
3267 ret = 1;
3268 } else {
3269 if (flags.dryrun) {
3270 (void) printf(gettext("would create '%s' with the "
3271 "following layout:\n\n"), newpool);
3272 print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
3273 }
3274 nvlist_free(config);
3275 }
3276
3277 zpool_close(zhp);
3278
3279 if (ret != 0 || flags.dryrun || !flags.import)
3280 return (ret);
3281
3282 /*
3283 * The split was successful. Now we need to open the new
3284 * pool and import it.
3285 */
3286 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
3287 return (1);
3288 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
3289 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
3290 ret = 1;
3291 (void) fprintf(stderr, gettext("Split was successful, but "
3292 "the datasets could not all be mounted\n"));
3293 (void) fprintf(stderr, gettext("Try doing '%s' with a "
3294 "different altroot\n"), "zpool import");
3295 }
3296 zpool_close(zhp);
3297
3298 return (ret);
3299 }
3300
3301
3302
3303 /*
3304 * zpool online <pool> <device> ...
3305 */
3306 int
3307 zpool_do_online(int argc, char **argv)
3308 {
3309 int c, i;
3310 char *poolname;
3311 zpool_handle_t *zhp;
3312 int ret = 0;
3313 vdev_state_t newstate;
3314 int flags = 0;
3315
3316 /* check options */
3317 while ((c = getopt(argc, argv, "et")) != -1) {
3318 switch (c) {
3319 case 'e':
3320 flags |= ZFS_ONLINE_EXPAND;
3321 break;
3322 case 't':
3323 case '?':
3324 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3325 optopt);
3326 usage(B_FALSE);
3327 }
3328 }
3329
3330 argc -= optind;
3331 argv += optind;
3332
3333 /* get pool name and check number of arguments */
3334 if (argc < 1) {
3335 (void) fprintf(stderr, gettext("missing pool name\n"));
3336 usage(B_FALSE);
3337 }
3338 if (argc < 2) {
3339 (void) fprintf(stderr, gettext("missing device name\n"));
3340 usage(B_FALSE);
3341 }
3342
3343 poolname = argv[0];
3344
3345 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3346 return (1);
3347
3348 for (i = 1; i < argc; i++) {
3349 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
3350 if (newstate != VDEV_STATE_HEALTHY) {
3351 (void) printf(gettext("warning: device '%s' "
3352 "onlined, but remains in faulted state\n"),
3353 argv[i]);
3354 if (newstate == VDEV_STATE_FAULTED)
3355 (void) printf(gettext("use 'zpool "
3356 "clear' to restore a faulted "
3357 "device\n"));
3358 else
3359 (void) printf(gettext("use 'zpool "
3360 "replace' to replace devices "
3361 "that are no longer present\n"));
3362 }
3363 } else {
3364 ret = 1;
3365 }
3366 }
3367
3368 zpool_close(zhp);
3369
3370 return (ret);
3371 }
3372
3373 /*
3374 * zpool offline [-ft] <pool> <device> ...
3375 *
3376 * -f Force the device into the offline state, even if doing
3377 * so would appear to compromise pool availability.
3378 * (not supported yet)
3379 *
3380 * -t Only take the device off-line temporarily. The offline
3381 * state will not be persistent across reboots.
3382 */
3383 /* ARGSUSED */
3384 int
3385 zpool_do_offline(int argc, char **argv)
3386 {
3387 int c, i;
3388 char *poolname;
3389 zpool_handle_t *zhp;
3390 int ret = 0;
3391 boolean_t istmp = B_FALSE;
3392
3393 /* check options */
3394 while ((c = getopt(argc, argv, "ft")) != -1) {
3395 switch (c) {
3396 case 't':
3397 istmp = B_TRUE;
3398 break;
3399 case 'f':
3400 case '?':
3401 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3402 optopt);
3403 usage(B_FALSE);
3404 }
3405 }
3406
3407 argc -= optind;
3408 argv += optind;
3409
3410 /* get pool name and check number of arguments */
3411 if (argc < 1) {
3412 (void) fprintf(stderr, gettext("missing pool name\n"));
3413 usage(B_FALSE);
3414 }
3415 if (argc < 2) {
3416 (void) fprintf(stderr, gettext("missing device name\n"));
3417 usage(B_FALSE);
3418 }
3419
3420 poolname = argv[0];
3421
3422 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3423 return (1);
3424
3425 for (i = 1; i < argc; i++) {
3426 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
3427 ret = 1;
3428 }
3429
3430 zpool_close(zhp);
3431
3432 return (ret);
3433 }
3434
3435 /*
3436 * zpool clear <pool> [device]
3437 *
3438 * Clear all errors associated with a pool or a particular device.
3439 */
3440 int
3441 zpool_do_clear(int argc, char **argv)
3442 {
3443 int c;
3444 int ret = 0;
3445 boolean_t dryrun = B_FALSE;
3446 boolean_t do_rewind = B_FALSE;
3447 boolean_t xtreme_rewind = B_FALSE;
3448 uint32_t rewind_policy = ZPOOL_NO_REWIND;
3449 nvlist_t *policy = NULL;
3450 zpool_handle_t *zhp;
3451 char *pool, *device;
3452
3453 /* check options */
3454 while ((c = getopt(argc, argv, "FnX")) != -1) {
3455 switch (c) {
3456 case 'F':
3457 do_rewind = B_TRUE;
3458 break;
3459 case 'n':
3460 dryrun = B_TRUE;
3461 break;
3462 case 'X':
3463 xtreme_rewind = B_TRUE;
3464 break;
3465 case '?':
3466 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3467 optopt);
3468 usage(B_FALSE);
3469 }
3470 }
3471
3472 argc -= optind;
3473 argv += optind;
3474
3475 if (argc < 1) {
3476 (void) fprintf(stderr, gettext("missing pool name\n"));
3477 usage(B_FALSE);
3478 }
3479
3480 if (argc > 2) {
3481 (void) fprintf(stderr, gettext("too many arguments\n"));
3482 usage(B_FALSE);
3483 }
3484
3485 if ((dryrun || xtreme_rewind) && !do_rewind) {
3486 (void) fprintf(stderr,
3487 gettext("-n or -X only meaningful with -F\n"));
3488 usage(B_FALSE);
3489 }
3490 if (dryrun)
3491 rewind_policy = ZPOOL_TRY_REWIND;
3492 else if (do_rewind)
3493 rewind_policy = ZPOOL_DO_REWIND;
3494 if (xtreme_rewind)
3495 rewind_policy |= ZPOOL_EXTREME_REWIND;
3496
3497 /* In future, further rewind policy choices can be passed along here */
3498 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3499 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
3500 return (1);
3501
3502 pool = argv[0];
3503 device = argc == 2 ? argv[1] : NULL;
3504
3505 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
3506 nvlist_free(policy);
3507 return (1);
3508 }
3509
3510 if (zpool_clear(zhp, device, policy) != 0)
3511 ret = 1;
3512
3513 zpool_close(zhp);
3514
3515 nvlist_free(policy);
3516
3517 return (ret);
3518 }
3519
3520 /*
3521 * zpool reguid <pool>
3522 */
3523 int
3524 zpool_do_reguid(int argc, char **argv)
3525 {
3526 int c;
3527 char *poolname;
3528 zpool_handle_t *zhp;
3529 int ret = 0;
3530
3531 /* check options */
3532 while ((c = getopt(argc, argv, "")) != -1) {
3533 switch (c) {
3534 case '?':
3535 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3536 optopt);
3537 usage(B_FALSE);
3538 }
3539 }
3540
3541 argc -= optind;
3542 argv += optind;
3543
3544 /* get pool name and check number of arguments */
3545 if (argc < 1) {
3546 (void) fprintf(stderr, gettext("missing pool name\n"));
3547 usage(B_FALSE);
3548 }
3549
3550 if (argc > 1) {
3551 (void) fprintf(stderr, gettext("too many arguments\n"));
3552 usage(B_FALSE);
3553 }
3554
3555 poolname = argv[0];
3556 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3557 return (1);
3558
3559 ret = zpool_reguid(zhp);
3560
3561 zpool_close(zhp);
3562 return (ret);
3563 }
3564
3565
3566 /*
3567 * zpool reopen <pool>
3568 *
3569 * Reopen the pool so that the kernel can update the sizes of all vdevs.
3570 */
3571 int
3572 zpool_do_reopen(int argc, char **argv)
3573 {
3574 int c;
3575 int ret = 0;
3576 zpool_handle_t *zhp;
3577 char *pool;
3578
3579 /* check options */
3580 while ((c = getopt(argc, argv, "")) != -1) {
3581 switch (c) {
3582 case '?':
3583 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3584 optopt);
3585 usage(B_FALSE);
3586 }
3587 }
3588
3589 argc--;
3590 argv++;
3591
3592 if (argc < 1) {
3593 (void) fprintf(stderr, gettext("missing pool name\n"));
3594 usage(B_FALSE);
3595 }
3596
3597 if (argc > 1) {
3598 (void) fprintf(stderr, gettext("too many arguments\n"));
3599 usage(B_FALSE);
3600 }
3601
3602 pool = argv[0];
3603 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
3604 return (1);
3605
3606 ret = zpool_reopen(zhp);
3607 zpool_close(zhp);
3608 return (ret);
3609 }
3610
3611 typedef struct scrub_cbdata {
3612 int cb_type;
3613 int cb_argc;
3614 char **cb_argv;
3615 } scrub_cbdata_t;
3616
3617 int
3618 scrub_callback(zpool_handle_t *zhp, void *data)
3619 {
3620 scrub_cbdata_t *cb = data;
3621 int err;
3622
3623 /*
3624 * Ignore faulted pools.
3625 */
3626 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3627 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3628 "currently unavailable\n"), zpool_get_name(zhp));
3629 return (1);
3630 }
3631
3632 err = zpool_scan(zhp, cb->cb_type);
3633
3634 return (err != 0);
3635 }
3636
3637 /*
3638 * zpool scrub [-s] <pool> ...
3639 *
3640 * -s Stop. Stops any in-progress scrub.
3641 */
3642 int
3643 zpool_do_scrub(int argc, char **argv)
3644 {
3645 int c;
3646 scrub_cbdata_t cb;
3647
3648 cb.cb_type = POOL_SCAN_SCRUB;
3649
3650 /* check options */
3651 while ((c = getopt(argc, argv, "s")) != -1) {
3652 switch (c) {
3653 case 's':
3654 cb.cb_type = POOL_SCAN_NONE;
3655 break;
3656 case '?':
3657 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3658 optopt);
3659 usage(B_FALSE);
3660 }
3661 }
3662
3663 cb.cb_argc = argc;
3664 cb.cb_argv = argv;
3665 argc -= optind;
3666 argv += optind;
3667
3668 if (argc < 1) {
3669 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3670 usage(B_FALSE);
3671 }
3672
3673 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
3674 }
3675
3676 typedef struct status_cbdata {
3677 int cb_count;
3678 boolean_t cb_allpools;
3679 boolean_t cb_verbose;
3680 boolean_t cb_explain;
3681 boolean_t cb_first;
3682 boolean_t cb_dedup_stats;
3683 } status_cbdata_t;
3684
3685 /*
3686 * Print out detailed scrub status.
3687 */
3688 void
3689 print_scan_status(pool_scan_stat_t *ps)
3690 {
3691 time_t start, end;
3692 uint64_t elapsed, mins_left, hours_left;
3693 uint64_t pass_exam, examined, total;
3694 uint_t rate;
3695 double fraction_done;
3696 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
3697
3698 (void) printf(gettext(" scan: "));
3699
3700 /* If there's never been a scan, there's not much to say. */
3701 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
3702 ps->pss_func >= POOL_SCAN_FUNCS) {
3703 (void) printf(gettext("none requested\n"));
3704 return;
3705 }
3706
3707 start = ps->pss_start_time;
3708 end = ps->pss_end_time;
3709 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
3710
3711 assert(ps->pss_func == POOL_SCAN_SCRUB ||
3712 ps->pss_func == POOL_SCAN_RESILVER);
3713 /*
3714 * Scan is finished or canceled.
3715 */
3716 if (ps->pss_state == DSS_FINISHED) {
3717 uint64_t minutes_taken = (end - start) / 60;
3718 char *fmt;
3719
3720 if (ps->pss_func == POOL_SCAN_SCRUB) {
3721 fmt = gettext("scrub repaired %s in %lluh%um with "
3722 "%llu errors on %s");
3723 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3724 fmt = gettext("resilvered %s in %lluh%um with "
3725 "%llu errors on %s");
3726 }
3727 /* LINTED */
3728 (void) printf(fmt, processed_buf,
3729 (u_longlong_t)(minutes_taken / 60),
3730 (uint_t)(minutes_taken % 60),
3731 (u_longlong_t)ps->pss_errors,
3732 ctime((time_t *)&end));
3733 return;
3734 } else if (ps->pss_state == DSS_CANCELED) {
3735 if (ps->pss_func == POOL_SCAN_SCRUB) {
3736 (void) printf(gettext("scrub canceled on %s"),
3737 ctime(&end));
3738 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3739 (void) printf(gettext("resilver canceled on %s"),
3740 ctime(&end));
3741 }
3742 return;
3743 }
3744
3745 assert(ps->pss_state == DSS_SCANNING);
3746
3747 /*
3748 * Scan is in progress.
3749 */
3750 if (ps->pss_func == POOL_SCAN_SCRUB) {
3751 (void) printf(gettext("scrub in progress since %s"),
3752 ctime(&start));
3753 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3754 (void) printf(gettext("resilver in progress since %s"),
3755 ctime(&start));
3756 }
3757
3758 examined = ps->pss_examined ? ps->pss_examined : 1;
3759 total = ps->pss_to_examine;
3760 fraction_done = (double)examined / total;
3761
3762 /* elapsed time for this pass */
3763 elapsed = time(NULL) - ps->pss_pass_start;
3764 elapsed = elapsed ? elapsed : 1;
3765 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
3766 rate = pass_exam / elapsed;
3767 rate = rate ? rate : 1;
3768 mins_left = ((total - examined) / rate) / 60;
3769 hours_left = mins_left / 60;
3770
3771 zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
3772 zfs_nicenum(total, total_buf, sizeof (total_buf));
3773 zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
3774
3775 /*
3776 * do not print estimated time if hours_left is more than 30 days
3777 */
3778 (void) printf(gettext(" %s scanned out of %s at %s/s"),
3779 examined_buf, total_buf, rate_buf);
3780 if (hours_left < (30 * 24)) {
3781 (void) printf(gettext(", %lluh%um to go\n"),
3782 (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
3783 } else {
3784 (void) printf(gettext(
3785 ", (scan is slow, no estimated time)\n"));
3786 }
3787
3788 if (ps->pss_func == POOL_SCAN_RESILVER) {
3789 (void) printf(gettext(" %s resilvered, %.2f%% done\n"),
3790 processed_buf, 100 * fraction_done);
3791 } else if (ps->pss_func == POOL_SCAN_SCRUB) {
3792 (void) printf(gettext(" %s repaired, %.2f%% done\n"),
3793 processed_buf, 100 * fraction_done);
3794 }
3795 }
3796
3797 static void
3798 print_error_log(zpool_handle_t *zhp)
3799 {
3800 nvlist_t *nverrlist = NULL;
3801 nvpair_t *elem;
3802 char *pathname;
3803 size_t len = MAXPATHLEN * 2;
3804
3805 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
3806 (void) printf("errors: List of errors unavailable "
3807 "(insufficient privileges)\n");
3808 return;
3809 }
3810
3811 (void) printf("errors: Permanent errors have been "
3812 "detected in the following files:\n\n");
3813
3814 pathname = safe_malloc(len);
3815 elem = NULL;
3816 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
3817 nvlist_t *nv;
3818 uint64_t dsobj, obj;
3819
3820 verify(nvpair_value_nvlist(elem, &nv) == 0);
3821 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
3822 &dsobj) == 0);
3823 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
3824 &obj) == 0);
3825 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
3826 (void) printf("%7s %s\n", "", pathname);
3827 }
3828 free(pathname);
3829 nvlist_free(nverrlist);
3830 }
3831
3832 static void
3833 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
3834 int namewidth)
3835 {
3836 uint_t i;
3837 char *name;
3838
3839 if (nspares == 0)
3840 return;
3841
3842 (void) printf(gettext("\tspares\n"));
3843
3844 for (i = 0; i < nspares; i++) {
3845 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
3846 print_status_config(zhp, name, spares[i],
3847 namewidth, 2, B_TRUE);
3848 free(name);
3849 }
3850 }
3851
3852 static void
3853 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
3854 int namewidth)
3855 {
3856 uint_t i;
3857 char *name;
3858
3859 if (nl2cache == 0)
3860 return;
3861
3862 (void) printf(gettext("\tcache\n"));
3863
3864 for (i = 0; i < nl2cache; i++) {
3865 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
3866 print_status_config(zhp, name, l2cache[i],
3867 namewidth, 2, B_FALSE);
3868 free(name);
3869 }
3870 }
3871
3872 static void
3873 print_dedup_stats(nvlist_t *config)
3874 {
3875 ddt_histogram_t *ddh;
3876 ddt_stat_t *dds;
3877 ddt_object_t *ddo;
3878 uint_t c;
3879
3880 /*
3881 * If the pool was faulted then we may not have been able to
3882 * obtain the config. Otherwise, if we have anything in the dedup
3883 * table continue processing the stats.
3884 */
3885 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
3886 (uint64_t **)&ddo, &c) != 0)
3887 return;
3888
3889 (void) printf("\n");
3890 (void) printf(gettext(" dedup: "));
3891 if (ddo->ddo_count == 0) {
3892 (void) printf(gettext("no DDT entries\n"));
3893 return;
3894 }
3895
3896 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
3897 (u_longlong_t)ddo->ddo_count,
3898 (u_longlong_t)ddo->ddo_dspace,
3899 (u_longlong_t)ddo->ddo_mspace);
3900
3901 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
3902 (uint64_t **)&dds, &c) == 0);
3903 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
3904 (uint64_t **)&ddh, &c) == 0);
3905 zpool_dump_ddt(dds, ddh);
3906 }
3907
3908 /*
3909 * Display a summary of pool status. Displays a summary such as:
3910 *
3911 * pool: tank
3912 * status: DEGRADED
3913 * reason: One or more devices ...
3914 * see: http://illumos.org/msg/ZFS-xxxx-01
3915 * config:
3916 * mirror DEGRADED
3917 * c1t0d0 OK
3918 * c2t0d0 UNAVAIL
3919 *
3920 * When given the '-v' option, we print out the complete config. If the '-e'
3921 * option is specified, then we print out error rate information as well.
3922 */
3923 int
3924 status_callback(zpool_handle_t *zhp, void *data)
3925 {
3926 status_cbdata_t *cbp = data;
3927 nvlist_t *config, *nvroot;
3928 char *msgid;
3929 int reason;
3930 const char *health;
3931 uint_t c;
3932 vdev_stat_t *vs;
3933
3934 config = zpool_get_config(zhp, NULL);
3935 reason = zpool_get_status(zhp, &msgid);
3936
3937 cbp->cb_count++;
3938
3939 /*
3940 * If we were given 'zpool status -x', only report those pools with
3941 * problems.
3942 */
3943 if (cbp->cb_explain &&
3944 (reason == ZPOOL_STATUS_OK ||
3945 reason == ZPOOL_STATUS_VERSION_OLDER ||
3946 reason == ZPOOL_STATUS_FEAT_DISABLED)) {
3947 if (!cbp->cb_allpools) {
3948 (void) printf(gettext("pool '%s' is healthy\n"),
3949 zpool_get_name(zhp));
3950 if (cbp->cb_first)
3951 cbp->cb_first = B_FALSE;
3952 }
3953 return (0);
3954 }
3955
3956 if (cbp->cb_first)
3957 cbp->cb_first = B_FALSE;
3958 else
3959 (void) printf("\n");
3960
3961 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3962 &nvroot) == 0);
3963 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
3964 (uint64_t **)&vs, &c) == 0);
3965 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3966
3967 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3968 (void) printf(gettext(" state: %s\n"), health);
3969
3970 switch (reason) {
3971 case ZPOOL_STATUS_MISSING_DEV_R:
3972 (void) printf(gettext("status: One or more devices could not "
3973 "be opened. Sufficient replicas exist for\n\tthe pool to "
3974 "continue functioning in a degraded state.\n"));
3975 (void) printf(gettext("action: Attach the missing device and "
3976 "online it using 'zpool online'.\n"));
3977 break;
3978
3979 case ZPOOL_STATUS_MISSING_DEV_NR:
3980 (void) printf(gettext("status: One or more devices could not "
3981 "be opened. There are insufficient\n\treplicas for the "
3982 "pool to continue functioning.\n"));
3983 (void) printf(gettext("action: Attach the missing device and "
3984 "online it using 'zpool online'.\n"));
3985 break;
3986
3987 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3988 (void) printf(gettext("status: One or more devices could not "
3989 "be used because the label is missing or\n\tinvalid. "
3990 "Sufficient replicas exist for the pool to continue\n\t"
3991 "functioning in a degraded state.\n"));
3992 (void) printf(gettext("action: Replace the device using "
3993 "'zpool replace'.\n"));
3994 break;
3995
3996 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3997 (void) printf(gettext("status: One or more devices could not "
3998 "be used because the label is missing \n\tor invalid. "
3999 "There are insufficient replicas for the pool to "
4000 "continue\n\tfunctioning.\n"));
4001 zpool_explain_recover(zpool_get_handle(zhp),
4002 zpool_get_name(zhp), reason, config);
4003 break;
4004
4005 case ZPOOL_STATUS_FAILING_DEV:
4006 (void) printf(gettext("status: One or more devices has "
4007 "experienced an unrecoverable error. An\n\tattempt was "
4008 "made to correct the error. Applications are "
4009 "unaffected.\n"));
4010 (void) printf(gettext("action: Determine if the device needs "
4011 "to be replaced, and clear the errors\n\tusing "
4012 "'zpool clear' or replace the device with 'zpool "
4013 "replace'.\n"));
4014 break;
4015
4016 case ZPOOL_STATUS_OFFLINE_DEV:
4017 (void) printf(gettext("status: One or more devices has "
4018 "been taken offline by the administrator.\n\tSufficient "
4019 "replicas exist for the pool to continue functioning in "
4020 "a\n\tdegraded state.\n"));
4021 (void) printf(gettext("action: Online the device using "
4022 "'zpool online' or replace the device with\n\t'zpool "
4023 "replace'.\n"));
4024 break;
4025
4026 case ZPOOL_STATUS_REMOVED_DEV:
4027 (void) printf(gettext("status: One or more devices has "
4028 "been removed by the administrator.\n\tSufficient "
4029 "replicas exist for the pool to continue functioning in "
4030 "a\n\tdegraded state.\n"));
4031 (void) printf(gettext("action: Online the device using "
4032 "'zpool online' or replace the device with\n\t'zpool "
4033 "replace'.\n"));
4034 break;
4035
4036 case ZPOOL_STATUS_RESILVERING:
4037 (void) printf(gettext("status: One or more devices is "
4038 "currently being resilvered. The pool will\n\tcontinue "
4039 "to function, possibly in a degraded state.\n"));
4040 (void) printf(gettext("action: Wait for the resilver to "
4041 "complete.\n"));
4042 break;
4043
4044 case ZPOOL_STATUS_CORRUPT_DATA:
4045 (void) printf(gettext("status: One or more devices has "
4046 "experienced an error resulting in data\n\tcorruption. "
4047 "Applications may be affected.\n"));
4048 (void) printf(gettext("action: Restore the file in question "
4049 "if possible. Otherwise restore the\n\tentire pool from "
4050 "backup.\n"));
4051 break;
4052
4053 case ZPOOL_STATUS_CORRUPT_POOL:
4054 (void) printf(gettext("status: The pool metadata is corrupted "
4055 "and the pool cannot be opened.\n"));
4056 zpool_explain_recover(zpool_get_handle(zhp),
4057 zpool_get_name(zhp), reason, config);
4058 break;
4059
4060 case ZPOOL_STATUS_VERSION_OLDER:
4061 (void) printf(gettext("status: The pool is formatted using a "
4062 "legacy on-disk format. The pool can\n\tstill be used, "
4063 "but some features are unavailable.\n"));
4064 (void) printf(gettext("action: Upgrade the pool using 'zpool "
4065 "upgrade'. Once this is done, the\n\tpool will no longer "
4066 "be accessible on software that does not support feature\n"
4067 "\tflags.\n"));
4068 break;
4069
4070 case ZPOOL_STATUS_VERSION_NEWER:
4071 (void) printf(gettext("status: The pool has been upgraded to a "
4072 "newer, incompatible on-disk version.\n\tThe pool cannot "
4073 "be accessed on this system.\n"));
4074 (void) printf(gettext("action: Access the pool from a system "
4075 "running more recent software, or\n\trestore the pool from "
4076 "backup.\n"));
4077 break;
4078
4079 case ZPOOL_STATUS_FEAT_DISABLED:
4080 (void) printf(gettext("status: Some supported features are not "
4081 "enabled on the pool. The pool can\n\tstill be used, but "
4082 "some features are unavailable.\n"));
4083 (void) printf(gettext("action: Enable all features using "
4084 "'zpool upgrade'. Once this is done,\n\tthe pool may no "
4085 "longer be accessible by software that does not support\n\t"
4086 "the features. See zpool-features(5) for details.\n"));
4087 break;
4088
4089 case ZPOOL_STATUS_UNSUP_FEAT_READ:
4090 (void) printf(gettext("status: The pool cannot be accessed on "
4091 "this system because it uses the\n\tfollowing feature(s) "
4092 "not supported on this system:\n"));
4093 zpool_print_unsup_feat(config);
4094 (void) printf("\n");
4095 (void) printf(gettext("action: Access the pool from a system "
4096 "that supports the required feature(s),\n\tor restore the "
4097 "pool from backup.\n"));
4098 break;
4099
4100 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4101 (void) printf(gettext("status: The pool can only be accessed "
4102 "in read-only mode on this system. It\n\tcannot be "
4103 "accessed in read-write mode because it uses the "
4104 "following\n\tfeature(s) not supported on this system:\n"));
4105 zpool_print_unsup_feat(config);
4106 (void) printf("\n");
4107 (void) printf(gettext("action: The pool cannot be accessed in "
4108 "read-write mode. Import the pool with\n"
4109 "\t\"-o readonly=on\", access the pool from a system that "
4110 "supports the\n\trequired feature(s), or restore the "
4111 "pool from backup.\n"));
4112 break;
4113
4114 case ZPOOL_STATUS_FAULTED_DEV_R:
4115 (void) printf(gettext("status: One or more devices are "
4116 "faulted in response to persistent errors.\n\tSufficient "
4117 "replicas exist for the pool to continue functioning "
4118 "in a\n\tdegraded state.\n"));
4119 (void) printf(gettext("action: Replace the faulted device, "
4120 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4121 break;
4122
4123 case ZPOOL_STATUS_FAULTED_DEV_NR:
4124 (void) printf(gettext("status: One or more devices are "
4125 "faulted in response to persistent errors. There are "
4126 "insufficient replicas for the pool to\n\tcontinue "
4127 "functioning.\n"));
4128 (void) printf(gettext("action: Destroy and re-create the pool "
4129 "from a backup source. Manually marking the device\n"
4130 "\trepaired using 'zpool clear' may allow some data "
4131 "to be recovered.\n"));
4132 break;
4133
4134 case ZPOOL_STATUS_IO_FAILURE_WAIT:
4135 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
4136 (void) printf(gettext("status: One or more devices are "
4137 "faulted in response to IO failures.\n"));
4138 (void) printf(gettext("action: Make sure the affected devices "
4139 "are connected, then run 'zpool clear'.\n"));
4140 break;
4141
4142 case ZPOOL_STATUS_BAD_LOG:
4143 (void) printf(gettext("status: An intent log record "
4144 "could not be read.\n"
4145 "\tWaiting for adminstrator intervention to fix the "
4146 "faulted pool.\n"));
4147 (void) printf(gettext("action: Either restore the affected "
4148 "device(s) and run 'zpool online',\n"
4149 "\tor ignore the intent log records by running "
4150 "'zpool clear'.\n"));
4151 break;
4152
4153 default:
4154 /*
4155 * The remaining errors can't actually be generated, yet.
4156 */
4157 assert(reason == ZPOOL_STATUS_OK);
4158 }
4159
4160 if (msgid != NULL)
4161 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"),
4162 msgid);
4163
4164 if (config != NULL) {
4165 int namewidth;
4166 uint64_t nerr;
4167 nvlist_t **spares, **l2cache;
4168 uint_t nspares, nl2cache;
4169 pool_scan_stat_t *ps = NULL;
4170
4171 (void) nvlist_lookup_uint64_array(nvroot,
4172 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
4173 print_scan_status(ps);
4174
4175 namewidth = max_width(zhp, nvroot, 0, 0);
4176 if (namewidth < 10)
4177 namewidth = 10;
4178
4179 (void) printf(gettext("config:\n\n"));
4180 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
4181 "NAME", "STATE", "READ", "WRITE", "CKSUM");
4182 print_status_config(zhp, zpool_get_name(zhp), nvroot,
4183 namewidth, 0, B_FALSE);
4184
4185 if (num_logs(nvroot) > 0)
4186 print_logs(zhp, nvroot, namewidth, B_TRUE);
4187 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
4188 &l2cache, &nl2cache) == 0)
4189 print_l2cache(zhp, l2cache, nl2cache, namewidth);
4190
4191 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
4192 &spares, &nspares) == 0)
4193 print_spares(zhp, spares, nspares, namewidth);
4194
4195 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
4196 &nerr) == 0) {
4197 nvlist_t *nverrlist = NULL;
4198
4199 /*
4200 * If the approximate error count is small, get a
4201 * precise count by fetching the entire log and
4202 * uniquifying the results.
4203 */
4204 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
4205 zpool_get_errlog(zhp, &nverrlist) == 0) {
4206 nvpair_t *elem;
4207
4208 elem = NULL;
4209 nerr = 0;
4210 while ((elem = nvlist_next_nvpair(nverrlist,
4211 elem)) != NULL) {
4212 nerr++;
4213 }
4214 }
4215 nvlist_free(nverrlist);
4216
4217 (void) printf("\n");
4218
4219 if (nerr == 0)
4220 (void) printf(gettext("errors: No known data "
4221 "errors\n"));
4222 else if (!cbp->cb_verbose)
4223 (void) printf(gettext("errors: %llu data "
4224 "errors, use '-v' for a list\n"),
4225 (u_longlong_t)nerr);
4226 else
4227 print_error_log(zhp);
4228 }
4229
4230 if (cbp->cb_dedup_stats)
4231 print_dedup_stats(config);
4232 } else {
4233 (void) printf(gettext("config: The configuration cannot be "
4234 "determined.\n"));
4235 }
4236
4237 return (0);
4238 }
4239
4240 /*
4241 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
4242 *
4243 * -v Display complete error logs
4244 * -x Display only pools with potential problems
4245 * -D Display dedup status (undocumented)
4246 * -T Display a timestamp in date(1) or Unix format
4247 *
4248 * Describes the health status of all pools or some subset.
4249 */
4250 int
4251 zpool_do_status(int argc, char **argv)
4252 {
4253 int c;
4254 int ret;
4255 unsigned long interval = 0, count = 0;
4256 status_cbdata_t cb = { 0 };
4257
4258 /* check options */
4259 while ((c = getopt(argc, argv, "vxDT:")) != -1) {
4260 switch (c) {
4261 case 'v':
4262 cb.cb_verbose = B_TRUE;
4263 break;
4264 case 'x':
4265 cb.cb_explain = B_TRUE;
4266 break;
4267 case 'D':
4268 cb.cb_dedup_stats = B_TRUE;
4269 break;
4270 case 'T':
4271 get_timestamp_arg(*optarg);
4272 break;
4273 case '?':
4274 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4275 optopt);
4276 usage(B_FALSE);
4277 }
4278 }
4279
4280 argc -= optind;
4281 argv += optind;
4282
4283 get_interval_count(&argc, argv, &interval, &count);
4284
4285 if (argc == 0)
4286 cb.cb_allpools = B_TRUE;
4287
4288 cb.cb_first = B_TRUE;
4289
4290 for (;;) {
4291 if (timestamp_fmt != NODATE)
4292 print_timestamp(timestamp_fmt);
4293
4294 ret = for_each_pool(argc, argv, B_TRUE, NULL,
4295 status_callback, &cb);
4296
4297 if (argc == 0 && cb.cb_count == 0)
4298 (void) printf(gettext("no pools available\n"));
4299 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
4300 (void) printf(gettext("all pools are healthy\n"));
4301
4302 if (ret != 0)
4303 return (ret);
4304
4305 if (interval == 0)
4306 break;
4307
4308 if (count != 0 && --count == 0)
4309 break;
4310
4311 (void) sleep(interval);
4312 }
4313
4314 return (0);
4315 }
4316
4317 typedef struct upgrade_cbdata {
4318 int cb_first;
4319 int cb_argc;
4320 uint64_t cb_version;
4321 char **cb_argv;
4322 } upgrade_cbdata_t;
4323
4324 static int
4325 upgrade_version(zpool_handle_t *zhp, uint64_t version)
4326 {
4327 int ret;
4328 nvlist_t *config;
4329 uint64_t oldversion;
4330
4331 config = zpool_get_config(zhp, NULL);
4332 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4333 &oldversion) == 0);
4334
4335 assert(SPA_VERSION_IS_SUPPORTED(oldversion));
4336 assert(oldversion < version);
4337
4338 ret = zpool_upgrade(zhp, version);
4339 if (ret != 0)
4340 return (ret);
4341
4342 if (version >= SPA_VERSION_FEATURES) {
4343 (void) printf(gettext("Successfully upgraded "
4344 "'%s' from version %llu to feature flags.\n"),
4345 zpool_get_name(zhp), oldversion);
4346 } else {
4347 (void) printf(gettext("Successfully upgraded "
4348 "'%s' from version %llu to version %llu.\n"),
4349 zpool_get_name(zhp), oldversion, version);
4350 }
4351
4352 return (0);
4353 }
4354
4355 static int
4356 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
4357 {
4358 int i, ret, count;
4359 boolean_t firstff = B_TRUE;
4360 nvlist_t *enabled = zpool_get_features(zhp);
4361
4362 count = 0;
4363 for (i = 0; i < SPA_FEATURES; i++) {
4364 const char *fname = spa_feature_table[i].fi_uname;
4365 const char *fguid = spa_feature_table[i].fi_guid;
4366 if (!nvlist_exists(enabled, fguid)) {
4367 char *propname;
4368 verify(-1 != asprintf(&propname, "feature@%s", fname));
4369 ret = zpool_set_prop(zhp, propname,
4370 ZFS_FEATURE_ENABLED);
4371 if (ret != 0) {
4372 free(propname);
4373 return (ret);
4374 }
4375 count++;
4376
4377 if (firstff) {
4378 (void) printf(gettext("Enabled the "
4379 "following features on '%s':\n"),
4380 zpool_get_name(zhp));
4381 firstff = B_FALSE;
4382 }
4383 (void) printf(gettext(" %s\n"), fname);
4384 free(propname);
4385 }
4386 }
4387
4388 if (countp != NULL)
4389 *countp = count;
4390 return (0);
4391 }
4392
4393 static int
4394 upgrade_cb(zpool_handle_t *zhp, void *arg)
4395 {
4396 upgrade_cbdata_t *cbp = arg;
4397 nvlist_t *config;
4398 uint64_t version;
4399 boolean_t printnl = B_FALSE;
4400 int ret;
4401
4402 config = zpool_get_config(zhp, NULL);
4403 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4404 &version) == 0);
4405
4406 assert(SPA_VERSION_IS_SUPPORTED(version));
4407
4408 if (version < cbp->cb_version) {
4409 cbp->cb_first = B_FALSE;
4410 ret = upgrade_version(zhp, cbp->cb_version);
4411 if (ret != 0)
4412 return (ret);
4413 printnl = B_TRUE;
4414
4415 /*
4416 * If they did "zpool upgrade -a", then we could
4417 * be doing ioctls to different pools. We need
4418 * to log this history once to each pool, and bypass
4419 * the normal history logging that happens in main().
4420 */
4421 (void) zpool_log_history(g_zfs, history_str);
4422 log_history = B_FALSE;
4423 }
4424
4425 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4426 int count;
4427 ret = upgrade_enable_all(zhp, &count);
4428 if (ret != 0)
4429 return (ret);
4430
4431 if (count > 0) {
4432 cbp->cb_first = B_FALSE;
4433 printnl = B_TRUE;
4434 }
4435 }
4436
4437 if (printnl) {
4438 (void) printf(gettext("\n"));
4439 }
4440
4441 return (0);
4442 }
4443
4444 static int
4445 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
4446 {
4447 upgrade_cbdata_t *cbp = arg;
4448 nvlist_t *config;
4449 uint64_t version;
4450
4451 config = zpool_get_config(zhp, NULL);
4452 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4453 &version) == 0);
4454
4455 assert(SPA_VERSION_IS_SUPPORTED(version));
4456
4457 if (version < SPA_VERSION_FEATURES) {
4458 if (cbp->cb_first) {
4459 (void) printf(gettext("The following pools are "
4460 "formatted with legacy version numbers and can\n"
4461 "be upgraded to use feature flags. After "
4462 "being upgraded, these pools\nwill no "
4463 "longer be accessible by software that does not "
4464 "support feature\nflags.\n\n"));
4465 (void) printf(gettext("VER POOL\n"));
4466 (void) printf(gettext("--- ------------\n"));
4467 cbp->cb_first = B_FALSE;
4468 }
4469
4470 (void) printf("%2llu %s\n", (u_longlong_t)version,
4471 zpool_get_name(zhp));
4472 }
4473
4474 return (0);
4475 }
4476
4477 static int
4478 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
4479 {
4480 upgrade_cbdata_t *cbp = arg;
4481 nvlist_t *config;
4482 uint64_t version;
4483
4484 config = zpool_get_config(zhp, NULL);
4485 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4486 &version) == 0);
4487
4488 if (version >= SPA_VERSION_FEATURES) {
4489 int i;
4490 boolean_t poolfirst = B_TRUE;
4491 nvlist_t *enabled = zpool_get_features(zhp);
4492
4493 for (i = 0; i < SPA_FEATURES; i++) {
4494 const char *fguid = spa_feature_table[i].fi_guid;
4495 const char *fname = spa_feature_table[i].fi_uname;
4496 if (!nvlist_exists(enabled, fguid)) {
4497 if (cbp->cb_first) {
4498 (void) printf(gettext("\nSome "
4499 "supported features are not "
4500 "enabled on the following pools. "
4501 "Once a\nfeature is enabled the "
4502 "pool may become incompatible with "
4503 "software\nthat does not support "
4504 "the feature. See "
4505 "zpool-features(5) for "
4506 "details.\n\n"));
4507 (void) printf(gettext("POOL "
4508 "FEATURE\n"));
4509 (void) printf(gettext("------"
4510 "---------\n"));
4511 cbp->cb_first = B_FALSE;
4512 }
4513
4514 if (poolfirst) {
4515 (void) printf(gettext("%s\n"),
4516 zpool_get_name(zhp));
4517 poolfirst = B_FALSE;
4518 }
4519
4520 (void) printf(gettext(" %s\n"), fname);
4521 }
4522 }
4523 }
4524
4525 return (0);
4526 }
4527
4528 /* ARGSUSED */
4529 static int
4530 upgrade_one(zpool_handle_t *zhp, void *data)
4531 {
4532 boolean_t printnl = B_FALSE;
4533 upgrade_cbdata_t *cbp = data;
4534 uint64_t cur_version;
4535 int ret;
4536
4537 if (strcmp("log", zpool_get_name(zhp)) == 0) {
4538 (void) printf(gettext("'log' is now a reserved word\n"
4539 "Pool 'log' must be renamed using export and import"
4540 " to upgrade.\n"));
4541 return (1);
4542 }
4543
4544 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
4545 if (cur_version > cbp->cb_version) {
4546 (void) printf(gettext("Pool '%s' is already formatted "
4547 "using more current version '%llu'.\n\n"),
4548 zpool_get_name(zhp), cur_version);
4549 return (0);
4550 }
4551
4552 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
4553 (void) printf(gettext("Pool '%s' is already formatted "
4554 "using version %llu.\n\n"), zpool_get_name(zhp),
4555 cbp->cb_version);
4556 return (0);
4557 }
4558
4559 if (cur_version != cbp->cb_version) {
4560 printnl = B_TRUE;
4561 ret = upgrade_version(zhp, cbp->cb_version);
4562 if (ret != 0)
4563 return (ret);
4564 }
4565
4566 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4567 int count = 0;
4568 ret = upgrade_enable_all(zhp, &count);
4569 if (ret != 0)
4570 return (ret);
4571
4572 if (count != 0) {
4573 printnl = B_TRUE;
4574 } else if (cur_version == SPA_VERSION) {
4575 (void) printf(gettext("Pool '%s' already has all "
4576 "supported features enabled.\n"),
4577 zpool_get_name(zhp));
4578 }
4579 }
4580
4581 if (printnl) {
4582 (void) printf(gettext("\n"));
4583 }
4584
4585 return (0);
4586 }
4587
4588 /*
4589 * zpool upgrade
4590 * zpool upgrade -v
4591 * zpool upgrade [-V version] <-a | pool ...>
4592 *
4593 * With no arguments, display downrev'd ZFS pool available for upgrade.
4594 * Individual pools can be upgraded by specifying the pool, and '-a' will
4595 * upgrade all pools.
4596 */
4597 int
4598 zpool_do_upgrade(int argc, char **argv)
4599 {
4600 int c;
4601 upgrade_cbdata_t cb = { 0 };
4602 int ret = 0;
4603 boolean_t showversions = B_FALSE;
4604 boolean_t upgradeall = B_FALSE;
4605 char *end;
4606
4607
4608 /* check options */
4609 while ((c = getopt(argc, argv, ":avV:")) != -1) {
4610 switch (c) {
4611 case 'a':
4612 upgradeall = B_TRUE;
4613 break;
4614 case 'v':
4615 showversions = B_TRUE;
4616 break;
4617 case 'V':
4618 cb.cb_version = strtoll(optarg, &end, 10);
4619 if (*end != '\0' ||
4620 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
4621 (void) fprintf(stderr,
4622 gettext("invalid version '%s'\n"), optarg);
4623 usage(B_FALSE);
4624 }
4625 break;
4626 case ':':
4627 (void) fprintf(stderr, gettext("missing argument for "
4628 "'%c' option\n"), optopt);
4629 usage(B_FALSE);
4630 break;
4631 case '?':
4632 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4633 optopt);
4634 usage(B_FALSE);
4635 }
4636 }
4637
4638 cb.cb_argc = argc;
4639 cb.cb_argv = argv;
4640 argc -= optind;
4641 argv += optind;
4642
4643 if (cb.cb_version == 0) {
4644 cb.cb_version = SPA_VERSION;
4645 } else if (!upgradeall && argc == 0) {
4646 (void) fprintf(stderr, gettext("-V option is "
4647 "incompatible with other arguments\n"));
4648 usage(B_FALSE);
4649 }
4650
4651 if (showversions) {
4652 if (upgradeall || argc != 0) {
4653 (void) fprintf(stderr, gettext("-v option is "
4654 "incompatible with other arguments\n"));
4655 usage(B_FALSE);
4656 }
4657 } else if (upgradeall) {
4658 if (argc != 0) {
4659 (void) fprintf(stderr, gettext("-a option should not "
4660 "be used along with a pool name\n"));
4661 usage(B_FALSE);
4662 }
4663 }
4664
4665 (void) printf(gettext("This system supports ZFS pool feature "
4666 "flags.\n\n"));
4667 if (showversions) {
4668 int i;
4669
4670 (void) printf(gettext("The following features are "
4671 "supported:\n\n"));
4672 (void) printf(gettext("FEAT DESCRIPTION\n"));
4673 (void) printf("----------------------------------------------"
4674 "---------------\n");
4675 for (i = 0; i < SPA_FEATURES; i++) {
4676 zfeature_info_t *fi = &spa_feature_table[i];
4677 const char *ro = fi->fi_can_readonly ?
4678 " (read-only compatible)" : "";
4679
4680 (void) printf("%-37s%s\n", fi->fi_uname, ro);
4681 (void) printf(" %s\n", fi->fi_desc);
4682 }
4683 (void) printf("\n");
4684
4685 (void) printf(gettext("The following legacy versions are also "
4686 "supported:\n\n"));
4687 (void) printf(gettext("VER DESCRIPTION\n"));
4688 (void) printf("--- -----------------------------------------"
4689 "---------------\n");
4690 (void) printf(gettext(" 1 Initial ZFS version\n"));
4691 (void) printf(gettext(" 2 Ditto blocks "
4692 "(replicated metadata)\n"));
4693 (void) printf(gettext(" 3 Hot spares and double parity "
4694 "RAID-Z\n"));
4695 (void) printf(gettext(" 4 zpool history\n"));
4696 (void) printf(gettext(" 5 Compression using the gzip "
4697 "algorithm\n"));
4698 (void) printf(gettext(" 6 bootfs pool property\n"));
4699 (void) printf(gettext(" 7 Separate intent log devices\n"));
4700 (void) printf(gettext(" 8 Delegated administration\n"));
4701 (void) printf(gettext(" 9 refquota and refreservation "
4702 "properties\n"));
4703 (void) printf(gettext(" 10 Cache devices\n"));
4704 (void) printf(gettext(" 11 Improved scrub performance\n"));
4705 (void) printf(gettext(" 12 Snapshot properties\n"));
4706 (void) printf(gettext(" 13 snapused property\n"));
4707 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
4708 (void) printf(gettext(" 15 user/group space accounting\n"));
4709 (void) printf(gettext(" 16 stmf property support\n"));
4710 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
4711 (void) printf(gettext(" 18 Snapshot user holds\n"));
4712 (void) printf(gettext(" 19 Log device removal\n"));
4713 (void) printf(gettext(" 20 Compression using zle "
4714 "(zero-length encoding)\n"));
4715 (void) printf(gettext(" 21 Deduplication\n"));
4716 (void) printf(gettext(" 22 Received properties\n"));
4717 (void) printf(gettext(" 23 Slim ZIL\n"));
4718 (void) printf(gettext(" 24 System attributes\n"));
4719 (void) printf(gettext(" 25 Improved scrub stats\n"));
4720 (void) printf(gettext(" 26 Improved snapshot deletion "
4721 "performance\n"));
4722 (void) printf(gettext(" 27 Improved snapshot creation "
4723 "performance\n"));
4724 (void) printf(gettext(" 28 Multiple vdev replacements\n"));
4725 (void) printf(gettext("\nFor more information on a particular "
4726 "version, including supported releases,\n"));
4727 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
4728 } else if (argc == 0 && upgradeall) {
4729 cb.cb_first = B_TRUE;
4730 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4731 if (ret == 0 && cb.cb_first) {
4732 if (cb.cb_version == SPA_VERSION) {
4733 (void) printf(gettext("All pools are already "
4734 "formatted using feature flags.\n\n"));
4735 (void) printf(gettext("Every feature flags "
4736 "pool already has all supported features "
4737 "enabled.\n"));
4738 } else {
4739 (void) printf(gettext("All pools are already "
4740 "formatted with version %llu or higher.\n"),
4741 cb.cb_version);
4742 }
4743 }
4744 } else if (argc == 0) {
4745 cb.cb_first = B_TRUE;
4746 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
4747 assert(ret == 0);
4748
4749 if (cb.cb_first) {
4750 (void) printf(gettext("All pools are formatted "
4751 "using feature flags.\n\n"));
4752 } else {
4753 (void) printf(gettext("\nUse 'zpool upgrade -v' "
4754 "for a list of available legacy versions.\n"));
4755 }
4756
4757 cb.cb_first = B_TRUE;
4758 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
4759 assert(ret == 0);
4760
4761 if (cb.cb_first) {
4762 (void) printf(gettext("Every feature flags pool has "
4763 "all supported features enabled.\n"));
4764 } else {
4765 (void) printf(gettext("\n"));
4766 }
4767 } else {
4768 ret = for_each_pool(argc, argv, B_FALSE, NULL,
4769 upgrade_one, &cb);
4770 }
4771
4772 return (ret);
4773 }
4774
4775 typedef struct hist_cbdata {
4776 boolean_t first;
4777 boolean_t longfmt;
4778 boolean_t internal;
4779 } hist_cbdata_t;
4780
4781 /*
4782 * Print out the command history for a specific pool.
4783 */
4784 static int
4785 get_history_one(zpool_handle_t *zhp, void *data)
4786 {
4787 nvlist_t *nvhis;
4788 nvlist_t **records;
4789 uint_t numrecords;
4790 int ret, i;
4791 hist_cbdata_t *cb = (hist_cbdata_t *)data;
4792
4793 cb->first = B_FALSE;
4794
4795 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
4796
4797 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
4798 return (ret);
4799
4800 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
4801 &records, &numrecords) == 0);
4802 for (i = 0; i < numrecords; i++) {
4803 nvlist_t *rec = records[i];
4804 char tbuf[30] = "";
4805
4806 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
4807 time_t tsec;
4808 struct tm t;
4809
4810 tsec = fnvlist_lookup_uint64(records[i],
4811 ZPOOL_HIST_TIME);
4812 (void) localtime_r(&tsec, &t);
4813 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
4814 }
4815
4816 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
4817 (void) printf("%s %s", tbuf,
4818 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
4819 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
4820 int ievent =
4821 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
4822 if (!cb->internal)
4823 continue;
4824 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
4825 (void) printf("%s unrecognized record:\n",
4826 tbuf);
4827 dump_nvlist(rec, 4);
4828 continue;
4829 }
4830 (void) printf("%s [internal %s txg:%lld] %s", tbuf,
4831 zfs_history_event_names[ievent],
4832 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
4833 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
4834 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
4835 if (!cb->internal)
4836 continue;
4837 (void) printf("%s [txg:%lld] %s", tbuf,
4838 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
4839 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
4840 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
4841 (void) printf(" %s (%llu)",
4842 fnvlist_lookup_string(rec,
4843 ZPOOL_HIST_DSNAME),
4844 fnvlist_lookup_uint64(rec,
4845 ZPOOL_HIST_DSID));
4846 }
4847 (void) printf(" %s", fnvlist_lookup_string(rec,
4848 ZPOOL_HIST_INT_STR));
4849 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
4850 if (!cb->internal)
4851 continue;
4852 (void) printf("%s ioctl %s\n", tbuf,
4853 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
4854 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
4855 (void) printf(" input:\n");
4856 dump_nvlist(fnvlist_lookup_nvlist(rec,
4857 ZPOOL_HIST_INPUT_NVL), 8);
4858 }
4859 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
4860 (void) printf(" output:\n");
4861 dump_nvlist(fnvlist_lookup_nvlist(rec,
4862 ZPOOL_HIST_OUTPUT_NVL), 8);
4863 }
4864 } else {
4865 if (!cb->internal)
4866 continue;
4867 (void) printf("%s unrecognized record:\n", tbuf);
4868 dump_nvlist(rec, 4);
4869 }
4870
4871 if (!cb->longfmt) {
4872 (void) printf("\n");
4873 continue;
4874 }
4875 (void) printf(" [");
4876 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
4877 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
4878 struct passwd *pwd = getpwuid(who);
4879 (void) printf("user %d ", (int)who);
4880 if (pwd != NULL)
4881 (void) printf("(%s) ", pwd->pw_name);
4882 }
4883 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
4884 (void) printf("on %s",
4885 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
4886 }
4887 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
4888 (void) printf(":%s",
4889 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
4890 }
4891 (void) printf("]");
4892 (void) printf("\n");
4893 }
4894 (void) printf("\n");
4895 nvlist_free(nvhis);
4896
4897 return (ret);
4898 }
4899
4900 /*
4901 * zpool history <pool>
4902 *
4903 * Displays the history of commands that modified pools.
4904 */
4905 int
4906 zpool_do_history(int argc, char **argv)
4907 {
4908 hist_cbdata_t cbdata = { 0 };
4909 int ret;
4910 int c;
4911
4912 cbdata.first = B_TRUE;
4913 /* check options */
4914 while ((c = getopt(argc, argv, "li")) != -1) {
4915 switch (c) {
4916 case 'l':
4917 cbdata.longfmt = B_TRUE;
4918 break;
4919 case 'i':
4920 cbdata.internal = B_TRUE;
4921 break;
4922 case '?':
4923 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4924 optopt);
4925 usage(B_FALSE);
4926 }
4927 }
4928 argc -= optind;
4929 argv += optind;
4930
4931 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
4932 &cbdata);
4933
4934 if (argc == 0 && cbdata.first == B_TRUE) {
4935 (void) printf(gettext("no pools available\n"));
4936 return (0);
4937 }
4938
4939 return (ret);
4940 }
4941
4942 static int
4943 get_callback(zpool_handle_t *zhp, void *data)
4944 {
4945 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
4946 char value[MAXNAMELEN];
4947 zprop_source_t srctype;
4948 zprop_list_t *pl;
4949
4950 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
4951
4952 /*
4953 * Skip the special fake placeholder. This will also skip
4954 * over the name property when 'all' is specified.
4955 */
4956 if (pl->pl_prop == ZPOOL_PROP_NAME &&
4957 pl == cbp->cb_proplist)
4958 continue;
4959
4960 if (pl->pl_prop == ZPROP_INVAL &&
4961 (zpool_prop_feature(pl->pl_user_prop) ||
4962 zpool_prop_unsupported(pl->pl_user_prop))) {
4963 srctype = ZPROP_SRC_LOCAL;
4964
4965 if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
4966 value, sizeof (value)) == 0) {
4967 zprop_print_one_property(zpool_get_name(zhp),
4968 cbp, pl->pl_user_prop, value, srctype,
4969 NULL, NULL);
4970 }
4971 } else {
4972 if (zpool_get_prop(zhp, pl->pl_prop, value,
4973 sizeof (value), &srctype) != 0)
4974 continue;
4975
4976 zprop_print_one_property(zpool_get_name(zhp), cbp,
4977 zpool_prop_to_name(pl->pl_prop), value, srctype,
4978 NULL, NULL);
4979 }
4980 }
4981 return (0);
4982 }
4983
4984 int
4985 zpool_do_get(int argc, char **argv)
4986 {
4987 zprop_get_cbdata_t cb = { 0 };
4988 zprop_list_t fake_name = { 0 };
4989 int ret;
4990
4991 if (argc < 2) {
4992 (void) fprintf(stderr, gettext("missing property "
4993 "argument\n"));
4994 usage(B_FALSE);
4995 }
4996
4997 cb.cb_first = B_TRUE;
4998 cb.cb_sources = ZPROP_SRC_ALL;
4999 cb.cb_columns[0] = GET_COL_NAME;
5000 cb.cb_columns[1] = GET_COL_PROPERTY;
5001 cb.cb_columns[2] = GET_COL_VALUE;
5002 cb.cb_columns[3] = GET_COL_SOURCE;
5003 cb.cb_type = ZFS_TYPE_POOL;
5004
5005 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
5006 ZFS_TYPE_POOL) != 0)
5007 usage(B_FALSE);
5008
5009 if (cb.cb_proplist != NULL) {
5010 fake_name.pl_prop = ZPOOL_PROP_NAME;
5011 fake_name.pl_width = strlen(gettext("NAME"));
5012 fake_name.pl_next = cb.cb_proplist;
5013 cb.cb_proplist = &fake_name;
5014 }
5015
5016 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
5017 get_callback, &cb);
5018
5019 if (cb.cb_proplist == &fake_name)
5020 zprop_free_list(fake_name.pl_next);
5021 else
5022 zprop_free_list(cb.cb_proplist);
5023
5024 return (ret);
5025 }
5026
5027 typedef struct set_cbdata {
5028 char *cb_propname;
5029 char *cb_value;
5030 boolean_t cb_any_successful;
5031 } set_cbdata_t;
5032
5033 int
5034 set_callback(zpool_handle_t *zhp, void *data)
5035 {
5036 int error;
5037 set_cbdata_t *cb = (set_cbdata_t *)data;
5038
5039 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
5040
5041 if (!error)
5042 cb->cb_any_successful = B_TRUE;
5043
5044 return (error);
5045 }
5046
5047 int
5048 zpool_do_set(int argc, char **argv)
5049 {
5050 set_cbdata_t cb = { 0 };
5051 int error;
5052
5053 if (argc > 1 && argv[1][0] == '-') {
5054 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5055 argv[1][1]);
5056 usage(B_FALSE);
5057 }
5058
5059 if (argc < 2) {
5060 (void) fprintf(stderr, gettext("missing property=value "
5061 "argument\n"));
5062 usage(B_FALSE);
5063 }
5064
5065 if (argc < 3) {
5066 (void) fprintf(stderr, gettext("missing pool name\n"));
5067 usage(B_FALSE);
5068 }
5069
5070 if (argc > 3) {
5071 (void) fprintf(stderr, gettext("too many pool names\n"));
5072 usage(B_FALSE);
5073 }
5074
5075 cb.cb_propname = argv[1];
5076 cb.cb_value = strchr(cb.cb_propname, '=');
5077 if (cb.cb_value == NULL) {
5078 (void) fprintf(stderr, gettext("missing value in "
5079 "property=value argument\n"));
5080 usage(B_FALSE);
5081 }
5082
5083 *(cb.cb_value) = '\0';
5084 cb.cb_value++;
5085
5086 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
5087 set_callback, &cb);
5088
5089 return (error);
5090 }
5091
5092 static int
5093 find_command_idx(char *command, int *idx)
5094 {
5095 int i;
5096
5097 for (i = 0; i < NCOMMAND; i++) {
5098 if (command_table[i].name == NULL)
5099 continue;
5100
5101 if (strcmp(command, command_table[i].name) == 0) {
5102 *idx = i;
5103 return (0);
5104 }
5105 }
5106 return (1);
5107 }
5108
5109 int
5110 main(int argc, char **argv)
5111 {
5112 int ret;
5113 int i;
5114 char *cmdname;
5115
5116 (void) setlocale(LC_ALL, "");
5117 (void) textdomain(TEXT_DOMAIN);
5118
5119 if ((g_zfs = libzfs_init()) == NULL) {
5120 (void) fprintf(stderr, gettext("internal error: failed to "
5121 "initialize ZFS library\n"));
5122 return (1);
5123 }
5124
5125 libzfs_print_on_error(g_zfs, B_TRUE);
5126
5127 opterr = 0;
5128
5129 /*
5130 * Make sure the user has specified some command.
5131 */
5132 if (argc < 2) {
5133 (void) fprintf(stderr, gettext("missing command\n"));
5134 usage(B_FALSE);
5135 }
5136
5137 cmdname = argv[1];
5138
5139 /*
5140 * Special case '-?'
5141 */
5142 if (strcmp(cmdname, "-?") == 0)
5143 usage(B_TRUE);
5144
5145 zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
5146
5147 /*
5148 * Run the appropriate command.
5149 */
5150 if (find_command_idx(cmdname, &i) == 0) {
5151 current_command = &command_table[i];
5152 ret = command_table[i].func(argc - 1, argv + 1);
5153 } else if (strchr(cmdname, '=')) {
5154 verify(find_command_idx("set", &i) == 0);
5155 current_command = &command_table[i];
5156 ret = command_table[i].func(argc, argv);
5157 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
5158 /*
5159 * 'freeze' is a vile debugging abomination, so we treat
5160 * it as such.
5161 */
5162 char buf[16384];
5163 int fd = open(ZFS_DEV, O_RDWR);
5164 (void) strcpy((void *)buf, argv[2]);
5165 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
5166 } else {
5167 (void) fprintf(stderr, gettext("unrecognized "
5168 "command '%s'\n"), cmdname);
5169 usage(B_FALSE);
5170 }
5171
5172 if (ret == 0 && log_history)
5173 (void) zpool_log_history(g_zfs, history_str);
5174
5175 libzfs_fini(g_zfs);
5176
5177 /*
5178 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
5179 * for the purposes of running ::findleaks.
5180 */
5181 if (getenv("ZFS_ABORT") != NULL) {
5182 (void) printf("dumping core by request\n");
5183 abort();
5184 }
5185
5186 return (ret);
5187 }