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