]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.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 typedef struct spare_cbdata {
984         uint64_t        cb_guid;
985         zpool_handle_t  *cb_zhp;
986 } spare_cbdata_t;
987
988 static boolean_t
989 find_vdev(nvlist_t *nv, uint64_t search)
990 {
991         uint64_t guid;
992         nvlist_t **child;
993         uint_t c, children;
994
995         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
996             search == guid)
997                 return (B_TRUE);
998
999         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1000             &child, &children) == 0) {
1001                 for (c = 0; c < children; c++)
1002                         if (find_vdev(child[c], search))
1003                                 return (B_TRUE);
1004         }
1005
1006         return (B_FALSE);
1007 }
1008
1009 static int
1010 find_spare(zpool_handle_t *zhp, void *data)
1011 {
1012         spare_cbdata_t *cbp = data;
1013         nvlist_t *config, *nvroot;
1014
1015         config = zpool_get_config(zhp, NULL);
1016         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1017             &nvroot) == 0);
1018
1019         if (find_vdev(nvroot, cbp->cb_guid)) {
1020                 cbp->cb_zhp = zhp;
1021                 return (1);
1022         }
1023
1024         zpool_close(zhp);
1025         return (0);
1026 }
1027
1028 /*
1029  * Print out configuration state as requested by status_callback.
1030  */
1031 void
1032 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1033     int namewidth, int depth, boolean_t isspare)
1034 {
1035         nvlist_t **child;
1036         uint_t c, children;
1037         vdev_stat_t *vs;
1038         char rbuf[6], wbuf[6], cbuf[6], repaired[7];
1039         char *vname;
1040         uint64_t notpresent;
1041         spare_cbdata_t cb;
1042         char *state;
1043
1044         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1045             (uint64_t **)&vs, &c) == 0);
1046
1047         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1048             &child, &children) != 0)
1049                 children = 0;
1050
1051         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1052         if (isspare) {
1053                 /*
1054                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1055                  * online drives.
1056                  */
1057                 if (vs->vs_aux == VDEV_AUX_SPARED)
1058                         state = "INUSE";
1059                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1060                         state = "AVAIL";
1061         }
1062
1063         (void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
1064             name, state);
1065
1066         if (!isspare) {
1067                 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1068                 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1069                 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1070                 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1071         }
1072
1073         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1074             &notpresent) == 0) {
1075                 char *path;
1076                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1077                 (void) printf("  was %s", path);
1078         } else if (vs->vs_aux != 0) {
1079                 (void) printf("  ");
1080
1081                 switch (vs->vs_aux) {
1082                 case VDEV_AUX_OPEN_FAILED:
1083                         (void) printf(gettext("cannot open"));
1084                         break;
1085
1086                 case VDEV_AUX_BAD_GUID_SUM:
1087                         (void) printf(gettext("missing device"));
1088                         break;
1089
1090                 case VDEV_AUX_NO_REPLICAS:
1091                         (void) printf(gettext("insufficient replicas"));
1092                         break;
1093
1094                 case VDEV_AUX_VERSION_NEWER:
1095                         (void) printf(gettext("newer version"));
1096                         break;
1097
1098                 case VDEV_AUX_SPARED:
1099                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1100                             &cb.cb_guid) == 0);
1101                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1102                                 if (strcmp(zpool_get_name(cb.cb_zhp),
1103                                     zpool_get_name(zhp)) == 0)
1104                                         (void) printf(gettext("currently in "
1105                                             "use"));
1106                                 else
1107                                         (void) printf(gettext("in use by "
1108                                             "pool '%s'"),
1109                                             zpool_get_name(cb.cb_zhp));
1110                                 zpool_close(cb.cb_zhp);
1111                         } else {
1112                                 (void) printf(gettext("currently in use"));
1113                         }
1114                         break;
1115
1116                 case VDEV_AUX_ERR_EXCEEDED:
1117                         (void) printf(gettext("too many errors"));
1118                         break;
1119
1120                 case VDEV_AUX_IO_FAILURE:
1121                         (void) printf(gettext("experienced I/O failures"));
1122                         break;
1123
1124                 case VDEV_AUX_BAD_LOG:
1125                         (void) printf(gettext("bad intent log"));
1126                         break;
1127
1128                 default:
1129                         (void) printf(gettext("corrupted data"));
1130                         break;
1131                 }
1132         } else if (vs->vs_scrub_repaired != 0 && children == 0) {
1133                 /*
1134                  * Report bytes resilvered/repaired on leaf devices.
1135                  */
1136                 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
1137                 (void) printf(gettext("  %s %s"), repaired,
1138                     (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
1139                     "resilvered" : "repaired");
1140         }
1141
1142         (void) printf("\n");
1143
1144         for (c = 0; c < children; c++) {
1145                 uint64_t is_log = B_FALSE;
1146
1147                 /* Don't print logs here */
1148                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1149                     &is_log);
1150                 if (is_log)
1151                         continue;
1152                 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
1153                 print_status_config(zhp, vname, child[c],
1154                     namewidth, depth + 2, isspare);
1155                 free(vname);
1156         }
1157 }
1158
1159
1160 /*
1161  * Print the configuration of an exported pool.  Iterate over all vdevs in the
1162  * pool, printing out the name and status for each one.
1163  */
1164 void
1165 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1166 {
1167         nvlist_t **child;
1168         uint_t c, children;
1169         vdev_stat_t *vs;
1170         char *type, *vname;
1171
1172         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1173         if (strcmp(type, VDEV_TYPE_MISSING) == 0)
1174                 return;
1175
1176         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
1177             (uint64_t **)&vs, &c) == 0);
1178
1179         (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1180         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1181
1182         if (vs->vs_aux != 0) {
1183                 (void) printf("  ");
1184
1185                 switch (vs->vs_aux) {
1186                 case VDEV_AUX_OPEN_FAILED:
1187                         (void) printf(gettext("cannot open"));
1188                         break;
1189
1190                 case VDEV_AUX_BAD_GUID_SUM:
1191                         (void) printf(gettext("missing device"));
1192                         break;
1193
1194                 case VDEV_AUX_NO_REPLICAS:
1195                         (void) printf(gettext("insufficient replicas"));
1196                         break;
1197
1198                 case VDEV_AUX_VERSION_NEWER:
1199                         (void) printf(gettext("newer version"));
1200                         break;
1201
1202                 case VDEV_AUX_ERR_EXCEEDED:
1203                         (void) printf(gettext("too many errors"));
1204                         break;
1205
1206                 default:
1207                         (void) printf(gettext("corrupted data"));
1208                         break;
1209                 }
1210         }
1211         (void) printf("\n");
1212
1213         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1214             &child, &children) != 0)
1215                 return;
1216
1217         for (c = 0; c < children; c++) {
1218                 uint64_t is_log = B_FALSE;
1219
1220                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1221                     &is_log);
1222                 if (is_log)
1223                         continue;
1224
1225                 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1226                 print_import_config(vname, child[c], namewidth, depth + 2);
1227                 free(vname);
1228         }
1229
1230         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1231             &child, &children) == 0) {
1232                 (void) printf(gettext("\tcache\n"));
1233                 for (c = 0; c < children; c++) {
1234                         vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1235                         (void) printf("\t  %s\n", vname);
1236                         free(vname);
1237                 }
1238         }
1239
1240         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1241             &child, &children) == 0) {
1242                 (void) printf(gettext("\tspares\n"));
1243                 for (c = 0; c < children; c++) {
1244                         vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1245                         (void) printf("\t  %s\n", vname);
1246                         free(vname);
1247                 }
1248         }
1249 }
1250
1251 /*
1252  * Print log vdevs.
1253  * Logs are recorded as top level vdevs in the main pool child array
1254  * but with "is_log" set to 1. We use either print_status_config() or
1255  * print_import_config() to print the top level logs then any log
1256  * children (eg mirrored slogs) are printed recursively - which
1257  * works because only the top level vdev is marked "is_log"
1258  */
1259 static void
1260 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1261 {
1262         uint_t c, children;
1263         nvlist_t **child;
1264
1265         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1266             &children) != 0)
1267                 return;
1268
1269         (void) printf(gettext("\tlogs\n"));
1270
1271         for (c = 0; c < children; c++) {
1272                 uint64_t is_log = B_FALSE;
1273                 char *name;
1274
1275                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1276                     &is_log);
1277                 if (!is_log)
1278                         continue;
1279                 name = zpool_vdev_name(g_zfs, zhp, child[c]);
1280                 if (verbose)
1281                         print_status_config(zhp, name, child[c], namewidth,
1282                             2, B_FALSE);
1283                 else
1284                         print_import_config(name, child[c], namewidth, 2);
1285                 free(name);
1286         }
1287 }
1288 /*
1289  * Display the status for the given pool.
1290  */
1291 static void
1292 show_import(nvlist_t *config)
1293 {
1294         uint64_t pool_state;
1295         vdev_stat_t *vs;
1296         char *name;
1297         uint64_t guid;
1298         char *msgid;
1299         nvlist_t *nvroot;
1300         int reason;
1301         const char *health;
1302         uint_t vsc;
1303         int namewidth;
1304
1305         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1306             &name) == 0);
1307         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1308             &guid) == 0);
1309         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1310             &pool_state) == 0);
1311         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1312             &nvroot) == 0);
1313
1314         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1315             (uint64_t **)&vs, &vsc) == 0);
1316         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1317
1318         reason = zpool_import_status(config, &msgid);
1319
1320         (void) printf(gettext("  pool: %s\n"), name);
1321         (void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
1322         (void) printf(gettext(" state: %s"), health);
1323         if (pool_state == POOL_STATE_DESTROYED)
1324                 (void) printf(gettext(" (DESTROYED)"));
1325         (void) printf("\n");
1326
1327         switch (reason) {
1328         case ZPOOL_STATUS_MISSING_DEV_R:
1329         case ZPOOL_STATUS_MISSING_DEV_NR:
1330         case ZPOOL_STATUS_BAD_GUID_SUM:
1331                 (void) printf(gettext("status: One or more devices are missing "
1332                     "from the system.\n"));
1333                 break;
1334
1335         case ZPOOL_STATUS_CORRUPT_LABEL_R:
1336         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1337                 (void) printf(gettext("status: One or more devices contains "
1338                     "corrupted data.\n"));
1339                 break;
1340
1341         case ZPOOL_STATUS_CORRUPT_DATA:
1342                 (void) printf(gettext("status: The pool data is corrupted.\n"));
1343                 break;
1344
1345         case ZPOOL_STATUS_OFFLINE_DEV:
1346                 (void) printf(gettext("status: One or more devices "
1347                     "are offlined.\n"));
1348                 break;
1349
1350         case ZPOOL_STATUS_CORRUPT_POOL:
1351                 (void) printf(gettext("status: The pool metadata is "
1352                     "corrupted.\n"));
1353                 break;
1354
1355         case ZPOOL_STATUS_VERSION_OLDER:
1356                 (void) printf(gettext("status: The pool is formatted using an "
1357                     "older on-disk version.\n"));
1358                 break;
1359
1360         case ZPOOL_STATUS_VERSION_NEWER:
1361                 (void) printf(gettext("status: The pool is formatted using an "
1362                     "incompatible version.\n"));
1363                 break;
1364
1365         case ZPOOL_STATUS_HOSTID_MISMATCH:
1366                 (void) printf(gettext("status: The pool was last accessed by "
1367                     "another system.\n"));
1368                 break;
1369
1370         case ZPOOL_STATUS_FAULTED_DEV_R:
1371         case ZPOOL_STATUS_FAULTED_DEV_NR:
1372                 (void) printf(gettext("status: One or more devices are "
1373                     "faulted.\n"));
1374                 break;
1375
1376         case ZPOOL_STATUS_BAD_LOG:
1377                 (void) printf(gettext("status: An intent log record cannot be "
1378                     "read.\n"));
1379                 break;
1380
1381         default:
1382                 /*
1383                  * No other status can be seen when importing pools.
1384                  */
1385                 assert(reason == ZPOOL_STATUS_OK);
1386         }
1387
1388         /*
1389          * Print out an action according to the overall state of the pool.
1390          */
1391         if (vs->vs_state == VDEV_STATE_HEALTHY) {
1392                 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1393                         (void) printf(gettext("action: The pool can be "
1394                             "imported using its name or numeric identifier, "
1395                             "though\n\tsome features will not be available "
1396                             "without an explicit 'zpool upgrade'.\n"));
1397                 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1398                         (void) printf(gettext("action: The pool can be "
1399                             "imported using its name or numeric "
1400                             "identifier and\n\tthe '-f' flag.\n"));
1401                 else
1402                         (void) printf(gettext("action: The pool can be "
1403                             "imported using its name or numeric "
1404                             "identifier.\n"));
1405         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1406                 (void) printf(gettext("action: The pool can be imported "
1407                     "despite missing or damaged devices.  The\n\tfault "
1408                     "tolerance of the pool may be compromised if imported.\n"));
1409         } else {
1410                 switch (reason) {
1411                 case ZPOOL_STATUS_VERSION_NEWER:
1412                         (void) printf(gettext("action: The pool cannot be "
1413                             "imported.  Access the pool on a system running "
1414                             "newer\n\tsoftware, or recreate the pool from "
1415                             "backup.\n"));
1416                         break;
1417                 case ZPOOL_STATUS_MISSING_DEV_R:
1418                 case ZPOOL_STATUS_MISSING_DEV_NR:
1419                 case ZPOOL_STATUS_BAD_GUID_SUM:
1420                         (void) printf(gettext("action: The pool cannot be "
1421                             "imported. Attach the missing\n\tdevices and try "
1422                             "again.\n"));
1423                         break;
1424                 default:
1425                         (void) printf(gettext("action: The pool cannot be "
1426                             "imported due to damaged devices or data.\n"));
1427                 }
1428         }
1429
1430         /*
1431          * If the state is "closed" or "can't open", and the aux state
1432          * is "corrupt data":
1433          */
1434         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1435             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1436             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1437                 if (pool_state == POOL_STATE_DESTROYED)
1438                         (void) printf(gettext("\tThe pool was destroyed, "
1439                             "but can be imported using the '-Df' flags.\n"));
1440                 else if (pool_state != POOL_STATE_EXPORTED)
1441                         (void) printf(gettext("\tThe pool may be active on "
1442                             "another system, but can be imported using\n\t"
1443                             "the '-f' flag.\n"));
1444         }
1445
1446         if (msgid != NULL)
1447                 (void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1448                     msgid);
1449
1450         (void) printf(gettext("config:\n\n"));
1451
1452         namewidth = max_width(NULL, nvroot, 0, 0);
1453         if (namewidth < 10)
1454                 namewidth = 10;
1455
1456         print_import_config(name, nvroot, namewidth, 0);
1457         if (num_logs(nvroot) > 0)
1458                 print_logs(NULL, nvroot, namewidth, B_FALSE);
1459
1460         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1461                 (void) printf(gettext("\n\tAdditional devices are known to "
1462                     "be part of this pool, though their\n\texact "
1463                     "configuration cannot be determined.\n"));
1464         }
1465 }
1466
1467 /*
1468  * Perform the import for the given configuration.  This passes the heavy
1469  * lifting off to zpool_import_props(), and then mounts the datasets contained
1470  * within the pool.
1471  */
1472 static int
1473 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1474     int force, nvlist_t *props, boolean_t do_verbatim)
1475 {
1476         zpool_handle_t *zhp;
1477         char *name;
1478         uint64_t state;
1479         uint64_t version;
1480         int error = 0;
1481
1482         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1483             &name) == 0);
1484
1485         verify(nvlist_lookup_uint64(config,
1486             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1487         verify(nvlist_lookup_uint64(config,
1488             ZPOOL_CONFIG_VERSION, &version) == 0);
1489         if (version > SPA_VERSION) {
1490                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1491                     "is formatted using a newer ZFS version\n"), name);
1492                 return (1);
1493         } else if (state != POOL_STATE_EXPORTED && !force) {
1494                 uint64_t hostid;
1495
1496                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1497                     &hostid) == 0) {
1498                         if ((unsigned long)hostid != gethostid()) {
1499                                 char *hostname;
1500                                 uint64_t timestamp;
1501                                 time_t t;
1502
1503                                 verify(nvlist_lookup_string(config,
1504                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1505                                 verify(nvlist_lookup_uint64(config,
1506                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1507                                 t = timestamp;
1508                                 (void) fprintf(stderr, gettext("cannot import "
1509                                     "'%s': pool may be in use from other "
1510                                     "system, it was last accessed by %s "
1511                                     "(hostid: 0x%lx) on %s"), name, hostname,
1512                                     (unsigned long)hostid,
1513                                     asctime(localtime(&t)));
1514                                 (void) fprintf(stderr, gettext("use '-f' to "
1515                                     "import anyway\n"));
1516                                 return (1);
1517                         }
1518                 } else {
1519                         (void) fprintf(stderr, gettext("cannot import '%s': "
1520                             "pool may be in use from other system\n"), name);
1521                         (void) fprintf(stderr, gettext("use '-f' to import "
1522                             "anyway\n"));
1523                         return (1);
1524                 }
1525         }
1526
1527         if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
1528                 return (1);
1529
1530         if (newname != NULL)
1531                 name = (char *)newname;
1532
1533         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1534                 return (1);
1535
1536         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1537             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1538                 zpool_close(zhp);
1539                 return (1);
1540         }
1541
1542         zpool_close(zhp);
1543         return (error);
1544 }
1545
1546 /*
1547  * zpool import [-d dir] [-D]
1548  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1549  *              [-d dir | -c cachefile] [-f] -a
1550  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1551  *              [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1552  *
1553  *       -c     Read pool information from a cachefile instead of searching
1554  *              devices.
1555  *
1556  *       -d     Scan in a specific directory, other than /dev/dsk.  More than
1557  *              one directory can be specified using multiple '-d' options.
1558  *
1559  *       -D     Scan for previously destroyed pools or import all or only
1560  *              specified destroyed pools.
1561  *
1562  *       -R     Temporarily import the pool, with all mountpoints relative to
1563  *              the given root.  The pool will remain exported when the machine
1564  *              is rebooted.
1565  *
1566  *       -f     Force import, even if it appears that the pool is active.
1567  *
1568  *       -F     Import even in the presence of faulted vdevs.  This is an
1569  *              intentionally undocumented option for testing purposes, and
1570  *              treats the pool configuration as complete, leaving any bad
1571  *              vdevs in the FAULTED state. In other words, it does verbatim
1572  *              import.
1573  *
1574  *       -a     Import all pools found.
1575  *
1576  *       -o     Set property=value and/or temporary mount options (without '=').
1577  *
1578  * The import command scans for pools to import, and import pools based on pool
1579  * name and GUID.  The pool can also be renamed as part of the import process.
1580  */
1581 int
1582 zpool_do_import(int argc, char **argv)
1583 {
1584         char **searchdirs = NULL;
1585         int nsearch = 0;
1586         int c;
1587         int err;
1588         nvlist_t *pools = NULL;
1589         boolean_t do_all = B_FALSE;
1590         boolean_t do_destroyed = B_FALSE;
1591         char *mntopts = NULL;
1592         boolean_t do_force = B_FALSE;
1593         nvpair_t *elem;
1594         nvlist_t *config;
1595         uint64_t searchguid = 0;
1596         char *searchname = NULL;
1597         char *propval;
1598         nvlist_t *found_config;
1599         nvlist_t *props = NULL;
1600         boolean_t first;
1601         boolean_t do_verbatim = B_FALSE;
1602         uint64_t pool_state;
1603         char *cachefile = NULL;
1604
1605         /* check options */
1606         while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1607                 switch (c) {
1608                 case 'a':
1609                         do_all = B_TRUE;
1610                         break;
1611                 case 'c':
1612                         cachefile = optarg;
1613                         break;
1614                 case 'd':
1615                         if (searchdirs == NULL) {
1616                                 searchdirs = safe_malloc(sizeof (char *));
1617                         } else {
1618                                 char **tmp = safe_malloc((nsearch + 1) *
1619                                     sizeof (char *));
1620                                 bcopy(searchdirs, tmp, nsearch *
1621                                     sizeof (char *));
1622                                 free(searchdirs);
1623                                 searchdirs = tmp;
1624                         }
1625                         searchdirs[nsearch++] = optarg;
1626                         break;
1627                 case 'D':
1628                         do_destroyed = B_TRUE;
1629                         break;
1630                 case 'f':
1631                         do_force = B_TRUE;
1632                         break;
1633                 case 'F':
1634                         do_verbatim = B_TRUE;
1635                         break;
1636                 case 'o':
1637                         if ((propval = strchr(optarg, '=')) != NULL) {
1638                                 *propval = '\0';
1639                                 propval++;
1640                                 if (add_prop_list(optarg, propval,
1641                                     &props, B_TRUE))
1642                                         goto error;
1643                         } else {
1644                                 mntopts = optarg;
1645                         }
1646                         break;
1647                 case 'R':
1648                         if (add_prop_list(zpool_prop_to_name(
1649                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1650                                 goto error;
1651                         if (nvlist_lookup_string(props,
1652                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1653                             &propval) == 0)
1654                                 break;
1655                         if (add_prop_list(zpool_prop_to_name(
1656                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1657                                 goto error;
1658                         break;
1659                 case ':':
1660                         (void) fprintf(stderr, gettext("missing argument for "
1661                             "'%c' option\n"), optopt);
1662                         usage(B_FALSE);
1663                         break;
1664                 case '?':
1665                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1666                             optopt);
1667                         usage(B_FALSE);
1668                 }
1669         }
1670
1671         argc -= optind;
1672         argv += optind;
1673
1674         if (cachefile && nsearch != 0) {
1675                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1676                 usage(B_FALSE);
1677         }
1678
1679         if (searchdirs == NULL) {
1680                 searchdirs = safe_malloc(sizeof (char *));
1681                 searchdirs[0] = "/dev/dsk";
1682                 nsearch = 1;
1683         }
1684
1685         /* check argument count */
1686         if (do_all) {
1687                 if (argc != 0) {
1688                         (void) fprintf(stderr, gettext("too many arguments\n"));
1689                         usage(B_FALSE);
1690                 }
1691         } else {
1692                 if (argc > 2) {
1693                         (void) fprintf(stderr, gettext("too many arguments\n"));
1694                         usage(B_FALSE);
1695                 }
1696
1697                 /*
1698                  * Check for the SYS_CONFIG privilege.  We do this explicitly
1699                  * here because otherwise any attempt to discover pools will
1700                  * silently fail.
1701                  */
1702                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1703                         (void) fprintf(stderr, gettext("cannot "
1704                             "discover pools: permission denied\n"));
1705                         free(searchdirs);
1706                         return (1);
1707                 }
1708         }
1709
1710         /*
1711          * Depending on the arguments given, we do one of the following:
1712          *
1713          *      <none>  Iterate through all pools and display information about
1714          *              each one.
1715          *
1716          *      -a      Iterate through all pools and try to import each one.
1717          *
1718          *      <id>    Find the pool that corresponds to the given GUID/pool
1719          *              name and import that one.
1720          *
1721          *      -D      Above options applies only to destroyed pools.
1722          */
1723         if (argc != 0) {
1724                 char *endptr;
1725
1726                 errno = 0;
1727                 searchguid = strtoull(argv[0], &endptr, 10);
1728                 if (errno != 0 || *endptr != '\0')
1729                         searchname = argv[0];
1730                 found_config = NULL;
1731         }
1732
1733         if (cachefile) {
1734                 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1735                     searchguid);
1736         } else if (searchname != NULL) {
1737                 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1738                     searchname);
1739         } else {
1740                 /*
1741                  * It's OK to search by guid even if searchguid is 0.
1742                  */
1743                 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1744                     searchguid);
1745         }
1746
1747         if (pools == NULL) {
1748                 if (argc != 0) {
1749                         (void) fprintf(stderr, gettext("cannot import '%s': "
1750                             "no such pool available\n"), argv[0]);
1751                 }
1752                 free(searchdirs);
1753                 return (1);
1754         }
1755
1756         /*
1757          * At this point we have a list of import candidate configs. Even if
1758          * we were searching by pool name or guid, we still need to
1759          * post-process the list to deal with pool state and possible
1760          * duplicate names.
1761          */
1762         err = 0;
1763         elem = NULL;
1764         first = B_TRUE;
1765         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1766
1767                 verify(nvpair_value_nvlist(elem, &config) == 0);
1768
1769                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1770                     &pool_state) == 0);
1771                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1772                         continue;
1773                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1774                         continue;
1775
1776                 if (argc == 0) {
1777                         if (first)
1778                                 first = B_FALSE;
1779                         else if (!do_all)
1780                                 (void) printf("\n");
1781
1782                         if (do_all)
1783                                 err |= do_import(config, NULL, mntopts,
1784                                     do_force, props, do_verbatim);
1785                         else
1786                                 show_import(config);
1787                 } else if (searchname != NULL) {
1788                         char *name;
1789
1790                         /*
1791                          * We are searching for a pool based on name.
1792                          */
1793                         verify(nvlist_lookup_string(config,
1794                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1795
1796                         if (strcmp(name, searchname) == 0) {
1797                                 if (found_config != NULL) {
1798                                         (void) fprintf(stderr, gettext(
1799                                             "cannot import '%s': more than "
1800                                             "one matching pool\n"), searchname);
1801                                         (void) fprintf(stderr, gettext(
1802                                             "import by numeric ID instead\n"));
1803                                         err = B_TRUE;
1804                                 }
1805                                 found_config = config;
1806                         }
1807                 } else {
1808                         uint64_t guid;
1809
1810                         /*
1811                          * Search for a pool by guid.
1812                          */
1813                         verify(nvlist_lookup_uint64(config,
1814                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1815
1816                         if (guid == searchguid)
1817                                 found_config = config;
1818                 }
1819         }
1820
1821         /*
1822          * If we were searching for a specific pool, verify that we found a
1823          * pool, and then do the import.
1824          */
1825         if (argc != 0 && err == 0) {
1826                 if (found_config == NULL) {
1827                         (void) fprintf(stderr, gettext("cannot import '%s': "
1828                             "no such pool available\n"), argv[0]);
1829                         err = B_TRUE;
1830                 } else {
1831                         err |= do_import(found_config, argc == 1 ? NULL :
1832                             argv[1], mntopts, do_force, props, do_verbatim);
1833                 }
1834         }
1835
1836         /*
1837          * If we were just looking for pools, report an error if none were
1838          * found.
1839          */
1840         if (argc == 0 && first)
1841                 (void) fprintf(stderr,
1842                     gettext("no pools available to import\n"));
1843
1844 error:
1845         nvlist_free(props);
1846         nvlist_free(pools);
1847         free(searchdirs);
1848
1849         return (err ? 1 : 0);
1850 }
1851
1852 typedef struct iostat_cbdata {
1853         zpool_list_t *cb_list;
1854         int cb_verbose;
1855         int cb_iteration;
1856         int cb_namewidth;
1857 } iostat_cbdata_t;
1858
1859 static void
1860 print_iostat_separator(iostat_cbdata_t *cb)
1861 {
1862         int i = 0;
1863
1864         for (i = 0; i < cb->cb_namewidth; i++)
1865                 (void) printf("-");
1866         (void) printf("  -----  -----  -----  -----  -----  -----\n");
1867 }
1868
1869 static void
1870 print_iostat_header(iostat_cbdata_t *cb)
1871 {
1872         (void) printf("%*s     capacity     operations    bandwidth\n",
1873             cb->cb_namewidth, "");
1874         (void) printf("%-*s   used  avail   read  write   read  write\n",
1875             cb->cb_namewidth, "pool");
1876         print_iostat_separator(cb);
1877 }
1878
1879 /*
1880  * Display a single statistic.
1881  */
1882 static void
1883 print_one_stat(uint64_t value)
1884 {
1885         char buf[64];
1886
1887         zfs_nicenum(value, buf, sizeof (buf));
1888         (void) printf("  %5s", buf);
1889 }
1890
1891 /*
1892  * Print out all the statistics for the given vdev.  This can either be the
1893  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1894  * is a verbose output, and we don't want to display the toplevel pool stats.
1895  */
1896 void
1897 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1898     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1899 {
1900         nvlist_t **oldchild, **newchild;
1901         uint_t c, children;
1902         vdev_stat_t *oldvs, *newvs;
1903         vdev_stat_t zerovs = { 0 };
1904         uint64_t tdelta;
1905         double scale;
1906         char *vname;
1907
1908         if (oldnv != NULL) {
1909                 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1910                     (uint64_t **)&oldvs, &c) == 0);
1911         } else {
1912                 oldvs = &zerovs;
1913         }
1914
1915         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1916             (uint64_t **)&newvs, &c) == 0);
1917
1918         if (strlen(name) + depth > cb->cb_namewidth)
1919                 (void) printf("%*s%s", depth, "", name);
1920         else
1921                 (void) printf("%*s%s%*s", depth, "", name,
1922                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
1923
1924         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1925
1926         if (tdelta == 0)
1927                 scale = 1.0;
1928         else
1929                 scale = (double)NANOSEC / tdelta;
1930
1931         /* only toplevel vdevs have capacity stats */
1932         if (newvs->vs_space == 0) {
1933                 (void) printf("      -      -");
1934         } else {
1935                 print_one_stat(newvs->vs_alloc);
1936                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1937         }
1938
1939         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1940             oldvs->vs_ops[ZIO_TYPE_READ])));
1941
1942         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1943             oldvs->vs_ops[ZIO_TYPE_WRITE])));
1944
1945         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1946             oldvs->vs_bytes[ZIO_TYPE_READ])));
1947
1948         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1949             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1950
1951         (void) printf("\n");
1952
1953         if (!cb->cb_verbose)
1954                 return;
1955
1956         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1957             &newchild, &children) != 0)
1958                 return;
1959
1960         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1961             &oldchild, &c) != 0)
1962                 return;
1963
1964         for (c = 0; c < children; c++) {
1965                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1966                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1967                     newchild[c], cb, depth + 2);
1968                 free(vname);
1969         }
1970
1971         /*
1972          * Include level 2 ARC devices in iostat output
1973          */
1974         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1975             &newchild, &children) != 0)
1976                 return;
1977
1978         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1979             &oldchild, &c) != 0)
1980                 return;
1981
1982         if (children > 0) {
1983                 (void) printf("%-*s      -      -      -      -      -      "
1984                     "-\n", cb->cb_namewidth, "cache");
1985                 for (c = 0; c < children; c++) {
1986                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1987                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1988                             newchild[c], cb, depth + 2);
1989                         free(vname);
1990                 }
1991         }
1992 }
1993
1994 static int
1995 refresh_iostat(zpool_handle_t *zhp, void *data)
1996 {
1997         iostat_cbdata_t *cb = data;
1998         boolean_t missing;
1999
2000         /*
2001          * If the pool has disappeared, remove it from the list and continue.
2002          */
2003         if (zpool_refresh_stats(zhp, &missing) != 0)
2004                 return (-1);
2005
2006         if (missing)
2007                 pool_list_remove(cb->cb_list, zhp);
2008
2009         return (0);
2010 }
2011
2012 /*
2013  * Callback to print out the iostats for the given pool.
2014  */
2015 int
2016 print_iostat(zpool_handle_t *zhp, void *data)
2017 {
2018         iostat_cbdata_t *cb = data;
2019         nvlist_t *oldconfig, *newconfig;
2020         nvlist_t *oldnvroot, *newnvroot;
2021
2022         newconfig = zpool_get_config(zhp, &oldconfig);
2023
2024         if (cb->cb_iteration == 1)
2025                 oldconfig = NULL;
2026
2027         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2028             &newnvroot) == 0);
2029
2030         if (oldconfig == NULL)
2031                 oldnvroot = NULL;
2032         else
2033                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2034                     &oldnvroot) == 0);
2035
2036         /*
2037          * Print out the statistics for the pool.
2038          */
2039         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2040
2041         if (cb->cb_verbose)
2042                 print_iostat_separator(cb);
2043
2044         return (0);
2045 }
2046
2047 int
2048 get_namewidth(zpool_handle_t *zhp, void *data)
2049 {
2050         iostat_cbdata_t *cb = data;
2051         nvlist_t *config, *nvroot;
2052
2053         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2054                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2055                     &nvroot) == 0);
2056                 if (!cb->cb_verbose)
2057                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
2058                 else
2059                         cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2060         }
2061
2062         /*
2063          * The width must fall into the range [10,38].  The upper limit is the
2064          * maximum we can have and still fit in 80 columns.
2065          */
2066         if (cb->cb_namewidth < 10)
2067                 cb->cb_namewidth = 10;
2068         if (cb->cb_namewidth > 38)
2069                 cb->cb_namewidth = 38;
2070
2071         return (0);
2072 }
2073
2074 /*
2075  * zpool iostat [-v] [pool] ... [interval [count]]
2076  *
2077  *      -v      Display statistics for individual vdevs
2078  *
2079  * This command can be tricky because we want to be able to deal with pool
2080  * creation/destruction as well as vdev configuration changes.  The bulk of this
2081  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2082  * on pool_list_update() to detect the addition of new pools.  Configuration
2083  * changes are all handled within libzfs.
2084  */
2085 int
2086 zpool_do_iostat(int argc, char **argv)
2087 {
2088         int c;
2089         int ret;
2090         int npools;
2091         unsigned long interval = 0, count = 0;
2092         zpool_list_t *list;
2093         boolean_t verbose = B_FALSE;
2094         iostat_cbdata_t cb;
2095
2096         /* check options */
2097         while ((c = getopt(argc, argv, "v")) != -1) {
2098                 switch (c) {
2099                 case 'v':
2100                         verbose = B_TRUE;
2101                         break;
2102                 case '?':
2103                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2104                             optopt);
2105                         usage(B_FALSE);
2106                 }
2107         }
2108
2109         argc -= optind;
2110         argv += optind;
2111
2112         /*
2113          * Determine if the last argument is an integer or a pool name
2114          */
2115         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2116                 char *end;
2117
2118                 errno = 0;
2119                 interval = strtoul(argv[argc - 1], &end, 10);
2120
2121                 if (*end == '\0' && errno == 0) {
2122                         if (interval == 0) {
2123                                 (void) fprintf(stderr, gettext("interval "
2124                                     "cannot be zero\n"));
2125                                 usage(B_FALSE);
2126                         }
2127
2128                         /*
2129                          * Ignore the last parameter
2130                          */
2131                         argc--;
2132                 } else {
2133                         /*
2134                          * If this is not a valid number, just plow on.  The
2135                          * user will get a more informative error message later
2136                          * on.
2137                          */
2138                         interval = 0;
2139                 }
2140         }
2141
2142         /*
2143          * If the last argument is also an integer, then we have both a count
2144          * and an integer.
2145          */
2146         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2147                 char *end;
2148
2149                 errno = 0;
2150                 count = interval;
2151                 interval = strtoul(argv[argc - 1], &end, 10);
2152
2153                 if (*end == '\0' && errno == 0) {
2154                         if (interval == 0) {
2155                                 (void) fprintf(stderr, gettext("interval "
2156                                     "cannot be zero\n"));
2157                                 usage(B_FALSE);
2158                         }
2159
2160                         /*
2161                          * Ignore the last parameter
2162                          */
2163                         argc--;
2164                 } else {
2165                         interval = 0;
2166                 }
2167         }
2168
2169         /*
2170          * Construct the list of all interesting pools.
2171          */
2172         ret = 0;
2173         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2174                 return (1);
2175
2176         if (pool_list_count(list) == 0 && argc != 0) {
2177                 pool_list_free(list);
2178                 return (1);
2179         }
2180
2181         if (pool_list_count(list) == 0 && interval == 0) {
2182                 pool_list_free(list);
2183                 (void) fprintf(stderr, gettext("no pools available\n"));
2184                 return (1);
2185         }
2186
2187         /*
2188          * Enter the main iostat loop.
2189          */
2190         cb.cb_list = list;
2191         cb.cb_verbose = verbose;
2192         cb.cb_iteration = 0;
2193         cb.cb_namewidth = 0;
2194
2195         for (;;) {
2196                 pool_list_update(list);
2197
2198                 if ((npools = pool_list_count(list)) == 0)
2199                         break;
2200
2201                 /*
2202                  * Refresh all statistics.  This is done as an explicit step
2203                  * before calculating the maximum name width, so that any
2204                  * configuration changes are properly accounted for.
2205                  */
2206                 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2207
2208                 /*
2209                  * Iterate over all pools to determine the maximum width
2210                  * for the pool / device name column across all pools.
2211                  */
2212                 cb.cb_namewidth = 0;
2213                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2214
2215                 /*
2216                  * If it's the first time, or verbose mode, print the header.
2217                  */
2218                 if (++cb.cb_iteration == 1 || verbose)
2219                         print_iostat_header(&cb);
2220
2221                 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2222
2223                 /*
2224                  * If there's more than one pool, and we're not in verbose mode
2225                  * (which prints a separator for us), then print a separator.
2226                  */
2227                 if (npools > 1 && !verbose)
2228                         print_iostat_separator(&cb);
2229
2230                 if (verbose)
2231                         (void) printf("\n");
2232
2233                 /*
2234                  * Flush the output so that redirection to a file isn't buffered
2235                  * indefinitely.
2236                  */
2237                 (void) fflush(stdout);
2238
2239                 if (interval == 0)
2240                         break;
2241
2242                 if (count != 0 && --count == 0)
2243                         break;
2244
2245                 (void) sleep(interval);
2246         }
2247
2248         pool_list_free(list);
2249
2250         return (ret);
2251 }
2252
2253 typedef struct list_cbdata {
2254         boolean_t       cb_scripted;
2255         boolean_t       cb_first;
2256         zprop_list_t    *cb_proplist;
2257 } list_cbdata_t;
2258
2259 /*
2260  * Given a list of columns to display, output appropriate headers for each one.
2261  */
2262 static void
2263 print_header(zprop_list_t *pl)
2264 {
2265         const char *header;
2266         boolean_t first = B_TRUE;
2267         boolean_t right_justify;
2268
2269         for (; pl != NULL; pl = pl->pl_next) {
2270                 if (pl->pl_prop == ZPROP_INVAL)
2271                         continue;
2272
2273                 if (!first)
2274                         (void) printf("  ");
2275                 else
2276                         first = B_FALSE;
2277
2278                 header = zpool_prop_column_name(pl->pl_prop);
2279                 right_justify = zpool_prop_align_right(pl->pl_prop);
2280
2281                 if (pl->pl_next == NULL && !right_justify)
2282                         (void) printf("%s", header);
2283                 else if (right_justify)
2284                         (void) printf("%*s", pl->pl_width, header);
2285                 else
2286                         (void) printf("%-*s", pl->pl_width, header);
2287         }
2288
2289         (void) printf("\n");
2290 }
2291
2292 /*
2293  * Given a pool and a list of properties, print out all the properties according
2294  * to the described layout.
2295  */
2296 static void
2297 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2298 {
2299         boolean_t first = B_TRUE;
2300         char property[ZPOOL_MAXPROPLEN];
2301         char *propstr;
2302         boolean_t right_justify;
2303         int width;
2304
2305         for (; pl != NULL; pl = pl->pl_next) {
2306                 if (!first) {
2307                         if (scripted)
2308                                 (void) printf("\t");
2309                         else
2310                                 (void) printf("  ");
2311                 } else {
2312                         first = B_FALSE;
2313                 }
2314
2315                 right_justify = B_FALSE;
2316                 if (pl->pl_prop != ZPROP_INVAL) {
2317                         if (zpool_get_prop(zhp, pl->pl_prop, property,
2318                             sizeof (property), NULL) != 0)
2319                                 propstr = "-";
2320                         else
2321                                 propstr = property;
2322
2323                         right_justify = zpool_prop_align_right(pl->pl_prop);
2324                 } else {
2325                         propstr = "-";
2326                 }
2327
2328                 width = pl->pl_width;
2329
2330                 /*
2331                  * If this is being called in scripted mode, or if this is the
2332                  * last column and it is left-justified, don't include a width
2333                  * format specifier.
2334                  */
2335                 if (scripted || (pl->pl_next == NULL && !right_justify))
2336                         (void) printf("%s", propstr);
2337                 else if (right_justify)
2338                         (void) printf("%*s", width, propstr);
2339                 else
2340                         (void) printf("%-*s", width, propstr);
2341         }
2342
2343         (void) printf("\n");
2344 }
2345
2346 /*
2347  * Generic callback function to list a pool.
2348  */
2349 int
2350 list_callback(zpool_handle_t *zhp, void *data)
2351 {
2352         list_cbdata_t *cbp = data;
2353
2354         if (cbp->cb_first) {
2355                 if (!cbp->cb_scripted)
2356                         print_header(cbp->cb_proplist);
2357                 cbp->cb_first = B_FALSE;
2358         }
2359
2360         print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2361
2362         return (0);
2363 }
2364
2365 /*
2366  * zpool list [-H] [-o prop[,prop]*] [pool] ...
2367  *
2368  *      -H      Scripted mode.  Don't display headers, and separate properties
2369  *              by a single tab.
2370  *      -o      List of properties to display.  Defaults to
2371  *              "name,size,used,available,capacity,health,altroot"
2372  *
2373  * List all pools in the system, whether or not they're healthy.  Output space
2374  * statistics for each one, as well as health status summary.
2375  */
2376 int
2377 zpool_do_list(int argc, char **argv)
2378 {
2379         int c;
2380         int ret;
2381         list_cbdata_t cb = { 0 };
2382         static char default_props[] =
2383             "name,size,used,available,capacity,health,altroot";
2384         char *props = default_props;
2385
2386         /* check options */
2387         while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2388                 switch (c) {
2389                 case 'H':
2390                         cb.cb_scripted = B_TRUE;
2391                         break;
2392                 case 'o':
2393                         props = optarg;
2394                         break;
2395                 case ':':
2396                         (void) fprintf(stderr, gettext("missing argument for "
2397                             "'%c' option\n"), optopt);
2398                         usage(B_FALSE);
2399                         break;
2400                 case '?':
2401                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2402                             optopt);
2403                         usage(B_FALSE);
2404                 }
2405         }
2406
2407         argc -= optind;
2408         argv += optind;
2409
2410         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2411                 usage(B_FALSE);
2412
2413         cb.cb_first = B_TRUE;
2414
2415         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2416             list_callback, &cb);
2417
2418         zprop_free_list(cb.cb_proplist);
2419
2420         if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2421                 (void) printf(gettext("no pools available\n"));
2422                 return (0);
2423         }
2424
2425         return (ret);
2426 }
2427
2428 static nvlist_t *
2429 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2430 {
2431         nvlist_t **child;
2432         uint_t c, children;
2433         nvlist_t *match;
2434         char *path;
2435
2436         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2437             &child, &children) != 0) {
2438                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2439                 if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2440                         name += sizeof(_PATH_DEV)-1;
2441                 if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0)
2442                         path += sizeof(_PATH_DEV)-1;
2443                 if (strcmp(name, path) == 0)
2444                         return (nv);
2445                 return (NULL);
2446         }
2447
2448         for (c = 0; c < children; c++)
2449                 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2450                         return (match);
2451
2452         return (NULL);
2453 }
2454
2455 static int
2456 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2457 {
2458         boolean_t force = B_FALSE;
2459         int c;
2460         nvlist_t *nvroot;
2461         char *poolname, *old_disk, *new_disk;
2462         zpool_handle_t *zhp;
2463         int ret;
2464
2465         /* check options */
2466         while ((c = getopt(argc, argv, "f")) != -1) {
2467                 switch (c) {
2468                 case 'f':
2469                         force = B_TRUE;
2470                         break;
2471                 case '?':
2472                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2473                             optopt);
2474                         usage(B_FALSE);
2475                 }
2476         }
2477
2478         argc -= optind;
2479         argv += optind;
2480
2481         /* get pool name and check number of arguments */
2482         if (argc < 1) {
2483                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2484                 usage(B_FALSE);
2485         }
2486
2487         poolname = argv[0];
2488
2489         if (argc < 2) {
2490                 (void) fprintf(stderr,
2491                     gettext("missing <device> specification\n"));
2492                 usage(B_FALSE);
2493         }
2494
2495         old_disk = argv[1];
2496
2497         if (argc < 3) {
2498                 if (!replacing) {
2499                         (void) fprintf(stderr,
2500                             gettext("missing <new_device> specification\n"));
2501                         usage(B_FALSE);
2502                 }
2503                 new_disk = old_disk;
2504                 argc -= 1;
2505                 argv += 1;
2506         } else {
2507                 new_disk = argv[2];
2508                 argc -= 2;
2509                 argv += 2;
2510         }
2511
2512         if (argc > 1) {
2513                 (void) fprintf(stderr, gettext("too many arguments\n"));
2514                 usage(B_FALSE);
2515         }
2516
2517         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2518                 return (1);
2519
2520         if (zpool_get_config(zhp, NULL) == NULL) {
2521                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2522                     poolname);
2523                 zpool_close(zhp);
2524                 return (1);
2525         }
2526
2527         nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2528             argc, argv);
2529         if (nvroot == NULL) {
2530                 zpool_close(zhp);
2531                 return (1);
2532         }
2533
2534         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2535
2536         nvlist_free(nvroot);
2537         zpool_close(zhp);
2538
2539         return (ret);
2540 }
2541
2542 /*
2543  * zpool replace [-f] <pool> <device> <new_device>
2544  *
2545  *      -f      Force attach, even if <new_device> appears to be in use.
2546  *
2547  * Replace <device> with <new_device>.
2548  */
2549 /* ARGSUSED */
2550 int
2551 zpool_do_replace(int argc, char **argv)
2552 {
2553         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2554 }
2555
2556 /*
2557  * zpool attach [-f] <pool> <device> <new_device>
2558  *
2559  *      -f      Force attach, even if <new_device> appears to be in use.
2560  *
2561  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2562  * part of a mirror, then <device> will be transformed into a mirror of
2563  * <device> and <new_device>.  In either case, <new_device> will begin life
2564  * with a DTL of [0, now], and will immediately begin to resilver itself.
2565  */
2566 int
2567 zpool_do_attach(int argc, char **argv)
2568 {
2569         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2570 }
2571
2572 /*
2573  * zpool detach [-f] <pool> <device>
2574  *
2575  *      -f      Force detach of <device>, even if DTLs argue against it
2576  *              (not supported yet)
2577  *
2578  * Detach a device from a mirror.  The operation will be refused if <device>
2579  * is the last device in the mirror, or if the DTLs indicate that this device
2580  * has the only valid copy of some data.
2581  */
2582 /* ARGSUSED */
2583 int
2584 zpool_do_detach(int argc, char **argv)
2585 {
2586         int c;
2587         char *poolname, *path;
2588         zpool_handle_t *zhp;
2589         int ret;
2590
2591         /* check options */
2592         while ((c = getopt(argc, argv, "f")) != -1) {
2593                 switch (c) {
2594                 case 'f':
2595                 case '?':
2596                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2597                             optopt);
2598                         usage(B_FALSE);
2599                 }
2600         }
2601
2602         argc -= optind;
2603         argv += optind;
2604
2605         /* get pool name and check number of arguments */
2606         if (argc < 1) {
2607                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2608                 usage(B_FALSE);
2609         }
2610
2611         if (argc < 2) {
2612                 (void) fprintf(stderr,
2613                     gettext("missing <device> specification\n"));
2614                 usage(B_FALSE);
2615         }
2616
2617         poolname = argv[0];
2618         path = argv[1];
2619
2620         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2621                 return (1);
2622
2623         ret = zpool_vdev_detach(zhp, path);
2624
2625         zpool_close(zhp);
2626
2627         return (ret);
2628 }
2629
2630 /*
2631  * zpool online <pool> <device> ...
2632  */
2633 int
2634 zpool_do_online(int argc, char **argv)
2635 {
2636         int c, i;
2637         char *poolname;
2638         zpool_handle_t *zhp;
2639         int ret = 0;
2640         vdev_state_t newstate;
2641
2642         /* check options */
2643         while ((c = getopt(argc, argv, "t")) != -1) {
2644                 switch (c) {
2645                 case 't':
2646                 case '?':
2647                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2648                             optopt);
2649                         usage(B_FALSE);
2650                 }
2651         }
2652
2653         argc -= optind;
2654         argv += optind;
2655
2656         /* get pool name and check number of arguments */
2657         if (argc < 1) {
2658                 (void) fprintf(stderr, gettext("missing pool name\n"));
2659                 usage(B_FALSE);
2660         }
2661         if (argc < 2) {
2662                 (void) fprintf(stderr, gettext("missing device name\n"));
2663                 usage(B_FALSE);
2664         }
2665
2666         poolname = argv[0];
2667
2668         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2669                 return (1);
2670
2671         for (i = 1; i < argc; i++) {
2672                 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2673                         if (newstate != VDEV_STATE_HEALTHY) {
2674                                 (void) printf(gettext("warning: device '%s' "
2675                                     "onlined, but remains in faulted state\n"),
2676                                     argv[i]);
2677                                 if (newstate == VDEV_STATE_FAULTED)
2678                                         (void) printf(gettext("use 'zpool "
2679                                             "clear' to restore a faulted "
2680                                             "device\n"));
2681                                 else
2682                                         (void) printf(gettext("use 'zpool "
2683                                             "replace' to replace devices "
2684                                             "that are no longer present\n"));
2685                         }
2686                 } else {
2687                         ret = 1;
2688                 }
2689         }
2690
2691         zpool_close(zhp);
2692
2693         return (ret);
2694 }
2695
2696 /*
2697  * zpool offline [-ft] <pool> <device> ...
2698  *
2699  *      -f      Force the device into the offline state, even if doing
2700  *              so would appear to compromise pool availability.
2701  *              (not supported yet)
2702  *
2703  *      -t      Only take the device off-line temporarily.  The offline
2704  *              state will not be persistent across reboots.
2705  */
2706 /* ARGSUSED */
2707 int
2708 zpool_do_offline(int argc, char **argv)
2709 {
2710         int c, i;
2711         char *poolname;
2712         zpool_handle_t *zhp;
2713         int ret = 0;
2714         boolean_t istmp = B_FALSE;
2715
2716         /* check options */
2717         while ((c = getopt(argc, argv, "ft")) != -1) {
2718                 switch (c) {
2719                 case 't':
2720                         istmp = B_TRUE;
2721                         break;
2722                 case 'f':
2723                 case '?':
2724                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2725                             optopt);
2726                         usage(B_FALSE);
2727                 }
2728         }
2729
2730         argc -= optind;
2731         argv += optind;
2732
2733         /* get pool name and check number of arguments */
2734         if (argc < 1) {
2735                 (void) fprintf(stderr, gettext("missing pool name\n"));
2736                 usage(B_FALSE);
2737         }
2738         if (argc < 2) {
2739                 (void) fprintf(stderr, gettext("missing device name\n"));
2740                 usage(B_FALSE);
2741         }
2742
2743         poolname = argv[0];
2744
2745         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2746                 return (1);
2747
2748         for (i = 1; i < argc; i++) {
2749                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2750                         ret = 1;
2751         }
2752
2753         zpool_close(zhp);
2754
2755         return (ret);
2756 }
2757
2758 /*
2759  * zpool clear <pool> [device]
2760  *
2761  * Clear all errors associated with a pool or a particular device.
2762  */
2763 int
2764 zpool_do_clear(int argc, char **argv)
2765 {
2766         int ret = 0;
2767         zpool_handle_t *zhp;
2768         char *pool, *device;
2769
2770         if (argc < 2) {
2771                 (void) fprintf(stderr, gettext("missing pool name\n"));
2772                 usage(B_FALSE);
2773         }
2774
2775         if (argc > 3) {
2776                 (void) fprintf(stderr, gettext("too many arguments\n"));
2777                 usage(B_FALSE);
2778         }
2779
2780         pool = argv[1];
2781         device = argc == 3 ? argv[2] : NULL;
2782
2783         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2784                 return (1);
2785
2786         if (zpool_clear(zhp, device) != 0)
2787                 ret = 1;
2788
2789         zpool_close(zhp);
2790
2791         return (ret);
2792 }
2793
2794 typedef struct scrub_cbdata {
2795         int     cb_type;
2796         int     cb_argc;
2797         char    **cb_argv;
2798 } scrub_cbdata_t;
2799
2800 int
2801 scrub_callback(zpool_handle_t *zhp, void *data)
2802 {
2803         scrub_cbdata_t *cb = data;
2804         int err;
2805
2806         /*
2807          * Ignore faulted pools.
2808          */
2809         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2810                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2811                     "currently unavailable\n"), zpool_get_name(zhp));
2812                 return (1);
2813         }
2814
2815         err = zpool_scrub(zhp, cb->cb_type);
2816
2817         return (err != 0);
2818 }
2819
2820 /*
2821  * zpool scrub [-s] <pool> ...
2822  *
2823  *      -s      Stop.  Stops any in-progress scrub.
2824  */
2825 int
2826 zpool_do_scrub(int argc, char **argv)
2827 {
2828         int c;
2829         scrub_cbdata_t cb;
2830
2831         cb.cb_type = POOL_SCRUB_EVERYTHING;
2832
2833         /* check options */
2834         while ((c = getopt(argc, argv, "s")) != -1) {
2835                 switch (c) {
2836                 case 's':
2837                         cb.cb_type = POOL_SCRUB_NONE;
2838                         break;
2839                 case '?':
2840                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2841                             optopt);
2842                         usage(B_FALSE);
2843                 }
2844         }
2845
2846         cb.cb_argc = argc;
2847         cb.cb_argv = argv;
2848         argc -= optind;
2849         argv += optind;
2850
2851         if (argc < 1) {
2852                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2853                 usage(B_FALSE);
2854         }
2855
2856         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2857 }
2858
2859 typedef struct status_cbdata {
2860         int             cb_count;
2861         boolean_t       cb_allpools;
2862         boolean_t       cb_verbose;
2863         boolean_t       cb_explain;
2864         boolean_t       cb_first;
2865 } status_cbdata_t;
2866
2867 /*
2868  * Print out detailed scrub status.
2869  */
2870 void
2871 print_scrub_status(nvlist_t *nvroot)
2872 {
2873         vdev_stat_t *vs;
2874         uint_t vsc;
2875         time_t start, end, now;
2876         double fraction_done;
2877         uint64_t examined, total, minutes_left, minutes_taken;
2878         char *scrub_type;
2879
2880         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2881             (uint64_t **)&vs, &vsc) == 0);
2882
2883         /*
2884          * If there's never been a scrub, there's not much to say.
2885          */
2886         if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2887                 (void) printf(gettext("none requested\n"));
2888                 return;
2889         }
2890
2891         scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2892             "resilver" : "scrub";
2893
2894         start = vs->vs_scrub_start;
2895         end = vs->vs_scrub_end;
2896         now = time(NULL);
2897         examined = vs->vs_scrub_examined;
2898         total = vs->vs_alloc;
2899
2900         if (end != 0) {
2901                 minutes_taken = (uint64_t)((end - start) / 60);
2902
2903                 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2904                     "on %s"),
2905                     scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2906                     (u_longlong_t)(minutes_taken / 60),
2907                     (uint_t)(minutes_taken % 60),
2908                     (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2909                 return;
2910         }
2911
2912         if (examined == 0)
2913                 examined = 1;
2914         if (examined > total)
2915                 total = examined;
2916
2917         fraction_done = (double)examined / total;
2918         minutes_left = (uint64_t)((now - start) *
2919             (1 - fraction_done) / fraction_done / 60);
2920         minutes_taken = (uint64_t)((now - start) / 60);
2921
2922         (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2923             "%lluh%um to go\n"),
2924             scrub_type, (u_longlong_t)(minutes_taken / 60),
2925             (uint_t)(minutes_taken % 60), 100 * fraction_done,
2926             (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2927 }
2928
2929 static void
2930 print_error_log(zpool_handle_t *zhp)
2931 {
2932         nvlist_t *nverrlist = NULL;
2933         nvpair_t *elem;
2934         char *pathname;
2935         size_t len = MAXPATHLEN * 2;
2936
2937         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2938                 (void) printf("errors: List of errors unavailable "
2939                     "(insufficient privileges)\n");
2940                 return;
2941         }
2942
2943         (void) printf("errors: Permanent errors have been "
2944             "detected in the following files:\n\n");
2945
2946         pathname = safe_malloc(len);
2947         elem = NULL;
2948         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2949                 nvlist_t *nv;
2950                 uint64_t dsobj, obj;
2951
2952                 verify(nvpair_value_nvlist(elem, &nv) == 0);
2953                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2954                     &dsobj) == 0);
2955                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2956                     &obj) == 0);
2957                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2958                 (void) printf("%7s %s\n", "", pathname);
2959         }
2960         free(pathname);
2961         nvlist_free(nverrlist);
2962 }
2963
2964 static void
2965 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2966     int namewidth)
2967 {
2968         uint_t i;
2969         char *name;
2970
2971         if (nspares == 0)
2972                 return;
2973
2974         (void) printf(gettext("\tspares\n"));
2975
2976         for (i = 0; i < nspares; i++) {
2977                 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2978                 print_status_config(zhp, name, spares[i],
2979                     namewidth, 2, B_TRUE);
2980                 free(name);
2981         }
2982 }
2983
2984 static void
2985 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2986     int namewidth)
2987 {
2988         uint_t i;
2989         char *name;
2990
2991         if (nl2cache == 0)
2992                 return;
2993
2994         (void) printf(gettext("\tcache\n"));
2995
2996         for (i = 0; i < nl2cache; i++) {
2997                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2998                 print_status_config(zhp, name, l2cache[i],
2999                     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, B_TRUE);
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 }