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