Explicitly flush output at end of each zevent
[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 (gettext("\treopen <pool>\n"));
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 int
3617 zpool_do_reopen(int argc, char **argv)
3618 {
3619         int c;
3620         int ret = 0;
3621         zpool_handle_t *zhp;
3622         char *pool;
3623
3624         /* check options */
3625         while ((c = getopt(argc, argv, "")) != -1) {
3626                 switch (c) {
3627                 case '?':
3628                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3629                             optopt);
3630                         usage(B_FALSE);
3631                 }
3632         }
3633
3634         argc--;
3635         argv++;
3636
3637         if (argc < 1) {
3638                 (void) fprintf(stderr, gettext("missing pool name\n"));
3639                 usage(B_FALSE);
3640         }
3641
3642         if (argc > 1) {
3643                 (void) fprintf(stderr, gettext("too many arguments\n"));
3644                 usage(B_FALSE);
3645         }
3646
3647         pool = argv[0];
3648         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
3649                 return (1);
3650
3651         ret = zpool_reopen(zhp);
3652         zpool_close(zhp);
3653         return (ret);
3654 }
3655
3656 typedef struct scrub_cbdata {
3657         int     cb_type;
3658         int     cb_argc;
3659         char    **cb_argv;
3660 } scrub_cbdata_t;
3661
3662 int
3663 scrub_callback(zpool_handle_t *zhp, void *data)
3664 {
3665         scrub_cbdata_t *cb = data;
3666         int err;
3667
3668         /*
3669          * Ignore faulted pools.
3670          */
3671         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3672                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3673                     "currently unavailable\n"), zpool_get_name(zhp));
3674                 return (1);
3675         }
3676
3677         err = zpool_scan(zhp, cb->cb_type);
3678
3679         return (err != 0);
3680 }
3681
3682 /*
3683  * zpool scrub [-s] <pool> ...
3684  *
3685  *      -s      Stop.  Stops any in-progress scrub.
3686  */
3687 int
3688 zpool_do_scrub(int argc, char **argv)
3689 {
3690         int c;
3691         scrub_cbdata_t cb;
3692
3693         cb.cb_type = POOL_SCAN_SCRUB;
3694
3695         /* check options */
3696         while ((c = getopt(argc, argv, "s")) != -1) {
3697                 switch (c) {
3698                 case 's':
3699                         cb.cb_type = POOL_SCAN_NONE;
3700                         break;
3701                 case '?':
3702                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3703                             optopt);
3704                         usage(B_FALSE);
3705                 }
3706         }
3707
3708         cb.cb_argc = argc;
3709         cb.cb_argv = argv;
3710         argc -= optind;
3711         argv += optind;
3712
3713         if (argc < 1) {
3714                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3715                 usage(B_FALSE);
3716         }
3717
3718         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
3719 }
3720
3721 typedef struct status_cbdata {
3722         int             cb_count;
3723         boolean_t       cb_allpools;
3724         boolean_t       cb_verbose;
3725         boolean_t       cb_explain;
3726         boolean_t       cb_first;
3727         boolean_t       cb_dedup_stats;
3728 } status_cbdata_t;
3729
3730 /*
3731  * Print out detailed scrub status.
3732  */
3733 void
3734 print_scan_status(pool_scan_stat_t *ps)
3735 {
3736         time_t start, end;
3737         uint64_t elapsed, mins_left, hours_left;
3738         uint64_t pass_exam, examined, total;
3739         uint_t rate;
3740         double fraction_done;
3741         char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
3742
3743         (void) printf(gettext("  scan: "));
3744
3745         /* If there's never been a scan, there's not much to say. */
3746         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
3747             ps->pss_func >= POOL_SCAN_FUNCS) {
3748                 (void) printf(gettext("none requested\n"));
3749                 return;
3750         }
3751
3752         start = ps->pss_start_time;
3753         end = ps->pss_end_time;
3754         zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
3755
3756         assert(ps->pss_func == POOL_SCAN_SCRUB ||
3757             ps->pss_func == POOL_SCAN_RESILVER);
3758         /*
3759          * Scan is finished or canceled.
3760          */
3761         if (ps->pss_state == DSS_FINISHED) {
3762                 uint64_t minutes_taken = (end - start) / 60;
3763                 char *fmt = NULL;
3764
3765                 if (ps->pss_func == POOL_SCAN_SCRUB) {
3766                         fmt = gettext("scrub repaired %s in %lluh%um with "
3767                             "%llu errors on %s");
3768                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3769                         fmt = gettext("resilvered %s in %lluh%um with "
3770                             "%llu errors on %s");
3771                 }
3772                 /* LINTED */
3773                 (void) printf(fmt, processed_buf,
3774                     (u_longlong_t)(minutes_taken / 60),
3775                     (uint_t)(minutes_taken % 60),
3776                     (u_longlong_t)ps->pss_errors,
3777                     ctime((time_t *)&end));
3778                 return;
3779         } else if (ps->pss_state == DSS_CANCELED) {
3780                 if (ps->pss_func == POOL_SCAN_SCRUB) {
3781                         (void) printf(gettext("scrub canceled on %s"),
3782                             ctime(&end));
3783                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3784                         (void) printf(gettext("resilver canceled on %s"),
3785                             ctime(&end));
3786                 }
3787                 return;
3788         }
3789
3790         assert(ps->pss_state == DSS_SCANNING);
3791
3792         /*
3793          * Scan is in progress.
3794          */
3795         if (ps->pss_func == POOL_SCAN_SCRUB) {
3796                 (void) printf(gettext("scrub in progress since %s"),
3797                     ctime(&start));
3798         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3799                 (void) printf(gettext("resilver in progress since %s"),
3800                     ctime(&start));
3801         }
3802
3803         examined = ps->pss_examined ? ps->pss_examined : 1;
3804         total = ps->pss_to_examine;
3805         fraction_done = (double)examined / total;
3806
3807         /* elapsed time for this pass */
3808         elapsed = time(NULL) - ps->pss_pass_start;
3809         elapsed = elapsed ? elapsed : 1;
3810         pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
3811         rate = pass_exam / elapsed;
3812         rate = rate ? rate : 1;
3813         mins_left = ((total - examined) / rate) / 60;
3814         hours_left = mins_left / 60;
3815
3816         zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
3817         zfs_nicenum(total, total_buf, sizeof (total_buf));
3818         zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
3819
3820         /*
3821          * do not print estimated time if hours_left is more than 30 days
3822          */
3823         (void) printf(gettext("    %s scanned out of %s at %s/s"),
3824             examined_buf, total_buf, rate_buf);
3825         if (hours_left < (30 * 24)) {
3826                 (void) printf(gettext(", %lluh%um to go\n"),
3827                     (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
3828         } else {
3829                 (void) printf(gettext(
3830                     ", (scan is slow, no estimated time)\n"));
3831         }
3832
3833         if (ps->pss_func == POOL_SCAN_RESILVER) {
3834                 (void) printf(gettext("    %s resilvered, %.2f%% done\n"),
3835                     processed_buf, 100 * fraction_done);
3836         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
3837                 (void) printf(gettext("    %s repaired, %.2f%% done\n"),
3838                     processed_buf, 100 * fraction_done);
3839         }
3840 }
3841
3842 static void
3843 print_error_log(zpool_handle_t *zhp)
3844 {
3845         nvlist_t *nverrlist = NULL;
3846         nvpair_t *elem;
3847         char *pathname;
3848         size_t len = MAXPATHLEN * 2;
3849
3850         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
3851                 (void) printf("errors: List of errors unavailable "
3852                     "(insufficient privileges)\n");
3853                 return;
3854         }
3855
3856         (void) printf("errors: Permanent errors have been "
3857             "detected in the following files:\n\n");
3858
3859         pathname = safe_malloc(len);
3860         elem = NULL;
3861         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
3862                 nvlist_t *nv;
3863                 uint64_t dsobj, obj;
3864
3865                 verify(nvpair_value_nvlist(elem, &nv) == 0);
3866                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
3867                     &dsobj) == 0);
3868                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
3869                     &obj) == 0);
3870                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
3871                 (void) printf("%7s %s\n", "", pathname);
3872         }
3873         free(pathname);
3874         nvlist_free(nverrlist);
3875 }
3876
3877 static void
3878 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
3879     int namewidth)
3880 {
3881         uint_t i;
3882         char *name;
3883
3884         if (nspares == 0)
3885                 return;
3886
3887         (void) printf(gettext("\tspares\n"));
3888
3889         for (i = 0; i < nspares; i++) {
3890                 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
3891                 print_status_config(zhp, name, spares[i],
3892                     namewidth, 2, B_TRUE);
3893                 free(name);
3894         }
3895 }
3896
3897 static void
3898 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
3899     int namewidth)
3900 {
3901         uint_t i;
3902         char *name;
3903
3904         if (nl2cache == 0)
3905                 return;
3906
3907         (void) printf(gettext("\tcache\n"));
3908
3909         for (i = 0; i < nl2cache; i++) {
3910                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
3911                 print_status_config(zhp, name, l2cache[i],
3912                     namewidth, 2, B_FALSE);
3913                 free(name);
3914         }
3915 }
3916
3917 static void
3918 print_dedup_stats(nvlist_t *config)
3919 {
3920         ddt_histogram_t *ddh;
3921         ddt_stat_t *dds;
3922         ddt_object_t *ddo;
3923         uint_t c;
3924
3925         /*
3926          * If the pool was faulted then we may not have been able to
3927          * obtain the config. Otherwise, if we have anything in the dedup
3928          * table continue processing the stats.
3929          */
3930         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
3931             (uint64_t **)&ddo, &c) != 0)
3932                 return;
3933
3934         (void) printf("\n");
3935         (void) printf(gettext(" dedup: "));
3936         if (ddo->ddo_count == 0) {
3937                 (void) printf(gettext("no DDT entries\n"));
3938                 return;
3939         }
3940
3941         (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
3942             (u_longlong_t)ddo->ddo_count,
3943             (u_longlong_t)ddo->ddo_dspace,
3944             (u_longlong_t)ddo->ddo_mspace);
3945
3946         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
3947             (uint64_t **)&dds, &c) == 0);
3948         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
3949             (uint64_t **)&ddh, &c) == 0);
3950         zpool_dump_ddt(dds, ddh);
3951 }
3952
3953 /*
3954  * Display a summary of pool status.  Displays a summary such as:
3955  *
3956  *        pool: tank
3957  *      status: DEGRADED
3958  *      reason: One or more devices ...
3959  *         see: http://zfsonlinux.org/msg/ZFS-xxxx-01
3960  *      config:
3961  *              mirror          DEGRADED
3962  *                c1t0d0        OK
3963  *                c2t0d0        UNAVAIL
3964  *
3965  * When given the '-v' option, we print out the complete config.  If the '-e'
3966  * option is specified, then we print out error rate information as well.
3967  */
3968 int
3969 status_callback(zpool_handle_t *zhp, void *data)
3970 {
3971         status_cbdata_t *cbp = data;
3972         nvlist_t *config, *nvroot;
3973         char *msgid;
3974         int reason;
3975         const char *health;
3976         uint_t c;
3977         vdev_stat_t *vs;
3978
3979         config = zpool_get_config(zhp, NULL);
3980         reason = zpool_get_status(zhp, &msgid);
3981
3982         cbp->cb_count++;
3983
3984         /*
3985          * If we were given 'zpool status -x', only report those pools with
3986          * problems.
3987          */
3988         if (cbp->cb_explain &&
3989             (reason == ZPOOL_STATUS_OK ||
3990             reason == ZPOOL_STATUS_VERSION_OLDER ||
3991             reason == ZPOOL_STATUS_FEAT_DISABLED)) {
3992                 if (!cbp->cb_allpools) {
3993                         (void) printf(gettext("pool '%s' is healthy\n"),
3994                             zpool_get_name(zhp));
3995                         if (cbp->cb_first)
3996                                 cbp->cb_first = B_FALSE;
3997                 }
3998                 return (0);
3999         }
4000
4001         if (cbp->cb_first)
4002                 cbp->cb_first = B_FALSE;
4003         else
4004                 (void) printf("\n");
4005
4006         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4007             &nvroot) == 0);
4008         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
4009             (uint64_t **)&vs, &c) == 0);
4010         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
4011
4012         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
4013         (void) printf(gettext(" state: %s\n"), health);
4014
4015         switch (reason) {
4016         case ZPOOL_STATUS_MISSING_DEV_R:
4017                 (void) printf(gettext("status: One or more devices could not "
4018                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
4019                     "continue functioning in a degraded state.\n"));
4020                 (void) printf(gettext("action: Attach the missing device and "
4021                     "online it using 'zpool online'.\n"));
4022                 break;
4023
4024         case ZPOOL_STATUS_MISSING_DEV_NR:
4025                 (void) printf(gettext("status: One or more devices could not "
4026                     "be opened.  There are insufficient\n\treplicas for the "
4027                     "pool to continue functioning.\n"));
4028                 (void) printf(gettext("action: Attach the missing device and "
4029                     "online it using 'zpool online'.\n"));
4030                 break;
4031
4032         case ZPOOL_STATUS_CORRUPT_LABEL_R:
4033                 (void) printf(gettext("status: One or more devices could not "
4034                     "be used because the label is missing or\n\tinvalid.  "
4035                     "Sufficient replicas exist for the pool to continue\n\t"
4036                     "functioning in a degraded state.\n"));
4037                 (void) printf(gettext("action: Replace the device using "
4038                     "'zpool replace'.\n"));
4039                 break;
4040
4041         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
4042                 (void) printf(gettext("status: One or more devices could not "
4043                     "be used because the label is missing \n\tor invalid.  "
4044                     "There are insufficient replicas for the pool to "
4045                     "continue\n\tfunctioning.\n"));
4046                 zpool_explain_recover(zpool_get_handle(zhp),
4047                     zpool_get_name(zhp), reason, config);
4048                 break;
4049
4050         case ZPOOL_STATUS_FAILING_DEV:
4051                 (void) printf(gettext("status: One or more devices has "
4052                     "experienced an unrecoverable error.  An\n\tattempt was "
4053                     "made to correct the error.  Applications are "
4054                     "unaffected.\n"));
4055                 (void) printf(gettext("action: Determine if the device needs "
4056                     "to be replaced, and clear the errors\n\tusing "
4057                     "'zpool clear' or replace the device with 'zpool "
4058                     "replace'.\n"));
4059                 break;
4060
4061         case ZPOOL_STATUS_OFFLINE_DEV:
4062                 (void) printf(gettext("status: One or more devices has "
4063                     "been taken offline by the administrator.\n\tSufficient "
4064                     "replicas exist for the pool to continue functioning in "
4065                     "a\n\tdegraded state.\n"));
4066                 (void) printf(gettext("action: Online the device using "
4067                     "'zpool online' or replace the device with\n\t'zpool "
4068                     "replace'.\n"));
4069                 break;
4070
4071         case ZPOOL_STATUS_REMOVED_DEV:
4072                 (void) printf(gettext("status: One or more devices has "
4073                     "been removed by the administrator.\n\tSufficient "
4074                     "replicas exist for the pool to continue functioning in "
4075                     "a\n\tdegraded state.\n"));
4076                 (void) printf(gettext("action: Online the device using "
4077                     "'zpool online' or replace the device with\n\t'zpool "
4078                     "replace'.\n"));
4079                 break;
4080
4081         case ZPOOL_STATUS_RESILVERING:
4082                 (void) printf(gettext("status: One or more devices is "
4083                     "currently being resilvered.  The pool will\n\tcontinue "
4084                     "to function, possibly in a degraded state.\n"));
4085                 (void) printf(gettext("action: Wait for the resilver to "
4086                     "complete.\n"));
4087                 break;
4088
4089         case ZPOOL_STATUS_CORRUPT_DATA:
4090                 (void) printf(gettext("status: One or more devices has "
4091                     "experienced an error resulting in data\n\tcorruption.  "
4092                     "Applications may be affected.\n"));
4093                 (void) printf(gettext("action: Restore the file in question "
4094                     "if possible.  Otherwise restore the\n\tentire pool from "
4095                     "backup.\n"));
4096                 break;
4097
4098         case ZPOOL_STATUS_CORRUPT_POOL:
4099                 (void) printf(gettext("status: The pool metadata is corrupted "
4100                     "and the pool cannot be opened.\n"));
4101                 zpool_explain_recover(zpool_get_handle(zhp),
4102                     zpool_get_name(zhp), reason, config);
4103                 break;
4104
4105         case ZPOOL_STATUS_VERSION_OLDER:
4106                 (void) printf(gettext("status: The pool is formatted using a "
4107                     "legacy on-disk format.  The pool can\n\tstill be used, "
4108                     "but some features are unavailable.\n"));
4109                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
4110                     "upgrade'.  Once this is done, the\n\tpool will no longer "
4111                     "be accessible on software that does not support\n\t"
4112                     "feature flags.\n"));
4113                 break;
4114
4115         case ZPOOL_STATUS_VERSION_NEWER:
4116                 (void) printf(gettext("status: The pool has been upgraded to a "
4117                     "newer, incompatible on-disk version.\n\tThe pool cannot "
4118                     "be accessed on this system.\n"));
4119                 (void) printf(gettext("action: Access the pool from a system "
4120                     "running more recent software, or\n\trestore the pool from "
4121                     "backup.\n"));
4122                 break;
4123
4124         case ZPOOL_STATUS_FEAT_DISABLED:
4125                 (void) printf(gettext("status: Some supported features are not "
4126                     "enabled on the pool. The pool can\n\tstill be used, but "
4127                     "some features are unavailable.\n"));
4128                 (void) printf(gettext("action: Enable all features using "
4129                     "'zpool upgrade'. Once this is done,\n\tthe pool may no "
4130                     "longer be accessible by software that does not support\n\t"
4131                     "the features. See zpool-features(5) for details.\n"));
4132                 break;
4133
4134         case ZPOOL_STATUS_UNSUP_FEAT_READ:
4135                 (void) printf(gettext("status: The pool cannot be accessed on "
4136                     "this system because it uses the\n\tfollowing feature(s) "
4137                     "not supported on this system:\n"));
4138                 zpool_print_unsup_feat(config);
4139                 (void) printf("\n");
4140                 (void) printf(gettext("action: Access the pool from a system "
4141                     "that supports the required feature(s),\n\tor restore the "
4142                     "pool from backup.\n"));
4143                 break;
4144
4145         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4146                 (void) printf(gettext("status: The pool can only be accessed "
4147                     "in read-only mode on this system. It\n\tcannot be "
4148                     "accessed in read-write mode because it uses the "
4149                     "following\n\tfeature(s) not supported on this system:\n"));
4150                 zpool_print_unsup_feat(config);
4151                 (void) printf("\n");
4152                 (void) printf(gettext("action: The pool cannot be accessed in "
4153                     "read-write mode. Import the pool with\n"
4154                     "\t\"-o readonly=on\", access the pool from a system that "
4155                     "supports the\n\trequired feature(s), or restore the "
4156                     "pool from backup.\n"));
4157                 break;
4158
4159         case ZPOOL_STATUS_FAULTED_DEV_R:
4160                 (void) printf(gettext("status: One or more devices are "
4161                     "faulted in response to persistent errors.\n\tSufficient "
4162                     "replicas exist for the pool to continue functioning "
4163                     "in a\n\tdegraded state.\n"));
4164                 (void) printf(gettext("action: Replace the faulted device, "
4165                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4166                 break;
4167
4168         case ZPOOL_STATUS_FAULTED_DEV_NR:
4169                 (void) printf(gettext("status: One or more devices are "
4170                     "faulted in response to persistent errors.  There are "
4171                     "insufficient replicas for the pool to\n\tcontinue "
4172                     "functioning.\n"));
4173                 (void) printf(gettext("action: Destroy and re-create the pool "
4174                     "from a backup source.  Manually marking the device\n"
4175                     "\trepaired using 'zpool clear' may allow some data "
4176                     "to be recovered.\n"));
4177                 break;
4178
4179         case ZPOOL_STATUS_IO_FAILURE_WAIT:
4180         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
4181                 (void) printf(gettext("status: One or more devices are "
4182                     "faulted in response to IO failures.\n"));
4183                 (void) printf(gettext("action: Make sure the affected devices "
4184                     "are connected, then run 'zpool clear'.\n"));
4185                 break;
4186
4187         case ZPOOL_STATUS_BAD_LOG:
4188                 (void) printf(gettext("status: An intent log record "
4189                     "could not be read.\n"
4190                     "\tWaiting for adminstrator intervention to fix the "
4191                     "faulted pool.\n"));
4192                 (void) printf(gettext("action: Either restore the affected "
4193                     "device(s) and run 'zpool online',\n"
4194                     "\tor ignore the intent log records by running "
4195                     "'zpool clear'.\n"));
4196                 break;
4197
4198         default:
4199                 /*
4200                  * The remaining errors can't actually be generated, yet.
4201                  */
4202                 assert(reason == ZPOOL_STATUS_OK);
4203         }
4204
4205         if (msgid != NULL)
4206                 (void) printf(gettext("   see: http://zfsonlinux.org/msg/%s\n"),
4207                     msgid);
4208
4209         if (config != NULL) {
4210                 int namewidth;
4211                 uint64_t nerr;
4212                 nvlist_t **spares, **l2cache;
4213                 uint_t nspares, nl2cache;
4214                 pool_scan_stat_t *ps = NULL;
4215
4216                 (void) nvlist_lookup_uint64_array(nvroot,
4217                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
4218                 print_scan_status(ps);
4219
4220                 namewidth = max_width(zhp, nvroot, 0, 0);
4221                 if (namewidth < 10)
4222                         namewidth = 10;
4223
4224                 (void) printf(gettext("config:\n\n"));
4225                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
4226                     "NAME", "STATE", "READ", "WRITE", "CKSUM");
4227                 print_status_config(zhp, zpool_get_name(zhp), nvroot,
4228                     namewidth, 0, B_FALSE);
4229
4230                 if (num_logs(nvroot) > 0)
4231                         print_logs(zhp, nvroot, namewidth, B_TRUE);
4232                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
4233                     &l2cache, &nl2cache) == 0)
4234                         print_l2cache(zhp, l2cache, nl2cache, namewidth);
4235
4236                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
4237                     &spares, &nspares) == 0)
4238                         print_spares(zhp, spares, nspares, namewidth);
4239
4240                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
4241                     &nerr) == 0) {
4242                         nvlist_t *nverrlist = NULL;
4243
4244                         /*
4245                          * If the approximate error count is small, get a
4246                          * precise count by fetching the entire log and
4247                          * uniquifying the results.
4248                          */
4249                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
4250                             zpool_get_errlog(zhp, &nverrlist) == 0) {
4251                                 nvpair_t *elem;
4252
4253                                 elem = NULL;
4254                                 nerr = 0;
4255                                 while ((elem = nvlist_next_nvpair(nverrlist,
4256                                     elem)) != NULL) {
4257                                         nerr++;
4258                                 }
4259                         }
4260                         nvlist_free(nverrlist);
4261
4262                         (void) printf("\n");
4263
4264                         if (nerr == 0)
4265                                 (void) printf(gettext("errors: No known data "
4266                                     "errors\n"));
4267                         else if (!cbp->cb_verbose)
4268                                 (void) printf(gettext("errors: %llu data "
4269                                     "errors, use '-v' for a list\n"),
4270                                     (u_longlong_t)nerr);
4271                         else
4272                                 print_error_log(zhp);
4273                 }
4274
4275                 if (cbp->cb_dedup_stats)
4276                         print_dedup_stats(config);
4277         } else {
4278                 (void) printf(gettext("config: The configuration cannot be "
4279                     "determined.\n"));
4280         }
4281
4282         return (0);
4283 }
4284
4285 /*
4286  * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
4287  *
4288  *      -v      Display complete error logs
4289  *      -x      Display only pools with potential problems
4290  *      -D      Display dedup status (undocumented)
4291  *      -T      Display a timestamp in date(1) or Unix format
4292  *
4293  * Describes the health status of all pools or some subset.
4294  */
4295 int
4296 zpool_do_status(int argc, char **argv)
4297 {
4298         int c;
4299         int ret;
4300         unsigned long interval = 0, count = 0;
4301         status_cbdata_t cb = { 0 };
4302
4303         /* check options */
4304         while ((c = getopt(argc, argv, "vxDT:")) != -1) {
4305                 switch (c) {
4306                 case 'v':
4307                         cb.cb_verbose = B_TRUE;
4308                         break;
4309                 case 'x':
4310                         cb.cb_explain = B_TRUE;
4311                         break;
4312                 case 'D':
4313                         cb.cb_dedup_stats = B_TRUE;
4314                         break;
4315                 case 'T':
4316                         get_timestamp_arg(*optarg);
4317                         break;
4318                 case '?':
4319                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4320                             optopt);
4321                         usage(B_FALSE);
4322                 }
4323         }
4324
4325         argc -= optind;
4326         argv += optind;
4327
4328         get_interval_count(&argc, argv, &interval, &count);
4329
4330         if (argc == 0)
4331                 cb.cb_allpools = B_TRUE;
4332
4333         cb.cb_first = B_TRUE;
4334
4335         for (;;) {
4336                 if (timestamp_fmt != NODATE)
4337                         print_timestamp(timestamp_fmt);
4338
4339                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
4340                     status_callback, &cb);
4341
4342                 if (argc == 0 && cb.cb_count == 0)
4343                         (void) fprintf(stderr, gettext("no pools available\n"));
4344                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
4345                         (void) printf(gettext("all pools are healthy\n"));
4346
4347                 if (ret != 0)
4348                         return (ret);
4349
4350                 if (interval == 0)
4351                         break;
4352
4353                 if (count != 0 && --count == 0)
4354                         break;
4355
4356                 (void) sleep(interval);
4357         }
4358
4359         return (0);
4360 }
4361
4362 typedef struct upgrade_cbdata {
4363         int     cb_first;
4364         int     cb_argc;
4365         uint64_t cb_version;
4366         char    **cb_argv;
4367 } upgrade_cbdata_t;
4368
4369 static int
4370 upgrade_version(zpool_handle_t *zhp, uint64_t version)
4371 {
4372         int ret;
4373         nvlist_t *config;
4374         uint64_t oldversion;
4375
4376         config = zpool_get_config(zhp, NULL);
4377         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4378             &oldversion) == 0);
4379
4380         assert(SPA_VERSION_IS_SUPPORTED(oldversion));
4381         assert(oldversion < version);
4382
4383         ret = zpool_upgrade(zhp, version);
4384         if (ret != 0)
4385                 return (ret);
4386
4387         if (version >= SPA_VERSION_FEATURES) {
4388                 (void) printf(gettext("Successfully upgraded "
4389                     "'%s' from version %llu to feature flags.\n"),
4390                     zpool_get_name(zhp), (u_longlong_t) oldversion);
4391         } else {
4392                 (void) printf(gettext("Successfully upgraded "
4393                     "'%s' from version %llu to version %llu.\n"),
4394                     zpool_get_name(zhp), (u_longlong_t) oldversion,
4395                     (u_longlong_t) version);
4396         }
4397
4398         return (0);
4399 }
4400
4401 static int
4402 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
4403 {
4404         int i, ret, count;
4405         boolean_t firstff = B_TRUE;
4406         nvlist_t *enabled = zpool_get_features(zhp);
4407
4408         count = 0;
4409         for (i = 0; i < SPA_FEATURES; i++) {
4410                 const char *fname = spa_feature_table[i].fi_uname;
4411                 const char *fguid = spa_feature_table[i].fi_guid;
4412                 if (!nvlist_exists(enabled, fguid)) {
4413                         char *propname;
4414                         verify(-1 != asprintf(&propname, "feature@%s", fname));
4415                         ret = zpool_set_prop(zhp, propname,
4416                             ZFS_FEATURE_ENABLED);
4417                         if (ret != 0) {
4418                                 free(propname);
4419                                 return (ret);
4420                         }
4421                         count++;
4422
4423                         if (firstff) {
4424                                 (void) printf(gettext("Enabled the "
4425                                     "following features on '%s':\n"),
4426                                     zpool_get_name(zhp));
4427                                 firstff = B_FALSE;
4428                         }
4429                         (void) printf(gettext("  %s\n"), fname);
4430                         free(propname);
4431                 }
4432         }
4433
4434         if (countp != NULL)
4435                 *countp = count;
4436         return (0);
4437 }
4438
4439 static int
4440 upgrade_cb(zpool_handle_t *zhp, void *arg)
4441 {
4442         upgrade_cbdata_t *cbp = arg;
4443         nvlist_t *config;
4444         uint64_t version;
4445         boolean_t printnl = B_FALSE;
4446         int ret;
4447
4448         config = zpool_get_config(zhp, NULL);
4449         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4450             &version) == 0);
4451
4452         assert(SPA_VERSION_IS_SUPPORTED(version));
4453
4454         if (version < cbp->cb_version) {
4455                 cbp->cb_first = B_FALSE;
4456                 ret = upgrade_version(zhp, cbp->cb_version);
4457                 if (ret != 0)
4458                         return (ret);
4459                 printnl = B_TRUE;
4460
4461 #if 0
4462                 /*
4463                  * XXX: This code can be enabled when Illumos commit
4464                  * 4445fffbbb1ea25fd0e9ea68b9380dd7a6709025 is merged.
4465                  * It reworks the history logging among other things.
4466                  */
4467
4468                 /*
4469                  * If they did "zpool upgrade -a", then we could
4470                  * be doing ioctls to different pools.  We need
4471                  * to log this history once to each pool, and bypass
4472                  * the normal history logging that happens in main().
4473                  */
4474                 (void) zpool_log_history(g_zfs, history_str);
4475                 log_history = B_FALSE;
4476 #endif
4477         }
4478
4479         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4480                 int count;
4481                 ret = upgrade_enable_all(zhp, &count);
4482                 if (ret != 0)
4483                         return (ret);
4484
4485                 if (count > 0) {
4486                         cbp->cb_first = B_FALSE;
4487                         printnl = B_TRUE;
4488                 }
4489         }
4490
4491         if (printnl) {
4492                 (void) printf(gettext("\n"));
4493         }
4494
4495         return (0);
4496 }
4497
4498 static int
4499 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
4500 {
4501         upgrade_cbdata_t *cbp = arg;
4502         nvlist_t *config;
4503         uint64_t version;
4504
4505         config = zpool_get_config(zhp, NULL);
4506         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4507             &version) == 0);
4508
4509         assert(SPA_VERSION_IS_SUPPORTED(version));
4510
4511         if (version < SPA_VERSION_FEATURES) {
4512                 if (cbp->cb_first) {
4513                         (void) printf(gettext("The following pools are "
4514                             "formatted with legacy version numbers and can\n"
4515                             "be upgraded to use feature flags.  After "
4516                             "being upgraded, these pools\nwill no "
4517                             "longer be accessible by software that does not "
4518                             "support feature\nflags.\n\n"));
4519                         (void) printf(gettext("VER  POOL\n"));
4520                         (void) printf(gettext("---  ------------\n"));
4521                         cbp->cb_first = B_FALSE;
4522                 }
4523
4524                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
4525                     zpool_get_name(zhp));
4526         }
4527
4528         return (0);
4529 }
4530
4531 static int
4532 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
4533 {
4534         upgrade_cbdata_t *cbp = arg;
4535         nvlist_t *config;
4536         uint64_t version;
4537
4538         config = zpool_get_config(zhp, NULL);
4539         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4540             &version) == 0);
4541
4542         if (version >= SPA_VERSION_FEATURES) {
4543                 int i;
4544                 boolean_t poolfirst = B_TRUE;
4545                 nvlist_t *enabled = zpool_get_features(zhp);
4546
4547                 for (i = 0; i < SPA_FEATURES; i++) {
4548                         const char *fguid = spa_feature_table[i].fi_guid;
4549                         const char *fname = spa_feature_table[i].fi_uname;
4550                         if (!nvlist_exists(enabled, fguid)) {
4551                                 if (cbp->cb_first) {
4552                                         (void) printf(gettext("\nSome "
4553                                             "supported features are not "
4554                                             "enabled on the following pools. "
4555                                             "Once a\nfeature is enabled the "
4556                                             "pool may become incompatible with "
4557                                             "software\nthat does not support "
4558                                             "the feature. See "
4559                                             "zpool-features(5) for "
4560                                             "details.\n\n"));
4561                                         (void) printf(gettext("POOL  "
4562                                             "FEATURE\n"));
4563                                         (void) printf(gettext("------"
4564                                             "---------\n"));
4565                                         cbp->cb_first = B_FALSE;
4566                                 }
4567
4568                                 if (poolfirst) {
4569                                         (void) printf(gettext("%s\n"),
4570                                             zpool_get_name(zhp));
4571                                         poolfirst = B_FALSE;
4572                                 }
4573
4574                                 (void) printf(gettext("      %s\n"), fname);
4575                         }
4576                 }
4577         }
4578
4579         return (0);
4580 }
4581
4582 /* ARGSUSED */
4583 static int
4584 upgrade_one(zpool_handle_t *zhp, void *data)
4585 {
4586         boolean_t printnl = B_FALSE;
4587         upgrade_cbdata_t *cbp = data;
4588         uint64_t cur_version;
4589         int ret;
4590
4591         if (strcmp("log", zpool_get_name(zhp)) == 0) {
4592                 (void) printf(gettext("'log' is now a reserved word\n"
4593                     "Pool 'log' must be renamed using export and import"
4594                     " to upgrade.\n"));
4595                 return (1);
4596         }
4597
4598         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
4599         if (cur_version > cbp->cb_version) {
4600                 (void) printf(gettext("Pool '%s' is already formatted "
4601                     "using more current version '%llu'.\n\n"),
4602                     zpool_get_name(zhp), (u_longlong_t) cur_version);
4603                 return (0);
4604         }
4605
4606         if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
4607                 (void) printf(gettext("Pool '%s' is already formatted "
4608                     "using version %llu.\n\n"), zpool_get_name(zhp),
4609                     (u_longlong_t) cbp->cb_version);
4610                 return (0);
4611         }
4612
4613         if (cur_version != cbp->cb_version) {
4614                 printnl = B_TRUE;
4615                 ret = upgrade_version(zhp, cbp->cb_version);
4616                 if (ret != 0)
4617                         return (ret);
4618         }
4619
4620         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4621                 int count = 0;
4622                 ret = upgrade_enable_all(zhp, &count);
4623                 if (ret != 0)
4624                         return (ret);
4625
4626                 if (count != 0) {
4627                         printnl = B_TRUE;
4628                 } else if (cur_version == SPA_VERSION) {
4629                         (void) printf(gettext("Pool '%s' already has all "
4630                             "supported features enabled.\n"),
4631                             zpool_get_name(zhp));
4632                 }
4633         }
4634
4635         if (printnl) {
4636                 (void) printf(gettext("\n"));
4637         }
4638
4639         return (0);
4640 }
4641
4642 /*
4643  * zpool upgrade
4644  * zpool upgrade -v
4645  * zpool upgrade [-V version] <-a | pool ...>
4646  *
4647  * With no arguments, display downrev'd ZFS pool available for upgrade.
4648  * Individual pools can be upgraded by specifying the pool, and '-a' will
4649  * upgrade all pools.
4650  */
4651 int
4652 zpool_do_upgrade(int argc, char **argv)
4653 {
4654         int c;
4655         upgrade_cbdata_t cb = { 0 };
4656         int ret = 0;
4657         boolean_t showversions = B_FALSE;
4658         boolean_t upgradeall = B_FALSE;
4659         char *end;
4660
4661
4662         /* check options */
4663         while ((c = getopt(argc, argv, ":avV:")) != -1) {
4664                 switch (c) {
4665                 case 'a':
4666                         upgradeall = B_TRUE;
4667                         break;
4668                 case 'v':
4669                         showversions = B_TRUE;
4670                         break;
4671                 case 'V':
4672                         cb.cb_version = strtoll(optarg, &end, 10);
4673                         if (*end != '\0' ||
4674                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
4675                                 (void) fprintf(stderr,
4676                                     gettext("invalid version '%s'\n"), optarg);
4677                                 usage(B_FALSE);
4678                         }
4679                         break;
4680                 case ':':
4681                         (void) fprintf(stderr, gettext("missing argument for "
4682                             "'%c' option\n"), optopt);
4683                         usage(B_FALSE);
4684                         break;
4685                 case '?':
4686                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4687                             optopt);
4688                         usage(B_FALSE);
4689                 }
4690         }
4691
4692         cb.cb_argc = argc;
4693         cb.cb_argv = argv;
4694         argc -= optind;
4695         argv += optind;
4696
4697         if (cb.cb_version == 0) {
4698                 cb.cb_version = SPA_VERSION;
4699         } else if (!upgradeall && argc == 0) {
4700                 (void) fprintf(stderr, gettext("-V option is "
4701                     "incompatible with other arguments\n"));
4702                 usage(B_FALSE);
4703         }
4704
4705         if (showversions) {
4706                 if (upgradeall || argc != 0) {
4707                         (void) fprintf(stderr, gettext("-v option is "
4708                             "incompatible with other arguments\n"));
4709                         usage(B_FALSE);
4710                 }
4711         } else if (upgradeall) {
4712                 if (argc != 0) {
4713                         (void) fprintf(stderr, gettext("-a option should not "
4714                             "be used along with a pool name\n"));
4715                         usage(B_FALSE);
4716                 }
4717         }
4718
4719         (void) printf(gettext("This system supports ZFS pool feature "
4720             "flags.\n\n"));
4721         if (showversions) {
4722                 int i;
4723
4724                 (void) printf(gettext("The following features are "
4725                     "supported:\n\n"));
4726                 (void) printf(gettext("FEAT DESCRIPTION\n"));
4727                 (void) printf("----------------------------------------------"
4728                     "---------------\n");
4729                 for (i = 0; i < SPA_FEATURES; i++) {
4730                         zfeature_info_t *fi = &spa_feature_table[i];
4731                         const char *ro = fi->fi_can_readonly ?
4732                             " (read-only compatible)" : "";
4733
4734                         (void) printf("%-37s%s\n", fi->fi_uname, ro);
4735                         (void) printf("     %s\n", fi->fi_desc);
4736                 }
4737                 (void) printf("\n");
4738
4739                 (void) printf(gettext("The following legacy versions are also "
4740                     "supported:\n\n"));
4741                 (void) printf(gettext("VER  DESCRIPTION\n"));
4742                 (void) printf("---  -----------------------------------------"
4743                     "---------------\n");
4744                 (void) printf(gettext(" 1   Initial ZFS version\n"));
4745                 (void) printf(gettext(" 2   Ditto blocks "
4746                     "(replicated metadata)\n"));
4747                 (void) printf(gettext(" 3   Hot spares and double parity "
4748                     "RAID-Z\n"));
4749                 (void) printf(gettext(" 4   zpool history\n"));
4750                 (void) printf(gettext(" 5   Compression using the gzip "
4751                     "algorithm\n"));
4752                 (void) printf(gettext(" 6   bootfs pool property\n"));
4753                 (void) printf(gettext(" 7   Separate intent log devices\n"));
4754                 (void) printf(gettext(" 8   Delegated administration\n"));
4755                 (void) printf(gettext(" 9   refquota and refreservation "
4756                     "properties\n"));
4757                 (void) printf(gettext(" 10  Cache devices\n"));
4758                 (void) printf(gettext(" 11  Improved scrub performance\n"));
4759                 (void) printf(gettext(" 12  Snapshot properties\n"));
4760                 (void) printf(gettext(" 13  snapused property\n"));
4761                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
4762                 (void) printf(gettext(" 15  user/group space accounting\n"));
4763                 (void) printf(gettext(" 16  stmf property support\n"));
4764                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
4765                 (void) printf(gettext(" 18  Snapshot user holds\n"));
4766                 (void) printf(gettext(" 19  Log device removal\n"));
4767                 (void) printf(gettext(" 20  Compression using zle "
4768                     "(zero-length encoding)\n"));
4769                 (void) printf(gettext(" 21  Deduplication\n"));
4770                 (void) printf(gettext(" 22  Received properties\n"));
4771                 (void) printf(gettext(" 23  Slim ZIL\n"));
4772                 (void) printf(gettext(" 24  System attributes\n"));
4773                 (void) printf(gettext(" 25  Improved scrub stats\n"));
4774                 (void) printf(gettext(" 26  Improved snapshot deletion "
4775                     "performance\n"));
4776                 (void) printf(gettext(" 27  Improved snapshot creation "
4777                     "performance\n"));
4778                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
4779                 (void) printf(gettext("\nFor more information on a particular "
4780                     "version, including supported releases,\n"));
4781                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
4782         } else if (argc == 0 && upgradeall) {
4783                 cb.cb_first = B_TRUE;
4784                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
4785                 if (ret == 0 && cb.cb_first) {
4786                         if (cb.cb_version == SPA_VERSION) {
4787                                 (void) printf(gettext("All pools are already "
4788                                     "formatted using feature flags.\n\n"));
4789                                 (void) printf(gettext("Every feature flags "
4790                                     "pool already has all supported features "
4791                                     "enabled.\n"));
4792                         } else {
4793                                 (void) printf(gettext("All pools are already "
4794                                     "formatted with version %llu or higher.\n"),
4795                                     (u_longlong_t) cb.cb_version);
4796                         }
4797                 }
4798         } else if (argc == 0) {
4799                 cb.cb_first = B_TRUE;
4800                 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
4801                 assert(ret == 0);
4802
4803                 if (cb.cb_first) {
4804                         (void) printf(gettext("All pools are formatted "
4805                             "using feature flags.\n\n"));
4806                 } else {
4807                         (void) printf(gettext("\nUse 'zpool upgrade -v' "
4808                             "for a list of available legacy versions.\n"));
4809                 }
4810
4811                 cb.cb_first = B_TRUE;
4812                 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
4813                 assert(ret == 0);
4814
4815                 if (cb.cb_first) {
4816                         (void) printf(gettext("Every feature flags pool has "
4817                             "all supported features enabled.\n"));
4818                 } else {
4819                         (void) printf(gettext("\n"));
4820                 }
4821         } else {
4822                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
4823                     upgrade_one, &cb);
4824         }
4825
4826         return (ret);
4827 }
4828
4829 typedef struct hist_cbdata {
4830         boolean_t first;
4831         int longfmt;
4832         int internal;
4833 } hist_cbdata_t;
4834
4835 /*
4836  * Print out the command history for a specific pool.
4837  */
4838 static int
4839 get_history_one(zpool_handle_t *zhp, void *data)
4840 {
4841         nvlist_t *nvhis;
4842         nvlist_t **records;
4843         uint_t numrecords;
4844         char *cmdstr;
4845         char *pathstr;
4846         uint64_t dst_time;
4847         time_t tsec;
4848         struct tm t;
4849         char tbuf[30];
4850         int ret, i;
4851         uint64_t who;
4852         struct passwd *pwd;
4853         char *hostname;
4854         char *zonename;
4855         char internalstr[MAXPATHLEN];
4856         hist_cbdata_t *cb = (hist_cbdata_t *)data;
4857         uint64_t txg;
4858         uint64_t ievent;
4859
4860         cb->first = B_FALSE;
4861
4862         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
4863
4864         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
4865                 return (ret);
4866
4867         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
4868             &records, &numrecords) == 0);
4869         for (i = 0; i < numrecords; i++) {
4870                 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
4871                     &dst_time) != 0)
4872                         continue;
4873
4874                 /* is it an internal event or a standard event? */
4875                 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
4876                     &cmdstr) != 0) {
4877                         if (cb->internal == 0)
4878                                 continue;
4879
4880                         if (nvlist_lookup_uint64(records[i],
4881                             ZPOOL_HIST_INT_EVENT, &ievent) != 0)
4882                                 continue;
4883                         verify(nvlist_lookup_uint64(records[i],
4884                             ZPOOL_HIST_TXG, &txg) == 0);
4885                         verify(nvlist_lookup_string(records[i],
4886                             ZPOOL_HIST_INT_STR, &pathstr) == 0);
4887                         if (ievent >= LOG_END)
4888                                 continue;
4889                         (void) snprintf(internalstr,
4890                             sizeof (internalstr),
4891                             "[internal %s txg:%llu] %s",
4892                             zfs_history_event_names[ievent], (u_longlong_t)txg,
4893                             pathstr);
4894                         cmdstr = internalstr;
4895                 }
4896                 tsec = dst_time;
4897                 (void) localtime_r(&tsec, &t);
4898                 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
4899                 (void) printf("%s %s", tbuf, cmdstr);
4900
4901                 if (!cb->longfmt) {
4902                         (void) printf("\n");
4903                         continue;
4904                 }
4905                 (void) printf(" [");
4906                 if (nvlist_lookup_uint64(records[i],
4907                     ZPOOL_HIST_WHO, &who) == 0) {
4908                         pwd = getpwuid((uid_t)who);
4909                         if (pwd)
4910                                 (void) printf("user %s on",
4911                                     pwd->pw_name);
4912                         else
4913                                 (void) printf("user %d on",
4914                                     (int)who);
4915                 } else {
4916                         (void) printf(gettext("no info]\n"));
4917                         continue;
4918                 }
4919                 if (nvlist_lookup_string(records[i],
4920                     ZPOOL_HIST_HOST, &hostname) == 0) {
4921                         (void) printf(" %s", hostname);
4922                 }
4923                 if (nvlist_lookup_string(records[i],
4924                     ZPOOL_HIST_ZONE, &zonename) == 0) {
4925                         (void) printf(":%s", zonename);
4926                 }
4927
4928                 (void) printf("]");
4929                 (void) printf("\n");
4930         }
4931         (void) printf("\n");
4932         nvlist_free(nvhis);
4933
4934         return (ret);
4935 }
4936
4937 /*
4938  * zpool history <pool>
4939  *
4940  * Displays the history of commands that modified pools.
4941  */
4942
4943
4944 int
4945 zpool_do_history(int argc, char **argv)
4946 {
4947         hist_cbdata_t cbdata = { 0 };
4948         int ret;
4949         int c;
4950
4951         cbdata.first = B_TRUE;
4952         /* check options */
4953         while ((c = getopt(argc, argv, "li")) != -1) {
4954                 switch (c) {
4955                 case 'l':
4956                         cbdata.longfmt = 1;
4957                         break;
4958                 case 'i':
4959                         cbdata.internal = 1;
4960                         break;
4961                 case '?':
4962                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4963                             optopt);
4964                         usage(B_FALSE);
4965                 }
4966         }
4967         argc -= optind;
4968         argv += optind;
4969
4970         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
4971             &cbdata);
4972
4973         if (argc == 0 && cbdata.first == B_TRUE) {
4974                 (void) fprintf(stderr, gettext("no pools available\n"));
4975                 return (0);
4976         }
4977
4978         return (ret);
4979 }
4980
4981 typedef struct ev_opts {
4982         int verbose;
4983         int scripted;
4984         int follow;
4985         int clear;
4986 } ev_opts_t;
4987
4988 static void
4989 zpool_do_events_short(nvlist_t *nvl)
4990 {
4991         char ctime_str[26], str[32], *ptr;
4992         int64_t *tv;
4993         uint_t n;
4994
4995         verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
4996         memset(str, ' ', 32);
4997         (void) ctime_r((const time_t *)&tv[0], ctime_str);
4998         (void) strncpy(str,    ctime_str+4,  6);             /* 'Jun 30'     */
4999         (void) strncpy(str+7,  ctime_str+20, 4);             /* '1993'       */
5000         (void) strncpy(str+12, ctime_str+11, 8);             /* '21:49:08'   */
5001         (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]);/* '.123456789' */
5002         (void) printf(gettext("%s "), str);
5003
5004         verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0);
5005         (void) printf(gettext("%s\n"), ptr);
5006 }
5007
5008 static void
5009 zpool_do_events_nvprint(nvlist_t *nvl, int depth)
5010 {
5011         nvpair_t *nvp;
5012
5013         for (nvp = nvlist_next_nvpair(nvl, NULL);
5014             nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
5015
5016                 data_type_t type = nvpair_type(nvp);
5017                 const char *name = nvpair_name(nvp);
5018
5019                 boolean_t b;
5020                 uint8_t i8;
5021                 uint16_t i16;
5022                 uint32_t i32;
5023                 uint64_t i64;
5024                 char *str;
5025                 nvlist_t *cnv;
5026
5027                 printf(gettext("%*s%s = "), depth, "", name);
5028
5029                 switch (type) {
5030                 case DATA_TYPE_BOOLEAN:
5031                         printf(gettext("%s"), "1");
5032                         break;
5033
5034                 case DATA_TYPE_BOOLEAN_VALUE:
5035                         (void) nvpair_value_boolean_value(nvp, &b);
5036                         printf(gettext("%s"), b ? "1" : "0");
5037                         break;
5038
5039                 case DATA_TYPE_BYTE:
5040                         (void) nvpair_value_byte(nvp, &i8);
5041                         printf(gettext("0x%x"), i8);
5042                         break;
5043
5044                 case DATA_TYPE_INT8:
5045                         (void) nvpair_value_int8(nvp, (void *)&i8);
5046                         printf(gettext("0x%x"), i8);
5047                         break;
5048
5049                 case DATA_TYPE_UINT8:
5050                         (void) nvpair_value_uint8(nvp, &i8);
5051                         printf(gettext("0x%x"), i8);
5052                         break;
5053
5054                 case DATA_TYPE_INT16:
5055                         (void) nvpair_value_int16(nvp, (void *)&i16);
5056                         printf(gettext("0x%x"), i16);
5057                         break;
5058
5059                 case DATA_TYPE_UINT16:
5060                         (void) nvpair_value_uint16(nvp, &i16);
5061                         printf(gettext("0x%x"), i16);
5062                         break;
5063
5064                 case DATA_TYPE_INT32:
5065                         (void) nvpair_value_int32(nvp, (void *)&i32);
5066                         printf(gettext("0x%x"), i32);
5067                         break;
5068
5069                 case DATA_TYPE_UINT32:
5070                         (void) nvpair_value_uint32(nvp, &i32);
5071                         printf(gettext("0x%x"), i32);
5072                         break;
5073
5074                 case DATA_TYPE_INT64:
5075                         (void) nvpair_value_int64(nvp, (void *)&i64);
5076                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5077                         break;
5078
5079                 case DATA_TYPE_UINT64:
5080                         (void) nvpair_value_uint64(nvp, &i64);
5081                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5082                         break;
5083
5084                 case DATA_TYPE_HRTIME:
5085                         (void) nvpair_value_hrtime(nvp, (void *)&i64);
5086                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5087                         break;
5088
5089                 case DATA_TYPE_STRING:
5090                         (void) nvpair_value_string(nvp, &str);
5091                         printf(gettext("\"%s\""), str ? str : "<NULL>");
5092                         break;
5093
5094                 case DATA_TYPE_NVLIST:
5095                         printf(gettext("(embedded nvlist)\n"));
5096                         (void) nvpair_value_nvlist(nvp, &cnv);
5097                         zpool_do_events_nvprint(cnv, depth + 8);
5098                         printf(gettext("%*s(end %s)"), depth, "", name);
5099                         break;
5100
5101                 case DATA_TYPE_NVLIST_ARRAY: {
5102                         nvlist_t **val;
5103                         uint_t i, nelem;
5104
5105                         (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
5106                         printf(gettext("(%d embedded nvlists)\n"), nelem);
5107                         for (i = 0; i < nelem; i++) {
5108                                 printf(gettext("%*s%s[%d] = %s\n"),
5109                                        depth, "", name, i, "(embedded nvlist)");
5110                                 zpool_do_events_nvprint(val[i], depth + 8);
5111                                 printf(gettext("%*s(end %s[%i])\n"),
5112                                        depth, "", name, i);
5113                         }
5114                         printf(gettext("%*s(end %s)\n"), depth, "", name);
5115                         }
5116                         break;
5117
5118                 case DATA_TYPE_INT8_ARRAY: {
5119                         int8_t *val;
5120                         uint_t i, nelem;
5121
5122                         (void) nvpair_value_int8_array(nvp, &val, &nelem);
5123                         for (i = 0; i < nelem; i++)
5124                                 printf(gettext("0x%x "), val[i]);
5125
5126                         break;
5127                         }
5128
5129                 case DATA_TYPE_UINT8_ARRAY: {
5130                         uint8_t *val;
5131                         uint_t i, nelem;
5132
5133                         (void) nvpair_value_uint8_array(nvp, &val, &nelem);
5134                         for (i = 0; i < nelem; i++)
5135                                 printf(gettext("0x%x "), val[i]);
5136
5137                         break;
5138                         }
5139
5140                 case DATA_TYPE_INT16_ARRAY: {
5141                         int16_t *val;
5142                         uint_t i, nelem;
5143
5144                         (void) nvpair_value_int16_array(nvp, &val, &nelem);
5145                         for (i = 0; i < nelem; i++)
5146                                 printf(gettext("0x%x "), val[i]);
5147
5148                         break;
5149                         }
5150
5151                 case DATA_TYPE_UINT16_ARRAY: {
5152                         uint16_t *val;
5153                         uint_t i, nelem;
5154
5155                         (void) nvpair_value_uint16_array(nvp, &val, &nelem);
5156                         for (i = 0; i < nelem; i++)
5157                                 printf(gettext("0x%x "), val[i]);
5158
5159                         break;
5160                         }
5161
5162                 case DATA_TYPE_INT32_ARRAY: {
5163                         int32_t *val;
5164                         uint_t i, nelem;
5165
5166                         (void) nvpair_value_int32_array(nvp, &val, &nelem);
5167                         for (i = 0; i < nelem; i++)
5168                                 printf(gettext("0x%x "), val[i]);
5169
5170                         break;
5171                         }
5172
5173                 case DATA_TYPE_UINT32_ARRAY: {
5174                         uint32_t *val;
5175                         uint_t i, nelem;
5176
5177                         (void) nvpair_value_uint32_array(nvp, &val, &nelem);
5178                         for (i = 0; i < nelem; i++)
5179                                 printf(gettext("0x%x "), val[i]);
5180
5181                         break;
5182                         }
5183
5184                 case DATA_TYPE_INT64_ARRAY: {
5185                         int64_t *val;
5186                         uint_t i, nelem;
5187
5188                         (void) nvpair_value_int64_array(nvp, &val, &nelem);
5189                         for (i = 0; i < nelem; i++)
5190                                 printf(gettext("0x%llx "), (u_longlong_t)val[i]);
5191
5192                         break;
5193                         }
5194
5195                 case DATA_TYPE_UINT64_ARRAY: {
5196                         uint64_t *val;
5197                         uint_t i, nelem;
5198
5199                         (void) nvpair_value_uint64_array(nvp, &val, &nelem);
5200                         for (i = 0; i < nelem; i++)
5201                                 printf(gettext("0x%llx "), (u_longlong_t)val[i]);
5202
5203                         break;
5204                         }
5205
5206                 case DATA_TYPE_STRING_ARRAY:
5207                 case DATA_TYPE_BOOLEAN_ARRAY:
5208                 case DATA_TYPE_BYTE_ARRAY:
5209                 case DATA_TYPE_DOUBLE:
5210                 case DATA_TYPE_UNKNOWN:
5211                         printf(gettext("<unknown>"));
5212                         break;
5213                 }
5214
5215                 printf(gettext("\n"));
5216         }
5217 }
5218
5219 static int
5220 zpool_do_events_next(ev_opts_t *opts)
5221 {
5222         nvlist_t *nvl;
5223         int cleanup_fd, ret, dropped;
5224
5225         cleanup_fd = open(ZFS_DEV, O_RDWR);
5226         VERIFY(cleanup_fd >= 0);
5227
5228         if (!opts->scripted)
5229                 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
5230
5231         while (1) {
5232                 ret = zpool_events_next(g_zfs, &nvl, &dropped,
5233                     !!opts->follow, cleanup_fd);
5234                 if (ret || nvl == NULL)
5235                         break;
5236
5237                 if (dropped > 0)
5238                         (void) printf(gettext("dropped %d events\n"), dropped);
5239
5240                 zpool_do_events_short(nvl);
5241
5242                 if (opts->verbose) {
5243                         zpool_do_events_nvprint(nvl, 8);
5244                         printf(gettext("\n"));
5245                 }
5246                 (void) fflush(stdout);
5247
5248                 nvlist_free(nvl);
5249         }
5250
5251         VERIFY(0 == close(cleanup_fd));
5252
5253         return (ret);
5254 }
5255
5256 static int
5257 zpool_do_events_clear(ev_opts_t *opts)
5258 {
5259         int count, ret;
5260
5261         ret = zpool_events_clear(g_zfs, &count);
5262         if (!ret)
5263                 (void) printf(gettext("cleared %d events\n"), count);
5264
5265         return (ret);
5266 }
5267
5268 /*
5269  * zpool events [-vfc]
5270  *
5271  * Displays events logs by ZFS.
5272  */
5273 int
5274 zpool_do_events(int argc, char **argv)
5275 {
5276         ev_opts_t opts = { 0 };
5277         int ret;
5278         int c;
5279
5280         /* check options */
5281         while ((c = getopt(argc, argv, "vHfc")) != -1) {
5282                 switch (c) {
5283                 case 'v':
5284                         opts.verbose = 1;
5285                         break;
5286                 case 'H':
5287                         opts.scripted = 1;
5288                         break;
5289                 case 'f':
5290                         opts.follow = 1;
5291                         break;
5292                 case 'c':
5293                         opts.clear = 1;
5294                         break;
5295                 case '?':
5296                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5297                             optopt);
5298                         usage(B_FALSE);
5299                 }
5300         }
5301         argc -= optind;
5302         argv += optind;
5303
5304         if (opts.clear)
5305                 ret = zpool_do_events_clear(&opts);
5306         else
5307                 ret = zpool_do_events_next(&opts);
5308
5309         return ret;
5310 }
5311
5312 static int
5313 get_callback(zpool_handle_t *zhp, void *data)
5314 {
5315         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
5316         char value[MAXNAMELEN];
5317         zprop_source_t srctype;
5318         zprop_list_t *pl;
5319
5320         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
5321
5322                 /*
5323                  * Skip the special fake placeholder. This will also skip
5324                  * over the name property when 'all' is specified.
5325                  */
5326                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
5327                     pl == cbp->cb_proplist)
5328                         continue;
5329
5330                 if (pl->pl_prop == ZPROP_INVAL &&
5331                     (zpool_prop_feature(pl->pl_user_prop) ||
5332                     zpool_prop_unsupported(pl->pl_user_prop))) {
5333                         srctype = ZPROP_SRC_LOCAL;
5334
5335                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
5336                             value, sizeof (value)) == 0) {
5337                                 zprop_print_one_property(zpool_get_name(zhp),
5338                                     cbp, pl->pl_user_prop, value, srctype,
5339                                     NULL, NULL);
5340                         }
5341                 } else {
5342                         if (zpool_get_prop(zhp, pl->pl_prop, value,
5343                             sizeof (value), &srctype) != 0)
5344                                 continue;
5345
5346                         zprop_print_one_property(zpool_get_name(zhp), cbp,
5347                             zpool_prop_to_name(pl->pl_prop), value, srctype,
5348                             NULL, NULL);
5349                 }
5350         }
5351         return (0);
5352 }
5353
5354 int
5355 zpool_do_get(int argc, char **argv)
5356 {
5357         zprop_get_cbdata_t cb = { 0 };
5358         zprop_list_t fake_name = { 0 };
5359         int ret;
5360
5361         if (argc < 2) {
5362                 (void) fprintf(stderr, gettext("missing property "
5363                     "argument\n"));
5364                 usage(B_FALSE);
5365         }
5366
5367         cb.cb_first = B_TRUE;
5368         cb.cb_sources = ZPROP_SRC_ALL;
5369         cb.cb_columns[0] = GET_COL_NAME;
5370         cb.cb_columns[1] = GET_COL_PROPERTY;
5371         cb.cb_columns[2] = GET_COL_VALUE;
5372         cb.cb_columns[3] = GET_COL_SOURCE;
5373         cb.cb_type = ZFS_TYPE_POOL;
5374
5375         if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
5376             ZFS_TYPE_POOL) != 0)
5377                 usage(B_FALSE);
5378
5379         if (cb.cb_proplist != NULL) {
5380                 fake_name.pl_prop = ZPOOL_PROP_NAME;
5381                 fake_name.pl_width = strlen(gettext("NAME"));
5382                 fake_name.pl_next = cb.cb_proplist;
5383                 cb.cb_proplist = &fake_name;
5384         }
5385
5386         ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
5387             get_callback, &cb);
5388
5389         if (cb.cb_proplist == &fake_name)
5390                 zprop_free_list(fake_name.pl_next);
5391         else
5392                 zprop_free_list(cb.cb_proplist);
5393
5394         return (ret);
5395 }
5396
5397 typedef struct set_cbdata {
5398         char *cb_propname;
5399         char *cb_value;
5400         boolean_t cb_any_successful;
5401 } set_cbdata_t;
5402
5403 int
5404 set_callback(zpool_handle_t *zhp, void *data)
5405 {
5406         int error;
5407         set_cbdata_t *cb = (set_cbdata_t *)data;
5408
5409         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
5410
5411         if (!error)
5412                 cb->cb_any_successful = B_TRUE;
5413
5414         return (error);
5415 }
5416
5417 int
5418 zpool_do_set(int argc, char **argv)
5419 {
5420         set_cbdata_t cb = { 0 };
5421         int error;
5422
5423         if (argc > 1 && argv[1][0] == '-') {
5424                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5425                     argv[1][1]);
5426                 usage(B_FALSE);
5427         }
5428
5429         if (argc < 2) {
5430                 (void) fprintf(stderr, gettext("missing property=value "
5431                     "argument\n"));
5432                 usage(B_FALSE);
5433         }
5434
5435         if (argc < 3) {
5436                 (void) fprintf(stderr, gettext("missing pool name\n"));
5437                 usage(B_FALSE);
5438         }
5439
5440         if (argc > 3) {
5441                 (void) fprintf(stderr, gettext("too many pool names\n"));
5442                 usage(B_FALSE);
5443         }
5444
5445         cb.cb_propname = argv[1];
5446         cb.cb_value = strchr(cb.cb_propname, '=');
5447         if (cb.cb_value == NULL) {
5448                 (void) fprintf(stderr, gettext("missing value in "
5449                     "property=value argument\n"));
5450                 usage(B_FALSE);
5451         }
5452
5453         *(cb.cb_value) = '\0';
5454         cb.cb_value++;
5455
5456         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
5457             set_callback, &cb);
5458
5459         return (error);
5460 }
5461
5462 static int
5463 find_command_idx(char *command, int *idx)
5464 {
5465         int i;
5466
5467         for (i = 0; i < NCOMMAND; i++) {
5468                 if (command_table[i].name == NULL)
5469                         continue;
5470
5471                 if (strcmp(command, command_table[i].name) == 0) {
5472                         *idx = i;
5473                         return (0);
5474                 }
5475         }
5476         return (1);
5477 }
5478
5479 int
5480 main(int argc, char **argv)
5481 {
5482         int ret;
5483         int i = 0;
5484         char *cmdname;
5485
5486         (void) setlocale(LC_ALL, "");
5487         (void) textdomain(TEXT_DOMAIN);
5488
5489         opterr = 0;
5490
5491         /*
5492          * Make sure the user has specified some command.
5493          */
5494         if (argc < 2) {
5495                 (void) fprintf(stderr, gettext("missing command\n"));
5496                 usage(B_FALSE);
5497         }
5498
5499         cmdname = argv[1];
5500
5501         /*
5502          * Special case '-?'
5503          */
5504         if ((strcmp(cmdname, "-?") == 0) ||
5505              strcmp(cmdname, "--help") == 0)
5506                 usage(B_TRUE);
5507
5508         if ((g_zfs = libzfs_init()) == NULL)
5509                 return (1);
5510
5511         libzfs_print_on_error(g_zfs, B_TRUE);
5512
5513         zpool_set_history_str("zpool", argc, argv, history_str);
5514         verify(zpool_stage_history(g_zfs, history_str) == 0);
5515
5516         /*
5517          * Run the appropriate command.
5518          */
5519         if (find_command_idx(cmdname, &i) == 0) {
5520                 current_command = &command_table[i];
5521                 ret = command_table[i].func(argc - 1, argv + 1);
5522         } else if (strchr(cmdname, '=')) {
5523                 verify(find_command_idx("set", &i) == 0);
5524                 current_command = &command_table[i];
5525                 ret = command_table[i].func(argc, argv);
5526         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
5527                 /*
5528                  * 'freeze' is a vile debugging abomination, so we treat
5529                  * it as such.
5530                  */
5531                 char buf[16384];
5532                 int fd = open(ZFS_DEV, O_RDWR);
5533                 (void) strcpy((void *)buf, argv[2]);
5534                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
5535         } else {
5536                 (void) fprintf(stderr, gettext("unrecognized "
5537                     "command '%s'\n"), cmdname);
5538                 usage(B_FALSE);
5539                 ret = 1;
5540         }
5541
5542         libzfs_fini(g_zfs);
5543
5544         /*
5545          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
5546          * for the purposes of running ::findleaks.
5547          */
5548         if (getenv("ZFS_ABORT") != NULL) {
5549                 (void) printf("dumping core by request\n");
5550                 abort();
5551         }
5552
5553         return (ret);
5554 }