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