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