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