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