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