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