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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <assert.h>
28 #include <ctype.h>
29 #include <dirent.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <libgen.h>
33 #include <libintl.h>
34 #include <libuutil.h>
35 #include <locale.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <unistd.h>
41 #include <priv.h>
42 #include <pwd.h>
43 #include <zone.h>
44 #include <sys/fs/zfs.h>
45
46 #include <sys/stat.h>
47
48 #include <libzfs.h>
49
50 #include "zpool_util.h"
51 #include "zfs_comutil.h"
52
53 static int zpool_do_create(int, char **);
54 static int zpool_do_destroy(int, char **);
55
56 static int zpool_do_add(int, char **);
57 static int zpool_do_remove(int, char **);
58
59 static int zpool_do_list(int, char **);
60 static int zpool_do_iostat(int, char **);
61 static int zpool_do_status(int, char **);
62
63 static int zpool_do_online(int, char **);
64 static int zpool_do_offline(int, char **);
65 static int zpool_do_clear(int, char **);
66
67 static int zpool_do_attach(int, char **);
68 static int zpool_do_detach(int, char **);
69 static int zpool_do_replace(int, char **);
70
71 static int zpool_do_scrub(int, char **);
72
73 static int zpool_do_import(int, char **);
74 static int zpool_do_export(int, char **);
75
76 static int zpool_do_upgrade(int, char **);
77
78 static int zpool_do_history(int, char **);
79
80 static int zpool_do_get(int, char **);
81 static int zpool_do_set(int, char **);
82
83 /*
84 * These libumem hooks provide a reasonable set of defaults for the allocator's
85 * debugging facilities.
86 */
87
88 #ifdef DEBUG
89 const char *
90 _umem_debug_init(void)
91 {
92 return ("default,verbose"); /* $UMEM_DEBUG setting */
93 }
94
95 const char *
96 _umem_logging_init(void)
97 {
98 return ("fail,contents"); /* $UMEM_LOGGING setting */
99 }
100 #endif
101
102 typedef enum {
103 HELP_ADD,
104 HELP_ATTACH,
105 HELP_CLEAR,
106 HELP_CREATE,
107 HELP_DESTROY,
108 HELP_DETACH,
109 HELP_EXPORT,
110 HELP_HISTORY,
111 HELP_IMPORT,
112 HELP_IOSTAT,
113 HELP_LIST,
114 HELP_OFFLINE,
115 HELP_ONLINE,
116 HELP_REPLACE,
117 HELP_REMOVE,
118 HELP_SCRUB,
119 HELP_STATUS,
120 HELP_UPGRADE,
121 HELP_GET,
122 HELP_SET
123 } zpool_help_t;
124
125
126 typedef struct zpool_command {
127 const char *name;
128 int (*func)(int, char **);
129 zpool_help_t usage;
130 } zpool_command_t;
131
132 /*
133 * Master command table. Each ZFS command has a name, associated function, and
134 * usage message. The usage messages need to be internationalized, so we have
135 * to have a function to return the usage message based on a command index.
136 *
137 * These commands are organized according to how they are displayed in the usage
138 * message. An empty command (one with a NULL name) indicates an empty line in
139 * the generic usage message.
140 */
141 static zpool_command_t command_table[] = {
142 { "create", zpool_do_create, HELP_CREATE },
143 { "destroy", zpool_do_destroy, HELP_DESTROY },
144 { NULL },
145 { "add", zpool_do_add, HELP_ADD },
146 { "remove", zpool_do_remove, HELP_REMOVE },
147 { NULL },
148 { "list", zpool_do_list, HELP_LIST },
149 { "iostat", zpool_do_iostat, HELP_IOSTAT },
150 { "status", zpool_do_status, HELP_STATUS },
151 { NULL },
152 { "online", zpool_do_online, HELP_ONLINE },
153 { "offline", zpool_do_offline, HELP_OFFLINE },
154 { "clear", zpool_do_clear, HELP_CLEAR },
155 { NULL },
156 { "attach", zpool_do_attach, HELP_ATTACH },
157 { "detach", zpool_do_detach, HELP_DETACH },
158 { "replace", zpool_do_replace, HELP_REPLACE },
159 { NULL },
160 { "scrub", zpool_do_scrub, HELP_SCRUB },
161 { NULL },
162 { "import", zpool_do_import, HELP_IMPORT },
163 { "export", zpool_do_export, HELP_EXPORT },
164 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
165 { NULL },
166 { "history", zpool_do_history, HELP_HISTORY },
167 { "get", zpool_do_get, HELP_GET },
168 { "set", zpool_do_set, HELP_SET },
169 };
170
171 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
172
173 zpool_command_t *current_command;
174 static char history_str[HIS_MAX_RECORD_LEN];
175
176 static const char *
177 get_usage(zpool_help_t idx) {
178 switch (idx) {
179 case HELP_ADD:
180 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
181 case HELP_ATTACH:
182 return (gettext("\tattach [-f] <pool> <device> "
183 "<new-device>\n"));
184 case HELP_CLEAR:
185 return (gettext("\tclear <pool> [device]\n"));
186 case HELP_CREATE:
187 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
188 "\t [-O file-system-property=value] ... \n"
189 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
190 case HELP_DESTROY:
191 return (gettext("\tdestroy [-f] <pool>\n"));
192 case HELP_DETACH:
193 return (gettext("\tdetach <pool> <device>\n"));
194 case HELP_EXPORT:
195 return (gettext("\texport [-f] <pool> ...\n"));
196 case HELP_HISTORY:
197 return (gettext("\thistory [-il] [<pool>] ...\n"));
198 case HELP_IMPORT:
199 return (gettext("\timport [-d dir] [-D]\n"
200 "\timport [-o mntopts] [-o property=value] ... \n"
201 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
202 "\timport [-o mntopts] [-o property=value] ... \n"
203 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
204 "<pool | id> [newpool]\n"));
205 case HELP_IOSTAT:
206 return (gettext("\tiostat [-v] [pool] ... [interval "
207 "[count]]\n"));
208 case HELP_LIST:
209 return (gettext("\tlist [-H] [-o property[,...]] "
210 "[pool] ...\n"));
211 case HELP_OFFLINE:
212 return (gettext("\toffline [-t] <pool> <device> ...\n"));
213 case HELP_ONLINE:
214 return (gettext("\tonline <pool> <device> ...\n"));
215 case HELP_REPLACE:
216 return (gettext("\treplace [-f] <pool> <device> "
217 "[new-device]\n"));
218 case HELP_REMOVE:
219 return (gettext("\tremove <pool> <device> ...\n"));
220 case HELP_SCRUB:
221 return (gettext("\tscrub [-s] <pool> ...\n"));
222 case HELP_STATUS:
223 return (gettext("\tstatus [-vx] [pool] ...\n"));
224 case HELP_UPGRADE:
225 return (gettext("\tupgrade\n"
226 "\tupgrade -v\n"
227 "\tupgrade [-V version] <-a | pool ...>\n"));
228 case HELP_GET:
229 return (gettext("\tget <\"all\" | property[,...]> "
230 "<pool> ...\n"));
231 case HELP_SET:
232 return (gettext("\tset <property=value> <pool> \n"));
233 }
234
235 abort();
236 /* NOTREACHED */
237 }
238
239
240 /*
241 * Callback routine that will print out a pool property value.
242 */
243 static int
244 print_prop_cb(int prop, void *cb)
245 {
246 FILE *fp = cb;
247
248 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
249
250 if (zpool_prop_readonly(prop))
251 (void) fprintf(fp, " NO ");
252 else
253 (void) fprintf(fp, " YES ");
254
255 if (zpool_prop_values(prop) == NULL)
256 (void) fprintf(fp, "-\n");
257 else
258 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
259
260 return (ZPROP_CONT);
261 }
262
263 /*
264 * Display usage message. If we're inside a command, display only the usage for
265 * that command. Otherwise, iterate over the entire command table and display
266 * a complete usage message.
267 */
268 void
269 usage(boolean_t requested)
270 {
271 FILE *fp = requested ? stdout : stderr;
272
273 if (current_command == NULL) {
274 int i;
275
276 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
277 (void) fprintf(fp,
278 gettext("where 'command' is one of the following:\n\n"));
279
280 for (i = 0; i < NCOMMAND; i++) {
281 if (command_table[i].name == NULL)
282 (void) fprintf(fp, "\n");
283 else
284 (void) fprintf(fp, "%s",
285 get_usage(command_table[i].usage));
286 }
287 } else {
288 (void) fprintf(fp, gettext("usage:\n"));
289 (void) fprintf(fp, "%s", get_usage(current_command->usage));
290 }
291
292 if (current_command != NULL &&
293 ((strcmp(current_command->name, "set") == 0) ||
294 (strcmp(current_command->name, "get") == 0) ||
295 (strcmp(current_command->name, "list") == 0))) {
296
297 (void) fprintf(fp,
298 gettext("\nthe following properties are supported:\n"));
299
300 (void) fprintf(fp, "\n\t%-13s %s %s\n\n",
301 "PROPERTY", "EDIT", "VALUES");
302
303 /* Iterate over all properties */
304 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
305 ZFS_TYPE_POOL);
306 }
307
308 /*
309 * See comments at end of main().
310 */
311 if (getenv("ZFS_ABORT") != NULL) {
312 (void) printf("dumping core by request\n");
313 abort();
314 }
315
316 exit(requested ? 0 : 2);
317 }
318
319 void
320 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
321 boolean_t print_logs)
322 {
323 nvlist_t **child;
324 uint_t c, children;
325 char *vname;
326
327 if (name != NULL)
328 (void) printf("\t%*s%s\n", indent, "", name);
329
330 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
331 &child, &children) != 0)
332 return;
333
334 for (c = 0; c < children; c++) {
335 uint64_t is_log = B_FALSE;
336
337 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
338 &is_log);
339 if ((is_log && !print_logs) || (!is_log && print_logs))
340 continue;
341
342 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
343 print_vdev_tree(zhp, vname, child[c], indent + 2,
344 B_FALSE);
345 free(vname);
346 }
347 }
348
349 /*
350 * Add a property pair (name, string-value) into a property nvlist.
351 */
352 static int
353 add_prop_list(const char *propname, char *propval, nvlist_t **props,
354 boolean_t poolprop)
355 {
356 zpool_prop_t prop = ZPROP_INVAL;
357 zfs_prop_t fprop;
358 nvlist_t *proplist;
359 const char *normnm;
360 char *strval;
361
362 if (*props == NULL &&
363 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
364 (void) fprintf(stderr,
365 gettext("internal error: out of memory\n"));
366 return (1);
367 }
368
369 proplist = *props;
370
371 if (poolprop) {
372 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
373 (void) fprintf(stderr, gettext("property '%s' is "
374 "not a valid pool property\n"), propname);
375 return (2);
376 }
377 normnm = zpool_prop_to_name(prop);
378 } else {
379 if ((fprop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
380 (void) fprintf(stderr, gettext("property '%s' is "
381 "not a valid file system property\n"), propname);
382 return (2);
383 }
384 normnm = zfs_prop_to_name(fprop);
385 }
386
387 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
388 prop != ZPOOL_PROP_CACHEFILE) {
389 (void) fprintf(stderr, gettext("property '%s' "
390 "specified multiple times\n"), propname);
391 return (2);
392 }
393
394 if (nvlist_add_string(proplist, normnm, propval) != 0) {
395 (void) fprintf(stderr, gettext("internal "
396 "error: out of memory\n"));
397 return (1);
398 }
399
400 return (0);
401 }
402
403 /*
404 * zpool add [-fn] <pool> <vdev> ...
405 *
406 * -f Force addition of devices, even if they appear in use
407 * -n Do not add the devices, but display the resulting layout if
408 * they were to be added.
409 *
410 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
411 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
412 * libzfs.
413 */
414 int
415 zpool_do_add(int argc, char **argv)
416 {
417 boolean_t force = B_FALSE;
418 boolean_t dryrun = B_FALSE;
419 int c;
420 nvlist_t *nvroot;
421 char *poolname;
422 int ret;
423 zpool_handle_t *zhp;
424 nvlist_t *config;
425
426 /* check options */
427 while ((c = getopt(argc, argv, "fn")) != -1) {
428 switch (c) {
429 case 'f':
430 force = B_TRUE;
431 break;
432 case 'n':
433 dryrun = B_TRUE;
434 break;
435 case '?':
436 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
437 optopt);
438 usage(B_FALSE);
439 }
440 }
441
442 argc -= optind;
443 argv += optind;
444
445 /* get pool name and check number of arguments */
446 if (argc < 1) {
447 (void) fprintf(stderr, gettext("missing pool name argument\n"));
448 usage(B_FALSE);
449 }
450 if (argc < 2) {
451 (void) fprintf(stderr, gettext("missing vdev specification\n"));
452 usage(B_FALSE);
453 }
454
455 poolname = argv[0];
456
457 argc--;
458 argv++;
459
460 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
461 return (1);
462
463 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
464 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
465 poolname);
466 zpool_close(zhp);
467 return (1);
468 }
469
470 /* pass off to get_vdev_spec for processing */
471 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
472 argc, argv);
473 if (nvroot == NULL) {
474 zpool_close(zhp);
475 return (1);
476 }
477
478 if (dryrun) {
479 nvlist_t *poolnvroot;
480
481 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
482 &poolnvroot) == 0);
483
484 (void) printf(gettext("would update '%s' to the following "
485 "configuration:\n"), zpool_get_name(zhp));
486
487 /* print original main pool and new tree */
488 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
489 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
490
491 /* Do the same for the logs */
492 if (num_logs(poolnvroot) > 0) {
493 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
494 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
495 } else if (num_logs(nvroot) > 0) {
496 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
497 }
498
499 ret = 0;
500 } else {
501 ret = (zpool_add(zhp, nvroot) != 0);
502 }
503
504 nvlist_free(nvroot);
505 zpool_close(zhp);
506
507 return (ret);
508 }
509
510 /*
511 * zpool remove <pool> <vdev> ...
512 *
513 * Removes the given vdev from the pool. Currently, this only supports removing
514 * spares and cache devices from the pool. Eventually, we'll want to support
515 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
516 */
517 int
518 zpool_do_remove(int argc, char **argv)
519 {
520 char *poolname;
521 int i, ret = 0;
522 zpool_handle_t *zhp;
523
524 argc--;
525 argv++;
526
527 /* get pool name and check number of arguments */
528 if (argc < 1) {
529 (void) fprintf(stderr, gettext("missing pool name argument\n"));
530 usage(B_FALSE);
531 }
532 if (argc < 2) {
533 (void) fprintf(stderr, gettext("missing device\n"));
534 usage(B_FALSE);
535 }
536
537 poolname = argv[0];
538
539 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
540 return (1);
541
542 for (i = 1; i < argc; i++) {
543 if (zpool_vdev_remove(zhp, argv[i]) != 0)
544 ret = 1;
545 }
546
547 return (ret);
548 }
549
550 /*
551 * zpool create [-fn] [-o property=value] ...
552 * [-O file-system-property=value] ...
553 * [-R root] [-m mountpoint] <pool> <dev> ...
554 *
555 * -f Force creation, even if devices appear in use
556 * -n Do not create the pool, but display the resulting layout if it
557 * were to be created.
558 * -R Create a pool under an alternate root
559 * -m Set default mountpoint for the root dataset. By default it's
560 * '/<pool>'
561 * -o Set property=value.
562 * -O Set fsproperty=value in the pool's root file system
563 *
564 * Creates the named pool according to the given vdev specification. The
565 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
566 * we get the nvlist back from get_vdev_spec(), we either print out the contents
567 * (if '-n' was specified), or pass it to libzfs to do the creation.
568 */
569 int
570 zpool_do_create(int argc, char **argv)
571 {
572 boolean_t force = B_FALSE;
573 boolean_t dryrun = B_FALSE;
574 int c;
575 nvlist_t *nvroot = NULL;
576 char *poolname;
577 int ret = 1;
578 char *altroot = NULL;
579 char *mountpoint = NULL;
580 nvlist_t *fsprops = NULL;
581 nvlist_t *props = NULL;
582 char *propval;
583
584 /* check options */
585 while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
586 switch (c) {
587 case 'f':
588 force = B_TRUE;
589 break;
590 case 'n':
591 dryrun = B_TRUE;
592 break;
593 case 'R':
594 altroot = optarg;
595 if (add_prop_list(zpool_prop_to_name(
596 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
597 goto errout;
598 if (nvlist_lookup_string(props,
599 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
600 &propval) == 0)
601 break;
602 if (add_prop_list(zpool_prop_to_name(
603 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
604 goto errout;
605 break;
606 case 'm':
607 mountpoint = optarg;
608 break;
609 case 'o':
610 if ((propval = strchr(optarg, '=')) == NULL) {
611 (void) fprintf(stderr, gettext("missing "
612 "'=' for -o option\n"));
613 goto errout;
614 }
615 *propval = '\0';
616 propval++;
617
618 if (add_prop_list(optarg, propval, &props, B_TRUE))
619 goto errout;
620 break;
621 case 'O':
622 if ((propval = strchr(optarg, '=')) == NULL) {
623 (void) fprintf(stderr, gettext("missing "
624 "'=' for -O option\n"));
625 goto errout;
626 }
627 *propval = '\0';
628 propval++;
629
630 if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
631 goto errout;
632 break;
633 case ':':
634 (void) fprintf(stderr, gettext("missing argument for "
635 "'%c' option\n"), optopt);
636 goto badusage;
637 case '?':
638 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
639 optopt);
640 goto badusage;
641 }
642 }
643
644 argc -= optind;
645 argv += optind;
646
647 /* get pool name and check number of arguments */
648 if (argc < 1) {
649 (void) fprintf(stderr, gettext("missing pool name argument\n"));
650 goto badusage;
651 }
652 if (argc < 2) {
653 (void) fprintf(stderr, gettext("missing vdev specification\n"));
654 goto badusage;
655 }
656
657 poolname = argv[0];
658
659 /*
660 * As a special case, check for use of '/' in the name, and direct the
661 * user to use 'zfs create' instead.
662 */
663 if (strchr(poolname, '/') != NULL) {
664 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
665 "character '/' in pool name\n"), poolname);
666 (void) fprintf(stderr, gettext("use 'zfs create' to "
667 "create a dataset\n"));
668 goto errout;
669 }
670
671 /* pass off to get_vdev_spec for bulk processing */
672 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
673 argc - 1, argv + 1);
674 if (nvroot == NULL)
675 goto errout;
676
677 /* make_root_vdev() allows 0 toplevel children if there are spares */
678 if (!zfs_allocatable_devs(nvroot)) {
679 (void) fprintf(stderr, gettext("invalid vdev "
680 "specification: at least one toplevel vdev must be "
681 "specified\n"));
682 goto errout;
683 }
684
685
686 if (altroot != NULL && altroot[0] != '/') {
687 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
688 "must be an absolute path\n"), altroot);
689 goto errout;
690 }
691
692 /*
693 * Check the validity of the mountpoint and direct the user to use the
694 * '-m' mountpoint option if it looks like its in use.
695 */
696 if (mountpoint == NULL ||
697 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
698 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
699 char buf[MAXPATHLEN];
700 DIR *dirp;
701
702 if (mountpoint && mountpoint[0] != '/') {
703 (void) fprintf(stderr, gettext("invalid mountpoint "
704 "'%s': must be an absolute path, 'legacy', or "
705 "'none'\n"), mountpoint);
706 goto errout;
707 }
708
709 if (mountpoint == NULL) {
710 if (altroot != NULL)
711 (void) snprintf(buf, sizeof (buf), "%s/%s",
712 altroot, poolname);
713 else
714 (void) snprintf(buf, sizeof (buf), "/%s",
715 poolname);
716 } else {
717 if (altroot != NULL)
718 (void) snprintf(buf, sizeof (buf), "%s%s",
719 altroot, mountpoint);
720 else
721 (void) snprintf(buf, sizeof (buf), "%s",
722 mountpoint);
723 }
724
725 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
726 (void) fprintf(stderr, gettext("mountpoint '%s' : "
727 "%s\n"), buf, strerror(errno));
728 (void) fprintf(stderr, gettext("use '-m' "
729 "option to provide a different default\n"));
730 goto errout;
731 } else if (dirp) {
732 int count = 0;
733
734 while (count < 3 && readdir(dirp) != NULL)
735 count++;
736 (void) closedir(dirp);
737
738 if (count > 2) {
739 (void) fprintf(stderr, gettext("mountpoint "
740 "'%s' exists and is not empty\n"), buf);
741 (void) fprintf(stderr, gettext("use '-m' "
742 "option to provide a "
743 "different default\n"));
744 goto errout;
745 }
746 }
747 }
748
749 if (dryrun) {
750 /*
751 * For a dry run invocation, print out a basic message and run
752 * through all the vdevs in the list and print out in an
753 * appropriate hierarchy.
754 */
755 (void) printf(gettext("would create '%s' with the "
756 "following layout:\n\n"), poolname);
757
758 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
759 if (num_logs(nvroot) > 0)
760 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
761
762 ret = 0;
763 } else {
764 /*
765 * Hand off to libzfs.
766 */
767 if (zpool_create(g_zfs, poolname,
768 nvroot, props, fsprops) == 0) {
769 zfs_handle_t *pool = zfs_open(g_zfs, poolname,
770 ZFS_TYPE_FILESYSTEM);
771 if (pool != NULL) {
772 if (mountpoint != NULL)
773 verify(zfs_prop_set(pool,
774 zfs_prop_to_name(
775 ZFS_PROP_MOUNTPOINT),
776 mountpoint) == 0);
777 if (zfs_mount(pool, NULL, 0) == 0)
778 ret = zfs_shareall(pool);
779 zfs_close(pool);
780 }
781 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
782 (void) fprintf(stderr, gettext("pool name may have "
783 "been omitted\n"));
784 }
785 }
786
787 errout:
788 nvlist_free(nvroot);
789 nvlist_free(fsprops);
790 nvlist_free(props);
791 return (ret);
792 badusage:
793 nvlist_free(fsprops);
794 nvlist_free(props);
795 usage(B_FALSE);
796 return (2);
797 }
798
799 /*
800 * zpool destroy <pool>
801 *
802 * -f Forcefully unmount any datasets
803 *
804 * Destroy the given pool. Automatically unmounts any datasets in the pool.
805 */
806 int
807 zpool_do_destroy(int argc, char **argv)
808 {
809 boolean_t force = B_FALSE;
810 int c;
811 char *pool;
812 zpool_handle_t *zhp;
813 int ret;
814
815 /* check options */
816 while ((c = getopt(argc, argv, "f")) != -1) {
817 switch (c) {
818 case 'f':
819 force = B_TRUE;
820 break;
821 case '?':
822 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
823 optopt);
824 usage(B_FALSE);
825 }
826 }
827
828 argc -= optind;
829 argv += optind;
830
831 /* check arguments */
832 if (argc < 1) {
833 (void) fprintf(stderr, gettext("missing pool argument\n"));
834 usage(B_FALSE);
835 }
836 if (argc > 1) {
837 (void) fprintf(stderr, gettext("too many arguments\n"));
838 usage(B_FALSE);
839 }
840
841 pool = argv[0];
842
843 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
844 /*
845 * As a special case, check for use of '/' in the name, and
846 * direct the user to use 'zfs destroy' instead.
847 */
848 if (strchr(pool, '/') != NULL)
849 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
850 "destroy a dataset\n"));
851 return (1);
852 }
853
854 if (zpool_disable_datasets(zhp, force) != 0) {
855 (void) fprintf(stderr, gettext("could not destroy '%s': "
856 "could not unmount datasets\n"), zpool_get_name(zhp));
857 return (1);
858 }
859
860 ret = (zpool_destroy(zhp) != 0);
861
862 zpool_close(zhp);
863
864 return (ret);
865 }
866
867 /*
868 * zpool export [-f] <pool> ...
869 *
870 * -f Forcefully unmount datasets
871 *
872 * Export the given pools. By default, the command will attempt to cleanly
873 * unmount any active datasets within the pool. If the '-f' flag is specified,
874 * then the datasets will be forcefully unmounted.
875 */
876 int
877 zpool_do_export(int argc, char **argv)
878 {
879 boolean_t force = B_FALSE;
880 boolean_t hardforce = B_FALSE;
881 int c;
882 zpool_handle_t *zhp;
883 int ret;
884 int i;
885
886 /* check options */
887 while ((c = getopt(argc, argv, "fF")) != -1) {
888 switch (c) {
889 case 'f':
890 force = B_TRUE;
891 break;
892 case 'F':
893 hardforce = B_TRUE;
894 break;
895 case '?':
896 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
897 optopt);
898 usage(B_FALSE);
899 }
900 }
901
902 argc -= optind;
903 argv += optind;
904
905 /* check arguments */
906 if (argc < 1) {
907 (void) fprintf(stderr, gettext("missing pool argument\n"));
908 usage(B_FALSE);
909 }
910
911 ret = 0;
912 for (i = 0; i < argc; i++) {
913 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
914 ret = 1;
915 continue;
916 }
917
918 if (zpool_disable_datasets(zhp, force) != 0) {
919 ret = 1;
920 zpool_close(zhp);
921 continue;
922 }
923
924 if (hardforce) {
925 if (zpool_export_force(zhp) != 0)
926 ret = 1;
927 } else if (zpool_export(zhp, force) != 0) {
928 ret = 1;
929 }
930
931 zpool_close(zhp);
932 }
933
934 return (ret);
935 }
936
937 /*
938 * Given a vdev configuration, determine the maximum width needed for the device
939 * name column.
940 */
941 static int
942 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
943 {
944 char *name = zpool_vdev_name(g_zfs, zhp, nv);
945 nvlist_t **child;
946 uint_t c, children;
947 int ret;
948
949 if (strlen(name) + depth > max)
950 max = strlen(name) + depth;
951
952 free(name);
953
954 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
955 &child, &children) == 0) {
956 for (c = 0; c < children; c++)
957 if ((ret = max_width(zhp, child[c], depth + 2,
958 max)) > max)
959 max = ret;
960 }
961
962 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
963 &child, &children) == 0) {
964 for (c = 0; c < children; c++)
965 if ((ret = max_width(zhp, child[c], depth + 2,
966 max)) > max)
967 max = ret;
968 }
969
970 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
971 &child, &children) == 0) {
972 for (c = 0; c < children; c++)
973 if ((ret = max_width(zhp, child[c], depth + 2,
974 max)) > max)
975 max = ret;
976 }
977
978
979 return (max);
980 }
981
982
983 /*
984 * Print the configuration of an exported pool. Iterate over all vdevs in the
985 * pool, printing out the name and status for each one.
986 */
987 void
988 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
989 boolean_t print_logs)
990 {
991 nvlist_t **child;
992 uint_t c, children;
993 vdev_stat_t *vs;
994 char *type, *vname;
995
996 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
997 if (strcmp(type, VDEV_TYPE_MISSING) == 0)
998 return;
999
1000 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1001 (uint64_t **)&vs, &c) == 0);
1002
1003 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1004 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1005
1006 if (vs->vs_aux != 0) {
1007 (void) printf(" ");
1008
1009 switch (vs->vs_aux) {
1010 case VDEV_AUX_OPEN_FAILED:
1011 (void) printf(gettext("cannot open"));
1012 break;
1013
1014 case VDEV_AUX_BAD_GUID_SUM:
1015 (void) printf(gettext("missing device"));
1016 break;
1017
1018 case VDEV_AUX_NO_REPLICAS:
1019 (void) printf(gettext("insufficient replicas"));
1020 break;
1021
1022 case VDEV_AUX_VERSION_NEWER:
1023 (void) printf(gettext("newer version"));
1024 break;
1025
1026 case VDEV_AUX_ERR_EXCEEDED:
1027 (void) printf(gettext("too many errors"));
1028 break;
1029
1030 default:
1031 (void) printf(gettext("corrupted data"));
1032 break;
1033 }
1034 }
1035 (void) printf("\n");
1036
1037 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1038 &child, &children) != 0)
1039 return;
1040
1041 for (c = 0; c < children; c++) {
1042 uint64_t is_log = B_FALSE;
1043
1044 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1045 &is_log);
1046 if ((is_log && !print_logs) || (!is_log && print_logs))
1047 continue;
1048
1049 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1050 print_import_config(vname, child[c],
1051 namewidth, depth + 2, B_FALSE);
1052 free(vname);
1053 }
1054
1055 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1056 &child, &children) == 0) {
1057 (void) printf(gettext("\tcache\n"));
1058 for (c = 0; c < children; c++) {
1059 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1060 (void) printf("\t %s\n", vname);
1061 free(vname);
1062 }
1063 }
1064
1065 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1066 &child, &children) == 0) {
1067 (void) printf(gettext("\tspares\n"));
1068 for (c = 0; c < children; c++) {
1069 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1070 (void) printf("\t %s\n", vname);
1071 free(vname);
1072 }
1073 }
1074 }
1075
1076 /*
1077 * Display the status for the given pool.
1078 */
1079 static void
1080 show_import(nvlist_t *config)
1081 {
1082 uint64_t pool_state;
1083 vdev_stat_t *vs;
1084 char *name;
1085 uint64_t guid;
1086 char *msgid;
1087 nvlist_t *nvroot;
1088 int reason;
1089 const char *health;
1090 uint_t vsc;
1091 int namewidth;
1092
1093 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1094 &name) == 0);
1095 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1096 &guid) == 0);
1097 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1098 &pool_state) == 0);
1099 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1100 &nvroot) == 0);
1101
1102 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1103 (uint64_t **)&vs, &vsc) == 0);
1104 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1105
1106 reason = zpool_import_status(config, &msgid);
1107
1108 (void) printf(gettext(" pool: %s\n"), name);
1109 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
1110 (void) printf(gettext(" state: %s"), health);
1111 if (pool_state == POOL_STATE_DESTROYED)
1112 (void) printf(gettext(" (DESTROYED)"));
1113 (void) printf("\n");
1114
1115 switch (reason) {
1116 case ZPOOL_STATUS_MISSING_DEV_R:
1117 case ZPOOL_STATUS_MISSING_DEV_NR:
1118 case ZPOOL_STATUS_BAD_GUID_SUM:
1119 (void) printf(gettext("status: One or more devices are missing "
1120 "from the system.\n"));
1121 break;
1122
1123 case ZPOOL_STATUS_CORRUPT_LABEL_R:
1124 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1125 (void) printf(gettext("status: One or more devices contains "
1126 "corrupted data.\n"));
1127 break;
1128
1129 case ZPOOL_STATUS_CORRUPT_DATA:
1130 (void) printf(gettext("status: The pool data is corrupted.\n"));
1131 break;
1132
1133 case ZPOOL_STATUS_OFFLINE_DEV:
1134 (void) printf(gettext("status: One or more devices "
1135 "are offlined.\n"));
1136 break;
1137
1138 case ZPOOL_STATUS_CORRUPT_POOL:
1139 (void) printf(gettext("status: The pool metadata is "
1140 "corrupted.\n"));
1141 break;
1142
1143 case ZPOOL_STATUS_VERSION_OLDER:
1144 (void) printf(gettext("status: The pool is formatted using an "
1145 "older on-disk version.\n"));
1146 break;
1147
1148 case ZPOOL_STATUS_VERSION_NEWER:
1149 (void) printf(gettext("status: The pool is formatted using an "
1150 "incompatible version.\n"));
1151 break;
1152
1153 case ZPOOL_STATUS_HOSTID_MISMATCH:
1154 (void) printf(gettext("status: The pool was last accessed by "
1155 "another system.\n"));
1156 break;
1157
1158 case ZPOOL_STATUS_FAULTED_DEV_R:
1159 case ZPOOL_STATUS_FAULTED_DEV_NR:
1160 (void) printf(gettext("status: One or more devices are "
1161 "faulted.\n"));
1162 break;
1163
1164 case ZPOOL_STATUS_BAD_LOG:
1165 (void) printf(gettext("status: An intent log record cannot be "
1166 "read.\n"));
1167 break;
1168
1169 default:
1170 /*
1171 * No other status can be seen when importing pools.
1172 */
1173 assert(reason == ZPOOL_STATUS_OK);
1174 }
1175
1176 /*
1177 * Print out an action according to the overall state of the pool.
1178 */
1179 if (vs->vs_state == VDEV_STATE_HEALTHY) {
1180 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1181 (void) printf(gettext("action: The pool can be "
1182 "imported using its name or numeric identifier, "
1183 "though\n\tsome features will not be available "
1184 "without an explicit 'zpool upgrade'.\n"));
1185 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1186 (void) printf(gettext("action: The pool can be "
1187 "imported using its name or numeric "
1188 "identifier and\n\tthe '-f' flag.\n"));
1189 else
1190 (void) printf(gettext("action: The pool can be "
1191 "imported using its name or numeric "
1192 "identifier.\n"));
1193 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1194 (void) printf(gettext("action: The pool can be imported "
1195 "despite missing or damaged devices. The\n\tfault "
1196 "tolerance of the pool may be compromised if imported.\n"));
1197 } else {
1198 switch (reason) {
1199 case ZPOOL_STATUS_VERSION_NEWER:
1200 (void) printf(gettext("action: The pool cannot be "
1201 "imported. Access the pool on a system running "
1202 "newer\n\tsoftware, or recreate the pool from "
1203 "backup.\n"));
1204 break;
1205 case ZPOOL_STATUS_MISSING_DEV_R:
1206 case ZPOOL_STATUS_MISSING_DEV_NR:
1207 case ZPOOL_STATUS_BAD_GUID_SUM:
1208 (void) printf(gettext("action: The pool cannot be "
1209 "imported. Attach the missing\n\tdevices and try "
1210 "again.\n"));
1211 break;
1212 default:
1213 (void) printf(gettext("action: The pool cannot be "
1214 "imported due to damaged devices or data.\n"));
1215 }
1216 }
1217
1218 /*
1219 * If the state is "closed" or "can't open", and the aux state
1220 * is "corrupt data":
1221 */
1222 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1223 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1224 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1225 if (pool_state == POOL_STATE_DESTROYED)
1226 (void) printf(gettext("\tThe pool was destroyed, "
1227 "but can be imported using the '-Df' flags.\n"));
1228 else if (pool_state != POOL_STATE_EXPORTED)
1229 (void) printf(gettext("\tThe pool may be active on "
1230 "another system, but can be imported using\n\t"
1231 "the '-f' flag.\n"));
1232 }
1233
1234 if (msgid != NULL)
1235 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
1236 msgid);
1237
1238 (void) printf(gettext("config:\n\n"));
1239
1240 namewidth = max_width(NULL, nvroot, 0, 0);
1241 if (namewidth < 10)
1242 namewidth = 10;
1243
1244 print_import_config(name, nvroot, namewidth, 0, B_FALSE);
1245 if (num_logs(nvroot) > 0) {
1246 (void) printf(gettext("\tlogs\n"));
1247 print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1248 }
1249
1250 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1251 (void) printf(gettext("\n\tAdditional devices are known to "
1252 "be part of this pool, though their\n\texact "
1253 "configuration cannot be determined.\n"));
1254 }
1255 }
1256
1257 /*
1258 * Perform the import for the given configuration. This passes the heavy
1259 * lifting off to zpool_import_props(), and then mounts the datasets contained
1260 * within the pool.
1261 */
1262 static int
1263 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1264 int force, nvlist_t *props, boolean_t allowfaulted)
1265 {
1266 zpool_handle_t *zhp;
1267 char *name;
1268 uint64_t state;
1269 uint64_t version;
1270 int error = 0;
1271
1272 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1273 &name) == 0);
1274
1275 verify(nvlist_lookup_uint64(config,
1276 ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1277 verify(nvlist_lookup_uint64(config,
1278 ZPOOL_CONFIG_VERSION, &version) == 0);
1279 if (version > SPA_VERSION) {
1280 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1281 "is formatted using a newer ZFS version\n"), name);
1282 return (1);
1283 } else if (state != POOL_STATE_EXPORTED && !force) {
1284 uint64_t hostid;
1285
1286 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1287 &hostid) == 0) {
1288 if ((unsigned long)hostid != gethostid()) {
1289 char *hostname;
1290 uint64_t timestamp;
1291 time_t t;
1292
1293 verify(nvlist_lookup_string(config,
1294 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1295 verify(nvlist_lookup_uint64(config,
1296 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0);
1297 t = timestamp;
1298 (void) fprintf(stderr, gettext("cannot import "
1299 "'%s': pool may be in use from other "
1300 "system, it was last accessed by %s "
1301 "(hostid: 0x%lx) on %s"), name, hostname,
1302 (unsigned long)hostid,
1303 asctime(localtime(&t)));
1304 (void) fprintf(stderr, gettext("use '-f' to "
1305 "import anyway\n"));
1306 return (1);
1307 }
1308 } else {
1309 (void) fprintf(stderr, gettext("cannot import '%s': "
1310 "pool may be in use from other system\n"), name);
1311 (void) fprintf(stderr, gettext("use '-f' to import "
1312 "anyway\n"));
1313 return (1);
1314 }
1315 }
1316
1317 if (zpool_import_props(g_zfs, config, newname, props,
1318 allowfaulted) != 0)
1319 return (1);
1320
1321 if (newname != NULL)
1322 name = (char *)newname;
1323
1324 verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL);
1325
1326 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1327 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1328 zpool_close(zhp);
1329 return (1);
1330 }
1331
1332 zpool_close(zhp);
1333 return (error);
1334 }
1335
1336 /*
1337 * zpool import [-d dir] [-D]
1338 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1339 * [-d dir | -c cachefile] [-f] -a
1340 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1341 * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1342 *
1343 * -c Read pool information from a cachefile instead of searching
1344 * devices.
1345 *
1346 * -d Scan in a specific directory, other than /dev/dsk. More than
1347 * one directory can be specified using multiple '-d' options.
1348 *
1349 * -D Scan for previously destroyed pools or import all or only
1350 * specified destroyed pools.
1351 *
1352 * -R Temporarily import the pool, with all mountpoints relative to
1353 * the given root. The pool will remain exported when the machine
1354 * is rebooted.
1355 *
1356 * -f Force import, even if it appears that the pool is active.
1357 *
1358 * -F Import even in the presence of faulted vdevs. This is an
1359 * intentionally undocumented option for testing purposes, and
1360 * treats the pool configuration as complete, leaving any bad
1361 * vdevs in the FAULTED state.
1362 *
1363 * -a Import all pools found.
1364 *
1365 * -o Set property=value and/or temporary mount options (without '=').
1366 *
1367 * The import command scans for pools to import, and import pools based on pool
1368 * name and GUID. The pool can also be renamed as part of the import process.
1369 */
1370 int
1371 zpool_do_import(int argc, char **argv)
1372 {
1373 char **searchdirs = NULL;
1374 int nsearch = 0;
1375 int c;
1376 int err;
1377 nvlist_t *pools = NULL;
1378 boolean_t do_all = B_FALSE;
1379 boolean_t do_destroyed = B_FALSE;
1380 char *mntopts = NULL;
1381 boolean_t do_force = B_FALSE;
1382 nvpair_t *elem;
1383 nvlist_t *config;
1384 uint64_t searchguid = 0;
1385 char *searchname = NULL;
1386 char *propval;
1387 nvlist_t *found_config;
1388 nvlist_t *props = NULL;
1389 boolean_t first;
1390 boolean_t allow_faulted = B_FALSE;
1391 uint64_t pool_state;
1392 char *cachefile = NULL;
1393
1394 /* check options */
1395 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1396 switch (c) {
1397 case 'a':
1398 do_all = B_TRUE;
1399 break;
1400 case 'c':
1401 cachefile = optarg;
1402 break;
1403 case 'd':
1404 if (searchdirs == NULL) {
1405 searchdirs = safe_malloc(sizeof (char *));
1406 } else {
1407 char **tmp = safe_malloc((nsearch + 1) *
1408 sizeof (char *));
1409 bcopy(searchdirs, tmp, nsearch *
1410 sizeof (char *));
1411 free(searchdirs);
1412 searchdirs = tmp;
1413 }
1414 searchdirs[nsearch++] = optarg;
1415 break;
1416 case 'D':
1417 do_destroyed = B_TRUE;
1418 break;
1419 case 'f':
1420 do_force = B_TRUE;
1421 break;
1422 case 'F':
1423 allow_faulted = B_TRUE;
1424 break;
1425 case 'o':
1426 if ((propval = strchr(optarg, '=')) != NULL) {
1427 *propval = '\0';
1428 propval++;
1429 if (add_prop_list(optarg, propval,
1430 &props, B_TRUE))
1431 goto error;
1432 } else {
1433 mntopts = optarg;
1434 }
1435 break;
1436 case 'R':
1437 if (add_prop_list(zpool_prop_to_name(
1438 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1439 goto error;
1440 if (nvlist_lookup_string(props,
1441 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1442 &propval) == 0)
1443 break;
1444 if (add_prop_list(zpool_prop_to_name(
1445 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1446 goto error;
1447 break;
1448 case ':':
1449 (void) fprintf(stderr, gettext("missing argument for "
1450 "'%c' option\n"), optopt);
1451 usage(B_FALSE);
1452 break;
1453 case '?':
1454 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1455 optopt);
1456 usage(B_FALSE);
1457 }
1458 }
1459
1460 argc -= optind;
1461 argv += optind;
1462
1463 if (cachefile && nsearch != 0) {
1464 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1465 usage(B_FALSE);
1466 }
1467
1468 if (searchdirs == NULL) {
1469 searchdirs = safe_malloc(sizeof (char *));
1470 searchdirs[0] = "/dev/dsk";
1471 nsearch = 1;
1472 }
1473
1474 /* check argument count */
1475 if (do_all) {
1476 if (argc != 0) {
1477 (void) fprintf(stderr, gettext("too many arguments\n"));
1478 usage(B_FALSE);
1479 }
1480 } else {
1481 if (argc > 2) {
1482 (void) fprintf(stderr, gettext("too many arguments\n"));
1483 usage(B_FALSE);
1484 }
1485
1486 /*
1487 * Check for the SYS_CONFIG privilege. We do this explicitly
1488 * here because otherwise any attempt to discover pools will
1489 * silently fail.
1490 */
1491 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1492 (void) fprintf(stderr, gettext("cannot "
1493 "discover pools: permission denied\n"));
1494 free(searchdirs);
1495 return (1);
1496 }
1497 }
1498
1499 /*
1500 * Depending on the arguments given, we do one of the following:
1501 *
1502 * <none> Iterate through all pools and display information about
1503 * each one.
1504 *
1505 * -a Iterate through all pools and try to import each one.
1506 *
1507 * <id> Find the pool that corresponds to the given GUID/pool
1508 * name and import that one.
1509 *
1510 * -D Above options applies only to destroyed pools.
1511 */
1512 if (argc != 0) {
1513 char *endptr;
1514
1515 errno = 0;
1516 searchguid = strtoull(argv[0], &endptr, 10);
1517 if (errno != 0 || *endptr != '\0')
1518 searchname = argv[0];
1519 found_config = NULL;
1520 }
1521
1522 if (cachefile) {
1523 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1524 searchguid);
1525 } else if (searchname != NULL) {
1526 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1527 searchname);
1528 } else {
1529 /*
1530 * It's OK to search by guid even if searchguid is 0.
1531 */
1532 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1533 searchguid);
1534 }
1535
1536 if (pools == NULL) {
1537 if (argc != 0) {
1538 (void) fprintf(stderr, gettext("cannot import '%s': "
1539 "no such pool available\n"), argv[0]);
1540 }
1541 free(searchdirs);
1542 return (1);
1543 }
1544
1545 /*
1546 * At this point we have a list of import candidate configs. Even if
1547 * we were searching by pool name or guid, we still need to
1548 * post-process the list to deal with pool state and possible
1549 * duplicate names.
1550 */
1551 err = 0;
1552 elem = NULL;
1553 first = B_TRUE;
1554 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1555
1556 verify(nvpair_value_nvlist(elem, &config) == 0);
1557
1558 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1559 &pool_state) == 0);
1560 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1561 continue;
1562 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1563 continue;
1564
1565 if (argc == 0) {
1566 if (first)
1567 first = B_FALSE;
1568 else if (!do_all)
1569 (void) printf("\n");
1570
1571 if (do_all)
1572 err |= do_import(config, NULL, mntopts,
1573 do_force, props, allow_faulted);
1574 else
1575 show_import(config);
1576 } else if (searchname != NULL) {
1577 char *name;
1578
1579 /*
1580 * We are searching for a pool based on name.
1581 */
1582 verify(nvlist_lookup_string(config,
1583 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1584
1585 if (strcmp(name, searchname) == 0) {
1586 if (found_config != NULL) {
1587 (void) fprintf(stderr, gettext(
1588 "cannot import '%s': more than "
1589 "one matching pool\n"), searchname);
1590 (void) fprintf(stderr, gettext(
1591 "import by numeric ID instead\n"));
1592 err = B_TRUE;
1593 }
1594 found_config = config;
1595 }
1596 } else {
1597 uint64_t guid;
1598
1599 /*
1600 * Search for a pool by guid.
1601 */
1602 verify(nvlist_lookup_uint64(config,
1603 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1604
1605 if (guid == searchguid)
1606 found_config = config;
1607 }
1608 }
1609
1610 /*
1611 * If we were searching for a specific pool, verify that we found a
1612 * pool, and then do the import.
1613 */
1614 if (argc != 0 && err == 0) {
1615 if (found_config == NULL) {
1616 (void) fprintf(stderr, gettext("cannot import '%s': "
1617 "no such pool available\n"), argv[0]);
1618 err = B_TRUE;
1619 } else {
1620 err |= do_import(found_config, argc == 1 ? NULL :
1621 argv[1], mntopts, do_force, props, allow_faulted);
1622 }
1623 }
1624
1625 /*
1626 * If we were just looking for pools, report an error if none were
1627 * found.
1628 */
1629 if (argc == 0 && first)
1630 (void) fprintf(stderr,
1631 gettext("no pools available to import\n"));
1632
1633 error:
1634 nvlist_free(props);
1635 nvlist_free(pools);
1636 free(searchdirs);
1637
1638 return (err ? 1 : 0);
1639 }
1640
1641 typedef struct iostat_cbdata {
1642 zpool_list_t *cb_list;
1643 int cb_verbose;
1644 int cb_iteration;
1645 int cb_namewidth;
1646 } iostat_cbdata_t;
1647
1648 static void
1649 print_iostat_separator(iostat_cbdata_t *cb)
1650 {
1651 int i = 0;
1652
1653 for (i = 0; i < cb->cb_namewidth; i++)
1654 (void) printf("-");
1655 (void) printf(" ----- ----- ----- ----- ----- -----\n");
1656 }
1657
1658 static void
1659 print_iostat_header(iostat_cbdata_t *cb)
1660 {
1661 (void) printf("%*s capacity operations bandwidth\n",
1662 cb->cb_namewidth, "");
1663 (void) printf("%-*s used avail read write read write\n",
1664 cb->cb_namewidth, "pool");
1665 print_iostat_separator(cb);
1666 }
1667
1668 /*
1669 * Display a single statistic.
1670 */
1671 static void
1672 print_one_stat(uint64_t value)
1673 {
1674 char buf[64];
1675
1676 zfs_nicenum(value, buf, sizeof (buf));
1677 (void) printf(" %5s", buf);
1678 }
1679
1680 /*
1681 * Print out all the statistics for the given vdev. This can either be the
1682 * toplevel configuration, or called recursively. If 'name' is NULL, then this
1683 * is a verbose output, and we don't want to display the toplevel pool stats.
1684 */
1685 void
1686 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1687 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1688 {
1689 nvlist_t **oldchild, **newchild;
1690 uint_t c, children;
1691 vdev_stat_t *oldvs, *newvs;
1692 vdev_stat_t zerovs = { 0 };
1693 uint64_t tdelta;
1694 double scale;
1695 char *vname;
1696
1697 if (oldnv != NULL) {
1698 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1699 (uint64_t **)&oldvs, &c) == 0);
1700 } else {
1701 oldvs = &zerovs;
1702 }
1703
1704 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1705 (uint64_t **)&newvs, &c) == 0);
1706
1707 if (strlen(name) + depth > cb->cb_namewidth)
1708 (void) printf("%*s%s", depth, "", name);
1709 else
1710 (void) printf("%*s%s%*s", depth, "", name,
1711 (int)(cb->cb_namewidth - strlen(name) - depth), "");
1712
1713 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1714
1715 if (tdelta == 0)
1716 scale = 1.0;
1717 else
1718 scale = (double)NANOSEC / tdelta;
1719
1720 /* only toplevel vdevs have capacity stats */
1721 if (newvs->vs_space == 0) {
1722 (void) printf(" - -");
1723 } else {
1724 print_one_stat(newvs->vs_alloc);
1725 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1726 }
1727
1728 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1729 oldvs->vs_ops[ZIO_TYPE_READ])));
1730
1731 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1732 oldvs->vs_ops[ZIO_TYPE_WRITE])));
1733
1734 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1735 oldvs->vs_bytes[ZIO_TYPE_READ])));
1736
1737 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1738 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1739
1740 (void) printf("\n");
1741
1742 if (!cb->cb_verbose)
1743 return;
1744
1745 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1746 &newchild, &children) != 0)
1747 return;
1748
1749 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1750 &oldchild, &c) != 0)
1751 return;
1752
1753 for (c = 0; c < children; c++) {
1754 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1755 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1756 newchild[c], cb, depth + 2);
1757 free(vname);
1758 }
1759
1760 /*
1761 * Include level 2 ARC devices in iostat output
1762 */
1763 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1764 &newchild, &children) != 0)
1765 return;
1766
1767 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1768 &oldchild, &c) != 0)
1769 return;
1770
1771 if (children > 0) {
1772 (void) printf("%-*s - - - - - "
1773 "-\n", cb->cb_namewidth, "cache");
1774 for (c = 0; c < children; c++) {
1775 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1776 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1777 newchild[c], cb, depth + 2);
1778 free(vname);
1779 }
1780 }
1781 }
1782
1783 static int
1784 refresh_iostat(zpool_handle_t *zhp, void *data)
1785 {
1786 iostat_cbdata_t *cb = data;
1787 boolean_t missing;
1788
1789 /*
1790 * If the pool has disappeared, remove it from the list and continue.
1791 */
1792 if (zpool_refresh_stats(zhp, &missing) != 0)
1793 return (-1);
1794
1795 if (missing)
1796 pool_list_remove(cb->cb_list, zhp);
1797
1798 return (0);
1799 }
1800
1801 /*
1802 * Callback to print out the iostats for the given pool.
1803 */
1804 int
1805 print_iostat(zpool_handle_t *zhp, void *data)
1806 {
1807 iostat_cbdata_t *cb = data;
1808 nvlist_t *oldconfig, *newconfig;
1809 nvlist_t *oldnvroot, *newnvroot;
1810
1811 newconfig = zpool_get_config(zhp, &oldconfig);
1812
1813 if (cb->cb_iteration == 1)
1814 oldconfig = NULL;
1815
1816 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1817 &newnvroot) == 0);
1818
1819 if (oldconfig == NULL)
1820 oldnvroot = NULL;
1821 else
1822 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1823 &oldnvroot) == 0);
1824
1825 /*
1826 * Print out the statistics for the pool.
1827 */
1828 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1829
1830 if (cb->cb_verbose)
1831 print_iostat_separator(cb);
1832
1833 return (0);
1834 }
1835
1836 int
1837 get_namewidth(zpool_handle_t *zhp, void *data)
1838 {
1839 iostat_cbdata_t *cb = data;
1840 nvlist_t *config, *nvroot;
1841
1842 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1843 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1844 &nvroot) == 0);
1845 if (!cb->cb_verbose)
1846 cb->cb_namewidth = strlen(zpool_get_name(zhp));
1847 else
1848 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1849 }
1850
1851 /*
1852 * The width must fall into the range [10,38]. The upper limit is the
1853 * maximum we can have and still fit in 80 columns.
1854 */
1855 if (cb->cb_namewidth < 10)
1856 cb->cb_namewidth = 10;
1857 if (cb->cb_namewidth > 38)
1858 cb->cb_namewidth = 38;
1859
1860 return (0);
1861 }
1862
1863 /*
1864 * zpool iostat [-v] [pool] ... [interval [count]]
1865 *
1866 * -v Display statistics for individual vdevs
1867 *
1868 * This command can be tricky because we want to be able to deal with pool
1869 * creation/destruction as well as vdev configuration changes. The bulk of this
1870 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
1871 * on pool_list_update() to detect the addition of new pools. Configuration
1872 * changes are all handled within libzfs.
1873 */
1874 int
1875 zpool_do_iostat(int argc, char **argv)
1876 {
1877 int c;
1878 int ret;
1879 int npools;
1880 unsigned long interval = 0, count = 0;
1881 zpool_list_t *list;
1882 boolean_t verbose = B_FALSE;
1883 iostat_cbdata_t cb;
1884
1885 /* check options */
1886 while ((c = getopt(argc, argv, "v")) != -1) {
1887 switch (c) {
1888 case 'v':
1889 verbose = B_TRUE;
1890 break;
1891 case '?':
1892 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1893 optopt);
1894 usage(B_FALSE);
1895 }
1896 }
1897
1898 argc -= optind;
1899 argv += optind;
1900
1901 /*
1902 * Determine if the last argument is an integer or a pool name
1903 */
1904 if (argc > 0 && isdigit(argv[argc - 1][0])) {
1905 char *end;
1906
1907 errno = 0;
1908 interval = strtoul(argv[argc - 1], &end, 10);
1909
1910 if (*end == '\0' && errno == 0) {
1911 if (interval == 0) {
1912 (void) fprintf(stderr, gettext("interval "
1913 "cannot be zero\n"));
1914 usage(B_FALSE);
1915 }
1916
1917 /*
1918 * Ignore the last parameter
1919 */
1920 argc--;
1921 } else {
1922 /*
1923 * If this is not a valid number, just plow on. The
1924 * user will get a more informative error message later
1925 * on.
1926 */
1927 interval = 0;
1928 }
1929 }
1930
1931 /*
1932 * If the last argument is also an integer, then we have both a count
1933 * and an integer.
1934 */
1935 if (argc > 0 && isdigit(argv[argc - 1][0])) {
1936 char *end;
1937
1938 errno = 0;
1939 count = interval;
1940 interval = strtoul(argv[argc - 1], &end, 10);
1941
1942 if (*end == '\0' && errno == 0) {
1943 if (interval == 0) {
1944 (void) fprintf(stderr, gettext("interval "
1945 "cannot be zero\n"));
1946 usage(B_FALSE);
1947 }
1948
1949 /*
1950 * Ignore the last parameter
1951 */
1952 argc--;
1953 } else {
1954 interval = 0;
1955 }
1956 }
1957
1958 /*
1959 * Construct the list of all interesting pools.
1960 */
1961 ret = 0;
1962 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1963 return (1);
1964
1965 if (pool_list_count(list) == 0 && argc != 0) {
1966 pool_list_free(list);
1967 return (1);
1968 }
1969
1970 if (pool_list_count(list) == 0 && interval == 0) {
1971 pool_list_free(list);
1972 (void) fprintf(stderr, gettext("no pools available\n"));
1973 return (1);
1974 }
1975
1976 /*
1977 * Enter the main iostat loop.
1978 */
1979 cb.cb_list = list;
1980 cb.cb_verbose = verbose;
1981 cb.cb_iteration = 0;
1982 cb.cb_namewidth = 0;
1983
1984 for (;;) {
1985 pool_list_update(list);
1986
1987 if ((npools = pool_list_count(list)) == 0)
1988 break;
1989
1990 /*
1991 * Refresh all statistics. This is done as an explicit step
1992 * before calculating the maximum name width, so that any
1993 * configuration changes are properly accounted for.
1994 */
1995 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1996
1997 /*
1998 * Iterate over all pools to determine the maximum width
1999 * for the pool / device name column across all pools.
2000 */
2001 cb.cb_namewidth = 0;
2002 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2003
2004 /*
2005 * If it's the first time, or verbose mode, print the header.
2006 */
2007 if (++cb.cb_iteration == 1 || verbose)
2008 print_iostat_header(&cb);
2009
2010 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2011
2012 /*
2013 * If there's more than one pool, and we're not in verbose mode
2014 * (which prints a separator for us), then print a separator.
2015 */
2016 if (npools > 1 && !verbose)
2017 print_iostat_separator(&cb);
2018
2019 if (verbose)
2020 (void) printf("\n");
2021
2022 /*
2023 * Flush the output so that redirection to a file isn't buffered
2024 * indefinitely.
2025 */
2026 (void) fflush(stdout);
2027
2028 if (interval == 0)
2029 break;
2030
2031 if (count != 0 && --count == 0)
2032 break;
2033
2034 (void) sleep(interval);
2035 }
2036
2037 pool_list_free(list);
2038
2039 return (ret);
2040 }
2041
2042 typedef struct list_cbdata {
2043 boolean_t cb_scripted;
2044 boolean_t cb_first;
2045 zprop_list_t *cb_proplist;
2046 } list_cbdata_t;
2047
2048 /*
2049 * Given a list of columns to display, output appropriate headers for each one.
2050 */
2051 static void
2052 print_header(zprop_list_t *pl)
2053 {
2054 const char *header;
2055 boolean_t first = B_TRUE;
2056 boolean_t right_justify;
2057
2058 for (; pl != NULL; pl = pl->pl_next) {
2059 if (pl->pl_prop == ZPROP_INVAL)
2060 continue;
2061
2062 if (!first)
2063 (void) printf(" ");
2064 else
2065 first = B_FALSE;
2066
2067 header = zpool_prop_column_name(pl->pl_prop);
2068 right_justify = zpool_prop_align_right(pl->pl_prop);
2069
2070 if (pl->pl_next == NULL && !right_justify)
2071 (void) printf("%s", header);
2072 else if (right_justify)
2073 (void) printf("%*s", pl->pl_width, header);
2074 else
2075 (void) printf("%-*s", pl->pl_width, header);
2076 }
2077
2078 (void) printf("\n");
2079 }
2080
2081 /*
2082 * Given a pool and a list of properties, print out all the properties according
2083 * to the described layout.
2084 */
2085 static void
2086 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2087 {
2088 boolean_t first = B_TRUE;
2089 char property[ZPOOL_MAXPROPLEN];
2090 char *propstr;
2091 boolean_t right_justify;
2092 int width;
2093
2094 for (; pl != NULL; pl = pl->pl_next) {
2095 if (!first) {
2096 if (scripted)
2097 (void) printf("\t");
2098 else
2099 (void) printf(" ");
2100 } else {
2101 first = B_FALSE;
2102 }
2103
2104 right_justify = B_FALSE;
2105 if (pl->pl_prop != ZPROP_INVAL) {
2106 if (zpool_get_prop(zhp, pl->pl_prop, property,
2107 sizeof (property), NULL) != 0)
2108 propstr = "-";
2109 else
2110 propstr = property;
2111
2112 right_justify = zpool_prop_align_right(pl->pl_prop);
2113 } else {
2114 propstr = "-";
2115 }
2116
2117 width = pl->pl_width;
2118
2119 /*
2120 * If this is being called in scripted mode, or if this is the
2121 * last column and it is left-justified, don't include a width
2122 * format specifier.
2123 */
2124 if (scripted || (pl->pl_next == NULL && !right_justify))
2125 (void) printf("%s", propstr);
2126 else if (right_justify)
2127 (void) printf("%*s", width, propstr);
2128 else
2129 (void) printf("%-*s", width, propstr);
2130 }
2131
2132 (void) printf("\n");
2133 }
2134
2135 /*
2136 * Generic callback function to list a pool.
2137 */
2138 int
2139 list_callback(zpool_handle_t *zhp, void *data)
2140 {
2141 list_cbdata_t *cbp = data;
2142
2143 if (cbp->cb_first) {
2144 if (!cbp->cb_scripted)
2145 print_header(cbp->cb_proplist);
2146 cbp->cb_first = B_FALSE;
2147 }
2148
2149 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2150
2151 return (0);
2152 }
2153
2154 /*
2155 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2156 *
2157 * -H Scripted mode. Don't display headers, and separate properties
2158 * by a single tab.
2159 * -o List of properties to display. Defaults to
2160 * "name,size,used,available,capacity,health,altroot"
2161 *
2162 * List all pools in the system, whether or not they're healthy. Output space
2163 * statistics for each one, as well as health status summary.
2164 */
2165 int
2166 zpool_do_list(int argc, char **argv)
2167 {
2168 int c;
2169 int ret;
2170 list_cbdata_t cb = { 0 };
2171 static char default_props[] =
2172 "name,size,used,available,capacity,health,altroot";
2173 char *props = default_props;
2174
2175 /* check options */
2176 while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2177 switch (c) {
2178 case 'H':
2179 cb.cb_scripted = B_TRUE;
2180 break;
2181 case 'o':
2182 props = optarg;
2183 break;
2184 case ':':
2185 (void) fprintf(stderr, gettext("missing argument for "
2186 "'%c' option\n"), optopt);
2187 usage(B_FALSE);
2188 break;
2189 case '?':
2190 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2191 optopt);
2192 usage(B_FALSE);
2193 }
2194 }
2195
2196 argc -= optind;
2197 argv += optind;
2198
2199 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2200 usage(B_FALSE);
2201
2202 cb.cb_first = B_TRUE;
2203
2204 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2205 list_callback, &cb);
2206
2207 zprop_free_list(cb.cb_proplist);
2208
2209 if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2210 (void) printf(gettext("no pools available\n"));
2211 return (0);
2212 }
2213
2214 return (ret);
2215 }
2216
2217 static nvlist_t *
2218 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2219 {
2220 nvlist_t **child;
2221 uint_t c, children;
2222 nvlist_t *match;
2223 char *path;
2224
2225 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2226 &child, &children) != 0) {
2227 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2228 if (strncmp(name, "/dev/dsk/", 9) == 0)
2229 name += 9;
2230 if (strncmp(path, "/dev/dsk/", 9) == 0)
2231 path += 9;
2232 if (strcmp(name, path) == 0)
2233 return (nv);
2234 return (NULL);
2235 }
2236
2237 for (c = 0; c < children; c++)
2238 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2239 return (match);
2240
2241 return (NULL);
2242 }
2243
2244 static int
2245 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2246 {
2247 boolean_t force = B_FALSE;
2248 int c;
2249 nvlist_t *nvroot;
2250 char *poolname, *old_disk, *new_disk;
2251 zpool_handle_t *zhp;
2252 int ret;
2253
2254 /* check options */
2255 while ((c = getopt(argc, argv, "f")) != -1) {
2256 switch (c) {
2257 case 'f':
2258 force = B_TRUE;
2259 break;
2260 case '?':
2261 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2262 optopt);
2263 usage(B_FALSE);
2264 }
2265 }
2266
2267 argc -= optind;
2268 argv += optind;
2269
2270 /* get pool name and check number of arguments */
2271 if (argc < 1) {
2272 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2273 usage(B_FALSE);
2274 }
2275
2276 poolname = argv[0];
2277
2278 if (argc < 2) {
2279 (void) fprintf(stderr,
2280 gettext("missing <device> specification\n"));
2281 usage(B_FALSE);
2282 }
2283
2284 old_disk = argv[1];
2285
2286 if (argc < 3) {
2287 if (!replacing) {
2288 (void) fprintf(stderr,
2289 gettext("missing <new_device> specification\n"));
2290 usage(B_FALSE);
2291 }
2292 new_disk = old_disk;
2293 argc -= 1;
2294 argv += 1;
2295 } else {
2296 new_disk = argv[2];
2297 argc -= 2;
2298 argv += 2;
2299 }
2300
2301 if (argc > 1) {
2302 (void) fprintf(stderr, gettext("too many arguments\n"));
2303 usage(B_FALSE);
2304 }
2305
2306 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2307 return (1);
2308
2309 if (zpool_get_config(zhp, NULL) == NULL) {
2310 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2311 poolname);
2312 zpool_close(zhp);
2313 return (1);
2314 }
2315
2316 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2317 argc, argv);
2318 if (nvroot == NULL) {
2319 zpool_close(zhp);
2320 return (1);
2321 }
2322
2323 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2324
2325 nvlist_free(nvroot);
2326 zpool_close(zhp);
2327
2328 return (ret);
2329 }
2330
2331 /*
2332 * zpool replace [-f] <pool> <device> <new_device>
2333 *
2334 * -f Force attach, even if <new_device> appears to be in use.
2335 *
2336 * Replace <device> with <new_device>.
2337 */
2338 /* ARGSUSED */
2339 int
2340 zpool_do_replace(int argc, char **argv)
2341 {
2342 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2343 }
2344
2345 /*
2346 * zpool attach [-f] <pool> <device> <new_device>
2347 *
2348 * -f Force attach, even if <new_device> appears to be in use.
2349 *
2350 * Attach <new_device> to the mirror containing <device>. If <device> is not
2351 * part of a mirror, then <device> will be transformed into a mirror of
2352 * <device> and <new_device>. In either case, <new_device> will begin life
2353 * with a DTL of [0, now], and will immediately begin to resilver itself.
2354 */
2355 int
2356 zpool_do_attach(int argc, char **argv)
2357 {
2358 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2359 }
2360
2361 /*
2362 * zpool detach [-f] <pool> <device>
2363 *
2364 * -f Force detach of <device>, even if DTLs argue against it
2365 * (not supported yet)
2366 *
2367 * Detach a device from a mirror. The operation will be refused if <device>
2368 * is the last device in the mirror, or if the DTLs indicate that this device
2369 * has the only valid copy of some data.
2370 */
2371 /* ARGSUSED */
2372 int
2373 zpool_do_detach(int argc, char **argv)
2374 {
2375 int c;
2376 char *poolname, *path;
2377 zpool_handle_t *zhp;
2378 int ret;
2379
2380 /* check options */
2381 while ((c = getopt(argc, argv, "f")) != -1) {
2382 switch (c) {
2383 case 'f':
2384 case '?':
2385 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2386 optopt);
2387 usage(B_FALSE);
2388 }
2389 }
2390
2391 argc -= optind;
2392 argv += optind;
2393
2394 /* get pool name and check number of arguments */
2395 if (argc < 1) {
2396 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2397 usage(B_FALSE);
2398 }
2399
2400 if (argc < 2) {
2401 (void) fprintf(stderr,
2402 gettext("missing <device> specification\n"));
2403 usage(B_FALSE);
2404 }
2405
2406 poolname = argv[0];
2407 path = argv[1];
2408
2409 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2410 return (1);
2411
2412 ret = zpool_vdev_detach(zhp, path);
2413
2414 zpool_close(zhp);
2415
2416 return (ret);
2417 }
2418
2419 /*
2420 * zpool online <pool> <device> ...
2421 */
2422 int
2423 zpool_do_online(int argc, char **argv)
2424 {
2425 int c, i;
2426 char *poolname;
2427 zpool_handle_t *zhp;
2428 int ret = 0;
2429 vdev_state_t newstate;
2430
2431 /* check options */
2432 while ((c = getopt(argc, argv, "t")) != -1) {
2433 switch (c) {
2434 case 't':
2435 case '?':
2436 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2437 optopt);
2438 usage(B_FALSE);
2439 }
2440 }
2441
2442 argc -= optind;
2443 argv += optind;
2444
2445 /* get pool name and check number of arguments */
2446 if (argc < 1) {
2447 (void) fprintf(stderr, gettext("missing pool name\n"));
2448 usage(B_FALSE);
2449 }
2450 if (argc < 2) {
2451 (void) fprintf(stderr, gettext("missing device name\n"));
2452 usage(B_FALSE);
2453 }
2454
2455 poolname = argv[0];
2456
2457 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2458 return (1);
2459
2460 for (i = 1; i < argc; i++) {
2461 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2462 if (newstate != VDEV_STATE_HEALTHY) {
2463 (void) printf(gettext("warning: device '%s' "
2464 "onlined, but remains in faulted state\n"),
2465 argv[i]);
2466 if (newstate == VDEV_STATE_FAULTED)
2467 (void) printf(gettext("use 'zpool "
2468 "clear' to restore a faulted "
2469 "device\n"));
2470 else
2471 (void) printf(gettext("use 'zpool "
2472 "replace' to replace devices "
2473 "that are no longer present\n"));
2474 }
2475 } else {
2476 ret = 1;
2477 }
2478 }
2479
2480 zpool_close(zhp);
2481
2482 return (ret);
2483 }
2484
2485 /*
2486 * zpool offline [-ft] <pool> <device> ...
2487 *
2488 * -f Force the device into the offline state, even if doing
2489 * so would appear to compromise pool availability.
2490 * (not supported yet)
2491 *
2492 * -t Only take the device off-line temporarily. The offline
2493 * state will not be persistent across reboots.
2494 */
2495 /* ARGSUSED */
2496 int
2497 zpool_do_offline(int argc, char **argv)
2498 {
2499 int c, i;
2500 char *poolname;
2501 zpool_handle_t *zhp;
2502 int ret = 0;
2503 boolean_t istmp = B_FALSE;
2504
2505 /* check options */
2506 while ((c = getopt(argc, argv, "ft")) != -1) {
2507 switch (c) {
2508 case 't':
2509 istmp = B_TRUE;
2510 break;
2511 case 'f':
2512 case '?':
2513 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2514 optopt);
2515 usage(B_FALSE);
2516 }
2517 }
2518
2519 argc -= optind;
2520 argv += optind;
2521
2522 /* get pool name and check number of arguments */
2523 if (argc < 1) {
2524 (void) fprintf(stderr, gettext("missing pool name\n"));
2525 usage(B_FALSE);
2526 }
2527 if (argc < 2) {
2528 (void) fprintf(stderr, gettext("missing device name\n"));
2529 usage(B_FALSE);
2530 }
2531
2532 poolname = argv[0];
2533
2534 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2535 return (1);
2536
2537 for (i = 1; i < argc; i++) {
2538 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2539 ret = 1;
2540 }
2541
2542 zpool_close(zhp);
2543
2544 return (ret);
2545 }
2546
2547 /*
2548 * zpool clear <pool> [device]
2549 *
2550 * Clear all errors associated with a pool or a particular device.
2551 */
2552 int
2553 zpool_do_clear(int argc, char **argv)
2554 {
2555 int ret = 0;
2556 zpool_handle_t *zhp;
2557 char *pool, *device;
2558
2559 if (argc < 2) {
2560 (void) fprintf(stderr, gettext("missing pool name\n"));
2561 usage(B_FALSE);
2562 }
2563
2564 if (argc > 3) {
2565 (void) fprintf(stderr, gettext("too many arguments\n"));
2566 usage(B_FALSE);
2567 }
2568
2569 pool = argv[1];
2570 device = argc == 3 ? argv[2] : NULL;
2571
2572 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2573 return (1);
2574
2575 if (zpool_clear(zhp, device) != 0)
2576 ret = 1;
2577
2578 zpool_close(zhp);
2579
2580 return (ret);
2581 }
2582
2583 typedef struct scrub_cbdata {
2584 int cb_type;
2585 int cb_argc;
2586 char **cb_argv;
2587 } scrub_cbdata_t;
2588
2589 int
2590 scrub_callback(zpool_handle_t *zhp, void *data)
2591 {
2592 scrub_cbdata_t *cb = data;
2593 int err;
2594
2595 /*
2596 * Ignore faulted pools.
2597 */
2598 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2599 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2600 "currently unavailable\n"), zpool_get_name(zhp));
2601 return (1);
2602 }
2603
2604 err = zpool_scrub(zhp, cb->cb_type);
2605
2606 return (err != 0);
2607 }
2608
2609 /*
2610 * zpool scrub [-s] <pool> ...
2611 *
2612 * -s Stop. Stops any in-progress scrub.
2613 */
2614 int
2615 zpool_do_scrub(int argc, char **argv)
2616 {
2617 int c;
2618 scrub_cbdata_t cb;
2619
2620 cb.cb_type = POOL_SCRUB_EVERYTHING;
2621
2622 /* check options */
2623 while ((c = getopt(argc, argv, "s")) != -1) {
2624 switch (c) {
2625 case 's':
2626 cb.cb_type = POOL_SCRUB_NONE;
2627 break;
2628 case '?':
2629 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2630 optopt);
2631 usage(B_FALSE);
2632 }
2633 }
2634
2635 cb.cb_argc = argc;
2636 cb.cb_argv = argv;
2637 argc -= optind;
2638 argv += optind;
2639
2640 if (argc < 1) {
2641 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2642 usage(B_FALSE);
2643 }
2644
2645 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2646 }
2647
2648 typedef struct status_cbdata {
2649 int cb_count;
2650 boolean_t cb_allpools;
2651 boolean_t cb_verbose;
2652 boolean_t cb_explain;
2653 boolean_t cb_first;
2654 } status_cbdata_t;
2655
2656 /*
2657 * Print out detailed scrub status.
2658 */
2659 void
2660 print_scrub_status(nvlist_t *nvroot)
2661 {
2662 vdev_stat_t *vs;
2663 uint_t vsc;
2664 time_t start, end, now;
2665 double fraction_done;
2666 uint64_t examined, total, minutes_left, minutes_taken;
2667 char *scrub_type;
2668
2669 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2670 (uint64_t **)&vs, &vsc) == 0);
2671
2672 /*
2673 * If there's never been a scrub, there's not much to say.
2674 */
2675 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2676 (void) printf(gettext("none requested\n"));
2677 return;
2678 }
2679
2680 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2681 "resilver" : "scrub";
2682
2683 start = vs->vs_scrub_start;
2684 end = vs->vs_scrub_end;
2685 now = time(NULL);
2686 examined = vs->vs_scrub_examined;
2687 total = vs->vs_alloc;
2688
2689 if (end != 0) {
2690 minutes_taken = (uint64_t)((end - start) / 60);
2691
2692 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2693 "on %s"),
2694 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2695 (u_longlong_t)(minutes_taken / 60),
2696 (uint_t)(minutes_taken % 60),
2697 (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2698 return;
2699 }
2700
2701 if (examined == 0)
2702 examined = 1;
2703 if (examined > total)
2704 total = examined;
2705
2706 fraction_done = (double)examined / total;
2707 minutes_left = (uint64_t)((now - start) *
2708 (1 - fraction_done) / fraction_done / 60);
2709 minutes_taken = (uint64_t)((now - start) / 60);
2710
2711 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2712 "%lluh%um to go\n"),
2713 scrub_type, (u_longlong_t)(minutes_taken / 60),
2714 (uint_t)(minutes_taken % 60), 100 * fraction_done,
2715 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2716 }
2717
2718 typedef struct spare_cbdata {
2719 uint64_t cb_guid;
2720 zpool_handle_t *cb_zhp;
2721 } spare_cbdata_t;
2722
2723 static boolean_t
2724 find_vdev(nvlist_t *nv, uint64_t search)
2725 {
2726 uint64_t guid;
2727 nvlist_t **child;
2728 uint_t c, children;
2729
2730 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2731 search == guid)
2732 return (B_TRUE);
2733
2734 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2735 &child, &children) == 0) {
2736 for (c = 0; c < children; c++)
2737 if (find_vdev(child[c], search))
2738 return (B_TRUE);
2739 }
2740
2741 return (B_FALSE);
2742 }
2743
2744 static int
2745 find_spare(zpool_handle_t *zhp, void *data)
2746 {
2747 spare_cbdata_t *cbp = data;
2748 nvlist_t *config, *nvroot;
2749
2750 config = zpool_get_config(zhp, NULL);
2751 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2752 &nvroot) == 0);
2753
2754 if (find_vdev(nvroot, cbp->cb_guid)) {
2755 cbp->cb_zhp = zhp;
2756 return (1);
2757 }
2758
2759 zpool_close(zhp);
2760 return (0);
2761 }
2762
2763 /*
2764 * Print out configuration state as requested by status_callback.
2765 */
2766 void
2767 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2768 int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
2769 {
2770 nvlist_t **child;
2771 uint_t c, children;
2772 vdev_stat_t *vs;
2773 char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2774 char *vname;
2775 uint64_t notpresent;
2776 spare_cbdata_t cb;
2777 char *state;
2778
2779 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2780 (uint64_t **)&vs, &c) == 0);
2781
2782 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2783 &child, &children) != 0)
2784 children = 0;
2785
2786 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2787 if (isspare) {
2788 /*
2789 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2790 * online drives.
2791 */
2792 if (vs->vs_aux == VDEV_AUX_SPARED)
2793 state = "INUSE";
2794 else if (vs->vs_state == VDEV_STATE_HEALTHY)
2795 state = "AVAIL";
2796 }
2797
2798 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
2799 name, state);
2800
2801 if (!isspare) {
2802 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2803 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2804 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2805 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2806 }
2807
2808 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2809 ¬present) == 0) {
2810 char *path;
2811 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2812 (void) printf(" was %s", path);
2813 } else if (vs->vs_aux != 0) {
2814 (void) printf(" ");
2815
2816 switch (vs->vs_aux) {
2817 case VDEV_AUX_OPEN_FAILED:
2818 (void) printf(gettext("cannot open"));
2819 break;
2820
2821 case VDEV_AUX_BAD_GUID_SUM:
2822 (void) printf(gettext("missing device"));
2823 break;
2824
2825 case VDEV_AUX_NO_REPLICAS:
2826 (void) printf(gettext("insufficient replicas"));
2827 break;
2828
2829 case VDEV_AUX_VERSION_NEWER:
2830 (void) printf(gettext("newer version"));
2831 break;
2832
2833 case VDEV_AUX_SPARED:
2834 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2835 &cb.cb_guid) == 0);
2836 if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2837 if (strcmp(zpool_get_name(cb.cb_zhp),
2838 zpool_get_name(zhp)) == 0)
2839 (void) printf(gettext("currently in "
2840 "use"));
2841 else
2842 (void) printf(gettext("in use by "
2843 "pool '%s'"),
2844 zpool_get_name(cb.cb_zhp));
2845 zpool_close(cb.cb_zhp);
2846 } else {
2847 (void) printf(gettext("currently in use"));
2848 }
2849 break;
2850
2851 case VDEV_AUX_ERR_EXCEEDED:
2852 (void) printf(gettext("too many errors"));
2853 break;
2854
2855 case VDEV_AUX_IO_FAILURE:
2856 (void) printf(gettext("experienced I/O failures"));
2857 break;
2858
2859 case VDEV_AUX_BAD_LOG:
2860 (void) printf(gettext("bad intent log"));
2861 break;
2862
2863 default:
2864 (void) printf(gettext("corrupted data"));
2865 break;
2866 }
2867 } else if (vs->vs_scrub_repaired != 0 && children == 0) {
2868 /*
2869 * Report bytes resilvered/repaired on leaf devices.
2870 */
2871 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2872 (void) printf(gettext(" %s %s"), repaired,
2873 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2874 "resilvered" : "repaired");
2875 }
2876
2877 (void) printf("\n");
2878
2879 for (c = 0; c < children; c++) {
2880 uint64_t is_log = B_FALSE;
2881
2882 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2883 &is_log);
2884 if ((is_log && !print_logs) || (!is_log && print_logs))
2885 continue;
2886 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2887 print_status_config(zhp, vname, child[c],
2888 namewidth, depth + 2, isspare, B_FALSE);
2889 free(vname);
2890 }
2891 }
2892
2893 static void
2894 print_error_log(zpool_handle_t *zhp)
2895 {
2896 nvlist_t *nverrlist = NULL;
2897 nvpair_t *elem;
2898 char *pathname;
2899 size_t len = MAXPATHLEN * 2;
2900
2901 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2902 (void) printf("errors: List of errors unavailable "
2903 "(insufficient privileges)\n");
2904 return;
2905 }
2906
2907 (void) printf("errors: Permanent errors have been "
2908 "detected in the following files:\n\n");
2909
2910 pathname = safe_malloc(len);
2911 elem = NULL;
2912 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2913 nvlist_t *nv;
2914 uint64_t dsobj, obj;
2915
2916 verify(nvpair_value_nvlist(elem, &nv) == 0);
2917 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2918 &dsobj) == 0);
2919 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2920 &obj) == 0);
2921 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2922 (void) printf("%7s %s\n", "", pathname);
2923 }
2924 free(pathname);
2925 nvlist_free(nverrlist);
2926 }
2927
2928 static void
2929 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2930 int namewidth)
2931 {
2932 uint_t i;
2933 char *name;
2934
2935 if (nspares == 0)
2936 return;
2937
2938 (void) printf(gettext("\tspares\n"));
2939
2940 for (i = 0; i < nspares; i++) {
2941 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2942 print_status_config(zhp, name, spares[i],
2943 namewidth, 2, B_TRUE, B_FALSE);
2944 free(name);
2945 }
2946 }
2947
2948 static void
2949 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2950 int namewidth)
2951 {
2952 uint_t i;
2953 char *name;
2954
2955 if (nl2cache == 0)
2956 return;
2957
2958 (void) printf(gettext("\tcache\n"));
2959
2960 for (i = 0; i < nl2cache; i++) {
2961 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2962 print_status_config(zhp, name, l2cache[i],
2963 namewidth, 2, B_FALSE, B_FALSE);
2964 free(name);
2965 }
2966 }
2967
2968 /*
2969 * Display a summary of pool status. Displays a summary such as:
2970 *
2971 * pool: tank
2972 * status: DEGRADED
2973 * reason: One or more devices ...
2974 * see: http://www.sun.com/msg/ZFS-xxxx-01
2975 * config:
2976 * mirror DEGRADED
2977 * c1t0d0 OK
2978 * c2t0d0 UNAVAIL
2979 *
2980 * When given the '-v' option, we print out the complete config. If the '-e'
2981 * option is specified, then we print out error rate information as well.
2982 */
2983 int
2984 status_callback(zpool_handle_t *zhp, void *data)
2985 {
2986 status_cbdata_t *cbp = data;
2987 nvlist_t *config, *nvroot;
2988 char *msgid;
2989 int reason;
2990 const char *health;
2991 uint_t c;
2992 vdev_stat_t *vs;
2993
2994 config = zpool_get_config(zhp, NULL);
2995 reason = zpool_get_status(zhp, &msgid);
2996
2997 cbp->cb_count++;
2998
2999 /*
3000 * If we were given 'zpool status -x', only report those pools with
3001 * problems.
3002 */
3003 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3004 if (!cbp->cb_allpools) {
3005 (void) printf(gettext("pool '%s' is healthy\n"),
3006 zpool_get_name(zhp));
3007 if (cbp->cb_first)
3008 cbp->cb_first = B_FALSE;
3009 }
3010 return (0);
3011 }
3012
3013 if (cbp->cb_first)
3014 cbp->cb_first = B_FALSE;
3015 else
3016 (void) printf("\n");
3017
3018 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3019 &nvroot) == 0);
3020 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3021 (uint64_t **)&vs, &c) == 0);
3022 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3023
3024 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3025 (void) printf(gettext(" state: %s\n"), health);
3026
3027 switch (reason) {
3028 case ZPOOL_STATUS_MISSING_DEV_R:
3029 (void) printf(gettext("status: One or more devices could not "
3030 "be opened. Sufficient replicas exist for\n\tthe pool to "
3031 "continue functioning in a degraded state.\n"));
3032 (void) printf(gettext("action: Attach the missing device and "
3033 "online it using 'zpool online'.\n"));
3034 break;
3035
3036 case ZPOOL_STATUS_MISSING_DEV_NR:
3037 (void) printf(gettext("status: One or more devices could not "
3038 "be opened. There are insufficient\n\treplicas for the "
3039 "pool to continue functioning.\n"));
3040 (void) printf(gettext("action: Attach the missing device and "
3041 "online it using 'zpool online'.\n"));
3042 break;
3043
3044 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3045 (void) printf(gettext("status: One or more devices could not "
3046 "be used because the label is missing or\n\tinvalid. "
3047 "Sufficient replicas exist for the pool to continue\n\t"
3048 "functioning in a degraded state.\n"));
3049 (void) printf(gettext("action: Replace the device using "
3050 "'zpool replace'.\n"));
3051 break;
3052
3053 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3054 (void) printf(gettext("status: One or more devices could not "
3055 "be used because the label is missing \n\tor invalid. "
3056 "There are insufficient replicas for the pool to "
3057 "continue\n\tfunctioning.\n"));
3058 (void) printf(gettext("action: Destroy and re-create the pool "
3059 "from a backup source.\n"));
3060 break;
3061
3062 case ZPOOL_STATUS_FAILING_DEV:
3063 (void) printf(gettext("status: One or more devices has "
3064 "experienced an unrecoverable error. An\n\tattempt was "
3065 "made to correct the error. Applications are "
3066 "unaffected.\n"));
3067 (void) printf(gettext("action: Determine if the device needs "
3068 "to be replaced, and clear the errors\n\tusing "
3069 "'zpool clear' or replace the device with 'zpool "
3070 "replace'.\n"));
3071 break;
3072
3073 case ZPOOL_STATUS_OFFLINE_DEV:
3074 (void) printf(gettext("status: One or more devices has "
3075 "been taken offline by the administrator.\n\tSufficient "
3076 "replicas exist for the pool to continue functioning in "
3077 "a\n\tdegraded state.\n"));
3078 (void) printf(gettext("action: Online the device using "
3079 "'zpool online' or replace the device with\n\t'zpool "
3080 "replace'.\n"));
3081 break;
3082
3083 case ZPOOL_STATUS_RESILVERING:
3084 (void) printf(gettext("status: One or more devices is "
3085 "currently being resilvered. The pool will\n\tcontinue "
3086 "to function, possibly in a degraded state.\n"));
3087 (void) printf(gettext("action: Wait for the resilver to "
3088 "complete.\n"));
3089 break;
3090
3091 case ZPOOL_STATUS_CORRUPT_DATA:
3092 (void) printf(gettext("status: One or more devices has "
3093 "experienced an error resulting in data\n\tcorruption. "
3094 "Applications may be affected.\n"));
3095 (void) printf(gettext("action: Restore the file in question "
3096 "if possible. Otherwise restore the\n\tentire pool from "
3097 "backup.\n"));
3098 break;
3099
3100 case ZPOOL_STATUS_CORRUPT_POOL:
3101 (void) printf(gettext("status: The pool metadata is corrupted "
3102 "and the pool cannot be opened.\n"));
3103 (void) printf(gettext("action: Destroy and re-create the pool "
3104 "from a backup source.\n"));
3105 break;
3106
3107 case ZPOOL_STATUS_VERSION_OLDER:
3108 (void) printf(gettext("status: The pool is formatted using an "
3109 "older on-disk format. The pool can\n\tstill be used, but "
3110 "some features are unavailable.\n"));
3111 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3112 "upgrade'. Once this is done, the\n\tpool will no longer "
3113 "be accessible on older software versions.\n"));
3114 break;
3115
3116 case ZPOOL_STATUS_VERSION_NEWER:
3117 (void) printf(gettext("status: The pool has been upgraded to a "
3118 "newer, incompatible on-disk version.\n\tThe pool cannot "
3119 "be accessed on this system.\n"));
3120 (void) printf(gettext("action: Access the pool from a system "
3121 "running more recent software, or\n\trestore the pool from "
3122 "backup.\n"));
3123 break;
3124
3125 case ZPOOL_STATUS_FAULTED_DEV_R:
3126 (void) printf(gettext("status: One or more devices are "
3127 "faulted in response to persistent errors.\n\tSufficient "
3128 "replicas exist for the pool to continue functioning "
3129 "in a\n\tdegraded state.\n"));
3130 (void) printf(gettext("action: Replace the faulted device, "
3131 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3132 break;
3133
3134 case ZPOOL_STATUS_FAULTED_DEV_NR:
3135 (void) printf(gettext("status: One or more devices are "
3136 "faulted in response to persistent errors. There are "
3137 "insufficient replicas for the pool to\n\tcontinue "
3138 "functioning.\n"));
3139 (void) printf(gettext("action: Destroy and re-create the pool "
3140 "from a backup source. Manually marking the device\n"
3141 "\trepaired using 'zpool clear' may allow some data "
3142 "to be recovered.\n"));
3143 break;
3144
3145 case ZPOOL_STATUS_IO_FAILURE_WAIT:
3146 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3147 (void) printf(gettext("status: One or more devices are "
3148 "faulted in response to IO failures.\n"));
3149 (void) printf(gettext("action: Make sure the affected devices "
3150 "are connected, then run 'zpool clear'.\n"));
3151 break;
3152
3153 case ZPOOL_STATUS_BAD_LOG:
3154 (void) printf(gettext("status: An intent log record "
3155 "could not be read.\n"
3156 "\tWaiting for adminstrator intervention to fix the "
3157 "faulted pool.\n"));
3158 (void) printf(gettext("action: Either restore the affected "
3159 "device(s) and run 'zpool online',\n"
3160 "\tor ignore the intent log records by running "
3161 "'zpool clear'.\n"));
3162 break;
3163
3164 default:
3165 /*
3166 * The remaining errors can't actually be generated, yet.
3167 */
3168 assert(reason == ZPOOL_STATUS_OK);
3169 }
3170
3171 if (msgid != NULL)
3172 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
3173 msgid);
3174
3175 if (config != NULL) {
3176 int namewidth;
3177 uint64_t nerr;
3178 nvlist_t **spares, **l2cache;
3179 uint_t nspares, nl2cache;
3180
3181
3182 (void) printf(gettext(" scrub: "));
3183 print_scrub_status(nvroot);
3184
3185 namewidth = max_width(zhp, nvroot, 0, 0);
3186 if (namewidth < 10)
3187 namewidth = 10;
3188
3189 (void) printf(gettext("config:\n\n"));
3190 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
3191 "NAME", "STATE", "READ", "WRITE", "CKSUM");
3192 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3193 namewidth, 0, B_FALSE, B_FALSE);
3194 if (num_logs(nvroot) > 0)
3195 print_status_config(zhp, "logs", nvroot, namewidth, 0,
3196 B_FALSE, B_TRUE);
3197
3198 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3199 &l2cache, &nl2cache) == 0)
3200 print_l2cache(zhp, l2cache, nl2cache, namewidth);
3201
3202 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3203 &spares, &nspares) == 0)
3204 print_spares(zhp, spares, nspares, namewidth);
3205
3206 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3207 &nerr) == 0) {
3208 nvlist_t *nverrlist = NULL;
3209
3210 /*
3211 * If the approximate error count is small, get a
3212 * precise count by fetching the entire log and
3213 * uniquifying the results.
3214 */
3215 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3216 zpool_get_errlog(zhp, &nverrlist) == 0) {
3217 nvpair_t *elem;
3218
3219 elem = NULL;
3220 nerr = 0;
3221 while ((elem = nvlist_next_nvpair(nverrlist,
3222 elem)) != NULL) {
3223 nerr++;
3224 }
3225 }
3226 nvlist_free(nverrlist);
3227
3228 (void) printf("\n");
3229
3230 if (nerr == 0)
3231 (void) printf(gettext("errors: No known data "
3232 "errors\n"));
3233 else if (!cbp->cb_verbose)
3234 (void) printf(gettext("errors: %llu data "
3235 "errors, use '-v' for a list\n"),
3236 (u_longlong_t)nerr);
3237 else
3238 print_error_log(zhp);
3239 }
3240 } else {
3241 (void) printf(gettext("config: The configuration cannot be "
3242 "determined.\n"));
3243 }
3244
3245 return (0);
3246 }
3247
3248 /*
3249 * zpool status [-vx] [pool] ...
3250 *
3251 * -v Display complete error logs
3252 * -x Display only pools with potential problems
3253 *
3254 * Describes the health status of all pools or some subset.
3255 */
3256 int
3257 zpool_do_status(int argc, char **argv)
3258 {
3259 int c;
3260 int ret;
3261 status_cbdata_t cb = { 0 };
3262
3263 /* check options */
3264 while ((c = getopt(argc, argv, "vx")) != -1) {
3265 switch (c) {
3266 case 'v':
3267 cb.cb_verbose = B_TRUE;
3268 break;
3269 case 'x':
3270 cb.cb_explain = B_TRUE;
3271 break;
3272 case '?':
3273 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3274 optopt);
3275 usage(B_FALSE);
3276 }
3277 }
3278
3279 argc -= optind;
3280 argv += optind;
3281
3282 cb.cb_first = B_TRUE;
3283
3284 if (argc == 0)
3285 cb.cb_allpools = B_TRUE;
3286
3287 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3288
3289 if (argc == 0 && cb.cb_count == 0)
3290 (void) printf(gettext("no pools available\n"));
3291 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3292 (void) printf(gettext("all pools are healthy\n"));
3293
3294 return (ret);
3295 }
3296
3297 typedef struct upgrade_cbdata {
3298 int cb_all;
3299 int cb_first;
3300 int cb_newer;
3301 int cb_argc;
3302 uint64_t cb_version;
3303 char **cb_argv;
3304 } upgrade_cbdata_t;
3305
3306 static int
3307 upgrade_cb(zpool_handle_t *zhp, void *arg)
3308 {
3309 upgrade_cbdata_t *cbp = arg;
3310 nvlist_t *config;
3311 uint64_t version;
3312 int ret = 0;
3313
3314 config = zpool_get_config(zhp, NULL);
3315 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3316 &version) == 0);
3317
3318 if (!cbp->cb_newer && version < SPA_VERSION) {
3319 if (!cbp->cb_all) {
3320 if (cbp->cb_first) {
3321 (void) printf(gettext("The following pools are "
3322 "out of date, and can be upgraded. After "
3323 "being\nupgraded, these pools will no "
3324 "longer be accessible by older software "
3325 "versions.\n\n"));
3326 (void) printf(gettext("VER POOL\n"));
3327 (void) printf(gettext("--- ------------\n"));
3328 cbp->cb_first = B_FALSE;
3329 }
3330
3331 (void) printf("%2llu %s\n", (u_longlong_t)version,
3332 zpool_get_name(zhp));
3333 } else {
3334 cbp->cb_first = B_FALSE;
3335 ret = zpool_upgrade(zhp, cbp->cb_version);
3336 if (!ret) {
3337 (void) printf(gettext("Successfully upgraded "
3338 "'%s'\n\n"), zpool_get_name(zhp));
3339 }
3340 }
3341 } else if (cbp->cb_newer && version > SPA_VERSION) {
3342 assert(!cbp->cb_all);
3343
3344 if (cbp->cb_first) {
3345 (void) printf(gettext("The following pools are "
3346 "formatted using a newer software version and\n"
3347 "cannot be accessed on the current system.\n\n"));
3348 (void) printf(gettext("VER POOL\n"));
3349 (void) printf(gettext("--- ------------\n"));
3350 cbp->cb_first = B_FALSE;
3351 }
3352
3353 (void) printf("%2llu %s\n", (u_longlong_t)version,
3354 zpool_get_name(zhp));
3355 }
3356
3357 zpool_close(zhp);
3358 return (ret);
3359 }
3360
3361 /* ARGSUSED */
3362 static int
3363 upgrade_one(zpool_handle_t *zhp, void *data)
3364 {
3365 upgrade_cbdata_t *cbp = data;
3366 uint64_t cur_version;
3367 int ret;
3368
3369 if (strcmp("log", zpool_get_name(zhp)) == 0) {
3370 (void) printf(gettext("'log' is now a reserved word\n"
3371 "Pool 'log' must be renamed using export and import"
3372 " to upgrade.\n"));
3373 return (1);
3374 }
3375
3376 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3377 if (cur_version > cbp->cb_version) {
3378 (void) printf(gettext("Pool '%s' is already formatted "
3379 "using more current version '%llu'.\n"),
3380 zpool_get_name(zhp), cur_version);
3381 return (0);
3382 }
3383 if (cur_version == cbp->cb_version) {
3384 (void) printf(gettext("Pool '%s' is already formatted "
3385 "using the current version.\n"), zpool_get_name(zhp));
3386 return (0);
3387 }
3388
3389 ret = zpool_upgrade(zhp, cbp->cb_version);
3390
3391 if (!ret) {
3392 (void) printf(gettext("Successfully upgraded '%s' "
3393 "from version %llu to version %llu\n\n"),
3394 zpool_get_name(zhp), (u_longlong_t)cur_version,
3395 (u_longlong_t)cbp->cb_version);
3396 }
3397
3398 return (ret != 0);
3399 }
3400
3401 /*
3402 * zpool upgrade
3403 * zpool upgrade -v
3404 * zpool upgrade [-V version] <-a | pool ...>
3405 *
3406 * With no arguments, display downrev'd ZFS pool available for upgrade.
3407 * Individual pools can be upgraded by specifying the pool, and '-a' will
3408 * upgrade all pools.
3409 */
3410 int
3411 zpool_do_upgrade(int argc, char **argv)
3412 {
3413 int c;
3414 upgrade_cbdata_t cb = { 0 };
3415 int ret = 0;
3416 boolean_t showversions = B_FALSE;
3417 char *end;
3418
3419
3420 /* check options */
3421 while ((c = getopt(argc, argv, "avV:")) != -1) {
3422 switch (c) {
3423 case 'a':
3424 cb.cb_all = B_TRUE;
3425 break;
3426 case 'v':
3427 showversions = B_TRUE;
3428 break;
3429 case 'V':
3430 cb.cb_version = strtoll(optarg, &end, 10);
3431 if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3432 cb.cb_version < SPA_VERSION_1) {
3433 (void) fprintf(stderr,
3434 gettext("invalid version '%s'\n"), optarg);
3435 usage(B_FALSE);
3436 }
3437 break;
3438 case '?':
3439 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3440 optopt);
3441 usage(B_FALSE);
3442 }
3443 }
3444
3445 cb.cb_argc = argc;
3446 cb.cb_argv = argv;
3447 argc -= optind;
3448 argv += optind;
3449
3450 if (cb.cb_version == 0) {
3451 cb.cb_version = SPA_VERSION;
3452 } else if (!cb.cb_all && argc == 0) {
3453 (void) fprintf(stderr, gettext("-V option is "
3454 "incompatible with other arguments\n"));
3455 usage(B_FALSE);
3456 }
3457
3458 if (showversions) {
3459 if (cb.cb_all || argc != 0) {
3460 (void) fprintf(stderr, gettext("-v option is "
3461 "incompatible with other arguments\n"));
3462 usage(B_FALSE);
3463 }
3464 } else if (cb.cb_all) {
3465 if (argc != 0) {
3466 (void) fprintf(stderr, gettext("-a option should not "
3467 "be used along with a pool name\n"));
3468 usage(B_FALSE);
3469 }
3470 }
3471
3472 (void) printf(gettext("This system is currently running "
3473 "ZFS pool version %llu.\n\n"), SPA_VERSION);
3474 cb.cb_first = B_TRUE;
3475 if (showversions) {
3476 (void) printf(gettext("The following versions are "
3477 "supported:\n\n"));
3478 (void) printf(gettext("VER DESCRIPTION\n"));
3479 (void) printf("--- -----------------------------------------"
3480 "---------------\n");
3481 (void) printf(gettext(" 1 Initial ZFS version\n"));
3482 (void) printf(gettext(" 2 Ditto blocks "
3483 "(replicated metadata)\n"));
3484 (void) printf(gettext(" 3 Hot spares and double parity "
3485 "RAID-Z\n"));
3486 (void) printf(gettext(" 4 zpool history\n"));
3487 (void) printf(gettext(" 5 Compression using the gzip "
3488 "algorithm\n"));
3489 (void) printf(gettext(" 6 bootfs pool property\n"));
3490 (void) printf(gettext(" 7 Separate intent log devices\n"));
3491 (void) printf(gettext(" 8 Delegated administration\n"));
3492 (void) printf(gettext(" 9 refquota and refreservation "
3493 "properties\n"));
3494 (void) printf(gettext(" 10 Cache devices\n"));
3495 (void) printf(gettext(" 11 Improved scrub performance\n"));
3496 (void) printf(gettext(" 12 Snapshot properties\n"));
3497 (void) printf(gettext(" 13 snapused property\n"));
3498 (void) printf(gettext(" 14 passthrough-x aclinherit "
3499 "support\n"));
3500 (void) printf(gettext("For more information on a particular "
3501 "version, including supported releases, see:\n\n"));
3502 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3503 "version/N\n\n");
3504 (void) printf(gettext("Where 'N' is the version number.\n"));
3505 } else if (argc == 0) {
3506 int notfound;
3507
3508 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3509 notfound = cb.cb_first;
3510
3511 if (!cb.cb_all && ret == 0) {
3512 if (!cb.cb_first)
3513 (void) printf("\n");
3514 cb.cb_first = B_TRUE;
3515 cb.cb_newer = B_TRUE;
3516 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3517 if (!cb.cb_first) {
3518 notfound = B_FALSE;
3519 (void) printf("\n");
3520 }
3521 }
3522
3523 if (ret == 0) {
3524 if (notfound)
3525 (void) printf(gettext("All pools are formatted "
3526 "using this version.\n"));
3527 else if (!cb.cb_all)
3528 (void) printf(gettext("Use 'zpool upgrade -v' "
3529 "for a list of available versions and "
3530 "their associated\nfeatures.\n"));
3531 }
3532 } else {
3533 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3534 upgrade_one, &cb);
3535 }
3536
3537 return (ret);
3538 }
3539
3540 typedef struct hist_cbdata {
3541 boolean_t first;
3542 int longfmt;
3543 int internal;
3544 } hist_cbdata_t;
3545
3546 char *hist_event_table[LOG_END] = {
3547 "invalid event",
3548 "pool create",
3549 "vdev add",
3550 "pool remove",
3551 "pool destroy",
3552 "pool export",
3553 "pool import",
3554 "vdev attach",
3555 "vdev replace",
3556 "vdev detach",
3557 "vdev online",
3558 "vdev offline",
3559 "vdev upgrade",
3560 "pool clear",
3561 "pool scrub",
3562 "pool property set",
3563 "create",
3564 "clone",
3565 "destroy",
3566 "destroy_begin_sync",
3567 "inherit",
3568 "property set",
3569 "quota set",
3570 "permission update",
3571 "permission remove",
3572 "permission who remove",
3573 "promote",
3574 "receive",
3575 "rename",
3576 "reservation set",
3577 "replay_inc_sync",
3578 "replay_full_sync",
3579 "rollback",
3580 "snapshot",
3581 "filesystem version upgrade",
3582 "refquota set",
3583 "refreservation set",
3584 "pool scrub done",
3585 };
3586
3587 /*
3588 * Print out the command history for a specific pool.
3589 */
3590 static int
3591 get_history_one(zpool_handle_t *zhp, void *data)
3592 {
3593 nvlist_t *nvhis;
3594 nvlist_t **records;
3595 uint_t numrecords;
3596 char *cmdstr;
3597 char *pathstr;
3598 uint64_t dst_time;
3599 time_t tsec;
3600 struct tm t;
3601 char tbuf[30];
3602 int ret, i;
3603 uint64_t who;
3604 struct passwd *pwd;
3605 char *hostname;
3606 char *zonename;
3607 char internalstr[MAXPATHLEN];
3608 hist_cbdata_t *cb = (hist_cbdata_t *)data;
3609 uint64_t txg;
3610 uint64_t ievent;
3611
3612 cb->first = B_FALSE;
3613
3614 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3615
3616 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3617 return (ret);
3618
3619 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3620 &records, &numrecords) == 0);
3621 for (i = 0; i < numrecords; i++) {
3622 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3623 &dst_time) != 0)
3624 continue;
3625
3626 /* is it an internal event or a standard event? */
3627 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3628 &cmdstr) != 0) {
3629 if (cb->internal == 0)
3630 continue;
3631
3632 if (nvlist_lookup_uint64(records[i],
3633 ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3634 continue;
3635 verify(nvlist_lookup_uint64(records[i],
3636 ZPOOL_HIST_TXG, &txg) == 0);
3637 verify(nvlist_lookup_string(records[i],
3638 ZPOOL_HIST_INT_STR, &pathstr) == 0);
3639 if (ievent >= LOG_END)
3640 continue;
3641 (void) snprintf(internalstr,
3642 sizeof (internalstr),
3643 "[internal %s txg:%lld] %s",
3644 hist_event_table[ievent], txg,
3645 pathstr);
3646 cmdstr = internalstr;
3647 }
3648 tsec = dst_time;
3649 (void) localtime_r(&tsec, &t);
3650 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3651 (void) printf("%s %s", tbuf, cmdstr);
3652
3653 if (!cb->longfmt) {
3654 (void) printf("\n");
3655 continue;
3656 }
3657 (void) printf(" [");
3658 if (nvlist_lookup_uint64(records[i],
3659 ZPOOL_HIST_WHO, &who) == 0) {
3660 pwd = getpwuid((uid_t)who);
3661 if (pwd)
3662 (void) printf("user %s on",
3663 pwd->pw_name);
3664 else
3665 (void) printf("user %d on",
3666 (int)who);
3667 } else {
3668 (void) printf(gettext("no info]\n"));
3669 continue;
3670 }
3671 if (nvlist_lookup_string(records[i],
3672 ZPOOL_HIST_HOST, &hostname) == 0) {
3673 (void) printf(" %s", hostname);
3674 }
3675 if (nvlist_lookup_string(records[i],
3676 ZPOOL_HIST_ZONE, &zonename) == 0) {
3677 (void) printf(":%s", zonename);
3678 }
3679
3680 (void) printf("]");
3681 (void) printf("\n");
3682 }
3683 (void) printf("\n");
3684 nvlist_free(nvhis);
3685
3686 return (ret);
3687 }
3688
3689 /*
3690 * zpool history <pool>
3691 *
3692 * Displays the history of commands that modified pools.
3693 */
3694
3695
3696 int
3697 zpool_do_history(int argc, char **argv)
3698 {
3699 hist_cbdata_t cbdata = { 0 };
3700 int ret;
3701 int c;
3702
3703 cbdata.first = B_TRUE;
3704 /* check options */
3705 while ((c = getopt(argc, argv, "li")) != -1) {
3706 switch (c) {
3707 case 'l':
3708 cbdata.longfmt = 1;
3709 break;
3710 case 'i':
3711 cbdata.internal = 1;
3712 break;
3713 case '?':
3714 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3715 optopt);
3716 usage(B_FALSE);
3717 }
3718 }
3719 argc -= optind;
3720 argv += optind;
3721
3722 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
3723 &cbdata);
3724
3725 if (argc == 0 && cbdata.first == B_TRUE) {
3726 (void) printf(gettext("no pools available\n"));
3727 return (0);
3728 }
3729
3730 return (ret);
3731 }
3732
3733 static int
3734 get_callback(zpool_handle_t *zhp, void *data)
3735 {
3736 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3737 char value[MAXNAMELEN];
3738 zprop_source_t srctype;
3739 zprop_list_t *pl;
3740
3741 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3742
3743 /*
3744 * Skip the special fake placeholder. This will also skip
3745 * over the name property when 'all' is specified.
3746 */
3747 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3748 pl == cbp->cb_proplist)
3749 continue;
3750
3751 if (zpool_get_prop(zhp, pl->pl_prop,
3752 value, sizeof (value), &srctype) != 0)
3753 continue;
3754
3755 zprop_print_one_property(zpool_get_name(zhp), cbp,
3756 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3757 }
3758 return (0);
3759 }
3760
3761 int
3762 zpool_do_get(int argc, char **argv)
3763 {
3764 zprop_get_cbdata_t cb = { 0 };
3765 zprop_list_t fake_name = { 0 };
3766 int ret;
3767
3768 if (argc < 3)
3769 usage(B_FALSE);
3770
3771 cb.cb_first = B_TRUE;
3772 cb.cb_sources = ZPROP_SRC_ALL;
3773 cb.cb_columns[0] = GET_COL_NAME;
3774 cb.cb_columns[1] = GET_COL_PROPERTY;
3775 cb.cb_columns[2] = GET_COL_VALUE;
3776 cb.cb_columns[3] = GET_COL_SOURCE;
3777 cb.cb_type = ZFS_TYPE_POOL;
3778
3779 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
3780 ZFS_TYPE_POOL) != 0)
3781 usage(B_FALSE);
3782
3783 if (cb.cb_proplist != NULL) {
3784 fake_name.pl_prop = ZPOOL_PROP_NAME;
3785 fake_name.pl_width = strlen(gettext("NAME"));
3786 fake_name.pl_next = cb.cb_proplist;
3787 cb.cb_proplist = &fake_name;
3788 }
3789
3790 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3791 get_callback, &cb);
3792
3793 if (cb.cb_proplist == &fake_name)
3794 zprop_free_list(fake_name.pl_next);
3795 else
3796 zprop_free_list(cb.cb_proplist);
3797
3798 return (ret);
3799 }
3800
3801 typedef struct set_cbdata {
3802 char *cb_propname;
3803 char *cb_value;
3804 boolean_t cb_any_successful;
3805 } set_cbdata_t;
3806
3807 int
3808 set_callback(zpool_handle_t *zhp, void *data)
3809 {
3810 int error;
3811 set_cbdata_t *cb = (set_cbdata_t *)data;
3812
3813 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3814
3815 if (!error)
3816 cb->cb_any_successful = B_TRUE;
3817
3818 return (error);
3819 }
3820
3821 int
3822 zpool_do_set(int argc, char **argv)
3823 {
3824 set_cbdata_t cb = { 0 };
3825 int error;
3826
3827 if (argc > 1 && argv[1][0] == '-') {
3828 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3829 argv[1][1]);
3830 usage(B_FALSE);
3831 }
3832
3833 if (argc < 2) {
3834 (void) fprintf(stderr, gettext("missing property=value "
3835 "argument\n"));
3836 usage(B_FALSE);
3837 }
3838
3839 if (argc < 3) {
3840 (void) fprintf(stderr, gettext("missing pool name\n"));
3841 usage(B_FALSE);
3842 }
3843
3844 if (argc > 3) {
3845 (void) fprintf(stderr, gettext("too many pool names\n"));
3846 usage(B_FALSE);
3847 }
3848
3849 cb.cb_propname = argv[1];
3850 cb.cb_value = strchr(cb.cb_propname, '=');
3851 if (cb.cb_value == NULL) {
3852 (void) fprintf(stderr, gettext("missing value in "
3853 "property=value argument\n"));
3854 usage(B_FALSE);
3855 }
3856
3857 *(cb.cb_value) = '\0';
3858 cb.cb_value++;
3859
3860 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3861 set_callback, &cb);
3862
3863 return (error);
3864 }
3865
3866 static int
3867 find_command_idx(char *command, int *idx)
3868 {
3869 int i;
3870
3871 for (i = 0; i < NCOMMAND; i++) {
3872 if (command_table[i].name == NULL)
3873 continue;
3874
3875 if (strcmp(command, command_table[i].name) == 0) {
3876 *idx = i;
3877 return (0);
3878 }
3879 }
3880 return (1);
3881 }
3882
3883 int
3884 main(int argc, char **argv)
3885 {
3886 int ret;
3887 int i;
3888 char *cmdname;
3889
3890 (void) setlocale(LC_ALL, "");
3891 (void) textdomain(TEXT_DOMAIN);
3892
3893 if ((g_zfs = libzfs_init()) == NULL) {
3894 (void) fprintf(stderr, gettext("internal error: failed to "
3895 "initialize ZFS library\n"));
3896 return (1);
3897 }
3898
3899 libzfs_print_on_error(g_zfs, B_TRUE);
3900
3901 opterr = 0;
3902
3903 /*
3904 * Make sure the user has specified some command.
3905 */
3906 if (argc < 2) {
3907 (void) fprintf(stderr, gettext("missing command\n"));
3908 usage(B_FALSE);
3909 }
3910
3911 cmdname = argv[1];
3912
3913 /*
3914 * Special case '-?'
3915 */
3916 if (strcmp(cmdname, "-?") == 0)
3917 usage(B_TRUE);
3918
3919 zpool_set_history_str("zpool", argc, argv, history_str);
3920 verify(zpool_stage_history(g_zfs, history_str) == 0);
3921
3922 /*
3923 * Run the appropriate command.
3924 */
3925 if (find_command_idx(cmdname, &i) == 0) {
3926 current_command = &command_table[i];
3927 ret = command_table[i].func(argc - 1, argv + 1);
3928 } else if (strchr(cmdname, '=')) {
3929 verify(find_command_idx("set", &i) == 0);
3930 current_command = &command_table[i];
3931 ret = command_table[i].func(argc, argv);
3932 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3933 /*
3934 * 'freeze' is a vile debugging abomination, so we treat
3935 * it as such.
3936 */
3937 char buf[16384];
3938 int fd = open(ZFS_DEV, O_RDWR);
3939 (void) strcpy((void *)buf, argv[2]);
3940 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3941 } else {
3942 (void) fprintf(stderr, gettext("unrecognized "
3943 "command '%s'\n"), cmdname);
3944 usage(B_FALSE);
3945 }
3946
3947 libzfs_fini(g_zfs);
3948
3949 /*
3950 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3951 * for the purposes of running ::findleaks.
3952 */
3953 if (getenv("ZFS_ABORT") != NULL) {
3954 (void) printf("dumping core by request\n");
3955 abort();
3956 }
3957
3958 return (ret);
3959 }