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