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