Rebase master to b121
[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 do_verbatim)
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, do_verbatim) != 0)
1526                 return (1);
1527
1528         if (newname != NULL)
1529                 name = (char *)newname;
1530
1531         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1532                 return (1);
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. In other words, it does verbatim
1570  *              import.
1571  *
1572  *       -a     Import all pools found.
1573  *
1574  *       -o     Set property=value and/or temporary mount options (without '=').
1575  *
1576  * The import command scans for pools to import, and import pools based on pool
1577  * name and GUID.  The pool can also be renamed as part of the import process.
1578  */
1579 int
1580 zpool_do_import(int argc, char **argv)
1581 {
1582         char **searchdirs = NULL;
1583         int nsearch = 0;
1584         int c;
1585         int err;
1586         nvlist_t *pools = NULL;
1587         boolean_t do_all = B_FALSE;
1588         boolean_t do_destroyed = B_FALSE;
1589         char *mntopts = NULL;
1590         boolean_t do_force = B_FALSE;
1591         nvpair_t *elem;
1592         nvlist_t *config;
1593         uint64_t searchguid = 0;
1594         char *searchname = NULL;
1595         char *propval;
1596         nvlist_t *found_config;
1597         nvlist_t *props = NULL;
1598         boolean_t first;
1599         boolean_t do_verbatim = B_FALSE;
1600         uint64_t pool_state;
1601         char *cachefile = NULL;
1602
1603         /* check options */
1604         while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
1605                 switch (c) {
1606                 case 'a':
1607                         do_all = B_TRUE;
1608                         break;
1609                 case 'c':
1610                         cachefile = optarg;
1611                         break;
1612                 case 'd':
1613                         if (searchdirs == NULL) {
1614                                 searchdirs = safe_malloc(sizeof (char *));
1615                         } else {
1616                                 char **tmp = safe_malloc((nsearch + 1) *
1617                                     sizeof (char *));
1618                                 bcopy(searchdirs, tmp, nsearch *
1619                                     sizeof (char *));
1620                                 free(searchdirs);
1621                                 searchdirs = tmp;
1622                         }
1623                         searchdirs[nsearch++] = optarg;
1624                         break;
1625                 case 'D':
1626                         do_destroyed = B_TRUE;
1627                         break;
1628                 case 'f':
1629                         do_force = B_TRUE;
1630                         break;
1631                 case 'F':
1632                         do_verbatim = B_TRUE;
1633                         break;
1634                 case 'o':
1635                         if ((propval = strchr(optarg, '=')) != NULL) {
1636                                 *propval = '\0';
1637                                 propval++;
1638                                 if (add_prop_list(optarg, propval,
1639                                     &props, B_TRUE))
1640                                         goto error;
1641                         } else {
1642                                 mntopts = optarg;
1643                         }
1644                         break;
1645                 case 'R':
1646                         if (add_prop_list(zpool_prop_to_name(
1647                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1648                                 goto error;
1649                         if (nvlist_lookup_string(props,
1650                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1651                             &propval) == 0)
1652                                 break;
1653                         if (add_prop_list(zpool_prop_to_name(
1654                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1655                                 goto error;
1656                         break;
1657                 case ':':
1658                         (void) fprintf(stderr, gettext("missing argument for "
1659                             "'%c' option\n"), optopt);
1660                         usage(B_FALSE);
1661                         break;
1662                 case '?':
1663                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1664                             optopt);
1665                         usage(B_FALSE);
1666                 }
1667         }
1668
1669         argc -= optind;
1670         argv += optind;
1671
1672         if (cachefile && nsearch != 0) {
1673                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1674                 usage(B_FALSE);
1675         }
1676
1677         if (searchdirs == NULL) {
1678                 searchdirs = safe_malloc(sizeof (char *));
1679                 searchdirs[0] = "/dev/dsk";
1680                 nsearch = 1;
1681         }
1682
1683         /* check argument count */
1684         if (do_all) {
1685                 if (argc != 0) {
1686                         (void) fprintf(stderr, gettext("too many arguments\n"));
1687                         usage(B_FALSE);
1688                 }
1689         } else {
1690                 if (argc > 2) {
1691                         (void) fprintf(stderr, gettext("too many arguments\n"));
1692                         usage(B_FALSE);
1693                 }
1694
1695                 /*
1696                  * Check for the SYS_CONFIG privilege.  We do this explicitly
1697                  * here because otherwise any attempt to discover pools will
1698                  * silently fail.
1699                  */
1700                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1701                         (void) fprintf(stderr, gettext("cannot "
1702                             "discover pools: permission denied\n"));
1703                         free(searchdirs);
1704                         return (1);
1705                 }
1706         }
1707
1708         /*
1709          * Depending on the arguments given, we do one of the following:
1710          *
1711          *      <none>  Iterate through all pools and display information about
1712          *              each one.
1713          *
1714          *      -a      Iterate through all pools and try to import each one.
1715          *
1716          *      <id>    Find the pool that corresponds to the given GUID/pool
1717          *              name and import that one.
1718          *
1719          *      -D      Above options applies only to destroyed pools.
1720          */
1721         if (argc != 0) {
1722                 char *endptr;
1723
1724                 errno = 0;
1725                 searchguid = strtoull(argv[0], &endptr, 10);
1726                 if (errno != 0 || *endptr != '\0')
1727                         searchname = argv[0];
1728                 found_config = NULL;
1729         }
1730
1731         if (cachefile) {
1732                 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1733                     searchguid);
1734         } else if (searchname != NULL) {
1735                 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1736                     searchname);
1737         } else {
1738                 /*
1739                  * It's OK to search by guid even if searchguid is 0.
1740                  */
1741                 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1742                     searchguid);
1743         }
1744
1745         if (pools == NULL) {
1746                 if (argc != 0) {
1747                         (void) fprintf(stderr, gettext("cannot import '%s': "
1748                             "no such pool available\n"), argv[0]);
1749                 }
1750                 free(searchdirs);
1751                 return (1);
1752         }
1753
1754         /*
1755          * At this point we have a list of import candidate configs. Even if
1756          * we were searching by pool name or guid, we still need to
1757          * post-process the list to deal with pool state and possible
1758          * duplicate names.
1759          */
1760         err = 0;
1761         elem = NULL;
1762         first = B_TRUE;
1763         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1764
1765                 verify(nvpair_value_nvlist(elem, &config) == 0);
1766
1767                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1768                     &pool_state) == 0);
1769                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1770                         continue;
1771                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1772                         continue;
1773
1774                 if (argc == 0) {
1775                         if (first)
1776                                 first = B_FALSE;
1777                         else if (!do_all)
1778                                 (void) printf("\n");
1779
1780                         if (do_all)
1781                                 err |= do_import(config, NULL, mntopts,
1782                                     do_force, props, do_verbatim);
1783                         else
1784                                 show_import(config);
1785                 } else if (searchname != NULL) {
1786                         char *name;
1787
1788                         /*
1789                          * We are searching for a pool based on name.
1790                          */
1791                         verify(nvlist_lookup_string(config,
1792                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1793
1794                         if (strcmp(name, searchname) == 0) {
1795                                 if (found_config != NULL) {
1796                                         (void) fprintf(stderr, gettext(
1797                                             "cannot import '%s': more than "
1798                                             "one matching pool\n"), searchname);
1799                                         (void) fprintf(stderr, gettext(
1800                                             "import by numeric ID instead\n"));
1801                                         err = B_TRUE;
1802                                 }
1803                                 found_config = config;
1804                         }
1805                 } else {
1806                         uint64_t guid;
1807
1808                         /*
1809                          * Search for a pool by guid.
1810                          */
1811                         verify(nvlist_lookup_uint64(config,
1812                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1813
1814                         if (guid == searchguid)
1815                                 found_config = config;
1816                 }
1817         }
1818
1819         /*
1820          * If we were searching for a specific pool, verify that we found a
1821          * pool, and then do the import.
1822          */
1823         if (argc != 0 && err == 0) {
1824                 if (found_config == NULL) {
1825                         (void) fprintf(stderr, gettext("cannot import '%s': "
1826                             "no such pool available\n"), argv[0]);
1827                         err = B_TRUE;
1828                 } else {
1829                         err |= do_import(found_config, argc == 1 ? NULL :
1830                             argv[1], mntopts, do_force, props, do_verbatim);
1831                 }
1832         }
1833
1834         /*
1835          * If we were just looking for pools, report an error if none were
1836          * found.
1837          */
1838         if (argc == 0 && first)
1839                 (void) fprintf(stderr,
1840                     gettext("no pools available to import\n"));
1841
1842 error:
1843         nvlist_free(props);
1844         nvlist_free(pools);
1845         free(searchdirs);
1846
1847         return (err ? 1 : 0);
1848 }
1849
1850 typedef struct iostat_cbdata {
1851         zpool_list_t *cb_list;
1852         int cb_verbose;
1853         int cb_iteration;
1854         int cb_namewidth;
1855 } iostat_cbdata_t;
1856
1857 static void
1858 print_iostat_separator(iostat_cbdata_t *cb)
1859 {
1860         int i = 0;
1861
1862         for (i = 0; i < cb->cb_namewidth; i++)
1863                 (void) printf("-");
1864         (void) printf("  -----  -----  -----  -----  -----  -----\n");
1865 }
1866
1867 static void
1868 print_iostat_header(iostat_cbdata_t *cb)
1869 {
1870         (void) printf("%*s     capacity     operations    bandwidth\n",
1871             cb->cb_namewidth, "");
1872         (void) printf("%-*s   used  avail   read  write   read  write\n",
1873             cb->cb_namewidth, "pool");
1874         print_iostat_separator(cb);
1875 }
1876
1877 /*
1878  * Display a single statistic.
1879  */
1880 static void
1881 print_one_stat(uint64_t value)
1882 {
1883         char buf[64];
1884
1885         zfs_nicenum(value, buf, sizeof (buf));
1886         (void) printf("  %5s", buf);
1887 }
1888
1889 /*
1890  * Print out all the statistics for the given vdev.  This can either be the
1891  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1892  * is a verbose output, and we don't want to display the toplevel pool stats.
1893  */
1894 void
1895 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1896     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1897 {
1898         nvlist_t **oldchild, **newchild;
1899         uint_t c, children;
1900         vdev_stat_t *oldvs, *newvs;
1901         vdev_stat_t zerovs = { 0 };
1902         uint64_t tdelta;
1903         double scale;
1904         char *vname;
1905
1906         if (oldnv != NULL) {
1907                 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1908                     (uint64_t **)&oldvs, &c) == 0);
1909         } else {
1910                 oldvs = &zerovs;
1911         }
1912
1913         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1914             (uint64_t **)&newvs, &c) == 0);
1915
1916         if (strlen(name) + depth > cb->cb_namewidth)
1917                 (void) printf("%*s%s", depth, "", name);
1918         else
1919                 (void) printf("%*s%s%*s", depth, "", name,
1920                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
1921
1922         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1923
1924         if (tdelta == 0)
1925                 scale = 1.0;
1926         else
1927                 scale = (double)NANOSEC / tdelta;
1928
1929         /* only toplevel vdevs have capacity stats */
1930         if (newvs->vs_space == 0) {
1931                 (void) printf("      -      -");
1932         } else {
1933                 print_one_stat(newvs->vs_alloc);
1934                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1935         }
1936
1937         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1938             oldvs->vs_ops[ZIO_TYPE_READ])));
1939
1940         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1941             oldvs->vs_ops[ZIO_TYPE_WRITE])));
1942
1943         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1944             oldvs->vs_bytes[ZIO_TYPE_READ])));
1945
1946         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1947             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1948
1949         (void) printf("\n");
1950
1951         if (!cb->cb_verbose)
1952                 return;
1953
1954         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1955             &newchild, &children) != 0)
1956                 return;
1957
1958         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1959             &oldchild, &c) != 0)
1960                 return;
1961
1962         for (c = 0; c < children; c++) {
1963                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1964                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1965                     newchild[c], cb, depth + 2);
1966                 free(vname);
1967         }
1968
1969         /*
1970          * Include level 2 ARC devices in iostat output
1971          */
1972         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1973             &newchild, &children) != 0)
1974                 return;
1975
1976         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1977             &oldchild, &c) != 0)
1978                 return;
1979
1980         if (children > 0) {
1981                 (void) printf("%-*s      -      -      -      -      -      "
1982                     "-\n", cb->cb_namewidth, "cache");
1983                 for (c = 0; c < children; c++) {
1984                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1985                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1986                             newchild[c], cb, depth + 2);
1987                         free(vname);
1988                 }
1989         }
1990 }
1991
1992 static int
1993 refresh_iostat(zpool_handle_t *zhp, void *data)
1994 {
1995         iostat_cbdata_t *cb = data;
1996         boolean_t missing;
1997
1998         /*
1999          * If the pool has disappeared, remove it from the list and continue.
2000          */
2001         if (zpool_refresh_stats(zhp, &missing) != 0)
2002                 return (-1);
2003
2004         if (missing)
2005                 pool_list_remove(cb->cb_list, zhp);
2006
2007         return (0);
2008 }
2009
2010 /*
2011  * Callback to print out the iostats for the given pool.
2012  */
2013 int
2014 print_iostat(zpool_handle_t *zhp, void *data)
2015 {
2016         iostat_cbdata_t *cb = data;
2017         nvlist_t *oldconfig, *newconfig;
2018         nvlist_t *oldnvroot, *newnvroot;
2019
2020         newconfig = zpool_get_config(zhp, &oldconfig);
2021
2022         if (cb->cb_iteration == 1)
2023                 oldconfig = NULL;
2024
2025         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2026             &newnvroot) == 0);
2027
2028         if (oldconfig == NULL)
2029                 oldnvroot = NULL;
2030         else
2031                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2032                     &oldnvroot) == 0);
2033
2034         /*
2035          * Print out the statistics for the pool.
2036          */
2037         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2038
2039         if (cb->cb_verbose)
2040                 print_iostat_separator(cb);
2041
2042         return (0);
2043 }
2044
2045 int
2046 get_namewidth(zpool_handle_t *zhp, void *data)
2047 {
2048         iostat_cbdata_t *cb = data;
2049         nvlist_t *config, *nvroot;
2050
2051         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2052                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2053                     &nvroot) == 0);
2054                 if (!cb->cb_verbose)
2055                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
2056                 else
2057                         cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2058         }
2059
2060         /*
2061          * The width must fall into the range [10,38].  The upper limit is the
2062          * maximum we can have and still fit in 80 columns.
2063          */
2064         if (cb->cb_namewidth < 10)
2065                 cb->cb_namewidth = 10;
2066         if (cb->cb_namewidth > 38)
2067                 cb->cb_namewidth = 38;
2068
2069         return (0);
2070 }
2071
2072 /*
2073  * zpool iostat [-v] [pool] ... [interval [count]]
2074  *
2075  *      -v      Display statistics for individual vdevs
2076  *
2077  * This command can be tricky because we want to be able to deal with pool
2078  * creation/destruction as well as vdev configuration changes.  The bulk of this
2079  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2080  * on pool_list_update() to detect the addition of new pools.  Configuration
2081  * changes are all handled within libzfs.
2082  */
2083 int
2084 zpool_do_iostat(int argc, char **argv)
2085 {
2086         int c;
2087         int ret;
2088         int npools;
2089         unsigned long interval = 0, count = 0;
2090         zpool_list_t *list;
2091         boolean_t verbose = B_FALSE;
2092         iostat_cbdata_t cb;
2093
2094         /* check options */
2095         while ((c = getopt(argc, argv, "v")) != -1) {
2096                 switch (c) {
2097                 case 'v':
2098                         verbose = B_TRUE;
2099                         break;
2100                 case '?':
2101                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2102                             optopt);
2103                         usage(B_FALSE);
2104                 }
2105         }
2106
2107         argc -= optind;
2108         argv += optind;
2109
2110         /*
2111          * Determine if the last argument is an integer or a pool name
2112          */
2113         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2114                 char *end;
2115
2116                 errno = 0;
2117                 interval = strtoul(argv[argc - 1], &end, 10);
2118
2119                 if (*end == '\0' && errno == 0) {
2120                         if (interval == 0) {
2121                                 (void) fprintf(stderr, gettext("interval "
2122                                     "cannot be zero\n"));
2123                                 usage(B_FALSE);
2124                         }
2125
2126                         /*
2127                          * Ignore the last parameter
2128                          */
2129                         argc--;
2130                 } else {
2131                         /*
2132                          * If this is not a valid number, just plow on.  The
2133                          * user will get a more informative error message later
2134                          * on.
2135                          */
2136                         interval = 0;
2137                 }
2138         }
2139
2140         /*
2141          * If the last argument is also an integer, then we have both a count
2142          * and an integer.
2143          */
2144         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2145                 char *end;
2146
2147                 errno = 0;
2148                 count = interval;
2149                 interval = strtoul(argv[argc - 1], &end, 10);
2150
2151                 if (*end == '\0' && errno == 0) {
2152                         if (interval == 0) {
2153                                 (void) fprintf(stderr, gettext("interval "
2154                                     "cannot be zero\n"));
2155                                 usage(B_FALSE);
2156                         }
2157
2158                         /*
2159                          * Ignore the last parameter
2160                          */
2161                         argc--;
2162                 } else {
2163                         interval = 0;
2164                 }
2165         }
2166
2167         /*
2168          * Construct the list of all interesting pools.
2169          */
2170         ret = 0;
2171         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2172                 return (1);
2173
2174         if (pool_list_count(list) == 0 && argc != 0) {
2175                 pool_list_free(list);
2176                 return (1);
2177         }
2178
2179         if (pool_list_count(list) == 0 && interval == 0) {
2180                 pool_list_free(list);
2181                 (void) fprintf(stderr, gettext("no pools available\n"));
2182                 return (1);
2183         }
2184
2185         /*
2186          * Enter the main iostat loop.
2187          */
2188         cb.cb_list = list;
2189         cb.cb_verbose = verbose;
2190         cb.cb_iteration = 0;
2191         cb.cb_namewidth = 0;
2192
2193         for (;;) {
2194                 pool_list_update(list);
2195
2196                 if ((npools = pool_list_count(list)) == 0)
2197                         break;
2198
2199                 /*
2200                  * Refresh all statistics.  This is done as an explicit step
2201                  * before calculating the maximum name width, so that any
2202                  * configuration changes are properly accounted for.
2203                  */
2204                 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2205
2206                 /*
2207                  * Iterate over all pools to determine the maximum width
2208                  * for the pool / device name column across all pools.
2209                  */
2210                 cb.cb_namewidth = 0;
2211                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2212
2213                 /*
2214                  * If it's the first time, or verbose mode, print the header.
2215                  */
2216                 if (++cb.cb_iteration == 1 || verbose)
2217                         print_iostat_header(&cb);
2218
2219                 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2220
2221                 /*
2222                  * If there's more than one pool, and we're not in verbose mode
2223                  * (which prints a separator for us), then print a separator.
2224                  */
2225                 if (npools > 1 && !verbose)
2226                         print_iostat_separator(&cb);
2227
2228                 if (verbose)
2229                         (void) printf("\n");
2230
2231                 /*
2232                  * Flush the output so that redirection to a file isn't buffered
2233                  * indefinitely.
2234                  */
2235                 (void) fflush(stdout);
2236
2237                 if (interval == 0)
2238                         break;
2239
2240                 if (count != 0 && --count == 0)
2241                         break;
2242
2243                 (void) sleep(interval);
2244         }
2245
2246         pool_list_free(list);
2247
2248         return (ret);
2249 }
2250
2251 typedef struct list_cbdata {
2252         boolean_t       cb_scripted;
2253         boolean_t       cb_first;
2254         zprop_list_t    *cb_proplist;
2255 } list_cbdata_t;
2256
2257 /*
2258  * Given a list of columns to display, output appropriate headers for each one.
2259  */
2260 static void
2261 print_header(zprop_list_t *pl)
2262 {
2263         const char *header;
2264         boolean_t first = B_TRUE;
2265         boolean_t right_justify;
2266
2267         for (; pl != NULL; pl = pl->pl_next) {
2268                 if (pl->pl_prop == ZPROP_INVAL)
2269                         continue;
2270
2271                 if (!first)
2272                         (void) printf("  ");
2273                 else
2274                         first = B_FALSE;
2275
2276                 header = zpool_prop_column_name(pl->pl_prop);
2277                 right_justify = zpool_prop_align_right(pl->pl_prop);
2278
2279                 if (pl->pl_next == NULL && !right_justify)
2280                         (void) printf("%s", header);
2281                 else if (right_justify)
2282                         (void) printf("%*s", pl->pl_width, header);
2283                 else
2284                         (void) printf("%-*s", pl->pl_width, header);
2285         }
2286
2287         (void) printf("\n");
2288 }
2289
2290 /*
2291  * Given a pool and a list of properties, print out all the properties according
2292  * to the described layout.
2293  */
2294 static void
2295 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2296 {
2297         boolean_t first = B_TRUE;
2298         char property[ZPOOL_MAXPROPLEN];
2299         char *propstr;
2300         boolean_t right_justify;
2301         int width;
2302
2303         for (; pl != NULL; pl = pl->pl_next) {
2304                 if (!first) {
2305                         if (scripted)
2306                                 (void) printf("\t");
2307                         else
2308                                 (void) printf("  ");
2309                 } else {
2310                         first = B_FALSE;
2311                 }
2312
2313                 right_justify = B_FALSE;
2314                 if (pl->pl_prop != ZPROP_INVAL) {
2315                         if (zpool_get_prop(zhp, pl->pl_prop, property,
2316                             sizeof (property), NULL) != 0)
2317                                 propstr = "-";
2318                         else
2319                                 propstr = property;
2320
2321                         right_justify = zpool_prop_align_right(pl->pl_prop);
2322                 } else {
2323                         propstr = "-";
2324                 }
2325
2326                 width = pl->pl_width;
2327
2328                 /*
2329                  * If this is being called in scripted mode, or if this is the
2330                  * last column and it is left-justified, don't include a width
2331                  * format specifier.
2332                  */
2333                 if (scripted || (pl->pl_next == NULL && !right_justify))
2334                         (void) printf("%s", propstr);
2335                 else if (right_justify)
2336                         (void) printf("%*s", width, propstr);
2337                 else
2338                         (void) printf("%-*s", width, propstr);
2339         }
2340
2341         (void) printf("\n");
2342 }
2343
2344 /*
2345  * Generic callback function to list a pool.
2346  */
2347 int
2348 list_callback(zpool_handle_t *zhp, void *data)
2349 {
2350         list_cbdata_t *cbp = data;
2351
2352         if (cbp->cb_first) {
2353                 if (!cbp->cb_scripted)
2354                         print_header(cbp->cb_proplist);
2355                 cbp->cb_first = B_FALSE;
2356         }
2357
2358         print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2359
2360         return (0);
2361 }
2362
2363 /*
2364  * zpool list [-H] [-o prop[,prop]*] [pool] ...
2365  *
2366  *      -H      Scripted mode.  Don't display headers, and separate properties
2367  *              by a single tab.
2368  *      -o      List of properties to display.  Defaults to
2369  *              "name,size,used,available,capacity,health,altroot"
2370  *
2371  * List all pools in the system, whether or not they're healthy.  Output space
2372  * statistics for each one, as well as health status summary.
2373  */
2374 int
2375 zpool_do_list(int argc, char **argv)
2376 {
2377         int c;
2378         int ret;
2379         list_cbdata_t cb = { 0 };
2380         static char default_props[] =
2381             "name,size,used,available,capacity,health,altroot";
2382         char *props = default_props;
2383
2384         /* check options */
2385         while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2386                 switch (c) {
2387                 case 'H':
2388                         cb.cb_scripted = B_TRUE;
2389                         break;
2390                 case 'o':
2391                         props = optarg;
2392                         break;
2393                 case ':':
2394                         (void) fprintf(stderr, gettext("missing argument for "
2395                             "'%c' option\n"), optopt);
2396                         usage(B_FALSE);
2397                         break;
2398                 case '?':
2399                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2400                             optopt);
2401                         usage(B_FALSE);
2402                 }
2403         }
2404
2405         argc -= optind;
2406         argv += optind;
2407
2408         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2409                 usage(B_FALSE);
2410
2411         cb.cb_first = B_TRUE;
2412
2413         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2414             list_callback, &cb);
2415
2416         zprop_free_list(cb.cb_proplist);
2417
2418         if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2419                 (void) printf(gettext("no pools available\n"));
2420                 return (0);
2421         }
2422
2423         return (ret);
2424 }
2425
2426 static nvlist_t *
2427 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2428 {
2429         nvlist_t **child;
2430         uint_t c, children;
2431         nvlist_t *match;
2432         char *path;
2433
2434         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2435             &child, &children) != 0) {
2436                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2437                 if (strncmp(name, "/dev/dsk/", 9) == 0)
2438                         name += 9;
2439                 if (strncmp(path, "/dev/dsk/", 9) == 0)
2440                         path += 9;
2441                 if (strcmp(name, path) == 0)
2442                         return (nv);
2443                 return (NULL);
2444         }
2445
2446         for (c = 0; c < children; c++)
2447                 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2448                         return (match);
2449
2450         return (NULL);
2451 }
2452
2453 static int
2454 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2455 {
2456         boolean_t force = B_FALSE;
2457         int c;
2458         nvlist_t *nvroot;
2459         char *poolname, *old_disk, *new_disk;
2460         zpool_handle_t *zhp;
2461         int ret;
2462
2463         /* check options */
2464         while ((c = getopt(argc, argv, "f")) != -1) {
2465                 switch (c) {
2466                 case 'f':
2467                         force = B_TRUE;
2468                         break;
2469                 case '?':
2470                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2471                             optopt);
2472                         usage(B_FALSE);
2473                 }
2474         }
2475
2476         argc -= optind;
2477         argv += optind;
2478
2479         /* get pool name and check number of arguments */
2480         if (argc < 1) {
2481                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2482                 usage(B_FALSE);
2483         }
2484
2485         poolname = argv[0];
2486
2487         if (argc < 2) {
2488                 (void) fprintf(stderr,
2489                     gettext("missing <device> specification\n"));
2490                 usage(B_FALSE);
2491         }
2492
2493         old_disk = argv[1];
2494
2495         if (argc < 3) {
2496                 if (!replacing) {
2497                         (void) fprintf(stderr,
2498                             gettext("missing <new_device> specification\n"));
2499                         usage(B_FALSE);
2500                 }
2501                 new_disk = old_disk;
2502                 argc -= 1;
2503                 argv += 1;
2504         } else {
2505                 new_disk = argv[2];
2506                 argc -= 2;
2507                 argv += 2;
2508         }
2509
2510         if (argc > 1) {
2511                 (void) fprintf(stderr, gettext("too many arguments\n"));
2512                 usage(B_FALSE);
2513         }
2514
2515         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2516                 return (1);
2517
2518         if (zpool_get_config(zhp, NULL) == NULL) {
2519                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2520                     poolname);
2521                 zpool_close(zhp);
2522                 return (1);
2523         }
2524
2525         nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2526             argc, argv);
2527         if (nvroot == NULL) {
2528                 zpool_close(zhp);
2529                 return (1);
2530         }
2531
2532         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2533
2534         nvlist_free(nvroot);
2535         zpool_close(zhp);
2536
2537         return (ret);
2538 }
2539
2540 /*
2541  * zpool replace [-f] <pool> <device> <new_device>
2542  *
2543  *      -f      Force attach, even if <new_device> appears to be in use.
2544  *
2545  * Replace <device> with <new_device>.
2546  */
2547 /* ARGSUSED */
2548 int
2549 zpool_do_replace(int argc, char **argv)
2550 {
2551         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2552 }
2553
2554 /*
2555  * zpool attach [-f] <pool> <device> <new_device>
2556  *
2557  *      -f      Force attach, even if <new_device> appears to be in use.
2558  *
2559  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2560  * part of a mirror, then <device> will be transformed into a mirror of
2561  * <device> and <new_device>.  In either case, <new_device> will begin life
2562  * with a DTL of [0, now], and will immediately begin to resilver itself.
2563  */
2564 int
2565 zpool_do_attach(int argc, char **argv)
2566 {
2567         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2568 }
2569
2570 /*
2571  * zpool detach [-f] <pool> <device>
2572  *
2573  *      -f      Force detach of <device>, even if DTLs argue against it
2574  *              (not supported yet)
2575  *
2576  * Detach a device from a mirror.  The operation will be refused if <device>
2577  * is the last device in the mirror, or if the DTLs indicate that this device
2578  * has the only valid copy of some data.
2579  */
2580 /* ARGSUSED */
2581 int
2582 zpool_do_detach(int argc, char **argv)
2583 {
2584         int c;
2585         char *poolname, *path;
2586         zpool_handle_t *zhp;
2587         int ret;
2588
2589         /* check options */
2590         while ((c = getopt(argc, argv, "f")) != -1) {
2591                 switch (c) {
2592                 case 'f':
2593                 case '?':
2594                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2595                             optopt);
2596                         usage(B_FALSE);
2597                 }
2598         }
2599
2600         argc -= optind;
2601         argv += optind;
2602
2603         /* get pool name and check number of arguments */
2604         if (argc < 1) {
2605                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2606                 usage(B_FALSE);
2607         }
2608
2609         if (argc < 2) {
2610                 (void) fprintf(stderr,
2611                     gettext("missing <device> specification\n"));
2612                 usage(B_FALSE);
2613         }
2614
2615         poolname = argv[0];
2616         path = argv[1];
2617
2618         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2619                 return (1);
2620
2621         ret = zpool_vdev_detach(zhp, path);
2622
2623         zpool_close(zhp);
2624
2625         return (ret);
2626 }
2627
2628 /*
2629  * zpool online <pool> <device> ...
2630  */
2631 int
2632 zpool_do_online(int argc, char **argv)
2633 {
2634         int c, i;
2635         char *poolname;
2636         zpool_handle_t *zhp;
2637         int ret = 0;
2638         vdev_state_t newstate;
2639         int flags = 0;
2640
2641         /* check options */
2642         while ((c = getopt(argc, argv, "et")) != -1) {
2643                 switch (c) {
2644                 case 'e':
2645                         flags |= ZFS_ONLINE_EXPAND;
2646                         break;
2647                 case 't':
2648                 case '?':
2649                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2650                             optopt);
2651                         usage(B_FALSE);
2652                 }
2653         }
2654
2655         argc -= optind;
2656         argv += optind;
2657
2658         /* get pool name and check number of arguments */
2659         if (argc < 1) {
2660                 (void) fprintf(stderr, gettext("missing pool name\n"));
2661                 usage(B_FALSE);
2662         }
2663         if (argc < 2) {
2664                 (void) fprintf(stderr, gettext("missing device name\n"));
2665                 usage(B_FALSE);
2666         }
2667
2668         poolname = argv[0];
2669
2670         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2671                 return (1);
2672
2673         for (i = 1; i < argc; i++) {
2674                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
2675                         if (newstate != VDEV_STATE_HEALTHY) {
2676                                 (void) printf(gettext("warning: device '%s' "
2677                                     "onlined, but remains in faulted state\n"),
2678                                     argv[i]);
2679                                 if (newstate == VDEV_STATE_FAULTED)
2680                                         (void) printf(gettext("use 'zpool "
2681                                             "clear' to restore a faulted "
2682                                             "device\n"));
2683                                 else
2684                                         (void) printf(gettext("use 'zpool "
2685                                             "replace' to replace devices "
2686                                             "that are no longer present\n"));
2687                         }
2688                 } else {
2689                         ret = 1;
2690                 }
2691         }
2692
2693         zpool_close(zhp);
2694
2695         return (ret);
2696 }
2697
2698 /*
2699  * zpool offline [-ft] <pool> <device> ...
2700  *
2701  *      -f      Force the device into the offline state, even if doing
2702  *              so would appear to compromise pool availability.
2703  *              (not supported yet)
2704  *
2705  *      -t      Only take the device off-line temporarily.  The offline
2706  *              state will not be persistent across reboots.
2707  */
2708 /* ARGSUSED */
2709 int
2710 zpool_do_offline(int argc, char **argv)
2711 {
2712         int c, i;
2713         char *poolname;
2714         zpool_handle_t *zhp;
2715         int ret = 0;
2716         boolean_t istmp = B_FALSE;
2717
2718         /* check options */
2719         while ((c = getopt(argc, argv, "ft")) != -1) {
2720                 switch (c) {
2721                 case 't':
2722                         istmp = B_TRUE;
2723                         break;
2724                 case 'f':
2725                 case '?':
2726                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2727                             optopt);
2728                         usage(B_FALSE);
2729                 }
2730         }
2731
2732         argc -= optind;
2733         argv += optind;
2734
2735         /* get pool name and check number of arguments */
2736         if (argc < 1) {
2737                 (void) fprintf(stderr, gettext("missing pool name\n"));
2738                 usage(B_FALSE);
2739         }
2740         if (argc < 2) {
2741                 (void) fprintf(stderr, gettext("missing device name\n"));
2742                 usage(B_FALSE);
2743         }
2744
2745         poolname = argv[0];
2746
2747         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2748                 return (1);
2749
2750         for (i = 1; i < argc; i++) {
2751                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2752                         ret = 1;
2753         }
2754
2755         zpool_close(zhp);
2756
2757         return (ret);
2758 }
2759
2760 /*
2761  * zpool clear <pool> [device]
2762  *
2763  * Clear all errors associated with a pool or a particular device.
2764  */
2765 int
2766 zpool_do_clear(int argc, char **argv)
2767 {
2768         int ret = 0;
2769         zpool_handle_t *zhp;
2770         char *pool, *device;
2771
2772         if (argc < 2) {
2773                 (void) fprintf(stderr, gettext("missing pool name\n"));
2774                 usage(B_FALSE);
2775         }
2776
2777         if (argc > 3) {
2778                 (void) fprintf(stderr, gettext("too many arguments\n"));
2779                 usage(B_FALSE);
2780         }
2781
2782         pool = argv[1];
2783         device = argc == 3 ? argv[2] : NULL;
2784
2785         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
2786                 return (1);
2787
2788         if (zpool_clear(zhp, device) != 0)
2789                 ret = 1;
2790
2791         zpool_close(zhp);
2792
2793         return (ret);
2794 }
2795
2796 typedef struct scrub_cbdata {
2797         int     cb_type;
2798         int     cb_argc;
2799         char    **cb_argv;
2800 } scrub_cbdata_t;
2801
2802 int
2803 scrub_callback(zpool_handle_t *zhp, void *data)
2804 {
2805         scrub_cbdata_t *cb = data;
2806         int err;
2807
2808         /*
2809          * Ignore faulted pools.
2810          */
2811         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2812                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2813                     "currently unavailable\n"), zpool_get_name(zhp));
2814                 return (1);
2815         }
2816
2817         err = zpool_scrub(zhp, cb->cb_type);
2818
2819         return (err != 0);
2820 }
2821
2822 /*
2823  * zpool scrub [-s] <pool> ...
2824  *
2825  *      -s      Stop.  Stops any in-progress scrub.
2826  */
2827 int
2828 zpool_do_scrub(int argc, char **argv)
2829 {
2830         int c;
2831         scrub_cbdata_t cb;
2832
2833         cb.cb_type = POOL_SCRUB_EVERYTHING;
2834
2835         /* check options */
2836         while ((c = getopt(argc, argv, "s")) != -1) {
2837                 switch (c) {
2838                 case 's':
2839                         cb.cb_type = POOL_SCRUB_NONE;
2840                         break;
2841                 case '?':
2842                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2843                             optopt);
2844                         usage(B_FALSE);
2845                 }
2846         }
2847
2848         cb.cb_argc = argc;
2849         cb.cb_argv = argv;
2850         argc -= optind;
2851         argv += optind;
2852
2853         if (argc < 1) {
2854                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2855                 usage(B_FALSE);
2856         }
2857
2858         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2859 }
2860
2861 typedef struct status_cbdata {
2862         int             cb_count;
2863         boolean_t       cb_allpools;
2864         boolean_t       cb_verbose;
2865         boolean_t       cb_explain;
2866         boolean_t       cb_first;
2867 } status_cbdata_t;
2868
2869 /*
2870  * Print out detailed scrub status.
2871  */
2872 void
2873 print_scrub_status(nvlist_t *nvroot)
2874 {
2875         vdev_stat_t *vs;
2876         uint_t vsc;
2877         time_t start, end, now;
2878         double fraction_done;
2879         uint64_t examined, total, minutes_left, minutes_taken;
2880         char *scrub_type;
2881
2882         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2883             (uint64_t **)&vs, &vsc) == 0);
2884
2885         /*
2886          * If there's never been a scrub, there's not much to say.
2887          */
2888         if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2889                 (void) printf(gettext("none requested\n"));
2890                 return;
2891         }
2892
2893         scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2894             "resilver" : "scrub";
2895
2896         start = vs->vs_scrub_start;
2897         end = vs->vs_scrub_end;
2898         now = time(NULL);
2899         examined = vs->vs_scrub_examined;
2900         total = vs->vs_alloc;
2901
2902         if (end != 0) {
2903                 minutes_taken = (uint64_t)((end - start) / 60);
2904
2905                 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2906                     "on %s"),
2907                     scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2908                     (u_longlong_t)(minutes_taken / 60),
2909                     (uint_t)(minutes_taken % 60),
2910                     (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2911                 return;
2912         }
2913
2914         if (examined == 0)
2915                 examined = 1;
2916         if (examined > total)
2917                 total = examined;
2918
2919         fraction_done = (double)examined / total;
2920         minutes_left = (uint64_t)((now - start) *
2921             (1 - fraction_done) / fraction_done / 60);
2922         minutes_taken = (uint64_t)((now - start) / 60);
2923
2924         (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2925             "%lluh%um to go\n"),
2926             scrub_type, (u_longlong_t)(minutes_taken / 60),
2927             (uint_t)(minutes_taken % 60), 100 * fraction_done,
2928             (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2929 }
2930
2931 static void
2932 print_error_log(zpool_handle_t *zhp)
2933 {
2934         nvlist_t *nverrlist = NULL;
2935         nvpair_t *elem;
2936         char *pathname;
2937         size_t len = MAXPATHLEN * 2;
2938
2939         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2940                 (void) printf("errors: List of errors unavailable "
2941                     "(insufficient privileges)\n");
2942                 return;
2943         }
2944
2945         (void) printf("errors: Permanent errors have been "
2946             "detected in the following files:\n\n");
2947
2948         pathname = safe_malloc(len);
2949         elem = NULL;
2950         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2951                 nvlist_t *nv;
2952                 uint64_t dsobj, obj;
2953
2954                 verify(nvpair_value_nvlist(elem, &nv) == 0);
2955                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2956                     &dsobj) == 0);
2957                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2958                     &obj) == 0);
2959                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2960                 (void) printf("%7s %s\n", "", pathname);
2961         }
2962         free(pathname);
2963         nvlist_free(nverrlist);
2964 }
2965
2966 static void
2967 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2968     int namewidth)
2969 {
2970         uint_t i;
2971         char *name;
2972
2973         if (nspares == 0)
2974                 return;
2975
2976         (void) printf(gettext("\tspares\n"));
2977
2978         for (i = 0; i < nspares; i++) {
2979                 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2980                 print_status_config(zhp, name, spares[i],
2981                     namewidth, 2, B_TRUE);
2982                 free(name);
2983         }
2984 }
2985
2986 static void
2987 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2988     int namewidth)
2989 {
2990         uint_t i;
2991         char *name;
2992
2993         if (nl2cache == 0)
2994                 return;
2995
2996         (void) printf(gettext("\tcache\n"));
2997
2998         for (i = 0; i < nl2cache; i++) {
2999                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
3000                 print_status_config(zhp, name, l2cache[i],
3001                     namewidth, 2, B_FALSE);
3002                 free(name);
3003         }
3004 }
3005
3006 /*
3007  * Display a summary of pool status.  Displays a summary such as:
3008  *
3009  *        pool: tank
3010  *      status: DEGRADED
3011  *      reason: One or more devices ...
3012  *         see: http://www.sun.com/msg/ZFS-xxxx-01
3013  *      config:
3014  *              mirror          DEGRADED
3015  *                c1t0d0        OK
3016  *                c2t0d0        UNAVAIL
3017  *
3018  * When given the '-v' option, we print out the complete config.  If the '-e'
3019  * option is specified, then we print out error rate information as well.
3020  */
3021 int
3022 status_callback(zpool_handle_t *zhp, void *data)
3023 {
3024         status_cbdata_t *cbp = data;
3025         nvlist_t *config, *nvroot;
3026         char *msgid;
3027         int reason;
3028         const char *health;
3029         uint_t c;
3030         vdev_stat_t *vs;
3031
3032         config = zpool_get_config(zhp, NULL);
3033         reason = zpool_get_status(zhp, &msgid);
3034
3035         cbp->cb_count++;
3036
3037         /*
3038          * If we were given 'zpool status -x', only report those pools with
3039          * problems.
3040          */
3041         if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3042                 if (!cbp->cb_allpools) {
3043                         (void) printf(gettext("pool '%s' is healthy\n"),
3044                             zpool_get_name(zhp));
3045                         if (cbp->cb_first)
3046                                 cbp->cb_first = B_FALSE;
3047                 }
3048                 return (0);
3049         }
3050
3051         if (cbp->cb_first)
3052                 cbp->cb_first = B_FALSE;
3053         else
3054                 (void) printf("\n");
3055
3056         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3057             &nvroot) == 0);
3058         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3059             (uint64_t **)&vs, &c) == 0);
3060         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3061
3062         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
3063         (void) printf(gettext(" state: %s\n"), health);
3064
3065         switch (reason) {
3066         case ZPOOL_STATUS_MISSING_DEV_R:
3067                 (void) printf(gettext("status: One or more devices could not "
3068                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
3069                     "continue functioning in a degraded state.\n"));
3070                 (void) printf(gettext("action: Attach the missing device and "
3071                     "online it using 'zpool online'.\n"));
3072                 break;
3073
3074         case ZPOOL_STATUS_MISSING_DEV_NR:
3075                 (void) printf(gettext("status: One or more devices could not "
3076                     "be opened.  There are insufficient\n\treplicas for the "
3077                     "pool to continue functioning.\n"));
3078                 (void) printf(gettext("action: Attach the missing device and "
3079                     "online it using 'zpool online'.\n"));
3080                 break;
3081
3082         case ZPOOL_STATUS_CORRUPT_LABEL_R:
3083                 (void) printf(gettext("status: One or more devices could not "
3084                     "be used because the label is missing or\n\tinvalid.  "
3085                     "Sufficient replicas exist for the pool to continue\n\t"
3086                     "functioning in a degraded state.\n"));
3087                 (void) printf(gettext("action: Replace the device using "
3088                     "'zpool replace'.\n"));
3089                 break;
3090
3091         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3092                 (void) printf(gettext("status: One or more devices could not "
3093                     "be used because the label is missing \n\tor invalid.  "
3094                     "There are insufficient replicas for the pool to "
3095                     "continue\n\tfunctioning.\n"));
3096                 (void) printf(gettext("action: Destroy and re-create the pool "
3097                     "from a backup source.\n"));
3098                 break;
3099
3100         case ZPOOL_STATUS_FAILING_DEV:
3101                 (void) printf(gettext("status: One or more devices has "
3102                     "experienced an unrecoverable error.  An\n\tattempt was "
3103                     "made to correct the error.  Applications are "
3104                     "unaffected.\n"));
3105                 (void) printf(gettext("action: Determine if the device needs "
3106                     "to be replaced, and clear the errors\n\tusing "
3107                     "'zpool clear' or replace the device with 'zpool "
3108                     "replace'.\n"));
3109                 break;
3110
3111         case ZPOOL_STATUS_OFFLINE_DEV:
3112                 (void) printf(gettext("status: One or more devices has "
3113                     "been taken offline by the administrator.\n\tSufficient "
3114                     "replicas exist for the pool to continue functioning in "
3115                     "a\n\tdegraded state.\n"));
3116                 (void) printf(gettext("action: Online the device using "
3117                     "'zpool online' or replace the device with\n\t'zpool "
3118                     "replace'.\n"));
3119                 break;
3120
3121         case ZPOOL_STATUS_REMOVED_DEV:
3122                 (void) printf(gettext("status: One or more devices has "
3123                     "been removed by the administrator.\n\tSufficient "
3124                     "replicas exist for the pool to continue functioning in "
3125                     "a\n\tdegraded state.\n"));
3126                 (void) printf(gettext("action: Online the device using "
3127                     "'zpool online' or replace the device with\n\t'zpool "
3128                     "replace'.\n"));
3129                 break;
3130
3131
3132         case ZPOOL_STATUS_RESILVERING:
3133                 (void) printf(gettext("status: One or more devices is "
3134                     "currently being resilvered.  The pool will\n\tcontinue "
3135                     "to function, possibly in a degraded state.\n"));
3136                 (void) printf(gettext("action: Wait for the resilver to "
3137                     "complete.\n"));
3138                 break;
3139
3140         case ZPOOL_STATUS_CORRUPT_DATA:
3141                 (void) printf(gettext("status: One or more devices has "
3142                     "experienced an error resulting in data\n\tcorruption.  "
3143                     "Applications may be affected.\n"));
3144                 (void) printf(gettext("action: Restore the file in question "
3145                     "if possible.  Otherwise restore the\n\tentire pool from "
3146                     "backup.\n"));
3147                 break;
3148
3149         case ZPOOL_STATUS_CORRUPT_POOL:
3150                 (void) printf(gettext("status: The pool metadata is corrupted "
3151                     "and the pool cannot be opened.\n"));
3152                 (void) printf(gettext("action: Destroy and re-create the pool "
3153                     "from a backup source.\n"));
3154                 break;
3155
3156         case ZPOOL_STATUS_VERSION_OLDER:
3157                 (void) printf(gettext("status: The pool is formatted using an "
3158                     "older on-disk format.  The pool can\n\tstill be used, but "
3159                     "some features are unavailable.\n"));
3160                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3161                     "upgrade'.  Once this is done, the\n\tpool will no longer "
3162                     "be accessible on older software versions.\n"));
3163                 break;
3164
3165         case ZPOOL_STATUS_VERSION_NEWER:
3166                 (void) printf(gettext("status: The pool has been upgraded to a "
3167                     "newer, incompatible on-disk version.\n\tThe pool cannot "
3168                     "be accessed on this system.\n"));
3169                 (void) printf(gettext("action: Access the pool from a system "
3170                     "running more recent software, or\n\trestore the pool from "
3171                     "backup.\n"));
3172                 break;
3173
3174         case ZPOOL_STATUS_FAULTED_DEV_R:
3175                 (void) printf(gettext("status: One or more devices are "
3176                     "faulted in response to persistent errors.\n\tSufficient "
3177                     "replicas exist for the pool to continue functioning "
3178                     "in a\n\tdegraded state.\n"));
3179                 (void) printf(gettext("action: Replace the faulted device, "
3180                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3181                 break;
3182
3183         case ZPOOL_STATUS_FAULTED_DEV_NR:
3184                 (void) printf(gettext("status: One or more devices are "
3185                     "faulted in response to persistent errors.  There are "
3186                     "insufficient replicas for the pool to\n\tcontinue "
3187                     "functioning.\n"));
3188                 (void) printf(gettext("action: Destroy and re-create the pool "
3189                     "from a backup source.  Manually marking the device\n"
3190                     "\trepaired using 'zpool clear' may allow some data "
3191                     "to be recovered.\n"));
3192                 break;
3193
3194         case ZPOOL_STATUS_IO_FAILURE_WAIT:
3195         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3196                 (void) printf(gettext("status: One or more devices are "
3197                     "faulted in response to IO failures.\n"));
3198                 (void) printf(gettext("action: Make sure the affected devices "
3199                     "are connected, then run 'zpool clear'.\n"));
3200                 break;
3201
3202         case ZPOOL_STATUS_BAD_LOG:
3203                 (void) printf(gettext("status: An intent log record "
3204                     "could not be read.\n"
3205                     "\tWaiting for adminstrator intervention to fix the "
3206                     "faulted pool.\n"));
3207                 (void) printf(gettext("action: Either restore the affected "
3208                     "device(s) and run 'zpool online',\n"
3209                     "\tor ignore the intent log records by running "
3210                     "'zpool clear'.\n"));
3211                 break;
3212
3213         default:
3214                 /*
3215                  * The remaining errors can't actually be generated, yet.
3216                  */
3217                 assert(reason == ZPOOL_STATUS_OK);
3218         }
3219
3220         if (msgid != NULL)
3221                 (void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3222                     msgid);
3223
3224         if (config != NULL) {
3225                 int namewidth;
3226                 uint64_t nerr;
3227                 nvlist_t **spares, **l2cache;
3228                 uint_t nspares, nl2cache;
3229
3230
3231                 (void) printf(gettext(" scrub: "));
3232                 print_scrub_status(nvroot);
3233
3234                 namewidth = max_width(zhp, nvroot, 0, 0);
3235                 if (namewidth < 10)
3236                         namewidth = 10;
3237
3238                 (void) printf(gettext("config:\n\n"));
3239                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3240                     "NAME", "STATE", "READ", "WRITE", "CKSUM");
3241                 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3242                     namewidth, 0, B_FALSE);
3243
3244                 if (num_logs(nvroot) > 0)
3245                         print_logs(zhp, nvroot, namewidth, B_TRUE);
3246                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3247                     &l2cache, &nl2cache) == 0)
3248                         print_l2cache(zhp, l2cache, nl2cache, namewidth);
3249
3250                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3251                     &spares, &nspares) == 0)
3252                         print_spares(zhp, spares, nspares, namewidth);
3253
3254                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3255                     &nerr) == 0) {
3256                         nvlist_t *nverrlist = NULL;
3257
3258                         /*
3259                          * If the approximate error count is small, get a
3260                          * precise count by fetching the entire log and
3261                          * uniquifying the results.
3262                          */
3263                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3264                             zpool_get_errlog(zhp, &nverrlist) == 0) {
3265                                 nvpair_t *elem;
3266
3267                                 elem = NULL;
3268                                 nerr = 0;
3269                                 while ((elem = nvlist_next_nvpair(nverrlist,
3270                                     elem)) != NULL) {
3271                                         nerr++;
3272                                 }
3273                         }
3274                         nvlist_free(nverrlist);
3275
3276                         (void) printf("\n");
3277
3278                         if (nerr == 0)
3279                                 (void) printf(gettext("errors: No known data "
3280                                     "errors\n"));
3281                         else if (!cbp->cb_verbose)
3282                                 (void) printf(gettext("errors: %llu data "
3283                                     "errors, use '-v' for a list\n"),
3284                                     (u_longlong_t)nerr);
3285                         else
3286                                 print_error_log(zhp);
3287                 }
3288         } else {
3289                 (void) printf(gettext("config: The configuration cannot be "
3290                     "determined.\n"));
3291         }
3292
3293         return (0);
3294 }
3295
3296 /*
3297  * zpool status [-vx] [pool] ...
3298  *
3299  *      -v      Display complete error logs
3300  *      -x      Display only pools with potential problems
3301  *
3302  * Describes the health status of all pools or some subset.
3303  */
3304 int
3305 zpool_do_status(int argc, char **argv)
3306 {
3307         int c;
3308         int ret;
3309         status_cbdata_t cb = { 0 };
3310
3311         /* check options */
3312         while ((c = getopt(argc, argv, "vx")) != -1) {
3313                 switch (c) {
3314                 case 'v':
3315                         cb.cb_verbose = B_TRUE;
3316                         break;
3317                 case 'x':
3318                         cb.cb_explain = B_TRUE;
3319                         break;
3320                 case '?':
3321                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3322                             optopt);
3323                         usage(B_FALSE);
3324                 }
3325         }
3326
3327         argc -= optind;
3328         argv += optind;
3329
3330         cb.cb_first = B_TRUE;
3331
3332         if (argc == 0)
3333                 cb.cb_allpools = B_TRUE;
3334
3335         ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3336
3337         if (argc == 0 && cb.cb_count == 0)
3338                 (void) printf(gettext("no pools available\n"));
3339         else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3340                 (void) printf(gettext("all pools are healthy\n"));
3341
3342         return (ret);
3343 }
3344
3345 typedef struct upgrade_cbdata {
3346         int     cb_all;
3347         int     cb_first;
3348         int     cb_newer;
3349         int     cb_argc;
3350         uint64_t cb_version;
3351         char    **cb_argv;
3352 } upgrade_cbdata_t;
3353
3354 static int
3355 upgrade_cb(zpool_handle_t *zhp, void *arg)
3356 {
3357         upgrade_cbdata_t *cbp = arg;
3358         nvlist_t *config;
3359         uint64_t version;
3360         int ret = 0;
3361
3362         config = zpool_get_config(zhp, NULL);
3363         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3364             &version) == 0);
3365
3366         if (!cbp->cb_newer && version < SPA_VERSION) {
3367                 if (!cbp->cb_all) {
3368                         if (cbp->cb_first) {
3369                                 (void) printf(gettext("The following pools are "
3370                                     "out of date, and can be upgraded.  After "
3371                                     "being\nupgraded, these pools will no "
3372                                     "longer be accessible by older software "
3373                                     "versions.\n\n"));
3374                                 (void) printf(gettext("VER  POOL\n"));
3375                                 (void) printf(gettext("---  ------------\n"));
3376                                 cbp->cb_first = B_FALSE;
3377                         }
3378
3379                         (void) printf("%2llu   %s\n", (u_longlong_t)version,
3380                             zpool_get_name(zhp));
3381                 } else {
3382                         cbp->cb_first = B_FALSE;
3383                         ret = zpool_upgrade(zhp, cbp->cb_version);
3384                         if (!ret) {
3385                                 (void) printf(gettext("Successfully upgraded "
3386                                     "'%s'\n\n"), zpool_get_name(zhp));
3387                         }
3388                 }
3389         } else if (cbp->cb_newer && version > SPA_VERSION) {
3390                 assert(!cbp->cb_all);
3391
3392                 if (cbp->cb_first) {
3393                         (void) printf(gettext("The following pools are "
3394                             "formatted using a newer software version and\n"
3395                             "cannot be accessed on the current system.\n\n"));
3396                         (void) printf(gettext("VER  POOL\n"));
3397                         (void) printf(gettext("---  ------------\n"));
3398                         cbp->cb_first = B_FALSE;
3399                 }
3400
3401                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
3402                     zpool_get_name(zhp));
3403         }
3404
3405         zpool_close(zhp);
3406         return (ret);
3407 }
3408
3409 /* ARGSUSED */
3410 static int
3411 upgrade_one(zpool_handle_t *zhp, void *data)
3412 {
3413         upgrade_cbdata_t *cbp = data;
3414         uint64_t cur_version;
3415         int ret;
3416
3417         if (strcmp("log", zpool_get_name(zhp)) == 0) {
3418                 (void) printf(gettext("'log' is now a reserved word\n"
3419                     "Pool 'log' must be renamed using export and import"
3420                     " to upgrade.\n"));
3421                 return (1);
3422         }
3423
3424         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3425         if (cur_version > cbp->cb_version) {
3426                 (void) printf(gettext("Pool '%s' is already formatted "
3427                     "using more current version '%llu'.\n"),
3428                     zpool_get_name(zhp), cur_version);
3429                 return (0);
3430         }
3431         if (cur_version == cbp->cb_version) {
3432                 (void) printf(gettext("Pool '%s' is already formatted "
3433                     "using the current version.\n"), zpool_get_name(zhp));
3434                 return (0);
3435         }
3436
3437         ret = zpool_upgrade(zhp, cbp->cb_version);
3438
3439         if (!ret) {
3440                 (void) printf(gettext("Successfully upgraded '%s' "
3441                     "from version %llu to version %llu\n\n"),
3442                     zpool_get_name(zhp), (u_longlong_t)cur_version,
3443                     (u_longlong_t)cbp->cb_version);
3444         }
3445
3446         return (ret != 0);
3447 }
3448
3449 /*
3450  * zpool upgrade
3451  * zpool upgrade -v
3452  * zpool upgrade [-V version] <-a | pool ...>
3453  *
3454  * With no arguments, display downrev'd ZFS pool available for upgrade.
3455  * Individual pools can be upgraded by specifying the pool, and '-a' will
3456  * upgrade all pools.
3457  */
3458 int
3459 zpool_do_upgrade(int argc, char **argv)
3460 {
3461         int c;
3462         upgrade_cbdata_t cb = { 0 };
3463         int ret = 0;
3464         boolean_t showversions = B_FALSE;
3465         char *end;
3466
3467
3468         /* check options */
3469         while ((c = getopt(argc, argv, ":avV:")) != -1) {
3470                 switch (c) {
3471                 case 'a':
3472                         cb.cb_all = B_TRUE;
3473                         break;
3474                 case 'v':
3475                         showversions = B_TRUE;
3476                         break;
3477                 case 'V':
3478                         cb.cb_version = strtoll(optarg, &end, 10);
3479                         if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3480                             cb.cb_version < SPA_VERSION_1) {
3481                                 (void) fprintf(stderr,
3482                                     gettext("invalid version '%s'\n"), optarg);
3483                                 usage(B_FALSE);
3484                         }
3485                         break;
3486                 case ':':
3487                         (void) fprintf(stderr, gettext("missing argument for "
3488                             "'%c' option\n"), optopt);
3489                         usage(B_FALSE);
3490                         break;
3491                 case '?':
3492                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3493                             optopt);
3494                         usage(B_FALSE);
3495                 }
3496         }
3497
3498         cb.cb_argc = argc;
3499         cb.cb_argv = argv;
3500         argc -= optind;
3501         argv += optind;
3502
3503         if (cb.cb_version == 0) {
3504                 cb.cb_version = SPA_VERSION;
3505         } else if (!cb.cb_all && argc == 0) {
3506                 (void) fprintf(stderr, gettext("-V option is "
3507                     "incompatible with other arguments\n"));
3508                 usage(B_FALSE);
3509         }
3510
3511         if (showversions) {
3512                 if (cb.cb_all || argc != 0) {
3513                         (void) fprintf(stderr, gettext("-v option is "
3514                             "incompatible with other arguments\n"));
3515                         usage(B_FALSE);
3516                 }
3517         } else if (cb.cb_all) {
3518                 if (argc != 0) {
3519                         (void) fprintf(stderr, gettext("-a option should not "
3520                             "be used along with a pool name\n"));
3521                         usage(B_FALSE);
3522                 }
3523         }
3524
3525         (void) printf(gettext("This system is currently running "
3526             "ZFS pool version %llu.\n\n"), SPA_VERSION);
3527         cb.cb_first = B_TRUE;
3528         if (showversions) {
3529                 (void) printf(gettext("The following versions are "
3530                     "supported:\n\n"));
3531                 (void) printf(gettext("VER  DESCRIPTION\n"));
3532                 (void) printf("---  -----------------------------------------"
3533                     "---------------\n");
3534                 (void) printf(gettext(" 1   Initial ZFS version\n"));
3535                 (void) printf(gettext(" 2   Ditto blocks "
3536                     "(replicated metadata)\n"));
3537                 (void) printf(gettext(" 3   Hot spares and double parity "
3538                     "RAID-Z\n"));
3539                 (void) printf(gettext(" 4   zpool history\n"));
3540                 (void) printf(gettext(" 5   Compression using the gzip "
3541                     "algorithm\n"));
3542                 (void) printf(gettext(" 6   bootfs pool property\n"));
3543                 (void) printf(gettext(" 7   Separate intent log devices\n"));
3544                 (void) printf(gettext(" 8   Delegated administration\n"));
3545                 (void) printf(gettext(" 9   refquota and refreservation "
3546                     "properties\n"));
3547                 (void) printf(gettext(" 10  Cache devices\n"));
3548                 (void) printf(gettext(" 11  Improved scrub performance\n"));
3549                 (void) printf(gettext(" 12  Snapshot properties\n"));
3550                 (void) printf(gettext(" 13  snapused property\n"));
3551                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
3552                 (void) printf(gettext(" 15  user/group space accounting\n"));
3553                 (void) printf(gettext(" 16  stmf property support\n"));
3554                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
3555                 (void) printf(gettext(" 18  snapshot user holds\n"));
3556                 (void) printf(gettext("For more information on a particular "
3557                     "version, including supported releases, see:\n\n"));
3558                 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3559                     "version/N\n\n");
3560                 (void) printf(gettext("Where 'N' is the version number.\n"));
3561         } else if (argc == 0) {
3562                 int notfound;
3563
3564                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3565                 notfound = cb.cb_first;
3566
3567                 if (!cb.cb_all && ret == 0) {
3568                         if (!cb.cb_first)
3569                                 (void) printf("\n");
3570                         cb.cb_first = B_TRUE;
3571                         cb.cb_newer = B_TRUE;
3572                         ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3573                         if (!cb.cb_first) {
3574                                 notfound = B_FALSE;
3575                                 (void) printf("\n");
3576                         }
3577                 }
3578
3579                 if (ret == 0) {
3580                         if (notfound)
3581                                 (void) printf(gettext("All pools are formatted "
3582                                     "using this version.\n"));
3583                         else if (!cb.cb_all)
3584                                 (void) printf(gettext("Use 'zpool upgrade -v' "
3585                                     "for a list of available versions and "
3586                                     "their associated\nfeatures.\n"));
3587                 }
3588         } else {
3589                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3590                     upgrade_one, &cb);
3591         }
3592
3593         return (ret);
3594 }
3595
3596 typedef struct hist_cbdata {
3597         boolean_t first;
3598         int longfmt;
3599         int internal;
3600 } hist_cbdata_t;
3601
3602 char *hist_event_table[LOG_END] = {
3603         "invalid event",
3604         "pool create",
3605         "vdev add",
3606         "pool remove",
3607         "pool destroy",
3608         "pool export",
3609         "pool import",
3610         "vdev attach",
3611         "vdev replace",
3612         "vdev detach",
3613         "vdev online",
3614         "vdev offline",
3615         "vdev upgrade",
3616         "pool clear",
3617         "pool scrub",
3618         "pool property set",
3619         "create",
3620         "clone",
3621         "destroy",
3622         "destroy_begin_sync",
3623         "inherit",
3624         "property set",
3625         "quota set",
3626         "permission update",
3627         "permission remove",
3628         "permission who remove",
3629         "promote",
3630         "receive",
3631         "rename",
3632         "reservation set",
3633         "replay_inc_sync",
3634         "replay_full_sync",
3635         "rollback",
3636         "snapshot",
3637         "filesystem version upgrade",
3638         "refquota set",
3639         "refreservation set",
3640         "pool scrub done",
3641         "user hold",
3642         "user release",
3643 };
3644
3645 /*
3646  * Print out the command history for a specific pool.
3647  */
3648 static int
3649 get_history_one(zpool_handle_t *zhp, void *data)
3650 {
3651         nvlist_t *nvhis;
3652         nvlist_t **records;
3653         uint_t numrecords;
3654         char *cmdstr;
3655         char *pathstr;
3656         uint64_t dst_time;
3657         time_t tsec;
3658         struct tm t;
3659         char tbuf[30];
3660         int ret, i;
3661         uint64_t who;
3662         struct passwd *pwd;
3663         char *hostname;
3664         char *zonename;
3665         char internalstr[MAXPATHLEN];
3666         hist_cbdata_t *cb = (hist_cbdata_t *)data;
3667         uint64_t txg;
3668         uint64_t ievent;
3669
3670         cb->first = B_FALSE;
3671
3672         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3673
3674         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3675                 return (ret);
3676
3677         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3678             &records, &numrecords) == 0);
3679         for (i = 0; i < numrecords; i++) {
3680                 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3681                     &dst_time) != 0)
3682                         continue;
3683
3684                 /* is it an internal event or a standard event? */
3685                 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3686                     &cmdstr) != 0) {
3687                         if (cb->internal == 0)
3688                                 continue;
3689
3690                         if (nvlist_lookup_uint64(records[i],
3691                             ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3692                                 continue;
3693                         verify(nvlist_lookup_uint64(records[i],
3694                             ZPOOL_HIST_TXG, &txg) == 0);
3695                         verify(nvlist_lookup_string(records[i],
3696                             ZPOOL_HIST_INT_STR, &pathstr) == 0);
3697                         if (ievent >= LOG_END)
3698                                 continue;
3699                         (void) snprintf(internalstr,
3700                             sizeof (internalstr),
3701                             "[internal %s txg:%lld] %s",
3702                             hist_event_table[ievent], txg,
3703                             pathstr);
3704                         cmdstr = internalstr;
3705                 }
3706                 tsec = dst_time;
3707                 (void) localtime_r(&tsec, &t);
3708                 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3709                 (void) printf("%s %s", tbuf, cmdstr);
3710
3711                 if (!cb->longfmt) {
3712                         (void) printf("\n");
3713                         continue;
3714                 }
3715                 (void) printf(" [");
3716                 if (nvlist_lookup_uint64(records[i],
3717                     ZPOOL_HIST_WHO, &who) == 0) {
3718                         pwd = getpwuid((uid_t)who);
3719                         if (pwd)
3720                                 (void) printf("user %s on",
3721                                     pwd->pw_name);
3722                         else
3723                                 (void) printf("user %d on",
3724                                     (int)who);
3725                 } else {
3726                         (void) printf(gettext("no info]\n"));
3727                         continue;
3728                 }
3729                 if (nvlist_lookup_string(records[i],
3730                     ZPOOL_HIST_HOST, &hostname) == 0) {
3731                         (void) printf(" %s", hostname);
3732                 }
3733                 if (nvlist_lookup_string(records[i],
3734                     ZPOOL_HIST_ZONE, &zonename) == 0) {
3735                         (void) printf(":%s", zonename);
3736                 }
3737
3738                 (void) printf("]");
3739                 (void) printf("\n");
3740         }
3741         (void) printf("\n");
3742         nvlist_free(nvhis);
3743
3744         return (ret);
3745 }
3746
3747 /*
3748  * zpool history <pool>
3749  *
3750  * Displays the history of commands that modified pools.
3751  */
3752
3753
3754 int
3755 zpool_do_history(int argc, char **argv)
3756 {
3757         hist_cbdata_t cbdata = { 0 };
3758         int ret;
3759         int c;
3760
3761         cbdata.first = B_TRUE;
3762         /* check options */
3763         while ((c = getopt(argc, argv, "li")) != -1) {
3764                 switch (c) {
3765                 case 'l':
3766                         cbdata.longfmt = 1;
3767                         break;
3768                 case 'i':
3769                         cbdata.internal = 1;
3770                         break;
3771                 case '?':
3772                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3773                             optopt);
3774                         usage(B_FALSE);
3775                 }
3776         }
3777         argc -= optind;
3778         argv += optind;
3779
3780         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
3781             &cbdata);
3782
3783         if (argc == 0 && cbdata.first == B_TRUE) {
3784                 (void) printf(gettext("no pools available\n"));
3785                 return (0);
3786         }
3787
3788         return (ret);
3789 }
3790
3791 static int
3792 get_callback(zpool_handle_t *zhp, void *data)
3793 {
3794         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3795         char value[MAXNAMELEN];
3796         zprop_source_t srctype;
3797         zprop_list_t *pl;
3798
3799         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3800
3801                 /*
3802                  * Skip the special fake placeholder. This will also skip
3803                  * over the name property when 'all' is specified.
3804                  */
3805                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3806                     pl == cbp->cb_proplist)
3807                         continue;
3808
3809                 if (zpool_get_prop(zhp, pl->pl_prop,
3810                     value, sizeof (value), &srctype) != 0)
3811                         continue;
3812
3813                 zprop_print_one_property(zpool_get_name(zhp), cbp,
3814                     zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3815         }
3816         return (0);
3817 }
3818
3819 int
3820 zpool_do_get(int argc, char **argv)
3821 {
3822         zprop_get_cbdata_t cb = { 0 };
3823         zprop_list_t fake_name = { 0 };
3824         int ret;
3825
3826         if (argc < 3)
3827                 usage(B_FALSE);
3828
3829         cb.cb_first = B_TRUE;
3830         cb.cb_sources = ZPROP_SRC_ALL;
3831         cb.cb_columns[0] = GET_COL_NAME;
3832         cb.cb_columns[1] = GET_COL_PROPERTY;
3833         cb.cb_columns[2] = GET_COL_VALUE;
3834         cb.cb_columns[3] = GET_COL_SOURCE;
3835         cb.cb_type = ZFS_TYPE_POOL;
3836
3837         if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
3838             ZFS_TYPE_POOL) != 0)
3839                 usage(B_FALSE);
3840
3841         if (cb.cb_proplist != NULL) {
3842                 fake_name.pl_prop = ZPOOL_PROP_NAME;
3843                 fake_name.pl_width = strlen(gettext("NAME"));
3844                 fake_name.pl_next = cb.cb_proplist;
3845                 cb.cb_proplist = &fake_name;
3846         }
3847
3848         ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3849             get_callback, &cb);
3850
3851         if (cb.cb_proplist == &fake_name)
3852                 zprop_free_list(fake_name.pl_next);
3853         else
3854                 zprop_free_list(cb.cb_proplist);
3855
3856         return (ret);
3857 }
3858
3859 typedef struct set_cbdata {
3860         char *cb_propname;
3861         char *cb_value;
3862         boolean_t cb_any_successful;
3863 } set_cbdata_t;
3864
3865 int
3866 set_callback(zpool_handle_t *zhp, void *data)
3867 {
3868         int error;
3869         set_cbdata_t *cb = (set_cbdata_t *)data;
3870
3871         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3872
3873         if (!error)
3874                 cb->cb_any_successful = B_TRUE;
3875
3876         return (error);
3877 }
3878
3879 int
3880 zpool_do_set(int argc, char **argv)
3881 {
3882         set_cbdata_t cb = { 0 };
3883         int error;
3884
3885         if (argc > 1 && argv[1][0] == '-') {
3886                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3887                     argv[1][1]);
3888                 usage(B_FALSE);
3889         }
3890
3891         if (argc < 2) {
3892                 (void) fprintf(stderr, gettext("missing property=value "
3893                     "argument\n"));
3894                 usage(B_FALSE);
3895         }
3896
3897         if (argc < 3) {
3898                 (void) fprintf(stderr, gettext("missing pool name\n"));
3899                 usage(B_FALSE);
3900         }
3901
3902         if (argc > 3) {
3903                 (void) fprintf(stderr, gettext("too many pool names\n"));
3904                 usage(B_FALSE);
3905         }
3906
3907         cb.cb_propname = argv[1];
3908         cb.cb_value = strchr(cb.cb_propname, '=');
3909         if (cb.cb_value == NULL) {
3910                 (void) fprintf(stderr, gettext("missing value in "
3911                     "property=value argument\n"));
3912                 usage(B_FALSE);
3913         }
3914
3915         *(cb.cb_value) = '\0';
3916         cb.cb_value++;
3917
3918         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3919             set_callback, &cb);
3920
3921         return (error);
3922 }
3923
3924 static int
3925 find_command_idx(char *command, int *idx)
3926 {
3927         int i;
3928
3929         for (i = 0; i < NCOMMAND; i++) {
3930                 if (command_table[i].name == NULL)
3931                         continue;
3932
3933                 if (strcmp(command, command_table[i].name) == 0) {
3934                         *idx = i;
3935                         return (0);
3936                 }
3937         }
3938         return (1);
3939 }
3940
3941 int
3942 main(int argc, char **argv)
3943 {
3944         int ret;
3945         int i;
3946         char *cmdname;
3947
3948         (void) setlocale(LC_ALL, "");
3949         (void) textdomain(TEXT_DOMAIN);
3950
3951         if ((g_zfs = libzfs_init()) == NULL) {
3952                 (void) fprintf(stderr, gettext("internal error: failed to "
3953                     "initialize ZFS library\n"));
3954                 return (1);
3955         }
3956
3957         libzfs_print_on_error(g_zfs, B_TRUE);
3958
3959         opterr = 0;
3960
3961         /*
3962          * Make sure the user has specified some command.
3963          */
3964         if (argc < 2) {
3965                 (void) fprintf(stderr, gettext("missing command\n"));
3966                 usage(B_FALSE);
3967         }
3968
3969         cmdname = argv[1];
3970
3971         /*
3972          * Special case '-?'
3973          */
3974         if (strcmp(cmdname, "-?") == 0)
3975                 usage(B_TRUE);
3976
3977         zpool_set_history_str("zpool", argc, argv, history_str);
3978         verify(zpool_stage_history(g_zfs, history_str) == 0);
3979
3980         /*
3981          * Run the appropriate command.
3982          */
3983         if (find_command_idx(cmdname, &i) == 0) {
3984                 current_command = &command_table[i];
3985                 ret = command_table[i].func(argc - 1, argv + 1);
3986         } else if (strchr(cmdname, '=')) {
3987                 verify(find_command_idx("set", &i) == 0);
3988                 current_command = &command_table[i];
3989                 ret = command_table[i].func(argc, argv);
3990         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3991                 /*
3992                  * 'freeze' is a vile debugging abomination, so we treat
3993                  * it as such.
3994                  */
3995                 char buf[16384];
3996                 int fd = open(ZFS_DEV, O_RDWR);
3997                 (void) strcpy((void *)buf, argv[2]);
3998                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3999         } else {
4000                 (void) fprintf(stderr, gettext("unrecognized "
4001                     "command '%s'\n"), cmdname);
4002                 usage(B_FALSE);
4003         }
4004
4005         libzfs_fini(g_zfs);
4006
4007         /*
4008          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
4009          * for the purposes of running ::findleaks.
4010          */
4011         if (getenv("ZFS_ABORT") != NULL) {
4012                 (void) printf("dumping core by request\n");
4013                 abort();
4014         }
4015
4016         return (ret);
4017 }