]> granicus.if.org Git - zfs/blob - cmd/zpool/zpool_main.c
Fix column alignment with long zpool names
[zfs] / cmd / zpool / zpool_main.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
26  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
27  * Copyright (c) 2012 by Cyril Plisko. All rights reserved.
28  * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
29  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
30  * Copyright (c) 2017 Datto Inc.
31  * 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 [-vHf [pool] | -c]\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, strlen(name),
2220             VDEV_NAME_TYPE_ID);
2221         if (cb.cb_namewidth < 10)
2222                 cb.cb_namewidth = 10;
2223
2224         print_import_config(&cb, name, nvroot, 0);
2225         if (num_logs(nvroot) > 0)
2226                 print_logs(NULL, &cb, nvroot);
2227
2228         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
2229                 (void) printf(gettext("\n\tAdditional devices are known to "
2230                     "be part of this pool, though their\n\texact "
2231                     "configuration cannot be determined.\n"));
2232         }
2233 }
2234
2235 static boolean_t
2236 zfs_force_import_required(nvlist_t *config)
2237 {
2238         uint64_t state;
2239         uint64_t hostid = 0;
2240         nvlist_t *nvinfo;
2241
2242         state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2243         (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
2244
2245         if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid())
2246                 return (B_TRUE);
2247
2248         nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2249         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) {
2250                 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo,
2251                     ZPOOL_CONFIG_MMP_STATE);
2252
2253                 if (mmp_state != MMP_STATE_INACTIVE)
2254                         return (B_TRUE);
2255         }
2256
2257         return (B_FALSE);
2258 }
2259
2260 /*
2261  * Perform the import for the given configuration.  This passes the heavy
2262  * lifting off to zpool_import_props(), and then mounts the datasets contained
2263  * within the pool.
2264  */
2265 static int
2266 do_import(nvlist_t *config, const char *newname, const char *mntopts,
2267     nvlist_t *props, int flags)
2268 {
2269         int ret = 0;
2270         zpool_handle_t *zhp;
2271         char *name;
2272         uint64_t state;
2273         uint64_t version;
2274
2275         name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2276         state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2277         version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2278
2279         if (!SPA_VERSION_IS_SUPPORTED(version)) {
2280                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
2281                     "is formatted using an unsupported ZFS version\n"), name);
2282                 return (1);
2283         } else if (zfs_force_import_required(config) &&
2284             !(flags & ZFS_IMPORT_ANY_HOST)) {
2285                 mmp_state_t mmp_state = MMP_STATE_INACTIVE;
2286                 nvlist_t *nvinfo;
2287
2288                 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2289                 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE))
2290                         mmp_state = fnvlist_lookup_uint64(nvinfo,
2291                             ZPOOL_CONFIG_MMP_STATE);
2292
2293                 if (mmp_state == MMP_STATE_ACTIVE) {
2294                         char *hostname = "<unknown>";
2295                         uint64_t hostid = 0;
2296
2297                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2298                                 hostname = fnvlist_lookup_string(nvinfo,
2299                                     ZPOOL_CONFIG_MMP_HOSTNAME);
2300
2301                         if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2302                                 hostid = fnvlist_lookup_uint64(nvinfo,
2303                                     ZPOOL_CONFIG_MMP_HOSTID);
2304
2305                         (void) fprintf(stderr, gettext("cannot import '%s': "
2306                             "pool is imported on %s (hostid: "
2307                             "0x%lx)\nExport the pool on the other system, "
2308                             "then run 'zpool import'.\n"),
2309                             name, hostname, (unsigned long) hostid);
2310                 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2311                         (void) fprintf(stderr, gettext("Cannot import '%s': "
2312                             "pool has the multihost property on and the\n"
2313                             "system's hostid is not set. Set a unique hostid "
2314                             "with the zgenhostid(8) command.\n"), name);
2315                 } else {
2316                         char *hostname = "<unknown>";
2317                         uint64_t timestamp = 0;
2318                         uint64_t hostid = 0;
2319
2320                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME))
2321                                 hostname = fnvlist_lookup_string(config,
2322                                     ZPOOL_CONFIG_HOSTNAME);
2323
2324                         if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP))
2325                                 timestamp = fnvlist_lookup_uint64(config,
2326                                     ZPOOL_CONFIG_TIMESTAMP);
2327
2328                         if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID))
2329                                 hostid = fnvlist_lookup_uint64(config,
2330                                     ZPOOL_CONFIG_HOSTID);
2331
2332                         (void) fprintf(stderr, gettext("cannot import '%s': "
2333                             "pool was previously in use from another system.\n"
2334                             "Last accessed by %s (hostid=%lx) at %s"
2335                             "The pool can be imported, use 'zpool import -f' "
2336                             "to import the pool.\n"), name, hostname,
2337                             (unsigned long)hostid, ctime((time_t *)&timestamp));
2338                 }
2339
2340                 return (1);
2341         }
2342
2343         if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2344                 return (1);
2345
2346         if (newname != NULL)
2347                 name = (char *)newname;
2348
2349         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2350                 return (1);
2351
2352         /*
2353          * Loading keys is best effort. We don't want to return immediately
2354          * if it fails but we do want to give the error to the caller.
2355          */
2356         if (flags & ZFS_IMPORT_LOAD_KEYS) {
2357                 ret = zfs_crypto_attempt_load_keys(g_zfs, name);
2358                 if (ret != 0)
2359                         ret = 1;
2360         }
2361
2362         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2363             !(flags & ZFS_IMPORT_ONLY) &&
2364             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2365                 zpool_close(zhp);
2366                 return (1);
2367         }
2368
2369         zpool_close(zhp);
2370         return (ret);
2371 }
2372
2373 /*
2374  * zpool import [-d dir] [-D]
2375  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
2376  *              [-d dir | -c cachefile] [-f] -a
2377  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
2378  *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
2379  *
2380  *       -c     Read pool information from a cachefile instead of searching
2381  *              devices.
2382  *
2383  *       -d     Scan in a specific directory, other than /dev/.  More than
2384  *              one directory can be specified using multiple '-d' options.
2385  *
2386  *       -D     Scan for previously destroyed pools or import all or only
2387  *              specified destroyed pools.
2388  *
2389  *       -R     Temporarily import the pool, with all mountpoints relative to
2390  *              the given root.  The pool will remain exported when the machine
2391  *              is rebooted.
2392  *
2393  *       -V     Import even in the presence of faulted vdevs.  This is an
2394  *              intentionally undocumented option for testing purposes, and
2395  *              treats the pool configuration as complete, leaving any bad
2396  *              vdevs in the FAULTED state. In other words, it does verbatim
2397  *              import.
2398  *
2399  *       -f     Force import, even if it appears that the pool is active.
2400  *
2401  *       -F     Attempt rewind if necessary.
2402  *
2403  *       -n     See if rewind would work, but don't actually rewind.
2404  *
2405  *       -N     Import the pool but don't mount datasets.
2406  *
2407  *       -T     Specify a starting txg to use for import. This option is
2408  *              intentionally undocumented option for testing purposes.
2409  *
2410  *       -a     Import all pools found.
2411  *
2412  *       -l     Load encryption keys while importing.
2413  *
2414  *       -o     Set property=value and/or temporary mount options (without '=').
2415  *
2416  *       -s     Scan using the default search path, the libblkid cache will
2417  *              not be consulted.
2418  *
2419  * The import command scans for pools to import, and import pools based on pool
2420  * name and GUID.  The pool can also be renamed as part of the import process.
2421  */
2422 int
2423 zpool_do_import(int argc, char **argv)
2424 {
2425         char **searchdirs = NULL;
2426         char *env, *envdup = NULL;
2427         int nsearch = 0;
2428         int c;
2429         int err = 0;
2430         nvlist_t *pools = NULL;
2431         boolean_t do_all = B_FALSE;
2432         boolean_t do_destroyed = B_FALSE;
2433         char *mntopts = NULL;
2434         nvpair_t *elem;
2435         nvlist_t *config;
2436         uint64_t searchguid = 0;
2437         char *searchname = NULL;
2438         char *propval;
2439         nvlist_t *found_config;
2440         nvlist_t *policy = NULL;
2441         nvlist_t *props = NULL;
2442         boolean_t first;
2443         int flags = ZFS_IMPORT_NORMAL;
2444         uint32_t rewind_policy = ZPOOL_NO_REWIND;
2445         boolean_t dryrun = B_FALSE;
2446         boolean_t do_rewind = B_FALSE;
2447         boolean_t xtreme_rewind = B_FALSE;
2448         boolean_t do_scan = B_FALSE;
2449         uint64_t pool_state, txg = -1ULL;
2450         char *cachefile = NULL;
2451         importargs_t idata = { 0 };
2452         char *endptr;
2453
2454         /* check options */
2455         while ((c = getopt(argc, argv, ":aCc:d:DEfFlmnNo:R:stT:VX")) != -1) {
2456                 switch (c) {
2457                 case 'a':
2458                         do_all = B_TRUE;
2459                         break;
2460                 case 'c':
2461                         cachefile = optarg;
2462                         break;
2463                 case 'd':
2464                         if (searchdirs == NULL) {
2465                                 searchdirs = safe_malloc(sizeof (char *));
2466                         } else {
2467                                 char **tmp = safe_malloc((nsearch + 1) *
2468                                     sizeof (char *));
2469                                 bcopy(searchdirs, tmp, nsearch *
2470                                     sizeof (char *));
2471                                 free(searchdirs);
2472                                 searchdirs = tmp;
2473                         }
2474                         searchdirs[nsearch++] = optarg;
2475                         break;
2476                 case 'D':
2477                         do_destroyed = B_TRUE;
2478                         break;
2479                 case 'f':
2480                         flags |= ZFS_IMPORT_ANY_HOST;
2481                         break;
2482                 case 'F':
2483                         do_rewind = B_TRUE;
2484                         break;
2485                 case 'l':
2486                         flags |= ZFS_IMPORT_LOAD_KEYS;
2487                         break;
2488                 case 'm':
2489                         flags |= ZFS_IMPORT_MISSING_LOG;
2490                         break;
2491                 case 'n':
2492                         dryrun = B_TRUE;
2493                         break;
2494                 case 'N':
2495                         flags |= ZFS_IMPORT_ONLY;
2496                         break;
2497                 case 'o':
2498                         if ((propval = strchr(optarg, '=')) != NULL) {
2499                                 *propval = '\0';
2500                                 propval++;
2501                                 if (add_prop_list(optarg, propval,
2502                                     &props, B_TRUE))
2503                                         goto error;
2504                         } else {
2505                                 mntopts = optarg;
2506                         }
2507                         break;
2508                 case 'R':
2509                         if (add_prop_list(zpool_prop_to_name(
2510                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2511                                 goto error;
2512                         if (add_prop_list_default(zpool_prop_to_name(
2513                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2514                                 goto error;
2515                         break;
2516                 case 's':
2517                         do_scan = B_TRUE;
2518                         break;
2519                 case 't':
2520                         flags |= ZFS_IMPORT_TEMP_NAME;
2521                         if (add_prop_list_default(zpool_prop_to_name(
2522                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2523                                 goto error;
2524                         break;
2525
2526                 case 'T':
2527                         errno = 0;
2528                         txg = strtoull(optarg, &endptr, 0);
2529                         if (errno != 0 || *endptr != '\0') {
2530                                 (void) fprintf(stderr,
2531                                     gettext("invalid txg value\n"));
2532                                 usage(B_FALSE);
2533                         }
2534                         rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2535                         break;
2536                 case 'V':
2537                         flags |= ZFS_IMPORT_VERBATIM;
2538                         break;
2539                 case 'X':
2540                         xtreme_rewind = B_TRUE;
2541                         break;
2542                 case ':':
2543                         (void) fprintf(stderr, gettext("missing argument for "
2544                             "'%c' option\n"), optopt);
2545                         usage(B_FALSE);
2546                         break;
2547                 case '?':
2548                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2549                             optopt);
2550                         usage(B_FALSE);
2551                 }
2552         }
2553
2554         argc -= optind;
2555         argv += optind;
2556
2557         if (cachefile && nsearch != 0) {
2558                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2559                 usage(B_FALSE);
2560         }
2561
2562         if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
2563                 (void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
2564                 usage(B_FALSE);
2565         }
2566
2567         if ((flags & ZFS_IMPORT_LOAD_KEYS) && !do_all && argc == 0) {
2568                 (void) fprintf(stderr, gettext("-l is only meaningful during "
2569                     "an import\n"));
2570                 usage(B_FALSE);
2571         }
2572
2573         if ((dryrun || xtreme_rewind) && !do_rewind) {
2574                 (void) fprintf(stderr,
2575                     gettext("-n or -X only meaningful with -F\n"));
2576                 usage(B_FALSE);
2577         }
2578         if (dryrun)
2579                 rewind_policy = ZPOOL_TRY_REWIND;
2580         else if (do_rewind)
2581                 rewind_policy = ZPOOL_DO_REWIND;
2582         if (xtreme_rewind)
2583                 rewind_policy |= ZPOOL_EXTREME_REWIND;
2584
2585         /* In the future, we can capture further policy and include it here */
2586         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2587             nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
2588             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
2589                 goto error;
2590
2591         /* check argument count */
2592         if (do_all) {
2593                 if (argc != 0) {
2594                         (void) fprintf(stderr, gettext("too many arguments\n"));
2595                         usage(B_FALSE);
2596                 }
2597         } else {
2598                 if (argc > 2) {
2599                         (void) fprintf(stderr, gettext("too many arguments\n"));
2600                         usage(B_FALSE);
2601                 }
2602         }
2603
2604         /*
2605          * Check for the effective uid.  We do this explicitly here because
2606          * otherwise any attempt to discover pools will silently fail.
2607          */
2608         if (argc == 0 && geteuid() != 0) {
2609                 (void) fprintf(stderr, gettext("cannot "
2610                     "discover pools: permission denied\n"));
2611                 if (searchdirs != NULL)
2612                         free(searchdirs);
2613
2614                 nvlist_free(props);
2615                 nvlist_free(policy);
2616                 return (1);
2617         }
2618
2619         /*
2620          * Depending on the arguments given, we do one of the following:
2621          *
2622          *      <none>  Iterate through all pools and display information about
2623          *              each one.
2624          *
2625          *      -a      Iterate through all pools and try to import each one.
2626          *
2627          *      <id>    Find the pool that corresponds to the given GUID/pool
2628          *              name and import that one.
2629          *
2630          *      -D      Above options applies only to destroyed pools.
2631          */
2632         if (argc != 0) {
2633                 char *endptr;
2634
2635                 errno = 0;
2636                 searchguid = strtoull(argv[0], &endptr, 10);
2637                 if (errno != 0 || *endptr != '\0') {
2638                         searchname = argv[0];
2639                         searchguid = 0;
2640                 }
2641                 found_config = NULL;
2642
2643                 /*
2644                  * User specified a name or guid.  Ensure it's unique.
2645                  */
2646                 idata.unique = B_TRUE;
2647         }
2648
2649         /*
2650          * Check the environment for the preferred search path.
2651          */
2652         if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) {
2653                 char *dir;
2654
2655                 envdup = strdup(env);
2656
2657                 dir = strtok(envdup, ":");
2658                 while (dir != NULL) {
2659                         if (searchdirs == NULL) {
2660                                 searchdirs = safe_malloc(sizeof (char *));
2661                         } else {
2662                                 char **tmp = safe_malloc((nsearch + 1) *
2663                                     sizeof (char *));
2664                                 bcopy(searchdirs, tmp, nsearch *
2665                                     sizeof (char *));
2666                                 free(searchdirs);
2667                                 searchdirs = tmp;
2668                         }
2669                         searchdirs[nsearch++] = dir;
2670                         dir = strtok(NULL, ":");
2671                 }
2672         }
2673
2674         idata.path = searchdirs;
2675         idata.paths = nsearch;
2676         idata.poolname = searchname;
2677         idata.guid = searchguid;
2678         idata.cachefile = cachefile;
2679         idata.scan = do_scan;
2680
2681         pools = zpool_search_import(g_zfs, &idata);
2682
2683         if (pools != NULL && idata.exists &&
2684             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2685                 (void) fprintf(stderr, gettext("cannot import '%s': "
2686                     "a pool with that name already exists\n"),
2687                     argv[0]);
2688                 (void) fprintf(stderr, gettext("use the form '%s "
2689                     "<pool | id> <newpool>' to give it a new name\n"),
2690                     "zpool import");
2691                 err = 1;
2692         } else if (pools == NULL && idata.exists) {
2693                 (void) fprintf(stderr, gettext("cannot import '%s': "
2694                     "a pool with that name is already created/imported,\n"),
2695                     argv[0]);
2696                 (void) fprintf(stderr, gettext("and no additional pools "
2697                     "with that name were found\n"));
2698                 err = 1;
2699         } else if (pools == NULL) {
2700                 if (argc != 0) {
2701                         (void) fprintf(stderr, gettext("cannot import '%s': "
2702                             "no such pool available\n"), argv[0]);
2703                 }
2704                 err = 1;
2705         }
2706
2707         if (err == 1) {
2708                 if (searchdirs != NULL)
2709                         free(searchdirs);
2710                 if (envdup != NULL)
2711                         free(envdup);
2712                 nvlist_free(policy);
2713                 nvlist_free(pools);
2714                 nvlist_free(props);
2715                 return (1);
2716         }
2717
2718         /*
2719          * At this point we have a list of import candidate configs. Even if
2720          * we were searching by pool name or guid, we still need to
2721          * post-process the list to deal with pool state and possible
2722          * duplicate names.
2723          */
2724         err = 0;
2725         elem = NULL;
2726         first = B_TRUE;
2727         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2728
2729                 verify(nvpair_value_nvlist(elem, &config) == 0);
2730
2731                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2732                     &pool_state) == 0);
2733                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2734                         continue;
2735                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2736                         continue;
2737
2738                 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
2739                     policy) == 0);
2740
2741                 if (argc == 0) {
2742                         if (first)
2743                                 first = B_FALSE;
2744                         else if (!do_all)
2745                                 (void) printf("\n");
2746
2747                         if (do_all) {
2748                                 err |= do_import(config, NULL, mntopts,
2749                                     props, flags);
2750                         } else {
2751                                 show_import(config);
2752                         }
2753                 } else if (searchname != NULL) {
2754                         char *name;
2755
2756                         /*
2757                          * We are searching for a pool based on name.
2758                          */
2759                         verify(nvlist_lookup_string(config,
2760                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2761
2762                         if (strcmp(name, searchname) == 0) {
2763                                 if (found_config != NULL) {
2764                                         (void) fprintf(stderr, gettext(
2765                                             "cannot import '%s': more than "
2766                                             "one matching pool\n"), searchname);
2767                                         (void) fprintf(stderr, gettext(
2768                                             "import by numeric ID instead\n"));
2769                                         err = B_TRUE;
2770                                 }
2771                                 found_config = config;
2772                         }
2773                 } else {
2774                         uint64_t guid;
2775
2776                         /*
2777                          * Search for a pool by guid.
2778                          */
2779                         verify(nvlist_lookup_uint64(config,
2780                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2781
2782                         if (guid == searchguid)
2783                                 found_config = config;
2784                 }
2785         }
2786
2787         /*
2788          * If we were searching for a specific pool, verify that we found a
2789          * pool, and then do the import.
2790          */
2791         if (argc != 0 && err == 0) {
2792                 if (found_config == NULL) {
2793                         (void) fprintf(stderr, gettext("cannot import '%s': "
2794                             "no such pool available\n"), argv[0]);
2795                         err = B_TRUE;
2796                 } else {
2797                         err |= do_import(found_config, argc == 1 ? NULL :
2798                             argv[1], mntopts, props, flags);
2799                 }
2800         }
2801
2802         /*
2803          * If we were just looking for pools, report an error if none were
2804          * found.
2805          */
2806         if (argc == 0 && first)
2807                 (void) fprintf(stderr,
2808                     gettext("no pools available to import\n"));
2809
2810 error:
2811         nvlist_free(props);
2812         nvlist_free(pools);
2813         nvlist_free(policy);
2814         if (searchdirs != NULL)
2815                 free(searchdirs);
2816         if (envdup != NULL)
2817                 free(envdup);
2818
2819         return (err ? 1 : 0);
2820 }
2821
2822 /*
2823  * zpool sync [-f] [pool] ...
2824  *
2825  * -f (undocumented) force uberblock (and config including zpool cache file)
2826  *    update.
2827  *
2828  * Sync the specified pool(s).
2829  * Without arguments "zpool sync" will sync all pools.
2830  * This command initiates TXG sync(s) and will return after the TXG(s) commit.
2831  *
2832  */
2833 static int
2834 zpool_do_sync(int argc, char **argv)
2835 {
2836         int ret;
2837         boolean_t force = B_FALSE;
2838
2839         /* check options */
2840         while ((ret  = getopt(argc, argv, "f")) != -1) {
2841                 switch (ret) {
2842                 case 'f':
2843                         force = B_TRUE;
2844                         break;
2845                 case '?':
2846                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2847                             optopt);
2848                         usage(B_FALSE);
2849                 }
2850         }
2851
2852         argc -= optind;
2853         argv += optind;
2854
2855         /* if argc == 0 we will execute zpool_sync_one on all pools */
2856         ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
2857
2858         return (ret);
2859 }
2860
2861 typedef struct iostat_cbdata {
2862         uint64_t cb_flags;
2863         int cb_name_flags;
2864         int cb_namewidth;
2865         int cb_iteration;
2866         char **cb_vdev_names; /* Only show these vdevs */
2867         unsigned int cb_vdev_names_count;
2868         boolean_t cb_verbose;
2869         boolean_t cb_literal;
2870         boolean_t cb_scripted;
2871         zpool_list_t *cb_list;
2872         vdev_cmd_data_list_t *vcdl;
2873 } iostat_cbdata_t;
2874
2875 /*  iostat labels */
2876 typedef struct name_and_columns {
2877         const char *name;       /* Column name */
2878         unsigned int columns;   /* Center name to this number of columns */
2879 } name_and_columns_t;
2880
2881 #define IOSTAT_MAX_LABELS       11      /* Max number of labels on one line */
2882
2883 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] =
2884 {
2885         [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2},
2886             {NULL}},
2887         [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
2888             {"asyncq_wait", 2}, {"scrub"}},
2889         [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2},
2890             {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2},
2891             {NULL}},
2892         [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2},
2893             {"sync_queue", 2}, {"async_queue", 2}, {NULL}},
2894         [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2},
2895             {"async_read", 2}, {"async_write", 2}, {"scrub", 2}, {NULL}},
2896
2897 };
2898
2899 /* Shorthand - if "columns" field not set, default to 1 column */
2900 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] =
2901 {
2902         [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"},
2903             {"write"}, {NULL}},
2904         [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
2905             {"write"}, {"read"}, {"write"}, {"wait"}, {NULL}},
2906         [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"},
2907             {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, {NULL}},
2908         [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
2909             {"write"}, {"read"}, {"write"}, {"scrub"}, {NULL}},
2910         [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"},
2911             {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}},
2912 };
2913
2914 static const char *histo_to_title[] = {
2915         [IOS_L_HISTO] = "latency",
2916         [IOS_RQ_HISTO] = "req_size",
2917 };
2918
2919 /*
2920  * Return the number of labels in a null-terminated name_and_columns_t
2921  * array.
2922  *
2923  */
2924 static unsigned int
2925 label_array_len(const name_and_columns_t *labels)
2926 {
2927         int i = 0;
2928
2929         while (labels[i].name)
2930                 i++;
2931
2932         return (i);
2933 }
2934
2935 /*
2936  * Return the number of strings in a null-terminated string array.
2937  * For example:
2938  *
2939  *     const char foo[] = {"bar", "baz", NULL}
2940  *
2941  * returns 2
2942  */
2943 static uint64_t
2944 str_array_len(const char *array[])
2945 {
2946         uint64_t i = 0;
2947         while (array[i])
2948                 i++;
2949
2950         return (i);
2951 }
2952
2953
2954 /*
2955  * Return a default column width for default/latency/queue columns. This does
2956  * not include histograms, which have their columns autosized.
2957  */
2958 static unsigned int
2959 default_column_width(iostat_cbdata_t *cb, enum iostat_type type)
2960 {
2961         unsigned long column_width = 5; /* Normal niceprint */
2962         static unsigned long widths[] = {
2963                 /*
2964                  * Choose some sane default column sizes for printing the
2965                  * raw numbers.
2966                  */
2967                 [IOS_DEFAULT] = 15, /* 1PB capacity */
2968                 [IOS_LATENCY] = 10, /* 1B ns = 10sec */
2969                 [IOS_QUEUES] = 6,   /* 1M queue entries */
2970         };
2971
2972         if (cb->cb_literal)
2973                 column_width = widths[type];
2974
2975         return (column_width);
2976 }
2977
2978 /*
2979  * Print the column labels, i.e:
2980  *
2981  *   capacity     operations     bandwidth
2982  * alloc   free   read  write   read  write  ...
2983  *
2984  * If force_column_width is set, use it for the column width.  If not set, use
2985  * the default column width.
2986  */
2987 void
2988 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width,
2989     const name_and_columns_t labels[][IOSTAT_MAX_LABELS])
2990 {
2991         int i, idx, s;
2992         unsigned int text_start, rw_column_width, spaces_to_end;
2993         uint64_t flags = cb->cb_flags;
2994         uint64_t f;
2995         unsigned int column_width = force_column_width;
2996
2997         /* For each bit set in flags */
2998         for (f = flags; f; f &= ~(1ULL << idx)) {
2999                 idx = lowbit64(f) - 1;
3000                 if (!force_column_width)
3001                         column_width = default_column_width(cb, idx);
3002                 /* Print our top labels centered over "read  write" label. */
3003                 for (i = 0; i < label_array_len(labels[idx]); i++) {
3004                         const char *name = labels[idx][i].name;
3005                         /*
3006                          * We treat labels[][].columns == 0 as shorthand
3007                          * for one column.  It makes writing out the label
3008                          * tables more concise.
3009                          */
3010                         unsigned int columns = MAX(1, labels[idx][i].columns);
3011                         unsigned int slen = strlen(name);
3012
3013                         rw_column_width = (column_width * columns) +
3014                             (2 * (columns - 1));
3015
3016                         text_start = (int)((rw_column_width)/columns -
3017                             slen/columns);
3018
3019                         printf("  ");   /* Two spaces between columns */
3020
3021                         /* Space from beginning of column to label */
3022                         for (s = 0; s < text_start; s++)
3023                                 printf(" ");
3024
3025                         printf("%s", name);
3026
3027                         /* Print space after label to end of column */
3028                         spaces_to_end = rw_column_width - text_start - slen;
3029                         for (s = 0; s < spaces_to_end; s++)
3030                                 printf(" ");
3031
3032                 }
3033         }
3034 }
3035
3036
3037 /*
3038  * print_cmd_columns - Print custom column titles from -c
3039  *
3040  * If the user specified the "zpool status|iostat -c" then print their custom
3041  * column titles in the header.  For example, print_cmd_columns() would print
3042  * the "  col1  col2" part of this:
3043  *
3044  * $ zpool iostat -vc 'echo col1=val1; echo col2=val2'
3045  * ...
3046  *            capacity     operations     bandwidth
3047  * pool        alloc   free   read  write   read  write  col1  col2
3048  * ----------  -----  -----  -----  -----  -----  -----  ----  ----
3049  * mypool       269K  1008M      0      0    107    946
3050  *   mirror     269K  1008M      0      0    107    946
3051  *     sdb         -      -      0      0    102    473  val1  val2
3052  *     sdc         -      -      0      0      5    473  val1  val2
3053  * ----------  -----  -----  -----  -----  -----  -----  ----  ----
3054  */
3055 void
3056 print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes)
3057 {
3058         int i, j;
3059         vdev_cmd_data_t *data = &vcdl->data[0];
3060
3061         if (vcdl->count == 0 || data == NULL)
3062                 return;
3063
3064         /*
3065          * Each vdev cmd should have the same column names unless the user did
3066          * something weird with their cmd.  Just take the column names from the
3067          * first vdev and assume it works for all of them.
3068          */
3069         for (i = 0; i < vcdl->uniq_cols_cnt; i++) {
3070                 printf("  ");
3071                 if (use_dashes) {
3072                         for (j = 0; j < vcdl->uniq_cols_width[i]; j++)
3073                                 printf("-");
3074                 } else {
3075                         printf("%*s", vcdl->uniq_cols_width[i],
3076                             vcdl->uniq_cols[i]);
3077                 }
3078         }
3079 }
3080
3081
3082 /*
3083  * Utility function to print out a line of dashes like:
3084  *
3085  *      --------------------------------  -----  -----  -----  -----  -----
3086  *
3087  * ...or a dashed named-row line like:
3088  *
3089  *      logs                                  -      -      -      -      -
3090  *
3091  * @cb:                         iostat data
3092  *
3093  * @force_column_width          If non-zero, use the value as the column width.
3094  *                              Otherwise use the default column widths.
3095  *
3096  * @name:                       Print a dashed named-row line starting
3097  *                              with @name.  Otherwise, print a regular
3098  *                              dashed line.
3099  */
3100 static void
3101 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width,
3102     const char *name)
3103 {
3104         int i;
3105         unsigned int namewidth;
3106         uint64_t flags = cb->cb_flags;
3107         uint64_t f;
3108         int idx;
3109         const name_and_columns_t *labels;
3110         const char *title;
3111
3112
3113         if (cb->cb_flags & IOS_ANYHISTO_M) {
3114                 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3115         } else if (cb->cb_vdev_names_count) {
3116                 title = "vdev";
3117         } else  {
3118                 title = "pool";
3119         }
3120
3121         namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3122             name ? strlen(name) : 0);
3123
3124
3125         if (name) {
3126                 printf("%-*s", namewidth, name);
3127         } else {
3128                 for (i = 0; i < namewidth; i++)
3129                         (void) printf("-");
3130         }
3131
3132         /* For each bit in flags */
3133         for (f = flags; f; f &= ~(1ULL << idx)) {
3134                 unsigned int column_width;
3135                 idx = lowbit64(f) - 1;
3136                 if (force_column_width)
3137                         column_width = force_column_width;
3138                 else
3139                         column_width = default_column_width(cb, idx);
3140
3141                 labels = iostat_bottom_labels[idx];
3142                 for (i = 0; i < label_array_len(labels); i++) {
3143                         if (name)
3144                                 printf("  %*s-", column_width - 1, " ");
3145                         else
3146                                 printf("  %.*s", column_width,
3147                                     "--------------------");
3148                 }
3149         }
3150 }
3151
3152
3153 static void
3154 print_iostat_separator_impl(iostat_cbdata_t *cb,
3155     unsigned int force_column_width)
3156 {
3157         print_iostat_dashes(cb, force_column_width, NULL);
3158 }
3159
3160 static void
3161 print_iostat_separator(iostat_cbdata_t *cb)
3162 {
3163         print_iostat_separator_impl(cb, 0);
3164 }
3165
3166 static void
3167 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
3168     const char *histo_vdev_name)
3169 {
3170         unsigned int namewidth;
3171         const char *title;
3172
3173         if (cb->cb_flags & IOS_ANYHISTO_M) {
3174                 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3175         } else if (cb->cb_vdev_names_count) {
3176                 title = "vdev";
3177         } else  {
3178                 title = "pool";
3179         }
3180
3181         namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3182             histo_vdev_name ? strlen(histo_vdev_name) : 0);
3183
3184         if (histo_vdev_name)
3185                 printf("%-*s", namewidth, histo_vdev_name);
3186         else
3187                 printf("%*s", namewidth, "");
3188
3189
3190         print_iostat_labels(cb, force_column_width, iostat_top_labels);
3191         printf("\n");
3192
3193         printf("%-*s", namewidth, title);
3194
3195         print_iostat_labels(cb, force_column_width, iostat_bottom_labels);
3196         if (cb->vcdl != NULL)
3197                 print_cmd_columns(cb->vcdl, 0);
3198
3199         printf("\n");
3200
3201         print_iostat_separator_impl(cb, force_column_width);
3202
3203         if (cb->vcdl != NULL)
3204                 print_cmd_columns(cb->vcdl, 1);
3205
3206         printf("\n");
3207 }
3208
3209 static void
3210 print_iostat_header(iostat_cbdata_t *cb)
3211 {
3212         print_iostat_header_impl(cb, 0, NULL);
3213 }
3214
3215
3216 /*
3217  * Display a single statistic.
3218  */
3219 static void
3220 print_one_stat(uint64_t value, enum zfs_nicenum_format format,
3221     unsigned int column_size, boolean_t scripted)
3222 {
3223         char buf[64];
3224
3225         zfs_nicenum_format(value, buf, sizeof (buf), format);
3226
3227         if (scripted)
3228                 printf("\t%s", buf);
3229         else
3230                 printf("  %*s", column_size, buf);
3231 }
3232
3233 /*
3234  * Calculate the default vdev stats
3235  *
3236  * Subtract oldvs from newvs, apply a scaling factor, and save the resulting
3237  * stats into calcvs.
3238  */
3239 static void
3240 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs,
3241     vdev_stat_t *calcvs)
3242 {
3243         int i;
3244
3245         memcpy(calcvs, newvs, sizeof (*calcvs));
3246         for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++)
3247                 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]);
3248
3249         for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++)
3250                 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]);
3251 }
3252
3253 /*
3254  * Internal representation of the extended iostats data.
3255  *
3256  * The extended iostat stats are exported in nvlists as either uint64_t arrays
3257  * or single uint64_t's.  We make both look like arrays to make them easier
3258  * to process.  In order to make single uint64_t's look like arrays, we set
3259  * __data to the stat data, and then set *data = &__data with count = 1.  Then,
3260  * we can just use *data and count.
3261  */
3262 struct stat_array {
3263         uint64_t *data;
3264         uint_t count;   /* Number of entries in data[] */
3265         uint64_t __data; /* Only used when data is a single uint64_t */
3266 };
3267
3268 static uint64_t
3269 stat_histo_max(struct stat_array *nva, unsigned int len)
3270 {
3271         uint64_t max = 0;
3272         int i;
3273         for (i = 0; i < len; i++)
3274                 max = MAX(max, array64_max(nva[i].data, nva[i].count));
3275
3276         return (max);
3277 }
3278
3279 /*
3280  * Helper function to lookup a uint64_t array or uint64_t value and store its
3281  * data as a stat_array.  If the nvpair is a single uint64_t value, then we make
3282  * it look like a one element array to make it easier to process.
3283  */
3284 static int
3285 nvpair64_to_stat_array(nvlist_t *nvl, const char *name,
3286     struct stat_array *nva)
3287 {
3288         nvpair_t *tmp;
3289         int ret;
3290
3291         verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0);
3292         switch (nvpair_type(tmp)) {
3293         case DATA_TYPE_UINT64_ARRAY:
3294                 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count);
3295                 break;
3296         case DATA_TYPE_UINT64:
3297                 ret = nvpair_value_uint64(tmp, &nva->__data);
3298                 nva->data = &nva->__data;
3299                 nva->count = 1;
3300                 break;
3301         default:
3302                 /* Not a uint64_t */
3303                 ret = EINVAL;
3304                 break;
3305         }
3306
3307         return (ret);
3308 }
3309
3310 /*
3311  * Given a list of nvlist names, look up the extended stats in newnv and oldnv,
3312  * subtract them, and return the results in a newly allocated stat_array.
3313  * You must free the returned array after you are done with it with
3314  * free_calc_stats().
3315  *
3316  * Additionally, you can set "oldnv" to NULL if you simply want the newnv
3317  * values.
3318  */
3319 static struct stat_array *
3320 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv,
3321     nvlist_t *newnv)
3322 {
3323         nvlist_t *oldnvx = NULL, *newnvx;
3324         struct stat_array *oldnva, *newnva, *calcnva;
3325         int i, j;
3326         unsigned int alloc_size = (sizeof (struct stat_array)) * len;
3327
3328         /* Extract our extended stats nvlist from the main list */
3329         verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3330             &newnvx) == 0);
3331         if (oldnv) {
3332                 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3333                     &oldnvx) == 0);
3334         }
3335
3336         newnva = safe_malloc(alloc_size);
3337         oldnva = safe_malloc(alloc_size);
3338         calcnva = safe_malloc(alloc_size);
3339
3340         for (j = 0; j < len; j++) {
3341                 verify(nvpair64_to_stat_array(newnvx, names[j],
3342                     &newnva[j]) == 0);
3343                 calcnva[j].count = newnva[j].count;
3344                 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]);
3345                 calcnva[j].data = safe_malloc(alloc_size);
3346                 memcpy(calcnva[j].data, newnva[j].data, alloc_size);
3347
3348                 if (oldnvx) {
3349                         verify(nvpair64_to_stat_array(oldnvx, names[j],
3350                             &oldnva[j]) == 0);
3351                         for (i = 0; i < oldnva[j].count; i++)
3352                                 calcnva[j].data[i] -= oldnva[j].data[i];
3353                 }
3354         }
3355         free(newnva);
3356         free(oldnva);
3357         return (calcnva);
3358 }
3359
3360 static void
3361 free_calc_stats(struct stat_array *nva, unsigned int len)
3362 {
3363         int i;
3364         for (i = 0; i < len; i++)
3365                 free(nva[i].data);
3366
3367         free(nva);
3368 }
3369
3370 static void
3371 print_iostat_histo(struct stat_array *nva, unsigned int len,
3372     iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth,
3373     double scale)
3374 {
3375         int i, j;
3376         char buf[6];
3377         uint64_t val;
3378         enum zfs_nicenum_format format;
3379         unsigned int buckets;
3380         unsigned int start_bucket;
3381
3382         if (cb->cb_literal)
3383                 format = ZFS_NICENUM_RAW;
3384         else
3385                 format = ZFS_NICENUM_1024;
3386
3387         /* All these histos are the same size, so just use nva[0].count */
3388         buckets = nva[0].count;
3389
3390         if (cb->cb_flags & IOS_RQ_HISTO_M) {
3391                 /* Start at 512 - req size should never be lower than this */
3392                 start_bucket = 9;
3393         } else {
3394                 start_bucket = 0;
3395         }
3396
3397         for (j = start_bucket; j < buckets; j++) {
3398                 /* Print histogram bucket label */
3399                 if (cb->cb_flags & IOS_L_HISTO_M) {
3400                         /* Ending range of this bucket */
3401                         val = (1UL << (j + 1)) - 1;
3402                         zfs_nicetime(val, buf, sizeof (buf));
3403                 } else {
3404                         /* Request size (starting range of bucket) */
3405                         val = (1UL << j);
3406                         zfs_nicenum(val, buf, sizeof (buf));
3407                 }
3408
3409                 if (cb->cb_scripted)
3410                         printf("%llu", (u_longlong_t)val);
3411                 else
3412                         printf("%-*s", namewidth, buf);
3413
3414                 /* Print the values on the line */
3415                 for (i = 0; i < len; i++) {
3416                         print_one_stat(nva[i].data[j] * scale, format,
3417                             column_width, cb->cb_scripted);
3418                 }
3419                 printf("\n");
3420         }
3421 }
3422
3423 static void
3424 print_solid_separator(unsigned int length)
3425 {
3426         while (length--)
3427                 printf("-");
3428         printf("\n");
3429 }
3430
3431 static void
3432 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv,
3433     nvlist_t *newnv, double scale, const char *name)
3434 {
3435         unsigned int column_width;
3436         unsigned int namewidth;
3437         unsigned int entire_width;
3438         enum iostat_type type;
3439         struct stat_array *nva;
3440         const char **names;
3441         unsigned int names_len;
3442
3443         /* What type of histo are we? */
3444         type = IOS_HISTO_IDX(cb->cb_flags);
3445
3446         /* Get NULL-terminated array of nvlist names for our histo */
3447         names = vsx_type_to_nvlist[type];
3448         names_len = str_array_len(names); /* num of names */
3449
3450         nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv);
3451
3452         if (cb->cb_literal) {
3453                 column_width = MAX(5,
3454                     (unsigned int) log10(stat_histo_max(nva, names_len)) + 1);
3455         } else {
3456                 column_width = 5;
3457         }
3458
3459         namewidth = MAX(cb->cb_namewidth,
3460             strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]));
3461
3462         /*
3463          * Calculate the entire line width of what we're printing.  The
3464          * +2 is for the two spaces between columns:
3465          */
3466         /*       read  write                            */
3467         /*      -----  -----                            */
3468         /*      |___|  <---------- column_width         */
3469         /*                                              */
3470         /*      |__________|  <--- entire_width         */
3471         /*                                              */
3472         entire_width = namewidth + (column_width + 2) *
3473             label_array_len(iostat_bottom_labels[type]);
3474
3475         if (cb->cb_scripted)
3476                 printf("%s\n", name);
3477         else
3478                 print_iostat_header_impl(cb, column_width, name);
3479
3480         print_iostat_histo(nva, names_len, cb, column_width,
3481             namewidth, scale);
3482
3483         free_calc_stats(nva, names_len);
3484         if (!cb->cb_scripted)
3485                 print_solid_separator(entire_width);
3486 }
3487
3488 /*
3489  * Calculate the average latency of a power-of-two latency histogram
3490  */
3491 static uint64_t
3492 single_histo_average(uint64_t *histo, unsigned int buckets)
3493 {
3494         int i;
3495         uint64_t count = 0, total = 0;
3496
3497         for (i = 0; i < buckets; i++) {
3498                 /*
3499                  * Our buckets are power-of-two latency ranges.  Use the
3500                  * midpoint latency of each bucket to calculate the average.
3501                  * For example:
3502                  *
3503                  * Bucket          Midpoint
3504                  * 8ns-15ns:       12ns
3505                  * 16ns-31ns:      24ns
3506                  * ...
3507                  */
3508                 if (histo[i] != 0) {
3509                         total += histo[i] * (((1UL << i) + ((1UL << i)/2)));
3510                         count += histo[i];
3511                 }
3512         }
3513
3514         /* Prevent divide by zero */
3515         return (count == 0 ? 0 : total / count);
3516 }
3517
3518 static void
3519 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv,
3520     nvlist_t *newnv, double scale)
3521 {
3522         int i;
3523         uint64_t val;
3524         const char *names[] = {
3525                 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE,
3526                 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
3527                 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE,
3528                 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
3529                 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE,
3530                 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
3531                 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE,
3532                 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
3533                 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE,
3534                 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
3535         };
3536
3537         struct stat_array *nva;
3538
3539         unsigned int column_width = default_column_width(cb, IOS_QUEUES);
3540         enum zfs_nicenum_format format;
3541
3542         nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv);
3543
3544         if (cb->cb_literal)
3545                 format = ZFS_NICENUM_RAW;
3546         else
3547                 format = ZFS_NICENUM_1024;
3548
3549         for (i = 0; i < ARRAY_SIZE(names); i++) {
3550                 val = nva[i].data[0] * scale;
3551                 print_one_stat(val, format, column_width, cb->cb_scripted);
3552         }
3553
3554         free_calc_stats(nva, ARRAY_SIZE(names));
3555 }
3556
3557 static void
3558 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv,
3559     nvlist_t *newnv, double scale)
3560 {
3561         int i;
3562         uint64_t val;
3563         const char *names[] = {
3564                 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
3565                 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
3566                 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
3567                 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
3568                 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
3569                 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
3570                 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
3571                 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
3572                 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
3573         };
3574         struct stat_array *nva;
3575
3576         unsigned int column_width = default_column_width(cb, IOS_LATENCY);
3577         enum zfs_nicenum_format format;
3578
3579         nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv);
3580
3581         if (cb->cb_literal)
3582                 format = ZFS_NICENUM_RAWTIME;
3583         else
3584                 format = ZFS_NICENUM_TIME;
3585
3586         /* Print our avg latencies on the line */
3587         for (i = 0; i < ARRAY_SIZE(names); i++) {
3588                 /* Compute average latency for a latency histo */
3589                 val = single_histo_average(nva[i].data, nva[i].count) * scale;
3590                 print_one_stat(val, format, column_width, cb->cb_scripted);
3591         }
3592         free_calc_stats(nva, ARRAY_SIZE(names));
3593 }
3594
3595 /*
3596  * Print default statistics (capacity/operations/bandwidth)
3597  */
3598 static void
3599 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale)
3600 {
3601         unsigned int column_width = default_column_width(cb, IOS_DEFAULT);
3602         enum zfs_nicenum_format format;
3603         char na;        /* char to print for "not applicable" values */
3604
3605         if (cb->cb_literal) {
3606                 format = ZFS_NICENUM_RAW;
3607                 na = '0';
3608         } else {
3609                 format = ZFS_NICENUM_1024;
3610                 na = '-';
3611         }
3612
3613         /* only toplevel vdevs have capacity stats */
3614         if (vs->vs_space == 0) {
3615                 if (cb->cb_scripted)
3616                         printf("\t%c\t%c", na, na);
3617                 else
3618                         printf("  %*c  %*c", column_width, na, column_width,
3619                             na);
3620         } else {
3621                 print_one_stat(vs->vs_alloc, format, column_width,
3622                     cb->cb_scripted);
3623                 print_one_stat(vs->vs_space - vs->vs_alloc, format,
3624                     column_width, cb->cb_scripted);
3625         }
3626
3627         print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale),
3628             format, column_width, cb->cb_scripted);
3629         print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale),
3630             format, column_width, cb->cb_scripted);
3631         print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale),
3632             format, column_width, cb->cb_scripted);
3633         print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale),
3634             format, column_width, cb->cb_scripted);
3635 }
3636
3637 /*
3638  * Print out all the statistics for the given vdev.  This can either be the
3639  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
3640  * is a verbose output, and we don't want to display the toplevel pool stats.
3641  *
3642  * Returns the number of stat lines printed.
3643  */
3644 unsigned int
3645 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
3646     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
3647 {
3648         nvlist_t **oldchild, **newchild;
3649         uint_t c, children;
3650         vdev_stat_t *oldvs, *newvs, *calcvs;
3651         vdev_stat_t zerovs = { 0 };
3652         char *vname;
3653         int i;
3654         int ret = 0;
3655         uint64_t tdelta;
3656         double scale;
3657
3658         calcvs = safe_malloc(sizeof (*calcvs));
3659
3660         if (oldnv != NULL) {
3661                 verify(nvlist_lookup_uint64_array(oldnv,
3662                     ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
3663         } else {
3664                 oldvs = &zerovs;
3665         }
3666
3667         /* Do we only want to see a specific vdev? */
3668         for (i = 0; i < cb->cb_vdev_names_count; i++) {
3669                 /* Yes we do.  Is this the vdev? */
3670                 if (strcmp(name, cb->cb_vdev_names[i]) == 0) {
3671                         /*
3672                          * This is our vdev.  Since it is the only vdev we
3673                          * will be displaying, make depth = 0 so that it
3674                          * doesn't get indented.
3675                          */
3676                         depth = 0;
3677                         break;
3678                 }
3679         }
3680
3681         if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) {
3682                 /* Couldn't match the name */
3683                 goto children;
3684         }
3685
3686
3687         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
3688             (uint64_t **)&newvs, &c) == 0);
3689
3690         /*
3691          * Print the vdev name unless it's is a histogram.  Histograms
3692          * display the vdev name in the header itself.
3693          */
3694         if (!(cb->cb_flags & IOS_ANYHISTO_M)) {
3695                 if (cb->cb_scripted) {
3696                         printf("%s", name);
3697                 } else {
3698                         if (strlen(name) + depth > cb->cb_namewidth)
3699                                 (void) printf("%*s%s", depth, "", name);
3700                         else
3701                                 (void) printf("%*s%s%*s", depth, "", name,
3702                                     (int)(cb->cb_namewidth - strlen(name) -
3703                                     depth), "");
3704                 }
3705         }
3706
3707         /* Calculate our scaling factor */
3708         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
3709         if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) {
3710                 /*
3711                  * If we specify printing histograms with no time interval, then
3712                  * print the histogram numbers over the entire lifetime of the
3713                  * vdev.
3714                  */
3715                 scale = 1;
3716         } else {
3717                 if (tdelta == 0)
3718                         scale = 1.0;
3719                 else
3720                         scale = (double)NANOSEC / tdelta;
3721         }
3722
3723         if (cb->cb_flags & IOS_DEFAULT_M) {
3724                 calc_default_iostats(oldvs, newvs, calcvs);
3725                 print_iostat_default(calcvs, cb, scale);
3726         }
3727         if (cb->cb_flags & IOS_LATENCY_M)
3728                 print_iostat_latency(cb, oldnv, newnv, scale);
3729         if (cb->cb_flags & IOS_QUEUES_M)
3730                 print_iostat_queues(cb, oldnv, newnv, scale);
3731         if (cb->cb_flags & IOS_ANYHISTO_M) {
3732                 printf("\n");
3733                 print_iostat_histos(cb, oldnv, newnv, scale, name);
3734         }
3735
3736         if (cb->vcdl != NULL) {
3737                 char *path;
3738                 if (nvlist_lookup_string(newnv, ZPOOL_CONFIG_PATH,
3739                     &path) == 0) {
3740                         printf("  ");
3741                         zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path);
3742                 }
3743         }
3744
3745         if (!(cb->cb_flags & IOS_ANYHISTO_M))
3746                 printf("\n");
3747
3748         ret++;
3749
3750 children:
3751
3752         free(calcvs);
3753
3754         if (!cb->cb_verbose)
3755                 return (ret);
3756
3757         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
3758             &newchild, &children) != 0)
3759                 return (ret);
3760
3761         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
3762             &oldchild, &c) != 0)
3763                 return (ret);
3764
3765         for (c = 0; c < children; c++) {
3766                 uint64_t ishole = B_FALSE, islog = B_FALSE;
3767
3768                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
3769                     &ishole);
3770
3771                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
3772                     &islog);
3773
3774                 if (ishole || islog)
3775                         continue;
3776
3777                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3778                     cb->cb_name_flags);
3779                 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
3780                     newchild[c], cb, depth + 2);
3781                 free(vname);
3782         }
3783
3784         /*
3785          * Log device section
3786          */
3787
3788         if (num_logs(newnv) > 0) {
3789                 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
3790                     !cb->cb_vdev_names) {
3791                         print_iostat_dashes(cb, 0, "logs");
3792                 }
3793                 printf("\n");
3794
3795                 for (c = 0; c < children; c++) {
3796                         uint64_t islog = B_FALSE;
3797                         (void) nvlist_lookup_uint64(newchild[c],
3798                             ZPOOL_CONFIG_IS_LOG, &islog);
3799
3800                         if (islog) {
3801                                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3802                                     cb->cb_name_flags);
3803                                 ret += print_vdev_stats(zhp, vname, oldnv ?
3804                                     oldchild[c] : NULL, newchild[c],
3805                                     cb, depth + 2);
3806                                 free(vname);
3807                         }
3808                 }
3809
3810         }
3811
3812         /*
3813          * Include level 2 ARC devices in iostat output
3814          */
3815         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
3816             &newchild, &children) != 0)
3817                 return (ret);
3818
3819         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
3820             &oldchild, &c) != 0)
3821                 return (ret);
3822
3823         if (children > 0) {
3824                 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
3825                     !cb->cb_vdev_names) {
3826                         print_iostat_dashes(cb, 0, "cache");
3827                 }
3828                 printf("\n");
3829
3830                 for (c = 0; c < children; c++) {
3831                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3832                             cb->cb_name_flags);
3833                         ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c]
3834                             : NULL, newchild[c], cb, depth + 2);
3835                         free(vname);
3836                 }
3837         }
3838
3839         return (ret);
3840 }
3841
3842 static int
3843 refresh_iostat(zpool_handle_t *zhp, void *data)
3844 {
3845         iostat_cbdata_t *cb = data;
3846         boolean_t missing;
3847
3848         /*
3849          * If the pool has disappeared, remove it from the list and continue.
3850          */
3851         if (zpool_refresh_stats(zhp, &missing) != 0)
3852                 return (-1);
3853
3854         if (missing)
3855                 pool_list_remove(cb->cb_list, zhp);
3856
3857         return (0);
3858 }
3859
3860 /*
3861  * Callback to print out the iostats for the given pool.
3862  */
3863 int
3864 print_iostat(zpool_handle_t *zhp, void *data)
3865 {
3866         iostat_cbdata_t *cb = data;
3867         nvlist_t *oldconfig, *newconfig;
3868         nvlist_t *oldnvroot, *newnvroot;
3869         int ret;
3870
3871         newconfig = zpool_get_config(zhp, &oldconfig);
3872
3873         if (cb->cb_iteration == 1)
3874                 oldconfig = NULL;
3875
3876         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
3877             &newnvroot) == 0);
3878
3879         if (oldconfig == NULL)
3880                 oldnvroot = NULL;
3881         else
3882                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
3883                     &oldnvroot) == 0);
3884
3885         ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot,
3886             cb, 0);
3887         if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) &&
3888             !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) {
3889                 print_iostat_separator(cb);
3890                 if (cb->vcdl != NULL) {
3891                         print_cmd_columns(cb->vcdl, 1);
3892                 }
3893                 printf("\n");
3894         }
3895
3896         return (ret);
3897 }
3898
3899 static int
3900 get_columns(void)
3901 {
3902         struct winsize ws;
3903         int columns = 80;
3904         int error;
3905
3906         if (isatty(STDOUT_FILENO)) {
3907                 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
3908                 if (error == 0)
3909                         columns = ws.ws_col;
3910         } else {
3911                 columns = 999;
3912         }
3913
3914         return (columns);
3915 }
3916
3917 int
3918 get_namewidth(zpool_handle_t *zhp, void *data)
3919 {
3920         iostat_cbdata_t *cb = data;
3921         nvlist_t *config, *nvroot;
3922         int columns;
3923
3924         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
3925                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3926                     &nvroot) == 0);
3927                 unsigned int poolname_len = strlen(zpool_get_name(zhp));
3928                 if (!cb->cb_verbose)
3929                         cb->cb_namewidth = MAX(poolname_len, cb->cb_namewidth);
3930                 else
3931                         cb->cb_namewidth = MAX(poolname_len,
3932                             max_width(zhp, nvroot, 0, cb->cb_namewidth,
3933                             cb->cb_name_flags));
3934         }
3935         /*
3936          * The width must be at least 10, but may be as large as the
3937          * column width - 42 so that we can still fit in one line.
3938          */
3939         columns = get_columns();
3940
3941         if (cb->cb_namewidth < 10)
3942                 cb->cb_namewidth = 10;
3943         if (cb->cb_namewidth > columns - 42)
3944                 cb->cb_namewidth = columns - 42;
3945
3946         return (0);
3947 }
3948
3949 /*
3950  * Parse the input string, get the 'interval' and 'count' value if there is one.
3951  */
3952 static void
3953 get_interval_count(int *argcp, char **argv, float *iv,
3954     unsigned long *cnt)
3955 {
3956         float interval = 0;
3957         unsigned long count = 0;
3958         int argc = *argcp;
3959
3960         /*
3961          * Determine if the last argument is an integer or a pool name
3962          */
3963         if (argc > 0 && isnumber(argv[argc - 1])) {
3964                 char *end;
3965
3966                 errno = 0;
3967                 interval = strtof(argv[argc - 1], &end);
3968
3969                 if (*end == '\0' && errno == 0) {
3970                         if (interval == 0) {
3971                                 (void) fprintf(stderr, gettext("interval "
3972                                     "cannot be zero\n"));
3973                                 usage(B_FALSE);
3974                         }
3975                         /*
3976                          * Ignore the last parameter
3977                          */
3978                         argc--;
3979                 } else {
3980                         /*
3981                          * If this is not a valid number, just plow on.  The
3982                          * user will get a more informative error message later
3983                          * on.
3984                          */
3985                         interval = 0;
3986                 }
3987         }
3988
3989         /*
3990          * If the last argument is also an integer, then we have both a count
3991          * and an interval.
3992          */
3993         if (argc > 0 && isnumber(argv[argc - 1])) {
3994                 char *end;
3995
3996                 errno = 0;
3997                 count = interval;
3998                 interval = strtof(argv[argc - 1], &end);
3999
4000                 if (*end == '\0' && errno == 0) {
4001                         if (interval == 0) {
4002                                 (void) fprintf(stderr, gettext("interval "
4003                                     "cannot be zero\n"));
4004                                 usage(B_FALSE);
4005                         }
4006
4007                         /*
4008                          * Ignore the last parameter
4009                          */
4010                         argc--;
4011                 } else {
4012                         interval = 0;
4013                 }
4014         }
4015
4016         *iv = interval;
4017         *cnt = count;
4018         *argcp = argc;
4019 }
4020
4021 static void
4022 get_timestamp_arg(char c)
4023 {
4024         if (c == 'u')
4025                 timestamp_fmt = UDATE;
4026         else if (c == 'd')
4027                 timestamp_fmt = DDATE;
4028         else
4029                 usage(B_FALSE);
4030 }
4031
4032 /*
4033  * Return stat flags that are supported by all pools by both the module and
4034  * zpool iostat.  "*data" should be initialized to all 0xFFs before running.
4035  * It will get ANDed down until only the flags that are supported on all pools
4036  * remain.
4037  */
4038 static int
4039 get_stat_flags_cb(zpool_handle_t *zhp, void *data)
4040 {
4041         uint64_t *mask = data;
4042         nvlist_t *config, *nvroot, *nvx;
4043         uint64_t flags = 0;
4044         int i, j;
4045
4046         config = zpool_get_config(zhp, NULL);
4047         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4048             &nvroot) == 0);
4049
4050         /* Default stats are always supported, but for completeness.. */
4051         if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS))
4052                 flags |= IOS_DEFAULT_M;
4053
4054         /* Get our extended stats nvlist from the main list */
4055         if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX,
4056             &nvx) != 0) {
4057                 /*
4058                  * No extended stats; they're probably running an older
4059                  * module.  No big deal, we support that too.
4060                  */
4061                 goto end;
4062         }
4063
4064         /* For each extended stat, make sure all its nvpairs are supported */
4065         for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) {
4066                 if (!vsx_type_to_nvlist[j][0])
4067                         continue;
4068
4069                 /* Start off by assuming the flag is supported, then check */
4070                 flags |= (1ULL << j);
4071                 for (i = 0; vsx_type_to_nvlist[j][i]; i++) {
4072                         if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) {
4073                                 /* flag isn't supported */
4074                                 flags = flags & ~(1ULL  << j);
4075                                 break;
4076                         }
4077                 }
4078         }
4079 end:
4080         *mask = *mask & flags;
4081         return (0);
4082 }
4083
4084 /*
4085  * Return a bitmask of stats that are supported on all pools by both the module
4086  * and zpool iostat.
4087  */
4088 static uint64_t
4089 get_stat_flags(zpool_list_t *list)
4090 {
4091         uint64_t mask = -1;
4092
4093         /*
4094          * get_stat_flags_cb() will lop off bits from "mask" until only the
4095          * flags that are supported on all pools remain.
4096          */
4097         pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
4098         return (mask);
4099 }
4100
4101 /*
4102  * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
4103  */
4104 static int
4105 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
4106 {
4107         iostat_cbdata_t *cb = cb_data;
4108         char *name = NULL;
4109         int ret = 0;
4110
4111         name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
4112
4113         if (strcmp(name, cb->cb_vdev_names[0]) == 0)
4114                 ret = 1; /* match */
4115         free(name);
4116
4117         return (ret);
4118 }
4119
4120 /*
4121  * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise.
4122  */
4123 static int
4124 is_vdev(zpool_handle_t *zhp, void *cb_data)
4125 {
4126         return (for_each_vdev(zhp, is_vdev_cb, cb_data));
4127 }
4128
4129 /*
4130  * Check if vdevs are in a pool
4131  *
4132  * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise
4133  * return 0.  If pool_name is NULL, then search all pools.
4134  */
4135 static int
4136 are_vdevs_in_pool(int argc, char **argv, char *pool_name,
4137     iostat_cbdata_t *cb)
4138 {
4139         char **tmp_name;
4140         int ret = 0;
4141         int i;
4142         int pool_count = 0;
4143
4144         if ((argc == 0) || !*argv)
4145                 return (0);
4146
4147         if (pool_name)
4148                 pool_count = 1;
4149
4150         /* Temporarily hijack cb_vdev_names for a second... */
4151         tmp_name = cb->cb_vdev_names;
4152
4153         /* Go though our list of prospective vdev names */
4154         for (i = 0; i < argc; i++) {
4155                 cb->cb_vdev_names = argv + i;
4156
4157                 /* Is this name a vdev in our pools? */
4158                 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL,
4159                     is_vdev, cb);
4160                 if (!ret) {
4161                         /* No match */
4162                         break;
4163                 }
4164         }
4165
4166         cb->cb_vdev_names = tmp_name;
4167
4168         return (ret);
4169 }
4170
4171 static int
4172 is_pool_cb(zpool_handle_t *zhp, void *data)
4173 {
4174         char *name = data;
4175         if (strcmp(name, zpool_get_name(zhp)) == 0)
4176                 return (1);
4177
4178         return (0);
4179 }
4180
4181 /*
4182  * Do we have a pool named *name?  If so, return 1, otherwise 0.
4183  */
4184 static int
4185 is_pool(char *name)
4186 {
4187         return (for_each_pool(0, NULL, B_TRUE, NULL,  is_pool_cb, name));
4188 }
4189
4190 /* Are all our argv[] strings pool names?  If so return 1, 0 otherwise. */
4191 static int
4192 are_all_pools(int argc, char **argv)
4193 {
4194         if ((argc == 0) || !*argv)
4195                 return (0);
4196
4197         while (--argc >= 0)
4198                 if (!is_pool(argv[argc]))
4199                         return (0);
4200
4201         return (1);
4202 }
4203
4204 /*
4205  * Helper function to print out vdev/pool names we can't resolve.  Used for an
4206  * error message.
4207  */
4208 static void
4209 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name,
4210     iostat_cbdata_t *cb)
4211 {
4212         int i;
4213         char *name;
4214         char *str;
4215         for (i = 0; i < argc; i++) {
4216                 name = argv[i];
4217
4218                 if (is_pool(name))
4219                         str = gettext("pool");
4220                 else if (are_vdevs_in_pool(1, &name, pool_name, cb))
4221                         str = gettext("vdev in this pool");
4222                 else if (are_vdevs_in_pool(1, &name, NULL, cb))
4223                         str = gettext("vdev in another pool");
4224                 else
4225                         str = gettext("unknown");
4226
4227                 fprintf(stderr, "\t%s (%s)\n", name, str);
4228         }
4229 }
4230
4231 /*
4232  * Same as get_interval_count(), but with additional checks to not misinterpret
4233  * guids as interval/count values.  Assumes VDEV_NAME_GUID is set in
4234  * cb.cb_name_flags.
4235  */
4236 static void
4237 get_interval_count_filter_guids(int *argc, char **argv, float *interval,
4238     unsigned long *count, iostat_cbdata_t *cb)
4239 {
4240         char **tmpargv = argv;
4241         int argc_for_interval = 0;
4242
4243         /* Is the last arg an interval value?  Or a guid? */
4244         if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) {
4245                 /*
4246                  * The last arg is not a guid, so it's probably an
4247                  * interval value.
4248                  */
4249                 argc_for_interval++;
4250
4251                 if (*argc >= 2 &&
4252                     !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) {
4253                         /*
4254                          * The 2nd to last arg is not a guid, so it's probably
4255                          * an interval value.
4256                          */
4257                         argc_for_interval++;
4258                 }
4259         }
4260
4261         /* Point to our list of possible intervals */
4262         tmpargv = &argv[*argc - argc_for_interval];
4263
4264         *argc = *argc - argc_for_interval;
4265         get_interval_count(&argc_for_interval, tmpargv,
4266             interval, count);
4267 }
4268
4269 /*
4270  * Floating point sleep().  Allows you to pass in a floating point value for
4271  * seconds.
4272  */
4273 static void
4274 fsleep(float sec)
4275 {
4276         struct timespec req;
4277         req.tv_sec = floor(sec);
4278         req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
4279         nanosleep(&req, NULL);
4280 }
4281
4282 /*
4283  * Run one of the zpool status/iostat -c scripts with the help (-h) option and
4284  * print the result.
4285  *
4286  * name:        Short name of the script ('iostat').
4287  * path:        Full path to the script ('/usr/local/etc/zfs/zpool.d/iostat');
4288  */
4289 static void
4290 print_zpool_script_help(char *name, char *path)
4291 {
4292         char *argv[] = {path, "-h", NULL};
4293         char **lines = NULL;
4294         int lines_cnt = 0;
4295         int rc;
4296
4297         rc = libzfs_run_process_get_stdout_nopath(path, argv, NULL, &lines,
4298             &lines_cnt);
4299         if (rc != 0 || lines == NULL || lines_cnt <= 0) {
4300                 if (lines != NULL)
4301                         libzfs_free_str_array(lines, lines_cnt);
4302                 return;
4303         }
4304
4305         for (int i = 0; i < lines_cnt; i++)
4306                 if (!is_blank_str(lines[i]))
4307                         printf("  %-14s  %s\n", name, lines[i]);
4308
4309         libzfs_free_str_array(lines, lines_cnt);
4310 }
4311
4312 /*
4313  * Go though the zpool status/iostat -c scripts in the user's path, run their
4314  * help option (-h), and print out the results.
4315  */
4316 static void
4317 print_zpool_dir_scripts(char *dirpath)
4318 {
4319         DIR *dir;
4320         struct dirent *ent;
4321         char fullpath[MAXPATHLEN];
4322         struct stat dir_stat;
4323
4324         if ((dir = opendir(dirpath)) != NULL) {
4325                 /* print all the files and directories within directory */
4326                 while ((ent = readdir(dir)) != NULL) {
4327                         sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
4328
4329                         /* Print the scripts */
4330                         if (stat(fullpath, &dir_stat) == 0)
4331                                 if (dir_stat.st_mode & S_IXUSR &&
4332                                     S_ISREG(dir_stat.st_mode))
4333                                         print_zpool_script_help(ent->d_name,
4334                                             fullpath);
4335                 }
4336                 closedir(dir);
4337         }
4338 }
4339
4340 /*
4341  * Print out help text for all zpool status/iostat -c scripts.
4342  */
4343 static void
4344 print_zpool_script_list(char *subcommand)
4345 {
4346         char *dir, *sp;
4347
4348         printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand);
4349
4350         sp = zpool_get_cmd_search_path();
4351         if (sp == NULL)
4352                 return;
4353
4354         dir = strtok(sp, ":");
4355         while (dir != NULL) {
4356                 print_zpool_dir_scripts(dir);
4357                 dir = strtok(NULL, ":");
4358         }
4359
4360         free(sp);
4361 }
4362
4363 /*
4364  * zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name]
4365  *              [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]]
4366  *              [interval [count]]
4367  *
4368  *      -c CMD  For each vdev, run command CMD
4369  *      -g      Display guid for individual vdev name.
4370  *      -L      Follow links when resolving vdev path name.
4371  *      -P      Display full path for vdev name.
4372  *      -v      Display statistics for individual vdevs
4373  *      -h      Display help
4374  *      -p      Display values in parsable (exact) format.
4375  *      -H      Scripted mode.  Don't display headers, and separate properties
4376  *              by a single tab.
4377  *      -l      Display average latency
4378  *      -q      Display queue depths
4379  *      -w      Display latency histograms
4380  *      -r      Display request size histogram
4381  *      -T      Display a timestamp in date(1) or Unix format
4382  *
4383  * This command can be tricky because we want to be able to deal with pool
4384  * creation/destruction as well as vdev configuration changes.  The bulk of this
4385  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
4386  * on pool_list_update() to detect the addition of new pools.  Configuration
4387  * changes are all handled within libzfs.
4388  */
4389 int
4390 zpool_do_iostat(int argc, char **argv)
4391 {
4392         int c;
4393         int ret;
4394         int npools;
4395         float interval = 0;
4396         unsigned long count = 0;
4397         zpool_list_t *list;
4398         boolean_t verbose = B_FALSE;
4399         boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
4400         boolean_t queues = B_FALSE, parsable = B_FALSE, scripted = B_FALSE;
4401         boolean_t omit_since_boot = B_FALSE;
4402         boolean_t guid = B_FALSE;
4403         boolean_t follow_links = B_FALSE;
4404         boolean_t full_name = B_FALSE;
4405         iostat_cbdata_t cb = { 0 };
4406         char *cmd = NULL;
4407
4408         /* Used for printing error message */
4409         const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q',
4410             [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'};
4411
4412         uint64_t unsupported_flags;
4413
4414         /* check options */
4415         while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwH")) != -1) {
4416                 switch (c) {
4417                 case 'c':
4418                         if (cmd != NULL) {
4419                                 fprintf(stderr,
4420                                     gettext("Can't set -c flag twice\n"));
4421                                 exit(1);
4422                         }
4423
4424                         if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
4425                             !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
4426                                 fprintf(stderr, gettext(
4427                                     "Can't run -c, disabled by "
4428                                     "ZPOOL_SCRIPTS_ENABLED.\n"));
4429                                 exit(1);
4430                         }
4431
4432                         if ((getuid() <= 0 || geteuid() <= 0) &&
4433                             !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
4434                                 fprintf(stderr, gettext(
4435                                     "Can't run -c with root privileges "
4436                                     "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
4437                                 exit(1);
4438                         }
4439                         cmd = optarg;
4440                         verbose = B_TRUE;
4441                         break;
4442                 case 'g':
4443                         guid = B_TRUE;
4444                         break;
4445                 case 'L':
4446                         follow_links = B_TRUE;
4447                         break;
4448                 case 'P':
4449                         full_name = B_TRUE;
4450                         break;
4451                 case 'T':
4452                         get_timestamp_arg(*optarg);
4453                         break;
4454                 case 'v':
4455                         verbose = B_TRUE;
4456                         break;
4457                 case 'p':
4458                         parsable = B_TRUE;
4459                         break;
4460                 case 'l':
4461                         latency = B_TRUE;
4462                         break;
4463                 case 'q':
4464                         queues = B_TRUE;
4465                         break;
4466                 case 'H':
4467                         scripted = B_TRUE;
4468                         break;
4469                 case 'w':
4470                         l_histo = B_TRUE;
4471                         break;
4472                 case 'r':
4473                         rq_histo = B_TRUE;
4474                         break;
4475                 case 'y':
4476                         omit_since_boot = B_TRUE;
4477                         break;
4478                 case 'h':
4479                         usage(B_FALSE);
4480                         break;
4481                 case '?':
4482                         if (optopt == 'c') {
4483                                 print_zpool_script_list("iostat");
4484                                 exit(0);
4485                         } else {
4486                                 fprintf(stderr,
4487                                     gettext("invalid option '%c'\n"), optopt);
4488                         }
4489                         usage(B_FALSE);
4490                 }
4491         }
4492
4493         argc -= optind;
4494         argv += optind;
4495
4496         cb.cb_literal = parsable;
4497         cb.cb_scripted = scripted;
4498
4499         if (guid)
4500                 cb.cb_name_flags |= VDEV_NAME_GUID;
4501         if (follow_links)
4502                 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
4503         if (full_name)
4504                 cb.cb_name_flags |= VDEV_NAME_PATH;
4505         cb.cb_iteration = 0;
4506         cb.cb_namewidth = 0;
4507         cb.cb_verbose = verbose;
4508
4509         /* Get our interval and count values (if any) */
4510         if (guid) {
4511                 get_interval_count_filter_guids(&argc, argv, &interval,
4512                     &count, &cb);
4513         } else {
4514                 get_interval_count(&argc, argv, &interval, &count);
4515         }
4516
4517         if (argc == 0) {
4518                 /* No args, so just print the defaults. */
4519         } else if (are_all_pools(argc, argv)) {
4520                 /* All the args are pool names */
4521         } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) {
4522                 /* All the args are vdevs */
4523                 cb.cb_vdev_names = argv;
4524                 cb.cb_vdev_names_count = argc;
4525                 argc = 0; /* No pools to process */
4526         } else if (are_all_pools(1, argv)) {
4527                 /* The first arg is a pool name */
4528                 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) {
4529                         /* ...and the rest are vdev names */
4530                         cb.cb_vdev_names = argv + 1;
4531                         cb.cb_vdev_names_count = argc - 1;
4532                         argc = 1; /* One pool to process */
4533                 } else {
4534                         fprintf(stderr, gettext("Expected either a list of "));
4535                         fprintf(stderr, gettext("pools, or list of vdevs in"));
4536                         fprintf(stderr, " \"%s\", ", argv[0]);
4537                         fprintf(stderr, gettext("but got:\n"));
4538                         error_list_unresolved_vdevs(argc - 1, argv + 1,
4539                             argv[0], &cb);
4540                         fprintf(stderr, "\n");
4541                         usage(B_FALSE);
4542                         return (1);
4543                 }
4544         } else {
4545                 /*
4546                  * The args don't make sense. The first arg isn't a pool name,
4547                  * nor are all the args vdevs.
4548                  */
4549                 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n"));
4550                 fprintf(stderr, "\n");
4551                 return (1);
4552         }
4553
4554         if (cb.cb_vdev_names_count != 0) {
4555                 /*
4556                  * If user specified vdevs, it implies verbose.
4557                  */
4558                 cb.cb_verbose = B_TRUE;
4559         }
4560
4561         /*
4562          * Construct the list of all interesting pools.
4563          */
4564         ret = 0;
4565         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
4566                 return (1);
4567
4568         if (pool_list_count(list) == 0 && argc != 0) {
4569                 pool_list_free(list);
4570                 return (1);
4571         }
4572
4573         if (pool_list_count(list) == 0 && interval == 0) {
4574                 pool_list_free(list);
4575                 (void) fprintf(stderr, gettext("no pools available\n"));
4576                 return (1);
4577         }
4578
4579         if ((l_histo || rq_histo) && (cmd != NULL || latency || queues)) {
4580                 pool_list_free(list);
4581                 (void) fprintf(stderr,
4582                     gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n"));
4583                 usage(B_FALSE);
4584                 return (1);
4585         }
4586
4587         if (l_histo && rq_histo) {
4588                 pool_list_free(list);
4589                 (void) fprintf(stderr,
4590                     gettext("Only one of [-r|-w] can be passed at a time\n"));
4591                 usage(B_FALSE);
4592                 return (1);
4593         }
4594
4595         /*
4596          * Enter the main iostat loop.
4597          */
4598         cb.cb_list = list;
4599
4600         if (l_histo) {
4601                 /*
4602                  * Histograms tables look out of place when you try to display
4603                  * them with the other stats, so make a rule that you can only
4604                  * print histograms by themselves.
4605                  */
4606                 cb.cb_flags = IOS_L_HISTO_M;
4607         } else if (rq_histo) {
4608                 cb.cb_flags = IOS_RQ_HISTO_M;
4609         } else {
4610                 cb.cb_flags = IOS_DEFAULT_M;
4611                 if (latency)
4612                         cb.cb_flags |= IOS_LATENCY_M;
4613                 if (queues)
4614                         cb.cb_flags |= IOS_QUEUES_M;
4615         }
4616
4617         /*
4618          * See if the module supports all the stats we want to display.
4619          */
4620         unsupported_flags = cb.cb_flags & ~get_stat_flags(list);
4621         if (unsupported_flags) {
4622                 uint64_t f;
4623                 int idx;
4624                 fprintf(stderr,
4625                     gettext("The loaded zfs module doesn't support:"));
4626
4627                 /* for each bit set in unsupported_flags */
4628                 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) {
4629                         idx = lowbit64(f) - 1;
4630                         fprintf(stderr, " -%c", flag_to_arg[idx]);
4631                 }
4632
4633                 fprintf(stderr, ".  Try running a newer module.\n");
4634                 pool_list_free(list);
4635
4636                 return (1);
4637         }
4638
4639         for (;;) {
4640                 if ((npools = pool_list_count(list)) == 0)
4641                         (void) fprintf(stderr, gettext("no pools available\n"));
4642                 else {
4643                         /*
4644                          * If this is the first iteration and -y was supplied
4645                          * we skip any printing.
4646                          */
4647                         boolean_t skip = (omit_since_boot &&
4648                             cb.cb_iteration == 0);
4649
4650                         /*
4651                          * Refresh all statistics.  This is done as an
4652                          * explicit step before calculating the maximum name
4653                          * width, so that any * configuration changes are
4654                          * properly accounted for.
4655                          */
4656                         (void) pool_list_iter(list, B_FALSE, refresh_iostat,
4657                             &cb);
4658
4659                         /*
4660                          * Iterate over all pools to determine the maximum width
4661                          * for the pool / device name column across all pools.
4662                          */
4663                         cb.cb_namewidth = 0;
4664                         (void) pool_list_iter(list, B_FALSE, get_namewidth,
4665                             &cb);
4666
4667                         if (timestamp_fmt != NODATE)
4668                                 print_timestamp(timestamp_fmt);
4669
4670                         if (cmd != NULL && cb.cb_verbose &&
4671                             !(cb.cb_flags & IOS_ANYHISTO_M)) {
4672                                 cb.vcdl = all_pools_for_each_vdev_run(argc,
4673                                     argv, cmd, g_zfs, cb.cb_vdev_names,
4674                                     cb.cb_vdev_names_count, cb.cb_name_flags);
4675                         } else {
4676                                 cb.vcdl = NULL;
4677                         }
4678
4679                         /*
4680                          * If it's the first time and we're not skipping it,
4681                          * or either skip or verbose mode, print the header.
4682                          *
4683                          * The histogram code explicitly prints its header on
4684                          * every vdev, so skip this for histograms.
4685                          */
4686                         if (((++cb.cb_iteration == 1 && !skip) ||
4687                             (skip != verbose)) &&
4688                             (!(cb.cb_flags & IOS_ANYHISTO_M)) &&
4689                             !cb.cb_scripted)
4690                                 print_iostat_header(&cb);
4691
4692                         if (skip) {
4693                                 (void) fsleep(interval);
4694                                 continue;
4695                         }
4696
4697
4698                         pool_list_iter(list, B_FALSE, print_iostat, &cb);
4699
4700                         /*
4701                          * If there's more than one pool, and we're not in
4702                          * verbose mode (which prints a separator for us),
4703                          * then print a separator.
4704                          *
4705                          * In addition, if we're printing specific vdevs then
4706                          * we also want an ending separator.
4707                          */
4708                         if (((npools > 1 && !verbose &&
4709                             !(cb.cb_flags & IOS_ANYHISTO_M)) ||
4710                             (!(cb.cb_flags & IOS_ANYHISTO_M) &&
4711                             cb.cb_vdev_names_count)) &&
4712                             !cb.cb_scripted) {
4713                                 print_iostat_separator(&cb);
4714                                 if (cb.vcdl != NULL)
4715                                         print_cmd_columns(cb.vcdl, 1);
4716                                 printf("\n");
4717                         }
4718
4719                         if (cb.vcdl != NULL)
4720                                 free_vdev_cmd_data_list(cb.vcdl);
4721
4722                 }
4723
4724                 /*
4725                  * Flush the output so that redirection to a file isn't buffered
4726                  * indefinitely.
4727                  */
4728                 (void) fflush(stdout);
4729
4730                 if (interval == 0)
4731                         break;
4732
4733                 if (count != 0 && --count == 0)
4734                         break;
4735
4736                 (void) fsleep(interval);
4737         }
4738
4739         pool_list_free(list);
4740
4741         return (ret);
4742 }
4743
4744 typedef struct list_cbdata {
4745         boolean_t       cb_verbose;
4746         int             cb_name_flags;
4747         int             cb_namewidth;
4748         boolean_t       cb_scripted;
4749         zprop_list_t    *cb_proplist;
4750         boolean_t       cb_literal;
4751 } list_cbdata_t;
4752
4753 /*
4754  * Given a list of columns to display, output appropriate headers for each one.
4755  */
4756 static void
4757 print_header(list_cbdata_t *cb)
4758 {
4759         zprop_list_t *pl = cb->cb_proplist;
4760         char headerbuf[ZPOOL_MAXPROPLEN];
4761         const char *header;
4762         boolean_t first = B_TRUE;
4763         boolean_t right_justify;
4764         size_t width = 0;
4765
4766         for (; pl != NULL; pl = pl->pl_next) {
4767                 width = pl->pl_width;
4768                 if (first && cb->cb_verbose) {
4769                         /*
4770                          * Reset the width to accommodate the verbose listing
4771                          * of devices.
4772                          */
4773                         width = cb->cb_namewidth;
4774                 }
4775
4776                 if (!first)
4777                         (void) printf("  ");
4778                 else
4779                         first = B_FALSE;
4780
4781                 right_justify = B_FALSE;
4782                 if (pl->pl_prop != ZPROP_INVAL) {
4783                         header = zpool_prop_column_name(pl->pl_prop);
4784                         right_justify = zpool_prop_align_right(pl->pl_prop);
4785                 } else {
4786                         int i;
4787
4788                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
4789                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
4790                         headerbuf[i] = '\0';
4791                         header = headerbuf;
4792                 }
4793
4794                 if (pl->pl_next == NULL && !right_justify)
4795                         (void) printf("%s", header);
4796                 else if (right_justify)
4797                         (void) printf("%*s", (int)width, header);
4798                 else
4799                         (void) printf("%-*s", (int)width, header);
4800         }
4801
4802         (void) printf("\n");
4803 }
4804
4805 /*
4806  * Given a pool and a list of properties, print out all the properties according
4807  * to the described layout.
4808  */
4809 static void
4810 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
4811 {
4812         zprop_list_t *pl = cb->cb_proplist;
4813         boolean_t first = B_TRUE;
4814         char property[ZPOOL_MAXPROPLEN];
4815         char *propstr;
4816         boolean_t right_justify;
4817         size_t width;
4818
4819         for (; pl != NULL; pl = pl->pl_next) {
4820
4821                 width = pl->pl_width;
4822                 if (first && cb->cb_verbose) {
4823                         /*
4824                          * Reset the width to accommodate the verbose listing
4825                          * of devices.
4826                          */
4827                         width = cb->cb_namewidth;
4828                 }
4829
4830                 if (!first) {
4831                         if (cb->cb_scripted)
4832                                 (void) printf("\t");
4833                         else
4834                                 (void) printf("  ");
4835                 } else {
4836                         first = B_FALSE;
4837                 }
4838
4839                 right_justify = B_FALSE;
4840                 if (pl->pl_prop != ZPROP_INVAL) {
4841                         if (zpool_get_prop(zhp, pl->pl_prop, property,
4842                             sizeof (property), NULL, cb->cb_literal) != 0)
4843                                 propstr = "-";
4844                         else
4845                                 propstr = property;
4846
4847                         right_justify = zpool_prop_align_right(pl->pl_prop);
4848                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
4849                     zpool_prop_unsupported(pl->pl_user_prop)) &&
4850                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
4851                     sizeof (property)) == 0) {
4852                         propstr = property;
4853                 } else {
4854                         propstr = "-";
4855                 }
4856
4857
4858                 /*
4859                  * If this is being called in scripted mode, or if this is the
4860                  * last column and it is left-justified, don't include a width
4861                  * format specifier.
4862                  */
4863                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
4864                         (void) printf("%s", propstr);
4865                 else if (right_justify)
4866                         (void) printf("%*s", (int)width, propstr);
4867                 else
4868                         (void) printf("%-*s", (int)width, propstr);
4869         }
4870
4871         (void) printf("\n");
4872 }
4873
4874 static void
4875 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
4876     boolean_t valid, enum zfs_nicenum_format format)
4877 {
4878         char propval[64];
4879         boolean_t fixed;
4880         size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
4881
4882         switch (prop) {
4883         case ZPOOL_PROP_EXPANDSZ:
4884                 if (value == 0)
4885                         (void) strlcpy(propval, "-", sizeof (propval));
4886                 else
4887                         zfs_nicenum_format(value, propval, sizeof (propval),
4888                             format);
4889                 break;
4890         case ZPOOL_PROP_FRAGMENTATION:
4891                 if (value == ZFS_FRAG_INVALID) {
4892                         (void) strlcpy(propval, "-", sizeof (propval));
4893                 } else if (format == ZFS_NICENUM_RAW) {
4894                         (void) snprintf(propval, sizeof (propval), "%llu",
4895                             (unsigned long long)value);
4896                 } else {
4897                         (void) snprintf(propval, sizeof (propval), "%llu%%",
4898                             (unsigned long long)value);
4899                 }
4900                 break;
4901         case ZPOOL_PROP_CAPACITY:
4902                 if (format == ZFS_NICENUM_RAW)
4903                         (void) snprintf(propval, sizeof (propval), "%llu",
4904                             (unsigned long long)value);
4905                 else
4906                         (void) snprintf(propval, sizeof (propval), "%llu%%",
4907                             (unsigned long long)value);
4908                 break;
4909         default:
4910                 zfs_nicenum_format(value, propval, sizeof (propval), format);
4911         }
4912
4913         if (!valid)
4914                 (void) strlcpy(propval, "-", sizeof (propval));
4915
4916         if (scripted)
4917                 (void) printf("\t%s", propval);
4918         else
4919                 (void) printf("  %*s", (int)width, propval);
4920 }
4921
4922 void
4923 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
4924     list_cbdata_t *cb, int depth)
4925 {
4926         nvlist_t **child;
4927         vdev_stat_t *vs;
4928         uint_t c, children;
4929         char *vname;
4930         boolean_t scripted = cb->cb_scripted;
4931         uint64_t islog = B_FALSE;
4932         boolean_t haslog = B_FALSE;
4933         char *dashes = "%-*s      -      -      -         -      -      -\n";
4934
4935         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
4936             (uint64_t **)&vs, &c) == 0);
4937
4938         if (name != NULL) {
4939                 boolean_t toplevel = (vs->vs_space != 0);
4940                 uint64_t cap;
4941                 enum zfs_nicenum_format format;
4942
4943                 if (cb->cb_literal)
4944                         format = ZFS_NICENUM_RAW;
4945                 else
4946                         format = ZFS_NICENUM_1024;
4947
4948                 if (scripted)
4949                         (void) printf("\t%s", name);
4950                 else if (strlen(name) + depth > cb->cb_namewidth)
4951                         (void) printf("%*s%s", depth, "", name);
4952                 else
4953                         (void) printf("%*s%s%*s", depth, "", name,
4954                             (int)(cb->cb_namewidth - strlen(name) - depth), "");
4955
4956                 /*
4957                  * Print the properties for the individual vdevs. Some
4958                  * properties are only applicable to toplevel vdevs. The
4959                  * 'toplevel' boolean value is passed to the print_one_column()
4960                  * to indicate that the value is valid.
4961                  */
4962                 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
4963                     toplevel, format);
4964                 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
4965                     toplevel, format);
4966                 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
4967                     scripted, toplevel, format);
4968                 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
4969                     B_TRUE, format);
4970                 print_one_column(ZPOOL_PROP_FRAGMENTATION,
4971                     vs->vs_fragmentation, scripted,
4972                     (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
4973                     format);
4974                 cap = (vs->vs_space == 0) ? 0 :
4975                     (vs->vs_alloc * 100 / vs->vs_space);
4976                 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel,
4977                     format);
4978                 (void) printf("\n");
4979         }
4980
4981         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
4982             &child, &children) != 0)
4983                 return;
4984
4985         for (c = 0; c < children; c++) {
4986                 uint64_t ishole = B_FALSE;
4987
4988                 if (nvlist_lookup_uint64(child[c],
4989                     ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
4990                         continue;
4991
4992                 if (nvlist_lookup_uint64(child[c],
4993                     ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) {
4994                         haslog = B_TRUE;
4995                         continue;
4996                 }
4997
4998                 vname = zpool_vdev_name(g_zfs, zhp, child[c],
4999                     cb->cb_name_flags);
5000                 print_list_stats(zhp, vname, child[c], cb, depth + 2);
5001                 free(vname);
5002         }
5003
5004         if (haslog == B_TRUE) {
5005                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5006                 (void) printf(dashes, cb->cb_namewidth, "log");
5007                 for (c = 0; c < children; c++) {
5008                         if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
5009                             &islog) != 0 || !islog)
5010                                 continue;
5011                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5012                             cb->cb_name_flags);
5013                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5014                         free(vname);
5015                 }
5016         }
5017
5018         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
5019             &child, &children) == 0 && children > 0) {
5020                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5021                 (void) printf(dashes, cb->cb_namewidth, "cache");
5022                 for (c = 0; c < children; c++) {
5023                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5024                             cb->cb_name_flags);
5025                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5026                         free(vname);
5027                 }
5028         }
5029
5030         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
5031             &children) == 0 && children > 0) {
5032                 /* LINTED E_SEC_PRINTF_VAR_FMT */
5033                 (void) printf(dashes, cb->cb_namewidth, "spare");
5034                 for (c = 0; c < children; c++) {
5035                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
5036                             cb->cb_name_flags);
5037                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
5038                         free(vname);
5039                 }
5040         }
5041 }
5042
5043
5044 /*
5045  * Generic callback function to list a pool.
5046  */
5047 int
5048 list_callback(zpool_handle_t *zhp, void *data)
5049 {
5050         list_cbdata_t *cbp = data;
5051         nvlist_t *config;
5052         nvlist_t *nvroot;
5053
5054         config = zpool_get_config(zhp, NULL);
5055
5056         print_pool(zhp, cbp);
5057         if (!cbp->cb_verbose)
5058                 return (0);
5059
5060         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
5061             &nvroot) == 0);
5062         print_list_stats(zhp, NULL, nvroot, cbp, 0);
5063
5064         return (0);
5065 }
5066
5067 /*
5068  * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
5069  *
5070  *      -g      Display guid for individual vdev name.
5071  *      -H      Scripted mode.  Don't display headers, and separate properties
5072  *              by a single tab.
5073  *      -L      Follow links when resolving vdev path name.
5074  *      -o      List of properties to display.  Defaults to
5075  *              "name,size,allocated,free,expandsize,fragmentation,capacity,"
5076  *              "dedupratio,health,altroot"
5077  *      -p      Display values in parsable (exact) format.
5078  *      -P      Display full path for vdev name.
5079  *      -T      Display a timestamp in date(1) or Unix format
5080  *
5081  * List all pools in the system, whether or not they're healthy.  Output space
5082  * statistics for each one, as well as health status summary.
5083  */
5084 int
5085 zpool_do_list(int argc, char **argv)
5086 {
5087         int c;
5088         int ret = 0;
5089         list_cbdata_t cb = { 0 };
5090         static char default_props[] =
5091             "name,size,allocated,free,expandsize,fragmentation,capacity,"
5092             "dedupratio,health,altroot";
5093         char *props = default_props;
5094         float interval = 0;
5095         unsigned long count = 0;
5096         zpool_list_t *list;
5097         boolean_t first = B_TRUE;
5098
5099         /* check options */
5100         while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) {
5101                 switch (c) {
5102                 case 'g':
5103                         cb.cb_name_flags |= VDEV_NAME_GUID;
5104                         break;
5105                 case 'H':
5106                         cb.cb_scripted = B_TRUE;
5107                         break;
5108                 case 'L':
5109                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
5110                         break;
5111                 case 'o':
5112                         props = optarg;
5113                         break;
5114                 case 'P':
5115                         cb.cb_name_flags |= VDEV_NAME_PATH;
5116                         break;
5117                 case 'p':
5118                         cb.cb_literal = B_TRUE;
5119                         break;
5120                 case 'T':
5121                         get_timestamp_arg(*optarg);
5122                         break;
5123                 case 'v':
5124                         cb.cb_verbose = B_TRUE;
5125                         break;
5126                 case ':':
5127                         (void) fprintf(stderr, gettext("missing argument for "
5128                             "'%c' option\n"), optopt);
5129                         usage(B_FALSE);
5130                         break;
5131                 case '?':
5132                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5133                             optopt);
5134                         usage(B_FALSE);
5135                 }
5136         }
5137
5138         argc -= optind;
5139         argv += optind;
5140
5141         get_interval_count(&argc, argv, &interval, &count);
5142
5143         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
5144                 usage(B_FALSE);
5145
5146         for (;;) {
5147                 if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
5148                     &ret)) == NULL)
5149                         return (1);
5150
5151                 if (pool_list_count(list) == 0)
5152                         break;
5153
5154                 if (timestamp_fmt != NODATE)
5155                         print_timestamp(timestamp_fmt);
5156
5157                 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
5158                         print_header(&cb);
5159                         first = B_FALSE;
5160                 }
5161                 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
5162
5163                 if (interval == 0)
5164                         break;
5165
5166                 if (count != 0 && --count == 0)
5167                         break;
5168
5169                 pool_list_free(list);
5170                 (void) fsleep(interval);
5171         }
5172
5173         if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
5174                 (void) printf(gettext("no pools available\n"));
5175                 ret = 0;
5176         }
5177
5178         pool_list_free(list);
5179         zprop_free_list(cb.cb_proplist);
5180         return (ret);
5181 }
5182
5183 static int
5184 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
5185 {
5186         boolean_t force = B_FALSE;
5187         int c;
5188         nvlist_t *nvroot;
5189         char *poolname, *old_disk, *new_disk;
5190         zpool_handle_t *zhp;
5191         nvlist_t *props = NULL;
5192         char *propval;
5193         int ret;
5194
5195         /* check options */
5196         while ((c = getopt(argc, argv, "fo:")) != -1) {
5197                 switch (c) {
5198                 case 'f':
5199                         force = B_TRUE;
5200                         break;
5201                 case 'o':
5202                         if ((propval = strchr(optarg, '=')) == NULL) {
5203                                 (void) fprintf(stderr, gettext("missing "
5204                                     "'=' for -o option\n"));
5205                                 usage(B_FALSE);
5206                         }
5207                         *propval = '\0';
5208                         propval++;
5209
5210                         if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
5211                             (add_prop_list(optarg, propval, &props, B_TRUE)))
5212                                 usage(B_FALSE);
5213                         break;
5214                 case '?':
5215                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5216                             optopt);
5217                         usage(B_FALSE);
5218                 }
5219         }
5220
5221         argc -= optind;
5222         argv += optind;
5223
5224         /* get pool name and check number of arguments */
5225         if (argc < 1) {
5226                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5227                 usage(B_FALSE);
5228         }
5229
5230         poolname = argv[0];
5231
5232         if (argc < 2) {
5233                 (void) fprintf(stderr,
5234                     gettext("missing <device> specification\n"));
5235                 usage(B_FALSE);
5236         }
5237
5238         old_disk = argv[1];
5239
5240         if (argc < 3) {
5241                 if (!replacing) {
5242                         (void) fprintf(stderr,
5243                             gettext("missing <new_device> specification\n"));
5244                         usage(B_FALSE);
5245                 }
5246                 new_disk = old_disk;
5247                 argc -= 1;
5248                 argv += 1;
5249         } else {
5250                 new_disk = argv[2];
5251                 argc -= 2;
5252                 argv += 2;
5253         }
5254
5255         if (argc > 1) {
5256                 (void) fprintf(stderr, gettext("too many arguments\n"));
5257                 usage(B_FALSE);
5258         }
5259
5260         if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
5261                 nvlist_free(props);
5262                 return (1);
5263         }
5264
5265         if (zpool_get_config(zhp, NULL) == NULL) {
5266                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
5267                     poolname);
5268                 zpool_close(zhp);
5269                 nvlist_free(props);
5270                 return (1);
5271         }
5272
5273         /* unless manually specified use "ashift" pool property (if set) */
5274         if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
5275                 int intval;
5276                 zprop_source_t src;
5277                 char strval[ZPOOL_MAXPROPLEN];
5278
5279                 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
5280                 if (src != ZPROP_SRC_DEFAULT) {
5281                         (void) sprintf(strval, "%" PRId32, intval);
5282                         verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
5283                             &props, B_TRUE) == 0);
5284                 }
5285         }
5286
5287         nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE,
5288             argc, argv);
5289         if (nvroot == NULL) {
5290                 zpool_close(zhp);
5291                 nvlist_free(props);
5292                 return (1);
5293         }
5294
5295         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
5296
5297         nvlist_free(props);
5298         nvlist_free(nvroot);
5299         zpool_close(zhp);
5300
5301         return (ret);
5302 }
5303
5304 /*
5305  * zpool replace [-f] <pool> <device> <new_device>
5306  *
5307  *      -f      Force attach, even if <new_device> appears to be in use.
5308  *
5309  * Replace <device> with <new_device>.
5310  */
5311 /* ARGSUSED */
5312 int
5313 zpool_do_replace(int argc, char **argv)
5314 {
5315         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
5316 }
5317
5318 /*
5319  * zpool attach [-f] [-o property=value] <pool> <device> <new_device>
5320  *
5321  *      -f      Force attach, even if <new_device> appears to be in use.
5322  *      -o      Set property=value.
5323  *
5324  * Attach <new_device> to the mirror containing <device>.  If <device> is not
5325  * part of a mirror, then <device> will be transformed into a mirror of
5326  * <device> and <new_device>.  In either case, <new_device> will begin life
5327  * with a DTL of [0, now], and will immediately begin to resilver itself.
5328  */
5329 int
5330 zpool_do_attach(int argc, char **argv)
5331 {
5332         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
5333 }
5334
5335 /*
5336  * zpool detach [-f] <pool> <device>
5337  *
5338  *      -f      Force detach of <device>, even if DTLs argue against it
5339  *              (not supported yet)
5340  *
5341  * Detach a device from a mirror.  The operation will be refused if <device>
5342  * is the last device in the mirror, or if the DTLs indicate that this device
5343  * has the only valid copy of some data.
5344  */
5345 /* ARGSUSED */
5346 int
5347 zpool_do_detach(int argc, char **argv)
5348 {
5349         int c;
5350         char *poolname, *path;
5351         zpool_handle_t *zhp;
5352         int ret;
5353
5354         /* check options */
5355         while ((c = getopt(argc, argv, "f")) != -1) {
5356                 switch (c) {
5357                 case 'f':
5358                 case '?':
5359                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5360                             optopt);
5361                         usage(B_FALSE);
5362                 }
5363         }
5364
5365         argc -= optind;
5366         argv += optind;
5367
5368         /* get pool name and check number of arguments */
5369         if (argc < 1) {
5370                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5371                 usage(B_FALSE);
5372         }
5373
5374         if (argc < 2) {
5375                 (void) fprintf(stderr,
5376                     gettext("missing <device> specification\n"));
5377                 usage(B_FALSE);
5378         }
5379
5380         poolname = argv[0];
5381         path = argv[1];
5382
5383         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5384                 return (1);
5385
5386         ret = zpool_vdev_detach(zhp, path);
5387
5388         zpool_close(zhp);
5389
5390         return (ret);
5391 }
5392
5393 /*
5394  * zpool split [-gLnP] [-o prop=val] ...
5395  *              [-o mntopt] ...
5396  *              [-R altroot] <pool> <newpool> [<device> ...]
5397  *
5398  *      -g      Display guid for individual vdev name.
5399  *      -L      Follow links when resolving vdev path name.
5400  *      -n      Do not split the pool, but display the resulting layout if
5401  *              it were to be split.
5402  *      -o      Set property=value, or set mount options.
5403  *      -P      Display full path for vdev name.
5404  *      -R      Mount the split-off pool under an alternate root.
5405  *      -l      Load encryption keys while importing.
5406  *
5407  * Splits the named pool and gives it the new pool name.  Devices to be split
5408  * off may be listed, provided that no more than one device is specified
5409  * per top-level vdev mirror.  The newly split pool is left in an exported
5410  * state unless -R is specified.
5411  *
5412  * Restrictions: the top-level of the pool pool must only be made up of
5413  * mirrors; all devices in the pool must be healthy; no device may be
5414  * undergoing a resilvering operation.
5415  */
5416 int
5417 zpool_do_split(int argc, char **argv)
5418 {
5419         char *srcpool, *newpool, *propval;
5420         char *mntopts = NULL;
5421         splitflags_t flags;
5422         int c, ret = 0;
5423         boolean_t loadkeys = B_FALSE;
5424         zpool_handle_t *zhp;
5425         nvlist_t *config, *props = NULL;
5426
5427         flags.dryrun = B_FALSE;
5428         flags.import = B_FALSE;
5429         flags.name_flags = 0;
5430
5431         /* check options */
5432         while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) {
5433                 switch (c) {
5434                 case 'g':
5435                         flags.name_flags |= VDEV_NAME_GUID;
5436                         break;
5437                 case 'L':
5438                         flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
5439                         break;
5440                 case 'R':
5441                         flags.import = B_TRUE;
5442                         if (add_prop_list(
5443                             zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
5444                             &props, B_TRUE) != 0) {
5445                                 nvlist_free(props);
5446                                 usage(B_FALSE);
5447                         }
5448                         break;
5449                 case 'l':
5450                         loadkeys = B_TRUE;
5451                         break;
5452                 case 'n':
5453                         flags.dryrun = B_TRUE;
5454                         break;
5455                 case 'o':
5456                         if ((propval = strchr(optarg, '=')) != NULL) {
5457                                 *propval = '\0';
5458                                 propval++;
5459                                 if (add_prop_list(optarg, propval,
5460                                     &props, B_TRUE) != 0) {
5461                                         nvlist_free(props);
5462                                         usage(B_FALSE);
5463                                 }
5464                         } else {
5465                                 mntopts = optarg;
5466                         }
5467                         break;
5468                 case 'P':
5469                         flags.name_flags |= VDEV_NAME_PATH;
5470                         break;
5471                 case ':':
5472                         (void) fprintf(stderr, gettext("missing argument for "
5473                             "'%c' option\n"), optopt);
5474                         usage(B_FALSE);
5475                         break;
5476                 case '?':
5477                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5478                             optopt);
5479                         usage(B_FALSE);
5480                         break;
5481                 }
5482         }
5483
5484         if (!flags.import && mntopts != NULL) {
5485                 (void) fprintf(stderr, gettext("setting mntopts is only "
5486                     "valid when importing the pool\n"));
5487                 usage(B_FALSE);
5488         }
5489
5490         if (!flags.import && loadkeys) {
5491                 (void) fprintf(stderr, gettext("loading keys is only "
5492                     "valid when importing the pool\n"));
5493                 usage(B_FALSE);
5494         }
5495
5496         argc -= optind;
5497         argv += optind;
5498
5499         if (argc < 1) {
5500                 (void) fprintf(stderr, gettext("Missing pool name\n"));
5501                 usage(B_FALSE);
5502         }
5503         if (argc < 2) {
5504                 (void) fprintf(stderr, gettext("Missing new pool name\n"));
5505                 usage(B_FALSE);
5506         }
5507
5508         srcpool = argv[0];
5509         newpool = argv[1];
5510
5511         argc -= 2;
5512         argv += 2;
5513
5514         if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) {
5515                 nvlist_free(props);
5516                 return (1);
5517         }
5518
5519         config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
5520         if (config == NULL) {
5521                 ret = 1;
5522         } else {
5523                 if (flags.dryrun) {
5524                         (void) printf(gettext("would create '%s' with the "
5525                             "following layout:\n\n"), newpool);
5526                         print_vdev_tree(NULL, newpool, config, 0, B_FALSE,
5527                             flags.name_flags);
5528                 }
5529         }
5530
5531         zpool_close(zhp);
5532
5533         if (ret != 0 || flags.dryrun || !flags.import) {
5534                 nvlist_free(config);
5535                 nvlist_free(props);
5536                 return (ret);
5537         }
5538
5539         /*
5540          * The split was successful. Now we need to open the new
5541          * pool and import it.
5542          */
5543         if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) {
5544                 nvlist_free(config);
5545                 nvlist_free(props);
5546                 return (1);
5547         }
5548
5549         if (loadkeys) {
5550                 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool);
5551                 if (ret != 0)
5552                         ret = 1;
5553         }
5554
5555         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
5556             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
5557                 ret = 1;
5558                 (void) fprintf(stderr, gettext("Split was successful, but "
5559                     "the datasets could not all be mounted\n"));
5560                 (void) fprintf(stderr, gettext("Try doing '%s' with a "
5561                     "different altroot\n"), "zpool import");
5562         }
5563         zpool_close(zhp);
5564         nvlist_free(config);
5565         nvlist_free(props);
5566
5567         return (ret);
5568 }
5569
5570
5571
5572 /*
5573  * zpool online <pool> <device> ...
5574  */
5575 int
5576 zpool_do_online(int argc, char **argv)
5577 {
5578         int c, i;
5579         char *poolname;
5580         zpool_handle_t *zhp;
5581         int ret = 0;
5582         vdev_state_t newstate;
5583         int flags = 0;
5584
5585         /* check options */
5586         while ((c = getopt(argc, argv, "et")) != -1) {
5587                 switch (c) {
5588                 case 'e':
5589                         flags |= ZFS_ONLINE_EXPAND;
5590                         break;
5591                 case 't':
5592                 case '?':
5593                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5594                             optopt);
5595                         usage(B_FALSE);
5596                 }
5597         }
5598
5599         argc -= optind;
5600         argv += optind;
5601
5602         /* get pool name and check number of arguments */
5603         if (argc < 1) {
5604                 (void) fprintf(stderr, gettext("missing pool name\n"));
5605                 usage(B_FALSE);
5606         }
5607         if (argc < 2) {
5608                 (void) fprintf(stderr, gettext("missing device name\n"));
5609                 usage(B_FALSE);
5610         }
5611
5612         poolname = argv[0];
5613
5614         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5615                 return (1);
5616
5617         for (i = 1; i < argc; i++) {
5618                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
5619                         if (newstate != VDEV_STATE_HEALTHY) {
5620                                 (void) printf(gettext("warning: device '%s' "
5621                                     "onlined, but remains in faulted state\n"),
5622                                     argv[i]);
5623                                 if (newstate == VDEV_STATE_FAULTED)
5624                                         (void) printf(gettext("use 'zpool "
5625                                             "clear' to restore a faulted "
5626                                             "device\n"));
5627                                 else
5628                                         (void) printf(gettext("use 'zpool "
5629                                             "replace' to replace devices "
5630                                             "that are no longer present\n"));
5631                         }
5632                 } else {
5633                         ret = 1;
5634                 }
5635         }
5636
5637         zpool_close(zhp);
5638
5639         return (ret);
5640 }
5641
5642 /*
5643  * zpool offline [-ft] <pool> <device> ...
5644  *
5645  *      -f      Force the device into a faulted state.
5646  *
5647  *      -t      Only take the device off-line temporarily.  The offline/faulted
5648  *              state will not be persistent across reboots.
5649  */
5650 /* ARGSUSED */
5651 int
5652 zpool_do_offline(int argc, char **argv)
5653 {
5654         int c, i;
5655         char *poolname;
5656         zpool_handle_t *zhp;
5657         int ret = 0;
5658         boolean_t istmp = B_FALSE;
5659         boolean_t fault = B_FALSE;
5660
5661         /* check options */
5662         while ((c = getopt(argc, argv, "ft")) != -1) {
5663                 switch (c) {
5664                 case 'f':
5665                         fault = B_TRUE;
5666                         break;
5667                 case 't':
5668                         istmp = B_TRUE;
5669                         break;
5670                 case '?':
5671                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5672                             optopt);
5673                         usage(B_FALSE);
5674                 }
5675         }
5676
5677         argc -= optind;
5678         argv += optind;
5679
5680         /* get pool name and check number of arguments */
5681         if (argc < 1) {
5682                 (void) fprintf(stderr, gettext("missing pool name\n"));
5683                 usage(B_FALSE);
5684         }
5685         if (argc < 2) {
5686                 (void) fprintf(stderr, gettext("missing device name\n"));
5687                 usage(B_FALSE);
5688         }
5689
5690         poolname = argv[0];
5691
5692         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5693                 return (1);
5694
5695         for (i = 1; i < argc; i++) {
5696                 if (fault) {
5697                         uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
5698                         vdev_aux_t aux;
5699                         if (istmp == B_FALSE) {
5700                                 /* Force the fault to persist across imports */
5701                                 aux = VDEV_AUX_EXTERNAL_PERSIST;
5702                         } else {
5703                                 aux = VDEV_AUX_EXTERNAL;
5704                         }
5705
5706                         if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0)
5707                                 ret = 1;
5708                 } else {
5709                         if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
5710                                 ret = 1;
5711                 }
5712         }
5713
5714         zpool_close(zhp);
5715
5716         return (ret);
5717 }
5718
5719 /*
5720  * zpool clear <pool> [device]
5721  *
5722  * Clear all errors associated with a pool or a particular device.
5723  */
5724 int
5725 zpool_do_clear(int argc, char **argv)
5726 {
5727         int c;
5728         int ret = 0;
5729         boolean_t dryrun = B_FALSE;
5730         boolean_t do_rewind = B_FALSE;
5731         boolean_t xtreme_rewind = B_FALSE;
5732         uint32_t rewind_policy = ZPOOL_NO_REWIND;
5733         nvlist_t *policy = NULL;
5734         zpool_handle_t *zhp;
5735         char *pool, *device;
5736
5737         /* check options */
5738         while ((c = getopt(argc, argv, "FnX")) != -1) {
5739                 switch (c) {
5740                 case 'F':
5741                         do_rewind = B_TRUE;
5742                         break;
5743                 case 'n':
5744                         dryrun = B_TRUE;
5745                         break;
5746                 case 'X':
5747                         xtreme_rewind = B_TRUE;
5748                         break;
5749                 case '?':
5750                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5751                             optopt);
5752                         usage(B_FALSE);
5753                 }
5754         }
5755
5756         argc -= optind;
5757         argv += optind;
5758
5759         if (argc < 1) {
5760                 (void) fprintf(stderr, gettext("missing pool name\n"));
5761                 usage(B_FALSE);
5762         }
5763
5764         if (argc > 2) {
5765                 (void) fprintf(stderr, gettext("too many arguments\n"));
5766                 usage(B_FALSE);
5767         }
5768
5769         if ((dryrun || xtreme_rewind) && !do_rewind) {
5770                 (void) fprintf(stderr,
5771                     gettext("-n or -X only meaningful with -F\n"));
5772                 usage(B_FALSE);
5773         }
5774         if (dryrun)
5775                 rewind_policy = ZPOOL_TRY_REWIND;
5776         else if (do_rewind)
5777                 rewind_policy = ZPOOL_DO_REWIND;
5778         if (xtreme_rewind)
5779                 rewind_policy |= ZPOOL_EXTREME_REWIND;
5780
5781         /* In future, further rewind policy choices can be passed along here */
5782         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
5783             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
5784                 return (1);
5785
5786         pool = argv[0];
5787         device = argc == 2 ? argv[1] : NULL;
5788
5789         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
5790                 nvlist_free(policy);
5791                 return (1);
5792         }
5793
5794         if (zpool_clear(zhp, device, policy) != 0)
5795                 ret = 1;
5796
5797         zpool_close(zhp);
5798
5799         nvlist_free(policy);
5800
5801         return (ret);
5802 }
5803
5804 /*
5805  * zpool reguid <pool>
5806  */
5807 int
5808 zpool_do_reguid(int argc, char **argv)
5809 {
5810         int c;
5811         char *poolname;
5812         zpool_handle_t *zhp;
5813         int ret = 0;
5814
5815         /* check options */
5816         while ((c = getopt(argc, argv, "")) != -1) {
5817                 switch (c) {
5818                 case '?':
5819                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5820                             optopt);
5821                         usage(B_FALSE);
5822                 }
5823         }
5824
5825         argc -= optind;
5826         argv += optind;
5827
5828         /* get pool name and check number of arguments */
5829         if (argc < 1) {
5830                 (void) fprintf(stderr, gettext("missing pool name\n"));
5831                 usage(B_FALSE);
5832         }
5833
5834         if (argc > 1) {
5835                 (void) fprintf(stderr, gettext("too many arguments\n"));
5836                 usage(B_FALSE);
5837         }
5838
5839         poolname = argv[0];
5840         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5841                 return (1);
5842
5843         ret = zpool_reguid(zhp);
5844
5845         zpool_close(zhp);
5846         return (ret);
5847 }
5848
5849
5850 /*
5851  * zpool reopen <pool>
5852  *
5853  * Reopen the pool so that the kernel can update the sizes of all vdevs.
5854  */
5855 int
5856 zpool_do_reopen(int argc, char **argv)
5857 {
5858         int c;
5859         int ret = 0;
5860         boolean_t scrub_restart = B_TRUE;
5861
5862         /* check options */
5863         while ((c = getopt(argc, argv, "n")) != -1) {
5864                 switch (c) {
5865                 case 'n':
5866                         scrub_restart = B_FALSE;
5867                         break;
5868                 case '?':
5869                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5870                             optopt);
5871                         usage(B_FALSE);
5872                 }
5873         }
5874
5875         argc -= optind;
5876         argv += optind;
5877
5878         /* if argc == 0 we will execute zpool_reopen_one on all pools */
5879         ret = for_each_pool(argc, argv, B_TRUE, NULL, zpool_reopen_one,
5880             &scrub_restart);
5881
5882         return (ret);
5883 }
5884
5885 typedef struct scrub_cbdata {
5886         int     cb_type;
5887         int     cb_argc;
5888         char    **cb_argv;
5889         pool_scrub_cmd_t cb_scrub_cmd;
5890 } scrub_cbdata_t;
5891
5892 int
5893 scrub_callback(zpool_handle_t *zhp, void *data)
5894 {
5895         scrub_cbdata_t *cb = data;
5896         int err;
5897
5898         /*
5899          * Ignore faulted pools.
5900          */
5901         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5902                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
5903                     "currently unavailable\n"), zpool_get_name(zhp));
5904                 return (1);
5905         }
5906
5907         err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
5908
5909         return (err != 0);
5910 }
5911
5912 /*
5913  * zpool scrub [-s | -p] <pool> ...
5914  *
5915  *      -s      Stop.  Stops any in-progress scrub.
5916  *      -p      Pause. Pause in-progress scrub.
5917  */
5918 int
5919 zpool_do_scrub(int argc, char **argv)
5920 {
5921         int c;
5922         scrub_cbdata_t cb;
5923
5924         cb.cb_type = POOL_SCAN_SCRUB;
5925         cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
5926
5927         /* check options */
5928         while ((c = getopt(argc, argv, "sp")) != -1) {
5929                 switch (c) {
5930                 case 's':
5931                         cb.cb_type = POOL_SCAN_NONE;
5932                         break;
5933                 case 'p':
5934                         cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
5935                         break;
5936                 case '?':
5937                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5938                             optopt);
5939                         usage(B_FALSE);
5940                 }
5941         }
5942
5943         if (cb.cb_type == POOL_SCAN_NONE &&
5944             cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
5945                 (void) fprintf(stderr, gettext("invalid option combination: "
5946                     "-s and -p are mutually exclusive\n"));
5947                 usage(B_FALSE);
5948         }
5949
5950         cb.cb_argc = argc;
5951         cb.cb_argv = argv;
5952         argc -= optind;
5953         argv += optind;
5954
5955         if (argc < 1) {
5956                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5957                 usage(B_FALSE);
5958         }
5959
5960         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
5961 }
5962
5963 /*
5964  * Print out detailed scrub status.
5965  */
5966 void
5967 print_scan_status(pool_scan_stat_t *ps)
5968 {
5969         time_t start, end, pause;
5970         uint64_t elapsed, mins_left, hours_left;
5971         uint64_t pass_exam, examined, total;
5972         uint_t rate;
5973         double fraction_done;
5974         char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
5975
5976         (void) printf(gettext("  scan: "));
5977
5978         /* If there's never been a scan, there's not much to say. */
5979         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
5980             ps->pss_func >= POOL_SCAN_FUNCS) {
5981                 (void) printf(gettext("none requested\n"));
5982                 return;
5983         }
5984
5985         start = ps->pss_start_time;
5986         end = ps->pss_end_time;
5987         pause = ps->pss_pass_scrub_pause;
5988         zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf));
5989
5990         assert(ps->pss_func == POOL_SCAN_SCRUB ||
5991             ps->pss_func == POOL_SCAN_RESILVER);
5992         /*
5993          * Scan is finished or canceled.
5994          */
5995         if (ps->pss_state == DSS_FINISHED) {
5996                 uint64_t minutes_taken = (end - start) / 60;
5997                 char *fmt = NULL;
5998
5999                 if (ps->pss_func == POOL_SCAN_SCRUB) {
6000                         fmt = gettext("scrub repaired %s in %lluh%um with "
6001                             "%llu errors on %s");
6002                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6003                         fmt = gettext("resilvered %s in %lluh%um with "
6004                             "%llu errors on %s");
6005                 }
6006                 /* LINTED */
6007                 (void) printf(fmt, processed_buf,
6008                     (u_longlong_t)(minutes_taken / 60),
6009                     (uint_t)(minutes_taken % 60),
6010                     (u_longlong_t)ps->pss_errors,
6011                     ctime((time_t *)&end));
6012                 return;
6013         } else if (ps->pss_state == DSS_CANCELED) {
6014                 if (ps->pss_func == POOL_SCAN_SCRUB) {
6015                         (void) printf(gettext("scrub canceled on %s"),
6016                             ctime(&end));
6017                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6018                         (void) printf(gettext("resilver canceled on %s"),
6019                             ctime(&end));
6020                 }
6021                 return;
6022         }
6023
6024         assert(ps->pss_state == DSS_SCANNING);
6025
6026         /*
6027          * Scan is in progress.
6028          */
6029         if (ps->pss_func == POOL_SCAN_SCRUB) {
6030                 if (pause == 0) {
6031                         (void) printf(gettext("scrub in progress since %s"),
6032                             ctime(&start));
6033                 } else {
6034                         char buf[32];
6035                         struct tm *p = localtime(&pause);
6036                         (void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
6037                         (void) printf(gettext("scrub paused since %s\n"), buf);
6038                         (void) printf(gettext("\tscrub started on   %s"),
6039                             ctime(&start));
6040                 }
6041         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6042                 (void) printf(gettext("resilver in progress since %s"),
6043                     ctime(&start));
6044         }
6045
6046         examined = ps->pss_examined ? ps->pss_examined : 1;
6047         total = ps->pss_to_examine;
6048         fraction_done = (double)examined / total;
6049
6050         /* elapsed time for this pass */
6051         elapsed = time(NULL) - ps->pss_pass_start;
6052         elapsed -= ps->pss_pass_scrub_spent_paused;
6053         elapsed = elapsed ? elapsed : 1;
6054         pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
6055         rate = pass_exam / elapsed;
6056         rate = rate ? rate : 1;
6057         mins_left = ((total - examined) / rate) / 60;
6058         hours_left = mins_left / 60;
6059
6060         zfs_nicebytes(examined, examined_buf, sizeof (examined_buf));
6061         zfs_nicebytes(total, total_buf, sizeof (total_buf));
6062
6063         /*
6064          * do not print estimated time if hours_left is more than 30 days
6065          * or we have a paused scrub
6066          */
6067         if (pause == 0) {
6068                 zfs_nicebytes(rate, rate_buf, sizeof (rate_buf));
6069                 (void) printf(gettext("\t%s scanned out of %s at %s/s"),
6070                     examined_buf, total_buf, rate_buf);
6071                 if (hours_left < (30 * 24)) {
6072                         (void) printf(gettext(", %lluh%um to go\n"),
6073                             (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
6074                 } else {
6075                         (void) printf(gettext(
6076                             ", (scan is slow, no estimated time)\n"));
6077                 }
6078         } else {
6079                 (void) printf(gettext("\t%s scanned out of %s\n"),
6080                     examined_buf, total_buf);
6081         }
6082
6083         if (ps->pss_func == POOL_SCAN_RESILVER) {
6084                 (void) printf(gettext("\t%s resilvered, %.2f%% done\n"),
6085                     processed_buf, 100 * fraction_done);
6086         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
6087                 (void) printf(gettext("\t%s repaired, %.2f%% done\n"),
6088                     processed_buf, 100 * fraction_done);
6089         }
6090 }
6091
6092 static void
6093 print_error_log(zpool_handle_t *zhp)
6094 {
6095         nvlist_t *nverrlist = NULL;
6096         nvpair_t *elem;
6097         char *pathname;
6098         size_t len = MAXPATHLEN * 2;
6099
6100         if (zpool_get_errlog(zhp, &nverrlist) != 0)
6101                 return;
6102
6103         (void) printf("errors: Permanent errors have been "
6104             "detected in the following files:\n\n");
6105
6106         pathname = safe_malloc(len);
6107         elem = NULL;
6108         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
6109                 nvlist_t *nv;
6110                 uint64_t dsobj, obj;
6111
6112                 verify(nvpair_value_nvlist(elem, &nv) == 0);
6113                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
6114                     &dsobj) == 0);
6115                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
6116                     &obj) == 0);
6117                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
6118                 (void) printf("%7s %s\n", "", pathname);
6119         }
6120         free(pathname);
6121         nvlist_free(nverrlist);
6122 }
6123
6124 static void
6125 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares,
6126     uint_t nspares)
6127 {
6128         uint_t i;
6129         char *name;
6130
6131         if (nspares == 0)
6132                 return;
6133
6134         (void) printf(gettext("\tspares\n"));
6135
6136         for (i = 0; i < nspares; i++) {
6137                 name = zpool_vdev_name(g_zfs, zhp, spares[i],
6138                     cb->cb_name_flags);
6139                 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE);
6140                 free(name);
6141         }
6142 }
6143
6144 static void
6145 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache,
6146     uint_t nl2cache)
6147 {
6148         uint_t i;
6149         char *name;
6150
6151         if (nl2cache == 0)
6152                 return;
6153
6154         (void) printf(gettext("\tcache\n"));
6155
6156         for (i = 0; i < nl2cache; i++) {
6157                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i],
6158                     cb->cb_name_flags);
6159                 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE);
6160                 free(name);
6161         }
6162 }
6163
6164 static void
6165 print_dedup_stats(nvlist_t *config)
6166 {
6167         ddt_histogram_t *ddh;
6168         ddt_stat_t *dds;
6169         ddt_object_t *ddo;
6170         uint_t c;
6171         char dspace[6], mspace[6];
6172
6173         /*
6174          * If the pool was faulted then we may not have been able to
6175          * obtain the config. Otherwise, if we have anything in the dedup
6176          * table continue processing the stats.
6177          */
6178         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
6179             (uint64_t **)&ddo, &c) != 0)
6180                 return;
6181
6182         (void) printf("\n");
6183         (void) printf(gettext(" dedup: "));
6184         if (ddo->ddo_count == 0) {
6185                 (void) printf(gettext("no DDT entries\n"));
6186                 return;
6187         }
6188
6189         zfs_nicebytes(ddo->ddo_dspace, dspace, sizeof (dspace));
6190         zfs_nicebytes(ddo->ddo_mspace, mspace, sizeof (mspace));
6191         (void) printf("DDT entries %llu, size %s on disk, %s in core\n",
6192             (u_longlong_t)ddo->ddo_count,
6193             dspace,
6194             mspace);
6195
6196         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
6197             (uint64_t **)&dds, &c) == 0);
6198         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
6199             (uint64_t **)&ddh, &c) == 0);
6200         zpool_dump_ddt(dds, ddh);
6201 }
6202
6203 /*
6204  * Display a summary of pool status.  Displays a summary such as:
6205  *
6206  *        pool: tank
6207  *      status: DEGRADED
6208  *      reason: One or more devices ...
6209  *         see: http://zfsonlinux.org/msg/ZFS-xxxx-01
6210  *      config:
6211  *              mirror          DEGRADED
6212  *                c1t0d0        OK
6213  *                c2t0d0        UNAVAIL
6214  *
6215  * When given the '-v' option, we print out the complete config.  If the '-e'
6216  * option is specified, then we print out error rate information as well.
6217  */
6218 int
6219 status_callback(zpool_handle_t *zhp, void *data)
6220 {
6221         status_cbdata_t *cbp = data;
6222         nvlist_t *config, *nvroot;
6223         char *msgid;
6224         zpool_status_t reason;
6225         zpool_errata_t errata;
6226         const char *health;
6227         uint_t c;
6228         vdev_stat_t *vs;
6229
6230         config = zpool_get_config(zhp, NULL);
6231         reason = zpool_get_status(zhp, &msgid, &errata);
6232
6233         cbp->cb_count++;
6234
6235         /*
6236          * If we were given 'zpool status -x', only report those pools with
6237          * problems.
6238          */
6239         if (cbp->cb_explain &&
6240             (reason == ZPOOL_STATUS_OK ||
6241             reason == ZPOOL_STATUS_VERSION_OLDER ||
6242             reason == ZPOOL_STATUS_FEAT_DISABLED)) {
6243                 if (!cbp->cb_allpools) {
6244                         (void) printf(gettext("pool '%s' is healthy\n"),
6245                             zpool_get_name(zhp));
6246                         if (cbp->cb_first)
6247                                 cbp->cb_first = B_FALSE;
6248                 }
6249                 return (0);
6250         }
6251
6252         if (cbp->cb_first)
6253                 cbp->cb_first = B_FALSE;
6254         else
6255                 (void) printf("\n");
6256
6257         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
6258             &nvroot) == 0);
6259         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
6260             (uint64_t **)&vs, &c) == 0);
6261         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
6262
6263         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
6264         (void) printf(gettext(" state: %s\n"), health);
6265
6266         switch (reason) {
6267         case ZPOOL_STATUS_MISSING_DEV_R:
6268                 (void) printf(gettext("status: One or more devices could not "
6269                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
6270                     "continue functioning in a degraded state.\n"));
6271                 (void) printf(gettext("action: Attach the missing device and "
6272                     "online it using 'zpool online'.\n"));
6273                 break;
6274
6275         case ZPOOL_STATUS_MISSING_DEV_NR:
6276                 (void) printf(gettext("status: One or more devices could not "
6277                     "be opened.  There are insufficient\n\treplicas for the "
6278                     "pool to continue functioning.\n"));
6279                 (void) printf(gettext("action: Attach the missing device and "
6280                     "online it using 'zpool online'.\n"));
6281                 break;
6282
6283         case ZPOOL_STATUS_CORRUPT_LABEL_R:
6284                 (void) printf(gettext("status: One or more devices could not "
6285                     "be used because the label is missing or\n\tinvalid.  "
6286                     "Sufficient replicas exist for the pool to continue\n\t"
6287                     "functioning in a degraded state.\n"));
6288                 (void) printf(gettext("action: Replace the device using "
6289                     "'zpool replace'.\n"));
6290                 break;
6291
6292         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
6293                 (void) printf(gettext("status: One or more devices could not "
6294                     "be used because the label is missing \n\tor invalid.  "
6295                     "There are insufficient replicas for the pool to "
6296                     "continue\n\tfunctioning.\n"));
6297                 zpool_explain_recover(zpool_get_handle(zhp),
6298                     zpool_get_name(zhp), reason, config);
6299                 break;
6300
6301         case ZPOOL_STATUS_FAILING_DEV:
6302                 (void) printf(gettext("status: One or more devices has "
6303                     "experienced an unrecoverable error.  An\n\tattempt was "
6304                     "made to correct the error.  Applications are "
6305                     "unaffected.\n"));
6306                 (void) printf(gettext("action: Determine if the device needs "
6307                     "to be replaced, and clear the errors\n\tusing "
6308                     "'zpool clear' or replace the device with 'zpool "
6309                     "replace'.\n"));
6310                 break;
6311
6312         case ZPOOL_STATUS_OFFLINE_DEV:
6313                 (void) printf(gettext("status: One or more devices has "
6314                     "been taken offline by the administrator.\n\tSufficient "
6315                     "replicas exist for the pool to continue functioning in "
6316                     "a\n\tdegraded state.\n"));
6317                 (void) printf(gettext("action: Online the device using "
6318                     "'zpool online' or replace the device with\n\t'zpool "
6319                     "replace'.\n"));
6320                 break;
6321
6322         case ZPOOL_STATUS_REMOVED_DEV:
6323                 (void) printf(gettext("status: One or more devices has "
6324                     "been removed by the administrator.\n\tSufficient "
6325                     "replicas exist for the pool to continue functioning in "
6326                     "a\n\tdegraded state.\n"));
6327                 (void) printf(gettext("action: Online the device using "
6328                     "'zpool online' or replace the device with\n\t'zpool "
6329                     "replace'.\n"));
6330                 break;
6331
6332         case ZPOOL_STATUS_RESILVERING:
6333                 (void) printf(gettext("status: One or more devices is "
6334                     "currently being resilvered.  The pool will\n\tcontinue "
6335                     "to function, possibly in a degraded state.\n"));
6336                 (void) printf(gettext("action: Wait for the resilver to "
6337                     "complete.\n"));
6338                 break;
6339
6340         case ZPOOL_STATUS_CORRUPT_DATA:
6341                 (void) printf(gettext("status: One or more devices has "
6342                     "experienced an error resulting in data\n\tcorruption.  "
6343                     "Applications may be affected.\n"));
6344                 (void) printf(gettext("action: Restore the file in question "
6345                     "if possible.  Otherwise restore the\n\tentire pool from "
6346                     "backup.\n"));
6347                 break;
6348
6349         case ZPOOL_STATUS_CORRUPT_POOL:
6350                 (void) printf(gettext("status: The pool metadata is corrupted "
6351                     "and the pool cannot be opened.\n"));
6352                 zpool_explain_recover(zpool_get_handle(zhp),
6353                     zpool_get_name(zhp), reason, config);
6354                 break;
6355
6356         case ZPOOL_STATUS_VERSION_OLDER:
6357                 (void) printf(gettext("status: The pool is formatted using a "
6358                     "legacy on-disk format.  The pool can\n\tstill be used, "
6359                     "but some features are unavailable.\n"));
6360                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
6361                     "upgrade'.  Once this is done, the\n\tpool will no longer "
6362                     "be accessible on software that does not support\n\t"
6363                     "feature flags.\n"));
6364                 break;
6365
6366         case ZPOOL_STATUS_VERSION_NEWER:
6367                 (void) printf(gettext("status: The pool has been upgraded to a "
6368                     "newer, incompatible on-disk version.\n\tThe pool cannot "
6369                     "be accessed on this system.\n"));
6370                 (void) printf(gettext("action: Access the pool from a system "
6371                     "running more recent software, or\n\trestore the pool from "
6372                     "backup.\n"));
6373                 break;
6374
6375         case ZPOOL_STATUS_FEAT_DISABLED:
6376                 (void) printf(gettext("status: Some supported features are not "
6377                     "enabled on the pool. The pool can\n\tstill be used, but "
6378                     "some features are unavailable.\n"));
6379                 (void) printf(gettext("action: Enable all features using "
6380                     "'zpool upgrade'. Once this is done,\n\tthe pool may no "
6381                     "longer be accessible by software that does not support\n\t"
6382                     "the features. See zpool-features(5) for details.\n"));
6383                 break;
6384
6385         case ZPOOL_STATUS_UNSUP_FEAT_READ:
6386                 (void) printf(gettext("status: The pool cannot be accessed on "
6387                     "this system because it uses the\n\tfollowing feature(s) "
6388                     "not supported on this system:\n"));
6389                 zpool_print_unsup_feat(config);
6390                 (void) printf("\n");
6391                 (void) printf(gettext("action: Access the pool from a system "
6392                     "that supports the required feature(s),\n\tor restore the "
6393                     "pool from backup.\n"));
6394                 break;
6395
6396         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
6397                 (void) printf(gettext("status: The pool can only be accessed "
6398                     "in read-only mode on this system. It\n\tcannot be "
6399                     "accessed in read-write mode because it uses the "
6400                     "following\n\tfeature(s) not supported on this system:\n"));
6401                 zpool_print_unsup_feat(config);
6402                 (void) printf("\n");
6403                 (void) printf(gettext("action: The pool cannot be accessed in "
6404                     "read-write mode. Import the pool with\n"
6405                     "\t\"-o readonly=on\", access the pool from a system that "
6406                     "supports the\n\trequired feature(s), or restore the "
6407                     "pool from backup.\n"));
6408                 break;
6409
6410         case ZPOOL_STATUS_FAULTED_DEV_R:
6411                 (void) printf(gettext("status: One or more devices are "
6412                     "faulted in response to persistent errors.\n\tSufficient "
6413                     "replicas exist for the pool to continue functioning "
6414                     "in a\n\tdegraded state.\n"));
6415                 (void) printf(gettext("action: Replace the faulted device, "
6416                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
6417                 break;
6418
6419         case ZPOOL_STATUS_FAULTED_DEV_NR:
6420                 (void) printf(gettext("status: One or more devices are "
6421                     "faulted in response to persistent errors.  There are "
6422                     "insufficient replicas for the pool to\n\tcontinue "
6423                     "functioning.\n"));
6424                 (void) printf(gettext("action: Destroy and re-create the pool "
6425                     "from a backup source.  Manually marking the device\n"
6426                     "\trepaired using 'zpool clear' may allow some data "
6427                     "to be recovered.\n"));
6428                 break;
6429
6430         case ZPOOL_STATUS_IO_FAILURE_WAIT:
6431         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
6432                 (void) printf(gettext("status: One or more devices are "
6433                     "faulted in response to IO failures.\n"));
6434                 (void) printf(gettext("action: Make sure the affected devices "
6435                     "are connected, then run 'zpool clear'.\n"));
6436                 break;
6437
6438         case ZPOOL_STATUS_BAD_LOG:
6439                 (void) printf(gettext("status: An intent log record "
6440                     "could not be read.\n"
6441                     "\tWaiting for administrator intervention to fix the "
6442                     "faulted pool.\n"));
6443                 (void) printf(gettext("action: Either restore the affected "
6444                     "device(s) and run 'zpool online',\n"
6445                     "\tor ignore the intent log records by running "
6446                     "'zpool clear'.\n"));
6447                 break;
6448
6449         case ZPOOL_STATUS_HOSTID_MISMATCH:
6450                 (void) printf(gettext("status: Mismatch between pool hostid "
6451                     "and system hostid on imported pool.\n\tThis pool was "
6452                     "previously imported into a system with a different "
6453                     "hostid,\n\tand then was verbatim imported into this "
6454                     "system.\n"));
6455                 (void) printf(gettext("action: Export this pool on all systems "
6456                     "on which it is imported.\n"
6457                     "\tThen import it to correct the mismatch.\n"));
6458                 break;
6459
6460         case ZPOOL_STATUS_ERRATA:
6461                 (void) printf(gettext("status: Errata #%d detected.\n"),
6462                     errata);
6463
6464                 switch (errata) {
6465                 case ZPOOL_ERRATA_NONE:
6466                         break;
6467
6468                 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
6469                         (void) printf(gettext("action: To correct the issue "
6470                             "run 'zpool scrub'.\n"));
6471                         break;
6472
6473                 default:
6474                         /*
6475                          * All errata which allow the pool to be imported
6476                          * must contain an action message.
6477                          */
6478                         assert(0);
6479                 }
6480                 break;
6481
6482         default:
6483                 /*
6484                  * The remaining errors can't actually be generated, yet.
6485                  */
6486                 assert(reason == ZPOOL_STATUS_OK);
6487         }
6488
6489         if (msgid != NULL)
6490                 (void) printf(gettext("   see: http://zfsonlinux.org/msg/%s\n"),
6491                     msgid);
6492
6493         if (config != NULL) {
6494                 uint64_t nerr;
6495                 nvlist_t **spares, **l2cache;
6496                 uint_t nspares, nl2cache;
6497                 pool_scan_stat_t *ps = NULL;
6498
6499                 (void) nvlist_lookup_uint64_array(nvroot,
6500                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
6501                 print_scan_status(ps);
6502
6503                 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
6504                     cbp->cb_name_flags | VDEV_NAME_TYPE_ID);
6505                 if (cbp->cb_namewidth < 10)
6506                         cbp->cb_namewidth = 10;
6507
6508                 (void) printf(gettext("config:\n\n"));
6509                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s"),
6510                     cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE",
6511                     "CKSUM");
6512
6513                 if (cbp->vcdl != NULL)
6514                         print_cmd_columns(cbp->vcdl, 0);
6515
6516                 printf("\n");
6517                 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0,
6518                     B_FALSE);
6519
6520                 if (num_logs(nvroot) > 0)
6521                         print_logs(zhp, cbp, nvroot);
6522                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
6523                     &l2cache, &nl2cache) == 0)
6524                         print_l2cache(zhp, cbp, l2cache, nl2cache);
6525
6526                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
6527                     &spares, &nspares) == 0)
6528                         print_spares(zhp, cbp, spares, nspares);
6529
6530                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
6531                     &nerr) == 0) {
6532                         nvlist_t *nverrlist = NULL;
6533
6534                         /*
6535                          * If the approximate error count is small, get a
6536                          * precise count by fetching the entire log and
6537                          * uniquifying the results.
6538                          */
6539                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
6540                             zpool_get_errlog(zhp, &nverrlist) == 0) {
6541                                 nvpair_t *elem;
6542
6543                                 elem = NULL;
6544                                 nerr = 0;
6545                                 while ((elem = nvlist_next_nvpair(nverrlist,
6546                                     elem)) != NULL) {
6547                                         nerr++;
6548                                 }
6549                         }
6550                         nvlist_free(nverrlist);
6551
6552                         (void) printf("\n");
6553
6554                         if (nerr == 0)
6555                                 (void) printf(gettext("errors: No known data "
6556                                     "errors\n"));
6557                         else if (!cbp->cb_verbose)
6558                                 (void) printf(gettext("errors: %llu data "
6559                                     "errors, use '-v' for a list\n"),
6560                                     (u_longlong_t)nerr);
6561                         else
6562                                 print_error_log(zhp);
6563                 }
6564
6565                 if (cbp->cb_dedup_stats)
6566                         print_dedup_stats(config);
6567         } else {
6568                 (void) printf(gettext("config: The configuration cannot be "
6569                     "determined.\n"));
6570         }
6571
6572         return (0);
6573 }
6574
6575 /*
6576  * zpool status [-c [script1,script2,...]] [-gLPvx] [-T d|u] [pool] ...
6577  *              [interval [count]]
6578  *
6579  *      -c CMD  For each vdev, run command CMD
6580  *      -g      Display guid for individual vdev name.
6581  *      -L      Follow links when resolving vdev path name.
6582  *      -P      Display full path for vdev name.
6583  *      -v      Display complete error logs
6584  *      -x      Display only pools with potential problems
6585  *      -D      Display dedup status (undocumented)
6586  *      -T      Display a timestamp in date(1) or Unix format
6587  *
6588  * Describes the health status of all pools or some subset.
6589  */
6590 int
6591 zpool_do_status(int argc, char **argv)
6592 {
6593         int c;
6594         int ret;
6595         float interval = 0;
6596         unsigned long count = 0;
6597         status_cbdata_t cb = { 0 };
6598         char *cmd = NULL;
6599
6600         /* check options */
6601         while ((c = getopt(argc, argv, "c:gLPvxDT:")) != -1) {
6602                 switch (c) {
6603                 case 'c':
6604                         if (cmd != NULL) {
6605                                 fprintf(stderr,
6606                                     gettext("Can't set -c flag twice\n"));
6607                                 exit(1);
6608                         }
6609
6610                         if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
6611                             !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
6612                                 fprintf(stderr, gettext(
6613                                     "Can't run -c, disabled by "
6614                                     "ZPOOL_SCRIPTS_ENABLED.\n"));
6615                                 exit(1);
6616                         }
6617
6618                         if ((getuid() <= 0 || geteuid() <= 0) &&
6619                             !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
6620                                 fprintf(stderr, gettext(
6621                                     "Can't run -c with root privileges "
6622                                     "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
6623                                 exit(1);
6624                         }
6625                         cmd = optarg;
6626                         break;
6627                 case 'g':
6628                         cb.cb_name_flags |= VDEV_NAME_GUID;
6629                         break;
6630                 case 'L':
6631                         cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
6632                         break;
6633                 case 'P':
6634                         cb.cb_name_flags |= VDEV_NAME_PATH;
6635                         break;
6636                 case 'v':
6637                         cb.cb_verbose = B_TRUE;
6638                         break;
6639                 case 'x':
6640                         cb.cb_explain = B_TRUE;
6641                         break;
6642                 case 'D':
6643                         cb.cb_dedup_stats = B_TRUE;
6644                         break;
6645                 case 'T':
6646                         get_timestamp_arg(*optarg);
6647                         break;
6648                 case '?':
6649                         if (optopt == 'c') {
6650                                 print_zpool_script_list("status");
6651                                 exit(0);
6652                         } else {
6653                                 fprintf(stderr,
6654                                     gettext("invalid option '%c'\n"), optopt);
6655                         }
6656                         usage(B_FALSE);
6657                 }
6658         }
6659
6660         argc -= optind;
6661         argv += optind;
6662
6663         get_interval_count(&argc, argv, &interval, &count);
6664
6665         if (argc == 0)
6666                 cb.cb_allpools = B_TRUE;
6667
6668         cb.cb_first = B_TRUE;
6669         cb.cb_print_status = B_TRUE;
6670
6671         for (;;) {
6672                 if (timestamp_fmt != NODATE)
6673                         print_timestamp(timestamp_fmt);
6674
6675                 if (cmd != NULL)
6676                         cb.vcdl = all_pools_for_each_vdev_run(argc, argv, cmd,
6677                             NULL, NULL, 0, 0);
6678
6679                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
6680                     status_callback, &cb);
6681
6682                 if (cb.vcdl != NULL)
6683                         free_vdev_cmd_data_list(cb.vcdl);
6684
6685                 if (argc == 0 && cb.cb_count == 0)
6686                         (void) fprintf(stderr, gettext("no pools available\n"));
6687                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
6688                         (void) printf(gettext("all pools are healthy\n"));
6689
6690                 if (ret != 0)
6691                         return (ret);
6692
6693                 if (interval == 0)
6694                         break;
6695
6696                 if (count != 0 && --count == 0)
6697                         break;
6698
6699                 (void) fsleep(interval);
6700         }
6701
6702         return (0);
6703 }
6704
6705 typedef struct upgrade_cbdata {
6706         int     cb_first;
6707         int     cb_argc;
6708         uint64_t cb_version;
6709         char    **cb_argv;
6710 } upgrade_cbdata_t;
6711
6712 static int
6713 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
6714 {
6715         int zfs_version = (int)zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
6716         int *count = (int *)unsupp_fs;
6717
6718         if (zfs_version > ZPL_VERSION) {
6719                 (void) printf(gettext("%s (v%d) is not supported by this "
6720                     "implementation of ZFS.\n"),
6721                     zfs_get_name(zhp), zfs_version);
6722                 (*count)++;
6723         }
6724
6725         zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
6726
6727         zfs_close(zhp);
6728
6729         return (0);
6730 }
6731
6732 static int
6733 upgrade_version(zpool_handle_t *zhp, uint64_t version)
6734 {
6735         int ret;
6736         nvlist_t *config;
6737         uint64_t oldversion;
6738         int unsupp_fs = 0;
6739
6740         config = zpool_get_config(zhp, NULL);
6741         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6742             &oldversion) == 0);
6743
6744         assert(SPA_VERSION_IS_SUPPORTED(oldversion));
6745         assert(oldversion < version);
6746
6747         ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
6748         if (ret != 0)
6749                 return (ret);
6750
6751         if (unsupp_fs) {
6752                 (void) fprintf(stderr, gettext("Upgrade not performed due "
6753                     "to %d unsupported filesystems (max v%d).\n"),
6754                     unsupp_fs, (int)ZPL_VERSION);
6755                 return (1);
6756         }
6757
6758         ret = zpool_upgrade(zhp, version);
6759         if (ret != 0)
6760                 return (ret);
6761
6762         if (version >= SPA_VERSION_FEATURES) {
6763                 (void) printf(gettext("Successfully upgraded "
6764                     "'%s' from version %llu to feature flags.\n"),
6765                     zpool_get_name(zhp), (u_longlong_t)oldversion);
6766         } else {
6767                 (void) printf(gettext("Successfully upgraded "
6768                     "'%s' from version %llu to version %llu.\n"),
6769                     zpool_get_name(zhp), (u_longlong_t)oldversion,
6770                     (u_longlong_t)version);
6771         }
6772
6773         return (0);
6774 }
6775
6776 static int
6777 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
6778 {
6779         int i, ret, count;
6780         boolean_t firstff = B_TRUE;
6781         nvlist_t *enabled = zpool_get_features(zhp);
6782
6783         count = 0;
6784         for (i = 0; i < SPA_FEATURES; i++) {
6785                 const char *fname = spa_feature_table[i].fi_uname;
6786                 const char *fguid = spa_feature_table[i].fi_guid;
6787                 if (!nvlist_exists(enabled, fguid)) {
6788                         char *propname;
6789                         verify(-1 != asprintf(&propname, "feature@%s", fname));
6790                         ret = zpool_set_prop(zhp, propname,
6791                             ZFS_FEATURE_ENABLED);
6792                         if (ret != 0) {
6793                                 free(propname);
6794                                 return (ret);
6795                         }
6796                         count++;
6797
6798                         if (firstff) {
6799                                 (void) printf(gettext("Enabled the "
6800                                     "following features on '%s':\n"),
6801                                     zpool_get_name(zhp));
6802                                 firstff = B_FALSE;
6803                         }
6804                         (void) printf(gettext("  %s\n"), fname);
6805                         free(propname);
6806                 }
6807         }
6808
6809         if (countp != NULL)
6810                 *countp = count;
6811         return (0);
6812 }
6813
6814 static int
6815 upgrade_cb(zpool_handle_t *zhp, void *arg)
6816 {
6817         upgrade_cbdata_t *cbp = arg;
6818         nvlist_t *config;
6819         uint64_t version;
6820         boolean_t printnl = B_FALSE;
6821         int ret;
6822
6823         config = zpool_get_config(zhp, NULL);
6824         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6825             &version) == 0);
6826
6827         assert(SPA_VERSION_IS_SUPPORTED(version));
6828
6829         if (version < cbp->cb_version) {
6830                 cbp->cb_first = B_FALSE;
6831                 ret = upgrade_version(zhp, cbp->cb_version);
6832                 if (ret != 0)
6833                         return (ret);
6834                 printnl = B_TRUE;
6835
6836                 /*
6837                  * If they did "zpool upgrade -a", then we could
6838                  * be doing ioctls to different pools.  We need
6839                  * to log this history once to each pool, and bypass
6840                  * the normal history logging that happens in main().
6841                  */
6842                 (void) zpool_log_history(g_zfs, history_str);
6843                 log_history = B_FALSE;
6844         }
6845
6846         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
6847                 int count;
6848                 ret = upgrade_enable_all(zhp, &count);
6849                 if (ret != 0)
6850                         return (ret);
6851
6852                 if (count > 0) {
6853                         cbp->cb_first = B_FALSE;
6854                         printnl = B_TRUE;
6855                 }
6856         }
6857
6858         if (printnl) {
6859                 (void) printf(gettext("\n"));
6860         }
6861
6862         return (0);
6863 }
6864
6865 static int
6866 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
6867 {
6868         upgrade_cbdata_t *cbp = arg;
6869         nvlist_t *config;
6870         uint64_t version;
6871
6872         config = zpool_get_config(zhp, NULL);
6873         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6874             &version) == 0);
6875
6876         assert(SPA_VERSION_IS_SUPPORTED(version));
6877
6878         if (version < SPA_VERSION_FEATURES) {
6879                 if (cbp->cb_first) {
6880                         (void) printf(gettext("The following pools are "
6881                             "formatted with legacy version numbers and can\n"
6882                             "be upgraded to use feature flags.  After "
6883                             "being upgraded, these pools\nwill no "
6884                             "longer be accessible by software that does not "
6885                             "support feature\nflags.\n\n"));
6886                         (void) printf(gettext("VER  POOL\n"));
6887                         (void) printf(gettext("---  ------------\n"));
6888                         cbp->cb_first = B_FALSE;
6889                 }
6890
6891                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
6892                     zpool_get_name(zhp));
6893         }
6894
6895         return (0);
6896 }
6897
6898 static int
6899 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
6900 {
6901         upgrade_cbdata_t *cbp = arg;
6902         nvlist_t *config;
6903         uint64_t version;
6904
6905         config = zpool_get_config(zhp, NULL);
6906         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6907             &version) == 0);
6908
6909         if (version >= SPA_VERSION_FEATURES) {
6910                 int i;
6911                 boolean_t poolfirst = B_TRUE;
6912                 nvlist_t *enabled = zpool_get_features(zhp);
6913
6914                 for (i = 0; i < SPA_FEATURES; i++) {
6915                         const char *fguid = spa_feature_table[i].fi_guid;
6916                         const char *fname = spa_feature_table[i].fi_uname;
6917                         if (!nvlist_exists(enabled, fguid)) {
6918                                 if (cbp->cb_first) {
6919                                         (void) printf(gettext("\nSome "
6920                                             "supported features are not "
6921                                             "enabled on the following pools. "
6922                                             "Once a\nfeature is enabled the "
6923                                             "pool may become incompatible with "
6924                                             "software\nthat does not support "
6925                                             "the feature. See "
6926                                             "zpool-features(5) for "
6927                                             "details.\n\n"));
6928                                         (void) printf(gettext("POOL  "
6929                                             "FEATURE\n"));
6930                                         (void) printf(gettext("------"
6931                                             "---------\n"));
6932                                         cbp->cb_first = B_FALSE;
6933                                 }
6934
6935                                 if (poolfirst) {
6936                                         (void) printf(gettext("%s\n"),
6937                                             zpool_get_name(zhp));
6938                                         poolfirst = B_FALSE;
6939                                 }
6940
6941                                 (void) printf(gettext("      %s\n"), fname);
6942                         }
6943                         /*
6944                          * If they did "zpool upgrade -a", then we could
6945                          * be doing ioctls to different pools.  We need
6946                          * to log this history once to each pool, and bypass
6947                          * the normal history logging that happens in main().
6948                          */
6949                         (void) zpool_log_history(g_zfs, history_str);
6950                         log_history = B_FALSE;
6951                 }
6952         }
6953
6954         return (0);
6955 }
6956
6957 /* ARGSUSED */
6958 static int
6959 upgrade_one(zpool_handle_t *zhp, void *data)
6960 {
6961         boolean_t printnl = B_FALSE;
6962         upgrade_cbdata_t *cbp = data;
6963         uint64_t cur_version;
6964         int ret;
6965
6966         if (strcmp("log", zpool_get_name(zhp)) == 0) {
6967                 (void) fprintf(stderr, gettext("'log' is now a reserved word\n"
6968                     "Pool 'log' must be renamed using export and import"
6969                     " to upgrade.\n"));
6970                 return (1);
6971         }
6972
6973         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
6974         if (cur_version > cbp->cb_version) {
6975                 (void) printf(gettext("Pool '%s' is already formatted "
6976                     "using more current version '%llu'.\n\n"),
6977                     zpool_get_name(zhp), (u_longlong_t)cur_version);
6978                 return (0);
6979         }
6980
6981         if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
6982                 (void) printf(gettext("Pool '%s' is already formatted "
6983                     "using version %llu.\n\n"), zpool_get_name(zhp),
6984                     (u_longlong_t)cbp->cb_version);
6985                 return (0);
6986         }
6987
6988         if (cur_version != cbp->cb_version) {
6989                 printnl = B_TRUE;
6990                 ret = upgrade_version(zhp, cbp->cb_version);
6991                 if (ret != 0)
6992                         return (ret);
6993         }
6994
6995         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
6996                 int count = 0;
6997                 ret = upgrade_enable_all(zhp, &count);
6998                 if (ret != 0)
6999                         return (ret);
7000
7001                 if (count != 0) {
7002                         printnl = B_TRUE;
7003                 } else if (cur_version == SPA_VERSION) {
7004                         (void) printf(gettext("Pool '%s' already has all "
7005                             "supported features enabled.\n"),
7006                             zpool_get_name(zhp));
7007                 }
7008         }
7009
7010         if (printnl) {
7011                 (void) printf(gettext("\n"));
7012         }
7013
7014         return (0);
7015 }
7016
7017 /*
7018  * zpool upgrade
7019  * zpool upgrade -v
7020  * zpool upgrade [-V version] <-a | pool ...>
7021  *
7022  * With no arguments, display downrev'd ZFS pool available for upgrade.
7023  * Individual pools can be upgraded by specifying the pool, and '-a' will
7024  * upgrade all pools.
7025  */
7026 int
7027 zpool_do_upgrade(int argc, char **argv)
7028 {
7029         int c;
7030         upgrade_cbdata_t cb = { 0 };
7031         int ret = 0;
7032         boolean_t showversions = B_FALSE;
7033         boolean_t upgradeall = B_FALSE;
7034         char *end;
7035
7036
7037         /* check options */
7038         while ((c = getopt(argc, argv, ":avV:")) != -1) {
7039                 switch (c) {
7040                 case 'a':
7041                         upgradeall = B_TRUE;
7042                         break;
7043                 case 'v':
7044                         showversions = B_TRUE;
7045                         break;
7046                 case 'V':
7047                         cb.cb_version = strtoll(optarg, &end, 10);
7048                         if (*end != '\0' ||
7049                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
7050                                 (void) fprintf(stderr,
7051                                     gettext("invalid version '%s'\n"), optarg);
7052                                 usage(B_FALSE);
7053                         }
7054                         break;
7055                 case ':':
7056                         (void) fprintf(stderr, gettext("missing argument for "
7057                             "'%c' option\n"), optopt);
7058                         usage(B_FALSE);
7059                         break;
7060                 case '?':
7061                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7062                             optopt);
7063                         usage(B_FALSE);
7064                 }
7065         }
7066
7067         cb.cb_argc = argc;
7068         cb.cb_argv = argv;
7069         argc -= optind;
7070         argv += optind;
7071
7072         if (cb.cb_version == 0) {
7073                 cb.cb_version = SPA_VERSION;
7074         } else if (!upgradeall && argc == 0) {
7075                 (void) fprintf(stderr, gettext("-V option is "
7076                     "incompatible with other arguments\n"));
7077                 usage(B_FALSE);
7078         }
7079
7080         if (showversions) {
7081                 if (upgradeall || argc != 0) {
7082                         (void) fprintf(stderr, gettext("-v option is "
7083                             "incompatible with other arguments\n"));
7084                         usage(B_FALSE);
7085                 }
7086         } else if (upgradeall) {
7087                 if (argc != 0) {
7088                         (void) fprintf(stderr, gettext("-a option should not "
7089                             "be used along with a pool name\n"));
7090                         usage(B_FALSE);
7091                 }
7092         }
7093
7094         (void) printf(gettext("This system supports ZFS pool feature "
7095             "flags.\n\n"));
7096         if (showversions) {
7097                 int i;
7098
7099                 (void) printf(gettext("The following features are "
7100                     "supported:\n\n"));
7101                 (void) printf(gettext("FEAT DESCRIPTION\n"));
7102                 (void) printf("----------------------------------------------"
7103                     "---------------\n");
7104                 for (i = 0; i < SPA_FEATURES; i++) {
7105                         zfeature_info_t *fi = &spa_feature_table[i];
7106                         const char *ro =
7107                             (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
7108                             " (read-only compatible)" : "";
7109
7110                         (void) printf("%-37s%s\n", fi->fi_uname, ro);
7111                         (void) printf("     %s\n", fi->fi_desc);
7112                 }
7113                 (void) printf("\n");
7114
7115                 (void) printf(gettext("The following legacy versions are also "
7116                     "supported:\n\n"));
7117                 (void) printf(gettext("VER  DESCRIPTION\n"));
7118                 (void) printf("---  -----------------------------------------"
7119                     "---------------\n");
7120                 (void) printf(gettext(" 1   Initial ZFS version\n"));
7121                 (void) printf(gettext(" 2   Ditto blocks "
7122                     "(replicated metadata)\n"));
7123                 (void) printf(gettext(" 3   Hot spares and double parity "
7124                     "RAID-Z\n"));
7125                 (void) printf(gettext(" 4   zpool history\n"));
7126                 (void) printf(gettext(" 5   Compression using the gzip "
7127                     "algorithm\n"));
7128                 (void) printf(gettext(" 6   bootfs pool property\n"));
7129                 (void) printf(gettext(" 7   Separate intent log devices\n"));
7130                 (void) printf(gettext(" 8   Delegated administration\n"));
7131                 (void) printf(gettext(" 9   refquota and refreservation "
7132                     "properties\n"));
7133                 (void) printf(gettext(" 10  Cache devices\n"));
7134                 (void) printf(gettext(" 11  Improved scrub performance\n"));
7135                 (void) printf(gettext(" 12  Snapshot properties\n"));
7136                 (void) printf(gettext(" 13  snapused property\n"));
7137                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
7138                 (void) printf(gettext(" 15  user/group space accounting\n"));
7139                 (void) printf(gettext(" 16  stmf property support\n"));
7140                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
7141                 (void) printf(gettext(" 18  Snapshot user holds\n"));
7142                 (void) printf(gettext(" 19  Log device removal\n"));
7143                 (void) printf(gettext(" 20  Compression using zle "
7144                     "(zero-length encoding)\n"));
7145                 (void) printf(gettext(" 21  Deduplication\n"));
7146                 (void) printf(gettext(" 22  Received properties\n"));
7147                 (void) printf(gettext(" 23  Slim ZIL\n"));
7148                 (void) printf(gettext(" 24  System attributes\n"));
7149                 (void) printf(gettext(" 25  Improved scrub stats\n"));
7150                 (void) printf(gettext(" 26  Improved snapshot deletion "
7151                     "performance\n"));
7152                 (void) printf(gettext(" 27  Improved snapshot creation "
7153                     "performance\n"));
7154                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
7155                 (void) printf(gettext("\nFor more information on a particular "
7156                     "version, including supported releases,\n"));
7157                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
7158         } else if (argc == 0 && upgradeall) {
7159                 cb.cb_first = B_TRUE;
7160                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
7161                 if (ret == 0 && cb.cb_first) {
7162                         if (cb.cb_version == SPA_VERSION) {
7163                                 (void) printf(gettext("All pools are already "
7164                                     "formatted using feature flags.\n\n"));
7165                                 (void) printf(gettext("Every feature flags "
7166                                     "pool already has all supported features "
7167                                     "enabled.\n"));
7168                         } else {
7169                                 (void) printf(gettext("All pools are already "
7170                                     "formatted with version %llu or higher.\n"),
7171                                     (u_longlong_t)cb.cb_version);
7172                         }
7173                 }
7174         } else if (argc == 0) {
7175                 cb.cb_first = B_TRUE;
7176                 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
7177                 assert(ret == 0);
7178
7179                 if (cb.cb_first) {
7180                         (void) printf(gettext("All pools are formatted "
7181                             "using feature flags.\n\n"));
7182                 } else {
7183                         (void) printf(gettext("\nUse 'zpool upgrade -v' "
7184                             "for a list of available legacy versions.\n"));
7185                 }
7186
7187                 cb.cb_first = B_TRUE;
7188                 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
7189                 assert(ret == 0);
7190
7191                 if (cb.cb_first) {
7192                         (void) printf(gettext("Every feature flags pool has "
7193                             "all supported features enabled.\n"));
7194                 } else {
7195                         (void) printf(gettext("\n"));
7196                 }
7197         } else {
7198                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
7199                     upgrade_one, &cb);
7200         }
7201
7202         return (ret);
7203 }
7204
7205 typedef struct hist_cbdata {
7206         boolean_t first;
7207         boolean_t longfmt;
7208         boolean_t internal;
7209 } hist_cbdata_t;
7210
7211 /*
7212  * Print out the command history for a specific pool.
7213  */
7214 static int
7215 get_history_one(zpool_handle_t *zhp, void *data)
7216 {
7217         nvlist_t *nvhis;
7218         nvlist_t **records;
7219         uint_t numrecords;
7220         int ret, i;
7221         hist_cbdata_t *cb = (hist_cbdata_t *)data;
7222
7223         cb->first = B_FALSE;
7224
7225         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
7226
7227         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
7228                 return (ret);
7229
7230         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
7231             &records, &numrecords) == 0);
7232         for (i = 0; i < numrecords; i++) {
7233                 nvlist_t *rec = records[i];
7234                 char tbuf[30] = "";
7235
7236                 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
7237                         time_t tsec;
7238                         struct tm t;
7239
7240                         tsec = fnvlist_lookup_uint64(records[i],
7241                             ZPOOL_HIST_TIME);
7242                         (void) localtime_r(&tsec, &t);
7243                         (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
7244                 }
7245
7246                 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
7247                         (void) printf("%s %s", tbuf,
7248                             fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
7249                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
7250                         int ievent =
7251                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
7252                         if (!cb->internal)
7253                                 continue;
7254                         if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
7255                                 (void) printf("%s unrecognized record:\n",
7256                                     tbuf);
7257                                 dump_nvlist(rec, 4);
7258                                 continue;
7259                         }
7260                         (void) printf("%s [internal %s txg:%lld] %s", tbuf,
7261                             zfs_history_event_names[ievent],
7262                             (longlong_t)fnvlist_lookup_uint64(
7263                             rec, ZPOOL_HIST_TXG),
7264                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
7265                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
7266                         if (!cb->internal)
7267                                 continue;
7268                         (void) printf("%s [txg:%lld] %s", tbuf,
7269                             (longlong_t)fnvlist_lookup_uint64(
7270                             rec, ZPOOL_HIST_TXG),
7271                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
7272                         if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
7273                                 (void) printf(" %s (%llu)",
7274                                     fnvlist_lookup_string(rec,
7275                                     ZPOOL_HIST_DSNAME),
7276                                     (u_longlong_t)fnvlist_lookup_uint64(rec,
7277                                     ZPOOL_HIST_DSID));
7278                         }
7279                         (void) printf(" %s", fnvlist_lookup_string(rec,
7280                             ZPOOL_HIST_INT_STR));
7281                 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
7282                         if (!cb->internal)
7283                                 continue;
7284                         (void) printf("%s ioctl %s\n", tbuf,
7285                             fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
7286                         if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
7287                                 (void) printf("    input:\n");
7288                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
7289                                     ZPOOL_HIST_INPUT_NVL), 8);
7290                         }
7291                         if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
7292                                 (void) printf("    output:\n");
7293                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
7294                                     ZPOOL_HIST_OUTPUT_NVL), 8);
7295                         }
7296                 } else {
7297                         if (!cb->internal)
7298                                 continue;
7299                         (void) printf("%s unrecognized record:\n", tbuf);
7300                         dump_nvlist(rec, 4);
7301                 }
7302
7303                 if (!cb->longfmt) {
7304                         (void) printf("\n");
7305                         continue;
7306                 }
7307                 (void) printf(" [");
7308                 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
7309                         uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
7310                         struct passwd *pwd = getpwuid(who);
7311                         (void) printf("user %d ", (int)who);
7312                         if (pwd != NULL)
7313                                 (void) printf("(%s) ", pwd->pw_name);
7314                 }
7315                 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
7316                         (void) printf("on %s",
7317                             fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
7318                 }
7319                 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
7320                         (void) printf(":%s",
7321                             fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
7322                 }
7323
7324                 (void) printf("]");
7325                 (void) printf("\n");
7326         }
7327         (void) printf("\n");
7328         nvlist_free(nvhis);
7329
7330         return (ret);
7331 }
7332
7333 /*
7334  * zpool history <pool>
7335  *
7336  * Displays the history of commands that modified pools.
7337  */
7338 int
7339 zpool_do_history(int argc, char **argv)
7340 {
7341         hist_cbdata_t cbdata = { 0 };
7342         int ret;
7343         int c;
7344
7345         cbdata.first = B_TRUE;
7346         /* check options */
7347         while ((c = getopt(argc, argv, "li")) != -1) {
7348                 switch (c) {
7349                 case 'l':
7350                         cbdata.longfmt = B_TRUE;
7351                         break;
7352                 case 'i':
7353                         cbdata.internal = B_TRUE;
7354                         break;
7355                 case '?':
7356                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7357                             optopt);
7358                         usage(B_FALSE);
7359                 }
7360         }
7361         argc -= optind;
7362         argv += optind;
7363
7364         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
7365             &cbdata);
7366
7367         if (argc == 0 && cbdata.first == B_TRUE) {
7368                 (void) fprintf(stderr, gettext("no pools available\n"));
7369                 return (0);
7370         }
7371
7372         return (ret);
7373 }
7374
7375 typedef struct ev_opts {
7376         int verbose;
7377         int scripted;
7378         int follow;
7379         int clear;
7380         char poolname[ZFS_MAX_DATASET_NAME_LEN];
7381 } ev_opts_t;
7382
7383 static void
7384 zpool_do_events_short(nvlist_t *nvl, ev_opts_t *opts)
7385 {
7386         char ctime_str[26], str[32], *ptr;
7387         int64_t *tv;
7388         uint_t n;
7389
7390         verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
7391         memset(str, ' ', 32);
7392         (void) ctime_r((const time_t *)&tv[0], ctime_str);
7393         (void) strncpy(str, ctime_str+4,  6);           /* 'Jun 30' */
7394         (void) strncpy(str+7, ctime_str+20, 4);         /* '1993' */
7395         (void) strncpy(str+12, ctime_str+11, 8);        /* '21:49:08' */
7396         (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */
7397         if (opts->scripted)
7398                 (void) printf(gettext("%s\t"), str);
7399         else
7400                 (void) printf(gettext("%s "), str);
7401
7402         verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0);
7403         (void) printf(gettext("%s\n"), ptr);
7404 }
7405
7406 static void
7407 zpool_do_events_nvprint(nvlist_t *nvl, int depth)
7408 {
7409         nvpair_t *nvp;
7410
7411         for (nvp = nvlist_next_nvpair(nvl, NULL);
7412             nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
7413
7414                 data_type_t type = nvpair_type(nvp);
7415                 const char *name = nvpair_name(nvp);
7416
7417                 boolean_t b;
7418                 uint8_t i8;
7419                 uint16_t i16;
7420                 uint32_t i32;
7421                 uint64_t i64;
7422                 char *str;
7423                 nvlist_t *cnv;
7424
7425                 printf(gettext("%*s%s = "), depth, "", name);
7426
7427                 switch (type) {
7428                 case DATA_TYPE_BOOLEAN:
7429                         printf(gettext("%s"), "1");
7430                         break;
7431
7432                 case DATA_TYPE_BOOLEAN_VALUE:
7433                         (void) nvpair_value_boolean_value(nvp, &b);
7434                         printf(gettext("%s"), b ? "1" : "0");
7435                         break;
7436
7437                 case DATA_TYPE_BYTE:
7438                         (void) nvpair_value_byte(nvp, &i8);
7439                         printf(gettext("0x%x"), i8);
7440                         break;
7441
7442                 case DATA_TYPE_INT8:
7443                         (void) nvpair_value_int8(nvp, (void *)&i8);
7444                         printf(gettext("0x%x"), i8);
7445                         break;
7446
7447                 case DATA_TYPE_UINT8:
7448                         (void) nvpair_value_uint8(nvp, &i8);
7449                         printf(gettext("0x%x"), i8);
7450                         break;
7451
7452                 case DATA_TYPE_INT16:
7453                         (void) nvpair_value_int16(nvp, (void *)&i16);
7454                         printf(gettext("0x%x"), i16);
7455                         break;
7456
7457                 case DATA_TYPE_UINT16:
7458                         (void) nvpair_value_uint16(nvp, &i16);
7459                         printf(gettext("0x%x"), i16);
7460                         break;
7461
7462                 case DATA_TYPE_INT32:
7463                         (void) nvpair_value_int32(nvp, (void *)&i32);
7464                         printf(gettext("0x%x"), i32);
7465                         break;
7466
7467                 case DATA_TYPE_UINT32:
7468                         (void) nvpair_value_uint32(nvp, &i32);
7469                         printf(gettext("0x%x"), i32);
7470                         break;
7471
7472                 case DATA_TYPE_INT64:
7473                         (void) nvpair_value_int64(nvp, (void *)&i64);
7474                         printf(gettext("0x%llx"), (u_longlong_t)i64);
7475                         break;
7476
7477                 case DATA_TYPE_UINT64:
7478                         (void) nvpair_value_uint64(nvp, &i64);
7479                         /*
7480                          * translate vdev state values to readable
7481                          * strings to aide zpool events consumers
7482                          */
7483                         if (strcmp(name,
7484                             FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 ||
7485                             strcmp(name,
7486                             FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) {
7487                                 printf(gettext("\"%s\" (0x%llx)"),
7488                                     zpool_state_to_name(i64, VDEV_AUX_NONE),
7489                                     (u_longlong_t)i64);
7490                         } else {
7491                                 printf(gettext("0x%llx"), (u_longlong_t)i64);
7492                         }
7493                         break;
7494
7495                 case DATA_TYPE_HRTIME:
7496                         (void) nvpair_value_hrtime(nvp, (void *)&i64);
7497                         printf(gettext("0x%llx"), (u_longlong_t)i64);
7498                         break;
7499
7500                 case DATA_TYPE_STRING:
7501                         (void) nvpair_value_string(nvp, &str);
7502                         printf(gettext("\"%s\""), str ? str : "<NULL>");
7503                         break;
7504
7505                 case DATA_TYPE_NVLIST:
7506                         printf(gettext("(embedded nvlist)\n"));
7507                         (void) nvpair_value_nvlist(nvp, &cnv);
7508                         zpool_do_events_nvprint(cnv, depth + 8);
7509                         printf(gettext("%*s(end %s)"), depth, "", name);
7510                         break;
7511
7512                 case DATA_TYPE_NVLIST_ARRAY: {
7513                         nvlist_t **val;
7514                         uint_t i, nelem;
7515
7516                         (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
7517                         printf(gettext("(%d embedded nvlists)\n"), nelem);
7518                         for (i = 0; i < nelem; i++) {
7519                                 printf(gettext("%*s%s[%d] = %s\n"),
7520                                     depth, "", name, i, "(embedded nvlist)");
7521                                 zpool_do_events_nvprint(val[i], depth + 8);
7522                                 printf(gettext("%*s(end %s[%i])\n"),
7523                                     depth, "", name, i);
7524                         }
7525                         printf(gettext("%*s(end %s)\n"), depth, "", name);
7526                         }
7527                         break;
7528
7529                 case DATA_TYPE_INT8_ARRAY: {
7530                         int8_t *val;
7531                         uint_t i, nelem;
7532
7533                         (void) nvpair_value_int8_array(nvp, &val, &nelem);
7534                         for (i = 0; i < nelem; i++)
7535                                 printf(gettext("0x%x "), val[i]);
7536
7537                         break;
7538                         }
7539
7540                 case DATA_TYPE_UINT8_ARRAY: {
7541                         uint8_t *val;
7542                         uint_t i, nelem;
7543
7544                         (void) nvpair_value_uint8_array(nvp, &val, &nelem);
7545                         for (i = 0; i < nelem; i++)
7546                                 printf(gettext("0x%x "), val[i]);
7547
7548                         break;
7549                         }
7550
7551                 case DATA_TYPE_INT16_ARRAY: {
7552                         int16_t *val;
7553                         uint_t i, nelem;
7554
7555                         (void) nvpair_value_int16_array(nvp, &val, &nelem);
7556                         for (i = 0; i < nelem; i++)
7557                                 printf(gettext("0x%x "), val[i]);
7558
7559                         break;
7560                         }
7561
7562                 case DATA_TYPE_UINT16_ARRAY: {
7563                         uint16_t *val;
7564                         uint_t i, nelem;
7565
7566                         (void) nvpair_value_uint16_array(nvp, &val, &nelem);
7567                         for (i = 0; i < nelem; i++)
7568                                 printf(gettext("0x%x "), val[i]);
7569
7570                         break;
7571                         }
7572
7573                 case DATA_TYPE_INT32_ARRAY: {
7574                         int32_t *val;
7575                         uint_t i, nelem;
7576
7577                         (void) nvpair_value_int32_array(nvp, &val, &nelem);
7578                         for (i = 0; i < nelem; i++)
7579                                 printf(gettext("0x%x "), val[i]);
7580
7581                         break;
7582                         }
7583
7584                 case DATA_TYPE_UINT32_ARRAY: {
7585                         uint32_t *val;
7586                         uint_t i, nelem;
7587
7588                         (void) nvpair_value_uint32_array(nvp, &val, &nelem);
7589                         for (i = 0; i < nelem; i++)
7590                                 printf(gettext("0x%x "), val[i]);
7591
7592                         break;
7593                         }
7594
7595                 case DATA_TYPE_INT64_ARRAY: {
7596                         int64_t *val;
7597                         uint_t i, nelem;
7598
7599                         (void) nvpair_value_int64_array(nvp, &val, &nelem);
7600                         for (i = 0; i < nelem; i++)
7601                                 printf(gettext("0x%llx "),
7602                                     (u_longlong_t)val[i]);
7603
7604                         break;
7605                         }
7606
7607                 case DATA_TYPE_UINT64_ARRAY: {
7608                         uint64_t *val;
7609                         uint_t i, nelem;
7610
7611                         (void) nvpair_value_uint64_array(nvp, &val, &nelem);
7612                         for (i = 0; i < nelem; i++)
7613                                 printf(gettext("0x%llx "),
7614                                     (u_longlong_t)val[i]);
7615
7616                         break;
7617                         }
7618
7619                 case DATA_TYPE_STRING_ARRAY: {
7620                         char **str;
7621                         uint_t i, nelem;
7622
7623                         (void) nvpair_value_string_array(nvp, &str, &nelem);
7624                         for (i = 0; i < nelem; i++)
7625                                 printf(gettext("\"%s\" "),
7626                                     str[i] ? str[i] : "<NULL>");
7627
7628                         break;
7629                         }
7630
7631                 case DATA_TYPE_BOOLEAN_ARRAY:
7632                 case DATA_TYPE_BYTE_ARRAY:
7633                 case DATA_TYPE_DOUBLE:
7634                 case DATA_TYPE_UNKNOWN:
7635                         printf(gettext("<unknown>"));
7636                         break;
7637                 }
7638
7639                 printf(gettext("\n"));
7640         }
7641 }
7642
7643 static int
7644 zpool_do_events_next(ev_opts_t *opts)
7645 {
7646         nvlist_t *nvl;
7647         int zevent_fd, ret, dropped;
7648         char *pool;
7649
7650         zevent_fd = open(ZFS_DEV, O_RDWR);
7651         VERIFY(zevent_fd >= 0);
7652
7653         if (!opts->scripted)
7654                 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
7655
7656         while (1) {
7657                 ret = zpool_events_next(g_zfs, &nvl, &dropped,
7658                     (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd);
7659                 if (ret || nvl == NULL)
7660                         break;
7661
7662                 if (dropped > 0)
7663                         (void) printf(gettext("dropped %d events\n"), dropped);
7664
7665                 if (strlen(opts->poolname) > 0 &&
7666                     nvlist_lookup_string(nvl, FM_FMRI_ZFS_POOL, &pool) == 0 &&
7667                     strcmp(opts->poolname, pool) != 0)
7668                         continue;
7669
7670                 zpool_do_events_short(nvl, opts);
7671
7672                 if (opts->verbose) {
7673                         zpool_do_events_nvprint(nvl, 8);
7674                         printf(gettext("\n"));
7675                 }
7676                 (void) fflush(stdout);
7677
7678                 nvlist_free(nvl);
7679         }
7680
7681         VERIFY(0 == close(zevent_fd));
7682
7683         return (ret);
7684 }
7685
7686 static int
7687 zpool_do_events_clear(ev_opts_t *opts)
7688 {
7689         int count, ret;
7690
7691         ret = zpool_events_clear(g_zfs, &count);
7692         if (!ret)
7693                 (void) printf(gettext("cleared %d events\n"), count);
7694
7695         return (ret);
7696 }
7697
7698 /*
7699  * zpool events [-vHf [pool] | -c]
7700  *
7701  * Displays events logs by ZFS.
7702  */
7703 int
7704 zpool_do_events(int argc, char **argv)
7705 {
7706         ev_opts_t opts = { 0 };
7707         int ret;
7708         int c;
7709
7710         /* check options */
7711         while ((c = getopt(argc, argv, "vHfc")) != -1) {
7712                 switch (c) {
7713                 case 'v':
7714                         opts.verbose = 1;
7715                         break;
7716                 case 'H':
7717                         opts.scripted = 1;
7718                         break;
7719                 case 'f':
7720                         opts.follow = 1;
7721                         break;
7722                 case 'c':
7723                         opts.clear = 1;
7724                         break;
7725                 case '?':
7726                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7727                             optopt);
7728                         usage(B_FALSE);
7729                 }
7730         }
7731         argc -= optind;
7732         argv += optind;
7733
7734         if (argc > 1) {
7735                 (void) fprintf(stderr, gettext("too many arguments\n"));
7736                 usage(B_FALSE);
7737         } else if (argc == 1) {
7738                 (void) strlcpy(opts.poolname, argv[0], sizeof (opts.poolname));
7739                 if (!zfs_name_valid(opts.poolname, ZFS_TYPE_POOL)) {
7740                         (void) fprintf(stderr,
7741                             gettext("invalid pool name '%s'\n"), opts.poolname);
7742                         usage(B_FALSE);
7743                 }
7744         }
7745
7746         if ((argc == 1 || opts.verbose || opts.scripted || opts.follow) &&
7747             opts.clear) {
7748                 (void) fprintf(stderr,
7749                     gettext("invalid options combined with -c\n"));
7750                 usage(B_FALSE);
7751         }
7752
7753         if (opts.clear)
7754                 ret = zpool_do_events_clear(&opts);
7755         else
7756                 ret = zpool_do_events_next(&opts);
7757
7758         return (ret);
7759 }
7760
7761 static int
7762 get_callback(zpool_handle_t *zhp, void *data)
7763 {
7764         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
7765         char value[MAXNAMELEN];
7766         zprop_source_t srctype;
7767         zprop_list_t *pl;
7768
7769         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
7770
7771                 /*
7772                  * Skip the special fake placeholder. This will also skip
7773                  * over the name property when 'all' is specified.
7774                  */
7775                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
7776                     pl == cbp->cb_proplist)
7777                         continue;
7778
7779                 if (pl->pl_prop == ZPROP_INVAL &&
7780                     (zpool_prop_feature(pl->pl_user_prop) ||
7781                     zpool_prop_unsupported(pl->pl_user_prop))) {
7782                         srctype = ZPROP_SRC_LOCAL;
7783
7784                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
7785                             value, sizeof (value)) == 0) {
7786                                 zprop_print_one_property(zpool_get_name(zhp),
7787                                     cbp, pl->pl_user_prop, value, srctype,
7788                                     NULL, NULL);
7789                         }
7790                 } else {
7791                         if (zpool_get_prop(zhp, pl->pl_prop, value,
7792                             sizeof (value), &srctype, cbp->cb_literal) != 0)
7793                                 continue;
7794
7795                         zprop_print_one_property(zpool_get_name(zhp), cbp,
7796                             zpool_prop_to_name(pl->pl_prop), value, srctype,
7797                             NULL, NULL);
7798                 }
7799         }
7800         return (0);
7801 }
7802
7803 /*
7804  * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
7805  *
7806  *      -H      Scripted mode.  Don't display headers, and separate properties
7807  *              by a single tab.
7808  *      -o      List of columns to display.  Defaults to
7809  *              "name,property,value,source".
7810  *      -p      Display values in parsable (exact) format.
7811  *
7812  * Get properties of pools in the system. Output space statistics
7813  * for each one as well as other attributes.
7814  */
7815 int
7816 zpool_do_get(int argc, char **argv)
7817 {
7818         zprop_get_cbdata_t cb = { 0 };
7819         zprop_list_t fake_name = { 0 };
7820         int ret;
7821         int c, i;
7822         char *value;
7823
7824         cb.cb_first = B_TRUE;
7825
7826         /*
7827          * Set up default columns and sources.
7828          */
7829         cb.cb_sources = ZPROP_SRC_ALL;
7830         cb.cb_columns[0] = GET_COL_NAME;
7831         cb.cb_columns[1] = GET_COL_PROPERTY;
7832         cb.cb_columns[2] = GET_COL_VALUE;
7833         cb.cb_columns[3] = GET_COL_SOURCE;
7834         cb.cb_type = ZFS_TYPE_POOL;
7835
7836         /* check options */
7837         while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
7838                 switch (c) {
7839                 case 'p':
7840                         cb.cb_literal = B_TRUE;
7841                         break;
7842                 case 'H':
7843                         cb.cb_scripted = B_TRUE;
7844                         break;
7845                 case 'o':
7846                         bzero(&cb.cb_columns, sizeof (cb.cb_columns));
7847                         i = 0;
7848                         while (*optarg != '\0') {
7849                                 static char *col_subopts[] =
7850                                 { "name", "property", "value", "source",
7851                                 "all", NULL };
7852
7853                                 if (i == ZFS_GET_NCOLS) {
7854                                         (void) fprintf(stderr, gettext("too "
7855                                         "many fields given to -o "
7856                                         "option\n"));
7857                                         usage(B_FALSE);
7858                                 }
7859
7860                                 switch (getsubopt(&optarg, col_subopts,
7861                                     &value)) {
7862                                 case 0:
7863                                         cb.cb_columns[i++] = GET_COL_NAME;
7864                                         break;
7865                                 case 1:
7866                                         cb.cb_columns[i++] = GET_COL_PROPERTY;
7867                                         break;
7868                                 case 2:
7869                                         cb.cb_columns[i++] = GET_COL_VALUE;
7870                                         break;
7871                                 case 3:
7872                                         cb.cb_columns[i++] = GET_COL_SOURCE;
7873                                         break;
7874                                 case 4:
7875                                         if (i > 0) {
7876                                                 (void) fprintf(stderr,
7877                                                     gettext("\"all\" conflicts "
7878                                                     "with specific fields "
7879                                                     "given to -o option\n"));
7880                                                 usage(B_FALSE);
7881                                         }
7882                                         cb.cb_columns[0] = GET_COL_NAME;
7883                                         cb.cb_columns[1] = GET_COL_PROPERTY;
7884                                         cb.cb_columns[2] = GET_COL_VALUE;
7885                                         cb.cb_columns[3] = GET_COL_SOURCE;
7886                                         i = ZFS_GET_NCOLS;
7887                                         break;
7888                                 default:
7889                                         (void) fprintf(stderr,
7890                                             gettext("invalid column name "
7891                                             "'%s'\n"), value);
7892                                         usage(B_FALSE);
7893                                 }
7894                         }
7895                         break;
7896                 case '?':
7897                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7898                             optopt);
7899                         usage(B_FALSE);
7900                 }
7901         }
7902
7903         argc -= optind;
7904         argv += optind;
7905
7906         if (argc < 1) {
7907                 (void) fprintf(stderr, gettext("missing property "
7908                     "argument\n"));
7909                 usage(B_FALSE);
7910         }
7911
7912         if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
7913             ZFS_TYPE_POOL) != 0)
7914                 usage(B_FALSE);
7915
7916         argc--;
7917         argv++;
7918
7919         if (cb.cb_proplist != NULL) {
7920                 fake_name.pl_prop = ZPOOL_PROP_NAME;
7921                 fake_name.pl_width = strlen(gettext("NAME"));
7922                 fake_name.pl_next = cb.cb_proplist;
7923                 cb.cb_proplist = &fake_name;
7924         }
7925
7926         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
7927             get_callback, &cb);
7928
7929         if (cb.cb_proplist == &fake_name)
7930                 zprop_free_list(fake_name.pl_next);
7931         else
7932                 zprop_free_list(cb.cb_proplist);
7933
7934         return (ret);
7935 }
7936
7937 typedef struct set_cbdata {
7938         char *cb_propname;
7939         char *cb_value;
7940         boolean_t cb_any_successful;
7941 } set_cbdata_t;
7942
7943 int
7944 set_callback(zpool_handle_t *zhp, void *data)
7945 {
7946         int error;
7947         set_cbdata_t *cb = (set_cbdata_t *)data;
7948
7949         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
7950
7951         if (!error)
7952                 cb->cb_any_successful = B_TRUE;
7953
7954         return (error);
7955 }
7956
7957 int
7958 zpool_do_set(int argc, char **argv)
7959 {
7960         set_cbdata_t cb = { 0 };
7961         int error;
7962
7963         if (argc > 1 && argv[1][0] == '-') {
7964                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7965                     argv[1][1]);
7966                 usage(B_FALSE);
7967         }
7968
7969         if (argc < 2) {
7970                 (void) fprintf(stderr, gettext("missing property=value "
7971                     "argument\n"));
7972                 usage(B_FALSE);
7973         }
7974
7975         if (argc < 3) {
7976                 (void) fprintf(stderr, gettext("missing pool name\n"));
7977                 usage(B_FALSE);
7978         }
7979
7980         if (argc > 3) {
7981                 (void) fprintf(stderr, gettext("too many pool names\n"));
7982                 usage(B_FALSE);
7983         }
7984
7985         cb.cb_propname = argv[1];
7986         cb.cb_value = strchr(cb.cb_propname, '=');
7987         if (cb.cb_value == NULL) {
7988                 (void) fprintf(stderr, gettext("missing value in "
7989                     "property=value argument\n"));
7990                 usage(B_FALSE);
7991         }
7992
7993         *(cb.cb_value) = '\0';
7994         cb.cb_value++;
7995
7996         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
7997             set_callback, &cb);
7998
7999         return (error);
8000 }
8001
8002 static int
8003 find_command_idx(char *command, int *idx)
8004 {
8005         int i;
8006
8007         for (i = 0; i < NCOMMAND; i++) {
8008                 if (command_table[i].name == NULL)
8009                         continue;
8010
8011                 if (strcmp(command, command_table[i].name) == 0) {
8012                         *idx = i;
8013                         return (0);
8014                 }
8015         }
8016         return (1);
8017 }
8018
8019 int
8020 main(int argc, char **argv)
8021 {
8022         int ret = 0;
8023         int i = 0;
8024         char *cmdname;
8025
8026         (void) setlocale(LC_ALL, "");
8027         (void) textdomain(TEXT_DOMAIN);
8028         srand(time(NULL));
8029
8030         opterr = 0;
8031
8032         /*
8033          * Make sure the user has specified some command.
8034          */
8035         if (argc < 2) {
8036                 (void) fprintf(stderr, gettext("missing command\n"));
8037                 usage(B_FALSE);
8038         }
8039
8040         cmdname = argv[1];
8041
8042         /*
8043          * Special case '-?'
8044          */
8045         if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0)
8046                 usage(B_TRUE);
8047
8048         if ((g_zfs = libzfs_init()) == NULL) {
8049                 (void) fprintf(stderr, "%s", libzfs_error_init(errno));
8050                 return (1);
8051         }
8052
8053         libzfs_print_on_error(g_zfs, B_TRUE);
8054
8055         zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
8056
8057         /*
8058          * Run the appropriate command.
8059          */
8060         if (find_command_idx(cmdname, &i) == 0) {
8061                 current_command = &command_table[i];
8062                 ret = command_table[i].func(argc - 1, argv + 1);
8063         } else if (strchr(cmdname, '=')) {
8064                 verify(find_command_idx("set", &i) == 0);
8065                 current_command = &command_table[i];
8066                 ret = command_table[i].func(argc, argv);
8067         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
8068                 /*
8069                  * 'freeze' is a vile debugging abomination, so we treat
8070                  * it as such.
8071                  */
8072                 zfs_cmd_t zc = {"\0"};
8073
8074                 (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name));
8075                 ret = zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc);
8076                 if (ret != 0) {
8077                         (void) fprintf(stderr,
8078                         gettext("failed to freeze pool: %d\n"), errno);
8079                         ret = 1;
8080                 }
8081
8082                 log_history = 0;
8083         } else {
8084                 (void) fprintf(stderr, gettext("unrecognized "
8085                     "command '%s'\n"), cmdname);
8086                 usage(B_FALSE);
8087                 ret = 1;
8088         }
8089
8090         if (ret == 0 && log_history)
8091                 (void) zpool_log_history(g_zfs, history_str);
8092
8093         libzfs_fini(g_zfs);
8094
8095         /*
8096          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
8097          * for the purposes of running ::findleaks.
8098          */
8099         if (getenv("ZFS_ABORT") != NULL) {
8100                 (void) printf("dumping core by request\n");
8101                 abort();
8102         }
8103
8104         return (ret);
8105 }