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