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