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