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