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