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