]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
zfs: fix -fno-common issues
[FreeBSD/FreeBSD.git] / cddl / contrib / opensolaris / cmd / zpool / zpool_main.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
25  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
26  * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
27  * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
28  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
29  * Copyright 2016 Nexenta Systems, Inc.
30  * Copyright (c) 2017 Datto Inc.
31  * Copyright (c) 2017, Intel Corporation.
32  */
33
34 #include <solaris.h>
35 #include <assert.h>
36 #include <ctype.h>
37 #include <dirent.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <getopt.h>
41 #include <libgen.h>
42 #include <libintl.h>
43 #include <libuutil.h>
44 #include <locale.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <strings.h>
49 #include <unistd.h>
50 #include <priv.h>
51 #include <pwd.h>
52 #include <zone.h>
53 #include <sys/time.h>
54 #include <zfs_prop.h>
55 #include <sys/fs/zfs.h>
56 #include <sys/stat.h>
57 #include <sys/debug.h>
58
59 #include <libzfs.h>
60
61 #include "zpool_util.h"
62 #include "zfs_comutil.h"
63 #include "zfeature_common.h"
64
65 #include "statcommon.h"
66
67 libzfs_handle_t *g_zfs;
68
69 static int zpool_do_create(int, char **);
70 static int zpool_do_destroy(int, char **);
71
72 static int zpool_do_add(int, char **);
73 static int zpool_do_remove(int, char **);
74 static int zpool_do_labelclear(int, char **);
75
76 static int zpool_do_checkpoint(int, char **);
77
78 static int zpool_do_list(int, char **);
79 static int zpool_do_iostat(int, char **);
80 static int zpool_do_status(int, char **);
81
82 static int zpool_do_online(int, char **);
83 static int zpool_do_offline(int, char **);
84 static int zpool_do_clear(int, char **);
85 static int zpool_do_reopen(int, char **);
86
87 static int zpool_do_reguid(int, char **);
88
89 static int zpool_do_attach(int, char **);
90 static int zpool_do_detach(int, char **);
91 static int zpool_do_replace(int, char **);
92 static int zpool_do_split(int, char **);
93
94 static int zpool_do_initialize(int, char **);
95 static int zpool_do_scrub(int, char **);
96
97 static int zpool_do_import(int, char **);
98 static int zpool_do_export(int, char **);
99
100 static int zpool_do_upgrade(int, char **);
101
102 static int zpool_do_history(int, char **);
103
104 static int zpool_do_get(int, char **);
105 static int zpool_do_set(int, char **);
106
107 static int zpool_do_sync(int, char **);
108
109 /*
110  * These libumem hooks provide a reasonable set of defaults for the allocator's
111  * debugging facilities.
112  */
113
114 #ifdef DEBUG
115 const char *
116 _umem_debug_init(void)
117 {
118         return ("default,verbose"); /* $UMEM_DEBUG setting */
119 }
120
121 const char *
122 _umem_logging_init(void)
123 {
124         return ("fail,contents"); /* $UMEM_LOGGING setting */
125 }
126 #endif
127
128 typedef enum {
129         HELP_ADD,
130         HELP_ATTACH,
131         HELP_CLEAR,
132         HELP_CREATE,
133         HELP_CHECKPOINT,
134         HELP_DESTROY,
135         HELP_DETACH,
136         HELP_EXPORT,
137         HELP_HISTORY,
138         HELP_IMPORT,
139         HELP_IOSTAT,
140         HELP_LABELCLEAR,
141         HELP_LIST,
142         HELP_OFFLINE,
143         HELP_ONLINE,
144         HELP_REPLACE,
145         HELP_REMOVE,
146         HELP_INITIALIZE,
147         HELP_SCRUB,
148         HELP_STATUS,
149         HELP_UPGRADE,
150         HELP_GET,
151         HELP_SET,
152         HELP_SPLIT,
153         HELP_SYNC,
154         HELP_REGUID,
155         HELP_REOPEN
156 } zpool_help_t;
157
158
159 typedef struct zpool_command {
160         const char      *name;
161         int             (*func)(int, char **);
162         zpool_help_t    usage;
163 } zpool_command_t;
164
165 /*
166  * Master command table.  Each ZFS command has a name, associated function, and
167  * usage message.  The usage messages need to be internationalized, so we have
168  * to have a function to return the usage message based on a command index.
169  *
170  * These commands are organized according to how they are displayed in the usage
171  * message.  An empty command (one with a NULL name) indicates an empty line in
172  * the generic usage message.
173  */
174 static zpool_command_t command_table[] = {
175         { "create",     zpool_do_create,        HELP_CREATE             },
176         { "destroy",    zpool_do_destroy,       HELP_DESTROY            },
177         { NULL },
178         { "add",        zpool_do_add,           HELP_ADD                },
179         { "remove",     zpool_do_remove,        HELP_REMOVE             },
180         { NULL },
181         { "labelclear", zpool_do_labelclear,    HELP_LABELCLEAR         },
182         { NULL },
183         { "checkpoint", zpool_do_checkpoint,    HELP_CHECKPOINT         },
184         { NULL },
185         { "list",       zpool_do_list,          HELP_LIST               },
186         { "iostat",     zpool_do_iostat,        HELP_IOSTAT             },
187         { "status",     zpool_do_status,        HELP_STATUS             },
188         { NULL },
189         { "online",     zpool_do_online,        HELP_ONLINE             },
190         { "offline",    zpool_do_offline,       HELP_OFFLINE            },
191         { "clear",      zpool_do_clear,         HELP_CLEAR              },
192         { "reopen",     zpool_do_reopen,        HELP_REOPEN             },
193         { NULL },
194         { "attach",     zpool_do_attach,        HELP_ATTACH             },
195         { "detach",     zpool_do_detach,        HELP_DETACH             },
196         { "replace",    zpool_do_replace,       HELP_REPLACE            },
197         { "split",      zpool_do_split,         HELP_SPLIT              },
198         { NULL },
199         { "initialize", zpool_do_initialize,    HELP_INITIALIZE         },
200         { "scrub",      zpool_do_scrub,         HELP_SCRUB              },
201         { NULL },
202         { "import",     zpool_do_import,        HELP_IMPORT             },
203         { "export",     zpool_do_export,        HELP_EXPORT             },
204         { "upgrade",    zpool_do_upgrade,       HELP_UPGRADE            },
205         { "reguid",     zpool_do_reguid,        HELP_REGUID             },
206         { NULL },
207         { "history",    zpool_do_history,       HELP_HISTORY            },
208         { "get",        zpool_do_get,           HELP_GET                },
209         { "set",        zpool_do_set,           HELP_SET                },
210         { "sync",       zpool_do_sync,          HELP_SYNC               },
211 };
212
213 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
214
215 #define VDEV_ALLOC_CLASS_LOGS   "logs"
216
217 static zpool_command_t *current_command;
218 static char history_str[HIS_MAX_RECORD_LEN];
219 static boolean_t log_history = B_TRUE;
220 static uint_t timestamp_fmt = NODATE;
221
222 static const char *
223 get_usage(zpool_help_t idx)
224 {
225         switch (idx) {
226         case HELP_ADD:
227                 return (gettext("\tadd [-fgLnP] <pool> <vdev> ...\n"));
228         case HELP_ATTACH:
229                 return (gettext("\tattach [-f] <pool> <device> "
230                     "<new-device>\n"));
231         case HELP_CLEAR:
232                 return (gettext("\tclear [-nF] <pool> [device]\n"));
233         case HELP_CREATE:
234                 return (gettext("\tcreate [-fnd] [-B] "
235                     "[-o property=value] ... \n"
236                     "\t    [-O file-system-property=value] ...\n"
237                     "\t    [-m mountpoint] [-R root] [-t tempname] "
238                     "<pool> <vdev> ...\n"));
239         case HELP_CHECKPOINT:
240                 return (gettext("\tcheckpoint [--discard] <pool> ...\n"));
241         case HELP_DESTROY:
242                 return (gettext("\tdestroy [-f] <pool>\n"));
243         case HELP_DETACH:
244                 return (gettext("\tdetach <pool> <device>\n"));
245         case HELP_EXPORT:
246                 return (gettext("\texport [-f] <pool> ...\n"));
247         case HELP_HISTORY:
248                 return (gettext("\thistory [-il] [<pool>] ...\n"));
249         case HELP_IMPORT:
250                 return (gettext("\timport [-d dir] [-D]\n"
251                     "\timport [-o mntopts] [-o property=value] ... \n"
252                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
253                     "[-R root] [-F [-n]] -a\n"
254                     "\timport [-o mntopts] [-o property=value] ... \n"
255                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
256                     "[-R root] [-F [-n]] [-t]\n"
257                     "\t    [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
258         case HELP_IOSTAT:
259                 return (gettext("\tiostat [-gLPv] [-T d|u] [pool] ... "
260                     "[interval [count]]\n"));
261         case HELP_LABELCLEAR:
262                 return (gettext("\tlabelclear [-f] <vdev>\n"));
263         case HELP_LIST:
264                 return (gettext("\tlist [-gHLpPv] [-o property[,...]] "
265                     "[-T d|u] [pool] ... [interval [count]]\n"));
266         case HELP_OFFLINE:
267                 return (gettext("\toffline [-t] <pool> <device> ...\n"));
268         case HELP_ONLINE:
269                 return (gettext("\tonline [-e] <pool> <device> ...\n"));
270         case HELP_REPLACE:
271                 return (gettext("\treplace [-f] <pool> <device> "
272                     "[new-device]\n"));
273         case HELP_REMOVE:
274                 return (gettext("\tremove [-nps] <pool> <device> ...\n"));
275         case HELP_REOPEN:
276                 return (gettext("\treopen <pool>\n"));
277         case HELP_INITIALIZE:
278                 return (gettext("\tinitialize [-cs] <pool> [<device> ...]\n"));
279         case HELP_SCRUB:
280                 return (gettext("\tscrub [-s | -p] <pool> ...\n"));
281         case HELP_STATUS:
282                 return (gettext("\tstatus [-DgLPvx] [-T d|u] [pool] ... "
283                     "[interval [count]]\n"));
284         case HELP_UPGRADE:
285                 return (gettext("\tupgrade [-v]\n"
286                     "\tupgrade [-V version] <-a | pool ...>\n"));
287         case HELP_GET:
288                 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
289                     "<\"all\" | property[,...]> <pool> ...\n"));
290         case HELP_SET:
291                 return (gettext("\tset <property=value> <pool> \n"));
292         case HELP_SPLIT:
293                 return (gettext("\tsplit [-gLnP] [-R altroot] [-o mntopts]\n"
294                     "\t    [-o property=value] <pool> <newpool> "
295                     "[<device> ...]\n"));
296         case HELP_REGUID:
297                 return (gettext("\treguid <pool>\n"));
298         case HELP_SYNC:
299                 return (gettext("\tsync [pool] ...\n"));
300         }
301
302         abort();
303         /* NOTREACHED */
304 }
305
306
307 /*
308  * Callback routine that will print out a pool property value.
309  */
310 static int
311 print_prop_cb(int prop, void *cb)
312 {
313         FILE *fp = cb;
314
315         (void) fprintf(fp, "\t%-19s  ", zpool_prop_to_name(prop));
316
317         if (zpool_prop_readonly(prop))
318                 (void) fprintf(fp, "  NO   ");
319         else
320                 (void) fprintf(fp, " YES   ");
321
322         if (zpool_prop_values(prop) == NULL)
323                 (void) fprintf(fp, "-\n");
324         else
325                 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
326
327         return (ZPROP_CONT);
328 }
329
330 /*
331  * Display usage message.  If we're inside a command, display only the usage for
332  * that command.  Otherwise, iterate over the entire command table and display
333  * a complete usage message.
334  */
335 void
336 usage(boolean_t requested)
337 {
338         FILE *fp = requested ? stdout : stderr;
339
340         if (current_command == NULL) {
341                 int i;
342
343                 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
344                 (void) fprintf(fp,
345                     gettext("where 'command' is one of the following:\n\n"));
346
347                 for (i = 0; i < NCOMMAND; i++) {
348                         if (command_table[i].name == NULL)
349                                 (void) fprintf(fp, "\n");
350                         else
351                                 (void) fprintf(fp, "%s",
352                                     get_usage(command_table[i].usage));
353                 }
354         } else {
355                 (void) fprintf(fp, gettext("usage:\n"));
356                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
357         }
358
359         if (current_command != NULL &&
360             ((strcmp(current_command->name, "set") == 0) ||
361             (strcmp(current_command->name, "get") == 0) ||
362             (strcmp(current_command->name, "list") == 0))) {
363
364                 (void) fprintf(fp,
365                     gettext("\nthe following properties are supported:\n"));
366
367                 (void) fprintf(fp, "\n\t%-19s  %s   %s\n\n",
368                     "PROPERTY", "EDIT", "VALUES");
369
370                 /* Iterate over all properties */
371                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
372                     ZFS_TYPE_POOL);
373
374                 (void) fprintf(fp, "\t%-19s   ", "feature@...");
375                 (void) fprintf(fp, "YES   disabled | enabled | active\n");
376
377                 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
378                     "appended with a feature name.\nSee zpool-features(7).\n"));
379         }
380
381         /*
382          * See comments at end of main().
383          */
384         if (getenv("ZFS_ABORT") != NULL) {
385                 (void) printf("dumping core by request\n");
386                 abort();
387         }
388
389         exit(requested ? 0 : 2);
390 }
391
392 /*
393  * print a pool vdev config for dry runs
394  */
395 static void
396 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
397     const char *match, int name_flags)
398 {
399         nvlist_t **child;
400         uint_t c, children;
401         char *vname;
402         boolean_t printed = B_FALSE;
403
404         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
405             &child, &children) != 0) {
406                 if (name != NULL)
407                         (void) printf("\t%*s%s\n", indent, "", name);
408                 return;
409         }
410
411         for (c = 0; c < children; c++) {
412                 uint64_t is_log = B_FALSE;
413                 char *class = "";
414
415                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
416                     &is_log);
417                 if (is_log)
418                         class = VDEV_ALLOC_BIAS_LOG;
419                 (void) nvlist_lookup_string(child[c],
420                     ZPOOL_CONFIG_ALLOCATION_BIAS, &class);
421                 if (strcmp(match, class) != 0)
422                         continue;
423
424                 if (!printed && name != NULL) {
425                         (void) printf("\t%*s%s\n", indent, "", name);
426                         printed = B_TRUE;
427                 }
428                 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
429                 print_vdev_tree(zhp, vname, child[c], indent + 2, "",
430                     name_flags);
431                 free(vname);
432         }
433 }
434
435 static boolean_t
436 prop_list_contains_feature(nvlist_t *proplist)
437 {
438         nvpair_t *nvp;
439         for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
440             nvp = nvlist_next_nvpair(proplist, nvp)) {
441                 if (zpool_prop_feature(nvpair_name(nvp)))
442                         return (B_TRUE);
443         }
444         return (B_FALSE);
445 }
446
447 /*
448  * Add a property pair (name, string-value) into a property nvlist.
449  */
450 static int
451 add_prop_list(const char *propname, char *propval, nvlist_t **props,
452     boolean_t poolprop)
453 {
454         zpool_prop_t prop = ZPROP_INVAL;
455         zfs_prop_t fprop;
456         nvlist_t *proplist;
457         const char *normnm;
458         char *strval;
459
460         if (*props == NULL &&
461             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
462                 (void) fprintf(stderr,
463                     gettext("internal error: out of memory\n"));
464                 return (1);
465         }
466
467         proplist = *props;
468
469         if (poolprop) {
470                 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
471
472                 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
473                     !zpool_prop_feature(propname)) {
474                         (void) fprintf(stderr, gettext("property '%s' is "
475                             "not a valid pool property\n"), propname);
476                         return (2);
477                 }
478
479                 /*
480                  * feature@ properties and version should not be specified
481                  * at the same time.
482                  */
483                 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) &&
484                     nvlist_exists(proplist, vname)) ||
485                     (prop == ZPOOL_PROP_VERSION &&
486                     prop_list_contains_feature(proplist))) {
487                         (void) fprintf(stderr, gettext("'feature@' and "
488                             "'version' properties cannot be specified "
489                             "together\n"));
490                         return (2);
491                 }
492
493
494                 if (zpool_prop_feature(propname))
495                         normnm = propname;
496                 else
497                         normnm = zpool_prop_to_name(prop);
498         } else {
499                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
500                         normnm = zfs_prop_to_name(fprop);
501                 } else {
502                         normnm = propname;
503                 }
504         }
505
506         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
507             prop != ZPOOL_PROP_CACHEFILE) {
508                 (void) fprintf(stderr, gettext("property '%s' "
509                     "specified multiple times\n"), propname);
510                 return (2);
511         }
512
513         if (nvlist_add_string(proplist, normnm, propval) != 0) {
514                 (void) fprintf(stderr, gettext("internal "
515                     "error: out of memory\n"));
516                 return (1);
517         }
518
519         return (0);
520 }
521
522 /*
523  * Set a default property pair (name, string-value) in a property nvlist
524  */
525 static int
526 add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
527     boolean_t poolprop)
528 {
529         char *pval;
530
531         if (nvlist_lookup_string(*props, propname, &pval) == 0)
532                 return (0);
533
534         return (add_prop_list(propname, propval, props, poolprop));
535 }
536
537 /*
538  * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
539  *
540  *      -f      Force addition of devices, even if they appear in use
541  *      -g      Display guid for individual vdev name.
542  *      -L      Follow links when resolving vdev path name.
543  *      -n      Do not add the devices, but display the resulting layout if
544  *              they were to be added.
545  *      -P      Display full path for vdev name.
546  *
547  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
548  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
549  * libzfs.
550  */
551 int
552 zpool_do_add(int argc, char **argv)
553 {
554         boolean_t force = B_FALSE;
555         boolean_t dryrun = B_FALSE;
556         int name_flags = 0;
557         int c;
558         nvlist_t *nvroot;
559         char *poolname;
560         zpool_boot_label_t boot_type;
561         uint64_t boot_size;
562         int ret;
563         zpool_handle_t *zhp;
564         nvlist_t *config;
565
566         /* check options */
567         while ((c = getopt(argc, argv, "fgLnP")) != -1) {
568                 switch (c) {
569                 case 'f':
570                         force = B_TRUE;
571                         break;
572                 case 'g':
573                         name_flags |= VDEV_NAME_GUID;
574                         break;
575                 case 'L':
576                         name_flags |= VDEV_NAME_FOLLOW_LINKS;
577                         break;
578                 case 'n':
579                         dryrun = B_TRUE;
580                         break;
581                 case 'P':
582                         name_flags |= VDEV_NAME_PATH;
583                         break;
584                 case '?':
585                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
586                             optopt);
587                         usage(B_FALSE);
588                 }
589         }
590
591         argc -= optind;
592         argv += optind;
593
594         /* get pool name and check number of arguments */
595         if (argc < 1) {
596                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
597                 usage(B_FALSE);
598         }
599         if (argc < 2) {
600                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
601                 usage(B_FALSE);
602         }
603
604         poolname = argv[0];
605
606         argc--;
607         argv++;
608
609         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
610                 return (1);
611
612         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
613                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
614                     poolname);
615                 zpool_close(zhp);
616                 return (1);
617         }
618
619         if (zpool_is_bootable(zhp))
620                 boot_type = ZPOOL_COPY_BOOT_LABEL;
621         else
622                 boot_type = ZPOOL_NO_BOOT_LABEL;
623
624         /* pass off to get_vdev_spec for processing */
625         boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
626         nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
627             boot_type, boot_size, argc, argv);
628         if (nvroot == NULL) {
629                 zpool_close(zhp);
630                 return (1);
631         }
632
633         if (dryrun) {
634                 nvlist_t *poolnvroot;
635
636                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
637                     &poolnvroot) == 0);
638
639                 (void) printf(gettext("would update '%s' to the following "
640                     "configuration:\n"), zpool_get_name(zhp));
641
642                 /* print original main pool and new tree */
643                 print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
644                     name_flags | VDEV_NAME_TYPE_ID);
645                 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags);
646
647                 /* print other classes: 'dedup', 'special', and 'log' */
648                 print_vdev_tree(zhp, "dedup", poolnvroot, 0,
649                     VDEV_ALLOC_BIAS_DEDUP, name_flags);
650                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_DEDUP,
651                     name_flags);
652
653                 print_vdev_tree(zhp, "special", poolnvroot, 0,
654                     VDEV_ALLOC_BIAS_SPECIAL, name_flags);
655                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_SPECIAL,
656                     name_flags);
657
658                 print_vdev_tree(zhp, "logs", poolnvroot, 0, VDEV_ALLOC_BIAS_LOG,
659                     name_flags);
660                 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_LOG,
661                     name_flags);
662
663                 ret = 0;
664         } else {
665                 ret = (zpool_add(zhp, nvroot) != 0);
666         }
667
668         nvlist_free(nvroot);
669         zpool_close(zhp);
670
671         return (ret);
672 }
673
674 /*
675  * zpool remove  <pool> <vdev> ...
676  *
677  * Removes the given vdev from the pool.
678  */
679 int
680 zpool_do_remove(int argc, char **argv)
681 {
682         char *poolname;
683         int i, ret = 0;
684         zpool_handle_t *zhp;
685         boolean_t stop = B_FALSE;
686         boolean_t noop = B_FALSE;
687         boolean_t parsable = B_FALSE;
688         char c;
689
690         /* check options */
691         while ((c = getopt(argc, argv, "nps")) != -1) {
692                 switch (c) {
693                 case 'n':
694                         noop = B_TRUE;
695                         break;
696                 case 'p':
697                         parsable = B_TRUE;
698                         break;
699                 case 's':
700                         stop = B_TRUE;
701                         break;
702                 case '?':
703                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
704                             optopt);
705                         usage(B_FALSE);
706                 }
707         }
708
709         argc -= optind;
710         argv += optind;
711
712         /* get pool name and check number of arguments */
713         if (argc < 1) {
714                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
715                 usage(B_FALSE);
716         }
717
718         poolname = argv[0];
719
720         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
721                 return (1);
722
723         if (stop && noop) {
724                 (void) fprintf(stderr, gettext("stop request ignored\n"));
725                 return (0);
726         }
727
728         if (stop) {
729                 if (argc > 1) {
730                         (void) fprintf(stderr, gettext("too many arguments\n"));
731                         usage(B_FALSE);
732                 }
733                 if (zpool_vdev_remove_cancel(zhp) != 0)
734                         ret = 1;
735         } else {
736                 if (argc < 2) {
737                         (void) fprintf(stderr, gettext("missing device\n"));
738                         usage(B_FALSE);
739                 }
740
741                 for (i = 1; i < argc; i++) {
742                         if (noop) {
743                                 uint64_t size;
744
745                                 if (zpool_vdev_indirect_size(zhp, argv[i],
746                                     &size) != 0) {
747                                         ret = 1;
748                                         break;
749                                 }
750                                 if (parsable) {
751                                         (void) printf("%s %llu\n",
752                                             argv[i], size);
753                                 } else {
754                                         char valstr[32];
755                                         zfs_nicenum(size, valstr,
756                                             sizeof (valstr));
757                                         (void) printf("Memory that will be "
758                                             "used after removing %s: %s\n",
759                                             argv[i], valstr);
760                                 }
761                         } else {
762                                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
763                                         ret = 1;
764                         }
765                 }
766         }
767
768         return (ret);
769 }
770
771 /*
772  * zpool labelclear [-f] <vdev>
773  *
774  *      -f      Force clearing the label for the vdevs which are members of
775  *              the exported or foreign pools.
776  *
777  * Verifies that the vdev is not active and zeros out the label information
778  * on the device.
779  */
780 int
781 zpool_do_labelclear(int argc, char **argv)
782 {
783         char vdev[MAXPATHLEN];
784         char *name = NULL;
785         struct stat st;
786         int c, fd, ret = 0;
787         nvlist_t *config;
788         pool_state_t state;
789         boolean_t inuse = B_FALSE;
790         boolean_t force = B_FALSE;
791
792         /* check options */
793         while ((c = getopt(argc, argv, "f")) != -1) {
794                 switch (c) {
795                 case 'f':
796                         force = B_TRUE;
797                         break;
798                 default:
799                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
800                             optopt);
801                         usage(B_FALSE);
802                 }
803         }
804
805         argc -= optind;
806         argv += optind;
807
808         /* get vdev name */
809         if (argc < 1) {
810                 (void) fprintf(stderr, gettext("missing vdev name\n"));
811                 usage(B_FALSE);
812         }
813         if (argc > 1) {
814                 (void) fprintf(stderr, gettext("too many arguments\n"));
815                 usage(B_FALSE);
816         }
817
818         /*
819          * Check if we were given absolute path and use it as is.
820          * Otherwise if the provided vdev name doesn't point to a file,
821          * try prepending dsk path and appending s0.
822          */
823         (void) strlcpy(vdev, argv[0], sizeof (vdev));
824         if (vdev[0] != '/' && stat(vdev, &st) != 0) {
825                 char *s;
826
827                 (void) snprintf(vdev, sizeof (vdev), "%s/%s",
828 #ifdef illumos
829                     ZFS_DISK_ROOT, argv[0]);
830                 if ((s = strrchr(argv[0], 's')) == NULL ||
831                     !isdigit(*(s + 1)))
832                         (void) strlcat(vdev, "s0", sizeof (vdev));
833 #else
834                     "/dev", argv[0]);
835 #endif
836                 if (stat(vdev, &st) != 0) {
837                         (void) fprintf(stderr, gettext(
838                             "failed to find device %s, try specifying absolute "
839                             "path instead\n"), argv[0]);
840                         return (1);
841                 }
842         }
843
844         if ((fd = open(vdev, O_RDWR)) < 0) {
845                 (void) fprintf(stderr, gettext("failed to open %s: %s\n"),
846                     vdev, strerror(errno));
847                 return (1);
848         }
849
850         if (zpool_read_label(fd, &config) != 0) {
851                 (void) fprintf(stderr,
852                     gettext("failed to read label from %s\n"), vdev);
853                 return (1);
854         }
855         nvlist_free(config);
856
857         ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
858         if (ret != 0) {
859                 (void) fprintf(stderr,
860                     gettext("failed to check state for %s\n"), vdev);
861                 return (1);
862         }
863
864         if (!inuse)
865                 goto wipe_label;
866
867         switch (state) {
868         default:
869         case POOL_STATE_ACTIVE:
870         case POOL_STATE_SPARE:
871         case POOL_STATE_L2CACHE:
872                 (void) fprintf(stderr, gettext(
873                     "%s is a member (%s) of pool \"%s\"\n"),
874                     vdev, zpool_pool_state_to_name(state), name);
875                 ret = 1;
876                 goto errout;
877
878         case POOL_STATE_EXPORTED:
879                 if (force)
880                         break;
881                 (void) fprintf(stderr, gettext(
882                     "use '-f' to override the following error:\n"
883                     "%s is a member of exported pool \"%s\"\n"),
884                     vdev, name);
885                 ret = 1;
886                 goto errout;
887
888         case POOL_STATE_POTENTIALLY_ACTIVE:
889                 if (force)
890                         break;
891                 (void) fprintf(stderr, gettext(
892                     "use '-f' to override the following error:\n"
893                     "%s is a member of potentially active pool \"%s\"\n"),
894                     vdev, name);
895                 ret = 1;
896                 goto errout;
897
898         case POOL_STATE_DESTROYED:
899                 /* inuse should never be set for a destroyed pool */
900                 assert(0);
901                 break;
902         }
903
904 wipe_label:
905         ret = zpool_clear_label(fd);
906         if (ret != 0) {
907                 (void) fprintf(stderr,
908                     gettext("failed to clear label for %s\n"), vdev);
909         }
910
911 errout:
912         free(name);
913         (void) close(fd);
914
915         return (ret);
916 }
917
918 /*
919  * zpool create [-fnd] [-B] [-o property=value] ...
920  *              [-O file-system-property=value] ...
921  *              [-R root] [-m mountpoint] [-t tempname] <pool> <dev> ...
922  *
923  *      -B      Create boot partition.
924  *      -f      Force creation, even if devices appear in use
925  *      -n      Do not create the pool, but display the resulting layout if it
926  *              were to be created.
927  *      -R      Create a pool under an alternate root
928  *      -m      Set default mountpoint for the root dataset.  By default it's
929  *              '/<pool>'
930  *      -t      Use the temporary name until the pool is exported.
931  *      -o      Set property=value.
932  *      -d      Don't automatically enable all supported pool features
933  *              (individual features can be enabled with -o).
934  *      -O      Set fsproperty=value in the pool's root file system
935  *
936  * Creates the named pool according to the given vdev specification.  The
937  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
938  * we get the nvlist back from get_vdev_spec(), we either print out the contents
939  * (if '-n' was specified), or pass it to libzfs to do the creation.
940  */
941
942 #define SYSTEM256       (256 * 1024 * 1024)
943 int
944 zpool_do_create(int argc, char **argv)
945 {
946         boolean_t force = B_FALSE;
947         boolean_t dryrun = B_FALSE;
948         boolean_t enable_all_pool_feat = B_TRUE;
949         zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL;
950         uint64_t boot_size = 0;
951         int c;
952         nvlist_t *nvroot = NULL;
953         char *poolname;
954         char *tname = NULL;
955         int ret = 1;
956         char *altroot = NULL;
957         char *mountpoint = NULL;
958         nvlist_t *fsprops = NULL;
959         nvlist_t *props = NULL;
960         char *propval;
961
962         /* check options */
963         while ((c = getopt(argc, argv, ":fndBR:m:o:O:t:")) != -1) {
964                 switch (c) {
965                 case 'f':
966                         force = B_TRUE;
967                         break;
968                 case 'n':
969                         dryrun = B_TRUE;
970                         break;
971                 case 'd':
972                         enable_all_pool_feat = B_FALSE;
973                         break;
974                 case 'B':
975 #ifdef illumos
976                         /*
977                          * We should create the system partition.
978                          * Also make sure the size is set.
979                          */
980                         boot_type = ZPOOL_CREATE_BOOT_LABEL;
981                         if (boot_size == 0)
982                                 boot_size = SYSTEM256;
983                         break;
984 #else
985                         (void) fprintf(stderr,
986                             gettext("option '%c' is not supported\n"),
987                             optopt);
988                         goto badusage;
989 #endif
990                 case 'R':
991                         altroot = optarg;
992                         if (add_prop_list(zpool_prop_to_name(
993                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
994                                 goto errout;
995                         if (add_prop_list_default(zpool_prop_to_name(
996                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
997                                 goto errout;
998                         break;
999                 case 'm':
1000                         /* Equivalent to -O mountpoint=optarg */
1001                         mountpoint = optarg;
1002                         break;
1003                 case 'o':
1004                         if ((propval = strchr(optarg, '=')) == NULL) {
1005                                 (void) fprintf(stderr, gettext("missing "
1006                                     "'=' for -o option\n"));
1007                                 goto errout;
1008                         }
1009                         *propval = '\0';
1010                         propval++;
1011
1012                         if (add_prop_list(optarg, propval, &props, B_TRUE))
1013                                 goto errout;
1014
1015                         /*
1016                          * Get bootsize value for make_root_vdev().
1017                          */
1018                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) {
1019                                 if (zfs_nicestrtonum(g_zfs, propval,
1020                                     &boot_size) < 0 || boot_size == 0) {
1021                                         (void) fprintf(stderr,
1022                                             gettext("bad boot partition size "
1023                                             "'%s': %s\n"),  propval,
1024                                             libzfs_error_description(g_zfs));
1025                                         goto errout;
1026                                 }
1027                         }
1028
1029                         /*
1030                          * If the user is creating a pool that doesn't support
1031                          * feature flags, don't enable any features.
1032                          */
1033                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
1034                                 char *end;
1035                                 u_longlong_t ver;
1036
1037                                 ver = strtoull(propval, &end, 10);
1038                                 if (*end == '\0' &&
1039                                     ver < SPA_VERSION_FEATURES) {
1040                                         enable_all_pool_feat = B_FALSE;
1041                                 }
1042                         }
1043                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
1044                                 altroot = propval;
1045                         break;
1046                 case 'O':
1047                         if ((propval = strchr(optarg, '=')) == NULL) {
1048                                 (void) fprintf(stderr, gettext("missing "
1049                                     "'=' for -O option\n"));
1050                                 goto errout;
1051                         }
1052                         *propval = '\0';
1053                         propval++;
1054
1055                         /*
1056                          * Mountpoints are checked and then added later.
1057                          * Uniquely among properties, they can be specified
1058                          * more than once, to avoid conflict with -m.
1059                          */
1060                         if (0 == strcmp(optarg,
1061                             zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
1062                                 mountpoint = propval;
1063                         } else if (add_prop_list(optarg, propval, &fsprops,
1064                             B_FALSE)) {
1065                                 goto errout;
1066                         }
1067                         break;
1068                 case 't':
1069                         /*
1070                          * Sanity check temporary pool name.
1071                          */
1072                         if (strchr(optarg, '/') != NULL) {
1073                                 (void) fprintf(stderr, gettext("cannot create "
1074                                     "'%s': invalid character '/' in temporary "
1075                                     "name\n"), optarg);
1076                                 (void) fprintf(stderr, gettext("use 'zfs "
1077                                     "create' to create a dataset\n"));
1078                                 goto errout;
1079                         }
1080
1081                         if (add_prop_list(zpool_prop_to_name(
1082                             ZPOOL_PROP_TNAME), optarg, &props, B_TRUE))
1083                                 goto errout;
1084                         if (add_prop_list_default(zpool_prop_to_name(
1085                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1086                                 goto errout;
1087                         tname = optarg;
1088                         break;
1089                 case ':':
1090                         (void) fprintf(stderr, gettext("missing argument for "
1091                             "'%c' option\n"), optopt);
1092                         goto badusage;
1093                 case '?':
1094                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1095                             optopt);
1096                         goto badusage;
1097                 }
1098         }
1099
1100         argc -= optind;
1101         argv += optind;
1102
1103         /* get pool name and check number of arguments */
1104         if (argc < 1) {
1105                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
1106                 goto badusage;
1107         }
1108         if (argc < 2) {
1109                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
1110                 goto badusage;
1111         }
1112
1113         poolname = argv[0];
1114
1115         /*
1116          * As a special case, check for use of '/' in the name, and direct the
1117          * user to use 'zfs create' instead.
1118          */
1119         if (strchr(poolname, '/') != NULL) {
1120                 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
1121                     "character '/' in pool name\n"), poolname);
1122                 (void) fprintf(stderr, gettext("use 'zfs create' to "
1123                     "create a dataset\n"));
1124                 goto errout;
1125         }
1126
1127         /*
1128          * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used,
1129          * and not set otherwise.
1130          */
1131         if (boot_type == ZPOOL_CREATE_BOOT_LABEL) {
1132                 const char *propname;
1133                 char *strptr, *buf = NULL;
1134                 int rv;
1135
1136                 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1137                 if (nvlist_lookup_string(props, propname, &strptr) != 0) {
1138                         (void) asprintf(&buf, "%" PRIu64, boot_size);
1139                         if (buf == NULL) {
1140                                 (void) fprintf(stderr,
1141                                     gettext("internal error: out of memory\n"));
1142                                 goto errout;
1143                         }
1144                         rv = add_prop_list(propname, buf, &props, B_TRUE);
1145                         free(buf);
1146                         if (rv != 0)
1147                                 goto errout;
1148                 }
1149         } else {
1150                 const char *propname;
1151                 char *strptr;
1152
1153                 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE);
1154                 if (nvlist_lookup_string(props, propname, &strptr) == 0) {
1155                         (void) fprintf(stderr, gettext("error: setting boot "
1156                             "partition size requires option '-B'\n"));
1157                         goto errout;
1158                 }
1159         }
1160
1161         /* pass off to get_vdev_spec for bulk processing */
1162         nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
1163             boot_type, boot_size, argc - 1, argv + 1);
1164         if (nvroot == NULL)
1165                 goto errout;
1166
1167         /* make_root_vdev() allows 0 toplevel children if there are spares */
1168         if (!zfs_allocatable_devs(nvroot)) {
1169                 (void) fprintf(stderr, gettext("invalid vdev "
1170                     "specification: at least one toplevel vdev must be "
1171                     "specified\n"));
1172                 goto errout;
1173         }
1174
1175         if (altroot != NULL && altroot[0] != '/') {
1176                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
1177                     "must be an absolute path\n"), altroot);
1178                 goto errout;
1179         }
1180
1181         /*
1182          * Check the validity of the mountpoint and direct the user to use the
1183          * '-m' mountpoint option if it looks like its in use.
1184          * Ignore the checks if the '-f' option is given.
1185          */
1186         if (!force && (mountpoint == NULL ||
1187             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
1188             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0))) {
1189                 char buf[MAXPATHLEN];
1190                 DIR *dirp;
1191
1192                 if (mountpoint && mountpoint[0] != '/') {
1193                         (void) fprintf(stderr, gettext("invalid mountpoint "
1194                             "'%s': must be an absolute path, 'legacy', or "
1195                             "'none'\n"), mountpoint);
1196                         goto errout;
1197                 }
1198
1199                 if (mountpoint == NULL) {
1200                         if (altroot != NULL)
1201                                 (void) snprintf(buf, sizeof (buf), "%s/%s",
1202                                     altroot, poolname);
1203                         else
1204                                 (void) snprintf(buf, sizeof (buf), "/%s",
1205                                     poolname);
1206                 } else {
1207                         if (altroot != NULL)
1208                                 (void) snprintf(buf, sizeof (buf), "%s%s",
1209                                     altroot, mountpoint);
1210                         else
1211                                 (void) snprintf(buf, sizeof (buf), "%s",
1212                                     mountpoint);
1213                 }
1214
1215                 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
1216                         (void) fprintf(stderr, gettext("mountpoint '%s' : "
1217                             "%s\n"), buf, strerror(errno));
1218                         (void) fprintf(stderr, gettext("use '-m' "
1219                             "option to provide a different default\n"));
1220                         goto errout;
1221                 } else if (dirp) {
1222                         int count = 0;
1223
1224                         while (count < 3 && readdir(dirp) != NULL)
1225                                 count++;
1226                         (void) closedir(dirp);
1227
1228                         if (count > 2) {
1229                                 (void) fprintf(stderr, gettext("mountpoint "
1230                                     "'%s' exists and is not empty\n"), buf);
1231                                 (void) fprintf(stderr, gettext("use '-m' "
1232                                     "option to provide a "
1233                                     "different default\n"));
1234                                 goto errout;
1235                         }
1236                 }
1237         }
1238
1239         /*
1240          * Now that the mountpoint's validity has been checked, ensure that
1241          * the property is set appropriately prior to creating the pool.
1242          */
1243         if (mountpoint != NULL) {
1244                 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1245                     mountpoint, &fsprops, B_FALSE);
1246                 if (ret != 0)
1247                         goto errout;
1248         }
1249
1250         ret = 1;
1251         if (dryrun) {
1252                 /*
1253                  * For a dry run invocation, print out a basic message and run
1254                  * through all the vdevs in the list and print out in an
1255                  * appropriate hierarchy.
1256                  */
1257                 (void) printf(gettext("would create '%s' with the "
1258                     "following layout:\n\n"), poolname);
1259
1260                 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0);
1261                 print_vdev_tree(NULL, "dedup", nvroot, 0,
1262                     VDEV_ALLOC_BIAS_DEDUP, 0);
1263                 print_vdev_tree(NULL, "special", nvroot, 0,
1264                     VDEV_ALLOC_BIAS_SPECIAL, 0);
1265                 print_vdev_tree(NULL, "logs", nvroot, 0,
1266                     VDEV_ALLOC_BIAS_LOG, 0);
1267
1268                 ret = 0;
1269         } else {
1270                 /*
1271                  * Hand off to libzfs.
1272                  */
1273                 if (enable_all_pool_feat) {
1274                         spa_feature_t i;
1275                         for (i = 0; i < SPA_FEATURES; i++) {
1276                                 char propname[MAXPATHLEN];
1277                                 zfeature_info_t *feat = &spa_feature_table[i];
1278
1279                                 (void) snprintf(propname, sizeof (propname),
1280                                     "feature@%s", feat->fi_uname);
1281
1282                                 /*
1283                                  * Skip feature if user specified it manually
1284                                  * on the command line.
1285                                  */
1286                                 if (nvlist_exists(props, propname))
1287                                         continue;
1288
1289                                 ret = add_prop_list(propname,
1290                                     ZFS_FEATURE_ENABLED, &props, B_TRUE);
1291                                 if (ret != 0)
1292                                         goto errout;
1293                         }
1294                 }
1295
1296                 ret = 1;
1297                 if (zpool_create(g_zfs, poolname,
1298                     nvroot, props, fsprops) == 0) {
1299                         zfs_handle_t *pool = zfs_open(g_zfs,
1300                             tname ? tname : poolname, ZFS_TYPE_FILESYSTEM);
1301                         if (pool != NULL) {
1302                                 if (zfs_mount(pool, NULL, 0) == 0)
1303                                         ret = zfs_shareall(pool);
1304                                 zfs_close(pool);
1305                         }
1306                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1307                         (void) fprintf(stderr, gettext("pool name may have "
1308                             "been omitted\n"));
1309                 }
1310         }
1311
1312 errout:
1313         nvlist_free(nvroot);
1314         nvlist_free(fsprops);
1315         nvlist_free(props);
1316         return (ret);
1317 badusage:
1318         nvlist_free(fsprops);
1319         nvlist_free(props);
1320         usage(B_FALSE);
1321         return (2);
1322 }
1323
1324 /*
1325  * zpool destroy <pool>
1326  *
1327  *      -f      Forcefully unmount any datasets
1328  *
1329  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
1330  */
1331 int
1332 zpool_do_destroy(int argc, char **argv)
1333 {
1334         boolean_t force = B_FALSE;
1335         int c;
1336         char *pool;
1337         zpool_handle_t *zhp;
1338         int ret;
1339
1340         /* check options */
1341         while ((c = getopt(argc, argv, "f")) != -1) {
1342                 switch (c) {
1343                 case 'f':
1344                         force = B_TRUE;
1345                         break;
1346                 case '?':
1347                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1348                             optopt);
1349                         usage(B_FALSE);
1350                 }
1351         }
1352
1353         argc -= optind;
1354         argv += optind;
1355
1356         /* check arguments */
1357         if (argc < 1) {
1358                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1359                 usage(B_FALSE);
1360         }
1361         if (argc > 1) {
1362                 (void) fprintf(stderr, gettext("too many arguments\n"));
1363                 usage(B_FALSE);
1364         }
1365
1366         pool = argv[0];
1367
1368         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1369                 /*
1370                  * As a special case, check for use of '/' in the name, and
1371                  * direct the user to use 'zfs destroy' instead.
1372                  */
1373                 if (strchr(pool, '/') != NULL)
1374                         (void) fprintf(stderr, gettext("use 'zfs destroy' to "
1375                             "destroy a dataset\n"));
1376                 return (1);
1377         }
1378
1379         if (zpool_disable_datasets(zhp, force) != 0) {
1380                 (void) fprintf(stderr, gettext("could not destroy '%s': "
1381                     "could not unmount datasets\n"), zpool_get_name(zhp));
1382                 return (1);
1383         }
1384
1385         /* The history must be logged as part of the export */
1386         log_history = B_FALSE;
1387
1388         ret = (zpool_destroy(zhp, history_str) != 0);
1389
1390         zpool_close(zhp);
1391
1392         return (ret);
1393 }
1394
1395 /*
1396  * zpool export [-f] <pool> ...
1397  *
1398  *      -f      Forcefully unmount datasets
1399  *
1400  * Export the given pools.  By default, the command will attempt to cleanly
1401  * unmount any active datasets within the pool.  If the '-f' flag is specified,
1402  * then the datasets will be forcefully unmounted.
1403  */
1404 int
1405 zpool_do_export(int argc, char **argv)
1406 {
1407         boolean_t force = B_FALSE;
1408         boolean_t hardforce = B_FALSE;
1409         int c;
1410         zpool_handle_t *zhp;
1411         int ret;
1412         int i;
1413
1414         /* check options */
1415         while ((c = getopt(argc, argv, "fF")) != -1) {
1416                 switch (c) {
1417                 case 'f':
1418                         force = B_TRUE;
1419                         break;
1420                 case 'F':
1421                         hardforce = B_TRUE;
1422                         break;
1423                 case '?':
1424                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1425                             optopt);
1426                         usage(B_FALSE);
1427                 }
1428         }
1429
1430         argc -= optind;
1431         argv += optind;
1432
1433         /* check arguments */
1434         if (argc < 1) {
1435                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1436                 usage(B_FALSE);
1437         }
1438
1439         ret = 0;
1440         for (i = 0; i < argc; i++) {
1441                 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
1442                         ret = 1;
1443                         continue;
1444                 }
1445
1446                 if (zpool_disable_datasets(zhp, force) != 0) {
1447                         ret = 1;
1448                         zpool_close(zhp);
1449                         continue;
1450                 }
1451
1452                 /* The history must be logged as part of the export */
1453                 log_history = B_FALSE;
1454
1455                 if (hardforce) {
1456                         if (zpool_export_force(zhp, history_str) != 0)
1457                                 ret = 1;
1458                 } else if (zpool_export(zhp, force, history_str) != 0) {
1459                         ret = 1;
1460                 }
1461
1462                 zpool_close(zhp);
1463         }
1464
1465         return (ret);
1466 }
1467
1468 /*
1469  * Given a vdev configuration, determine the maximum width needed for the device
1470  * name column.
1471  */
1472 static int
1473 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
1474     int name_flags)
1475 {
1476         char *name;
1477         nvlist_t **child;
1478         uint_t c, children;
1479         int ret;
1480
1481         name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID);
1482         if (strlen(name) + depth > max)
1483                 max = strlen(name) + depth;
1484
1485         free(name);
1486
1487         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1488             &child, &children) == 0) {
1489                 for (c = 0; c < children; c++)
1490                         if ((ret = max_width(zhp, child[c], depth + 2,
1491                             max, name_flags)) > max)
1492                                 max = ret;
1493         }
1494
1495         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1496             &child, &children) == 0) {
1497                 for (c = 0; c < children; c++)
1498                         if ((ret = max_width(zhp, child[c], depth + 2,
1499                             max, name_flags)) > max)
1500                                 max = ret;
1501         }
1502
1503         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1504             &child, &children) == 0) {
1505                 for (c = 0; c < children; c++)
1506                         if ((ret = max_width(zhp, child[c], depth + 2,
1507                             max, name_flags)) > max)
1508                                 max = ret;
1509         }
1510
1511         return (max);
1512 }
1513
1514 typedef struct spare_cbdata {
1515         uint64_t        cb_guid;
1516         zpool_handle_t  *cb_zhp;
1517 } spare_cbdata_t;
1518
1519 static boolean_t
1520 find_vdev(nvlist_t *nv, uint64_t search)
1521 {
1522         uint64_t guid;
1523         nvlist_t **child;
1524         uint_t c, children;
1525
1526         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1527             search == guid)
1528                 return (B_TRUE);
1529
1530         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1531             &child, &children) == 0) {
1532                 for (c = 0; c < children; c++)
1533                         if (find_vdev(child[c], search))
1534                                 return (B_TRUE);
1535         }
1536
1537         return (B_FALSE);
1538 }
1539
1540 static int
1541 find_spare(zpool_handle_t *zhp, void *data)
1542 {
1543         spare_cbdata_t *cbp = data;
1544         nvlist_t *config, *nvroot;
1545
1546         config = zpool_get_config(zhp, NULL);
1547         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1548             &nvroot) == 0);
1549
1550         if (find_vdev(nvroot, cbp->cb_guid)) {
1551                 cbp->cb_zhp = zhp;
1552                 return (1);
1553         }
1554
1555         zpool_close(zhp);
1556         return (0);
1557 }
1558
1559 typedef struct status_cbdata {
1560         int             cb_count;
1561         int             cb_name_flags;
1562         int             cb_namewidth;
1563         boolean_t       cb_allpools;
1564         boolean_t       cb_verbose;
1565         boolean_t       cb_explain;
1566         boolean_t       cb_first;
1567         boolean_t       cb_dedup_stats;
1568         boolean_t       cb_print_status;
1569 } status_cbdata_t;
1570
1571 /*
1572  * Print out configuration state as requested by status_callback.
1573  */
1574 static void
1575 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
1576     nvlist_t *nv, int depth, boolean_t isspare)
1577 {
1578         nvlist_t **child;
1579         uint_t c, vsc, children;
1580         pool_scan_stat_t *ps = NULL;
1581         vdev_stat_t *vs;
1582         char rbuf[6], wbuf[6], cbuf[6];
1583         char *vname;
1584         uint64_t notpresent;
1585         uint64_t ashift;
1586         spare_cbdata_t spare_cb;
1587         const char *state;
1588         char *type;
1589
1590         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1591             &child, &children) != 0)
1592                 children = 0;
1593
1594         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1595             (uint64_t **)&vs, &vsc) == 0);
1596
1597         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1598
1599         if (strcmp(type, VDEV_TYPE_INDIRECT) == 0)
1600                 return;
1601
1602         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1603         if (isspare) {
1604                 /*
1605                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1606                  * online drives.
1607                  */
1608                 if (vs->vs_aux == VDEV_AUX_SPARED)
1609                         state = "INUSE";
1610                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1611                         state = "AVAIL";
1612         }
1613
1614         (void) printf("\t%*s%-*s  %-8s", depth, "", cb->cb_namewidth - depth,
1615             name, state);
1616
1617         if (!isspare) {
1618                 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1619                 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1620                 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1621                 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1622         }
1623
1624         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1625             &notpresent) == 0 ||
1626             vs->vs_state <= VDEV_STATE_CANT_OPEN) {
1627                 char *path;
1628                 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0)
1629                         (void) printf("  was %s", path);
1630         } else if (vs->vs_aux != 0) {
1631                 (void) printf("  ");
1632
1633                 switch (vs->vs_aux) {
1634                 case VDEV_AUX_OPEN_FAILED:
1635                         (void) printf(gettext("cannot open"));
1636                         break;
1637
1638                 case VDEV_AUX_BAD_GUID_SUM:
1639                         (void) printf(gettext("missing device"));
1640                         break;
1641
1642                 case VDEV_AUX_NO_REPLICAS:
1643                         (void) printf(gettext("insufficient replicas"));
1644                         break;
1645
1646                 case VDEV_AUX_VERSION_NEWER:
1647                         (void) printf(gettext("newer version"));
1648                         break;
1649
1650                 case VDEV_AUX_UNSUP_FEAT:
1651                         (void) printf(gettext("unsupported feature(s)"));
1652                         break;
1653
1654                 case VDEV_AUX_ASHIFT_TOO_BIG:
1655                         (void) printf(gettext("unsupported minimum blocksize"));
1656                         break;
1657
1658                 case VDEV_AUX_SPARED:
1659                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1660                             &spare_cb.cb_guid) == 0);
1661                         if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) {
1662                                 if (strcmp(zpool_get_name(spare_cb.cb_zhp),
1663                                     zpool_get_name(zhp)) == 0)
1664                                         (void) printf(gettext("currently in "
1665                                             "use"));
1666                                 else
1667                                         (void) printf(gettext("in use by "
1668                                             "pool '%s'"),
1669                                             zpool_get_name(spare_cb.cb_zhp));
1670                                 zpool_close(spare_cb.cb_zhp);
1671                         } else {
1672                                 (void) printf(gettext("currently in use"));
1673                         }
1674                         break;
1675
1676                 case VDEV_AUX_ERR_EXCEEDED:
1677                         (void) printf(gettext("too many errors"));
1678                         break;
1679
1680                 case VDEV_AUX_IO_FAILURE:
1681                         (void) printf(gettext("experienced I/O failures"));
1682                         break;
1683
1684                 case VDEV_AUX_BAD_LOG:
1685                         (void) printf(gettext("bad intent log"));
1686                         break;
1687
1688                 case VDEV_AUX_EXTERNAL:
1689                         (void) printf(gettext("external device fault"));
1690                         break;
1691
1692                 case VDEV_AUX_SPLIT_POOL:
1693                         (void) printf(gettext("split into new pool"));
1694                         break;
1695
1696                 case VDEV_AUX_ACTIVE:
1697                         (void) printf(gettext("currently in use"));
1698                         break;
1699
1700                 case VDEV_AUX_CHILDREN_OFFLINE:
1701                         (void) printf(gettext("all children offline"));
1702                         break;
1703
1704                 default:
1705                         (void) printf(gettext("corrupted data"));
1706                         break;
1707                 }
1708         } else if (children == 0 && !isspare &&
1709             VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
1710             vs->vs_configured_ashift < vs->vs_physical_ashift) {
1711                 (void) printf(
1712                     gettext("  block size: %dB configured, %dB native"),
1713                     1 << vs->vs_configured_ashift, 1 << vs->vs_physical_ashift);
1714         }
1715
1716         (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1717             (uint64_t **)&ps, &c);
1718
1719         if (ps != NULL && ps->pss_state == DSS_SCANNING &&
1720             vs->vs_scan_processed != 0 && children == 0) {
1721                 (void) printf(gettext("  (%s)"),
1722                     (ps->pss_func == POOL_SCAN_RESILVER) ?
1723                     "resilvering" : "repairing");
1724         }
1725
1726         if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE ||
1727             vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED ||
1728             vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) &&
1729             !vs->vs_scan_removing) {
1730                 char zbuf[1024];
1731                 char tbuf[256];
1732                 struct tm zaction_ts;
1733
1734                 time_t t = vs->vs_initialize_action_time;
1735                 int initialize_pct = 100;
1736                 if (vs->vs_initialize_state != VDEV_INITIALIZE_COMPLETE) {
1737                         initialize_pct = (vs->vs_initialize_bytes_done * 100 /
1738                             (vs->vs_initialize_bytes_est + 1));
1739                 }
1740
1741                 (void) localtime_r(&t, &zaction_ts);
1742                 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts);
1743
1744                 switch (vs->vs_initialize_state) {
1745                 case VDEV_INITIALIZE_SUSPENDED:
1746                         (void) snprintf(zbuf, sizeof (zbuf),
1747                             ", suspended, started at %s", tbuf);
1748                         break;
1749                 case VDEV_INITIALIZE_ACTIVE:
1750                         (void) snprintf(zbuf, sizeof (zbuf),
1751                             ", started at %s", tbuf);
1752                         break;
1753                 case VDEV_INITIALIZE_COMPLETE:
1754                         (void) snprintf(zbuf, sizeof (zbuf),
1755                             ", completed at %s", tbuf);
1756                         break;
1757                 }
1758
1759                 (void) printf(gettext("  (%d%% initialized%s)"),
1760                     initialize_pct, zbuf);
1761         }
1762
1763         (void) printf("\n");
1764
1765         for (c = 0; c < children; c++) {
1766                 uint64_t islog = B_FALSE, ishole = B_FALSE;
1767
1768                 /* Don't print logs or holes here */
1769                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1770                     &islog);
1771                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1772                     &ishole);
1773                 if (islog || ishole)
1774                         continue;
1775                 /* Only print normal classes here */
1776                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
1777                         continue;
1778
1779                 vname = zpool_vdev_name(g_zfs, zhp, child[c],
1780                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1781                 print_status_config(zhp, cb, vname, child[c], depth + 2,
1782                     isspare);
1783                 free(vname);
1784         }
1785 }
1786
1787 /*
1788  * Print the configuration of an exported pool.  Iterate over all vdevs in the
1789  * pool, printing out the name and status for each one.
1790  */
1791 static void
1792 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv,
1793     int depth)
1794 {
1795         nvlist_t **child;
1796         uint_t c, children;
1797         vdev_stat_t *vs;
1798         char *type, *vname;
1799
1800         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1801         if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1802             strcmp(type, VDEV_TYPE_HOLE) == 0)
1803                 return;
1804
1805         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1806             (uint64_t **)&vs, &c) == 0);
1807
1808         (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name);
1809         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1810
1811         if (vs->vs_aux != 0) {
1812                 (void) printf("  ");
1813
1814                 switch (vs->vs_aux) {
1815                 case VDEV_AUX_OPEN_FAILED:
1816                         (void) printf(gettext("cannot open"));
1817                         break;
1818
1819                 case VDEV_AUX_BAD_GUID_SUM:
1820                         (void) printf(gettext("missing device"));
1821                         break;
1822
1823                 case VDEV_AUX_NO_REPLICAS:
1824                         (void) printf(gettext("insufficient replicas"));
1825                         break;
1826
1827                 case VDEV_AUX_VERSION_NEWER:
1828                         (void) printf(gettext("newer version"));
1829                         break;
1830
1831                 case VDEV_AUX_UNSUP_FEAT:
1832                         (void) printf(gettext("unsupported feature(s)"));
1833                         break;
1834
1835                 case VDEV_AUX_ERR_EXCEEDED:
1836                         (void) printf(gettext("too many errors"));
1837                         break;
1838
1839                 case VDEV_AUX_ACTIVE:
1840                         (void) printf(gettext("currently in use"));
1841                         break;
1842
1843                 case VDEV_AUX_CHILDREN_OFFLINE:
1844                         (void) printf(gettext("all children offline"));
1845                         break;
1846
1847                 default:
1848                         (void) printf(gettext("corrupted data"));
1849                         break;
1850                 }
1851         }
1852         (void) printf("\n");
1853
1854         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1855             &child, &children) != 0)
1856                 return;
1857
1858         for (c = 0; c < children; c++) {
1859                 uint64_t is_log = B_FALSE;
1860
1861                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1862                     &is_log);
1863                 if (is_log)
1864                         continue;
1865                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
1866                         continue;
1867
1868                 vname = zpool_vdev_name(g_zfs, NULL, child[c],
1869                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1870                 print_import_config(cb, vname, child[c], depth + 2);
1871                 free(vname);
1872         }
1873
1874         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1875             &child, &children) == 0) {
1876                 (void) printf(gettext("\tcache\n"));
1877                 for (c = 0; c < children; c++) {
1878                         vname = zpool_vdev_name(g_zfs, NULL, child[c],
1879                             cb->cb_name_flags);
1880                         (void) printf("\t  %s\n", vname);
1881                         free(vname);
1882                 }
1883         }
1884
1885         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1886             &child, &children) == 0) {
1887                 (void) printf(gettext("\tspares\n"));
1888                 for (c = 0; c < children; c++) {
1889                         vname = zpool_vdev_name(g_zfs, NULL, child[c],
1890                             cb->cb_name_flags);
1891                         (void) printf("\t  %s\n", vname);
1892                         free(vname);
1893                 }
1894         }
1895 }
1896
1897 /*
1898  * Print specialized class vdevs.
1899  *
1900  * These are recorded as top level vdevs in the main pool child array
1901  * but with "is_log" set to 1 or an "alloc_bias" string. We use either
1902  * print_status_config() or print_import_config() to print the top level
1903  * class vdevs then any of their children (eg mirrored slogs) are printed
1904  * recursively - which works because only the top level vdev is marked.
1905  */
1906 static void
1907 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
1908     const char *class)
1909 {
1910         uint_t c, children;
1911         nvlist_t **child;
1912         boolean_t printed = B_FALSE;
1913
1914         assert(zhp != NULL || !cb->cb_verbose);
1915
1916         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1917             &children) != 0)
1918                 return;
1919
1920         for (c = 0; c < children; c++) {
1921                 uint64_t is_log = B_FALSE;
1922                 char *bias = NULL;
1923                 char *type = NULL;
1924
1925                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1926                     &is_log);
1927
1928                 if (is_log) {
1929                         bias = VDEV_ALLOC_CLASS_LOGS;
1930                 } else {
1931                         (void) nvlist_lookup_string(child[c],
1932                             ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
1933                         (void) nvlist_lookup_string(child[c],
1934                             ZPOOL_CONFIG_TYPE, &type);
1935                 }
1936
1937                 if (bias == NULL || strcmp(bias, class) != 0)
1938                         continue;
1939                 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
1940                         continue;
1941
1942                 if (!printed) {
1943                         (void) printf("\t%s\t\n", gettext(class));
1944                         printed = B_TRUE;
1945                 }
1946
1947                 char *name = zpool_vdev_name(g_zfs, zhp, child[c],
1948                     cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1949                 if (cb->cb_print_status)
1950                         print_status_config(zhp, cb, name, child[c], 2,
1951                             B_FALSE);
1952                 else
1953                         print_import_config(cb, name, child[c], 2);
1954                 free(name);
1955         }
1956 }
1957
1958 /*
1959  * Display the status for the given pool.
1960  */
1961 static void
1962 show_import(nvlist_t *config)
1963 {
1964         uint64_t pool_state;
1965         vdev_stat_t *vs;
1966         char *name;
1967         uint64_t guid;
1968         uint64_t hostid = 0;
1969         char *msgid;
1970         char *hostname = "unknown";
1971         nvlist_t *nvroot, *nvinfo;
1972         int reason;
1973         const char *health;
1974         uint_t vsc;
1975         char *comment;
1976         status_cbdata_t cb = { 0 };
1977
1978         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1979             &name) == 0);
1980         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1981             &guid) == 0);
1982         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1983             &pool_state) == 0);
1984         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1985             &nvroot) == 0);
1986
1987         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1988             (uint64_t **)&vs, &vsc) == 0);
1989         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1990
1991         reason = zpool_import_status(config, &msgid);
1992
1993         (void) printf(gettext("   pool: %s\n"), name);
1994         (void) printf(gettext("     id: %llu\n"), (u_longlong_t)guid);
1995         (void) printf(gettext("  state: %s"), health);
1996         if (pool_state == POOL_STATE_DESTROYED)
1997                 (void) printf(gettext(" (DESTROYED)"));
1998         (void) printf("\n");
1999
2000         switch (reason) {
2001         case ZPOOL_STATUS_MISSING_DEV_R:
2002         case ZPOOL_STATUS_MISSING_DEV_NR:
2003         case ZPOOL_STATUS_BAD_GUID_SUM:
2004                 (void) printf(gettext(" status: One or more devices are "
2005                     "missing from the system.\n"));
2006                 break;
2007
2008         case ZPOOL_STATUS_CORRUPT_LABEL_R:
2009         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2010                 (void) printf(gettext(" status: One or more devices contains "
2011                     "corrupted data.\n"));
2012                 break;
2013
2014         case ZPOOL_STATUS_CORRUPT_DATA:
2015                 (void) printf(
2016                     gettext(" status: The pool data is corrupted.\n"));
2017                 break;
2018
2019         case ZPOOL_STATUS_OFFLINE_DEV:
2020                 (void) printf(gettext(" status: One or more devices "
2021                     "are offlined.\n"));
2022                 break;
2023
2024         case ZPOOL_STATUS_CORRUPT_POOL:
2025                 (void) printf(gettext(" status: The pool metadata is "
2026                     "corrupted.\n"));
2027                 break;
2028
2029         case ZPOOL_STATUS_VERSION_OLDER:
2030                 (void) printf(gettext(" status: The pool is formatted using a "
2031                     "legacy on-disk version.\n"));
2032                 break;
2033
2034         case ZPOOL_STATUS_VERSION_NEWER:
2035                 (void) printf(gettext(" status: The pool is formatted using an "
2036                     "incompatible version.\n"));
2037                 break;
2038
2039         case ZPOOL_STATUS_FEAT_DISABLED:
2040                 (void) printf(gettext(" status: Some supported features are "
2041                     "not enabled on the pool.\n"));
2042                 break;
2043
2044         case ZPOOL_STATUS_UNSUP_FEAT_READ:
2045                 (void) printf(gettext("status: The pool uses the following "
2046                     "feature(s) not supported on this system:\n"));
2047                 zpool_print_unsup_feat(config);
2048                 break;
2049
2050         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2051                 (void) printf(gettext("status: The pool can only be accessed "
2052                     "in read-only mode on this system. It\n\tcannot be "
2053                     "accessed in read-write mode because it uses the "
2054                     "following\n\tfeature(s) not supported on this system:\n"));
2055                 zpool_print_unsup_feat(config);
2056                 break;
2057
2058         case ZPOOL_STATUS_HOSTID_ACTIVE:
2059                 (void) printf(gettext(" status: The pool is currently "
2060                     "imported by another system.\n"));
2061                 break;
2062
2063         case ZPOOL_STATUS_HOSTID_REQUIRED:
2064                 (void) printf(gettext(" status: The pool has the "
2065                     "multihost property on.  It cannot\n\tbe safely imported "
2066                     "when the system hostid is not set.\n"));
2067                 break;
2068
2069         case ZPOOL_STATUS_HOSTID_MISMATCH:
2070                 (void) printf(gettext(" status: The pool was last accessed by "
2071                     "another system.\n"));
2072                 break;
2073
2074         case ZPOOL_STATUS_FAULTED_DEV_R:
2075         case ZPOOL_STATUS_FAULTED_DEV_NR:
2076                 (void) printf(gettext(" status: One or more devices are "
2077                     "faulted.\n"));
2078                 break;
2079
2080         case ZPOOL_STATUS_BAD_LOG:
2081                 (void) printf(gettext(" status: An intent log record cannot be "
2082                     "read.\n"));
2083                 break;
2084
2085         case ZPOOL_STATUS_RESILVERING:
2086                 (void) printf(gettext(" status: One or more devices were being "
2087                     "resilvered.\n"));
2088                 break;
2089
2090         case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
2091                 (void) printf(gettext("status: One or more devices were "
2092                     "configured to use a non-native block size.\n"
2093                     "\tExpect reduced performance.\n"));
2094                 break;
2095
2096         default:
2097                 /*
2098                  * No other status can be seen when importing pools.
2099                  */
2100                 assert(reason == ZPOOL_STATUS_OK);
2101         }
2102
2103         /*
2104          * Print out an action according to the overall state of the pool.
2105          */
2106         if (vs->vs_state == VDEV_STATE_HEALTHY) {
2107                 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
2108                     reason == ZPOOL_STATUS_FEAT_DISABLED) {
2109                         (void) printf(gettext(" action: The pool can be "
2110                             "imported using its name or numeric identifier, "
2111                             "though\n\tsome features will not be available "
2112                             "without an explicit 'zpool upgrade'.\n"));
2113                 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
2114                         (void) printf(gettext(" action: The pool can be "
2115                             "imported using its name or numeric "
2116                             "identifier and\n\tthe '-f' flag.\n"));
2117                 } else {
2118                         (void) printf(gettext(" action: The pool can be "
2119                             "imported using its name or numeric "
2120                             "identifier.\n"));
2121                 }
2122         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
2123                 (void) printf(gettext(" action: The pool can be imported "
2124                     "despite missing or damaged devices.  The\n\tfault "
2125                     "tolerance of the pool may be compromised if imported.\n"));
2126         } else {
2127                 switch (reason) {
2128                 case ZPOOL_STATUS_VERSION_NEWER:
2129                         (void) printf(gettext(" action: The pool cannot be "
2130                             "imported.  Access the pool on a system running "
2131                             "newer\n\tsoftware, or recreate the pool from "
2132                             "backup.\n"));
2133                         break;
2134                 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2135                         (void) printf(gettext("action: The pool cannot be "
2136                             "imported. Access the pool on a system that "
2137                             "supports\n\tthe required feature(s), or recreate "
2138                             "the pool from backup.\n"));
2139                         break;
2140                 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2141                         (void) printf(gettext("action: The pool cannot be "
2142                             "imported in read-write mode. Import the pool "
2143                             "with\n"
2144                             "\t\"-o readonly=on\", access the pool on a system "
2145                             "that supports the\n\trequired feature(s), or "
2146                             "recreate the pool from backup.\n"));
2147                         break;
2148                 case ZPOOL_STATUS_MISSING_DEV_R:
2149                 case ZPOOL_STATUS_MISSING_DEV_NR:
2150                 case ZPOOL_STATUS_BAD_GUID_SUM:
2151                         (void) printf(gettext(" action: The pool cannot be "
2152                             "imported. Attach the missing\n\tdevices and try "
2153                             "again.\n"));
2154                         break;
2155                 case ZPOOL_STATUS_HOSTID_ACTIVE:
2156                         VERIFY0(nvlist_lookup_nvlist(config,
2157                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo));
2158
2159                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2160                                 hostname = fnvlist_lookup_string(nvinfo,
2161                                     ZPOOL_CONFIG_MMP_HOSTNAME);
2162
2163                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2164                                 hostid = fnvlist_lookup_uint64(nvinfo,
2165                                     ZPOOL_CONFIG_MMP_HOSTID);
2166
2167                         (void) printf(gettext(" action: The pool must be "
2168                             "exported from %s (hostid=%lx)\n\tbefore it "
2169                             "can be safely imported.\n"), hostname,
2170                             (unsigned long) hostid);
2171                         break;
2172                 case ZPOOL_STATUS_HOSTID_REQUIRED:
2173                         (void) printf(gettext(" action: Check the SMF "
2174                             "svc:/system/hostid service.\n"));
2175                         break;
2176                 default:
2177                         (void) printf(gettext(" action: The pool cannot be "
2178                             "imported due to damaged devices or data.\n"));
2179                 }
2180         }
2181
2182         /* Print the comment attached to the pool. */
2183         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
2184                 (void) printf(gettext("comment: %s\n"), comment);
2185
2186         /*
2187          * If the state is "closed" or "can't open", and the aux state
2188          * is "corrupt data":
2189          */
2190         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
2191             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
2192             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
2193                 if (pool_state == POOL_STATE_DESTROYED)
2194                         (void) printf(gettext("\tThe pool was destroyed, "
2195                             "but can be imported using the '-Df' flags.\n"));
2196                 else if (pool_state != POOL_STATE_EXPORTED)
2197                         (void) printf(gettext("\tThe pool may be active on "
2198                             "another system, but can be imported using\n\t"
2199                             "the '-f' flag.\n"));
2200         }
2201
2202         if (msgid != NULL)
2203                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
2204                     msgid);
2205
2206         (void) printf(gettext(" config:\n\n"));
2207
2208         cb.cb_namewidth = max_width(NULL, nvroot, 0, 0, 0);
2209         if (cb.cb_namewidth < 10)
2210                 cb.cb_namewidth = 10;
2211
2212         print_import_config(&cb, name, nvroot, 0);
2213
2214         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP);
2215         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
2216         print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS);
2217
2218         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
2219                 (void) printf(gettext("\n\tAdditional devices are known to "
2220                     "be part of this pool, though their\n\texact "
2221                     "configuration cannot be determined.\n"));
2222         }
2223 }
2224
2225 static boolean_t
2226 zfs_force_import_required(nvlist_t *config)
2227 {
2228         uint64_t state;
2229         uint64_t hostid = 0;
2230         nvlist_t *nvinfo;
2231
2232         state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2233         (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
2234
2235         if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid())
2236                 return (B_TRUE);
2237
2238         nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2239         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) {
2240                 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo,
2241                     ZPOOL_CONFIG_MMP_STATE);
2242
2243                 if (mmp_state != MMP_STATE_INACTIVE)
2244                         return (B_TRUE);
2245         }
2246
2247         return (B_FALSE);
2248 }
2249
2250 /*
2251  * Perform the import for the given configuration.  This passes the heavy
2252  * lifting off to zpool_import_props(), and then mounts the datasets contained
2253  * within the pool.
2254  */
2255 static int
2256 do_import(nvlist_t *config, const char *newname, const char *mntopts,
2257     nvlist_t *props, int flags)
2258 {
2259         zpool_handle_t *zhp;
2260         char *name;
2261         uint64_t version;
2262
2263         name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2264         version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2265
2266         if (!SPA_VERSION_IS_SUPPORTED(version)) {
2267                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
2268                     "is formatted using an unsupported ZFS version\n"), name);
2269                 return (1);
2270         } else if (zfs_force_import_required(config) &&
2271             !(flags & ZFS_IMPORT_ANY_HOST)) {
2272                 mmp_state_t mmp_state = MMP_STATE_INACTIVE;
2273                 nvlist_t *nvinfo;
2274
2275                 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2276                 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE))
2277                         mmp_state = fnvlist_lookup_uint64(nvinfo,
2278                             ZPOOL_CONFIG_MMP_STATE);
2279
2280                 if (mmp_state == MMP_STATE_ACTIVE) {
2281                         char *hostname = "<unknown>";
2282                         uint64_t hostid = 0;
2283
2284                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2285                                 hostname = fnvlist_lookup_string(nvinfo,
2286                                     ZPOOL_CONFIG_MMP_HOSTNAME);
2287
2288                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2289                                 hostid = fnvlist_lookup_uint64(nvinfo,
2290                                     ZPOOL_CONFIG_MMP_HOSTID);
2291
2292                         (void) fprintf(stderr, gettext("cannot import '%s': "
2293                             "pool is imported on %s (hostid: "
2294                             "0x%lx)\nExport the pool on the other system, "
2295                             "then run 'zpool import'.\n"),
2296                             name, hostname, (unsigned long) hostid);
2297                 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2298                         (void) fprintf(stderr, gettext("Cannot import '%s': "
2299                             "pool has the multihost property on and the\n"
2300                             "system's hostid is not set.\n"), name);
2301                 } else {
2302                         char *hostname = "<unknown>";
2303                         uint64_t timestamp = 0;
2304                         uint64_t hostid = 0;
2305
2306                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME))
2307                                 hostname = fnvlist_lookup_string(config,
2308                                     ZPOOL_CONFIG_HOSTNAME);
2309
2310                         if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP))
2311                                 timestamp = fnvlist_lookup_uint64(config,
2312                                     ZPOOL_CONFIG_TIMESTAMP);
2313
2314                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID))
2315                                 hostid = fnvlist_lookup_uint64(config,
2316                                     ZPOOL_CONFIG_HOSTID);
2317
2318                         (void) fprintf(stderr, gettext("cannot import '%s': "
2319                             "pool was previously in use from another system.\n"
2320                             "Last accessed by %s (hostid=%lx) at %s"
2321                             "The pool can be imported, use 'zpool import -f' "
2322                             "to import the pool.\n"), name, hostname,
2323                             (unsigned long)hostid, ctime((time_t *)&timestamp));
2324
2325                 }
2326
2327                 return (1);
2328         }
2329
2330         if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2331                 return (1);
2332
2333         if (newname != NULL)
2334                 name = (char *)newname;
2335
2336         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2337                 return (1);
2338
2339         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2340             !(flags & ZFS_IMPORT_ONLY) &&
2341             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2342                 zpool_close(zhp);
2343                 return (1);
2344         }
2345
2346         zpool_close(zhp);
2347         return (0);
2348 }
2349
2350 /*
2351  * zpool checkpoint <pool>
2352  *       checkpoint --discard <pool>
2353  *
2354  *      -d      Discard the checkpoint from a checkpointed
2355  *      --discard  pool.
2356  *
2357  * Checkpoints the specified pool, by taking a "snapshot" of its
2358  * current state. A pool can only have one checkpoint at a time.
2359  */
2360 int
2361 zpool_do_checkpoint(int argc, char **argv)
2362 {
2363         boolean_t discard;
2364         char *pool;
2365         zpool_handle_t *zhp;
2366         int c, err;
2367
2368         struct option long_options[] = {
2369                 {"discard", no_argument, NULL, 'd'},
2370                 {0, 0, 0, 0}
2371         };
2372
2373         discard = B_FALSE;
2374         while ((c = getopt_long(argc, argv, ":d", long_options, NULL)) != -1) {
2375                 switch (c) {
2376                 case 'd':
2377                         discard = B_TRUE;
2378                         break;
2379                 case '?':
2380                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2381                             optopt);
2382                         usage(B_FALSE);
2383                 }
2384         }
2385
2386         argc -= optind;
2387         argv += optind;
2388
2389         if (argc < 1) {
2390                 (void) fprintf(stderr, gettext("missing pool argument\n"));
2391                 usage(B_FALSE);
2392         }
2393
2394         if (argc > 1) {
2395                 (void) fprintf(stderr, gettext("too many arguments\n"));
2396                 usage(B_FALSE);
2397         }
2398
2399         pool = argv[0];
2400
2401         if ((zhp = zpool_open(g_zfs, pool)) == NULL) {
2402                 /* As a special case, check for use of '/' in the name */
2403                 if (strchr(pool, '/') != NULL)
2404                         (void) fprintf(stderr, gettext("'zpool checkpoint' "
2405                             "doesn't work on datasets. To save the state "
2406                             "of a dataset from a specific point in time "
2407                             "please use 'zfs snapshot'\n"));
2408                 return (1);
2409         }
2410
2411         if (discard)
2412                 err = (zpool_discard_checkpoint(zhp) != 0);
2413         else
2414                 err = (zpool_checkpoint(zhp) != 0);
2415
2416         zpool_close(zhp);
2417
2418         return (err);
2419 }
2420
2421 #define CHECKPOINT_OPT  1024
2422
2423 /*
2424  * zpool import [-d dir] [-D]
2425  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2426  *              [-d dir | -c cachefile] [-f] -a
2427  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2428  *              [-d dir | -c cachefile] [-f] [-n] [-F] [-t]
2429  *              <pool | id> [newpool]
2430  *
2431  *      -c      Read pool information from a cachefile instead of searching
2432  *              devices.
2433  *
2434  *      -d      Scan in a specific directory, other than /dev/dsk.  More than
2435  *              one directory can be specified using multiple '-d' options.
2436  *
2437  *      -D      Scan for previously destroyed pools or import all or only
2438  *              specified destroyed pools.
2439  *
2440  *      -R      Temporarily import the pool, with all mountpoints relative to
2441  *              the given root.  The pool will remain exported when the machine
2442  *              is rebooted.
2443  *
2444  *      -V      Import even in the presence of faulted vdevs.  This is an
2445  *              intentionally undocumented option for testing purposes, and
2446  *              treats the pool configuration as complete, leaving any bad
2447  *              vdevs in the FAULTED state. In other words, it does verbatim
2448  *              import.
2449  *
2450  *      -f      Force import, even if it appears that the pool is active.
2451  *
2452  *      -F      Attempt rewind if necessary.
2453  *
2454  *      -n      See if rewind would work, but don't actually rewind.
2455  *
2456  *      -N      Import the pool but don't mount datasets.
2457  *
2458  *      -t      Use newpool as a temporary pool name instead of renaming
2459  *              the pool.
2460  *
2461  *      -T      Specify a starting txg to use for import. This option is
2462  *              intentionally undocumented option for testing purposes.
2463  *
2464  *      -a      Import all pools found.
2465  *
2466  *      -o      Set property=value and/or temporary mount options (without '=').
2467  *
2468  *      --rewind-to-checkpoint
2469  *              Import the pool and revert back to the checkpoint.
2470  *
2471  * The import command scans for pools to import, and import pools based on pool
2472  * name and GUID.  The pool can also be renamed as part of the import process.
2473  */
2474 int
2475 zpool_do_import(int argc, char **argv)
2476 {
2477         char **searchdirs = NULL;
2478         int nsearch = 0;
2479         int c;
2480         int err = 0;
2481         nvlist_t *pools = NULL;
2482         boolean_t do_all = B_FALSE;
2483         boolean_t do_destroyed = B_FALSE;
2484         char *mntopts = NULL;
2485         nvpair_t *elem;
2486         nvlist_t *config;
2487         uint64_t searchguid = 0;
2488         char *searchname = NULL;
2489         char *propval;
2490         nvlist_t *found_config;
2491         nvlist_t *policy = NULL;
2492         nvlist_t *props = NULL;
2493         boolean_t first;
2494         int flags = ZFS_IMPORT_NORMAL;
2495         uint32_t rewind_policy = ZPOOL_NO_REWIND;
2496         boolean_t dryrun = B_FALSE;
2497         boolean_t do_rewind = B_FALSE;
2498         boolean_t xtreme_rewind = B_FALSE;
2499         uint64_t pool_state, txg = -1ULL;
2500         char *cachefile = NULL;
2501         importargs_t idata = { 0 };
2502         char *endptr;
2503
2504
2505         struct option long_options[] = {
2506                 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT},
2507                 {0, 0, 0, 0}
2508         };
2509
2510         /* check options */
2511         while ((c = getopt_long(argc, argv, ":aCc:d:DEfFmnNo:rR:tT:VX",
2512             long_options, NULL)) != -1) {
2513                 switch (c) {
2514                 case 'a':
2515                         do_all = B_TRUE;
2516                         break;
2517                 case 'c':
2518                         cachefile = optarg;
2519                         break;
2520                 case 'd':
2521                         if (searchdirs == NULL) {
2522                                 searchdirs = safe_malloc(sizeof (char *));
2523                         } else {
2524                                 char **tmp = safe_malloc((nsearch + 1) *
2525                                     sizeof (char *));
2526                                 bcopy(searchdirs, tmp, nsearch *
2527                                     sizeof (char *));
2528                                 free(searchdirs);
2529                                 searchdirs = tmp;
2530                         }
2531                         searchdirs[nsearch++] = optarg;
2532                         break;
2533                 case 'D':
2534                         do_destroyed = B_TRUE;
2535                         break;
2536                 case 'f':
2537                         flags |= ZFS_IMPORT_ANY_HOST;
2538                         break;
2539                 case 'F':
2540                         do_rewind = B_TRUE;
2541                         break;
2542                 case 'm':
2543                         flags |= ZFS_IMPORT_MISSING_LOG;
2544                         break;
2545                 case 'n':
2546                         dryrun = B_TRUE;
2547                         break;
2548                 case 'N':
2549                         flags |= ZFS_IMPORT_ONLY;
2550                         break;
2551                 case 'o':
2552                         if ((propval = strchr(optarg, '=')) != NULL) {
2553                                 *propval = '\0';
2554                                 propval++;
2555                                 if (add_prop_list(optarg, propval,
2556                                     &props, B_TRUE))
2557                                         goto error;
2558                         } else {
2559                                 mntopts = optarg;
2560                         }
2561                         break;
2562                 case 'R':
2563                         if (add_prop_list(zpool_prop_to_name(
2564                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2565                                 goto error;
2566                         if (add_prop_list_default(zpool_prop_to_name(
2567                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2568                                 goto error;
2569                         break;
2570                 case 't':
2571                         flags |= ZFS_IMPORT_TEMP_NAME;
2572                         if (add_prop_list_default(zpool_prop_to_name(
2573                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2574                                 goto error;
2575                         break;
2576                 case 'T':
2577                         errno = 0;
2578                         txg = strtoull(optarg, &endptr, 0);
2579                         if (errno != 0 || *endptr != '\0') {
2580                                 (void) fprintf(stderr,
2581                                     gettext("invalid txg value\n"));
2582                                 usage(B_FALSE);
2583                         }
2584                         rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2585                         break;
2586                 case 'V':
2587                         flags |= ZFS_IMPORT_VERBATIM;
2588                         break;
2589                 case 'X':
2590                         xtreme_rewind = B_TRUE;
2591                         break;
2592                 case CHECKPOINT_OPT:
2593                         flags |= ZFS_IMPORT_CHECKPOINT;
2594                         break;
2595                 case ':':
2596                         (void) fprintf(stderr, gettext("missing argument for "
2597                             "'%c' option\n"), optopt);
2598                         usage(B_FALSE);
2599                         break;
2600                 case '?':
2601                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2602                             optopt);
2603                         usage(B_FALSE);
2604                 }
2605         }
2606
2607         argc -= optind;
2608         argv += optind;
2609
2610         if (cachefile && nsearch != 0) {
2611                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2612                 usage(B_FALSE);
2613         }
2614
2615         if ((dryrun || xtreme_rewind) && !do_rewind) {
2616                 (void) fprintf(stderr,
2617                     gettext("-n or -X only meaningful with -F\n"));
2618                 usage(B_FALSE);
2619         }
2620         if (dryrun)
2621                 rewind_policy = ZPOOL_TRY_REWIND;
2622         else if (do_rewind)
2623                 rewind_policy = ZPOOL_DO_REWIND;
2624         if (xtreme_rewind)
2625                 rewind_policy |= ZPOOL_EXTREME_REWIND;
2626
2627         /* In the future, we can capture further policy and include it here */
2628         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2629             nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 ||
2630             nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
2631             rewind_policy) != 0)
2632                 goto error;
2633
2634         if (searchdirs == NULL) {
2635                 searchdirs = safe_malloc(sizeof (char *));
2636                 searchdirs[0] = "/dev";
2637                 nsearch = 1;
2638         }
2639
2640         /* check argument count */
2641         if (do_all) {
2642                 if (argc != 0) {
2643                         (void) fprintf(stderr, gettext("too many arguments\n"));
2644                         usage(B_FALSE);
2645                 }
2646         } else {
2647                 if (argc > 2) {
2648                         (void) fprintf(stderr, gettext("too many arguments\n"));
2649                         usage(B_FALSE);
2650                 }
2651
2652                 /*
2653                  * Check for the SYS_CONFIG privilege.  We do this explicitly
2654                  * here because otherwise any attempt to discover pools will
2655                  * silently fail.
2656                  */
2657                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
2658                         (void) fprintf(stderr, gettext("cannot "
2659                             "discover pools: permission denied\n"));
2660                         free(searchdirs);
2661                         nvlist_free(policy);
2662                         return (1);
2663                 }
2664         }
2665
2666         /*
2667          * Depending on the arguments given, we do one of the following:
2668          *
2669          *      <none>  Iterate through all pools and display information about
2670          *              each one.
2671          *
2672          *      -a      Iterate through all pools and try to import each one.
2673          *
2674          *      <id>    Find the pool that corresponds to the given GUID/pool
2675          *              name and import that one.
2676          *
2677          *      -D      Above options applies only to destroyed pools.
2678          */
2679         if (argc != 0) {
2680                 char *endptr;
2681
2682                 errno = 0;
2683                 searchguid = strtoull(argv[0], &endptr, 10);
2684                 if (errno != 0 || *endptr != '\0') {
2685                         searchname = argv[0];
2686                         searchguid = 0;
2687                 }
2688                 found_config = NULL;
2689
2690                 /*
2691                  * User specified a name or guid.  Ensure it's unique.
2692                  */
2693                 idata.unique = B_TRUE;
2694         }
2695
2696
2697         idata.path = searchdirs;
2698         idata.paths = nsearch;
2699         idata.poolname = searchname;
2700         idata.guid = searchguid;
2701         idata.cachefile = cachefile;
2702         idata.policy = policy;
2703
2704         pools = zpool_search_import(g_zfs, &idata);
2705
2706         if (pools != NULL && idata.exists &&
2707             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2708                 (void) fprintf(stderr, gettext("cannot import '%s': "
2709                     "a pool with that name already exists\n"),
2710                     argv[0]);
2711                 (void) fprintf(stderr, gettext("use the form 'zpool import "
2712                     "[-t] <pool | id> <newpool>' to give it a new temporary "
2713                     "or permanent name\n"));
2714                 err = 1;
2715         } else if (pools == NULL && idata.exists) {
2716                 (void) fprintf(stderr, gettext("cannot import '%s': "
2717                     "a pool with that name is already created/imported,\n"),
2718                     argv[0]);
2719                 (void) fprintf(stderr, gettext("and no additional pools "
2720                     "with that name were found\n"));
2721                 err = 1;
2722         } else if (pools == NULL) {
2723                 if (argc != 0) {
2724                         (void) fprintf(stderr, gettext("cannot import '%s': "
2725                             "no such pool available\n"), argv[0]);
2726                 }
2727                 err = 1;
2728         }
2729
2730         if (err == 1) {
2731                 free(searchdirs);
2732                 nvlist_free(policy);
2733                 return (1);
2734         }
2735
2736         /*
2737          * At this point we have a list of import candidate configs. Even if
2738          * we were searching by pool name or guid, we still need to
2739          * post-process the list to deal with pool state and possible
2740          * duplicate names.
2741          */
2742         err = 0;
2743         elem = NULL;
2744         first = B_TRUE;
2745         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2746
2747                 verify(nvpair_value_nvlist(elem, &config) == 0);
2748
2749                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2750                     &pool_state) == 0);
2751                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2752                         continue;
2753                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2754                         continue;
2755
2756                 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
2757                     policy) == 0);
2758
2759                 if (argc == 0) {
2760                         if (first)
2761                                 first = B_FALSE;
2762                         else if (!do_all)
2763                                 (void) printf("\n");
2764
2765                         if (do_all) {
2766                                 err |= do_import(config, NULL, mntopts,
2767                                     props, flags);
2768                         } else {
2769                                 show_import(config);
2770                         }
2771                 } else if (searchname != NULL) {
2772                         char *name;
2773
2774                         /*
2775                          * We are searching for a pool based on name.
2776                          */
2777                         verify(nvlist_lookup_string(config,
2778                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2779
2780                         if (strcmp(name, searchname) == 0) {
2781                                 if (found_config != NULL) {
2782                                         (void) fprintf(stderr, gettext(
2783                                             "cannot import '%s': more than "
2784                                             "one matching pool\n"), searchname);
2785                                         (void) fprintf(stderr, gettext(
2786                                             "import by numeric ID instead\n"));
2787                                         err = B_TRUE;
2788                                 }
2789                                 found_config = config;
2790                         }
2791                 } else {
2792                         uint64_t guid;
2793
2794                         /*
2795                          * Search for a pool by guid.
2796                          */
2797                         verify(nvlist_lookup_uint64(config,
2798                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2799
2800                         if (guid == searchguid)
2801                                 found_config = config;
2802                 }
2803         }
2804
2805         /*
2806          * If we were searching for a specific pool, verify that we found a
2807          * pool, and then do the import.
2808          */
2809         if (argc != 0 && err == 0) {
2810                 if (found_config == NULL) {
2811                         (void) fprintf(stderr, gettext("cannot import '%s': "
2812                             "no such pool available\n"), argv[0]);
2813                         err = B_TRUE;
2814                 } else {
2815                         err |= do_import(found_config, argc == 1 ? NULL :
2816                             argv[1], mntopts, props, flags);
2817                 }
2818         }
2819
2820         /*
2821          * If we were just looking for pools, report an error if none were
2822          * found.
2823          */
2824         if (argc == 0 && first)
2825                 (void) fprintf(stderr,
2826                     gettext("no pools available to import\n"));
2827
2828 error:
2829         nvlist_free(props);
2830         nvlist_free(pools);
2831         nvlist_free(policy);
2832         free(searchdirs);
2833
2834         return (err ? 1 : 0);
2835 }
2836
2837 /*
2838  * zpool sync [-f] [pool] ...
2839  *
2840  * -f (undocumented) force uberblock (and config including zpool cache file)
2841  *    update.
2842  *
2843  * Sync the specified pool(s).
2844  * Without arguments "zpool sync" will sync all pools.
2845  * This command initiates TXG sync(s) and will return after the TXG(s) commit.
2846  *
2847  */
2848 static int
2849 zpool_do_sync(int argc, char **argv)
2850 {
2851         int ret;
2852         boolean_t force = B_FALSE;
2853
2854         /* check options */
2855         while ((ret  = getopt(argc, argv, "f")) != -1) {
2856                 switch (ret) {
2857                 case 'f':
2858                         force = B_TRUE;
2859                         break;
2860                 case '?':
2861                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2862                             optopt);
2863                         usage(B_FALSE);
2864                 }
2865         }
2866
2867         argc -= optind;
2868         argv += optind;
2869
2870         /* if argc == 0 we will execute zpool_sync_one on all pools */
2871         ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
2872
2873         return (ret);
2874 }
2875
2876 typedef struct iostat_cbdata {
2877         boolean_t cb_verbose;
2878         int cb_name_flags;
2879         int cb_namewidth;
2880         int cb_iteration;
2881         boolean_t cb_scripted;
2882         zpool_list_t *cb_list;
2883 } iostat_cbdata_t;
2884
2885 static void
2886 print_iostat_separator(iostat_cbdata_t *cb)
2887 {
2888         int i = 0;
2889
2890         for (i = 0; i < cb->cb_namewidth; i++)
2891                 (void) printf("-");
2892         (void) printf("  -----  -----  -----  -----  -----  -----\n");
2893 }
2894
2895 static void
2896 print_iostat_header(iostat_cbdata_t *cb)
2897 {
2898         (void) printf("%*s     capacity     operations    bandwidth\n",
2899             cb->cb_namewidth, "");
2900         (void) printf("%-*s  alloc   free   read  write   read  write\n",
2901             cb->cb_namewidth, "pool");
2902         print_iostat_separator(cb);
2903 }
2904
2905 /*
2906  * Display a single statistic.
2907  */
2908 static void
2909 print_one_stat(uint64_t value)
2910 {
2911         char buf[64];
2912
2913         zfs_nicenum(value, buf, sizeof (buf));
2914         (void) printf("  %5s", buf);
2915 }
2916
2917 static const char *class_name[] = {
2918         VDEV_ALLOC_BIAS_DEDUP,
2919         VDEV_ALLOC_BIAS_SPECIAL,
2920         VDEV_ALLOC_CLASS_LOGS
2921 };
2922
2923 /*
2924  * Print out all the statistics for the given vdev.  This can either be the
2925  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
2926  * is a verbose output, and we don't want to display the toplevel pool stats.
2927  *
2928  * Returns the number of stat lines printed.
2929  */
2930 static unsigned int
2931 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2932     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2933 {
2934         nvlist_t **oldchild, **newchild;
2935         uint_t c, children;
2936         vdev_stat_t *oldvs, *newvs;
2937         vdev_stat_t zerovs = { 0 };
2938         char *vname;
2939         int ret = 0;
2940         uint64_t tdelta;
2941         double scale;
2942
2943         if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
2944                 return (ret);
2945
2946         if (oldnv != NULL) {
2947                 verify(nvlist_lookup_uint64_array(oldnv,
2948                     ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2949         } else {
2950                 oldvs = &zerovs;
2951         }
2952
2953         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2954             (uint64_t **)&newvs, &c) == 0);
2955
2956         if (strlen(name) + depth > cb->cb_namewidth)
2957                 (void) printf("%*s%s", depth, "", name);
2958         else
2959                 (void) printf("%*s%s%*s", depth, "", name,
2960                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
2961
2962         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2963
2964         if (tdelta == 0)
2965                 scale = 1.0;
2966         else
2967                 scale = (double)NANOSEC / tdelta;
2968
2969         /* only toplevel vdevs have capacity stats */
2970         if (newvs->vs_space == 0) {
2971                 (void) printf("      -      -");
2972         } else {
2973                 print_one_stat(newvs->vs_alloc);
2974                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
2975         }
2976
2977         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2978             oldvs->vs_ops[ZIO_TYPE_READ])));
2979
2980         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2981             oldvs->vs_ops[ZIO_TYPE_WRITE])));
2982
2983         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2984             oldvs->vs_bytes[ZIO_TYPE_READ])));
2985
2986         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2987             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2988
2989         (void) printf("\n");
2990
2991         if (!cb->cb_verbose)
2992                 return (ret);
2993
2994         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2995             &newchild, &children) != 0)
2996                 return (ret);
2997
2998         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2999             &oldchild, &c) != 0)
3000                 return (ret);
3001
3002         /*
3003          * print normal top-level devices
3004          */
3005         for (c = 0; c < children; c++) {
3006                 uint64_t ishole = B_FALSE, islog = B_FALSE;
3007
3008                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
3009                     &ishole);
3010
3011                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
3012                     &islog);
3013
3014                 if (ishole || islog)
3015                         continue;
3016
3017                 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
3018                         continue;
3019
3020                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3021                     cb->cb_name_flags);
3022                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
3023                     newchild[c], cb, depth + 2);
3024                 free(vname);
3025         }
3026
3027         /*
3028          * print all other top-level devices
3029          */
3030         for (uint_t n = 0; n < 3; n++) {
3031                 for (c = 0; c < children; c++) {
3032                         uint64_t islog = B_FALSE;
3033                         char *bias = NULL;
3034                         char *type = NULL;
3035
3036                         (void) nvlist_lookup_uint64(newchild[c],
3037                             ZPOOL_CONFIG_IS_LOG, &islog);
3038                         if (islog) {
3039                                 bias = VDEV_ALLOC_CLASS_LOGS;
3040                         } else {
3041                                 (void) nvlist_lookup_string(newchild[c],
3042                                     ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
3043                                 (void) nvlist_lookup_string(newchild[c],
3044                                     ZPOOL_CONFIG_TYPE, &type);
3045                         }
3046                         if (bias == NULL || strcmp(bias, class_name[n]) != 0)
3047                                 continue;
3048                         if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
3049                                 continue;
3050
3051                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3052                             cb->cb_name_flags);
3053                         ret += print_vdev_stats(zhp, vname, oldnv ?
3054                             oldchild[c] : NULL, newchild[c], cb, depth + 2);
3055                         free(vname);
3056                 }
3057
3058         }
3059
3060         /*
3061          * Include level 2 ARC devices in iostat output
3062          */
3063         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
3064             &newchild, &children) != 0)
3065                 return (ret);
3066
3067         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
3068             &oldchild, &c) != 0)
3069                 return (ret);
3070
3071         if (children > 0) {
3072                 (void) printf("%-*s      -      -      -      -      -      "
3073                     "-\n", cb->cb_namewidth, "cache");
3074                 for (c = 0; c < children; c++) {
3075                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3076                             cb->cb_name_flags);
3077                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
3078                             newchild[c], cb, depth + 2);
3079                         free(vname);
3080                 }
3081         }
3082
3083         return (ret);
3084 }
3085
3086 static int
3087 refresh_iostat(zpool_handle_t *zhp, void *data)
3088 {
3089         iostat_cbdata_t *cb = data;
3090         boolean_t missing;
3091
3092         /*
3093          * If the pool has disappeared, remove it from the list and continue.
3094          */
3095         if (zpool_refresh_stats(zhp, &missing) != 0)
3096                 return (-1);
3097
3098         if (missing)
3099                 pool_list_remove(cb->cb_list, zhp);
3100
3101         return (0);
3102 }
3103
3104 /*
3105  * Callback to print out the iostats for the given pool.
3106  */
3107 int
3108 print_iostat(zpool_handle_t *zhp, void *data)
3109 {
3110         iostat_cbdata_t *cb = data;
3111         nvlist_t *oldconfig, *newconfig;
3112         nvlist_t *oldnvroot, *newnvroot;
3113
3114         newconfig = zpool_get_config(zhp, &oldconfig);
3115
3116         if (cb->cb_iteration == 1)
3117                 oldconfig = NULL;
3118
3119         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
3120             &newnvroot) == 0);
3121
3122         if (oldconfig == NULL)
3123                 oldnvroot = NULL;
3124         else
3125                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
3126                     &oldnvroot) == 0);
3127
3128         /*
3129          * Print out the statistics for the pool.
3130          */
3131         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
3132
3133         if (cb->cb_verbose)
3134                 print_iostat_separator(cb);
3135
3136         return (0);
3137 }
3138
3139 int
3140 get_namewidth(zpool_handle_t *zhp, void *data)
3141 {
3142         iostat_cbdata_t *cb = data;
3143         nvlist_t *config, *nvroot;
3144
3145         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
3146                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3147                     &nvroot) == 0);
3148                 if (!cb->cb_verbose)
3149                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
3150                 else
3151                         cb->cb_namewidth = max_width(zhp, nvroot, 0,
3152                             cb->cb_namewidth, cb->cb_name_flags);
3153         }
3154
3155         /*
3156          * The width must fall into the range [10,38].  The upper limit is the
3157          * maximum we can have and still fit in 80 columns.
3158          */
3159         if (cb->cb_namewidth < 10)
3160                 cb->cb_namewidth = 10;
3161         if (cb->cb_namewidth > 38)
3162                 cb->cb_namewidth = 38;
3163
3164         return (0);
3165 }
3166
3167 /*
3168  * Parse the input string, get the 'interval' and 'count' value if there is one.
3169  */
3170 static void
3171 get_interval_count(int *argcp, char **argv, unsigned long *iv,
3172     unsigned long *cnt)
3173 {
3174         unsigned long interval = 0, count = 0;
3175         int argc = *argcp, errno;
3176
3177         /*
3178          * Determine if the last argument is an integer or a pool name
3179          */
3180         if (argc > 0 && isdigit(argv[argc - 1][0])) {
3181                 char *end;
3182
3183                 errno = 0;
3184                 interval = strtoul(argv[argc - 1], &end, 10);
3185
3186                 if (*end == '\0' && errno == 0) {
3187                         if (interval == 0) {
3188                                 (void) fprintf(stderr, gettext("interval "
3189                                     "cannot be zero\n"));
3190                                 usage(B_FALSE);
3191                         }
3192                         /*
3193                          * Ignore the last parameter
3194                          */
3195                         argc--;
3196                 } else {
3197                         /*
3198                          * If this is not a valid number, just plow on.  The
3199                          * user will get a more informative error message later
3200                          * on.
3201                          */
3202                         interval = 0;
3203                 }
3204         }
3205
3206         /*
3207          * If the last argument is also an integer, then we have both a count
3208          * and an interval.
3209          */
3210         if (argc > 0 && isdigit(argv[argc - 1][0])) {
3211                 char *end;
3212
3213                 errno = 0;
3214                 count = interval;
3215                 interval = strtoul(argv[argc - 1], &end, 10);
3216
3217                 if (*end == '\0' && errno == 0) {
3218                         if (interval == 0) {
3219                                 (void) fprintf(stderr, gettext("interval "
3220                                     "cannot be zero\n"));
3221                                 usage(B_FALSE);
3222                         }
3223
3224                         /*
3225                          * Ignore the last parameter
3226                          */
3227                         argc--;
3228                 } else {
3229                         interval = 0;
3230                 }
3231         }
3232
3233         *iv = interval;
3234         *cnt = count;
3235         *argcp = argc;
3236 }
3237
3238 static void
3239 get_timestamp_arg(char c)
3240 {
3241         if (c == 'u')
3242                 timestamp_fmt = UDATE;
3243         else if (c == 'd')
3244                 timestamp_fmt = DDATE;
3245         else
3246                 usage(B_FALSE);
3247 }
3248
3249 /*
3250  * zpool iostat [-gLPv] [-T d|u] [pool] ... [interval [count]]
3251  *
3252  *      -g      Display guid for individual vdev name.
3253  *      -L      Follow links when resolving vdev path name.
3254  *      -P      Display full path for vdev name.
3255  *      -v      Display statistics for individual vdevs
3256  *      -T      Display a timestamp in date(1) or Unix format
3257  *
3258  * This command can be tricky because we want to be able to deal with pool
3259  * creation/destruction as well as vdev configuration changes.  The bulk of this
3260  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
3261  * on pool_list_update() to detect the addition of new pools.  Configuration
3262  * changes are all handled within libzfs.
3263  */
3264 int
3265 zpool_do_iostat(int argc, char **argv)
3266 {
3267         int c;
3268         int ret;
3269         int npools;
3270         unsigned long interval = 0, count = 0;
3271         zpool_list_t *list;
3272         boolean_t verbose = B_FALSE;
3273         boolean_t guid = B_FALSE;
3274         boolean_t follow_links = B_FALSE;
3275         boolean_t full_name = B_FALSE;
3276         iostat_cbdata_t cb = { 0 };
3277
3278         /* check options */
3279         while ((c = getopt(argc, argv, "gLPT:v")) != -1) {
3280                 switch (c) {
3281                 case 'g':
3282                         guid = B_TRUE;
3283                         break;
3284                 case 'L':
3285                         follow_links = B_TRUE;
3286                         break;
3287                 case 'P':
3288                         full_name = B_TRUE;
3289                         break;
3290                 case 'T':
3291                         get_timestamp_arg(*optarg);
3292                         break;
3293                 case 'v':
3294                         verbose = B_TRUE;
3295                         break;
3296                 case '?':
3297                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3298                             optopt);
3299                         usage(B_FALSE);
3300                 }
3301         }
3302
3303         argc -= optind;
3304         argv += optind;
3305
3306         get_interval_count(&argc, argv, &interval, &count);
3307
3308         /*
3309          * Construct the list of all interesting pools.
3310          */
3311         ret = 0;
3312         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
3313                 return (1);
3314
3315         if (pool_list_count(list) == 0 && argc != 0) {
3316                 pool_list_free(list);
3317                 return (1);
3318         }
3319
3320         if (pool_list_count(list) == 0 && interval == 0) {
3321                 pool_list_free(list);
3322                 (void) fprintf(stderr, gettext("no pools available\n"));
3323                 return (1);
3324         }
3325
3326         /*
3327          * Enter the main iostat loop.
3328          */
3329         cb.cb_list = list;
3330         cb.cb_verbose = verbose;
3331         if (guid)
3332                 cb.cb_name_flags |= VDEV_NAME_GUID;
3333         if (follow_links)
3334                 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
3335         if (full_name)
3336                 cb.cb_name_flags |= VDEV_NAME_PATH;
3337         cb.cb_iteration = 0;
3338         cb.cb_namewidth = 0;
3339
3340         for (;;) {
3341                 pool_list_update(list);
3342
3343                 if ((npools = pool_list_count(list)) == 0)
3344                         break;
3345
3346                 /*
3347                  * Refresh all statistics.  This is done as an explicit step
3348                  * before calculating the maximum name width, so that any
3349                  * configuration changes are properly accounted for.
3350                  */
3351                 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
3352
3353                 /*
3354                  * Iterate over all pools to determine the maximum width
3355                  * for the pool / device name column across all pools.
3356                  */
3357                 cb.cb_namewidth = 0;
3358                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
3359
3360                 if (timestamp_fmt != NODATE)
3361                         print_timestamp(timestamp_fmt);
3362
3363                 /*
3364                  * If it's the first time, or verbose mode, print the header.
3365                  */
3366                 if (++cb.cb_iteration == 1 || verbose)
3367                         print_iostat_header(&cb);
3368
3369                 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
3370
3371                 /*
3372                  * If there's more than one pool, and we're not in verbose mode
3373                  * (which prints a separator for us), then print a separator.
3374                  */
3375                 if (npools > 1 && !verbose)
3376                         print_iostat_separator(&cb);
3377
3378                 if (verbose)
3379                         (void) printf("\n");
3380
3381                 /*
3382                  * Flush the output so that redirection to a file isn't buffered
3383                  * indefinitely.
3384                  */
3385                 (void) fflush(stdout);
3386
3387                 if (interval == 0)
3388                         break;
3389
3390                 if (count != 0 && --count == 0)
3391                         break;
3392
3393                 (void) sleep(interval);
3394         }
3395
3396         pool_list_free(list);
3397
3398         return (ret);
3399 }
3400
3401 typedef struct list_cbdata {
3402         boolean_t       cb_verbose;
3403         int             cb_name_flags;
3404         int             cb_namewidth;
3405         boolean_t       cb_scripted;
3406         zprop_list_t    *cb_proplist;
3407         boolean_t       cb_literal;
3408 } list_cbdata_t;
3409
3410
3411 /*
3412  * Given a list of columns to display, output appropriate headers for each one.
3413  */
3414 static void
3415 print_header(list_cbdata_t *cb)
3416 {
3417         zprop_list_t *pl = cb->cb_proplist;
3418         char headerbuf[ZPOOL_MAXPROPLEN];
3419         const char *header;
3420         boolean_t first = B_TRUE;
3421         boolean_t right_justify;
3422         size_t width = 0;
3423
3424         for (; pl != NULL; pl = pl->pl_next) {
3425                 width = pl->pl_width;
3426                 if (first && cb->cb_verbose) {
3427                         /*
3428                          * Reset the width to accommodate the verbose listing
3429                          * of devices.
3430                          */
3431                         width = cb->cb_namewidth;
3432                 }
3433
3434                 if (!first)
3435                         (void) printf("  ");
3436                 else
3437                         first = B_FALSE;
3438
3439                 right_justify = B_FALSE;
3440                 if (pl->pl_prop != ZPROP_INVAL) {
3441                         header = zpool_prop_column_name(pl->pl_prop);
3442                         right_justify = zpool_prop_align_right(pl->pl_prop);
3443                 } else {
3444                         int i;
3445
3446                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
3447                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
3448                         headerbuf[i] = '\0';
3449                         header = headerbuf;
3450                 }
3451
3452                 if (pl->pl_next == NULL && !right_justify)
3453                         (void) printf("%s", header);
3454                 else if (right_justify)
3455                         (void) printf("%*s", width, header);
3456                 else
3457                         (void) printf("%-*s", width, header);
3458
3459         }
3460
3461         (void) printf("\n");
3462 }
3463
3464 /*
3465  * Given a pool and a list of properties, print out all the properties according
3466  * to the described layout. Used by zpool_do_list().
3467  */
3468 static void
3469 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
3470 {
3471         zprop_list_t *pl = cb->cb_proplist;
3472         boolean_t first = B_TRUE;
3473         char property[ZPOOL_MAXPROPLEN];
3474         char *propstr;
3475         boolean_t right_justify;
3476         size_t width;
3477
3478         for (; pl != NULL; pl = pl->pl_next) {
3479
3480                 width = pl->pl_width;
3481                 if (first && cb->cb_verbose) {
3482                         /*
3483                          * Reset the width to accommodate the verbose listing
3484                          * of devices.
3485                          */
3486                         width = cb->cb_namewidth;
3487                 }
3488
3489                 if (!first) {
3490                         if (cb->cb_scripted)
3491                                 (void) printf("\t");
3492                         else
3493                                 (void) printf("  ");
3494                 } else {
3495                         first = B_FALSE;
3496                 }
3497
3498                 right_justify = B_FALSE;
3499                 if (pl->pl_prop != ZPROP_INVAL) {
3500                         if (zpool_get_prop(zhp, pl->pl_prop, property,
3501                             sizeof (property), NULL, cb->cb_literal) != 0)
3502                                 propstr = "-";
3503                         else
3504                                 propstr = property;
3505
3506                         right_justify = zpool_prop_align_right(pl->pl_prop);
3507                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
3508                     zpool_prop_unsupported(pl->pl_user_prop)) &&
3509                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
3510                     sizeof (property)) == 0) {
3511                         propstr = property;
3512                 } else {
3513                         propstr = "-";
3514                 }
3515
3516
3517                 /*
3518                  * If this is being called in scripted mode, or if this is the
3519                  * last column and it is left-justified, don't include a width
3520                  * format specifier.
3521                  */
3522                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
3523                         (void) printf("%s", propstr);
3524                 else if (right_justify)
3525                         (void) printf("%*s", width, propstr);
3526                 else
3527                         (void) printf("%-*s", width, propstr);
3528         }
3529
3530         (void) printf("\n");
3531 }
3532
3533 static void
3534 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
3535     boolean_t valid)
3536 {
3537         char propval[64];
3538         boolean_t fixed;
3539         size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
3540
3541         switch (prop) {
3542         case ZPOOL_PROP_EXPANDSZ:
3543         case ZPOOL_PROP_CHECKPOINT:
3544                 if (value == 0)
3545                         (void) strlcpy(propval, "-", sizeof (propval));
3546                 else
3547                         zfs_nicenum(value, propval, sizeof (propval));
3548                 break;
3549         case ZPOOL_PROP_FRAGMENTATION:
3550                 if (value == ZFS_FRAG_INVALID) {
3551                         (void) strlcpy(propval, "-", sizeof (propval));
3552                 } else {
3553                         (void) snprintf(propval, sizeof (propval), "%llu%%",
3554                             value);
3555                 }
3556                 break;
3557         case ZPOOL_PROP_CAPACITY:
3558                 (void) snprintf(propval, sizeof (propval),
3559                     value < 1000 ? "%1.2f%%" : value < 10000 ?
3560                     "%2.1f%%" : "%3.0f%%", value / 100.0);
3561                 break;
3562         default:
3563                 zfs_nicenum(value, propval, sizeof (propval));
3564         }
3565
3566         if (!valid)
3567                 (void) strlcpy(propval, "-", sizeof (propval));
3568
3569         if (scripted)
3570                 (void) printf("\t%s", propval);
3571         else
3572                 (void) printf("  %*s", width, propval);
3573 }
3574
3575 /*
3576  * print static default line per vdev
3577  */
3578 void
3579 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
3580     list_cbdata_t *cb, int depth)
3581 {
3582         nvlist_t **child;
3583         vdev_stat_t *vs;
3584         uint_t c, children;
3585         char *vname;
3586         boolean_t scripted = cb->cb_scripted;
3587         uint64_t islog = B_FALSE;
3588         char *dashes = "%-*s      -      -      -         -      -      -\n";
3589
3590         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3591             (uint64_t **)&vs, &c) == 0);
3592
3593         if (name != NULL) {
3594                 boolean_t toplevel = (vs->vs_space != 0);
3595                 uint64_t cap;
3596
3597                 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0)
3598                         return;
3599
3600                 if (scripted)
3601                         (void) printf("\t%s", name);
3602                 else if (strlen(name) + depth > cb->cb_namewidth)
3603                         (void) printf("%*s%s", depth, "", name);
3604                 else
3605                         (void) printf("%*s%s%*s", depth, "", name,
3606                             (int)(cb->cb_namewidth - strlen(name) - depth), "");
3607
3608                 /*
3609                  * Print the properties for the individual vdevs. Some
3610                  * properties are only applicable to toplevel vdevs. The
3611                  * 'toplevel' boolean value is passed to the print_one_column()
3612                  * to indicate that the value is valid.
3613                  */
3614                 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
3615                     toplevel);
3616                 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
3617                     toplevel);
3618                 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
3619                     scripted, toplevel);
3620                 print_one_column(ZPOOL_PROP_CHECKPOINT,
3621                     vs->vs_checkpoint_space, scripted, toplevel);
3622                 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
3623                     B_TRUE);
3624                 print_one_column(ZPOOL_PROP_FRAGMENTATION,
3625                     vs->vs_fragmentation, scripted,
3626                     (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel));
3627                 cap = (vs->vs_space == 0) ? 0 :
3628                     (vs->vs_alloc * 10000 / vs->vs_space);
3629                 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel);
3630                 (void) printf("\n");
3631         }
3632
3633         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
3634             &child, &children) != 0)
3635                 return;
3636
3637         /* list the normal vdevs first */
3638         for (c = 0; c < children; c++) {
3639                 uint64_t ishole = B_FALSE;
3640
3641                 if (nvlist_lookup_uint64(child[c],
3642                     ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
3643                         continue;
3644
3645                 if (nvlist_lookup_uint64(child[c],
3646                     ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog)
3647                         continue;
3648
3649                 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS))
3650                         continue;
3651
3652                 vname = zpool_vdev_name(g_zfs, zhp, child[c],
3653                     cb->cb_name_flags);
3654                 print_list_stats(zhp, vname, child[c], cb, depth + 2);
3655                 free(vname);
3656         }
3657
3658         /* list the classes: 'logs', 'dedup', and 'special' */
3659         for (uint_t n = 0; n < 3; n++) {
3660                 boolean_t printed = B_FALSE;
3661
3662                 for (c = 0; c < children; c++) {
3663                         char *bias = NULL;
3664                         char *type = NULL;
3665
3666                         if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
3667                             &islog) == 0 && islog) {
3668                                 bias = VDEV_ALLOC_CLASS_LOGS;
3669                         } else {
3670                                 (void) nvlist_lookup_string(child[c],
3671                                     ZPOOL_CONFIG_ALLOCATION_BIAS, &bias);
3672                                 (void) nvlist_lookup_string(child[c],
3673                                     ZPOOL_CONFIG_TYPE, &type);
3674                         }
3675                         if (bias == NULL || strcmp(bias, class_name[n]) != 0)
3676                                 continue;
3677                         if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0)
3678                                 continue;
3679
3680                         if (!printed) {
3681                                 /* LINTED E_SEC_PRINTF_VAR_FMT */
3682                                 (void) printf(dashes, cb->cb_namewidth,
3683                                     class_name[n]);
3684                                 printed = B_TRUE;
3685                         }
3686                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
3687                             cb->cb_name_flags);
3688                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
3689                         free(vname);
3690                 }
3691         }
3692
3693         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
3694             &child, &children) == 0 && children > 0) {
3695                 /* LINTED E_SEC_PRINTF_VAR_FMT */
3696                 (void) printf(dashes, cb->cb_namewidth, "cache");
3697                 for (c = 0; c < children; c++) {
3698                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
3699                             cb->cb_name_flags);
3700                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
3701                         free(vname);
3702                 }
3703         }
3704
3705         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
3706             &children) == 0 && children > 0) {
3707                 /* LINTED E_SEC_PRINTF_VAR_FMT */
3708                 (void) printf(dashes, cb->cb_namewidth, "spare");
3709                 for (c = 0; c < children; c++) {
3710                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
3711                             cb->cb_name_flags);
3712                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
3713                         free(vname);
3714                 }
3715         }
3716 }
3717
3718 /*
3719  * Generic callback function to list a pool.
3720  */
3721 int
3722 list_callback(zpool_handle_t *zhp, void *data)
3723 {
3724         list_cbdata_t *cbp = data;
3725         nvlist_t *config;
3726         nvlist_t *nvroot;
3727
3728         config = zpool_get_config(zhp, NULL);
3729
3730         if (cbp->cb_verbose) {
3731                 config = zpool_get_config(zhp, NULL);
3732
3733                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3734                     &nvroot) == 0);
3735         }
3736
3737         if (cbp->cb_verbose)
3738                 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
3739                     cbp->cb_name_flags);
3740
3741         print_pool(zhp, cbp);
3742
3743         if (cbp->cb_verbose)
3744                 print_list_stats(zhp, NULL, nvroot, cbp, 0);
3745
3746         return (0);
3747 }
3748
3749 /*
3750  * zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
3751  *
3752  *      -g      Display guid for individual vdev name.
3753  *      -H      Scripted mode.  Don't display headers, and separate properties
3754  *              by a single tab.
3755  *      -L      Follow links when resolving vdev path name.
3756  *      -o      List of properties to display.  Defaults to
3757  *              "name,size,allocated,free,expandsize,fragmentation,capacity,"
3758  *              "dedupratio,health,altroot"
3759  *      -p      Diplay values in parsable (exact) format.
3760  *      -P      Display full path for vdev name.
3761  *      -T      Display a timestamp in date(1) or Unix format
3762  *
3763  * List all pools in the system, whether or not they're healthy.  Output space
3764  * statistics for each one, as well as health status summary.
3765  */
3766 int
3767 zpool_do_list(int argc, char **argv)
3768 {
3769         int c;
3770         int ret;
3771         list_cbdata_t cb = { 0 };
3772         static char default_props[] =
3773             "name,size,allocated,free,checkpoint,expandsize,fragmentation,"
3774             "capacity,dedupratio,health,altroot";
3775         char *props = default_props;
3776         unsigned long interval = 0, count = 0;
3777         zpool_list_t *list;
3778         boolean_t first = B_TRUE;
3779
3780         /* check options */
3781         while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) {
3782                 switch (c) {
3783                 case 'g':
3784                         cb.cb_name_flags |= VDEV_NAME_GUID;
3785                         break;
3786                 case 'H':
3787                         cb.cb_scripted = B_TRUE;
3788                         break;
3789                 case 'L':
3790                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
3791                         break;
3792                 case 'o':
3793                         props = optarg;
3794                         break;
3795                 case 'P':
3796                         cb.cb_name_flags |= VDEV_NAME_PATH;
3797                         break;
3798                 case 'p':
3799                         cb.cb_literal = B_TRUE;
3800                         break;
3801                 case 'T':
3802                         get_timestamp_arg(*optarg);
3803                         break;
3804                 case 'v':
3805                         cb.cb_verbose = B_TRUE;
3806                         cb.cb_namewidth = 8;    /* 8 until precalc is avail */
3807                         break;
3808                 case ':':
3809                         (void) fprintf(stderr, gettext("missing argument for "
3810                             "'%c' option\n"), optopt);
3811                         usage(B_FALSE);
3812                         break;
3813                 case '?':
3814                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3815                             optopt);
3816                         usage(B_FALSE);
3817                 }
3818         }
3819
3820         argc -= optind;
3821         argv += optind;
3822
3823         get_interval_count(&argc, argv, &interval, &count);
3824
3825         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
3826                 usage(B_FALSE);
3827
3828         for (;;) {
3829                 if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
3830                     &ret)) == NULL)
3831                         return (1);
3832
3833                 if (pool_list_count(list) == 0)
3834                         break;
3835
3836                 cb.cb_namewidth = 0;
3837                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
3838
3839                 if (timestamp_fmt != NODATE)
3840                         print_timestamp(timestamp_fmt);
3841
3842                 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
3843                         print_header(&cb);
3844                         first = B_FALSE;
3845                 }
3846                 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
3847
3848                 if (interval == 0)
3849                         break;
3850
3851                 if (count != 0 && --count == 0)
3852                         break;
3853
3854                 pool_list_free(list);
3855                 (void) sleep(interval);
3856         }
3857
3858         if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
3859                 (void) printf(gettext("no pools available\n"));
3860                 ret = 0;
3861         }
3862
3863         pool_list_free(list);
3864         zprop_free_list(cb.cb_proplist);
3865         return (ret);
3866 }
3867
3868 static int
3869 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
3870 {
3871         boolean_t force = B_FALSE;
3872         int c;
3873         nvlist_t *nvroot;
3874         char *poolname, *old_disk, *new_disk;
3875         zpool_handle_t *zhp;
3876         zpool_boot_label_t boot_type;
3877         uint64_t boot_size;
3878         int ret;
3879
3880         /* check options */
3881         while ((c = getopt(argc, argv, "f")) != -1) {
3882                 switch (c) {
3883                 case 'f':
3884                         force = B_TRUE;
3885                         break;
3886                 case '?':
3887                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3888                             optopt);
3889                         usage(B_FALSE);
3890                 }
3891         }
3892
3893         argc -= optind;
3894         argv += optind;
3895
3896         /* get pool name and check number of arguments */
3897         if (argc < 1) {
3898                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3899                 usage(B_FALSE);
3900         }
3901
3902         poolname = argv[0];
3903
3904         if (argc < 2) {
3905                 (void) fprintf(stderr,
3906                     gettext("missing <device> specification\n"));
3907                 usage(B_FALSE);
3908         }
3909
3910         old_disk = argv[1];
3911
3912         if (argc < 3) {
3913                 if (!replacing) {
3914                         (void) fprintf(stderr,
3915                             gettext("missing <new_device> specification\n"));
3916                         usage(B_FALSE);
3917                 }
3918                 new_disk = old_disk;
3919                 argc -= 1;
3920                 argv += 1;
3921         } else {
3922                 new_disk = argv[2];
3923                 argc -= 2;
3924                 argv += 2;
3925         }
3926
3927         if (argc > 1) {
3928                 (void) fprintf(stderr, gettext("too many arguments\n"));
3929                 usage(B_FALSE);
3930         }
3931
3932         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3933                 return (1);
3934
3935         if (zpool_get_config(zhp, NULL) == NULL) {
3936                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
3937                     poolname);
3938                 zpool_close(zhp);
3939                 return (1);
3940         }
3941
3942         if (zpool_is_bootable(zhp))
3943                 boot_type = ZPOOL_COPY_BOOT_LABEL;
3944         else
3945                 boot_type = ZPOOL_NO_BOOT_LABEL;
3946
3947         boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL);
3948         nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
3949             boot_type, boot_size, argc, argv);
3950         if (nvroot == NULL) {
3951                 zpool_close(zhp);
3952                 return (1);
3953         }
3954
3955         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
3956
3957         nvlist_free(nvroot);
3958         zpool_close(zhp);
3959
3960         return (ret);
3961 }
3962
3963 /*
3964  * zpool replace [-f] <pool> <device> <new_device>
3965  *
3966  *      -f      Force attach, even if <new_device> appears to be in use.
3967  *
3968  * Replace <device> with <new_device>.
3969  */
3970 /* ARGSUSED */
3971 int
3972 zpool_do_replace(int argc, char **argv)
3973 {
3974         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
3975 }
3976
3977 /*
3978  * zpool attach [-f] <pool> <device> <new_device>
3979  *
3980  *      -f      Force attach, even if <new_device> appears to be in use.
3981  *
3982  * Attach <new_device> to the mirror containing <device>.  If <device> is not
3983  * part of a mirror, then <device> will be transformed into a mirror of
3984  * <device> and <new_device>.  In either case, <new_device> will begin life
3985  * with a DTL of [0, now], and will immediately begin to resilver itself.
3986  */
3987 int
3988 zpool_do_attach(int argc, char **argv)
3989 {
3990         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
3991 }
3992
3993 /*
3994  * zpool detach [-f] <pool> <device>
3995  *
3996  *      -f      Force detach of <device>, even if DTLs argue against it
3997  *              (not supported yet)
3998  *
3999  * Detach a device from a mirror.  The operation will be refused if <device>
4000  * is the last device in the mirror, or if the DTLs indicate that this device
4001  * has the only valid copy of some data.
4002  */
4003 /* ARGSUSED */
4004 int
4005 zpool_do_detach(int argc, char **argv)
4006 {
4007         int c;
4008         char *poolname, *path;
4009         zpool_handle_t *zhp;
4010         int ret;
4011
4012         /* check options */
4013         while ((c = getopt(argc, argv, "f")) != -1) {
4014                 switch (c) {
4015                 case 'f':
4016                 case '?':
4017                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4018                             optopt);
4019                         usage(B_FALSE);
4020                 }
4021         }
4022
4023         argc -= optind;
4024         argv += optind;
4025
4026         /* get pool name and check number of arguments */
4027         if (argc < 1) {
4028                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
4029                 usage(B_FALSE);
4030         }
4031
4032         if (argc < 2) {
4033                 (void) fprintf(stderr,
4034                     gettext("missing <device> specification\n"));
4035                 usage(B_FALSE);
4036         }
4037
4038         poolname = argv[0];
4039         path = argv[1];
4040
4041         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
4042                 return (1);
4043
4044         ret = zpool_vdev_detach(zhp, path);
4045
4046         zpool_close(zhp);
4047
4048         return (ret);
4049 }
4050
4051 /*
4052  * zpool split [-gLnP] [-o prop=val] ...
4053  *              [-o mntopt] ...
4054  *              [-R altroot] <pool> <newpool> [<device> ...]
4055  *
4056  *      -g      Display guid for individual vdev name.
4057  *      -L      Follow links when resolving vdev path name.
4058  *      -n      Do not split the pool, but display the resulting layout if
4059  *              it were to be split.
4060  *      -o      Set property=value, or set mount options.
4061  *      -P      Display full path for vdev name.
4062  *      -R      Mount the split-off pool under an alternate root.
4063  *
4064  * Splits the named pool and gives it the new pool name.  Devices to be split
4065  * off may be listed, provided that no more than one device is specified
4066  * per top-level vdev mirror.  The newly split pool is left in an exported
4067  * state unless -R is specified.
4068  *
4069  * Restrictions: the top-level of the pool pool must only be made up of
4070  * mirrors; all devices in the pool must be healthy; no device may be
4071  * undergoing a resilvering operation.
4072  */
4073 int
4074 zpool_do_split(int argc, char **argv)
4075 {
4076         char *srcpool, *newpool, *propval;
4077         char *mntopts = NULL;
4078         splitflags_t flags;
4079         int c, ret = 0;
4080         zpool_handle_t *zhp;
4081         nvlist_t *config, *props = NULL;
4082
4083         flags.dryrun = B_FALSE;
4084         flags.import = B_FALSE;
4085         flags.name_flags = 0;
4086
4087         /* check options */
4088         while ((c = getopt(argc, argv, ":gLR:no:P")) != -1) {
4089                 switch (c) {
4090                 case 'g':
4091                         flags.name_flags |= VDEV_NAME_GUID;
4092                         break;
4093                 case 'L':
4094                         flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
4095                         break;
4096                 case 'R':
4097                         flags.import = B_TRUE;
4098                         if (add_prop_list(
4099                             zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
4100                             &props, B_TRUE) != 0) {
4101                                 nvlist_free(props);
4102                                 usage(B_FALSE);
4103                         }
4104                         break;
4105                 case 'n':
4106                         flags.dryrun = B_TRUE;
4107                         break;
4108                 case 'o':
4109                         if ((propval = strchr(optarg, '=')) != NULL) {
4110                                 *propval = '\0';
4111                                 propval++;
4112                                 if (add_prop_list(optarg, propval,
4113                                     &props, B_TRUE) != 0) {
4114                                         nvlist_free(props);
4115                                         usage(B_FALSE);
4116                                 }
4117                         } else {
4118                                 mntopts = optarg;
4119                         }
4120                         break;
4121                 case 'P':
4122                         flags.name_flags |= VDEV_NAME_PATH;
4123                         break;
4124                 case ':':
4125                         (void) fprintf(stderr, gettext("missing argument for "
4126                             "'%c' option\n"), optopt);
4127                         usage(B_FALSE);
4128                         break;
4129                 case '?':
4130                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4131                             optopt);
4132                         usage(B_FALSE);
4133                         break;
4134                 }
4135         }
4136
4137         if (!flags.import && mntopts != NULL) {
4138                 (void) fprintf(stderr, gettext("setting mntopts is only "
4139                     "valid when importing the pool\n"));
4140                 usage(B_FALSE);
4141         }
4142
4143         argc -= optind;
4144         argv += optind;
4145
4146         if (argc < 1) {
4147                 (void) fprintf(stderr, gettext("Missing pool name\n"));
4148                 usage(B_FALSE);
4149         }
4150         if (argc < 2) {
4151                 (void) fprintf(stderr, gettext("Missing new pool name\n"));
4152                 usage(B_FALSE);
4153         }
4154
4155         srcpool = argv[0];
4156         newpool = argv[1];
4157
4158         argc -= 2;
4159         argv += 2;
4160
4161         if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
4162                 return (1);
4163
4164         config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
4165         if (config == NULL) {
4166                 ret = 1;
4167         } else {
4168                 if (flags.dryrun) {
4169                         (void) printf(gettext("would create '%s' with the "
4170                             "following layout:\n\n"), newpool);
4171                         print_vdev_tree(NULL, newpool, config, 0, "",
4172                             flags.name_flags);
4173                 }
4174                 nvlist_free(config);
4175         }
4176
4177         zpool_close(zhp);
4178
4179         if (ret != 0 || flags.dryrun || !flags.import)
4180                 return (ret);
4181
4182         /*
4183          * The split was successful. Now we need to open the new
4184          * pool and import it.
4185          */
4186         if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
4187                 return (1);
4188         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
4189             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
4190                 ret = 1;
4191                 (void) fprintf(stderr, gettext("Split was successful, but "
4192                     "the datasets could not all be mounted\n"));
4193                 (void) fprintf(stderr, gettext("Try doing '%s' with a "
4194                     "different altroot\n"), "zpool import");
4195         }
4196         zpool_close(zhp);
4197
4198         return (ret);
4199 }
4200
4201
4202
4203 /*
4204  * zpool online <pool> <device> ...
4205  */
4206 int
4207 zpool_do_online(int argc, char **argv)
4208 {
4209         int c, i;
4210         char *poolname;
4211         zpool_handle_t *zhp;
4212         int ret = 0;
4213         vdev_state_t newstate;
4214         int flags = 0;
4215
4216         /* check options */
4217         while ((c = getopt(argc, argv, "et")) != -1) {
4218                 switch (c) {
4219                 case 'e':
4220                         flags |= ZFS_ONLINE_EXPAND;
4221                         break;
4222                 case 't':
4223                 case '?':
4224                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4225                             optopt);
4226                         usage(B_FALSE);
4227                 }
4228         }
4229
4230         argc -= optind;
4231         argv += optind;
4232
4233         /* get pool name and check number of arguments */
4234         if (argc < 1) {
4235                 (void) fprintf(stderr, gettext("missing pool name\n"));
4236                 usage(B_FALSE);
4237         }
4238         if (argc < 2) {
4239                 (void) fprintf(stderr, gettext("missing device name\n"));
4240                 usage(B_FALSE);
4241         }
4242
4243         poolname = argv[0];
4244
4245         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
4246                 return (1);
4247
4248         for (i = 1; i < argc; i++) {
4249                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
4250                         if (newstate != VDEV_STATE_HEALTHY) {
4251                                 (void) printf(gettext("warning: device '%s' "
4252                                     "onlined, but remains in faulted state\n"),
4253                                     argv[i]);
4254                                 if (newstate == VDEV_STATE_FAULTED)
4255                                         (void) printf(gettext("use 'zpool "
4256                                             "clear' to restore a faulted "
4257                                             "device\n"));
4258                                 else
4259                                         (void) printf(gettext("use 'zpool "
4260                                             "replace' to replace devices "
4261                                             "that are no longer present\n"));
4262                         }
4263                 } else {
4264                         ret = 1;
4265                 }
4266         }
4267
4268         zpool_close(zhp);
4269
4270         return (ret);
4271 }
4272
4273 /*
4274  * zpool offline [-ft] <pool> <device> ...
4275  *
4276  *      -f      Force the device into the offline state, even if doing
4277  *              so would appear to compromise pool availability.
4278  *              (not supported yet)
4279  *
4280  *      -t      Only take the device off-line temporarily.  The offline
4281  *              state will not be persistent across reboots.
4282  */
4283 /* ARGSUSED */
4284 int
4285 zpool_do_offline(int argc, char **argv)
4286 {
4287         int c, i;
4288         char *poolname;
4289         zpool_handle_t *zhp;
4290         int ret = 0;
4291         boolean_t istmp = B_FALSE;
4292
4293         /* check options */
4294         while ((c = getopt(argc, argv, "ft")) != -1) {
4295                 switch (c) {
4296                 case 't':
4297                         istmp = B_TRUE;
4298                         break;
4299                 case 'f':
4300                 case '?':
4301                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4302                             optopt);
4303                         usage(B_FALSE);
4304                 }
4305         }
4306
4307         argc -= optind;
4308         argv += optind;
4309
4310         /* get pool name and check number of arguments */
4311         if (argc < 1) {
4312                 (void) fprintf(stderr, gettext("missing pool name\n"));
4313                 usage(B_FALSE);
4314         }
4315         if (argc < 2) {
4316                 (void) fprintf(stderr, gettext("missing device name\n"));
4317                 usage(B_FALSE);
4318         }
4319
4320         poolname = argv[0];
4321
4322         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
4323                 return (1);
4324
4325         for (i = 1; i < argc; i++) {
4326                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
4327                         ret = 1;
4328         }
4329
4330         zpool_close(zhp);
4331
4332         return (ret);
4333 }
4334
4335 /*
4336  * zpool clear <pool> [device]
4337  *
4338  * Clear all errors associated with a pool or a particular device.
4339  */
4340 int
4341 zpool_do_clear(int argc, char **argv)
4342 {
4343         int c;
4344         int ret = 0;
4345         boolean_t dryrun = B_FALSE;
4346         boolean_t do_rewind = B_FALSE;
4347         boolean_t xtreme_rewind = B_FALSE;
4348         uint32_t rewind_policy = ZPOOL_NO_REWIND;
4349         nvlist_t *policy = NULL;
4350         zpool_handle_t *zhp;
4351         char *pool, *device;
4352
4353         /* check options */
4354         while ((c = getopt(argc, argv, "FnX")) != -1) {
4355                 switch (c) {
4356                 case 'F':
4357                         do_rewind = B_TRUE;
4358                         break;
4359                 case 'n':
4360                         dryrun = B_TRUE;
4361                         break;
4362                 case 'X':
4363                         xtreme_rewind = B_TRUE;
4364                         break;
4365                 case '?':
4366                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4367                             optopt);
4368                         usage(B_FALSE);
4369                 }
4370         }
4371
4372         argc -= optind;
4373         argv += optind;
4374
4375         if (argc < 1) {
4376                 (void) fprintf(stderr, gettext("missing pool name\n"));
4377                 usage(B_FALSE);
4378         }
4379
4380         if (argc > 2) {
4381                 (void) fprintf(stderr, gettext("too many arguments\n"));
4382                 usage(B_FALSE);
4383         }
4384
4385         if ((dryrun || xtreme_rewind) && !do_rewind) {
4386                 (void) fprintf(stderr,
4387                     gettext("-n or -X only meaningful with -F\n"));
4388                 usage(B_FALSE);
4389         }
4390         if (dryrun)
4391                 rewind_policy = ZPOOL_TRY_REWIND;
4392         else if (do_rewind)
4393                 rewind_policy = ZPOOL_DO_REWIND;
4394         if (xtreme_rewind)
4395                 rewind_policy |= ZPOOL_EXTREME_REWIND;
4396
4397         /* In future, further rewind policy choices can be passed along here */
4398         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
4399             nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY,
4400             rewind_policy) != 0) {
4401                 return (1);
4402         }
4403
4404         pool = argv[0];
4405         device = argc == 2 ? argv[1] : NULL;
4406
4407         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
4408                 nvlist_free(policy);
4409                 return (1);
4410         }
4411
4412         if (zpool_clear(zhp, device, policy) != 0)
4413                 ret = 1;
4414
4415         zpool_close(zhp);
4416
4417         nvlist_free(policy);
4418
4419         return (ret);
4420 }
4421
4422 /*
4423  * zpool reguid <pool>
4424  */
4425 int
4426 zpool_do_reguid(int argc, char **argv)
4427 {
4428         int c;
4429         char *poolname;
4430         zpool_handle_t *zhp;
4431         int ret = 0;
4432
4433         /* check options */
4434         while ((c = getopt(argc, argv, "")) != -1) {
4435                 switch (c) {
4436                 case '?':
4437                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4438                             optopt);
4439                         usage(B_FALSE);
4440                 }
4441         }
4442
4443         argc -= optind;
4444         argv += optind;
4445
4446         /* get pool name and check number of arguments */
4447         if (argc < 1) {
4448                 (void) fprintf(stderr, gettext("missing pool name\n"));
4449                 usage(B_FALSE);
4450         }
4451
4452         if (argc > 1) {
4453                 (void) fprintf(stderr, gettext("too many arguments\n"));
4454                 usage(B_FALSE);
4455         }
4456
4457         poolname = argv[0];
4458         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
4459                 return (1);
4460
4461         ret = zpool_reguid(zhp);
4462
4463         zpool_close(zhp);
4464         return (ret);
4465 }
4466
4467
4468 /*
4469  * zpool reopen <pool>
4470  *
4471  * Reopen the pool so that the kernel can update the sizes of all vdevs.
4472  */
4473 int
4474 zpool_do_reopen(int argc, char **argv)
4475 {
4476         int c;
4477         int ret = 0;
4478         zpool_handle_t *zhp;
4479         char *pool;
4480
4481         /* check options */
4482         while ((c = getopt(argc, argv, "")) != -1) {
4483                 switch (c) {
4484                 case '?':
4485                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4486                             optopt);
4487                         usage(B_FALSE);
4488                 }
4489         }
4490
4491         argc--;
4492         argv++;
4493
4494         if (argc < 1) {
4495                 (void) fprintf(stderr, gettext("missing pool name\n"));
4496                 usage(B_FALSE);
4497         }
4498
4499         if (argc > 1) {
4500                 (void) fprintf(stderr, gettext("too many arguments\n"));
4501                 usage(B_FALSE);
4502         }
4503
4504         pool = argv[0];
4505         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
4506                 return (1);
4507
4508         ret = zpool_reopen(zhp);
4509         zpool_close(zhp);
4510         return (ret);
4511 }
4512
4513 typedef struct scrub_cbdata {
4514         int     cb_type;
4515         int     cb_argc;
4516         char    **cb_argv;
4517         pool_scrub_cmd_t cb_scrub_cmd;
4518 } scrub_cbdata_t;
4519
4520 static boolean_t
4521 zpool_has_checkpoint(zpool_handle_t *zhp)
4522 {
4523         nvlist_t *config, *nvroot;
4524
4525         config = zpool_get_config(zhp, NULL);
4526
4527         if (config != NULL) {
4528                 pool_checkpoint_stat_t *pcs = NULL;
4529                 uint_t c;
4530
4531                 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
4532                 (void) nvlist_lookup_uint64_array(nvroot,
4533                     ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
4534
4535                 if (pcs == NULL || pcs->pcs_state == CS_NONE)
4536                         return (B_FALSE);
4537
4538                 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS ||
4539                     pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
4540                 return (B_TRUE);
4541         }
4542
4543         return (B_FALSE);
4544 }
4545
4546 int
4547 scrub_callback(zpool_handle_t *zhp, void *data)
4548 {
4549         scrub_cbdata_t *cb = data;
4550         int err;
4551
4552         /*
4553          * Ignore faulted pools.
4554          */
4555         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
4556                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
4557                     "currently unavailable\n"), zpool_get_name(zhp));
4558                 return (1);
4559         }
4560
4561         err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
4562
4563         if (err == 0 && zpool_has_checkpoint(zhp) &&
4564             cb->cb_type == POOL_SCAN_SCRUB) {
4565                 (void) printf(gettext("warning: will not scrub state that "
4566                     "belongs to the checkpoint of pool '%s'\n"),
4567                     zpool_get_name(zhp));
4568         }
4569
4570         return (err != 0);
4571 }
4572
4573 /*
4574  * zpool scrub [-s | -p] <pool> ...
4575  *
4576  *      -s      Stop.  Stops any in-progress scrub.
4577  *      -p      Pause. Pause in-progress scrub.
4578  */
4579 int
4580 zpool_do_scrub(int argc, char **argv)
4581 {
4582         int c;
4583         scrub_cbdata_t cb;
4584
4585         cb.cb_type = POOL_SCAN_SCRUB;
4586         cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
4587
4588         /* check options */
4589         while ((c = getopt(argc, argv, "sp")) != -1) {
4590                 switch (c) {
4591                 case 's':
4592                         cb.cb_type = POOL_SCAN_NONE;
4593                         break;
4594                 case 'p':
4595                         cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
4596                         break;
4597                 case '?':
4598                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4599                             optopt);
4600                         usage(B_FALSE);
4601                 }
4602         }
4603
4604         if (cb.cb_type == POOL_SCAN_NONE &&
4605             cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
4606                 (void) fprintf(stderr, gettext("invalid option combination: "
4607                     "-s and -p are mutually exclusive\n"));
4608                 usage(B_FALSE);
4609         }
4610
4611         cb.cb_argc = argc;
4612         cb.cb_argv = argv;
4613         argc -= optind;
4614         argv += optind;
4615
4616         if (argc < 1) {
4617                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
4618                 usage(B_FALSE);
4619         }
4620
4621         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
4622 }
4623
4624 static void
4625 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
4626 {
4627         uint_t children = 0;
4628         nvlist_t **child;
4629         uint_t i;
4630
4631         (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
4632             &child, &children);
4633
4634         if (children == 0) {
4635                 char *path = zpool_vdev_name(g_zfs, zhp, nvroot, B_FALSE);
4636                 fnvlist_add_boolean(res, path);
4637                 free(path);
4638                 return;
4639         }
4640
4641         for (i = 0; i < children; i++) {
4642                 zpool_collect_leaves(zhp, child[i], res);
4643         }
4644 }
4645
4646 /*
4647  * zpool initialize [-cs] <pool> [<vdev> ...]
4648  * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool
4649  * if none specified.
4650  *
4651  *      -c      Cancel. Ends active initializing.
4652  *      -s      Suspend. Initializing can then be restarted with no flags.
4653  */
4654 int
4655 zpool_do_initialize(int argc, char **argv)
4656 {
4657         int c;
4658         char *poolname;
4659         zpool_handle_t *zhp;
4660         nvlist_t *vdevs;
4661         int err = 0;
4662
4663         struct option long_options[] = {
4664                 {"cancel",      no_argument,            NULL, 'c'},
4665                 {"suspend",     no_argument,            NULL, 's'},
4666                 {0, 0, 0, 0}
4667         };
4668
4669         pool_initialize_func_t cmd_type = POOL_INITIALIZE_DO;
4670         while ((c = getopt_long(argc, argv, "cs", long_options, NULL)) != -1) {
4671                 switch (c) {
4672                 case 'c':
4673                         if (cmd_type != POOL_INITIALIZE_DO) {
4674                                 (void) fprintf(stderr, gettext("-c cannot be "
4675                                     "combined with other options\n"));
4676                                 usage(B_FALSE);
4677                         }
4678                         cmd_type = POOL_INITIALIZE_CANCEL;
4679                         break;
4680                 case 's':
4681                         if (cmd_type != POOL_INITIALIZE_DO) {
4682                                 (void) fprintf(stderr, gettext("-s cannot be "
4683                                     "combined with other options\n"));
4684                                 usage(B_FALSE);
4685                         }
4686                         cmd_type = POOL_INITIALIZE_SUSPEND;
4687                         break;
4688                 case '?':
4689                         if (optopt != 0) {
4690                                 (void) fprintf(stderr,
4691                                     gettext("invalid option '%c'\n"), optopt);
4692                         } else {
4693                                 (void) fprintf(stderr,
4694                                     gettext("invalid option '%s'\n"),
4695                                     argv[optind - 1]);
4696                         }
4697                         usage(B_FALSE);
4698                 }
4699         }
4700
4701         argc -= optind;
4702         argv += optind;
4703
4704         if (argc < 1) {
4705                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
4706                 usage(B_FALSE);
4707                 return (-1);
4708         }
4709
4710         poolname = argv[0];
4711         zhp = zpool_open(g_zfs, poolname);
4712         if (zhp == NULL)
4713                 return (-1);
4714
4715         vdevs = fnvlist_alloc();
4716         if (argc == 1) {
4717                 /* no individual leaf vdevs specified, so add them all */
4718                 nvlist_t *config = zpool_get_config(zhp, NULL);
4719                 nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
4720                     ZPOOL_CONFIG_VDEV_TREE);
4721                 zpool_collect_leaves(zhp, nvroot, vdevs);
4722         } else {
4723                 int i;
4724                 for (i = 1; i < argc; i++) {
4725                         fnvlist_add_boolean(vdevs, argv[i]);
4726                 }
4727         }
4728
4729         err = zpool_initialize(zhp, cmd_type, vdevs);
4730
4731         fnvlist_free(vdevs);
4732         zpool_close(zhp);
4733
4734         return (err);
4735 }
4736
4737 /*
4738  * Print out detailed scrub status.
4739  */
4740 static void
4741 print_scan_status(pool_scan_stat_t *ps)
4742 {
4743         time_t start, end, pause;
4744         uint64_t total_secs_left;
4745         uint64_t elapsed, secs_left, mins_left, hours_left, days_left;
4746         uint64_t pass_scanned, scanned, pass_issued, issued, total;
4747         uint_t scan_rate, issue_rate;
4748         double fraction_done;
4749         char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7];
4750         char srate_buf[7], irate_buf[7];
4751
4752         (void) printf(gettext("  scan: "));
4753
4754         /* If there's never been a scan, there's not much to say. */
4755         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
4756             ps->pss_func >= POOL_SCAN_FUNCS) {
4757                 (void) printf(gettext("none requested\n"));
4758                 return;
4759         }
4760
4761         start = ps->pss_start_time;
4762         end = ps->pss_end_time;
4763         pause = ps->pss_pass_scrub_pause;
4764
4765         zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
4766
4767         assert(ps->pss_func == POOL_SCAN_SCRUB ||
4768             ps->pss_func == POOL_SCAN_RESILVER);
4769
4770         /* Scan is finished or canceled. */
4771         if (ps->pss_state == DSS_FINISHED) {
4772                 total_secs_left = end - start;
4773                 days_left = total_secs_left / 60 / 60 / 24;
4774                 hours_left = (total_secs_left / 60 / 60) % 24;
4775                 mins_left = (total_secs_left / 60) % 60;
4776                 secs_left = (total_secs_left % 60);
4777                 
4778                 if (ps->pss_func == POOL_SCAN_SCRUB) {
4779                         (void) printf(gettext("scrub repaired %s "
4780                             "in %llu days %02llu:%02llu:%02llu "
4781                             "with %llu errors on %s"), processed_buf,
4782                             (u_longlong_t)days_left, (u_longlong_t)hours_left,
4783                             (u_longlong_t)mins_left, (u_longlong_t)secs_left,
4784                             (u_longlong_t)ps->pss_errors, ctime(&end));
4785                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
4786                        (void) printf(gettext("resilvered %s "
4787                            "in %llu days %02llu:%02llu:%02llu "
4788                            "with %llu errors on %s"), processed_buf,
4789                            (u_longlong_t)days_left, (u_longlong_t)hours_left,
4790                            (u_longlong_t)mins_left, (u_longlong_t)secs_left,
4791                            (u_longlong_t)ps->pss_errors, ctime(&end));
4792
4793                 }
4794
4795                 return;
4796         } else if (ps->pss_state == DSS_CANCELED) {
4797                 if (ps->pss_func == POOL_SCAN_SCRUB) {
4798                         (void) printf(gettext("scrub canceled on %s"),
4799                             ctime(&end));
4800                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
4801                         (void) printf(gettext("resilver canceled on %s"),
4802                             ctime(&end));
4803                 }
4804                 return;
4805         }
4806
4807         assert(ps->pss_state == DSS_SCANNING);
4808
4809         /* Scan is in progress. Resilvers can't be paused. */
4810         if (ps->pss_func == POOL_SCAN_SCRUB) {
4811                 if (pause == 0) {
4812                         (void) printf(gettext("scrub in progress since %s"),
4813                             ctime(&start));
4814                 } else {
4815                         (void) printf(gettext("scrub paused since %s"),
4816                             ctime(&pause));
4817                         (void) printf(gettext("\tscrub started on %s"),
4818                             ctime(&start));
4819                 }
4820         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
4821                 (void) printf(gettext("resilver in progress since %s"),
4822                     ctime(&start));
4823         }
4824
4825         scanned = ps->pss_examined;
4826         pass_scanned = ps->pss_pass_exam;
4827         issued = ps->pss_issued;
4828         pass_issued = ps->pss_pass_issued;
4829         total = ps->pss_to_examine;
4830
4831         /* we are only done with a block once we have issued the IO for it */
4832         fraction_done = (double)issued / total;
4833
4834         /* elapsed time for this pass, rounding up to 1 if it's 0 */
4835         elapsed = time(NULL) - ps->pss_pass_start;
4836         elapsed -= ps->pss_pass_scrub_spent_paused;
4837         elapsed = (elapsed != 0) ? elapsed : 1;
4838
4839         scan_rate = pass_scanned / elapsed;
4840         issue_rate = pass_issued / elapsed;
4841         total_secs_left = (issue_rate != 0) ?
4842             ((total - issued) / issue_rate) : UINT64_MAX;
4843
4844         days_left = total_secs_left / 60 / 60 / 24;
4845         hours_left = (total_secs_left / 60 / 60) % 24;
4846         mins_left = (total_secs_left / 60) % 60;
4847         secs_left = (total_secs_left % 60);
4848
4849         /* format all of the numbers we will be reporting */
4850         zfs_nicenum(scanned, scanned_buf, sizeof (scanned_buf));
4851         zfs_nicenum(issued, issued_buf, sizeof (issued_buf));
4852         zfs_nicenum(total, total_buf, sizeof (total_buf));
4853         zfs_nicenum(scan_rate, srate_buf, sizeof (srate_buf));
4854         zfs_nicenum(issue_rate, irate_buf, sizeof (irate_buf));
4855
4856         /* doo not print estimated time if we have a paused scrub */
4857         if (pause == 0) {
4858                 (void) printf(gettext("\t%s scanned at %s/s, "
4859                     "%s issued at %s/s, %s total\n"),
4860                     scanned_buf, srate_buf, issued_buf, irate_buf, total_buf);
4861         } else {
4862                 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"),
4863                     scanned_buf, issued_buf, total_buf);
4864         }
4865
4866         if (ps->pss_func == POOL_SCAN_RESILVER) {
4867                 (void) printf(gettext("\t%s resilvered, %.2f%% done"),
4868                     processed_buf, 100 * fraction_done);
4869         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
4870                 (void) printf(gettext("\t%s repaired, %.2f%% done"),
4871                     processed_buf, 100 * fraction_done);
4872         }
4873
4874         if (pause == 0) {
4875                 if (issue_rate >= 10 * 1024 * 1024) {
4876                         (void) printf(gettext(", %llu days "
4877                             "%02llu:%02llu:%02llu to go\n"),
4878                             (u_longlong_t)days_left, (u_longlong_t)hours_left,
4879                             (u_longlong_t)mins_left, (u_longlong_t)secs_left);
4880                 } else {
4881                         (void) printf(gettext(", no estimated "
4882                             "completion time\n"));
4883                 }
4884         } else {
4885                 (void) printf(gettext("\n"));
4886         }
4887 }
4888
4889 /*
4890  * As we don't scrub checkpointed blocks, we want to warn the
4891  * user that we skipped scanning some blocks if a checkpoint exists
4892  * or existed at any time during the scan.
4893  */
4894 static void
4895 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs)
4896 {
4897         if (ps == NULL || pcs == NULL)
4898                 return;
4899
4900         if (pcs->pcs_state == CS_NONE ||
4901             pcs->pcs_state == CS_CHECKPOINT_DISCARDING)
4902                 return;
4903
4904         assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS);
4905
4906         if (ps->pss_state == DSS_NONE)
4907                 return;
4908
4909         if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) &&
4910             ps->pss_end_time < pcs->pcs_start_time)
4911                 return;
4912
4913         if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) {
4914                 (void) printf(gettext("    scan warning: skipped blocks "
4915                     "that are only referenced by the checkpoint.\n"));
4916         } else {
4917                 assert(ps->pss_state == DSS_SCANNING);
4918                 (void) printf(gettext("    scan warning: skipping blocks "
4919                     "that are only referenced by the checkpoint.\n"));
4920         }
4921 }
4922
4923 /*
4924  * Print out detailed removal status.
4925  */
4926 static void
4927 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
4928 {
4929         char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
4930         time_t start, end;
4931         nvlist_t *config, *nvroot;
4932         nvlist_t **child;
4933         uint_t children;
4934         char *vdev_name;
4935
4936         if (prs == NULL || prs->prs_state == DSS_NONE)
4937                 return;
4938
4939         /*
4940          * Determine name of vdev.
4941          */
4942         config = zpool_get_config(zhp, NULL);
4943         nvroot = fnvlist_lookup_nvlist(config,
4944             ZPOOL_CONFIG_VDEV_TREE);
4945         verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
4946             &child, &children) == 0);
4947         assert(prs->prs_removing_vdev < children);
4948         vdev_name = zpool_vdev_name(g_zfs, zhp,
4949             child[prs->prs_removing_vdev], B_TRUE);
4950
4951         (void) printf(gettext("remove: "));
4952
4953         start = prs->prs_start_time;
4954         end = prs->prs_end_time;
4955         zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf));
4956
4957         /*
4958          * Removal is finished or canceled.
4959          */
4960         if (prs->prs_state == DSS_FINISHED) {
4961                 uint64_t minutes_taken = (end - start) / 60;
4962
4963                 (void) printf(gettext("Removal of vdev %llu copied %s "
4964                     "in %lluh%um, completed on %s"),
4965                     (longlong_t)prs->prs_removing_vdev,
4966                     copied_buf,
4967                     (u_longlong_t)(minutes_taken / 60),
4968                     (uint_t)(minutes_taken % 60),
4969                     ctime((time_t *)&end));
4970         } else if (prs->prs_state == DSS_CANCELED) {
4971                 (void) printf(gettext("Removal of %s canceled on %s"),
4972                     vdev_name, ctime(&end));
4973         } else {
4974                 uint64_t copied, total, elapsed, mins_left, hours_left;
4975                 double fraction_done;
4976                 uint_t rate;
4977
4978                 assert(prs->prs_state == DSS_SCANNING);
4979
4980                 /*
4981                  * Removal is in progress.
4982                  */
4983                 (void) printf(gettext(
4984                     "Evacuation of %s in progress since %s"),
4985                     vdev_name, ctime(&start));
4986
4987                 copied = prs->prs_copied > 0 ? prs->prs_copied : 1;
4988                 total = prs->prs_to_copy;
4989                 fraction_done = (double)copied / total;
4990
4991                 /* elapsed time for this pass */
4992                 elapsed = time(NULL) - prs->prs_start_time;
4993                 elapsed = elapsed > 0 ? elapsed : 1;
4994                 rate = copied / elapsed;
4995                 rate = rate > 0 ? rate : 1;
4996                 mins_left = ((total - copied) / rate) / 60;
4997                 hours_left = mins_left / 60;
4998
4999                 zfs_nicenum(copied, examined_buf, sizeof (examined_buf));
5000                 zfs_nicenum(total, total_buf, sizeof (total_buf));
5001                 zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
5002
5003                 /*
5004                  * do not print estimated time if hours_left is more than
5005                  * 30 days
5006                  */
5007                 (void) printf(gettext("    %s copied out of %s at %s/s, "
5008                     "%.2f%% done"),
5009                     examined_buf, total_buf, rate_buf, 100 * fraction_done);
5010                 if (hours_left < (30 * 24)) {
5011                         (void) printf(gettext(", %lluh%um to go\n"),
5012                             (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
5013                 } else {
5014                         (void) printf(gettext(
5015                             ", (copy is slow, no estimated time)\n"));
5016                 }
5017         }
5018
5019         if (prs->prs_mapping_memory > 0) {
5020                 char mem_buf[7];
5021                 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
5022                 (void) printf(gettext("    %s memory used for "
5023                     "removed device mappings\n"),
5024                     mem_buf);
5025         }
5026 }
5027
5028 static void
5029 print_checkpoint_status(pool_checkpoint_stat_t *pcs)
5030 {
5031         time_t start;
5032         char space_buf[7];
5033
5034         if (pcs == NULL || pcs->pcs_state == CS_NONE)
5035                 return;
5036
5037         (void) printf(gettext("checkpoint: "));
5038
5039         start = pcs->pcs_start_time;
5040         zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf));
5041
5042         if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) {
5043                 char *date = ctime(&start);
5044
5045                 /*
5046                  * ctime() adds a newline at the end of the generated
5047                  * string, thus the weird format specifier and the
5048                  * strlen() call used to chop it off from the output.
5049                  */
5050                 (void) printf(gettext("created %.*s, consumes %s\n"),
5051                     strlen(date) - 1, date, space_buf);
5052                 return;
5053         }
5054
5055         assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING);
5056
5057         (void) printf(gettext("discarding, %s remaining.\n"),
5058             space_buf);
5059 }
5060
5061 static void
5062 print_error_log(zpool_handle_t *zhp)
5063 {
5064         nvlist_t *nverrlist = NULL;
5065         nvpair_t *elem;
5066         char *pathname;
5067         size_t len = MAXPATHLEN * 2;
5068
5069         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
5070                 (void) printf("errors: List of errors unavailable "
5071                     "(insufficient privileges)\n");
5072                 return;
5073         }
5074
5075         (void) printf("errors: Permanent errors have been "
5076             "detected in the following files:\n\n");
5077
5078         pathname = safe_malloc(len);
5079         elem = NULL;
5080         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
5081                 nvlist_t *nv;
5082                 uint64_t dsobj, obj;
5083
5084                 verify(nvpair_value_nvlist(elem, &nv) == 0);
5085                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
5086                     &dsobj) == 0);
5087                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
5088                     &obj) == 0);
5089                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
5090                 (void) printf("%7s %s\n", "", pathname);
5091         }
5092         free(pathname);
5093         nvlist_free(nverrlist);
5094 }
5095
5096 static void
5097 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares,
5098     uint_t nspares)
5099 {
5100         uint_t i;
5101         char *name;
5102
5103         if (nspares == 0)
5104                 return;
5105
5106         (void) printf(gettext("\tspares\n"));
5107
5108         for (i = 0; i < nspares; i++) {
5109                 name = zpool_vdev_name(g_zfs, zhp, spares[i],
5110                     cb->cb_name_flags);
5111                 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE);
5112                 free(name);
5113         }
5114 }
5115
5116 static void
5117 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache,
5118     uint_t nl2cache)
5119 {
5120         uint_t i;
5121         char *name;
5122
5123         if (nl2cache == 0)
5124                 return;
5125
5126         (void) printf(gettext("\tcache\n"));
5127
5128         for (i = 0; i < nl2cache; i++) {
5129                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i],
5130                     cb->cb_name_flags);
5131                 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE);
5132                 free(name);
5133         }
5134 }
5135
5136 static void
5137 print_dedup_stats(nvlist_t *config)
5138 {
5139         ddt_histogram_t *ddh;
5140         ddt_stat_t *dds;
5141         ddt_object_t *ddo;
5142         uint_t c;
5143
5144         /*
5145          * If the pool was faulted then we may not have been able to
5146          * obtain the config. Otherwise, if we have anything in the dedup
5147          * table continue processing the stats.
5148          */
5149         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
5150             (uint64_t **)&ddo, &c) != 0)
5151                 return;
5152
5153         (void) printf("\n");
5154         (void) printf(gettext(" dedup: "));
5155         if (ddo->ddo_count == 0) {
5156                 (void) printf(gettext("no DDT entries\n"));
5157                 return;
5158         }
5159
5160         (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
5161             (u_longlong_t)ddo->ddo_count,
5162             (u_longlong_t)ddo->ddo_dspace,
5163             (u_longlong_t)ddo->ddo_mspace);
5164
5165         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
5166             (uint64_t **)&dds, &c) == 0);
5167         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
5168             (uint64_t **)&ddh, &c) == 0);
5169         zpool_dump_ddt(dds, ddh);
5170 }
5171
5172 /*
5173  * Display a summary of pool status.  Displays a summary such as:
5174  *
5175  *        pool: tank
5176  *      status: DEGRADED
5177  *      reason: One or more devices ...
5178  *         see: http://illumos.org/msg/ZFS-xxxx-01
5179  *      config:
5180  *              mirror          DEGRADED
5181  *                c1t0d0        OK
5182  *                c2t0d0        UNAVAIL
5183  *
5184  * When given the '-v' option, we print out the complete config.  If the '-e'
5185  * option is specified, then we print out error rate information as well.
5186  */
5187 int
5188 status_callback(zpool_handle_t *zhp, void *data)
5189 {
5190         status_cbdata_t *cbp = data;
5191         nvlist_t *config, *nvroot;
5192         char *msgid;
5193         int reason;
5194         const char *health;
5195         uint_t c;
5196         vdev_stat_t *vs;
5197
5198         config = zpool_get_config(zhp, NULL);
5199         reason = zpool_get_status(zhp, &msgid);
5200
5201         cbp->cb_count++;
5202
5203         /*
5204          * If we were given 'zpool status -x', only report those pools with
5205          * problems.
5206          */
5207         if (cbp->cb_explain &&
5208             (reason == ZPOOL_STATUS_OK ||
5209             reason == ZPOOL_STATUS_VERSION_OLDER ||
5210             reason == ZPOOL_STATUS_NON_NATIVE_ASHIFT ||
5211             reason == ZPOOL_STATUS_FEAT_DISABLED)) {
5212                 if (!cbp->cb_allpools) {
5213                         (void) printf(gettext("pool '%s' is healthy\n"),
5214                             zpool_get_name(zhp));
5215                         if (cbp->cb_first)
5216                                 cbp->cb_first = B_FALSE;
5217                 }
5218                 return (0);
5219         }
5220
5221         if (cbp->cb_first)
5222                 cbp->cb_first = B_FALSE;
5223         else
5224                 (void) printf("\n");
5225
5226         nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
5227         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
5228             (uint64_t **)&vs, &c) == 0);
5229         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
5230
5231         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
5232         (void) printf(gettext(" state: %s\n"), health);
5233
5234         switch (reason) {
5235         case ZPOOL_STATUS_MISSING_DEV_R:
5236                 (void) printf(gettext("status: One or more devices could not "
5237                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
5238                     "continue functioning in a degraded state.\n"));
5239                 (void) printf(gettext("action: Attach the missing device and "
5240                     "online it using 'zpool online'.\n"));
5241                 break;
5242
5243         case ZPOOL_STATUS_MISSING_DEV_NR:
5244                 (void) printf(gettext("status: One or more devices could not "
5245                     "be opened.  There are insufficient\n\treplicas for the "
5246                     "pool to continue functioning.\n"));
5247                 (void) printf(gettext("action: Attach the missing device and "
5248                     "online it using 'zpool online'.\n"));
5249                 break;
5250
5251         case ZPOOL_STATUS_CORRUPT_LABEL_R:
5252                 (void) printf(gettext("status: One or more devices could not "
5253                     "be used because the label is missing or\n\tinvalid.  "
5254                     "Sufficient replicas exist for the pool to continue\n\t"
5255                     "functioning in a degraded state.\n"));
5256                 (void) printf(gettext("action: Replace the device using "
5257                     "'zpool replace'.\n"));
5258                 break;
5259
5260         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
5261                 (void) printf(gettext("status: One or more devices could not "
5262                     "be used because the label is missing \n\tor invalid.  "
5263                     "There are insufficient replicas for the pool to "
5264                     "continue\n\tfunctioning.\n"));
5265                 zpool_explain_recover(zpool_get_handle(zhp),
5266                     zpool_get_name(zhp), reason, config);
5267                 break;
5268
5269         case ZPOOL_STATUS_FAILING_DEV:
5270                 (void) printf(gettext("status: One or more devices has "
5271                     "experienced an unrecoverable error.  An\n\tattempt was "
5272                     "made to correct the error.  Applications are "
5273                     "unaffected.\n"));
5274                 (void) printf(gettext("action: Determine if the device needs "
5275                     "to be replaced, and clear the errors\n\tusing "
5276                     "'zpool clear' or replace the device with 'zpool "
5277                     "replace'.\n"));
5278                 break;
5279
5280         case ZPOOL_STATUS_OFFLINE_DEV:
5281                 (void) printf(gettext("status: One or more devices has "
5282                     "been taken offline by the administrator.\n\tSufficient "
5283                     "replicas exist for the pool to continue functioning in "
5284                     "a\n\tdegraded state.\n"));
5285                 (void) printf(gettext("action: Online the device using "
5286                     "'zpool online' or replace the device with\n\t'zpool "
5287                     "replace'.\n"));
5288                 break;
5289
5290         case ZPOOL_STATUS_REMOVED_DEV:
5291                 (void) printf(gettext("status: One or more devices has "
5292                     "been removed by the administrator.\n\tSufficient "
5293                     "replicas exist for the pool to continue functioning in "
5294                     "a\n\tdegraded state.\n"));
5295                 (void) printf(gettext("action: Online the device using "
5296                     "'zpool online' or replace the device with\n\t'zpool "
5297                     "replace'.\n"));
5298                 break;
5299
5300         case ZPOOL_STATUS_RESILVERING:
5301                 (void) printf(gettext("status: One or more devices is "
5302                     "currently being resilvered.  The pool will\n\tcontinue "
5303                     "to function, possibly in a degraded state.\n"));
5304                 (void) printf(gettext("action: Wait for the resilver to "
5305                     "complete.\n"));
5306                 break;
5307
5308         case ZPOOL_STATUS_CORRUPT_DATA:
5309                 (void) printf(gettext("status: One or more devices has "
5310                     "experienced an error resulting in data\n\tcorruption.  "
5311                     "Applications may be affected.\n"));
5312                 (void) printf(gettext("action: Restore the file in question "
5313                     "if possible.  Otherwise restore the\n\tentire pool from "
5314                     "backup.\n"));
5315                 break;
5316
5317         case ZPOOL_STATUS_CORRUPT_POOL:
5318                 (void) printf(gettext("status: The pool metadata is corrupted "
5319                     "and the pool cannot be opened.\n"));
5320                 zpool_explain_recover(zpool_get_handle(zhp),
5321                     zpool_get_name(zhp), reason, config);
5322                 break;
5323
5324         case ZPOOL_STATUS_VERSION_OLDER:
5325                 (void) printf(gettext("status: The pool is formatted using a "
5326                     "legacy on-disk format.  The pool can\n\tstill be used, "
5327                     "but some features are unavailable.\n"));
5328                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
5329                     "upgrade'.  Once this is done, the\n\tpool will no longer "
5330                     "be accessible on software that does not support feature\n"
5331                     "\tflags.\n"));
5332                 break;
5333
5334         case ZPOOL_STATUS_VERSION_NEWER:
5335                 (void) printf(gettext("status: The pool has been upgraded to a "
5336                     "newer, incompatible on-disk version.\n\tThe pool cannot "
5337                     "be accessed on this system.\n"));
5338                 (void) printf(gettext("action: Access the pool from a system "
5339                     "running more recent software, or\n\trestore the pool from "
5340                     "backup.\n"));
5341                 break;
5342
5343         case ZPOOL_STATUS_FEAT_DISABLED:
5344                 (void) printf(gettext("status: Some supported features are not "
5345                     "enabled on the pool. The pool can\n\tstill be used, but "
5346                     "some features are unavailable.\n"));
5347                 (void) printf(gettext("action: Enable all features using "
5348                     "'zpool upgrade'. Once this is done,\n\tthe pool may no "
5349                     "longer be accessible by software that does not support\n\t"
5350                     "the features. See zpool-features(7) for details.\n"));
5351                 break;
5352
5353         case ZPOOL_STATUS_UNSUP_FEAT_READ:
5354                 (void) printf(gettext("status: The pool cannot be accessed on "
5355                     "this system because it uses the\n\tfollowing feature(s) "
5356                     "not supported on this system:\n"));
5357                 zpool_print_unsup_feat(config);
5358                 (void) printf("\n");
5359                 (void) printf(gettext("action: Access the pool from a system "
5360                     "that supports the required feature(s),\n\tor restore the "
5361                     "pool from backup.\n"));
5362                 break;
5363
5364         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
5365                 (void) printf(gettext("status: The pool can only be accessed "
5366                     "in read-only mode on this system. It\n\tcannot be "
5367                     "accessed in read-write mode because it uses the "
5368                     "following\n\tfeature(s) not supported on this system:\n"));
5369                 zpool_print_unsup_feat(config);
5370                 (void) printf("\n");
5371                 (void) printf(gettext("action: The pool cannot be accessed in "
5372                     "read-write mode. Import the pool with\n"
5373                     "\t\"-o readonly=on\", access the pool from a system that "
5374                     "supports the\n\trequired feature(s), or restore the "
5375                     "pool from backup.\n"));
5376                 break;
5377
5378         case ZPOOL_STATUS_FAULTED_DEV_R:
5379                 (void) printf(gettext("status: One or more devices are "
5380                     "faulted in response to persistent errors.\n\tSufficient "
5381                     "replicas exist for the pool to continue functioning "
5382                     "in a\n\tdegraded state.\n"));
5383                 (void) printf(gettext("action: Replace the faulted device, "
5384                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
5385                 break;
5386
5387         case ZPOOL_STATUS_FAULTED_DEV_NR:
5388                 (void) printf(gettext("status: One or more devices are "
5389                     "faulted in response to persistent errors.  There are "
5390                     "insufficient replicas for the pool to\n\tcontinue "
5391                     "functioning.\n"));
5392                 (void) printf(gettext("action: Destroy and re-create the pool "
5393                     "from a backup source.  Manually marking the device\n"
5394                     "\trepaired using 'zpool clear' may allow some data "
5395                     "to be recovered.\n"));
5396                 break;
5397
5398         case ZPOOL_STATUS_IO_FAILURE_MMP:
5399                 (void) printf(gettext("status: The pool is suspended because "
5400                     "multihost writes failed or were delayed;\n\tanother "
5401                     "system could import the pool undetected.\n"));
5402                 (void) printf(gettext("action: Make sure the pool's devices "
5403                     "are connected, then reboot your system and\n\timport the "
5404                     "pool.\n"));
5405                 break;
5406
5407         case ZPOOL_STATUS_IO_FAILURE_WAIT:
5408         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
5409                 (void) printf(gettext("status: One or more devices are "
5410                     "faulted in response to IO failures.\n"));
5411                 (void) printf(gettext("action: Make sure the affected devices "
5412                     "are connected, then run 'zpool clear'.\n"));
5413                 break;
5414
5415         case ZPOOL_STATUS_BAD_LOG:
5416                 (void) printf(gettext("status: An intent log record "
5417                     "could not be read.\n"
5418                     "\tWaiting for adminstrator intervention to fix the "
5419                     "faulted pool.\n"));
5420                 (void) printf(gettext("action: Either restore the affected "
5421                     "device(s) and run 'zpool online',\n"
5422                     "\tor ignore the intent log records by running "
5423                     "'zpool clear'.\n"));
5424                 break;
5425
5426         case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
5427                 (void) printf(gettext("status: One or more devices are "
5428                     "configured to use a non-native block size.\n"
5429                     "\tExpect reduced performance.\n"));
5430                 (void) printf(gettext("action: Replace affected devices with "
5431                     "devices that support the\n\tconfigured block size, or "
5432                     "migrate data to a properly configured\n\tpool.\n"));
5433                 break;
5434
5435         default:
5436                 /*
5437                  * The remaining errors can't actually be generated, yet.
5438                  */
5439                 assert(reason == ZPOOL_STATUS_OK);
5440         }
5441
5442         if (msgid != NULL)
5443                 (void) printf(gettext("   see: http://illumos.org/msg/%s\n"),
5444                     msgid);
5445
5446         if (config != NULL) {
5447                 uint64_t nerr;
5448                 nvlist_t **spares, **l2cache;
5449                 uint_t nspares, nl2cache;
5450                 pool_checkpoint_stat_t *pcs = NULL;
5451                 pool_scan_stat_t *ps = NULL;
5452                 pool_removal_stat_t *prs = NULL;
5453
5454                 (void) nvlist_lookup_uint64_array(nvroot,
5455                     ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c);
5456                 (void) nvlist_lookup_uint64_array(nvroot,
5457                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
5458                 (void) nvlist_lookup_uint64_array(nvroot,
5459                     ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c);
5460
5461                 print_scan_status(ps);
5462                 print_checkpoint_scan_warning(ps, pcs);
5463                 print_removal_status(zhp, prs);
5464                 print_checkpoint_status(pcs);
5465
5466                 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
5467                     cbp->cb_name_flags);
5468                 if (cbp->cb_namewidth < 10)
5469                         cbp->cb_namewidth = 10;
5470
5471                 (void) printf(gettext("config:\n\n"));
5472                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"),
5473                     cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE",
5474                     "CKSUM");
5475
5476                 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0,
5477                     B_FALSE);
5478
5479                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP);
5480                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL);
5481                 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS);
5482
5483                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
5484                     &l2cache, &nl2cache) == 0)
5485                         print_l2cache(zhp, cbp, l2cache, nl2cache);
5486
5487                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
5488                     &spares, &nspares) == 0)
5489                         print_spares(zhp, cbp, spares, nspares);
5490
5491                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
5492                     &nerr) == 0) {
5493                         nvlist_t *nverrlist = NULL;
5494
5495                         /*
5496                          * If the approximate error count is small, get a
5497                          * precise count by fetching the entire log and
5498                          * uniquifying the results.
5499                          */
5500                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
5501                             zpool_get_errlog(zhp, &nverrlist) == 0) {
5502                                 nvpair_t *elem;
5503
5504                                 elem = NULL;
5505                                 nerr = 0;
5506                                 while ((elem = nvlist_next_nvpair(nverrlist,
5507                                     elem)) != NULL) {
5508                                         nerr++;
5509                                 }
5510                         }
5511                         nvlist_free(nverrlist);
5512
5513                         (void) printf("\n");
5514
5515                         if (nerr == 0)
5516                                 (void) printf(gettext("errors: No known data "
5517                                     "errors\n"));
5518                         else if (!cbp->cb_verbose)
5519                                 (void) printf(gettext("errors: %llu data "
5520                                     "errors, use '-v' for a list\n"),
5521                                     (u_longlong_t)nerr);
5522                         else
5523                                 print_error_log(zhp);
5524                 }
5525
5526                 if (cbp->cb_dedup_stats)
5527                         print_dedup_stats(config);
5528         } else {
5529                 (void) printf(gettext("config: The configuration cannot be "
5530                     "determined.\n"));
5531         }
5532
5533         return (0);
5534 }
5535
5536 /*
5537  * zpool status [-gLPvx] [-T d|u] [pool] ... [interval [count]]
5538  *
5539  *      -g      Display guid for individual vdev name.
5540  *      -L      Follow links when resolving vdev path name.
5541  *      -P      Display full path for vdev name.
5542  *      -v      Display complete error logs
5543  *      -x      Display only pools with potential problems
5544  *      -D      Display dedup status (undocumented)
5545  *      -T      Display a timestamp in date(1) or Unix format
5546  *
5547  * Describes the health status of all pools or some subset.
5548  */
5549 int
5550 zpool_do_status(int argc, char **argv)
5551 {
5552         int c;
5553         int ret;
5554         unsigned long interval = 0, count = 0;
5555         status_cbdata_t cb = { 0 };
5556
5557         /* check options */
5558         while ((c = getopt(argc, argv, "gLPvxDT:")) != -1) {
5559                 switch (c) {
5560                 case 'g':
5561                         cb.cb_name_flags |= VDEV_NAME_GUID;
5562                         break;
5563                 case 'L':
5564                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
5565                         break;
5566                 case 'P':
5567                         cb.cb_name_flags |= VDEV_NAME_PATH;
5568                         break;
5569                 case 'v':
5570                         cb.cb_verbose = B_TRUE;
5571                         break;
5572                 case 'x':
5573                         cb.cb_explain = B_TRUE;
5574                         break;
5575                 case 'D':
5576                         cb.cb_dedup_stats = B_TRUE;
5577                         break;
5578                 case 'T':
5579                         get_timestamp_arg(*optarg);
5580                         break;
5581                 case '?':
5582                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5583                             optopt);
5584                         usage(B_FALSE);
5585                 }
5586         }
5587
5588         argc -= optind;
5589         argv += optind;
5590
5591         get_interval_count(&argc, argv, &interval, &count);
5592
5593         if (argc == 0)
5594                 cb.cb_allpools = B_TRUE;
5595
5596         cb.cb_first = B_TRUE;
5597         cb.cb_print_status = B_TRUE;
5598
5599         for (;;) {
5600                 if (timestamp_fmt != NODATE)
5601                         print_timestamp(timestamp_fmt);
5602
5603                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
5604                     status_callback, &cb);
5605
5606                 if (argc == 0 && cb.cb_count == 0)
5607                         (void) printf(gettext("no pools available\n"));
5608                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
5609                         (void) printf(gettext("all pools are healthy\n"));
5610
5611                 if (ret != 0)
5612                         return (ret);
5613
5614                 if (interval == 0)
5615                         break;
5616
5617                 if (count != 0 && --count == 0)
5618                         break;
5619
5620                 (void) sleep(interval);
5621         }
5622
5623         return (0);
5624 }
5625
5626 typedef struct upgrade_cbdata {
5627         boolean_t       cb_first;
5628         boolean_t       cb_unavail;
5629         char            cb_poolname[ZFS_MAX_DATASET_NAME_LEN];
5630         int             cb_argc;
5631         uint64_t        cb_version;
5632         char            **cb_argv;
5633 } upgrade_cbdata_t;
5634
5635 #ifdef __FreeBSD__
5636 static int
5637 is_root_pool(zpool_handle_t *zhp)
5638 {
5639         static struct statfs sfs;
5640         static char *poolname = NULL;
5641         static boolean_t stated = B_FALSE;
5642         char *slash;
5643
5644         if (!stated) {
5645                 stated = B_TRUE;
5646                 if (statfs("/", &sfs) == -1) {
5647                         (void) fprintf(stderr,
5648                             "Unable to stat root file system: %s.\n",
5649                             strerror(errno));
5650                         return (0);
5651                 }
5652                 if (strcmp(sfs.f_fstypename, "zfs") != 0)
5653                         return (0);
5654                 poolname = sfs.f_mntfromname;
5655                 if ((slash = strchr(poolname, '/')) != NULL)
5656                         *slash = '\0';
5657         }
5658         return (poolname != NULL && strcmp(poolname, zpool_get_name(zhp)) == 0);
5659 }
5660
5661 static void
5662 root_pool_upgrade_check(zpool_handle_t *zhp, char *poolname, int size)
5663 {
5664
5665         if (poolname[0] == '\0' && is_root_pool(zhp))
5666                 (void) strlcpy(poolname, zpool_get_name(zhp), size);
5667 }
5668 #endif  /* FreeBSD */
5669
5670 static int
5671 upgrade_version(zpool_handle_t *zhp, uint64_t version)
5672 {
5673         int ret;
5674         nvlist_t *config;
5675         uint64_t oldversion;
5676
5677         config = zpool_get_config(zhp, NULL);
5678         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
5679             &oldversion) == 0);
5680
5681         assert(SPA_VERSION_IS_SUPPORTED(oldversion));
5682         assert(oldversion < version);
5683
5684         ret = zpool_upgrade(zhp, version);
5685         if (ret != 0)
5686                 return (ret);
5687
5688         if (version >= SPA_VERSION_FEATURES) {
5689                 (void) printf(gettext("Successfully upgraded "
5690                     "'%s' from version %llu to feature flags.\n"),
5691                     zpool_get_name(zhp), oldversion);
5692         } else {
5693                 (void) printf(gettext("Successfully upgraded "
5694                     "'%s' from version %llu to version %llu.\n"),
5695                     zpool_get_name(zhp), oldversion, version);
5696         }
5697
5698         return (0);
5699 }
5700
5701 static int
5702 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
5703 {
5704         int i, ret, count;
5705         boolean_t firstff = B_TRUE;
5706         nvlist_t *enabled = zpool_get_features(zhp);
5707
5708         count = 0;
5709         for (i = 0; i < SPA_FEATURES; i++) {
5710                 const char *fname = spa_feature_table[i].fi_uname;
5711                 const char *fguid = spa_feature_table[i].fi_guid;
5712                 if (!nvlist_exists(enabled, fguid)) {
5713                         char *propname;
5714                         verify(-1 != asprintf(&propname, "feature@%s", fname));
5715                         ret = zpool_set_prop(zhp, propname,
5716                             ZFS_FEATURE_ENABLED);
5717                         if (ret != 0) {
5718                                 free(propname);
5719                                 return (ret);
5720                         }
5721                         count++;
5722
5723                         if (firstff) {
5724                                 (void) printf(gettext("Enabled the "
5725                                     "following features on '%s':\n"),
5726                                     zpool_get_name(zhp));
5727                                 firstff = B_FALSE;
5728                         }
5729                         (void) printf(gettext("  %s\n"), fname);
5730                         free(propname);
5731                 }
5732         }
5733
5734         if (countp != NULL)
5735                 *countp = count;
5736         return (0);
5737 }
5738
5739 static int
5740 upgrade_cb(zpool_handle_t *zhp, void *arg)
5741 {
5742         upgrade_cbdata_t *cbp = arg;
5743         nvlist_t *config;
5744         uint64_t version;
5745         boolean_t printnl = B_FALSE;
5746         int ret;
5747
5748         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5749                 (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
5750                     "currently unavailable.\n\n"), zpool_get_name(zhp));
5751                 cbp->cb_unavail = B_TRUE;
5752                 /* Allow iteration to continue. */
5753                 return (0);
5754         }
5755
5756         config = zpool_get_config(zhp, NULL);
5757         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
5758             &version) == 0);
5759
5760         assert(SPA_VERSION_IS_SUPPORTED(version));
5761
5762         if (version < cbp->cb_version) {
5763                 cbp->cb_first = B_FALSE;
5764                 ret = upgrade_version(zhp, cbp->cb_version);
5765                 if (ret != 0)
5766                         return (ret);
5767 #ifdef __FreeBSD__
5768                 root_pool_upgrade_check(zhp, cbp->cb_poolname,
5769                     sizeof(cbp->cb_poolname));
5770 #endif  /* __FreeBSD__ */
5771                 printnl = B_TRUE;
5772
5773 #ifdef illumos
5774                 /*
5775                  * If they did "zpool upgrade -a", then we could
5776                  * be doing ioctls to different pools.  We need
5777                  * to log this history once to each pool, and bypass
5778                  * the normal history logging that happens in main().
5779                  */
5780                 (void) zpool_log_history(g_zfs, history_str);
5781                 log_history = B_FALSE;
5782 #endif
5783         }
5784
5785         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
5786                 int count;
5787                 ret = upgrade_enable_all(zhp, &count);
5788                 if (ret != 0)
5789                         return (ret);
5790
5791                 if (count > 0) {
5792                         cbp->cb_first = B_FALSE;
5793                         printnl = B_TRUE;
5794 #ifdef __FreeBSD__
5795                         root_pool_upgrade_check(zhp, cbp->cb_poolname,
5796                             sizeof(cbp->cb_poolname));
5797 #endif  /* __FreeBSD__ */
5798                         /*
5799                          * If they did "zpool upgrade -a", then we could
5800                          * be doing ioctls to different pools.  We need
5801                          * to log this history once to each pool, and bypass
5802                          * the normal history logging that happens in main().
5803                          */
5804                         (void) zpool_log_history(g_zfs, history_str);
5805                         log_history = B_FALSE;
5806                 }
5807         }
5808
5809         if (printnl) {
5810                 (void) printf(gettext("\n"));
5811         }
5812
5813         return (0);
5814 }
5815
5816 static int
5817 upgrade_list_unavail(zpool_handle_t *zhp, void *arg)
5818 {
5819         upgrade_cbdata_t *cbp = arg;
5820
5821         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5822                 if (cbp->cb_first) {
5823                         (void) fprintf(stderr, gettext("The following pools "
5824                             "are unavailable and cannot be upgraded as this "
5825                             "time.\n\n"));
5826                         (void) fprintf(stderr, gettext("POOL\n"));
5827                         (void) fprintf(stderr, gettext("------------\n"));
5828                         cbp->cb_first = B_FALSE;
5829                 }
5830                 (void) printf(gettext("%s\n"), zpool_get_name(zhp));
5831                 cbp->cb_unavail = B_TRUE;
5832         }
5833         return (0);
5834 }
5835
5836 static int
5837 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
5838 {
5839         upgrade_cbdata_t *cbp = arg;
5840         nvlist_t *config;
5841         uint64_t version;
5842
5843         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5844                 /*
5845                  * This will have been reported by upgrade_list_unavail so
5846                  * just allow iteration to continue.
5847                  */
5848                 cbp->cb_unavail = B_TRUE;
5849                 return (0);
5850         }
5851
5852         config = zpool_get_config(zhp, NULL);
5853         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
5854             &version) == 0);
5855
5856         assert(SPA_VERSION_IS_SUPPORTED(version));
5857
5858         if (version < SPA_VERSION_FEATURES) {
5859                 if (cbp->cb_first) {
5860                         (void) printf(gettext("The following pools are "
5861                             "formatted with legacy version numbers and can\n"
5862                             "be upgraded to use feature flags.  After "
5863                             "being upgraded, these pools\nwill no "
5864                             "longer be accessible by software that does not "
5865                             "support feature\nflags.\n\n"));
5866                         (void) printf(gettext("VER  POOL\n"));
5867                         (void) printf(gettext("---  ------------\n"));
5868                         cbp->cb_first = B_FALSE;
5869                 }
5870
5871                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
5872                     zpool_get_name(zhp));
5873         }
5874
5875         return (0);
5876 }
5877
5878 static int
5879 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
5880 {
5881         upgrade_cbdata_t *cbp = arg;
5882         nvlist_t *config;
5883         uint64_t version;
5884
5885         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5886                 /*
5887                  * This will have been reported by upgrade_list_unavail so
5888                  * just allow iteration to continue.
5889                  */
5890                 cbp->cb_unavail = B_TRUE;
5891                 return (0);
5892         }
5893
5894         config = zpool_get_config(zhp, NULL);
5895         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
5896             &version) == 0);
5897
5898         if (version >= SPA_VERSION_FEATURES) {
5899                 int i;
5900                 boolean_t poolfirst = B_TRUE;
5901                 nvlist_t *enabled = zpool_get_features(zhp);
5902
5903                 for (i = 0; i < SPA_FEATURES; i++) {
5904                         const char *fguid = spa_feature_table[i].fi_guid;
5905                         const char *fname = spa_feature_table[i].fi_uname;
5906                         if (!nvlist_exists(enabled, fguid)) {
5907                                 if (cbp->cb_first) {
5908                                         (void) printf(gettext("\nSome "
5909                                             "supported features are not "
5910                                             "enabled on the following pools. "
5911                                             "Once a\nfeature is enabled the "
5912                                             "pool may become incompatible with "
5913                                             "software\nthat does not support "
5914                                             "the feature. See "
5915                                             "zpool-features(7) for "
5916                                             "details.\n\n"));
5917                                         (void) printf(gettext("POOL  "
5918                                             "FEATURE\n"));
5919                                         (void) printf(gettext("------"
5920                                             "---------\n"));
5921                                         cbp->cb_first = B_FALSE;
5922                                 }
5923
5924                                 if (poolfirst) {
5925                                         (void) printf(gettext("%s\n"),
5926                                             zpool_get_name(zhp));
5927                                         poolfirst = B_FALSE;
5928                                 }
5929
5930                                 (void) printf(gettext("      %s\n"), fname);
5931                         }
5932                 }
5933         }
5934
5935         return (0);
5936 }
5937
5938 /* ARGSUSED */
5939 static int
5940 upgrade_one(zpool_handle_t *zhp, void *data)
5941 {
5942         boolean_t printnl = B_FALSE;
5943         upgrade_cbdata_t *cbp = data;
5944         uint64_t cur_version;
5945         int ret;
5946
5947         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5948                 (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
5949                     "is currently unavailable.\n\n"), zpool_get_name(zhp));
5950                 cbp->cb_unavail = B_TRUE;
5951                 return (1);
5952         }
5953
5954         if (strcmp("log", zpool_get_name(zhp)) == 0) {
5955                 (void) printf(gettext("'log' is now a reserved word\n"
5956                     "Pool 'log' must be renamed using export and import"
5957                     " to upgrade.\n\n"));
5958                 return (1);
5959         }
5960
5961         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
5962         if (cur_version > cbp->cb_version) {
5963                 (void) printf(gettext("Pool '%s' is already formatted "
5964                     "using more current version '%llu'.\n\n"),
5965                     zpool_get_name(zhp), cur_version);
5966                 return (0);
5967         }
5968
5969         if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
5970                 (void) printf(gettext("Pool '%s' is already formatted "
5971                     "using version %llu.\n\n"), zpool_get_name(zhp),
5972                     cbp->cb_version);
5973                 return (0);
5974         }
5975
5976         if (cur_version != cbp->cb_version) {
5977                 printnl = B_TRUE;
5978                 ret = upgrade_version(zhp, cbp->cb_version);
5979                 if (ret != 0)
5980                         return (ret);
5981 #ifdef __FreeBSD__
5982                 root_pool_upgrade_check(zhp, cbp->cb_poolname,
5983                     sizeof(cbp->cb_poolname));
5984 #endif  /* __FreeBSD__ */
5985         }
5986
5987         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
5988                 int count = 0;
5989                 ret = upgrade_enable_all(zhp, &count);
5990                 if (ret != 0)
5991                         return (ret);
5992
5993                 if (count != 0) {
5994                         printnl = B_TRUE;
5995 #ifdef __FreeBSD__
5996                         root_pool_upgrade_check(zhp, cbp->cb_poolname,
5997                             sizeof(cbp->cb_poolname));
5998 #endif  /* __FreeBSD __*/
5999                 } else if (cur_version == SPA_VERSION) {
6000                         (void) printf(gettext("Pool '%s' already has all "
6001                             "supported features enabled.\n\n"),
6002                             zpool_get_name(zhp));
6003                 }
6004         }
6005
6006         if (printnl) {
6007                 (void) printf(gettext("\n"));
6008         }
6009
6010         return (0);
6011 }
6012
6013 /*
6014  * zpool upgrade
6015  * zpool upgrade -v
6016  * zpool upgrade [-V version] <-a | pool ...>
6017  *
6018  * With no arguments, display downrev'd ZFS pool available for upgrade.
6019  * Individual pools can be upgraded by specifying the pool, and '-a' will
6020  * upgrade all pools.
6021  */
6022 int
6023 zpool_do_upgrade(int argc, char **argv)
6024 {
6025         int c;
6026         upgrade_cbdata_t cb = { 0 };
6027         int ret = 0;
6028         boolean_t showversions = B_FALSE;
6029         boolean_t upgradeall = B_FALSE;
6030         char *end;
6031
6032
6033         /* check options */
6034         while ((c = getopt(argc, argv, ":avV:")) != -1) {
6035                 switch (c) {
6036                 case 'a':
6037                         upgradeall = B_TRUE;
6038                         break;
6039                 case 'v':
6040                         showversions = B_TRUE;
6041                         break;
6042                 case 'V':
6043                         cb.cb_version = strtoll(optarg, &end, 10);
6044                         if (*end != '\0' ||
6045                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
6046                                 (void) fprintf(stderr,
6047                                     gettext("invalid version '%s'\n"), optarg);
6048                                 usage(B_FALSE);
6049                         }
6050                         break;
6051                 case ':':
6052                         (void) fprintf(stderr, gettext("missing argument for "
6053                             "'%c' option\n"), optopt);
6054                         usage(B_FALSE);
6055                         break;
6056                 case '?':
6057                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6058                             optopt);
6059                         usage(B_FALSE);
6060                 }
6061         }
6062
6063         cb.cb_argc = argc;
6064         cb.cb_argv = argv;
6065         argc -= optind;
6066         argv += optind;
6067
6068         if (cb.cb_version == 0) {
6069                 cb.cb_version = SPA_VERSION;
6070         } else if (!upgradeall && argc == 0) {
6071                 (void) fprintf(stderr, gettext("-V option is "
6072                     "incompatible with other arguments\n"));
6073                 usage(B_FALSE);
6074         }
6075
6076         if (showversions) {
6077                 if (upgradeall || argc != 0) {
6078                         (void) fprintf(stderr, gettext("-v option is "
6079                             "incompatible with other arguments\n"));
6080                         usage(B_FALSE);
6081                 }
6082         } else if (upgradeall) {
6083                 if (argc != 0) {
6084                         (void) fprintf(stderr, gettext("-a option should not "
6085                             "be used along with a pool name\n"));
6086                         usage(B_FALSE);
6087                 }
6088         }
6089
6090         (void) printf(gettext("This system supports ZFS pool feature "
6091             "flags.\n\n"));
6092         if (showversions) {
6093                 int i;
6094
6095                 (void) printf(gettext("The following features are "
6096                     "supported:\n\n"));
6097                 (void) printf(gettext("FEAT DESCRIPTION\n"));
6098                 (void) printf("----------------------------------------------"
6099                     "---------------\n");
6100                 for (i = 0; i < SPA_FEATURES; i++) {
6101                         zfeature_info_t *fi = &spa_feature_table[i];
6102                         const char *ro =
6103                             (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
6104                             " (read-only compatible)" : "";
6105
6106                         (void) printf("%-37s%s\n", fi->fi_uname, ro);
6107                         (void) printf("     %s\n", fi->fi_desc);
6108                 }
6109                 (void) printf("\n");
6110
6111                 (void) printf(gettext("The following legacy versions are also "
6112                     "supported:\n\n"));
6113                 (void) printf(gettext("VER  DESCRIPTION\n"));
6114                 (void) printf("---  -----------------------------------------"
6115                     "---------------\n");
6116                 (void) printf(gettext(" 1   Initial ZFS version\n"));
6117                 (void) printf(gettext(" 2   Ditto blocks "
6118                     "(replicated metadata)\n"));
6119                 (void) printf(gettext(" 3   Hot spares and double parity "
6120                     "RAID-Z\n"));
6121                 (void) printf(gettext(" 4   zpool history\n"));
6122                 (void) printf(gettext(" 5   Compression using the gzip "
6123                     "algorithm\n"));
6124                 (void) printf(gettext(" 6   bootfs pool property\n"));
6125                 (void) printf(gettext(" 7   Separate intent log devices\n"));
6126                 (void) printf(gettext(" 8   Delegated administration\n"));
6127                 (void) printf(gettext(" 9   refquota and refreservation "
6128                     "properties\n"));
6129                 (void) printf(gettext(" 10  Cache devices\n"));
6130                 (void) printf(gettext(" 11  Improved scrub performance\n"));
6131                 (void) printf(gettext(" 12  Snapshot properties\n"));
6132                 (void) printf(gettext(" 13  snapused property\n"));
6133                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
6134                 (void) printf(gettext(" 15  user/group space accounting\n"));
6135                 (void) printf(gettext(" 16  stmf property support\n"));
6136                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
6137                 (void) printf(gettext(" 18  Snapshot user holds\n"));
6138                 (void) printf(gettext(" 19  Log device removal\n"));
6139                 (void) printf(gettext(" 20  Compression using zle "
6140                     "(zero-length encoding)\n"));
6141                 (void) printf(gettext(" 21  Deduplication\n"));
6142                 (void) printf(gettext(" 22  Received properties\n"));
6143                 (void) printf(gettext(" 23  Slim ZIL\n"));
6144                 (void) printf(gettext(" 24  System attributes\n"));
6145                 (void) printf(gettext(" 25  Improved scrub stats\n"));
6146                 (void) printf(gettext(" 26  Improved snapshot deletion "
6147                     "performance\n"));
6148                 (void) printf(gettext(" 27  Improved snapshot creation "
6149                     "performance\n"));
6150                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
6151                 (void) printf(gettext("\nFor more information on a particular "
6152                     "version, including supported releases,\n"));
6153                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
6154         } else if (argc == 0 && upgradeall) {
6155                 cb.cb_first = B_TRUE;
6156                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
6157                 if (ret == 0 && cb.cb_first) {
6158                         if (cb.cb_version == SPA_VERSION) {
6159                                 (void) printf(gettext("All %spools are already "
6160                                     "formatted using feature flags.\n\n"),
6161                                     cb.cb_unavail ? gettext("available ") : "");
6162                                 (void) printf(gettext("Every %sfeature flags "
6163                                     "pool already has all supported features "
6164                                     "enabled.\n"),
6165                                     cb.cb_unavail ? gettext("available ") : "");
6166                         } else {
6167                                 (void) printf(gettext("All pools are already "
6168                                     "formatted with version %llu or higher.\n"),
6169                                     cb.cb_version);
6170                         }
6171                 }
6172         } else if (argc == 0) {
6173                 cb.cb_first = B_TRUE;
6174                 ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb);
6175                 assert(ret == 0);
6176
6177                 if (!cb.cb_first) {
6178                         (void) fprintf(stderr, "\n");
6179                 }
6180
6181                 cb.cb_first = B_TRUE;
6182                 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
6183                 assert(ret == 0);
6184
6185                 if (cb.cb_first) {
6186                         (void) printf(gettext("All %spools are formatted using "
6187                             "feature flags.\n\n"), cb.cb_unavail ?
6188                             gettext("available ") : "");
6189                 } else {
6190                         (void) printf(gettext("\nUse 'zpool upgrade -v' "
6191                             "for a list of available legacy versions.\n"));
6192                 }
6193
6194                 cb.cb_first = B_TRUE;
6195                 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
6196                 assert(ret == 0);
6197
6198                 if (cb.cb_first) {
6199                         (void) printf(gettext("Every %sfeature flags pool has "
6200                             "all supported features enabled.\n"),
6201                             cb.cb_unavail ? gettext("available ") : "");
6202                 } else {
6203                         (void) printf(gettext("\n"));
6204                 }
6205         } else {
6206                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
6207                     upgrade_one, &cb);
6208         }
6209
6210         if (cb.cb_poolname[0] != '\0') {
6211                 (void) printf(
6212                     "If you boot from pool '%s', don't forget to update boot code.\n"
6213                     "Assuming you use GPT partitioning and da0 is your boot disk\n"
6214                     "the following command will do it:\n"
6215                     "\n"
6216                     "\tgpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0\n\n",
6217                     cb.cb_poolname);
6218         }
6219
6220         return (ret);
6221 }
6222
6223 typedef struct hist_cbdata {
6224         boolean_t first;
6225         boolean_t longfmt;
6226         boolean_t internal;
6227 } hist_cbdata_t;
6228
6229 /*
6230  * Print out the command history for a specific pool.
6231  */
6232 static int
6233 get_history_one(zpool_handle_t *zhp, void *data)
6234 {
6235         nvlist_t *nvhis;
6236         nvlist_t **records;
6237         uint_t numrecords;
6238         int ret, i;
6239         hist_cbdata_t *cb = (hist_cbdata_t *)data;
6240
6241         cb->first = B_FALSE;
6242
6243         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
6244
6245         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
6246                 return (ret);
6247
6248         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
6249             &records, &numrecords) == 0);
6250         for (i = 0; i < numrecords; i++) {
6251                 nvlist_t *rec = records[i];
6252                 char tbuf[30] = "";
6253
6254                 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
6255                         time_t tsec;
6256                         struct tm t;
6257
6258                         tsec = fnvlist_lookup_uint64(records[i],
6259                             ZPOOL_HIST_TIME);
6260                         (void) localtime_r(&tsec, &t);
6261                         (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
6262                 }
6263
6264                 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
6265                         (void) printf("%s %s", tbuf,
6266                             fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
6267                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
6268                         int ievent =
6269                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
6270                         if (!cb->internal)
6271                                 continue;
6272                         if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
6273                                 (void) printf("%s unrecognized record:\n",
6274                                     tbuf);
6275                                 dump_nvlist(rec, 4);
6276                                 continue;
6277                         }
6278                         (void) printf("%s [internal %s txg:%lld] %s", tbuf,
6279                             zfs_history_event_names[ievent],
6280                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
6281                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
6282                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
6283                         if (!cb->internal)
6284                                 continue;
6285                         (void) printf("%s [txg:%lld] %s", tbuf,
6286                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG),
6287                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
6288                         if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
6289                                 (void) printf(" %s (%llu)",
6290                                     fnvlist_lookup_string(rec,
6291                                     ZPOOL_HIST_DSNAME),
6292                                     fnvlist_lookup_uint64(rec,
6293                                     ZPOOL_HIST_DSID));
6294                         }
6295                         (void) printf(" %s", fnvlist_lookup_string(rec,
6296                             ZPOOL_HIST_INT_STR));
6297                 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
6298                         if (!cb->internal)
6299                                 continue;
6300                         (void) printf("%s ioctl %s\n", tbuf,
6301                             fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
6302                         if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
6303                                 (void) printf("    input:\n");
6304                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
6305                                     ZPOOL_HIST_INPUT_NVL), 8);
6306                         }
6307                         if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
6308                                 (void) printf("    output:\n");
6309                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
6310                                     ZPOOL_HIST_OUTPUT_NVL), 8);
6311                         }
6312                         if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
6313                                 (void) printf("    errno: %lld\n",
6314                                     fnvlist_lookup_int64(rec,
6315                                     ZPOOL_HIST_ERRNO));
6316                         }
6317                 } else {
6318                         if (!cb->internal)
6319                                 continue;
6320                         (void) printf("%s unrecognized record:\n", tbuf);
6321                         dump_nvlist(rec, 4);
6322                 }
6323
6324                 if (!cb->longfmt) {
6325                         (void) printf("\n");
6326                         continue;
6327                 }
6328                 (void) printf(" [");
6329                 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
6330                         uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
6331                         struct passwd *pwd = getpwuid(who);
6332                         (void) printf("user %d ", (int)who);
6333                         if (pwd != NULL)
6334                                 (void) printf("(%s) ", pwd->pw_name);
6335                 }
6336                 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
6337                         (void) printf("on %s",
6338                             fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
6339                 }
6340                 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
6341                         (void) printf(":%s",
6342                             fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
6343                 }
6344                 (void) printf("]");
6345                 (void) printf("\n");
6346         }
6347         (void) printf("\n");
6348         nvlist_free(nvhis);
6349
6350         return (ret);
6351 }
6352
6353 /*
6354  * zpool history <pool>
6355  *
6356  * Displays the history of commands that modified pools.
6357  */
6358 int
6359 zpool_do_history(int argc, char **argv)
6360 {
6361         hist_cbdata_t cbdata = { 0 };
6362         int ret;
6363         int c;
6364
6365         cbdata.first = B_TRUE;
6366         /* check options */
6367         while ((c = getopt(argc, argv, "li")) != -1) {
6368                 switch (c) {
6369                 case 'l':
6370                         cbdata.longfmt = B_TRUE;
6371                         break;
6372                 case 'i':
6373                         cbdata.internal = B_TRUE;
6374                         break;
6375                 case '?':
6376                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6377                             optopt);
6378                         usage(B_FALSE);
6379                 }
6380         }
6381         argc -= optind;
6382         argv += optind;
6383
6384         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
6385             &cbdata);
6386
6387         if (argc == 0 && cbdata.first == B_TRUE) {
6388                 (void) printf(gettext("no pools available\n"));
6389                 return (0);
6390         }
6391
6392         return (ret);
6393 }
6394
6395 static int
6396 get_callback(zpool_handle_t *zhp, void *data)
6397 {
6398         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
6399         char value[MAXNAMELEN];
6400         zprop_source_t srctype;
6401         zprop_list_t *pl;
6402
6403         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
6404
6405                 /*
6406                  * Skip the special fake placeholder. This will also skip
6407                  * over the name property when 'all' is specified.
6408                  */
6409                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
6410                     pl == cbp->cb_proplist)
6411                         continue;
6412
6413                 if (pl->pl_prop == ZPROP_INVAL &&
6414                     (zpool_prop_feature(pl->pl_user_prop) ||
6415                     zpool_prop_unsupported(pl->pl_user_prop))) {
6416                         srctype = ZPROP_SRC_LOCAL;
6417
6418                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
6419                             value, sizeof (value)) == 0) {
6420                                 zprop_print_one_property(zpool_get_name(zhp),
6421                                     cbp, pl->pl_user_prop, value, srctype,
6422                                     NULL, NULL);
6423                         }
6424                 } else {
6425                         if (zpool_get_prop(zhp, pl->pl_prop, value,
6426                             sizeof (value), &srctype, cbp->cb_literal) != 0)
6427                                 continue;
6428
6429                         zprop_print_one_property(zpool_get_name(zhp), cbp,
6430                             zpool_prop_to_name(pl->pl_prop), value, srctype,
6431                             NULL, NULL);
6432                 }
6433         }
6434         return (0);
6435 }
6436
6437 /*
6438  * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
6439  *
6440  *      -H      Scripted mode.  Don't display headers, and separate properties
6441  *              by a single tab.
6442  *      -o      List of columns to display.  Defaults to
6443  *              "name,property,value,source".
6444  *      -p      Diplay values in parsable (exact) format.
6445  *
6446  * Get properties of pools in the system. Output space statistics
6447  * for each one as well as other attributes.
6448  */
6449 int
6450 zpool_do_get(int argc, char **argv)
6451 {
6452         zprop_get_cbdata_t cb = { 0 };
6453         zprop_list_t fake_name = { 0 };
6454         int ret;
6455         int c, i;
6456         char *value;
6457
6458         cb.cb_first = B_TRUE;
6459
6460         /*
6461          * Set up default columns and sources.
6462          */
6463         cb.cb_sources = ZPROP_SRC_ALL;
6464         cb.cb_columns[0] = GET_COL_NAME;
6465         cb.cb_columns[1] = GET_COL_PROPERTY;
6466         cb.cb_columns[2] = GET_COL_VALUE;
6467         cb.cb_columns[3] = GET_COL_SOURCE;
6468         cb.cb_type = ZFS_TYPE_POOL;
6469
6470         /* check options */
6471         while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
6472                 switch (c) {
6473                 case 'p':
6474                         cb.cb_literal = B_TRUE;
6475                         break;
6476                 case 'H':
6477                         cb.cb_scripted = B_TRUE;
6478                         break;
6479                 case 'o':
6480                         bzero(&cb.cb_columns, sizeof (cb.cb_columns));
6481                         i = 0;
6482                         while (*optarg != '\0') {
6483                                 static char *col_subopts[] =
6484                                 { "name", "property", "value", "source",
6485                                 "all", NULL };
6486
6487                                 if (i == ZFS_GET_NCOLS) {
6488                                         (void) fprintf(stderr, gettext("too "
6489                                         "many fields given to -o "
6490                                         "option\n"));
6491                                         usage(B_FALSE);
6492                                 }
6493
6494                                 switch (getsubopt(&optarg, col_subopts,
6495                                     &value)) {
6496                                 case 0:
6497                                         cb.cb_columns[i++] = GET_COL_NAME;
6498                                         break;
6499                                 case 1:
6500                                         cb.cb_columns[i++] = GET_COL_PROPERTY;
6501                                         break;
6502                                 case 2:
6503                                         cb.cb_columns[i++] = GET_COL_VALUE;
6504                                         break;
6505                                 case 3:
6506                                         cb.cb_columns[i++] = GET_COL_SOURCE;
6507                                         break;
6508                                 case 4:
6509                                         if (i > 0) {
6510                                                 (void) fprintf(stderr,
6511                                                     gettext("\"all\" conflicts "
6512                                                     "with specific fields "
6513                                                     "given to -o option\n"));
6514                                                 usage(B_FALSE);
6515                                         }
6516                                         cb.cb_columns[0] = GET_COL_NAME;
6517                                         cb.cb_columns[1] = GET_COL_PROPERTY;
6518                                         cb.cb_columns[2] = GET_COL_VALUE;
6519                                         cb.cb_columns[3] = GET_COL_SOURCE;
6520                                         i = ZFS_GET_NCOLS;
6521                                         break;
6522                                 default:
6523                                         (void) fprintf(stderr,
6524                                             gettext("invalid column name "
6525                                             "'%s'\n"), suboptarg);
6526                                         usage(B_FALSE);
6527                                 }
6528                         }
6529                         break;
6530                 case '?':
6531                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6532                             optopt);
6533                         usage(B_FALSE);
6534                 }
6535         }
6536
6537         argc -= optind;
6538         argv += optind;
6539
6540         if (argc < 1) {
6541                 (void) fprintf(stderr, gettext("missing property "
6542                     "argument\n"));
6543                 usage(B_FALSE);
6544         }
6545
6546         if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
6547             ZFS_TYPE_POOL) != 0)
6548                 usage(B_FALSE);
6549
6550         argc--;
6551         argv++;
6552
6553         if (cb.cb_proplist != NULL) {
6554                 fake_name.pl_prop = ZPOOL_PROP_NAME;
6555                 fake_name.pl_width = strlen(gettext("NAME"));
6556                 fake_name.pl_next = cb.cb_proplist;
6557                 cb.cb_proplist = &fake_name;
6558         }
6559
6560         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
6561             get_callback, &cb);
6562
6563         if (cb.cb_proplist == &fake_name)
6564                 zprop_free_list(fake_name.pl_next);
6565         else
6566                 zprop_free_list(cb.cb_proplist);
6567
6568         return (ret);
6569 }
6570
6571 typedef struct set_cbdata {
6572         char *cb_propname;
6573         char *cb_value;
6574         boolean_t cb_any_successful;
6575 } set_cbdata_t;
6576
6577 int
6578 set_callback(zpool_handle_t *zhp, void *data)
6579 {
6580         int error;
6581         set_cbdata_t *cb = (set_cbdata_t *)data;
6582
6583         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
6584
6585         if (!error)
6586                 cb->cb_any_successful = B_TRUE;
6587
6588         return (error);
6589 }
6590
6591 int
6592 zpool_do_set(int argc, char **argv)
6593 {
6594         set_cbdata_t cb = { 0 };
6595         int error;
6596
6597         if (argc > 1 && argv[1][0] == '-') {
6598                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
6599                     argv[1][1]);
6600                 usage(B_FALSE);
6601         }
6602
6603         if (argc < 2) {
6604                 (void) fprintf(stderr, gettext("missing property=value "
6605                     "argument\n"));
6606                 usage(B_FALSE);
6607         }
6608
6609         if (argc < 3) {
6610                 (void) fprintf(stderr, gettext("missing pool name\n"));
6611                 usage(B_FALSE);
6612         }
6613
6614         if (argc > 3) {
6615                 (void) fprintf(stderr, gettext("too many pool names\n"));
6616                 usage(B_FALSE);
6617         }
6618
6619         cb.cb_propname = argv[1];
6620         cb.cb_value = strchr(cb.cb_propname, '=');
6621         if (cb.cb_value == NULL) {
6622                 (void) fprintf(stderr, gettext("missing value in "
6623                     "property=value argument\n"));
6624                 usage(B_FALSE);
6625         }
6626
6627         *(cb.cb_value) = '\0';
6628         cb.cb_value++;
6629
6630         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
6631             set_callback, &cb);
6632
6633         return (error);
6634 }
6635
6636 static int
6637 find_command_idx(char *command, int *idx)
6638 {
6639         int i;
6640
6641         for (i = 0; i < NCOMMAND; i++) {
6642                 if (command_table[i].name == NULL)
6643                         continue;
6644
6645                 if (strcmp(command, command_table[i].name) == 0) {
6646                         *idx = i;
6647                         return (0);
6648                 }
6649         }
6650         return (1);
6651 }
6652
6653 int
6654 main(int argc, char **argv)
6655 {
6656         int ret = 0;
6657         int i;
6658         char *cmdname;
6659
6660         (void) setlocale(LC_ALL, "");
6661         (void) textdomain(TEXT_DOMAIN);
6662
6663         if ((g_zfs = libzfs_init()) == NULL) {
6664                 (void) fprintf(stderr, gettext("internal error: failed to "
6665                     "initialize ZFS library\n"));
6666                 return (1);
6667         }
6668
6669         libzfs_print_on_error(g_zfs, B_TRUE);
6670
6671         opterr = 0;
6672
6673         /*
6674          * Make sure the user has specified some command.
6675          */
6676         if (argc < 2) {
6677                 (void) fprintf(stderr, gettext("missing command\n"));
6678                 usage(B_FALSE);
6679         }
6680
6681         cmdname = argv[1];
6682
6683         /*
6684          * Special case '-?'
6685          */
6686         if (strcmp(cmdname, "-?") == 0)
6687                 usage(B_TRUE);
6688
6689         zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
6690
6691         /*
6692          * Run the appropriate command.
6693          */
6694         if (find_command_idx(cmdname, &i) == 0) {
6695                 current_command = &command_table[i];
6696                 ret = command_table[i].func(argc - 1, argv + 1);
6697         } else if (strchr(cmdname, '=')) {
6698                 verify(find_command_idx("set", &i) == 0);
6699                 current_command = &command_table[i];
6700                 ret = command_table[i].func(argc, argv);
6701         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
6702                 /*
6703                  * 'freeze' is a vile debugging abomination, so we treat
6704                  * it as such.
6705                  */
6706                 zfs_cmd_t zc = { 0 };
6707                 (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name));
6708                 return (!!zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc));
6709         } else {
6710                 (void) fprintf(stderr, gettext("unrecognized "
6711                     "command '%s'\n"), cmdname);
6712                 usage(B_FALSE);
6713         }
6714
6715         if (ret == 0 && log_history)
6716                 (void) zpool_log_history(g_zfs, history_str);
6717
6718         libzfs_fini(g_zfs);
6719
6720         /*
6721          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
6722          * for the purposes of running ::findleaks.
6723          */
6724         if (getenv("ZFS_ABORT") != NULL) {
6725                 (void) printf("dumping core by request\n");
6726                 abort();
6727         }
6728
6729         return (ret);
6730 }