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