]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cmd/zpool/zpool_main.c
zpool import -t should not update cachefile
[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, 2014 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  */
29
30 #include <assert.h>
31 #include <ctype.h>
32 #include <dirent.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <libgen.h>
36 #include <libintl.h>
37 #include <libuutil.h>
38 #include <locale.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <strings.h>
43 #include <unistd.h>
44 #include <priv.h>
45 #include <pwd.h>
46 #include <zone.h>
47 #include <zfs_prop.h>
48 #include <sys/fs/zfs.h>
49 #include <sys/stat.h>
50 #include <sys/fm/util.h>
51 #include <sys/fm/protocol.h>
52 #include <sys/zfs_ioctl.h>
53
54 #include <libzfs.h>
55
56 #include "zpool_util.h"
57 #include "zfs_comutil.h"
58 #include "zfeature_common.h"
59
60 #include "statcommon.h"
61
62 static int zpool_do_create(int, char **);
63 static int zpool_do_destroy(int, char **);
64
65 static int zpool_do_add(int, char **);
66 static int zpool_do_remove(int, char **);
67 static int zpool_do_labelclear(int, char **);
68
69 static int zpool_do_list(int, char **);
70 static int zpool_do_iostat(int, char **);
71 static int zpool_do_status(int, char **);
72
73 static int zpool_do_online(int, char **);
74 static int zpool_do_offline(int, char **);
75 static int zpool_do_clear(int, char **);
76 static int zpool_do_reopen(int, char **);
77
78 static int zpool_do_reguid(int, char **);
79
80 static int zpool_do_attach(int, char **);
81 static int zpool_do_detach(int, char **);
82 static int zpool_do_replace(int, char **);
83 static int zpool_do_split(int, char **);
84
85 static int zpool_do_scrub(int, char **);
86
87 static int zpool_do_import(int, char **);
88 static int zpool_do_export(int, char **);
89
90 static int zpool_do_upgrade(int, char **);
91
92 static int zpool_do_history(int, char **);
93 static int zpool_do_events(int, char **);
94
95 static int zpool_do_get(int, char **);
96 static int zpool_do_set(int, char **);
97
98 /*
99  * These libumem hooks provide a reasonable set of defaults for the allocator's
100  * debugging facilities.
101  */
102
103 #ifdef DEBUG
104 const char *
105 _umem_debug_init(void)
106 {
107         return ("default,verbose"); /* $UMEM_DEBUG setting */
108 }
109
110 const char *
111 _umem_logging_init(void)
112 {
113         return ("fail,contents"); /* $UMEM_LOGGING setting */
114 }
115 #endif
116
117 typedef enum {
118         HELP_ADD,
119         HELP_ATTACH,
120         HELP_CLEAR,
121         HELP_CREATE,
122         HELP_DESTROY,
123         HELP_DETACH,
124         HELP_EXPORT,
125         HELP_HISTORY,
126         HELP_IMPORT,
127         HELP_IOSTAT,
128         HELP_LABELCLEAR,
129         HELP_LIST,
130         HELP_OFFLINE,
131         HELP_ONLINE,
132         HELP_REPLACE,
133         HELP_REMOVE,
134         HELP_SCRUB,
135         HELP_STATUS,
136         HELP_UPGRADE,
137         HELP_EVENTS,
138         HELP_GET,
139         HELP_SET,
140         HELP_SPLIT,
141         HELP_REGUID,
142         HELP_REOPEN
143 } zpool_help_t;
144
145
146 typedef struct zpool_command {
147         const char      *name;
148         int             (*func)(int, char **);
149         zpool_help_t    usage;
150 } zpool_command_t;
151
152 /*
153  * Master command table.  Each ZFS command has a name, associated function, and
154  * usage message.  The usage messages need to be internationalized, so we have
155  * to have a function to return the usage message based on a command index.
156  *
157  * These commands are organized according to how they are displayed in the usage
158  * message.  An empty command (one with a NULL name) indicates an empty line in
159  * the generic usage message.
160  */
161 static zpool_command_t command_table[] = {
162         { "create",     zpool_do_create,        HELP_CREATE             },
163         { "destroy",    zpool_do_destroy,       HELP_DESTROY            },
164         { NULL },
165         { "add",        zpool_do_add,           HELP_ADD                },
166         { "remove",     zpool_do_remove,        HELP_REMOVE             },
167         { NULL },
168         { "labelclear", zpool_do_labelclear,    HELP_LABELCLEAR         },
169         { NULL },
170         { "list",       zpool_do_list,          HELP_LIST               },
171         { "iostat",     zpool_do_iostat,        HELP_IOSTAT             },
172         { "status",     zpool_do_status,        HELP_STATUS             },
173         { NULL },
174         { "online",     zpool_do_online,        HELP_ONLINE             },
175         { "offline",    zpool_do_offline,       HELP_OFFLINE            },
176         { "clear",      zpool_do_clear,         HELP_CLEAR              },
177         { "reopen",     zpool_do_reopen,        HELP_REOPEN             },
178         { NULL },
179         { "attach",     zpool_do_attach,        HELP_ATTACH             },
180         { "detach",     zpool_do_detach,        HELP_DETACH             },
181         { "replace",    zpool_do_replace,       HELP_REPLACE            },
182         { "split",      zpool_do_split,         HELP_SPLIT              },
183         { NULL },
184         { "scrub",      zpool_do_scrub,         HELP_SCRUB              },
185         { NULL },
186         { "import",     zpool_do_import,        HELP_IMPORT             },
187         { "export",     zpool_do_export,        HELP_EXPORT             },
188         { "upgrade",    zpool_do_upgrade,       HELP_UPGRADE            },
189         { "reguid",     zpool_do_reguid,        HELP_REGUID             },
190         { NULL },
191         { "history",    zpool_do_history,       HELP_HISTORY            },
192         { "events",     zpool_do_events,        HELP_EVENTS             },
193         { NULL },
194         { "get",        zpool_do_get,           HELP_GET                },
195         { "set",        zpool_do_set,           HELP_SET                },
196 };
197
198 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
199
200 static zpool_command_t *current_command;
201 static char history_str[HIS_MAX_RECORD_LEN];
202 static boolean_t log_history = B_TRUE;
203 static uint_t timestamp_fmt = NODATE;
204
205 static const char *
206 get_usage(zpool_help_t idx) {
207         switch (idx) {
208         case HELP_ADD:
209                 return (gettext("\tadd [-fn] [-o property=value] "
210                     "<pool> <vdev> ...\n"));
211         case HELP_ATTACH:
212                 return (gettext("\tattach [-f] [-o property=value] "
213                     "<pool> <device> <new-device>\n"));
214         case HELP_CLEAR:
215                 return (gettext("\tclear [-nF] <pool> [device]\n"));
216         case HELP_CREATE:
217                 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
218                     "\t    [-O file-system-property=value] ... \n"
219                     "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
220         case HELP_DESTROY:
221                 return (gettext("\tdestroy [-f] <pool>\n"));
222         case HELP_DETACH:
223                 return (gettext("\tdetach <pool> <device>\n"));
224         case HELP_EXPORT:
225                 return (gettext("\texport [-f] <pool> ...\n"));
226         case HELP_HISTORY:
227                 return (gettext("\thistory [-il] [<pool>] ...\n"));
228         case HELP_IMPORT:
229                 return (gettext("\timport [-d dir] [-D]\n"
230                     "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
231                     "\timport [-o mntopts] [-o property=value] ... \n"
232                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
233                     "[-R root] [-F [-n]] -a\n"
234                     "\timport [-o mntopts] [-o property=value] ... \n"
235                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
236                     "[-R root] [-F [-n]]\n"
237                     "\t    <pool | id> [newpool]\n"));
238         case HELP_IOSTAT:
239                 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
240                     "[count]]\n"));
241         case HELP_LABELCLEAR:
242                 return (gettext("\tlabelclear [-f] <vdev>\n"));
243         case HELP_LIST:
244                 return (gettext("\tlist [-Hv] [-o property[,...]] "
245                     "[-T d|u] [pool] ... [interval [count]]\n"));
246         case HELP_OFFLINE:
247                 return (gettext("\toffline [-t] <pool> <device> ...\n"));
248         case HELP_ONLINE:
249                 return (gettext("\tonline <pool> <device> ...\n"));
250         case HELP_REPLACE:
251                 return (gettext("\treplace [-f] [-o property=value] "
252                     "<pool> <device> [new-device]\n"));
253         case HELP_REMOVE:
254                 return (gettext("\tremove <pool> <device> ...\n"));
255         case HELP_REOPEN:
256                 return (gettext("\treopen <pool>\n"));
257         case HELP_SCRUB:
258                 return (gettext("\tscrub [-s] <pool> ...\n"));
259         case HELP_STATUS:
260                 return (gettext("\tstatus [-vxD] [-T d|u] [pool] ... [interval "
261                     "[count]]\n"));
262         case HELP_UPGRADE:
263                 return (gettext("\tupgrade\n"
264                     "\tupgrade -v\n"
265                     "\tupgrade [-V version] <-a | pool ...>\n"));
266         case HELP_EVENTS:
267                 return (gettext("\tevents [-vHfc]\n"));
268         case HELP_GET:
269                 return (gettext("\tget [-pH] <\"all\" | property[,...]> "
270                     "<pool> ...\n"));
271         case HELP_SET:
272                 return (gettext("\tset <property=value> <pool> \n"));
273         case HELP_SPLIT:
274                 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
275                     "\t    [-o property=value] <pool> <newpool> "
276                     "[<device> ...]\n"));
277         case HELP_REGUID:
278                 return (gettext("\treguid <pool>\n"));
279         }
280
281         abort();
282         /* NOTREACHED */
283 }
284
285
286 /*
287  * Callback routine that will print out a pool property value.
288  */
289 static int
290 print_prop_cb(int prop, void *cb)
291 {
292         FILE *fp = cb;
293
294         (void) fprintf(fp, "\t%-15s  ", zpool_prop_to_name(prop));
295
296         if (zpool_prop_readonly(prop))
297                 (void) fprintf(fp, "  NO   ");
298         else
299                 (void) fprintf(fp, " YES   ");
300
301         if (zpool_prop_values(prop) == NULL)
302                 (void) fprintf(fp, "-\n");
303         else
304                 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
305
306         return (ZPROP_CONT);
307 }
308
309 /*
310  * Display usage message.  If we're inside a command, display only the usage for
311  * that command.  Otherwise, iterate over the entire command table and display
312  * a complete usage message.
313  */
314 void
315 usage(boolean_t requested)
316 {
317         FILE *fp = requested ? stdout : stderr;
318
319         if (current_command == NULL) {
320                 int i;
321
322                 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
323                 (void) fprintf(fp,
324                     gettext("where 'command' is one of the following:\n\n"));
325
326                 for (i = 0; i < NCOMMAND; i++) {
327                         if (command_table[i].name == NULL)
328                                 (void) fprintf(fp, "\n");
329                         else
330                                 (void) fprintf(fp, "%s",
331                                     get_usage(command_table[i].usage));
332                 }
333         } else {
334                 (void) fprintf(fp, gettext("usage:\n"));
335                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
336         }
337
338         if (current_command != NULL &&
339             ((strcmp(current_command->name, "set") == 0) ||
340             (strcmp(current_command->name, "get") == 0) ||
341             (strcmp(current_command->name, "list") == 0))) {
342
343                 (void) fprintf(fp,
344                     gettext("\nthe following properties are supported:\n"));
345
346                 (void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
347                     "PROPERTY", "EDIT", "VALUES");
348
349                 /* Iterate over all properties */
350                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
351                     ZFS_TYPE_POOL);
352
353                 (void) fprintf(fp, "\t%-15s   ", "feature@...");
354                 (void) fprintf(fp, "YES   disabled | enabled | active\n");
355
356                 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
357                     "appended with a feature name.\nSee zpool-features(5).\n"));
358         }
359
360         /*
361          * See comments at end of main().
362          */
363         if (getenv("ZFS_ABORT") != NULL) {
364                 (void) printf("dumping core by request\n");
365                 abort();
366         }
367
368         exit(requested ? 0 : 2);
369 }
370
371 void
372 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
373     boolean_t print_logs)
374 {
375         nvlist_t **child;
376         uint_t c, children;
377         char *vname;
378
379         if (name != NULL)
380                 (void) printf("\t%*s%s\n", indent, "", name);
381
382         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
383             &child, &children) != 0)
384                 return;
385
386         for (c = 0; c < children; c++) {
387                 uint64_t is_log = B_FALSE;
388
389                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
390                     &is_log);
391                 if ((is_log && !print_logs) || (!is_log && print_logs))
392                         continue;
393
394                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
395                 print_vdev_tree(zhp, vname, child[c], indent + 2,
396                     B_FALSE);
397                 free(vname);
398         }
399 }
400
401 static boolean_t
402 prop_list_contains_feature(nvlist_t *proplist)
403 {
404         nvpair_t *nvp;
405         for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
406             nvp = nvlist_next_nvpair(proplist, nvp)) {
407                 if (zpool_prop_feature(nvpair_name(nvp)))
408                         return (B_TRUE);
409         }
410         return (B_FALSE);
411 }
412
413 /*
414  * Add a property pair (name, string-value) into a property nvlist.
415  */
416 static int
417 add_prop_list(const char *propname, char *propval, nvlist_t **props,
418     boolean_t poolprop)
419 {
420         zpool_prop_t prop = ZPROP_INVAL;
421         zfs_prop_t fprop;
422         nvlist_t *proplist;
423         const char *normnm;
424         char *strval;
425
426         if (*props == NULL &&
427             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
428                 (void) fprintf(stderr,
429                     gettext("internal error: out of memory\n"));
430                 return (1);
431         }
432
433         proplist = *props;
434
435         if (poolprop) {
436                 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
437
438                 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
439                     !zpool_prop_feature(propname)) {
440                         (void) fprintf(stderr, gettext("property '%s' is "
441                             "not a valid pool property\n"), propname);
442                         return (2);
443                 }
444
445                 /*
446                  * feature@ properties and version should not be specified
447                  * at the same time.
448                  */
449                 if ((prop == ZPROP_INVAL && zpool_prop_feature(propname) &&
450                     nvlist_exists(proplist, vname)) ||
451                     (prop == ZPOOL_PROP_VERSION &&
452                     prop_list_contains_feature(proplist))) {
453                         (void) fprintf(stderr, gettext("'feature@' and "
454                             "'version' properties cannot be specified "
455                             "together\n"));
456                         return (2);
457                 }
458
459
460                 if (zpool_prop_feature(propname))
461                         normnm = propname;
462                 else
463                         normnm = zpool_prop_to_name(prop);
464         } else {
465                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
466                         normnm = zfs_prop_to_name(fprop);
467                 } else {
468                         normnm = propname;
469                 }
470         }
471
472         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
473             prop != ZPOOL_PROP_CACHEFILE) {
474                 (void) fprintf(stderr, gettext("property '%s' "
475                     "specified multiple times\n"), propname);
476                 return (2);
477         }
478
479         if (nvlist_add_string(proplist, normnm, propval) != 0) {
480                 (void) fprintf(stderr, gettext("internal "
481                     "error: out of memory\n"));
482                 return (1);
483         }
484
485         return (0);
486 }
487
488 /*
489  * Set a default property pair (name, string-value) in a property nvlist
490  */
491 static int
492 add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
493     boolean_t poolprop)
494 {
495         char *pval;
496
497         if (nvlist_lookup_string(*props, propname, &pval) == 0)
498                 return (0);
499
500         return (add_prop_list(propname, propval, props, B_TRUE));
501 }
502
503 /*
504  * zpool add [-fn] [-o property=value] <pool> <vdev> ...
505  *
506  *      -f      Force addition of devices, even if they appear in use
507  *      -n      Do not add the devices, but display the resulting layout if
508  *              they were to be added.
509  *      -o      Set property=value.
510  *
511  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
512  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
513  * libzfs.
514  */
515 int
516 zpool_do_add(int argc, char **argv)
517 {
518         boolean_t force = B_FALSE;
519         boolean_t dryrun = B_FALSE;
520         int c;
521         nvlist_t *nvroot;
522         char *poolname;
523         int ret;
524         zpool_handle_t *zhp;
525         nvlist_t *config;
526         nvlist_t *props = NULL;
527         char *propval;
528
529         /* check options */
530         while ((c = getopt(argc, argv, "fno:")) != -1) {
531                 switch (c) {
532                 case 'f':
533                         force = B_TRUE;
534                         break;
535                 case 'n':
536                         dryrun = B_TRUE;
537                         break;
538                 case 'o':
539                         if ((propval = strchr(optarg, '=')) == NULL) {
540                                 (void) fprintf(stderr, gettext("missing "
541                                     "'=' for -o option\n"));
542                                 usage(B_FALSE);
543                         }
544                         *propval = '\0';
545                         propval++;
546
547                         if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
548                             (add_prop_list(optarg, propval, &props, B_TRUE)))
549                                 usage(B_FALSE);
550                         break;
551                 case '?':
552                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
553                             optopt);
554                         usage(B_FALSE);
555                 }
556         }
557
558         argc -= optind;
559         argv += optind;
560
561         /* get pool name and check number of arguments */
562         if (argc < 1) {
563                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
564                 usage(B_FALSE);
565         }
566         if (argc < 2) {
567                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
568                 usage(B_FALSE);
569         }
570
571         poolname = argv[0];
572
573         argc--;
574         argv++;
575
576         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
577                 return (1);
578
579         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
580                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
581                     poolname);
582                 zpool_close(zhp);
583                 return (1);
584         }
585
586         /* pass off to get_vdev_spec for processing */
587         nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
588             argc, argv);
589         if (nvroot == NULL) {
590                 zpool_close(zhp);
591                 return (1);
592         }
593
594         if (dryrun) {
595                 nvlist_t *poolnvroot;
596
597                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
598                     &poolnvroot) == 0);
599
600                 (void) printf(gettext("would update '%s' to the following "
601                     "configuration:\n"), zpool_get_name(zhp));
602
603                 /* print original main pool and new tree */
604                 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
605                 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
606
607                 /* Do the same for the logs */
608                 if (num_logs(poolnvroot) > 0) {
609                         print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
610                         print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
611                 } else if (num_logs(nvroot) > 0) {
612                         print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
613                 }
614
615                 ret = 0;
616         } else {
617                 ret = (zpool_add(zhp, nvroot) != 0);
618         }
619
620         nvlist_free(props);
621         nvlist_free(nvroot);
622         zpool_close(zhp);
623
624         return (ret);
625 }
626
627 /*
628  * zpool remove  <pool> <vdev> ...
629  *
630  * Removes the given vdev from the pool.  Currently, this supports removing
631  * spares, cache, and log devices from the pool.
632  */
633 int
634 zpool_do_remove(int argc, char **argv)
635 {
636         char *poolname;
637         int i, ret = 0;
638         zpool_handle_t *zhp;
639
640         argc--;
641         argv++;
642
643         /* get pool name and check number of arguments */
644         if (argc < 1) {
645                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
646                 usage(B_FALSE);
647         }
648         if (argc < 2) {
649                 (void) fprintf(stderr, gettext("missing device\n"));
650                 usage(B_FALSE);
651         }
652
653         poolname = argv[0];
654
655         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
656                 return (1);
657
658         for (i = 1; i < argc; i++) {
659                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
660                         ret = 1;
661         }
662
663         return (ret);
664 }
665
666 /*
667  * zpool labelclear <vdev>
668  *
669  * Verifies that the vdev is not active and zeros out the label information
670  * on the device.
671  */
672 int
673 zpool_do_labelclear(int argc, char **argv)
674 {
675         char *vdev, *name;
676         int c, fd = -1, ret = 0;
677         pool_state_t state;
678         boolean_t inuse = B_FALSE;
679         boolean_t force = B_FALSE;
680
681         /* check options */
682         while ((c = getopt(argc, argv, "f")) != -1) {
683                 switch (c) {
684                 case 'f':
685                         force = B_TRUE;
686                         break;
687                 default:
688                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
689                             optopt);
690                         usage(B_FALSE);
691                 }
692         }
693
694         argc -= optind;
695         argv += optind;
696
697         /* get vdev name */
698         if (argc < 1) {
699                 (void) fprintf(stderr, gettext("missing vdev device name\n"));
700                 usage(B_FALSE);
701         }
702
703         vdev = argv[0];
704         if ((fd = open(vdev, O_RDWR)) < 0) {
705                 (void) fprintf(stderr, gettext("Unable to open %s\n"), vdev);
706                 return (B_FALSE);
707         }
708
709         name = NULL;
710         if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0) {
711                 if (force)
712                         goto wipe_label;
713
714                 (void) fprintf(stderr,
715                     gettext("Unable to determine pool state for %s\n"
716                     "Use -f to force the clearing any label data\n"), vdev);
717
718                 return (1);
719         }
720
721         if (inuse) {
722                 switch (state) {
723                 default:
724                 case POOL_STATE_ACTIVE:
725                 case POOL_STATE_SPARE:
726                 case POOL_STATE_L2CACHE:
727                         (void) fprintf(stderr,
728                             gettext("labelclear operation failed.\n"
729                             "\tVdev %s is a member (%s), of pool \"%s\".\n"
730                             "\tTo remove label information from this device, "
731                             "export or destroy\n\tthe pool, or remove %s from "
732                             "the configuration of this pool\n\tand retry the "
733                             "labelclear operation.\n"),
734                             vdev, zpool_pool_state_to_name(state), name, vdev);
735                         ret = 1;
736                         goto errout;
737
738                 case POOL_STATE_EXPORTED:
739                         if (force)
740                                 break;
741
742                         (void) fprintf(stderr,
743                             gettext("labelclear operation failed.\n\tVdev "
744                             "%s is a member of the exported pool \"%s\".\n"
745                             "\tUse \"zpool labelclear -f %s\" to force the "
746                             "removal of label\n\tinformation.\n"),
747                             vdev, name, vdev);
748                         ret = 1;
749                         goto errout;
750
751                 case POOL_STATE_POTENTIALLY_ACTIVE:
752                         if (force)
753                                 break;
754
755                         (void) fprintf(stderr,
756                             gettext("labelclear operation failed.\n"
757                             "\tVdev %s is a member of the pool \"%s\".\n"
758                             "\tThis pool is unknown to this system, but may "
759                             "be active on\n\tanother system. Use "
760                             "\'zpool labelclear -f %s\' to force the\n"
761                             "\tremoval of label information.\n"),
762                             vdev, name, vdev);
763                         ret = 1;
764                         goto errout;
765
766                 case POOL_STATE_DESTROYED:
767                         /* inuse should never be set for a destroyed pool... */
768                         break;
769                 }
770         }
771
772 wipe_label:
773         if (zpool_clear_label(fd) != 0) {
774                 (void) fprintf(stderr,
775                     gettext("Label clear failed on vdev %s\n"), vdev);
776                 ret = 1;
777         }
778
779 errout:
780         close(fd);
781         if (name != NULL)
782                 free(name);
783
784         return (ret);
785 }
786
787 /*
788  * zpool create [-fnd] [-o property=value] ...
789  *              [-O file-system-property=value] ...
790  *              [-R root] [-m mountpoint] <pool> <dev> ...
791  *
792  *      -f      Force creation, even if devices appear in use
793  *      -n      Do not create the pool, but display the resulting layout if it
794  *              were to be created.
795  *      -R      Create a pool under an alternate root
796  *      -m      Set default mountpoint for the root dataset.  By default it's
797  *              '/<pool>'
798  *      -o      Set property=value.
799  *      -d      Don't automatically enable all supported pool features
800  *              (individual features can be enabled with -o).
801  *      -O      Set fsproperty=value in the pool's root file system
802  *
803  * Creates the named pool according to the given vdev specification.  The
804  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
805  * we get the nvlist back from get_vdev_spec(), we either print out the contents
806  * (if '-n' was specified), or pass it to libzfs to do the creation.
807  */
808 int
809 zpool_do_create(int argc, char **argv)
810 {
811         boolean_t force = B_FALSE;
812         boolean_t dryrun = B_FALSE;
813         boolean_t enable_all_pool_feat = B_TRUE;
814         int c;
815         nvlist_t *nvroot = NULL;
816         char *poolname;
817         int ret = 1;
818         char *altroot = NULL;
819         char *mountpoint = NULL;
820         nvlist_t *fsprops = NULL;
821         nvlist_t *props = NULL;
822         char *propval;
823
824         /* check options */
825         while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) {
826                 switch (c) {
827                 case 'f':
828                         force = B_TRUE;
829                         break;
830                 case 'n':
831                         dryrun = B_TRUE;
832                         break;
833                 case 'd':
834                         enable_all_pool_feat = B_FALSE;
835                         break;
836                 case 'R':
837                         altroot = optarg;
838                         if (add_prop_list(zpool_prop_to_name(
839                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
840                                 goto errout;
841                         if (add_prop_list_default(zpool_prop_to_name(
842                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
843                                 goto errout;
844                         break;
845                 case 'm':
846                         /* Equivalent to -O mountpoint=optarg */
847                         mountpoint = optarg;
848                         break;
849                 case 'o':
850                         if ((propval = strchr(optarg, '=')) == NULL) {
851                                 (void) fprintf(stderr, gettext("missing "
852                                     "'=' for -o option\n"));
853                                 goto errout;
854                         }
855                         *propval = '\0';
856                         propval++;
857
858                         if (add_prop_list(optarg, propval, &props, B_TRUE))
859                                 goto errout;
860
861                         /*
862                          * If the user is creating a pool that doesn't support
863                          * feature flags, don't enable any features.
864                          */
865                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
866                                 char *end;
867                                 u_longlong_t ver;
868
869                                 ver = strtoull(propval, &end, 10);
870                                 if (*end == '\0' &&
871                                     ver < SPA_VERSION_FEATURES) {
872                                         enable_all_pool_feat = B_FALSE;
873                                 }
874                         }
875                         break;
876                 case 'O':
877                         if ((propval = strchr(optarg, '=')) == NULL) {
878                                 (void) fprintf(stderr, gettext("missing "
879                                     "'=' for -O option\n"));
880                                 goto errout;
881                         }
882                         *propval = '\0';
883                         propval++;
884
885                         /*
886                          * Mountpoints are checked and then added later.
887                          * Uniquely among properties, they can be specified
888                          * more than once, to avoid conflict with -m.
889                          */
890                         if (0 == strcmp(optarg,
891                             zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
892                                 mountpoint = propval;
893                         } else if (add_prop_list(optarg, propval, &fsprops,
894                             B_FALSE)) {
895                                 goto errout;
896                         }
897                         break;
898                 case ':':
899                         (void) fprintf(stderr, gettext("missing argument for "
900                             "'%c' option\n"), optopt);
901                         goto badusage;
902                 case '?':
903                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
904                             optopt);
905                         goto badusage;
906                 }
907         }
908
909         argc -= optind;
910         argv += optind;
911
912         /* get pool name and check number of arguments */
913         if (argc < 1) {
914                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
915                 goto badusage;
916         }
917         if (argc < 2) {
918                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
919                 goto badusage;
920         }
921
922         poolname = argv[0];
923
924         /*
925          * As a special case, check for use of '/' in the name, and direct the
926          * user to use 'zfs create' instead.
927          */
928         if (strchr(poolname, '/') != NULL) {
929                 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
930                     "character '/' in pool name\n"), poolname);
931                 (void) fprintf(stderr, gettext("use 'zfs create' to "
932                     "create a dataset\n"));
933                 goto errout;
934         }
935
936         /* pass off to get_vdev_spec for bulk processing */
937         nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
938             argc - 1, argv + 1);
939         if (nvroot == NULL)
940                 goto errout;
941
942         /* make_root_vdev() allows 0 toplevel children if there are spares */
943         if (!zfs_allocatable_devs(nvroot)) {
944                 (void) fprintf(stderr, gettext("invalid vdev "
945                     "specification: at least one toplevel vdev must be "
946                     "specified\n"));
947                 goto errout;
948         }
949
950         if (altroot != NULL && altroot[0] != '/') {
951                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
952                     "must be an absolute path\n"), altroot);
953                 goto errout;
954         }
955
956         /*
957          * Check the validity of the mountpoint and direct the user to use the
958          * '-m' mountpoint option if it looks like its in use.
959          */
960         if (mountpoint == NULL ||
961             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
962             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
963                 char buf[MAXPATHLEN];
964                 DIR *dirp;
965
966                 if (mountpoint && mountpoint[0] != '/') {
967                         (void) fprintf(stderr, gettext("invalid mountpoint "
968                             "'%s': must be an absolute path, 'legacy', or "
969                             "'none'\n"), mountpoint);
970                         goto errout;
971                 }
972
973                 if (mountpoint == NULL) {
974                         if (altroot != NULL)
975                                 (void) snprintf(buf, sizeof (buf), "%s/%s",
976                                     altroot, poolname);
977                         else
978                                 (void) snprintf(buf, sizeof (buf), "/%s",
979                                     poolname);
980                 } else {
981                         if (altroot != NULL)
982                                 (void) snprintf(buf, sizeof (buf), "%s%s",
983                                     altroot, mountpoint);
984                         else
985                                 (void) snprintf(buf, sizeof (buf), "%s",
986                                     mountpoint);
987                 }
988
989                 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
990                         (void) fprintf(stderr, gettext("mountpoint '%s' : "
991                             "%s\n"), buf, strerror(errno));
992                         (void) fprintf(stderr, gettext("use '-m' "
993                             "option to provide a different default\n"));
994                         goto errout;
995                 } else if (dirp) {
996                         int count = 0;
997
998                         while (count < 3 && readdir(dirp) != NULL)
999                                 count++;
1000                         (void) closedir(dirp);
1001
1002                         if (count > 2) {
1003                                 (void) fprintf(stderr, gettext("mountpoint "
1004                                     "'%s' exists and is not empty\n"), buf);
1005                                 (void) fprintf(stderr, gettext("use '-m' "
1006                                     "option to provide a "
1007                                     "different default\n"));
1008                                 goto errout;
1009                         }
1010                 }
1011         }
1012
1013         /*
1014          * Now that the mountpoint's validity has been checked, ensure that
1015          * the property is set appropriately prior to creating the pool.
1016          */
1017         if (mountpoint != NULL) {
1018                 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1019                     mountpoint, &fsprops, B_FALSE);
1020                 if (ret != 0)
1021                         goto errout;
1022         }
1023
1024         ret = 1;
1025         if (dryrun) {
1026                 /*
1027                  * For a dry run invocation, print out a basic message and run
1028                  * through all the vdevs in the list and print out in an
1029                  * appropriate hierarchy.
1030                  */
1031                 (void) printf(gettext("would create '%s' with the "
1032                     "following layout:\n\n"), poolname);
1033
1034                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
1035                 if (num_logs(nvroot) > 0)
1036                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
1037
1038                 ret = 0;
1039         } else {
1040                 /*
1041                  * Hand off to libzfs.
1042                  */
1043                 if (enable_all_pool_feat) {
1044                         spa_feature_t i;
1045                         for (i = 0; i < SPA_FEATURES; i++) {
1046                                 char propname[MAXPATHLEN];
1047                                 zfeature_info_t *feat = &spa_feature_table[i];
1048
1049                                 (void) snprintf(propname, sizeof (propname),
1050                                     "feature@%s", feat->fi_uname);
1051
1052                                 /*
1053                                  * Skip feature if user specified it manually
1054                                  * on the command line.
1055                                  */
1056                                 if (nvlist_exists(props, propname))
1057                                         continue;
1058
1059                                 ret = add_prop_list(propname,
1060                                     ZFS_FEATURE_ENABLED, &props, B_TRUE);
1061                                 if (ret != 0)
1062                                         goto errout;
1063                         }
1064                 }
1065
1066                 ret = 1;
1067                 if (zpool_create(g_zfs, poolname,
1068                     nvroot, props, fsprops) == 0) {
1069                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
1070                             ZFS_TYPE_FILESYSTEM);
1071                         if (pool != NULL) {
1072                                 if (zfs_mount(pool, NULL, 0) == 0)
1073                                         ret = zfs_shareall(pool);
1074                                 zfs_close(pool);
1075                         }
1076                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1077                         (void) fprintf(stderr, gettext("pool name may have "
1078                             "been omitted\n"));
1079                 }
1080         }
1081
1082 errout:
1083         nvlist_free(nvroot);
1084         nvlist_free(fsprops);
1085         nvlist_free(props);
1086         return (ret);
1087 badusage:
1088         nvlist_free(fsprops);
1089         nvlist_free(props);
1090         usage(B_FALSE);
1091         return (2);
1092 }
1093
1094 /*
1095  * zpool destroy <pool>
1096  *
1097  *      -f      Forcefully unmount any datasets
1098  *
1099  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
1100  */
1101 int
1102 zpool_do_destroy(int argc, char **argv)
1103 {
1104         boolean_t force = B_FALSE;
1105         int c;
1106         char *pool;
1107         zpool_handle_t *zhp;
1108         int ret;
1109
1110         /* check options */
1111         while ((c = getopt(argc, argv, "f")) != -1) {
1112                 switch (c) {
1113                 case 'f':
1114                         force = B_TRUE;
1115                         break;
1116                 case '?':
1117                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1118                             optopt);
1119                         usage(B_FALSE);
1120                 }
1121         }
1122
1123         argc -= optind;
1124         argv += optind;
1125
1126         /* check arguments */
1127         if (argc < 1) {
1128                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1129                 usage(B_FALSE);
1130         }
1131         if (argc > 1) {
1132                 (void) fprintf(stderr, gettext("too many arguments\n"));
1133                 usage(B_FALSE);
1134         }
1135
1136         pool = argv[0];
1137
1138         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1139                 /*
1140                  * As a special case, check for use of '/' in the name, and
1141                  * direct the user to use 'zfs destroy' instead.
1142                  */
1143                 if (strchr(pool, '/') != NULL)
1144                         (void) fprintf(stderr, gettext("use 'zfs destroy' to "
1145                             "destroy a dataset\n"));
1146                 return (1);
1147         }
1148
1149         if (zpool_disable_datasets(zhp, force) != 0) {
1150                 (void) fprintf(stderr, gettext("could not destroy '%s': "
1151                     "could not unmount datasets\n"), zpool_get_name(zhp));
1152                 return (1);
1153         }
1154
1155         /* The history must be logged as part of the export */
1156         log_history = B_FALSE;
1157
1158         ret = (zpool_destroy(zhp, history_str) != 0);
1159
1160         zpool_close(zhp);
1161
1162         return (ret);
1163 }
1164
1165 /*
1166  * zpool export [-f] <pool> ...
1167  *
1168  *      -f      Forcefully unmount datasets
1169  *
1170  * Export the given pools.  By default, the command will attempt to cleanly
1171  * unmount any active datasets within the pool.  If the '-f' flag is specified,
1172  * then the datasets will be forcefully unmounted.
1173  */
1174 int
1175 zpool_do_export(int argc, char **argv)
1176 {
1177         boolean_t force = B_FALSE;
1178         boolean_t hardforce = B_FALSE;
1179         int c;
1180         zpool_handle_t *zhp;
1181         int ret;
1182         int i;
1183
1184         /* check options */
1185         while ((c = getopt(argc, argv, "fF")) != -1) {
1186                 switch (c) {
1187                 case 'f':
1188                         force = B_TRUE;
1189                         break;
1190                 case 'F':
1191                         hardforce = B_TRUE;
1192                         break;
1193                 case '?':
1194                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1195                             optopt);
1196                         usage(B_FALSE);
1197                 }
1198         }
1199
1200         argc -= optind;
1201         argv += optind;
1202
1203         /* check arguments */
1204         if (argc < 1) {
1205                 (void) fprintf(stderr, gettext("missing pool argument\n"));
1206                 usage(B_FALSE);
1207         }
1208
1209         ret = 0;
1210         for (i = 0; i < argc; i++) {
1211                 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
1212                         ret = 1;
1213                         continue;
1214                 }
1215
1216                 if (zpool_disable_datasets(zhp, force) != 0) {
1217                         ret = 1;
1218                         zpool_close(zhp);
1219                         continue;
1220                 }
1221
1222                 /* The history must be logged as part of the export */
1223                 log_history = B_FALSE;
1224
1225                 if (hardforce) {
1226                         if (zpool_export_force(zhp, history_str) != 0)
1227                                 ret = 1;
1228                 } else if (zpool_export(zhp, force, history_str) != 0) {
1229                         ret = 1;
1230                 }
1231
1232                 zpool_close(zhp);
1233         }
1234
1235         return (ret);
1236 }
1237
1238 /*
1239  * Given a vdev configuration, determine the maximum width needed for the device
1240  * name column.
1241  */
1242 static int
1243 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
1244 {
1245         char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
1246         nvlist_t **child;
1247         uint_t c, children;
1248         int ret;
1249
1250         if (strlen(name) + depth > max)
1251                 max = strlen(name) + depth;
1252
1253         free(name);
1254
1255         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1256             &child, &children) == 0) {
1257                 for (c = 0; c < children; c++)
1258                         if ((ret = max_width(zhp, child[c], depth + 2,
1259                             max)) > max)
1260                                 max = ret;
1261         }
1262
1263         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1264             &child, &children) == 0) {
1265                 for (c = 0; c < children; c++)
1266                         if ((ret = max_width(zhp, child[c], depth + 2,
1267                             max)) > max)
1268                                 max = ret;
1269         }
1270
1271         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1272             &child, &children) == 0) {
1273                 for (c = 0; c < children; c++)
1274                         if ((ret = max_width(zhp, child[c], depth + 2,
1275                             max)) > max)
1276                                 max = ret;
1277         }
1278
1279
1280         return (max);
1281 }
1282
1283 typedef struct spare_cbdata {
1284         uint64_t        cb_guid;
1285         zpool_handle_t  *cb_zhp;
1286 } spare_cbdata_t;
1287
1288 static boolean_t
1289 find_vdev(nvlist_t *nv, uint64_t search)
1290 {
1291         uint64_t guid;
1292         nvlist_t **child;
1293         uint_t c, children;
1294
1295         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1296             search == guid)
1297                 return (B_TRUE);
1298
1299         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1300             &child, &children) == 0) {
1301                 for (c = 0; c < children; c++)
1302                         if (find_vdev(child[c], search))
1303                                 return (B_TRUE);
1304         }
1305
1306         return (B_FALSE);
1307 }
1308
1309 static int
1310 find_spare(zpool_handle_t *zhp, void *data)
1311 {
1312         spare_cbdata_t *cbp = data;
1313         nvlist_t *config, *nvroot;
1314
1315         config = zpool_get_config(zhp, NULL);
1316         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1317             &nvroot) == 0);
1318
1319         if (find_vdev(nvroot, cbp->cb_guid)) {
1320                 cbp->cb_zhp = zhp;
1321                 return (1);
1322         }
1323
1324         zpool_close(zhp);
1325         return (0);
1326 }
1327
1328 /*
1329  * Print out configuration state as requested by status_callback.
1330  */
1331 void
1332 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
1333     int namewidth, int depth, boolean_t isspare)
1334 {
1335         nvlist_t **child;
1336         uint_t c, children;
1337         pool_scan_stat_t *ps = NULL;
1338         vdev_stat_t *vs;
1339         char rbuf[6], wbuf[6], cbuf[6];
1340         char *vname;
1341         uint64_t notpresent;
1342         spare_cbdata_t cb;
1343         char *state;
1344
1345         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1346             &child, &children) != 0)
1347                 children = 0;
1348
1349         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1350             (uint64_t **)&vs, &c) == 0);
1351
1352         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1353         if (isspare) {
1354                 /*
1355                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1356                  * online drives.
1357                  */
1358                 if (vs->vs_aux == VDEV_AUX_SPARED)
1359                         state = "INUSE";
1360                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1361                         state = "AVAIL";
1362         }
1363
1364         (void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
1365             name, state);
1366
1367         if (!isspare) {
1368                 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1369                 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1370                 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1371                 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1372         }
1373
1374         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1375             &notpresent) == 0) {
1376                 char *path;
1377                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1378                 (void) printf("  was %s", path);
1379         } else if (vs->vs_aux != 0) {
1380                 (void) printf("  ");
1381
1382                 switch (vs->vs_aux) {
1383                 case VDEV_AUX_OPEN_FAILED:
1384                         (void) printf(gettext("cannot open"));
1385                         break;
1386
1387                 case VDEV_AUX_BAD_GUID_SUM:
1388                         (void) printf(gettext("missing device"));
1389                         break;
1390
1391                 case VDEV_AUX_NO_REPLICAS:
1392                         (void) printf(gettext("insufficient replicas"));
1393                         break;
1394
1395                 case VDEV_AUX_VERSION_NEWER:
1396                         (void) printf(gettext("newer version"));
1397                         break;
1398
1399                 case VDEV_AUX_UNSUP_FEAT:
1400                         (void) printf(gettext("unsupported feature(s)"));
1401                         break;
1402
1403                 case VDEV_AUX_SPARED:
1404                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1405                             &cb.cb_guid) == 0);
1406                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1407                                 if (strcmp(zpool_get_name(cb.cb_zhp),
1408                                     zpool_get_name(zhp)) == 0)
1409                                         (void) printf(gettext("currently in "
1410                                             "use"));
1411                                 else
1412                                         (void) printf(gettext("in use by "
1413                                             "pool '%s'"),
1414                                             zpool_get_name(cb.cb_zhp));
1415                                 zpool_close(cb.cb_zhp);
1416                         } else {
1417                                 (void) printf(gettext("currently in use"));
1418                         }
1419                         break;
1420
1421                 case VDEV_AUX_ERR_EXCEEDED:
1422                         (void) printf(gettext("too many errors"));
1423                         break;
1424
1425                 case VDEV_AUX_IO_FAILURE:
1426                         (void) printf(gettext("experienced I/O failures"));
1427                         break;
1428
1429                 case VDEV_AUX_BAD_LOG:
1430                         (void) printf(gettext("bad intent log"));
1431                         break;
1432
1433                 case VDEV_AUX_EXTERNAL:
1434                         (void) printf(gettext("external device fault"));
1435                         break;
1436
1437                 case VDEV_AUX_SPLIT_POOL:
1438                         (void) printf(gettext("split into new pool"));
1439                         break;
1440
1441                 default:
1442                         (void) printf(gettext("corrupted data"));
1443                         break;
1444                 }
1445         }
1446
1447         (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1448             (uint64_t **)&ps, &c);
1449
1450         if (ps && ps->pss_state == DSS_SCANNING &&
1451             vs->vs_scan_processed != 0 && children == 0) {
1452                 (void) printf(gettext("  (%s)"),
1453                     (ps->pss_func == POOL_SCAN_RESILVER) ?
1454                     "resilvering" : "repairing");
1455         }
1456
1457         (void) printf("\n");
1458
1459         for (c = 0; c < children; c++) {
1460                 uint64_t islog = B_FALSE, ishole = B_FALSE;
1461
1462                 /* Don't print logs or holes here */
1463                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1464                     &islog);
1465                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1466                     &ishole);
1467                 if (islog || ishole)
1468                         continue;
1469                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1470                 print_status_config(zhp, vname, child[c],
1471                     namewidth, depth + 2, isspare);
1472                 free(vname);
1473         }
1474 }
1475
1476
1477 /*
1478  * Print the configuration of an exported pool.  Iterate over all vdevs in the
1479  * pool, printing out the name and status for each one.
1480  */
1481 void
1482 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
1483 {
1484         nvlist_t **child;
1485         uint_t c, children;
1486         vdev_stat_t *vs;
1487         char *type, *vname;
1488
1489         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1490         if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1491             strcmp(type, VDEV_TYPE_HOLE) == 0)
1492                 return;
1493
1494         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1495             (uint64_t **)&vs, &c) == 0);
1496
1497         (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
1498         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1499
1500         if (vs->vs_aux != 0) {
1501                 (void) printf("  ");
1502
1503                 switch (vs->vs_aux) {
1504                 case VDEV_AUX_OPEN_FAILED:
1505                         (void) printf(gettext("cannot open"));
1506                         break;
1507
1508                 case VDEV_AUX_BAD_GUID_SUM:
1509                         (void) printf(gettext("missing device"));
1510                         break;
1511
1512                 case VDEV_AUX_NO_REPLICAS:
1513                         (void) printf(gettext("insufficient replicas"));
1514                         break;
1515
1516                 case VDEV_AUX_VERSION_NEWER:
1517                         (void) printf(gettext("newer version"));
1518                         break;
1519
1520                 case VDEV_AUX_UNSUP_FEAT:
1521                         (void) printf(gettext("unsupported feature(s)"));
1522                         break;
1523
1524                 case VDEV_AUX_ERR_EXCEEDED:
1525                         (void) printf(gettext("too many errors"));
1526                         break;
1527
1528                 default:
1529                         (void) printf(gettext("corrupted data"));
1530                         break;
1531                 }
1532         }
1533         (void) printf("\n");
1534
1535         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1536             &child, &children) != 0)
1537                 return;
1538
1539         for (c = 0; c < children; c++) {
1540                 uint64_t is_log = B_FALSE;
1541
1542                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1543                     &is_log);
1544                 if (is_log)
1545                         continue;
1546
1547                 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
1548                 print_import_config(vname, child[c], namewidth, depth + 2);
1549                 free(vname);
1550         }
1551
1552         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1553             &child, &children) == 0) {
1554                 (void) printf(gettext("\tcache\n"));
1555                 for (c = 0; c < children; c++) {
1556                         vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1557                         (void) printf("\t  %s\n", vname);
1558                         free(vname);
1559                 }
1560         }
1561
1562         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1563             &child, &children) == 0) {
1564                 (void) printf(gettext("\tspares\n"));
1565                 for (c = 0; c < children; c++) {
1566                         vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
1567                         (void) printf("\t  %s\n", vname);
1568                         free(vname);
1569                 }
1570         }
1571 }
1572
1573 /*
1574  * Print log vdevs.
1575  * Logs are recorded as top level vdevs in the main pool child array
1576  * but with "is_log" set to 1. We use either print_status_config() or
1577  * print_import_config() to print the top level logs then any log
1578  * children (eg mirrored slogs) are printed recursively - which
1579  * works because only the top level vdev is marked "is_log"
1580  */
1581 static void
1582 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
1583 {
1584         uint_t c, children;
1585         nvlist_t **child;
1586
1587         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1588             &children) != 0)
1589                 return;
1590
1591         (void) printf(gettext("\tlogs\n"));
1592
1593         for (c = 0; c < children; c++) {
1594                 uint64_t is_log = B_FALSE;
1595                 char *name;
1596
1597                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1598                     &is_log);
1599                 if (!is_log)
1600                         continue;
1601                 name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
1602                 if (verbose)
1603                         print_status_config(zhp, name, child[c], namewidth,
1604                             2, B_FALSE);
1605                 else
1606                         print_import_config(name, child[c], namewidth, 2);
1607                 free(name);
1608         }
1609 }
1610
1611 /*
1612  * Display the status for the given pool.
1613  */
1614 static void
1615 show_import(nvlist_t *config)
1616 {
1617         uint64_t pool_state;
1618         vdev_stat_t *vs;
1619         char *name;
1620         uint64_t guid;
1621         char *msgid;
1622         nvlist_t *nvroot;
1623         zpool_status_t reason;
1624         zpool_errata_t errata;
1625         const char *health;
1626         uint_t vsc;
1627         int namewidth;
1628         char *comment;
1629
1630         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1631             &name) == 0);
1632         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1633             &guid) == 0);
1634         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1635             &pool_state) == 0);
1636         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1637             &nvroot) == 0);
1638
1639         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1640             (uint64_t **)&vs, &vsc) == 0);
1641         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1642
1643         reason = zpool_import_status(config, &msgid, &errata);
1644
1645         (void) printf(gettext("   pool: %s\n"), name);
1646         (void) printf(gettext("     id: %llu\n"), (u_longlong_t)guid);
1647         (void) printf(gettext("  state: %s"), health);
1648         if (pool_state == POOL_STATE_DESTROYED)
1649                 (void) printf(gettext(" (DESTROYED)"));
1650         (void) printf("\n");
1651
1652         switch (reason) {
1653         case ZPOOL_STATUS_MISSING_DEV_R:
1654         case ZPOOL_STATUS_MISSING_DEV_NR:
1655         case ZPOOL_STATUS_BAD_GUID_SUM:
1656                 (void) printf(gettext(" status: One or more devices are "
1657                     "missing from the system.\n"));
1658                 break;
1659
1660         case ZPOOL_STATUS_CORRUPT_LABEL_R:
1661         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1662                 (void) printf(gettext(" status: One or more devices contains "
1663                     "corrupted data.\n"));
1664                 break;
1665
1666         case ZPOOL_STATUS_CORRUPT_DATA:
1667                 (void) printf(
1668                     gettext(" status: The pool data is corrupted.\n"));
1669                 break;
1670
1671         case ZPOOL_STATUS_OFFLINE_DEV:
1672                 (void) printf(gettext(" status: One or more devices "
1673                     "are offlined.\n"));
1674                 break;
1675
1676         case ZPOOL_STATUS_CORRUPT_POOL:
1677                 (void) printf(gettext(" status: The pool metadata is "
1678                     "corrupted.\n"));
1679                 break;
1680
1681         case ZPOOL_STATUS_VERSION_OLDER:
1682                 (void) printf(gettext(" status: The pool is formatted using a "
1683                     "legacy on-disk version.\n"));
1684                 break;
1685
1686         case ZPOOL_STATUS_VERSION_NEWER:
1687                 (void) printf(gettext(" status: The pool is formatted using an "
1688                     "incompatible version.\n"));
1689                 break;
1690
1691         case ZPOOL_STATUS_FEAT_DISABLED:
1692                 (void) printf(gettext(" status: Some supported features are "
1693                     "not enabled on the pool.\n"));
1694                 break;
1695
1696         case ZPOOL_STATUS_UNSUP_FEAT_READ:
1697                 (void) printf(gettext("status: The pool uses the following "
1698                     "feature(s) not supported on this sytem:\n"));
1699                 zpool_print_unsup_feat(config);
1700                 break;
1701
1702         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1703                 (void) printf(gettext("status: The pool can only be accessed "
1704                     "in read-only mode on this system. It\n\tcannot be "
1705                     "accessed in read-write mode because it uses the "
1706                     "following\n\tfeature(s) not supported on this system:\n"));
1707                 zpool_print_unsup_feat(config);
1708                 break;
1709
1710         case ZPOOL_STATUS_HOSTID_MISMATCH:
1711                 (void) printf(gettext(" status: The pool was last accessed by "
1712                     "another system.\n"));
1713                 break;
1714
1715         case ZPOOL_STATUS_FAULTED_DEV_R:
1716         case ZPOOL_STATUS_FAULTED_DEV_NR:
1717                 (void) printf(gettext(" status: One or more devices are "
1718                     "faulted.\n"));
1719                 break;
1720
1721         case ZPOOL_STATUS_BAD_LOG:
1722                 (void) printf(gettext(" status: An intent log record cannot be "
1723                     "read.\n"));
1724                 break;
1725
1726         case ZPOOL_STATUS_RESILVERING:
1727                 (void) printf(gettext(" status: One or more devices were being "
1728                     "resilvered.\n"));
1729                 break;
1730
1731         case ZPOOL_STATUS_ERRATA:
1732                 (void) printf(gettext(" status: Errata #%d detected.\n"),
1733                     errata);
1734                 break;
1735
1736         default:
1737                 /*
1738                  * No other status can be seen when importing pools.
1739                  */
1740                 assert(reason == ZPOOL_STATUS_OK);
1741         }
1742
1743         /*
1744          * Print out an action according to the overall state of the pool.
1745          */
1746         if (vs->vs_state == VDEV_STATE_HEALTHY) {
1747                 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
1748                     reason == ZPOOL_STATUS_FEAT_DISABLED) {
1749                         (void) printf(gettext(" action: The pool can be "
1750                             "imported using its name or numeric identifier, "
1751                             "though\n\tsome features will not be available "
1752                             "without an explicit 'zpool upgrade'.\n"));
1753                 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
1754                         (void) printf(gettext(" action: The pool can be "
1755                             "imported using its name or numeric "
1756                             "identifier and\n\tthe '-f' flag.\n"));
1757                 } else if (reason == ZPOOL_STATUS_ERRATA) {
1758                         switch (errata) {
1759                         case ZPOOL_ERRATA_NONE:
1760                                 break;
1761
1762                         case ZPOOL_ERRATA_ZOL_2094_SCRUB:
1763                                 (void) printf(gettext(" action: The pool can "
1764                                     "be imported using its name or numeric "
1765                                     "identifier,\n\thowever there is a compat"
1766                                     "ibility issue which should be corrected"
1767                                     "\n\tby running 'zpool scrub'\n"));
1768                                 break;
1769
1770                         case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
1771                                 (void) printf(gettext(" action: The pool can"
1772                                     "not be imported with this version of ZFS "
1773                                     "due to\n\tan active asynchronous destroy. "
1774                                     "Revert to an earlier version\n\tand "
1775                                     "allow the destroy to complete before "
1776                                     "updating.\n"));
1777                                 break;
1778
1779                         default:
1780                                 /*
1781                                  * All errata must contain an action message.
1782                                  */
1783                                 assert(0);
1784                         }
1785                 } else {
1786                         (void) printf(gettext(" action: The pool can be "
1787                             "imported using its name or numeric "
1788                             "identifier.\n"));
1789                 }
1790         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1791                 (void) printf(gettext(" action: The pool can be imported "
1792                     "despite missing or damaged devices.  The\n\tfault "
1793                     "tolerance of the pool may be compromised if imported.\n"));
1794         } else {
1795                 switch (reason) {
1796                 case ZPOOL_STATUS_VERSION_NEWER:
1797                         (void) printf(gettext(" action: The pool cannot be "
1798                             "imported.  Access the pool on a system running "
1799                             "newer\n\tsoftware, or recreate the pool from "
1800                             "backup.\n"));
1801                         break;
1802                 case ZPOOL_STATUS_UNSUP_FEAT_READ:
1803                         (void) printf(gettext("action: The pool cannot be "
1804                             "imported. Access the pool on a system that "
1805                             "supports\n\tthe required feature(s), or recreate "
1806                             "the pool from backup.\n"));
1807                         break;
1808                 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1809                         (void) printf(gettext("action: The pool cannot be "
1810                             "imported in read-write mode. Import the pool "
1811                             "with\n"
1812                             "\t\"-o readonly=on\", access the pool on a system "
1813                             "that supports the\n\trequired feature(s), or "
1814                             "recreate the pool from backup.\n"));
1815                         break;
1816                 case ZPOOL_STATUS_MISSING_DEV_R:
1817                 case ZPOOL_STATUS_MISSING_DEV_NR:
1818                 case ZPOOL_STATUS_BAD_GUID_SUM:
1819                         (void) printf(gettext(" action: The pool cannot be "
1820                             "imported. Attach the missing\n\tdevices and try "
1821                             "again.\n"));
1822                         break;
1823                 default:
1824                         (void) printf(gettext(" action: The pool cannot be "
1825                             "imported due to damaged devices or data.\n"));
1826                 }
1827         }
1828
1829         /* Print the comment attached to the pool. */
1830         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1831                 (void) printf(gettext("comment: %s\n"), comment);
1832
1833         /*
1834          * If the state is "closed" or "can't open", and the aux state
1835          * is "corrupt data":
1836          */
1837         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1838             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1839             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1840                 if (pool_state == POOL_STATE_DESTROYED)
1841                         (void) printf(gettext("\tThe pool was destroyed, "
1842                             "but can be imported using the '-Df' flags.\n"));
1843                 else if (pool_state != POOL_STATE_EXPORTED)
1844                         (void) printf(gettext("\tThe pool may be active on "
1845                             "another system, but can be imported using\n\t"
1846                             "the '-f' flag.\n"));
1847         }
1848
1849         if (msgid != NULL)
1850                 (void) printf(gettext("   see: http://zfsonlinux.org/msg/%s\n"),
1851                     msgid);
1852
1853         (void) printf(gettext(" config:\n\n"));
1854
1855         namewidth = max_width(NULL, nvroot, 0, 0);
1856         if (namewidth < 10)
1857                 namewidth = 10;
1858
1859         print_import_config(name, nvroot, namewidth, 0);
1860         if (num_logs(nvroot) > 0)
1861                 print_logs(NULL, nvroot, namewidth, B_FALSE);
1862
1863         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1864                 (void) printf(gettext("\n\tAdditional devices are known to "
1865                     "be part of this pool, though their\n\texact "
1866                     "configuration cannot be determined.\n"));
1867         }
1868 }
1869
1870 /*
1871  * Perform the import for the given configuration.  This passes the heavy
1872  * lifting off to zpool_import_props(), and then mounts the datasets contained
1873  * within the pool.
1874  */
1875 static int
1876 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1877     nvlist_t *props, int flags)
1878 {
1879         zpool_handle_t *zhp;
1880         char *name;
1881         uint64_t state;
1882         uint64_t version;
1883
1884         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1885             &name) == 0);
1886
1887         verify(nvlist_lookup_uint64(config,
1888             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1889         verify(nvlist_lookup_uint64(config,
1890             ZPOOL_CONFIG_VERSION, &version) == 0);
1891         if (!SPA_VERSION_IS_SUPPORTED(version)) {
1892                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1893                     "is formatted using an unsupported ZFS version\n"), name);
1894                 return (1);
1895         } else if (state != POOL_STATE_EXPORTED &&
1896             !(flags & ZFS_IMPORT_ANY_HOST)) {
1897                 uint64_t hostid;
1898
1899                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1900                     &hostid) == 0) {
1901                         unsigned long system_hostid = gethostid() & 0xffffffff;
1902
1903                         if ((unsigned long)hostid != system_hostid) {
1904                                 char *hostname;
1905                                 uint64_t timestamp;
1906                                 time_t t;
1907
1908                                 verify(nvlist_lookup_string(config,
1909                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1910                                 verify(nvlist_lookup_uint64(config,
1911                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1912                                 t = timestamp;
1913                                 (void) fprintf(stderr, gettext("cannot import "
1914                                     "'%s': pool may be in use from other "
1915                                     "system, it was last accessed by %s "
1916                                     "(hostid: 0x%lx) on %s"), name, hostname,
1917                                     (unsigned long)hostid,
1918                                     asctime(localtime(&t)));
1919                                 (void) fprintf(stderr, gettext("use '-f' to "
1920                                     "import anyway\n"));
1921                                 return (1);
1922                         }
1923                 } else {
1924                         (void) fprintf(stderr, gettext("cannot import '%s': "
1925                             "pool may be in use from other system\n"), name);
1926                         (void) fprintf(stderr, gettext("use '-f' to import "
1927                             "anyway\n"));
1928                         return (1);
1929                 }
1930         }
1931
1932         if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
1933                 return (1);
1934
1935         if (newname != NULL)
1936                 name = (char *)newname;
1937
1938         if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1939                 return (1);
1940
1941         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1942             !(flags & ZFS_IMPORT_ONLY) &&
1943             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1944                 zpool_close(zhp);
1945                 return (1);
1946         }
1947
1948         zpool_close(zhp);
1949         return (0);
1950 }
1951
1952 /*
1953  * zpool import [-d dir] [-D]
1954  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1955  *              [-d dir | -c cachefile] [-f] -a
1956  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1957  *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
1958  *
1959  *       -c     Read pool information from a cachefile instead of searching
1960  *              devices.
1961  *
1962  *       -d     Scan in a specific directory, other than /dev/.  More than
1963  *              one directory can be specified using multiple '-d' options.
1964  *
1965  *       -D     Scan for previously destroyed pools or import all or only
1966  *              specified destroyed pools.
1967  *
1968  *       -R     Temporarily import the pool, with all mountpoints relative to
1969  *              the given root.  The pool will remain exported when the machine
1970  *              is rebooted.
1971  *
1972  *       -V     Import even in the presence of faulted vdevs.  This is an
1973  *              intentionally undocumented option for testing purposes, and
1974  *              treats the pool configuration as complete, leaving any bad
1975  *              vdevs in the FAULTED state. In other words, it does verbatim
1976  *              import.
1977  *
1978  *       -f     Force import, even if it appears that the pool is active.
1979  *
1980  *       -F     Attempt rewind if necessary.
1981  *
1982  *       -n     See if rewind would work, but don't actually rewind.
1983  *
1984  *       -N     Import the pool but don't mount datasets.
1985  *
1986  *       -T     Specify a starting txg to use for import. This option is
1987  *              intentionally undocumented option for testing purposes.
1988  *
1989  *       -a     Import all pools found.
1990  *
1991  *       -o     Set property=value and/or temporary mount options (without '=').
1992  *
1993  * The import command scans for pools to import, and import pools based on pool
1994  * name and GUID.  The pool can also be renamed as part of the import process.
1995  */
1996 int
1997 zpool_do_import(int argc, char **argv)
1998 {
1999         char **searchdirs = NULL;
2000         char *env, *envdup = NULL;
2001         int nsearch = 0;
2002         int c;
2003         int err = 0;
2004         nvlist_t *pools = NULL;
2005         boolean_t do_all = B_FALSE;
2006         boolean_t do_destroyed = B_FALSE;
2007         char *mntopts = NULL;
2008         nvpair_t *elem;
2009         nvlist_t *config;
2010         uint64_t searchguid = 0;
2011         char *searchname = NULL;
2012         char *propval;
2013         nvlist_t *found_config;
2014         nvlist_t *policy = NULL;
2015         nvlist_t *props = NULL;
2016         boolean_t first;
2017         int flags = ZFS_IMPORT_NORMAL;
2018         uint32_t rewind_policy = ZPOOL_NO_REWIND;
2019         boolean_t dryrun = B_FALSE;
2020         boolean_t do_rewind = B_FALSE;
2021         boolean_t xtreme_rewind = B_FALSE;
2022         uint64_t pool_state, txg = -1ULL;
2023         char *cachefile = NULL;
2024         importargs_t idata = { 0 };
2025         char *endptr;
2026
2027         /* check options */
2028         while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:tT:VX")) != -1) {
2029                 switch (c) {
2030                 case 'a':
2031                         do_all = B_TRUE;
2032                         break;
2033                 case 'c':
2034                         cachefile = optarg;
2035                         break;
2036                 case 'd':
2037                         if (searchdirs == NULL) {
2038                                 searchdirs = safe_malloc(sizeof (char *));
2039                         } else {
2040                                 char **tmp = safe_malloc((nsearch + 1) *
2041                                     sizeof (char *));
2042                                 bcopy(searchdirs, tmp, nsearch *
2043                                     sizeof (char *));
2044                                 free(searchdirs);
2045                                 searchdirs = tmp;
2046                         }
2047                         searchdirs[nsearch++] = optarg;
2048                         break;
2049                 case 'D':
2050                         do_destroyed = B_TRUE;
2051                         break;
2052                 case 'f':
2053                         flags |= ZFS_IMPORT_ANY_HOST;
2054                         break;
2055                 case 'F':
2056                         do_rewind = B_TRUE;
2057                         break;
2058                 case 'm':
2059                         flags |= ZFS_IMPORT_MISSING_LOG;
2060                         break;
2061                 case 'n':
2062                         dryrun = B_TRUE;
2063                         break;
2064                 case 'N':
2065                         flags |= ZFS_IMPORT_ONLY;
2066                         break;
2067                 case 'o':
2068                         if ((propval = strchr(optarg, '=')) != NULL) {
2069                                 *propval = '\0';
2070                                 propval++;
2071                                 if (add_prop_list(optarg, propval,
2072                                     &props, B_TRUE))
2073                                         goto error;
2074                         } else {
2075                                 mntopts = optarg;
2076                         }
2077                         break;
2078                 case 'R':
2079                         if (add_prop_list(zpool_prop_to_name(
2080                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2081                                 goto error;
2082                         if (add_prop_list_default(zpool_prop_to_name(
2083                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2084                                 goto error;
2085                         break;
2086                 case 't':
2087                         flags |= ZFS_IMPORT_TEMP_NAME;
2088                         if (add_prop_list_default(zpool_prop_to_name(
2089                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2090                                 goto error;
2091                         break;
2092
2093                 case 'T':
2094                         errno = 0;
2095                         txg = strtoull(optarg, &endptr, 0);
2096                         if (errno != 0 || *endptr != '\0') {
2097                                 (void) fprintf(stderr,
2098                                     gettext("invalid txg value\n"));
2099                                 usage(B_FALSE);
2100                         }
2101                         rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2102                         break;
2103                 case 'V':
2104                         flags |= ZFS_IMPORT_VERBATIM;
2105                         break;
2106                 case 'X':
2107                         xtreme_rewind = B_TRUE;
2108                         break;
2109                 case ':':
2110                         (void) fprintf(stderr, gettext("missing argument for "
2111                             "'%c' option\n"), optopt);
2112                         usage(B_FALSE);
2113                         break;
2114                 case '?':
2115                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2116                             optopt);
2117                         usage(B_FALSE);
2118                 }
2119         }
2120
2121         argc -= optind;
2122         argv += optind;
2123
2124         if (cachefile && nsearch != 0) {
2125                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2126                 usage(B_FALSE);
2127         }
2128
2129         if ((dryrun || xtreme_rewind) && !do_rewind) {
2130                 (void) fprintf(stderr,
2131                     gettext("-n or -X only meaningful with -F\n"));
2132                 usage(B_FALSE);
2133         }
2134         if (dryrun)
2135                 rewind_policy = ZPOOL_TRY_REWIND;
2136         else if (do_rewind)
2137                 rewind_policy = ZPOOL_DO_REWIND;
2138         if (xtreme_rewind)
2139                 rewind_policy |= ZPOOL_EXTREME_REWIND;
2140
2141         /* In the future, we can capture further policy and include it here */
2142         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2143             nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
2144             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
2145                 goto error;
2146
2147         /* check argument count */
2148         if (do_all) {
2149                 if (argc != 0) {
2150                         (void) fprintf(stderr, gettext("too many arguments\n"));
2151                         usage(B_FALSE);
2152                 }
2153         } else {
2154                 if (argc > 2) {
2155                         (void) fprintf(stderr, gettext("too many arguments\n"));
2156                         usage(B_FALSE);
2157                 }
2158
2159                 /*
2160                  * Check for the SYS_CONFIG privilege.  We do this explicitly
2161                  * here because otherwise any attempt to discover pools will
2162                  * silently fail.
2163                  */
2164                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
2165                         (void) fprintf(stderr, gettext("cannot "
2166                             "discover pools: permission denied\n"));
2167                         if (searchdirs != NULL)
2168                                 free(searchdirs);
2169
2170                         nvlist_free(policy);
2171                         return (1);
2172                 }
2173         }
2174
2175         /*
2176          * Depending on the arguments given, we do one of the following:
2177          *
2178          *      <none>  Iterate through all pools and display information about
2179          *              each one.
2180          *
2181          *      -a      Iterate through all pools and try to import each one.
2182          *
2183          *      <id>    Find the pool that corresponds to the given GUID/pool
2184          *              name and import that one.
2185          *
2186          *      -D      Above options applies only to destroyed pools.
2187          */
2188         if (argc != 0) {
2189                 char *endptr;
2190
2191                 errno = 0;
2192                 searchguid = strtoull(argv[0], &endptr, 10);
2193                 if (errno != 0 || *endptr != '\0')
2194                         searchname = argv[0];
2195                 found_config = NULL;
2196
2197                 /*
2198                  * User specified a name or guid.  Ensure it's unique.
2199                  */
2200                 idata.unique = B_TRUE;
2201         }
2202
2203         /*
2204          * Check the environment for the preferred search path.
2205          */
2206         if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) {
2207                 char *dir;
2208
2209                 envdup = strdup(env);
2210
2211                 dir = strtok(envdup, ":");
2212                 while (dir != NULL) {
2213                         if (searchdirs == NULL) {
2214                                 searchdirs = safe_malloc(sizeof (char *));
2215                         } else {
2216                                 char **tmp = safe_malloc((nsearch + 1) *
2217                                     sizeof (char *));
2218                                 bcopy(searchdirs, tmp, nsearch *
2219                                     sizeof (char *));
2220                                 free(searchdirs);
2221                                 searchdirs = tmp;
2222                         }
2223                         searchdirs[nsearch++] = dir;
2224                         dir = strtok(NULL, ":");
2225                 }
2226         }
2227
2228         idata.path = searchdirs;
2229         idata.paths = nsearch;
2230         idata.poolname = searchname;
2231         idata.guid = searchguid;
2232         idata.cachefile = cachefile;
2233
2234         pools = zpool_search_import(g_zfs, &idata);
2235
2236         if (pools != NULL && idata.exists &&
2237             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2238                 (void) fprintf(stderr, gettext("cannot import '%s': "
2239                     "a pool with that name already exists\n"),
2240                     argv[0]);
2241                 (void) fprintf(stderr, gettext("use the form '%s "
2242                     "<pool | id> <newpool>' to give it a new name\n"),
2243                     "zpool import");
2244                 err = 1;
2245         } else if (pools == NULL && idata.exists) {
2246                 (void) fprintf(stderr, gettext("cannot import '%s': "
2247                     "a pool with that name is already created/imported,\n"),
2248                     argv[0]);
2249                 (void) fprintf(stderr, gettext("and no additional pools "
2250                     "with that name were found\n"));
2251                 err = 1;
2252         } else if (pools == NULL) {
2253                 if (argc != 0) {
2254                         (void) fprintf(stderr, gettext("cannot import '%s': "
2255                             "no such pool available\n"), argv[0]);
2256                 }
2257                 err = 1;
2258         }
2259
2260         if (err == 1) {
2261                 if (searchdirs != NULL)
2262                         free(searchdirs);
2263                 if (envdup != NULL)
2264                         free(envdup);
2265                 nvlist_free(policy);
2266                 return (1);
2267         }
2268
2269         /*
2270          * At this point we have a list of import candidate configs. Even if
2271          * we were searching by pool name or guid, we still need to
2272          * post-process the list to deal with pool state and possible
2273          * duplicate names.
2274          */
2275         err = 0;
2276         elem = NULL;
2277         first = B_TRUE;
2278         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2279
2280                 verify(nvpair_value_nvlist(elem, &config) == 0);
2281
2282                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2283                     &pool_state) == 0);
2284                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2285                         continue;
2286                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2287                         continue;
2288
2289                 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
2290                     policy) == 0);
2291
2292                 if (argc == 0) {
2293                         if (first)
2294                                 first = B_FALSE;
2295                         else if (!do_all)
2296                                 (void) printf("\n");
2297
2298                         if (do_all) {
2299                                 err |= do_import(config, NULL, mntopts,
2300                                     props, flags);
2301                         } else {
2302                                 show_import(config);
2303                         }
2304                 } else if (searchname != NULL) {
2305                         char *name;
2306
2307                         /*
2308                          * We are searching for a pool based on name.
2309                          */
2310                         verify(nvlist_lookup_string(config,
2311                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2312
2313                         if (strcmp(name, searchname) == 0) {
2314                                 if (found_config != NULL) {
2315                                         (void) fprintf(stderr, gettext(
2316                                             "cannot import '%s': more than "
2317                                             "one matching pool\n"), searchname);
2318                                         (void) fprintf(stderr, gettext(
2319                                             "import by numeric ID instead\n"));
2320                                         err = B_TRUE;
2321                                 }
2322                                 found_config = config;
2323                         }
2324                 } else {
2325                         uint64_t guid;
2326
2327                         /*
2328                          * Search for a pool by guid.
2329                          */
2330                         verify(nvlist_lookup_uint64(config,
2331                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2332
2333                         if (guid == searchguid)
2334                                 found_config = config;
2335                 }
2336         }
2337
2338         /*
2339          * If we were searching for a specific pool, verify that we found a
2340          * pool, and then do the import.
2341          */
2342         if (argc != 0 && err == 0) {
2343                 if (found_config == NULL) {
2344                         (void) fprintf(stderr, gettext("cannot import '%s': "
2345                             "no such pool available\n"), argv[0]);
2346                         err = B_TRUE;
2347                 } else {
2348                         err |= do_import(found_config, argc == 1 ? NULL :
2349                             argv[1], mntopts, props, flags);
2350                 }
2351         }
2352
2353         /*
2354          * If we were just looking for pools, report an error if none were
2355          * found.
2356          */
2357         if (argc == 0 && first)
2358                 (void) fprintf(stderr,
2359                     gettext("no pools available to import\n"));
2360
2361 error:
2362         nvlist_free(props);
2363         nvlist_free(pools);
2364         nvlist_free(policy);
2365         if (searchdirs != NULL)
2366                 free(searchdirs);
2367         if (envdup != NULL)
2368                 free(envdup);
2369
2370         return (err ? 1 : 0);
2371 }
2372
2373 typedef struct iostat_cbdata {
2374         boolean_t cb_verbose;
2375         int cb_namewidth;
2376         int cb_iteration;
2377         zpool_list_t *cb_list;
2378 } iostat_cbdata_t;
2379
2380 static void
2381 print_iostat_separator(iostat_cbdata_t *cb)
2382 {
2383         int i = 0;
2384
2385         for (i = 0; i < cb->cb_namewidth; i++)
2386                 (void) printf("-");
2387         (void) printf("  -----  -----  -----  -----  -----  -----\n");
2388 }
2389
2390 static void
2391 print_iostat_header(iostat_cbdata_t *cb)
2392 {
2393         (void) printf("%*s     capacity     operations    bandwidth\n",
2394             cb->cb_namewidth, "");
2395         (void) printf("%-*s  alloc   free   read  write   read  write\n",
2396             cb->cb_namewidth, "pool");
2397         print_iostat_separator(cb);
2398 }
2399
2400 /*
2401  * Display a single statistic.
2402  */
2403 static void
2404 print_one_stat(uint64_t value)
2405 {
2406         char buf[64];
2407
2408         zfs_nicenum(value, buf, sizeof (buf));
2409         (void) printf("  %5s", buf);
2410 }
2411
2412 /*
2413  * Print out all the statistics for the given vdev.  This can either be the
2414  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
2415  * is a verbose output, and we don't want to display the toplevel pool stats.
2416  */
2417 void
2418 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
2419     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
2420 {
2421         nvlist_t **oldchild, **newchild;
2422         uint_t c, children;
2423         vdev_stat_t *oldvs, *newvs;
2424         vdev_stat_t zerovs = { 0 };
2425         uint64_t tdelta;
2426         double scale;
2427         char *vname;
2428
2429         if (oldnv != NULL) {
2430                 verify(nvlist_lookup_uint64_array(oldnv,
2431                     ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
2432         } else {
2433                 oldvs = &zerovs;
2434         }
2435
2436         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
2437             (uint64_t **)&newvs, &c) == 0);
2438
2439         if (strlen(name) + depth > cb->cb_namewidth)
2440                 (void) printf("%*s%s", depth, "", name);
2441         else
2442                 (void) printf("%*s%s%*s", depth, "", name,
2443                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
2444
2445         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
2446
2447         if (tdelta == 0)
2448                 scale = 1.0;
2449         else
2450                 scale = (double)NANOSEC / tdelta;
2451
2452         /* only toplevel vdevs have capacity stats */
2453         if (newvs->vs_space == 0) {
2454                 (void) printf("      -      -");
2455         } else {
2456                 print_one_stat(newvs->vs_alloc);
2457                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
2458         }
2459
2460         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
2461             oldvs->vs_ops[ZIO_TYPE_READ])));
2462
2463         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
2464             oldvs->vs_ops[ZIO_TYPE_WRITE])));
2465
2466         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
2467             oldvs->vs_bytes[ZIO_TYPE_READ])));
2468
2469         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
2470             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
2471
2472         (void) printf("\n");
2473
2474         if (!cb->cb_verbose)
2475                 return;
2476
2477         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
2478             &newchild, &children) != 0)
2479                 return;
2480
2481         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
2482             &oldchild, &c) != 0)
2483                 return;
2484
2485         for (c = 0; c < children; c++) {
2486                 uint64_t ishole = B_FALSE, islog = B_FALSE;
2487
2488                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
2489                     &ishole);
2490
2491                 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
2492                     &islog);
2493
2494                 if (ishole || islog)
2495                         continue;
2496
2497                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
2498                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2499                     newchild[c], cb, depth + 2);
2500                 free(vname);
2501         }
2502
2503         /*
2504          * Log device section
2505          */
2506
2507         if (num_logs(newnv) > 0) {
2508                 (void) printf("%-*s      -      -      -      -      -      "
2509                     "-\n", cb->cb_namewidth, "logs");
2510
2511                 for (c = 0; c < children; c++) {
2512                         uint64_t islog = B_FALSE;
2513                         (void) nvlist_lookup_uint64(newchild[c],
2514                             ZPOOL_CONFIG_IS_LOG, &islog);
2515
2516                         if (islog) {
2517                                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2518                                     B_FALSE);
2519                                 print_vdev_stats(zhp, vname, oldnv ?
2520                                     oldchild[c] : NULL, newchild[c],
2521                                     cb, depth + 2);
2522                                 free(vname);
2523                         }
2524                 }
2525
2526         }
2527
2528         /*
2529          * Include level 2 ARC devices in iostat output
2530          */
2531         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
2532             &newchild, &children) != 0)
2533                 return;
2534
2535         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
2536             &oldchild, &c) != 0)
2537                 return;
2538
2539         if (children > 0) {
2540                 (void) printf("%-*s      -      -      -      -      -      "
2541                     "-\n", cb->cb_namewidth, "cache");
2542                 for (c = 0; c < children; c++) {
2543                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
2544                             B_FALSE);
2545                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
2546                             newchild[c], cb, depth + 2);
2547                         free(vname);
2548                 }
2549         }
2550 }
2551
2552 static int
2553 refresh_iostat(zpool_handle_t *zhp, void *data)
2554 {
2555         iostat_cbdata_t *cb = data;
2556         boolean_t missing;
2557
2558         /*
2559          * If the pool has disappeared, remove it from the list and continue.
2560          */
2561         if (zpool_refresh_stats(zhp, &missing) != 0)
2562                 return (-1);
2563
2564         if (missing)
2565                 pool_list_remove(cb->cb_list, zhp);
2566
2567         return (0);
2568 }
2569
2570 /*
2571  * Callback to print out the iostats for the given pool.
2572  */
2573 int
2574 print_iostat(zpool_handle_t *zhp, void *data)
2575 {
2576         iostat_cbdata_t *cb = data;
2577         nvlist_t *oldconfig, *newconfig;
2578         nvlist_t *oldnvroot, *newnvroot;
2579
2580         newconfig = zpool_get_config(zhp, &oldconfig);
2581
2582         if (cb->cb_iteration == 1)
2583                 oldconfig = NULL;
2584
2585         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2586             &newnvroot) == 0);
2587
2588         if (oldconfig == NULL)
2589                 oldnvroot = NULL;
2590         else
2591                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2592                     &oldnvroot) == 0);
2593
2594         /*
2595          * Print out the statistics for the pool.
2596          */
2597         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2598
2599         if (cb->cb_verbose)
2600                 print_iostat_separator(cb);
2601
2602         return (0);
2603 }
2604
2605 static int
2606 get_columns(void)
2607 {
2608         struct winsize ws;
2609         int columns = 80;
2610         int error;
2611
2612         if (isatty(STDOUT_FILENO)) {
2613                 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
2614                 if (error == 0)
2615                         columns = ws.ws_col;
2616         } else {
2617                 columns = 999;
2618         }
2619
2620         return (columns);
2621 }
2622
2623 int
2624 get_namewidth(zpool_handle_t *zhp, void *data)
2625 {
2626         iostat_cbdata_t *cb = data;
2627         nvlist_t *config, *nvroot;
2628         int columns;
2629
2630         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2631                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2632                     &nvroot) == 0);
2633                 if (!cb->cb_verbose)
2634                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
2635                 else
2636                         cb->cb_namewidth = max_width(zhp, nvroot, 0,
2637                             cb->cb_namewidth);
2638         }
2639
2640         /*
2641          * The width must be at least 10, but may be as large as the
2642          * column width - 42 so that we can still fit in one line.
2643          */
2644         columns = get_columns();
2645
2646         if (cb->cb_namewidth < 10)
2647                 cb->cb_namewidth = 10;
2648         if (cb->cb_namewidth > columns - 42)
2649                 cb->cb_namewidth = columns - 42;
2650
2651         return (0);
2652 }
2653
2654 /*
2655  * Parse the input string, get the 'interval' and 'count' value if there is one.
2656  */
2657 static void
2658 get_interval_count(int *argcp, char **argv, unsigned long *iv,
2659     unsigned long *cnt)
2660 {
2661         unsigned long interval = 0, count = 0;
2662         int argc = *argcp;
2663
2664         /*
2665          * Determine if the last argument is an integer or a pool name
2666          */
2667         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2668                 char *end;
2669
2670                 errno = 0;
2671                 interval = strtoul(argv[argc - 1], &end, 10);
2672
2673                 if (*end == '\0' && errno == 0) {
2674                         if (interval == 0) {
2675                                 (void) fprintf(stderr, gettext("interval "
2676                                     "cannot be zero\n"));
2677                                 usage(B_FALSE);
2678                         }
2679                         /*
2680                          * Ignore the last parameter
2681                          */
2682                         argc--;
2683                 } else {
2684                         /*
2685                          * If this is not a valid number, just plow on.  The
2686                          * user will get a more informative error message later
2687                          * on.
2688                          */
2689                         interval = 0;
2690                 }
2691         }
2692
2693         /*
2694          * If the last argument is also an integer, then we have both a count
2695          * and an interval.
2696          */
2697         if (argc > 0 && isdigit(argv[argc - 1][0])) {
2698                 char *end;
2699
2700                 errno = 0;
2701                 count = interval;
2702                 interval = strtoul(argv[argc - 1], &end, 10);
2703
2704                 if (*end == '\0' && errno == 0) {
2705                         if (interval == 0) {
2706                                 (void) fprintf(stderr, gettext("interval "
2707                                     "cannot be zero\n"));
2708                                 usage(B_FALSE);
2709                         }
2710
2711                         /*
2712                          * Ignore the last parameter
2713                          */
2714                         argc--;
2715                 } else {
2716                         interval = 0;
2717                 }
2718         }
2719
2720         *iv = interval;
2721         *cnt = count;
2722         *argcp = argc;
2723 }
2724
2725 static void
2726 get_timestamp_arg(char c)
2727 {
2728         if (c == 'u')
2729                 timestamp_fmt = UDATE;
2730         else if (c == 'd')
2731                 timestamp_fmt = DDATE;
2732         else
2733                 usage(B_FALSE);
2734 }
2735
2736 /*
2737  * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
2738  *
2739  *      -v      Display statistics for individual vdevs
2740  *      -T      Display a timestamp in date(1) or Unix format
2741  *
2742  * This command can be tricky because we want to be able to deal with pool
2743  * creation/destruction as well as vdev configuration changes.  The bulk of this
2744  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
2745  * on pool_list_update() to detect the addition of new pools.  Configuration
2746  * changes are all handled within libzfs.
2747  */
2748 int
2749 zpool_do_iostat(int argc, char **argv)
2750 {
2751         int c;
2752         int ret;
2753         int npools;
2754         unsigned long interval = 0, count = 0;
2755         zpool_list_t *list;
2756         boolean_t verbose = B_FALSE;
2757         iostat_cbdata_t cb;
2758
2759         /* check options */
2760         while ((c = getopt(argc, argv, "T:v")) != -1) {
2761                 switch (c) {
2762                 case 'T':
2763                         get_timestamp_arg(*optarg);
2764                         break;
2765                 case 'v':
2766                         verbose = B_TRUE;
2767                         break;
2768                 case '?':
2769                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2770                             optopt);
2771                         usage(B_FALSE);
2772                 }
2773         }
2774
2775         argc -= optind;
2776         argv += optind;
2777
2778         get_interval_count(&argc, argv, &interval, &count);
2779
2780         /*
2781          * Construct the list of all interesting pools.
2782          */
2783         ret = 0;
2784         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2785                 return (1);
2786
2787         if (pool_list_count(list) == 0 && argc != 0) {
2788                 pool_list_free(list);
2789                 return (1);
2790         }
2791
2792         if (pool_list_count(list) == 0 && interval == 0) {
2793                 pool_list_free(list);
2794                 (void) fprintf(stderr, gettext("no pools available\n"));
2795                 return (1);
2796         }
2797
2798         /*
2799          * Enter the main iostat loop.
2800          */
2801         cb.cb_list = list;
2802         cb.cb_verbose = verbose;
2803         cb.cb_iteration = 0;
2804         cb.cb_namewidth = 0;
2805
2806         for (;;) {
2807                 pool_list_update(list);
2808
2809                 if ((npools = pool_list_count(list)) == 0)
2810                         (void) fprintf(stderr, gettext("no pools available\n"));
2811                 else {
2812                         /*
2813                          * Refresh all statistics.  This is done as an
2814                          * explicit step before calculating the maximum name
2815                          * width, so that any * configuration changes are
2816                          * properly accounted for.
2817                          */
2818                         (void) pool_list_iter(list, B_FALSE, refresh_iostat,
2819                                 &cb);
2820
2821                         /*
2822                          * Iterate over all pools to determine the maximum width
2823                          * for the pool / device name column across all pools.
2824                          */
2825                         cb.cb_namewidth = 0;
2826                         (void) pool_list_iter(list, B_FALSE, get_namewidth,
2827                                 &cb);
2828
2829                         if (timestamp_fmt != NODATE)
2830                                 print_timestamp(timestamp_fmt);
2831
2832                         /*
2833                          * If it's the first time, or verbose mode, print the
2834                          * header.
2835                          */
2836                         if (++cb.cb_iteration == 1 || verbose)
2837                                 print_iostat_header(&cb);
2838
2839                         (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2840
2841                         /*
2842                          * If there's more than one pool, and we're not in
2843                          * verbose mode (which prints a separator for us),
2844                          * then print a separator.
2845                          */
2846                         if (npools > 1 && !verbose)
2847                                 print_iostat_separator(&cb);
2848
2849                         if (verbose)
2850                                 (void) printf("\n");
2851                 }
2852
2853                 /*
2854                  * Flush the output so that redirection to a file isn't buffered
2855                  * indefinitely.
2856                  */
2857                 (void) fflush(stdout);
2858
2859                 if (interval == 0)
2860                         break;
2861
2862                 if (count != 0 && --count == 0)
2863                         break;
2864
2865                 (void) sleep(interval);
2866         }
2867
2868         pool_list_free(list);
2869
2870         return (ret);
2871 }
2872
2873 typedef struct list_cbdata {
2874         boolean_t       cb_verbose;
2875         int             cb_namewidth;
2876         boolean_t       cb_scripted;
2877         zprop_list_t    *cb_proplist;
2878 } list_cbdata_t;
2879
2880 /*
2881  * Given a list of columns to display, output appropriate headers for each one.
2882  */
2883 static void
2884 print_header(list_cbdata_t *cb)
2885 {
2886         zprop_list_t *pl = cb->cb_proplist;
2887         char headerbuf[ZPOOL_MAXPROPLEN];
2888         const char *header;
2889         boolean_t first = B_TRUE;
2890         boolean_t right_justify;
2891         size_t width = 0;
2892
2893         for (; pl != NULL; pl = pl->pl_next) {
2894                 width = pl->pl_width;
2895                 if (first && cb->cb_verbose) {
2896                         /*
2897                          * Reset the width to accommodate the verbose listing
2898                          * of devices.
2899                          */
2900                         width = cb->cb_namewidth;
2901                 }
2902
2903                 if (!first)
2904                         (void) printf("  ");
2905                 else
2906                         first = B_FALSE;
2907
2908                 right_justify = B_FALSE;
2909                 if (pl->pl_prop != ZPROP_INVAL) {
2910                         header = zpool_prop_column_name(pl->pl_prop);
2911                         right_justify = zpool_prop_align_right(pl->pl_prop);
2912                 } else {
2913                         int i;
2914
2915                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
2916                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
2917                         headerbuf[i] = '\0';
2918                         header = headerbuf;
2919                 }
2920
2921                 if (pl->pl_next == NULL && !right_justify)
2922                         (void) printf("%s", header);
2923                 else if (right_justify)
2924                         (void) printf("%*s", (int)width, header);
2925                 else
2926                         (void) printf("%-*s", (int)width, header);
2927         }
2928
2929         (void) printf("\n");
2930 }
2931
2932 /*
2933  * Given a pool and a list of properties, print out all the properties according
2934  * to the described layout.
2935  */
2936 static void
2937 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2938 {
2939         zprop_list_t *pl = cb->cb_proplist;
2940         boolean_t first = B_TRUE;
2941         char property[ZPOOL_MAXPROPLEN];
2942         char *propstr;
2943         boolean_t right_justify;
2944         size_t width;
2945
2946         for (; pl != NULL; pl = pl->pl_next) {
2947
2948                 width = pl->pl_width;
2949                 if (first && cb->cb_verbose) {
2950                         /*
2951                          * Reset the width to accommodate the verbose listing
2952                          * of devices.
2953                          */
2954                         width = cb->cb_namewidth;
2955                 }
2956
2957                 if (!first) {
2958                         if (cb->cb_scripted)
2959                                 (void) printf("\t");
2960                         else
2961                                 (void) printf("  ");
2962                 } else {
2963                         first = B_FALSE;
2964                 }
2965
2966                 right_justify = B_FALSE;
2967                 if (pl->pl_prop != ZPROP_INVAL) {
2968                         if (zpool_get_prop(zhp, pl->pl_prop, property,
2969                             sizeof (property), NULL) != 0)
2970                                 propstr = "-";
2971                         else
2972                                 propstr = property;
2973
2974                         right_justify = zpool_prop_align_right(pl->pl_prop);
2975                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
2976                     zpool_prop_unsupported(pl->pl_user_prop)) &&
2977                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
2978                     sizeof (property)) == 0) {
2979                         propstr = property;
2980                 } else {
2981                         propstr = "-";
2982                 }
2983
2984
2985                 /*
2986                  * If this is being called in scripted mode, or if this is the
2987                  * last column and it is left-justified, don't include a width
2988                  * format specifier.
2989                  */
2990                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
2991                         (void) printf("%s", propstr);
2992                 else if (right_justify)
2993                         (void) printf("%*s", (int)width, propstr);
2994                 else
2995                         (void) printf("%-*s", (int)width, propstr);
2996         }
2997
2998         (void) printf("\n");
2999 }
3000
3001 static void
3002 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
3003     boolean_t valid)
3004 {
3005         char propval[64];
3006         boolean_t fixed;
3007         size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
3008
3009         switch (prop) {
3010         case ZPOOL_PROP_EXPANDSZ:
3011                 if (value == 0)
3012                         (void) strlcpy(propval, "-", sizeof (propval));
3013                 else
3014                         zfs_nicenum(value, propval, sizeof (propval));
3015                 break;
3016         case ZPOOL_PROP_FRAGMENTATION:
3017                 if (value == ZFS_FRAG_INVALID) {
3018                         (void) strlcpy(propval, "-", sizeof (propval));
3019                 } else {
3020                         (void) snprintf(propval, sizeof (propval), "%llu%%",
3021                             (unsigned long long)value);
3022                 }
3023                 break;
3024         case ZPOOL_PROP_CAPACITY:
3025                 (void) snprintf(propval, sizeof (propval), "%llu%%",
3026                     (unsigned long long)value);
3027                 break;
3028         default:
3029                 zfs_nicenum(value, propval, sizeof (propval));
3030         }
3031
3032         if (!valid)
3033                 (void) strlcpy(propval, "-", sizeof (propval));
3034
3035         if (scripted)
3036                 (void) printf("\t%s", propval);
3037         else
3038                 (void) printf("  %*s", (int)width, propval);
3039 }
3040
3041 void
3042 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
3043     list_cbdata_t *cb, int depth)
3044 {
3045         nvlist_t **child;
3046         vdev_stat_t *vs;
3047         uint_t c, children;
3048         char *vname;
3049         boolean_t scripted = cb->cb_scripted;
3050
3051         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3052             (uint64_t **)&vs, &c) == 0);
3053
3054         if (name != NULL) {
3055                 boolean_t toplevel = (vs->vs_space != 0);
3056                 uint64_t cap;
3057
3058                 if (scripted)
3059                         (void) printf("\t%s", name);
3060                 else if (strlen(name) + depth > cb->cb_namewidth)
3061                         (void) printf("%*s%s", depth, "", name);
3062                 else
3063                         (void) printf("%*s%s%*s", depth, "", name,
3064                             (int)(cb->cb_namewidth - strlen(name) - depth), "");
3065
3066                 /*
3067                  * Print the properties for the individual vdevs. Some
3068                  * properties are only applicable to toplevel vdevs. The
3069                  * 'toplevel' boolean value is passed to the print_one_column()
3070                  * to indicate that the value is valid.
3071                  */
3072                 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
3073                     toplevel);
3074                 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
3075                     toplevel);
3076                 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
3077                     scripted, toplevel);
3078                 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
3079                     B_TRUE);
3080                 print_one_column(ZPOOL_PROP_FRAGMENTATION,
3081                     vs->vs_fragmentation, scripted,
3082                     (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel));
3083                 cap = (vs->vs_space == 0) ? 0 :
3084                     (vs->vs_alloc * 100 / vs->vs_space);
3085                 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel);
3086                 (void) printf("\n");
3087         }
3088
3089         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
3090             &child, &children) != 0)
3091                 return;
3092
3093         for (c = 0; c < children; c++) {
3094                 uint64_t ishole = B_FALSE;
3095
3096                 if (nvlist_lookup_uint64(child[c],
3097                     ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
3098                         continue;
3099
3100                 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
3101                 print_list_stats(zhp, vname, child[c], cb, depth + 2);
3102                 free(vname);
3103         }
3104
3105         /*
3106          * Include level 2 ARC devices in iostat output
3107          */
3108         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
3109             &child, &children) != 0)
3110                 return;
3111
3112         if (children > 0) {
3113                 (void) printf("%-*s      -      -      -      -      -      "
3114                     "-\n", cb->cb_namewidth, "cache");
3115                 for (c = 0; c < children; c++) {
3116                         vname = zpool_vdev_name(g_zfs, zhp, child[c],
3117                             B_FALSE);
3118                         print_list_stats(zhp, vname, child[c], cb, depth + 2);
3119                         free(vname);
3120                 }
3121         }
3122 }
3123
3124
3125 /*
3126  * Generic callback function to list a pool.
3127  */
3128 int
3129 list_callback(zpool_handle_t *zhp, void *data)
3130 {
3131         list_cbdata_t *cbp = data;
3132         nvlist_t *config;
3133         nvlist_t *nvroot;
3134
3135         config = zpool_get_config(zhp, NULL);
3136
3137         print_pool(zhp, cbp);
3138         if (!cbp->cb_verbose)
3139                 return (0);
3140
3141         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3142             &nvroot) == 0);
3143         print_list_stats(zhp, NULL, nvroot, cbp, 0);
3144
3145         return (0);
3146 }
3147
3148 /*
3149  * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
3150  *
3151  *      -H      Scripted mode.  Don't display headers, and separate properties
3152  *              by a single tab.
3153  *      -o      List of properties to display.  Defaults to
3154  *              "name,size,allocated,free,expandsize,fragmentation,capacity,"
3155  *              "dedupratio,health,altroot"
3156  *      -T      Display a timestamp in date(1) or Unix format
3157  *
3158  * List all pools in the system, whether or not they're healthy.  Output space
3159  * statistics for each one, as well as health status summary.
3160  */
3161 int
3162 zpool_do_list(int argc, char **argv)
3163 {
3164         int c;
3165         int ret = 0;
3166         list_cbdata_t cb = { 0 };
3167         static char default_props[] =
3168             "name,size,allocated,free,expandsize,fragmentation,capacity,"
3169             "dedupratio,health,altroot";
3170         char *props = default_props;
3171         unsigned long interval = 0, count = 0;
3172         zpool_list_t *list;
3173         boolean_t first = B_TRUE;
3174
3175         /* check options */
3176         while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
3177                 switch (c) {
3178                 case 'H':
3179                         cb.cb_scripted = B_TRUE;
3180                         break;
3181                 case 'o':
3182                         props = optarg;
3183                         break;
3184                 case 'T':
3185                         get_timestamp_arg(*optarg);
3186                         break;
3187                 case 'v':
3188                         cb.cb_verbose = B_TRUE;
3189                         break;
3190                 case ':':
3191                         (void) fprintf(stderr, gettext("missing argument for "
3192                             "'%c' option\n"), optopt);
3193                         usage(B_FALSE);
3194                         break;
3195                 case '?':
3196                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3197                             optopt);
3198                         usage(B_FALSE);
3199                 }
3200         }
3201
3202         argc -= optind;
3203         argv += optind;
3204
3205         get_interval_count(&argc, argv, &interval, &count);
3206
3207         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
3208                 usage(B_FALSE);
3209
3210         if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL)
3211                 return (1);
3212
3213         if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
3214                 (void) printf(gettext("no pools available\n"));
3215                 zprop_free_list(cb.cb_proplist);
3216                 return (0);
3217         }
3218
3219         for (;;) {
3220                 pool_list_update(list);
3221
3222                 if (pool_list_count(list) == 0)
3223                         break;
3224
3225                 if (timestamp_fmt != NODATE)
3226                         print_timestamp(timestamp_fmt);
3227
3228                 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
3229                         print_header(&cb);
3230                         first = B_FALSE;
3231                 }
3232                 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
3233
3234                 if (interval == 0)
3235                         break;
3236
3237                 if (count != 0 && --count == 0)
3238                         break;
3239
3240                 (void) sleep(interval);
3241         }
3242
3243         zprop_free_list(cb.cb_proplist);
3244         return (ret);
3245 }
3246
3247 static int
3248 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
3249 {
3250         boolean_t force = B_FALSE;
3251         int c;
3252         nvlist_t *nvroot;
3253         char *poolname, *old_disk, *new_disk;
3254         zpool_handle_t *zhp;
3255         nvlist_t *props = NULL;
3256         char *propval;
3257         int ret;
3258
3259         /* check options */
3260         while ((c = getopt(argc, argv, "fo:")) != -1) {
3261                 switch (c) {
3262                 case 'f':
3263                         force = B_TRUE;
3264                         break;
3265                 case 'o':
3266                         if ((propval = strchr(optarg, '=')) == NULL) {
3267                                 (void) fprintf(stderr, gettext("missing "
3268                                     "'=' for -o option\n"));
3269                                 usage(B_FALSE);
3270                         }
3271                         *propval = '\0';
3272                         propval++;
3273
3274                         if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
3275                             (add_prop_list(optarg, propval, &props, B_TRUE)))
3276                                 usage(B_FALSE);
3277                         break;
3278                 case '?':
3279                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3280                             optopt);
3281                         usage(B_FALSE);
3282                 }
3283         }
3284
3285         argc -= optind;
3286         argv += optind;
3287
3288         /* get pool name and check number of arguments */
3289         if (argc < 1) {
3290                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3291                 usage(B_FALSE);
3292         }
3293
3294         poolname = argv[0];
3295
3296         if (argc < 2) {
3297                 (void) fprintf(stderr,
3298                     gettext("missing <device> specification\n"));
3299                 usage(B_FALSE);
3300         }
3301
3302         old_disk = argv[1];
3303
3304         if (argc < 3) {
3305                 if (!replacing) {
3306                         (void) fprintf(stderr,
3307                             gettext("missing <new_device> specification\n"));
3308                         usage(B_FALSE);
3309                 }
3310                 new_disk = old_disk;
3311                 argc -= 1;
3312                 argv += 1;
3313         } else {
3314                 new_disk = argv[2];
3315                 argc -= 2;
3316                 argv += 2;
3317         }
3318
3319         if (argc > 1) {
3320                 (void) fprintf(stderr, gettext("too many arguments\n"));
3321                 usage(B_FALSE);
3322         }
3323
3324         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3325                 return (1);
3326
3327         if (zpool_get_config(zhp, NULL) == NULL) {
3328                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
3329                     poolname);
3330                 zpool_close(zhp);
3331                 return (1);
3332         }
3333
3334         nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE,
3335             argc, argv);
3336         if (nvroot == NULL) {
3337                 zpool_close(zhp);
3338                 return (1);
3339         }
3340
3341         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
3342
3343         nvlist_free(nvroot);
3344         zpool_close(zhp);
3345
3346         return (ret);
3347 }
3348
3349 /*
3350  * zpool replace [-f] <pool> <device> <new_device>
3351  *
3352  *      -f      Force attach, even if <new_device> appears to be in use.
3353  *
3354  * Replace <device> with <new_device>.
3355  */
3356 /* ARGSUSED */
3357 int
3358 zpool_do_replace(int argc, char **argv)
3359 {
3360         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
3361 }
3362
3363 /*
3364  * zpool attach [-f] [-o property=value] <pool> <device> <new_device>
3365  *
3366  *      -f      Force attach, even if <new_device> appears to be in use.
3367  *      -o      Set property=value.
3368  *
3369  * Attach <new_device> to the mirror containing <device>.  If <device> is not
3370  * part of a mirror, then <device> will be transformed into a mirror of
3371  * <device> and <new_device>.  In either case, <new_device> will begin life
3372  * with a DTL of [0, now], and will immediately begin to resilver itself.
3373  */
3374 int
3375 zpool_do_attach(int argc, char **argv)
3376 {
3377         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
3378 }
3379
3380 /*
3381  * zpool detach [-f] <pool> <device>
3382  *
3383  *      -f      Force detach of <device>, even if DTLs argue against it
3384  *              (not supported yet)
3385  *
3386  * Detach a device from a mirror.  The operation will be refused if <device>
3387  * is the last device in the mirror, or if the DTLs indicate that this device
3388  * has the only valid copy of some data.
3389  */
3390 /* ARGSUSED */
3391 int
3392 zpool_do_detach(int argc, char **argv)
3393 {
3394         int c;
3395         char *poolname, *path;
3396         zpool_handle_t *zhp;
3397         int ret;
3398
3399         /* check options */
3400         while ((c = getopt(argc, argv, "f")) != -1) {
3401                 switch (c) {
3402                 case 'f':
3403                 case '?':
3404                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3405                             optopt);
3406                         usage(B_FALSE);
3407                 }
3408         }
3409
3410         argc -= optind;
3411         argv += optind;
3412
3413         /* get pool name and check number of arguments */
3414         if (argc < 1) {
3415                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3416                 usage(B_FALSE);
3417         }
3418
3419         if (argc < 2) {
3420                 (void) fprintf(stderr,
3421                     gettext("missing <device> specification\n"));
3422                 usage(B_FALSE);
3423         }
3424
3425         poolname = argv[0];
3426         path = argv[1];
3427
3428         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3429                 return (1);
3430
3431         ret = zpool_vdev_detach(zhp, path);
3432
3433         zpool_close(zhp);
3434
3435         return (ret);
3436 }
3437
3438 /*
3439  * zpool split [-n] [-o prop=val] ...
3440  *              [-o mntopt] ...
3441  *              [-R altroot] <pool> <newpool> [<device> ...]
3442  *
3443  *      -n      Do not split the pool, but display the resulting layout if
3444  *              it were to be split.
3445  *      -o      Set property=value, or set mount options.
3446  *      -R      Mount the split-off pool under an alternate root.
3447  *
3448  * Splits the named pool and gives it the new pool name.  Devices to be split
3449  * off may be listed, provided that no more than one device is specified
3450  * per top-level vdev mirror.  The newly split pool is left in an exported
3451  * state unless -R is specified.
3452  *
3453  * Restrictions: the top-level of the pool pool must only be made up of
3454  * mirrors; all devices in the pool must be healthy; no device may be
3455  * undergoing a resilvering operation.
3456  */
3457 int
3458 zpool_do_split(int argc, char **argv)
3459 {
3460         char *srcpool, *newpool, *propval;
3461         char *mntopts = NULL;
3462         splitflags_t flags;
3463         int c, ret = 0;
3464         zpool_handle_t *zhp;
3465         nvlist_t *config, *props = NULL;
3466
3467         flags.dryrun = B_FALSE;
3468         flags.import = B_FALSE;
3469
3470         /* check options */
3471         while ((c = getopt(argc, argv, ":R:no:")) != -1) {
3472                 switch (c) {
3473                 case 'R':
3474                         flags.import = B_TRUE;
3475                         if (add_prop_list(
3476                             zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
3477                             &props, B_TRUE) != 0) {
3478                                 if (props)
3479                                         nvlist_free(props);
3480                                 usage(B_FALSE);
3481                         }
3482                         break;
3483                 case 'n':
3484                         flags.dryrun = B_TRUE;
3485                         break;
3486                 case 'o':
3487                         if ((propval = strchr(optarg, '=')) != NULL) {
3488                                 *propval = '\0';
3489                                 propval++;
3490                                 if (add_prop_list(optarg, propval,
3491                                     &props, B_TRUE) != 0) {
3492                                         if (props)
3493                                                 nvlist_free(props);
3494                                         usage(B_FALSE);
3495                                 }
3496                         } else {
3497                                 mntopts = optarg;
3498                         }
3499                         break;
3500                 case ':':
3501                         (void) fprintf(stderr, gettext("missing argument for "
3502                             "'%c' option\n"), optopt);
3503                         usage(B_FALSE);
3504                         break;
3505                 case '?':
3506                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3507                             optopt);
3508                         usage(B_FALSE);
3509                         break;
3510                 }
3511         }
3512
3513         if (!flags.import && mntopts != NULL) {
3514                 (void) fprintf(stderr, gettext("setting mntopts is only "
3515                     "valid when importing the pool\n"));
3516                 usage(B_FALSE);
3517         }
3518
3519         argc -= optind;
3520         argv += optind;
3521
3522         if (argc < 1) {
3523                 (void) fprintf(stderr, gettext("Missing pool name\n"));
3524                 usage(B_FALSE);
3525         }
3526         if (argc < 2) {
3527                 (void) fprintf(stderr, gettext("Missing new pool name\n"));
3528                 usage(B_FALSE);
3529         }
3530
3531         srcpool = argv[0];
3532         newpool = argv[1];
3533
3534         argc -= 2;
3535         argv += 2;
3536
3537         if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
3538                 return (1);
3539
3540         config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
3541         if (config == NULL) {
3542                 ret = 1;
3543         } else {
3544                 if (flags.dryrun) {
3545                         (void) printf(gettext("would create '%s' with the "
3546                             "following layout:\n\n"), newpool);
3547                         print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
3548                 }
3549                 nvlist_free(config);
3550         }
3551
3552         zpool_close(zhp);
3553
3554         if (ret != 0 || flags.dryrun || !flags.import)
3555                 return (ret);
3556
3557         /*
3558          * The split was successful. Now we need to open the new
3559          * pool and import it.
3560          */
3561         if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
3562                 return (1);
3563         if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
3564             zpool_enable_datasets(zhp, mntopts, 0) != 0) {
3565                 ret = 1;
3566                 (void) fprintf(stderr, gettext("Split was successful, but "
3567                     "the datasets could not all be mounted\n"));
3568                 (void) fprintf(stderr, gettext("Try doing '%s' with a "
3569                     "different altroot\n"), "zpool import");
3570         }
3571         zpool_close(zhp);
3572
3573         return (ret);
3574 }
3575
3576
3577
3578 /*
3579  * zpool online <pool> <device> ...
3580  */
3581 int
3582 zpool_do_online(int argc, char **argv)
3583 {
3584         int c, i;
3585         char *poolname;
3586         zpool_handle_t *zhp;
3587         int ret = 0;
3588         vdev_state_t newstate;
3589         int flags = 0;
3590
3591         /* check options */
3592         while ((c = getopt(argc, argv, "et")) != -1) {
3593                 switch (c) {
3594                 case 'e':
3595                         flags |= ZFS_ONLINE_EXPAND;
3596                         break;
3597                 case 't':
3598                 case '?':
3599                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3600                             optopt);
3601                         usage(B_FALSE);
3602                 }
3603         }
3604
3605         argc -= optind;
3606         argv += optind;
3607
3608         /* get pool name and check number of arguments */
3609         if (argc < 1) {
3610                 (void) fprintf(stderr, gettext("missing pool name\n"));
3611                 usage(B_FALSE);
3612         }
3613         if (argc < 2) {
3614                 (void) fprintf(stderr, gettext("missing device name\n"));
3615                 usage(B_FALSE);
3616         }
3617
3618         poolname = argv[0];
3619
3620         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3621                 return (1);
3622
3623         for (i = 1; i < argc; i++) {
3624                 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
3625                         if (newstate != VDEV_STATE_HEALTHY) {
3626                                 (void) printf(gettext("warning: device '%s' "
3627                                     "onlined, but remains in faulted state\n"),
3628                                     argv[i]);
3629                                 if (newstate == VDEV_STATE_FAULTED)
3630                                         (void) printf(gettext("use 'zpool "
3631                                             "clear' to restore a faulted "
3632                                             "device\n"));
3633                                 else
3634                                         (void) printf(gettext("use 'zpool "
3635                                             "replace' to replace devices "
3636                                             "that are no longer present\n"));
3637                         }
3638                 } else {
3639                         ret = 1;
3640                 }
3641         }
3642
3643         zpool_close(zhp);
3644
3645         return (ret);
3646 }
3647
3648 /*
3649  * zpool offline [-ft] <pool> <device> ...
3650  *
3651  *      -f      Force the device into the offline state, even if doing
3652  *              so would appear to compromise pool availability.
3653  *              (not supported yet)
3654  *
3655  *      -t      Only take the device off-line temporarily.  The offline
3656  *              state will not be persistent across reboots.
3657  */
3658 /* ARGSUSED */
3659 int
3660 zpool_do_offline(int argc, char **argv)
3661 {
3662         int c, i;
3663         char *poolname;
3664         zpool_handle_t *zhp;
3665         int ret = 0;
3666         boolean_t istmp = B_FALSE;
3667
3668         /* check options */
3669         while ((c = getopt(argc, argv, "ft")) != -1) {
3670                 switch (c) {
3671                 case 't':
3672                         istmp = B_TRUE;
3673                         break;
3674                 case 'f':
3675                 case '?':
3676                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3677                             optopt);
3678                         usage(B_FALSE);
3679                 }
3680         }
3681
3682         argc -= optind;
3683         argv += optind;
3684
3685         /* get pool name and check number of arguments */
3686         if (argc < 1) {
3687                 (void) fprintf(stderr, gettext("missing pool name\n"));
3688                 usage(B_FALSE);
3689         }
3690         if (argc < 2) {
3691                 (void) fprintf(stderr, gettext("missing device name\n"));
3692                 usage(B_FALSE);
3693         }
3694
3695         poolname = argv[0];
3696
3697         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3698                 return (1);
3699
3700         for (i = 1; i < argc; i++) {
3701                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
3702                         ret = 1;
3703         }
3704
3705         zpool_close(zhp);
3706
3707         return (ret);
3708 }
3709
3710 /*
3711  * zpool clear <pool> [device]
3712  *
3713  * Clear all errors associated with a pool or a particular device.
3714  */
3715 int
3716 zpool_do_clear(int argc, char **argv)
3717 {
3718         int c;
3719         int ret = 0;
3720         boolean_t dryrun = B_FALSE;
3721         boolean_t do_rewind = B_FALSE;
3722         boolean_t xtreme_rewind = B_FALSE;
3723         uint32_t rewind_policy = ZPOOL_NO_REWIND;
3724         nvlist_t *policy = NULL;
3725         zpool_handle_t *zhp;
3726         char *pool, *device;
3727
3728         /* check options */
3729         while ((c = getopt(argc, argv, "FnX")) != -1) {
3730                 switch (c) {
3731                 case 'F':
3732                         do_rewind = B_TRUE;
3733                         break;
3734                 case 'n':
3735                         dryrun = B_TRUE;
3736                         break;
3737                 case 'X':
3738                         xtreme_rewind = B_TRUE;
3739                         break;
3740                 case '?':
3741                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3742                             optopt);
3743                         usage(B_FALSE);
3744                 }
3745         }
3746
3747         argc -= optind;
3748         argv += optind;
3749
3750         if (argc < 1) {
3751                 (void) fprintf(stderr, gettext("missing pool name\n"));
3752                 usage(B_FALSE);
3753         }
3754
3755         if (argc > 2) {
3756                 (void) fprintf(stderr, gettext("too many arguments\n"));
3757                 usage(B_FALSE);
3758         }
3759
3760         if ((dryrun || xtreme_rewind) && !do_rewind) {
3761                 (void) fprintf(stderr,
3762                     gettext("-n or -X only meaningful with -F\n"));
3763                 usage(B_FALSE);
3764         }
3765         if (dryrun)
3766                 rewind_policy = ZPOOL_TRY_REWIND;
3767         else if (do_rewind)
3768                 rewind_policy = ZPOOL_DO_REWIND;
3769         if (xtreme_rewind)
3770                 rewind_policy |= ZPOOL_EXTREME_REWIND;
3771
3772         /* In future, further rewind policy choices can be passed along here */
3773         if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
3774             nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
3775                 return (1);
3776
3777         pool = argv[0];
3778         device = argc == 2 ? argv[1] : NULL;
3779
3780         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
3781                 nvlist_free(policy);
3782                 return (1);
3783         }
3784
3785         if (zpool_clear(zhp, device, policy) != 0)
3786                 ret = 1;
3787
3788         zpool_close(zhp);
3789
3790         nvlist_free(policy);
3791
3792         return (ret);
3793 }
3794
3795 /*
3796  * zpool reguid <pool>
3797  */
3798 int
3799 zpool_do_reguid(int argc, char **argv)
3800 {
3801         int c;
3802         char *poolname;
3803         zpool_handle_t *zhp;
3804         int ret = 0;
3805
3806         /* check options */
3807         while ((c = getopt(argc, argv, "")) != -1) {
3808                 switch (c) {
3809                 case '?':
3810                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3811                             optopt);
3812                         usage(B_FALSE);
3813                 }
3814         }
3815
3816         argc -= optind;
3817         argv += optind;
3818
3819         /* get pool name and check number of arguments */
3820         if (argc < 1) {
3821                 (void) fprintf(stderr, gettext("missing pool name\n"));
3822                 usage(B_FALSE);
3823         }
3824
3825         if (argc > 1) {
3826                 (void) fprintf(stderr, gettext("too many arguments\n"));
3827                 usage(B_FALSE);
3828         }
3829
3830         poolname = argv[0];
3831         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
3832                 return (1);
3833
3834         ret = zpool_reguid(zhp);
3835
3836         zpool_close(zhp);
3837         return (ret);
3838 }
3839
3840
3841 /*
3842  * zpool reopen <pool>
3843  *
3844  * Reopen the pool so that the kernel can update the sizes of all vdevs.
3845  */
3846 int
3847 zpool_do_reopen(int argc, char **argv)
3848 {
3849         int c;
3850         int ret = 0;
3851         zpool_handle_t *zhp;
3852         char *pool;
3853
3854         /* check options */
3855         while ((c = getopt(argc, argv, "")) != -1) {
3856                 switch (c) {
3857                 case '?':
3858                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3859                             optopt);
3860                         usage(B_FALSE);
3861                 }
3862         }
3863
3864         argc--;
3865         argv++;
3866
3867         if (argc < 1) {
3868                 (void) fprintf(stderr, gettext("missing pool name\n"));
3869                 usage(B_FALSE);
3870         }
3871
3872         if (argc > 1) {
3873                 (void) fprintf(stderr, gettext("too many arguments\n"));
3874                 usage(B_FALSE);
3875         }
3876
3877         pool = argv[0];
3878         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
3879                 return (1);
3880
3881         ret = zpool_reopen(zhp);
3882         zpool_close(zhp);
3883         return (ret);
3884 }
3885
3886 typedef struct scrub_cbdata {
3887         int     cb_type;
3888         int     cb_argc;
3889         char    **cb_argv;
3890 } scrub_cbdata_t;
3891
3892 int
3893 scrub_callback(zpool_handle_t *zhp, void *data)
3894 {
3895         scrub_cbdata_t *cb = data;
3896         int err;
3897
3898         /*
3899          * Ignore faulted pools.
3900          */
3901         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
3902                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
3903                     "currently unavailable\n"), zpool_get_name(zhp));
3904                 return (1);
3905         }
3906
3907         err = zpool_scan(zhp, cb->cb_type);
3908
3909         return (err != 0);
3910 }
3911
3912 /*
3913  * zpool scrub [-s] <pool> ...
3914  *
3915  *      -s      Stop.  Stops any in-progress scrub.
3916  */
3917 int
3918 zpool_do_scrub(int argc, char **argv)
3919 {
3920         int c;
3921         scrub_cbdata_t cb;
3922
3923         cb.cb_type = POOL_SCAN_SCRUB;
3924
3925         /* check options */
3926         while ((c = getopt(argc, argv, "s")) != -1) {
3927                 switch (c) {
3928                 case 's':
3929                         cb.cb_type = POOL_SCAN_NONE;
3930                         break;
3931                 case '?':
3932                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3933                             optopt);
3934                         usage(B_FALSE);
3935                 }
3936         }
3937
3938         cb.cb_argc = argc;
3939         cb.cb_argv = argv;
3940         argc -= optind;
3941         argv += optind;
3942
3943         if (argc < 1) {
3944                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
3945                 usage(B_FALSE);
3946         }
3947
3948         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
3949 }
3950
3951 typedef struct status_cbdata {
3952         int             cb_count;
3953         boolean_t       cb_allpools;
3954         boolean_t       cb_verbose;
3955         boolean_t       cb_explain;
3956         boolean_t       cb_first;
3957         boolean_t       cb_dedup_stats;
3958 } status_cbdata_t;
3959
3960 /*
3961  * Print out detailed scrub status.
3962  */
3963 void
3964 print_scan_status(pool_scan_stat_t *ps)
3965 {
3966         time_t start, end;
3967         uint64_t elapsed, mins_left, hours_left;
3968         uint64_t pass_exam, examined, total;
3969         uint_t rate;
3970         double fraction_done;
3971         char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
3972
3973         (void) printf(gettext("  scan: "));
3974
3975         /* If there's never been a scan, there's not much to say. */
3976         if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
3977             ps->pss_func >= POOL_SCAN_FUNCS) {
3978                 (void) printf(gettext("none requested\n"));
3979                 return;
3980         }
3981
3982         start = ps->pss_start_time;
3983         end = ps->pss_end_time;
3984         zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
3985
3986         assert(ps->pss_func == POOL_SCAN_SCRUB ||
3987             ps->pss_func == POOL_SCAN_RESILVER);
3988         /*
3989          * Scan is finished or canceled.
3990          */
3991         if (ps->pss_state == DSS_FINISHED) {
3992                 uint64_t minutes_taken = (end - start) / 60;
3993                 char *fmt = NULL;
3994
3995                 if (ps->pss_func == POOL_SCAN_SCRUB) {
3996                         fmt = gettext("scrub repaired %s in %lluh%um with "
3997                             "%llu errors on %s");
3998                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
3999                         fmt = gettext("resilvered %s in %lluh%um with "
4000                             "%llu errors on %s");
4001                 }
4002                 /* LINTED */
4003                 (void) printf(fmt, processed_buf,
4004                     (u_longlong_t)(minutes_taken / 60),
4005                     (uint_t)(minutes_taken % 60),
4006                     (u_longlong_t)ps->pss_errors,
4007                     ctime((time_t *)&end));
4008                 return;
4009         } else if (ps->pss_state == DSS_CANCELED) {
4010                 if (ps->pss_func == POOL_SCAN_SCRUB) {
4011                         (void) printf(gettext("scrub canceled on %s"),
4012                             ctime(&end));
4013                 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
4014                         (void) printf(gettext("resilver canceled on %s"),
4015                             ctime(&end));
4016                 }
4017                 return;
4018         }
4019
4020         assert(ps->pss_state == DSS_SCANNING);
4021
4022         /*
4023          * Scan is in progress.
4024          */
4025         if (ps->pss_func == POOL_SCAN_SCRUB) {
4026                 (void) printf(gettext("scrub in progress since %s"),
4027                     ctime(&start));
4028         } else if (ps->pss_func == POOL_SCAN_RESILVER) {
4029                 (void) printf(gettext("resilver in progress since %s"),
4030                     ctime(&start));
4031         }
4032
4033         examined = ps->pss_examined ? ps->pss_examined : 1;
4034         total = ps->pss_to_examine;
4035         fraction_done = (double)examined / total;
4036
4037         /* elapsed time for this pass */
4038         elapsed = time(NULL) - ps->pss_pass_start;
4039         elapsed = elapsed ? elapsed : 1;
4040         pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
4041         rate = pass_exam / elapsed;
4042         rate = rate ? rate : 1;
4043         mins_left = ((total - examined) / rate) / 60;
4044         hours_left = mins_left / 60;
4045
4046         zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
4047         zfs_nicenum(total, total_buf, sizeof (total_buf));
4048         zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
4049
4050         /*
4051          * do not print estimated time if hours_left is more than 30 days
4052          */
4053         (void) printf(gettext("    %s scanned out of %s at %s/s"),
4054             examined_buf, total_buf, rate_buf);
4055         if (hours_left < (30 * 24)) {
4056                 (void) printf(gettext(", %lluh%um to go\n"),
4057                     (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
4058         } else {
4059                 (void) printf(gettext(
4060                     ", (scan is slow, no estimated time)\n"));
4061         }
4062
4063         if (ps->pss_func == POOL_SCAN_RESILVER) {
4064                 (void) printf(gettext("    %s resilvered, %.2f%% done\n"),
4065                     processed_buf, 100 * fraction_done);
4066         } else if (ps->pss_func == POOL_SCAN_SCRUB) {
4067                 (void) printf(gettext("    %s repaired, %.2f%% done\n"),
4068                     processed_buf, 100 * fraction_done);
4069         }
4070 }
4071
4072 static void
4073 print_error_log(zpool_handle_t *zhp)
4074 {
4075         nvlist_t *nverrlist = NULL;
4076         nvpair_t *elem;
4077         char *pathname;
4078         size_t len = MAXPATHLEN * 2;
4079
4080         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
4081                 (void) printf("errors: List of errors unavailable "
4082                     "(insufficient privileges)\n");
4083                 return;
4084         }
4085
4086         (void) printf("errors: Permanent errors have been "
4087             "detected in the following files:\n\n");
4088
4089         pathname = safe_malloc(len);
4090         elem = NULL;
4091         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
4092                 nvlist_t *nv;
4093                 uint64_t dsobj, obj;
4094
4095                 verify(nvpair_value_nvlist(elem, &nv) == 0);
4096                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
4097                     &dsobj) == 0);
4098                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
4099                     &obj) == 0);
4100                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
4101                 (void) printf("%7s %s\n", "", pathname);
4102         }
4103         free(pathname);
4104         nvlist_free(nverrlist);
4105 }
4106
4107 static void
4108 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
4109     int namewidth)
4110 {
4111         uint_t i;
4112         char *name;
4113
4114         if (nspares == 0)
4115                 return;
4116
4117         (void) printf(gettext("\tspares\n"));
4118
4119         for (i = 0; i < nspares; i++) {
4120                 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
4121                 print_status_config(zhp, name, spares[i],
4122                     namewidth, 2, B_TRUE);
4123                 free(name);
4124         }
4125 }
4126
4127 static void
4128 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
4129     int namewidth)
4130 {
4131         uint_t i;
4132         char *name;
4133
4134         if (nl2cache == 0)
4135                 return;
4136
4137         (void) printf(gettext("\tcache\n"));
4138
4139         for (i = 0; i < nl2cache; i++) {
4140                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
4141                 print_status_config(zhp, name, l2cache[i],
4142                     namewidth, 2, B_FALSE);
4143                 free(name);
4144         }
4145 }
4146
4147 static void
4148 print_dedup_stats(nvlist_t *config)
4149 {
4150         ddt_histogram_t *ddh;
4151         ddt_stat_t *dds;
4152         ddt_object_t *ddo;
4153         uint_t c;
4154
4155         /*
4156          * If the pool was faulted then we may not have been able to
4157          * obtain the config. Otherwise, if we have anything in the dedup
4158          * table continue processing the stats.
4159          */
4160         if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
4161             (uint64_t **)&ddo, &c) != 0)
4162                 return;
4163
4164         (void) printf("\n");
4165         (void) printf(gettext(" dedup: "));
4166         if (ddo->ddo_count == 0) {
4167                 (void) printf(gettext("no DDT entries\n"));
4168                 return;
4169         }
4170
4171         (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n",
4172             (u_longlong_t)ddo->ddo_count,
4173             (u_longlong_t)ddo->ddo_dspace,
4174             (u_longlong_t)ddo->ddo_mspace);
4175
4176         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
4177             (uint64_t **)&dds, &c) == 0);
4178         verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
4179             (uint64_t **)&ddh, &c) == 0);
4180         zpool_dump_ddt(dds, ddh);
4181 }
4182
4183 /*
4184  * Display a summary of pool status.  Displays a summary such as:
4185  *
4186  *        pool: tank
4187  *      status: DEGRADED
4188  *      reason: One or more devices ...
4189  *         see: http://zfsonlinux.org/msg/ZFS-xxxx-01
4190  *      config:
4191  *              mirror          DEGRADED
4192  *                c1t0d0        OK
4193  *                c2t0d0        UNAVAIL
4194  *
4195  * When given the '-v' option, we print out the complete config.  If the '-e'
4196  * option is specified, then we print out error rate information as well.
4197  */
4198 int
4199 status_callback(zpool_handle_t *zhp, void *data)
4200 {
4201         status_cbdata_t *cbp = data;
4202         nvlist_t *config, *nvroot;
4203         char *msgid;
4204         zpool_status_t reason;
4205         zpool_errata_t errata;
4206         const char *health;
4207         uint_t c;
4208         vdev_stat_t *vs;
4209
4210         config = zpool_get_config(zhp, NULL);
4211         reason = zpool_get_status(zhp, &msgid, &errata);
4212
4213         cbp->cb_count++;
4214
4215         /*
4216          * If we were given 'zpool status -x', only report those pools with
4217          * problems.
4218          */
4219         if (cbp->cb_explain &&
4220             (reason == ZPOOL_STATUS_OK ||
4221             reason == ZPOOL_STATUS_VERSION_OLDER ||
4222             reason == ZPOOL_STATUS_FEAT_DISABLED)) {
4223                 if (!cbp->cb_allpools) {
4224                         (void) printf(gettext("pool '%s' is healthy\n"),
4225                             zpool_get_name(zhp));
4226                         if (cbp->cb_first)
4227                                 cbp->cb_first = B_FALSE;
4228                 }
4229                 return (0);
4230         }
4231
4232         if (cbp->cb_first)
4233                 cbp->cb_first = B_FALSE;
4234         else
4235                 (void) printf("\n");
4236
4237         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4238             &nvroot) == 0);
4239         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
4240             (uint64_t **)&vs, &c) == 0);
4241         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
4242
4243         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
4244         (void) printf(gettext(" state: %s\n"), health);
4245
4246         switch (reason) {
4247         case ZPOOL_STATUS_MISSING_DEV_R:
4248                 (void) printf(gettext("status: One or more devices could not "
4249                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
4250                     "continue functioning in a degraded state.\n"));
4251                 (void) printf(gettext("action: Attach the missing device and "
4252                     "online it using 'zpool online'.\n"));
4253                 break;
4254
4255         case ZPOOL_STATUS_MISSING_DEV_NR:
4256                 (void) printf(gettext("status: One or more devices could not "
4257                     "be opened.  There are insufficient\n\treplicas for the "
4258                     "pool to continue functioning.\n"));
4259                 (void) printf(gettext("action: Attach the missing device and "
4260                     "online it using 'zpool online'.\n"));
4261                 break;
4262
4263         case ZPOOL_STATUS_CORRUPT_LABEL_R:
4264                 (void) printf(gettext("status: One or more devices could not "
4265                     "be used because the label is missing or\n\tinvalid.  "
4266                     "Sufficient replicas exist for the pool to continue\n\t"
4267                     "functioning in a degraded state.\n"));
4268                 (void) printf(gettext("action: Replace the device using "
4269                     "'zpool replace'.\n"));
4270                 break;
4271
4272         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
4273                 (void) printf(gettext("status: One or more devices could not "
4274                     "be used because the label is missing \n\tor invalid.  "
4275                     "There are insufficient replicas for the pool to "
4276                     "continue\n\tfunctioning.\n"));
4277                 zpool_explain_recover(zpool_get_handle(zhp),
4278                     zpool_get_name(zhp), reason, config);
4279                 break;
4280
4281         case ZPOOL_STATUS_FAILING_DEV:
4282                 (void) printf(gettext("status: One or more devices has "
4283                     "experienced an unrecoverable error.  An\n\tattempt was "
4284                     "made to correct the error.  Applications are "
4285                     "unaffected.\n"));
4286                 (void) printf(gettext("action: Determine if the device needs "
4287                     "to be replaced, and clear the errors\n\tusing "
4288                     "'zpool clear' or replace the device with 'zpool "
4289                     "replace'.\n"));
4290                 break;
4291
4292         case ZPOOL_STATUS_OFFLINE_DEV:
4293                 (void) printf(gettext("status: One or more devices has "
4294                     "been taken offline by the administrator.\n\tSufficient "
4295                     "replicas exist for the pool to continue functioning in "
4296                     "a\n\tdegraded state.\n"));
4297                 (void) printf(gettext("action: Online the device using "
4298                     "'zpool online' or replace the device with\n\t'zpool "
4299                     "replace'.\n"));
4300                 break;
4301
4302         case ZPOOL_STATUS_REMOVED_DEV:
4303                 (void) printf(gettext("status: One or more devices has "
4304                     "been removed by the administrator.\n\tSufficient "
4305                     "replicas exist for the pool to continue functioning in "
4306                     "a\n\tdegraded state.\n"));
4307                 (void) printf(gettext("action: Online the device using "
4308                     "'zpool online' or replace the device with\n\t'zpool "
4309                     "replace'.\n"));
4310                 break;
4311
4312         case ZPOOL_STATUS_RESILVERING:
4313                 (void) printf(gettext("status: One or more devices is "
4314                     "currently being resilvered.  The pool will\n\tcontinue "
4315                     "to function, possibly in a degraded state.\n"));
4316                 (void) printf(gettext("action: Wait for the resilver to "
4317                     "complete.\n"));
4318                 break;
4319
4320         case ZPOOL_STATUS_CORRUPT_DATA:
4321                 (void) printf(gettext("status: One or more devices has "
4322                     "experienced an error resulting in data\n\tcorruption.  "
4323                     "Applications may be affected.\n"));
4324                 (void) printf(gettext("action: Restore the file in question "
4325                     "if possible.  Otherwise restore the\n\tentire pool from "
4326                     "backup.\n"));
4327                 break;
4328
4329         case ZPOOL_STATUS_CORRUPT_POOL:
4330                 (void) printf(gettext("status: The pool metadata is corrupted "
4331                     "and the pool cannot be opened.\n"));
4332                 zpool_explain_recover(zpool_get_handle(zhp),
4333                     zpool_get_name(zhp), reason, config);
4334                 break;
4335
4336         case ZPOOL_STATUS_VERSION_OLDER:
4337                 (void) printf(gettext("status: The pool is formatted using a "
4338                     "legacy on-disk format.  The pool can\n\tstill be used, "
4339                     "but some features are unavailable.\n"));
4340                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
4341                     "upgrade'.  Once this is done, the\n\tpool will no longer "
4342                     "be accessible on software that does not support\n\t"
4343                     "feature flags.\n"));
4344                 break;
4345
4346         case ZPOOL_STATUS_VERSION_NEWER:
4347                 (void) printf(gettext("status: The pool has been upgraded to a "
4348                     "newer, incompatible on-disk version.\n\tThe pool cannot "
4349                     "be accessed on this system.\n"));
4350                 (void) printf(gettext("action: Access the pool from a system "
4351                     "running more recent software, or\n\trestore the pool from "
4352                     "backup.\n"));
4353                 break;
4354
4355         case ZPOOL_STATUS_FEAT_DISABLED:
4356                 (void) printf(gettext("status: Some supported features are not "
4357                     "enabled on the pool. The pool can\n\tstill be used, but "
4358                     "some features are unavailable.\n"));
4359                 (void) printf(gettext("action: Enable all features using "
4360                     "'zpool upgrade'. Once this is done,\n\tthe pool may no "
4361                     "longer be accessible by software that does not support\n\t"
4362                     "the features. See zpool-features(5) for details.\n"));
4363                 break;
4364
4365         case ZPOOL_STATUS_UNSUP_FEAT_READ:
4366                 (void) printf(gettext("status: The pool cannot be accessed on "
4367                     "this system because it uses the\n\tfollowing feature(s) "
4368                     "not supported on this system:\n"));
4369                 zpool_print_unsup_feat(config);
4370                 (void) printf("\n");
4371                 (void) printf(gettext("action: Access the pool from a system "
4372                     "that supports the required feature(s),\n\tor restore the "
4373                     "pool from backup.\n"));
4374                 break;
4375
4376         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4377                 (void) printf(gettext("status: The pool can only be accessed "
4378                     "in read-only mode on this system. It\n\tcannot be "
4379                     "accessed in read-write mode because it uses the "
4380                     "following\n\tfeature(s) not supported on this system:\n"));
4381                 zpool_print_unsup_feat(config);
4382                 (void) printf("\n");
4383                 (void) printf(gettext("action: The pool cannot be accessed in "
4384                     "read-write mode. Import the pool with\n"
4385                     "\t\"-o readonly=on\", access the pool from a system that "
4386                     "supports the\n\trequired feature(s), or restore the "
4387                     "pool from backup.\n"));
4388                 break;
4389
4390         case ZPOOL_STATUS_FAULTED_DEV_R:
4391                 (void) printf(gettext("status: One or more devices are "
4392                     "faulted in response to persistent errors.\n\tSufficient "
4393                     "replicas exist for the pool to continue functioning "
4394                     "in a\n\tdegraded state.\n"));
4395                 (void) printf(gettext("action: Replace the faulted device, "
4396                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4397                 break;
4398
4399         case ZPOOL_STATUS_FAULTED_DEV_NR:
4400                 (void) printf(gettext("status: One or more devices are "
4401                     "faulted in response to persistent errors.  There are "
4402                     "insufficient replicas for the pool to\n\tcontinue "
4403                     "functioning.\n"));
4404                 (void) printf(gettext("action: Destroy and re-create the pool "
4405                     "from a backup source.  Manually marking the device\n"
4406                     "\trepaired using 'zpool clear' may allow some data "
4407                     "to be recovered.\n"));
4408                 break;
4409
4410         case ZPOOL_STATUS_IO_FAILURE_WAIT:
4411         case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
4412                 (void) printf(gettext("status: One or more devices are "
4413                     "faulted in response to IO failures.\n"));
4414                 (void) printf(gettext("action: Make sure the affected devices "
4415                     "are connected, then run 'zpool clear'.\n"));
4416                 break;
4417
4418         case ZPOOL_STATUS_BAD_LOG:
4419                 (void) printf(gettext("status: An intent log record "
4420                     "could not be read.\n"
4421                     "\tWaiting for adminstrator intervention to fix the "
4422                     "faulted pool.\n"));
4423                 (void) printf(gettext("action: Either restore the affected "
4424                     "device(s) and run 'zpool online',\n"
4425                     "\tor ignore the intent log records by running "
4426                     "'zpool clear'.\n"));
4427                 break;
4428
4429         case ZPOOL_STATUS_HOSTID_MISMATCH:
4430                 (void) printf(gettext("status: Mismatch between pool hostid "
4431                     "and system hostid on imported pool.\n\tThis pool was "
4432                     "previously imported into a system with a different "
4433                     "hostid,\n\tand then was verbatim imported into this "
4434                     "system.\n"));
4435                 (void) printf(gettext("action: Export this pool on all systems "
4436                     "on which it is imported.\n"
4437                     "\tThen import it to correct the mismatch.\n"));
4438                 break;
4439
4440         case ZPOOL_STATUS_ERRATA:
4441                 (void) printf(gettext("status: Errata #%d detected.\n"),
4442                     errata);
4443
4444                 switch (errata) {
4445                 case ZPOOL_ERRATA_NONE:
4446                         break;
4447
4448                 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
4449                         (void) printf(gettext("action: To correct the issue "
4450                             "run 'zpool scrub'.\n"));
4451                         break;
4452
4453                 default:
4454                         /*
4455                          * All errata which allow the pool to be imported
4456                          * must contain an action message.
4457                          */
4458                         assert(0);
4459                 }
4460                 break;
4461
4462         default:
4463                 /*
4464                  * The remaining errors can't actually be generated, yet.
4465                  */
4466                 assert(reason == ZPOOL_STATUS_OK);
4467         }
4468
4469         if (msgid != NULL)
4470                 (void) printf(gettext("   see: http://zfsonlinux.org/msg/%s\n"),
4471                     msgid);
4472
4473         if (config != NULL) {
4474                 int namewidth;
4475                 uint64_t nerr;
4476                 nvlist_t **spares, **l2cache;
4477                 uint_t nspares, nl2cache;
4478                 pool_scan_stat_t *ps = NULL;
4479
4480                 (void) nvlist_lookup_uint64_array(nvroot,
4481                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
4482                 print_scan_status(ps);
4483
4484                 namewidth = max_width(zhp, nvroot, 0, 0);
4485                 if (namewidth < 10)
4486                         namewidth = 10;
4487
4488                 (void) printf(gettext("config:\n\n"));
4489                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
4490                     "NAME", "STATE", "READ", "WRITE", "CKSUM");
4491                 print_status_config(zhp, zpool_get_name(zhp), nvroot,
4492                     namewidth, 0, B_FALSE);
4493
4494                 if (num_logs(nvroot) > 0)
4495                         print_logs(zhp, nvroot, namewidth, B_TRUE);
4496                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
4497                     &l2cache, &nl2cache) == 0)
4498                         print_l2cache(zhp, l2cache, nl2cache, namewidth);
4499
4500                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
4501                     &spares, &nspares) == 0)
4502                         print_spares(zhp, spares, nspares, namewidth);
4503
4504                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
4505                     &nerr) == 0) {
4506                         nvlist_t *nverrlist = NULL;
4507
4508                         /*
4509                          * If the approximate error count is small, get a
4510                          * precise count by fetching the entire log and
4511                          * uniquifying the results.
4512                          */
4513                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
4514                             zpool_get_errlog(zhp, &nverrlist) == 0) {
4515                                 nvpair_t *elem;
4516
4517                                 elem = NULL;
4518                                 nerr = 0;
4519                                 while ((elem = nvlist_next_nvpair(nverrlist,
4520                                     elem)) != NULL) {
4521                                         nerr++;
4522                                 }
4523                         }
4524                         nvlist_free(nverrlist);
4525
4526                         (void) printf("\n");
4527
4528                         if (nerr == 0)
4529                                 (void) printf(gettext("errors: No known data "
4530                                     "errors\n"));
4531                         else if (!cbp->cb_verbose)
4532                                 (void) printf(gettext("errors: %llu data "
4533                                     "errors, use '-v' for a list\n"),
4534                                     (u_longlong_t)nerr);
4535                         else
4536                                 print_error_log(zhp);
4537                 }
4538
4539                 if (cbp->cb_dedup_stats)
4540                         print_dedup_stats(config);
4541         } else {
4542                 (void) printf(gettext("config: The configuration cannot be "
4543                     "determined.\n"));
4544         }
4545
4546         return (0);
4547 }
4548
4549 /*
4550  * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
4551  *
4552  *      -v      Display complete error logs
4553  *      -x      Display only pools with potential problems
4554  *      -D      Display dedup status (undocumented)
4555  *      -T      Display a timestamp in date(1) or Unix format
4556  *
4557  * Describes the health status of all pools or some subset.
4558  */
4559 int
4560 zpool_do_status(int argc, char **argv)
4561 {
4562         int c;
4563         int ret;
4564         unsigned long interval = 0, count = 0;
4565         status_cbdata_t cb = { 0 };
4566
4567         /* check options */
4568         while ((c = getopt(argc, argv, "vxDT:")) != -1) {
4569                 switch (c) {
4570                 case 'v':
4571                         cb.cb_verbose = B_TRUE;
4572                         break;
4573                 case 'x':
4574                         cb.cb_explain = B_TRUE;
4575                         break;
4576                 case 'D':
4577                         cb.cb_dedup_stats = B_TRUE;
4578                         break;
4579                 case 'T':
4580                         get_timestamp_arg(*optarg);
4581                         break;
4582                 case '?':
4583                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4584                             optopt);
4585                         usage(B_FALSE);
4586                 }
4587         }
4588
4589         argc -= optind;
4590         argv += optind;
4591
4592         get_interval_count(&argc, argv, &interval, &count);
4593
4594         if (argc == 0)
4595                 cb.cb_allpools = B_TRUE;
4596
4597         cb.cb_first = B_TRUE;
4598
4599         for (;;) {
4600                 if (timestamp_fmt != NODATE)
4601                         print_timestamp(timestamp_fmt);
4602
4603                 ret = for_each_pool(argc, argv, B_TRUE, NULL,
4604                     status_callback, &cb);
4605
4606                 if (argc == 0 && cb.cb_count == 0)
4607                         (void) fprintf(stderr, gettext("no pools available\n"));
4608                 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
4609                         (void) printf(gettext("all pools are healthy\n"));
4610
4611                 if (ret != 0)
4612                         return (ret);
4613
4614                 if (interval == 0)
4615                         break;
4616
4617                 if (count != 0 && --count == 0)
4618                         break;
4619
4620                 (void) sleep(interval);
4621         }
4622
4623         return (0);
4624 }
4625
4626 typedef struct upgrade_cbdata {
4627         int     cb_first;
4628         int     cb_argc;
4629         uint64_t cb_version;
4630         char    **cb_argv;
4631 } upgrade_cbdata_t;
4632
4633 static int
4634 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
4635 {
4636         int zfs_version = (int) zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
4637         int *count = (int *)unsupp_fs;
4638
4639         if (zfs_version > ZPL_VERSION) {
4640                 (void) printf(gettext("%s (v%d) is not supported by this "
4641                     "implementation of ZFS.\n"),
4642                     zfs_get_name(zhp), zfs_version);
4643                 (*count)++;
4644         }
4645
4646         zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
4647
4648         zfs_close(zhp);
4649
4650         return (0);
4651 }
4652
4653 static int
4654 upgrade_version(zpool_handle_t *zhp, uint64_t version)
4655 {
4656         int ret;
4657         nvlist_t *config;
4658         uint64_t oldversion;
4659         int unsupp_fs = 0;
4660
4661         config = zpool_get_config(zhp, NULL);
4662         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4663             &oldversion) == 0);
4664
4665         assert(SPA_VERSION_IS_SUPPORTED(oldversion));
4666         assert(oldversion < version);
4667
4668         ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
4669         if (ret != 0)
4670                 return (ret);
4671
4672         if (unsupp_fs) {
4673                 (void) printf(gettext("Upgrade not performed due to %d "
4674                     "unsupported filesystems (max v%d).\n"),
4675                     unsupp_fs, (int) ZPL_VERSION);
4676                 return (1);
4677         }
4678
4679         ret = zpool_upgrade(zhp, version);
4680         if (ret != 0)
4681                 return (ret);
4682
4683         if (version >= SPA_VERSION_FEATURES) {
4684                 (void) printf(gettext("Successfully upgraded "
4685                     "'%s' from version %llu to feature flags.\n"),
4686                     zpool_get_name(zhp), (u_longlong_t) oldversion);
4687         } else {
4688                 (void) printf(gettext("Successfully upgraded "
4689                     "'%s' from version %llu to version %llu.\n"),
4690                     zpool_get_name(zhp), (u_longlong_t) oldversion,
4691                     (u_longlong_t) version);
4692         }
4693
4694         return (0);
4695 }
4696
4697 static int
4698 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
4699 {
4700         int i, ret, count;
4701         boolean_t firstff = B_TRUE;
4702         nvlist_t *enabled = zpool_get_features(zhp);
4703
4704         count = 0;
4705         for (i = 0; i < SPA_FEATURES; i++) {
4706                 const char *fname = spa_feature_table[i].fi_uname;
4707                 const char *fguid = spa_feature_table[i].fi_guid;
4708                 if (!nvlist_exists(enabled, fguid)) {
4709                         char *propname;
4710                         verify(-1 != asprintf(&propname, "feature@%s", fname));
4711                         ret = zpool_set_prop(zhp, propname,
4712                             ZFS_FEATURE_ENABLED);
4713                         if (ret != 0) {
4714                                 free(propname);
4715                                 return (ret);
4716                         }
4717                         count++;
4718
4719                         if (firstff) {
4720                                 (void) printf(gettext("Enabled the "
4721                                     "following features on '%s':\n"),
4722                                     zpool_get_name(zhp));
4723                                 firstff = B_FALSE;
4724                         }
4725                         (void) printf(gettext("  %s\n"), fname);
4726                         free(propname);
4727                 }
4728         }
4729
4730         if (countp != NULL)
4731                 *countp = count;
4732         return (0);
4733 }
4734
4735 static int
4736 upgrade_cb(zpool_handle_t *zhp, void *arg)
4737 {
4738         upgrade_cbdata_t *cbp = arg;
4739         nvlist_t *config;
4740         uint64_t version;
4741         boolean_t printnl = B_FALSE;
4742         int ret;
4743
4744         config = zpool_get_config(zhp, NULL);
4745         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4746             &version) == 0);
4747
4748         assert(SPA_VERSION_IS_SUPPORTED(version));
4749
4750         if (version < cbp->cb_version) {
4751                 cbp->cb_first = B_FALSE;
4752                 ret = upgrade_version(zhp, cbp->cb_version);
4753                 if (ret != 0)
4754                         return (ret);
4755                 printnl = B_TRUE;
4756
4757                 /*
4758                  * If they did "zpool upgrade -a", then we could
4759                  * be doing ioctls to different pools.  We need
4760                  * to log this history once to each pool, and bypass
4761                  * the normal history logging that happens in main().
4762                  */
4763                 (void) zpool_log_history(g_zfs, history_str);
4764                 log_history = B_FALSE;
4765         }
4766
4767         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4768                 int count;
4769                 ret = upgrade_enable_all(zhp, &count);
4770                 if (ret != 0)
4771                         return (ret);
4772
4773                 if (count > 0) {
4774                         cbp->cb_first = B_FALSE;
4775                         printnl = B_TRUE;
4776                 }
4777         }
4778
4779         if (printnl) {
4780                 (void) printf(gettext("\n"));
4781         }
4782
4783         return (0);
4784 }
4785
4786 static int
4787 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
4788 {
4789         upgrade_cbdata_t *cbp = arg;
4790         nvlist_t *config;
4791         uint64_t version;
4792
4793         config = zpool_get_config(zhp, NULL);
4794         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4795             &version) == 0);
4796
4797         assert(SPA_VERSION_IS_SUPPORTED(version));
4798
4799         if (version < SPA_VERSION_FEATURES) {
4800                 if (cbp->cb_first) {
4801                         (void) printf(gettext("The following pools are "
4802                             "formatted with legacy version numbers and can\n"
4803                             "be upgraded to use feature flags.  After "
4804                             "being upgraded, these pools\nwill no "
4805                             "longer be accessible by software that does not "
4806                             "support feature\nflags.\n\n"));
4807                         (void) printf(gettext("VER  POOL\n"));
4808                         (void) printf(gettext("---  ------------\n"));
4809                         cbp->cb_first = B_FALSE;
4810                 }
4811
4812                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
4813                     zpool_get_name(zhp));
4814         }
4815
4816         return (0);
4817 }
4818
4819 static int
4820 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
4821 {
4822         upgrade_cbdata_t *cbp = arg;
4823         nvlist_t *config;
4824         uint64_t version;
4825
4826         config = zpool_get_config(zhp, NULL);
4827         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4828             &version) == 0);
4829
4830         if (version >= SPA_VERSION_FEATURES) {
4831                 int i;
4832                 boolean_t poolfirst = B_TRUE;
4833                 nvlist_t *enabled = zpool_get_features(zhp);
4834
4835                 for (i = 0; i < SPA_FEATURES; i++) {
4836                         const char *fguid = spa_feature_table[i].fi_guid;
4837                         const char *fname = spa_feature_table[i].fi_uname;
4838                         if (!nvlist_exists(enabled, fguid)) {
4839                                 if (cbp->cb_first) {
4840                                         (void) printf(gettext("\nSome "
4841                                             "supported features are not "
4842                                             "enabled on the following pools. "
4843                                             "Once a\nfeature is enabled the "
4844                                             "pool may become incompatible with "
4845                                             "software\nthat does not support "
4846                                             "the feature. See "
4847                                             "zpool-features(5) for "
4848                                             "details.\n\n"));
4849                                         (void) printf(gettext("POOL  "
4850                                             "FEATURE\n"));
4851                                         (void) printf(gettext("------"
4852                                             "---------\n"));
4853                                         cbp->cb_first = B_FALSE;
4854                                 }
4855
4856                                 if (poolfirst) {
4857                                         (void) printf(gettext("%s\n"),
4858                                             zpool_get_name(zhp));
4859                                         poolfirst = B_FALSE;
4860                                 }
4861
4862                                 (void) printf(gettext("      %s\n"), fname);
4863                         }
4864                         /*
4865                          * If they did "zpool upgrade -a", then we could
4866                          * be doing ioctls to different pools.  We need
4867                          * to log this history once to each pool, and bypass
4868                          * the normal history logging that happens in main().
4869                          */
4870                         (void) zpool_log_history(g_zfs, history_str);
4871                         log_history = B_FALSE;
4872                 }
4873         }
4874
4875         return (0);
4876 }
4877
4878 /* ARGSUSED */
4879 static int
4880 upgrade_one(zpool_handle_t *zhp, void *data)
4881 {
4882         boolean_t printnl = B_FALSE;
4883         upgrade_cbdata_t *cbp = data;
4884         uint64_t cur_version;
4885         int ret;
4886
4887         if (strcmp("log", zpool_get_name(zhp)) == 0) {
4888                 (void) printf(gettext("'log' is now a reserved word\n"
4889                     "Pool 'log' must be renamed using export and import"
4890                     " to upgrade.\n"));
4891                 return (1);
4892         }
4893
4894         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
4895         if (cur_version > cbp->cb_version) {
4896                 (void) printf(gettext("Pool '%s' is already formatted "
4897                     "using more current version '%llu'.\n\n"),
4898                     zpool_get_name(zhp), (u_longlong_t) cur_version);
4899                 return (0);
4900         }
4901
4902         if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
4903                 (void) printf(gettext("Pool '%s' is already formatted "
4904                     "using version %llu.\n\n"), zpool_get_name(zhp),
4905                     (u_longlong_t) cbp->cb_version);
4906                 return (0);
4907         }
4908
4909         if (cur_version != cbp->cb_version) {
4910                 printnl = B_TRUE;
4911                 ret = upgrade_version(zhp, cbp->cb_version);
4912                 if (ret != 0)
4913                         return (ret);
4914         }
4915
4916         if (cbp->cb_version >= SPA_VERSION_FEATURES) {
4917                 int count = 0;
4918                 ret = upgrade_enable_all(zhp, &count);
4919                 if (ret != 0)
4920                         return (ret);
4921
4922                 if (count != 0) {
4923                         printnl = B_TRUE;
4924                 } else if (cur_version == SPA_VERSION) {
4925                         (void) printf(gettext("Pool '%s' already has all "
4926                             "supported features enabled.\n"),
4927                             zpool_get_name(zhp));
4928                 }
4929         }
4930
4931         if (printnl) {
4932                 (void) printf(gettext("\n"));
4933         }
4934
4935         return (0);
4936 }
4937
4938 /*
4939  * zpool upgrade
4940  * zpool upgrade -v
4941  * zpool upgrade [-V version] <-a | pool ...>
4942  *
4943  * With no arguments, display downrev'd ZFS pool available for upgrade.
4944  * Individual pools can be upgraded by specifying the pool, and '-a' will
4945  * upgrade all pools.
4946  */
4947 int
4948 zpool_do_upgrade(int argc, char **argv)
4949 {
4950         int c;
4951         upgrade_cbdata_t cb = { 0 };
4952         int ret = 0;
4953         boolean_t showversions = B_FALSE;
4954         boolean_t upgradeall = B_FALSE;
4955         char *end;
4956
4957
4958         /* check options */
4959         while ((c = getopt(argc, argv, ":avV:")) != -1) {
4960                 switch (c) {
4961                 case 'a':
4962                         upgradeall = B_TRUE;
4963                         break;
4964                 case 'v':
4965                         showversions = B_TRUE;
4966                         break;
4967                 case 'V':
4968                         cb.cb_version = strtoll(optarg, &end, 10);
4969                         if (*end != '\0' ||
4970                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
4971                                 (void) fprintf(stderr,
4972                                     gettext("invalid version '%s'\n"), optarg);
4973                                 usage(B_FALSE);
4974                         }
4975                         break;
4976                 case ':':
4977                         (void) fprintf(stderr, gettext("missing argument for "
4978                             "'%c' option\n"), optopt);
4979                         usage(B_FALSE);
4980                         break;
4981                 case '?':
4982                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4983                             optopt);
4984                         usage(B_FALSE);
4985                 }
4986         }
4987
4988         cb.cb_argc = argc;
4989         cb.cb_argv = argv;
4990         argc -= optind;
4991         argv += optind;
4992
4993         if (cb.cb_version == 0) {
4994                 cb.cb_version = SPA_VERSION;
4995         } else if (!upgradeall && argc == 0) {
4996                 (void) fprintf(stderr, gettext("-V option is "
4997                     "incompatible with other arguments\n"));
4998                 usage(B_FALSE);
4999         }
5000
5001         if (showversions) {
5002                 if (upgradeall || argc != 0) {
5003                         (void) fprintf(stderr, gettext("-v option is "
5004                             "incompatible with other arguments\n"));
5005                         usage(B_FALSE);
5006                 }
5007         } else if (upgradeall) {
5008                 if (argc != 0) {
5009                         (void) fprintf(stderr, gettext("-a option should not "
5010                             "be used along with a pool name\n"));
5011                         usage(B_FALSE);
5012                 }
5013         }
5014
5015         (void) printf(gettext("This system supports ZFS pool feature "
5016             "flags.\n\n"));
5017         if (showversions) {
5018                 int i;
5019
5020                 (void) printf(gettext("The following features are "
5021                     "supported:\n\n"));
5022                 (void) printf(gettext("FEAT DESCRIPTION\n"));
5023                 (void) printf("----------------------------------------------"
5024                     "---------------\n");
5025                 for (i = 0; i < SPA_FEATURES; i++) {
5026                         zfeature_info_t *fi = &spa_feature_table[i];
5027                         const char *ro = fi->fi_can_readonly ?
5028                             " (read-only compatible)" : "";
5029
5030                         (void) printf("%-37s%s\n", fi->fi_uname, ro);
5031                         (void) printf("     %s\n", fi->fi_desc);
5032                 }
5033                 (void) printf("\n");
5034
5035                 (void) printf(gettext("The following legacy versions are also "
5036                     "supported:\n\n"));
5037                 (void) printf(gettext("VER  DESCRIPTION\n"));
5038                 (void) printf("---  -----------------------------------------"
5039                     "---------------\n");
5040                 (void) printf(gettext(" 1   Initial ZFS version\n"));
5041                 (void) printf(gettext(" 2   Ditto blocks "
5042                     "(replicated metadata)\n"));
5043                 (void) printf(gettext(" 3   Hot spares and double parity "
5044                     "RAID-Z\n"));
5045                 (void) printf(gettext(" 4   zpool history\n"));
5046                 (void) printf(gettext(" 5   Compression using the gzip "
5047                     "algorithm\n"));
5048                 (void) printf(gettext(" 6   bootfs pool property\n"));
5049                 (void) printf(gettext(" 7   Separate intent log devices\n"));
5050                 (void) printf(gettext(" 8   Delegated administration\n"));
5051                 (void) printf(gettext(" 9   refquota and refreservation "
5052                     "properties\n"));
5053                 (void) printf(gettext(" 10  Cache devices\n"));
5054                 (void) printf(gettext(" 11  Improved scrub performance\n"));
5055                 (void) printf(gettext(" 12  Snapshot properties\n"));
5056                 (void) printf(gettext(" 13  snapused property\n"));
5057                 (void) printf(gettext(" 14  passthrough-x aclinherit\n"));
5058                 (void) printf(gettext(" 15  user/group space accounting\n"));
5059                 (void) printf(gettext(" 16  stmf property support\n"));
5060                 (void) printf(gettext(" 17  Triple-parity RAID-Z\n"));
5061                 (void) printf(gettext(" 18  Snapshot user holds\n"));
5062                 (void) printf(gettext(" 19  Log device removal\n"));
5063                 (void) printf(gettext(" 20  Compression using zle "
5064                     "(zero-length encoding)\n"));
5065                 (void) printf(gettext(" 21  Deduplication\n"));
5066                 (void) printf(gettext(" 22  Received properties\n"));
5067                 (void) printf(gettext(" 23  Slim ZIL\n"));
5068                 (void) printf(gettext(" 24  System attributes\n"));
5069                 (void) printf(gettext(" 25  Improved scrub stats\n"));
5070                 (void) printf(gettext(" 26  Improved snapshot deletion "
5071                     "performance\n"));
5072                 (void) printf(gettext(" 27  Improved snapshot creation "
5073                     "performance\n"));
5074                 (void) printf(gettext(" 28  Multiple vdev replacements\n"));
5075                 (void) printf(gettext("\nFor more information on a particular "
5076                     "version, including supported releases,\n"));
5077                 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
5078         } else if (argc == 0 && upgradeall) {
5079                 cb.cb_first = B_TRUE;
5080                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
5081                 if (ret == 0 && cb.cb_first) {
5082                         if (cb.cb_version == SPA_VERSION) {
5083                                 (void) printf(gettext("All pools are already "
5084                                     "formatted using feature flags.\n\n"));
5085                                 (void) printf(gettext("Every feature flags "
5086                                     "pool already has all supported features "
5087                                     "enabled.\n"));
5088                         } else {
5089                                 (void) printf(gettext("All pools are already "
5090                                     "formatted with version %llu or higher.\n"),
5091                                     (u_longlong_t) cb.cb_version);
5092                         }
5093                 }
5094         } else if (argc == 0) {
5095                 cb.cb_first = B_TRUE;
5096                 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
5097                 assert(ret == 0);
5098
5099                 if (cb.cb_first) {
5100                         (void) printf(gettext("All pools are formatted "
5101                             "using feature flags.\n\n"));
5102                 } else {
5103                         (void) printf(gettext("\nUse 'zpool upgrade -v' "
5104                             "for a list of available legacy versions.\n"));
5105                 }
5106
5107                 cb.cb_first = B_TRUE;
5108                 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
5109                 assert(ret == 0);
5110
5111                 if (cb.cb_first) {
5112                         (void) printf(gettext("Every feature flags pool has "
5113                             "all supported features enabled.\n"));
5114                 } else {
5115                         (void) printf(gettext("\n"));
5116                 }
5117         } else {
5118                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
5119                     upgrade_one, &cb);
5120         }
5121
5122         return (ret);
5123 }
5124
5125 typedef struct hist_cbdata {
5126         boolean_t first;
5127         boolean_t longfmt;
5128         boolean_t internal;
5129 } hist_cbdata_t;
5130
5131 /*
5132  * Print out the command history for a specific pool.
5133  */
5134 static int
5135 get_history_one(zpool_handle_t *zhp, void *data)
5136 {
5137         nvlist_t *nvhis;
5138         nvlist_t **records;
5139         uint_t numrecords;
5140         int ret, i;
5141         hist_cbdata_t *cb = (hist_cbdata_t *)data;
5142
5143         cb->first = B_FALSE;
5144
5145         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
5146
5147         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
5148                 return (ret);
5149
5150         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
5151             &records, &numrecords) == 0);
5152         for (i = 0; i < numrecords; i++) {
5153                 nvlist_t *rec = records[i];
5154                 char tbuf[30] = "";
5155
5156                 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
5157                         time_t tsec;
5158                         struct tm t;
5159
5160                         tsec = fnvlist_lookup_uint64(records[i],
5161                             ZPOOL_HIST_TIME);
5162                         (void) localtime_r(&tsec, &t);
5163                         (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
5164                 }
5165
5166                 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
5167                         (void) printf("%s %s", tbuf,
5168                             fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
5169                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
5170                         int ievent =
5171                             fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
5172                         if (!cb->internal)
5173                                 continue;
5174                         if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
5175                                 (void) printf("%s unrecognized record:\n",
5176                                     tbuf);
5177                                 dump_nvlist(rec, 4);
5178                                 continue;
5179                         }
5180                         (void) printf("%s [internal %s txg:%lld] %s", tbuf,
5181                             zfs_history_event_names[ievent],
5182                             (longlong_t) fnvlist_lookup_uint64(
5183                             rec, ZPOOL_HIST_TXG),
5184                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
5185                 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
5186                         if (!cb->internal)
5187                                 continue;
5188                         (void) printf("%s [txg:%lld] %s", tbuf,
5189                             (longlong_t) fnvlist_lookup_uint64(
5190                             rec, ZPOOL_HIST_TXG),
5191                             fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
5192                         if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
5193                                 (void) printf(" %s (%llu)",
5194                                     fnvlist_lookup_string(rec,
5195                                     ZPOOL_HIST_DSNAME),
5196                                     (u_longlong_t)fnvlist_lookup_uint64(rec,
5197                                     ZPOOL_HIST_DSID));
5198                         }
5199                         (void) printf(" %s", fnvlist_lookup_string(rec,
5200                             ZPOOL_HIST_INT_STR));
5201                 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
5202                         if (!cb->internal)
5203                                 continue;
5204                         (void) printf("%s ioctl %s\n", tbuf,
5205                             fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
5206                         if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
5207                                 (void) printf("    input:\n");
5208                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
5209                                     ZPOOL_HIST_INPUT_NVL), 8);
5210                         }
5211                         if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
5212                                 (void) printf("    output:\n");
5213                                 dump_nvlist(fnvlist_lookup_nvlist(rec,
5214                                     ZPOOL_HIST_OUTPUT_NVL), 8);
5215                         }
5216                 } else {
5217                         if (!cb->internal)
5218                                 continue;
5219                         (void) printf("%s unrecognized record:\n", tbuf);
5220                         dump_nvlist(rec, 4);
5221                 }
5222
5223                 if (!cb->longfmt) {
5224                         (void) printf("\n");
5225                         continue;
5226                 }
5227                 (void) printf(" [");
5228                 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
5229                         uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
5230                         struct passwd *pwd = getpwuid(who);
5231                         (void) printf("user %d ", (int)who);
5232                         if (pwd != NULL)
5233                                 (void) printf("(%s) ", pwd->pw_name);
5234                 }
5235                 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
5236                         (void) printf("on %s",
5237                             fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
5238                 }
5239                 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
5240                         (void) printf(":%s",
5241                             fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
5242                 }
5243
5244                 (void) printf("]");
5245                 (void) printf("\n");
5246         }
5247         (void) printf("\n");
5248         nvlist_free(nvhis);
5249
5250         return (ret);
5251 }
5252
5253 /*
5254  * zpool history <pool>
5255  *
5256  * Displays the history of commands that modified pools.
5257  */
5258 int
5259 zpool_do_history(int argc, char **argv)
5260 {
5261         hist_cbdata_t cbdata = { 0 };
5262         int ret;
5263         int c;
5264
5265         cbdata.first = B_TRUE;
5266         /* check options */
5267         while ((c = getopt(argc, argv, "li")) != -1) {
5268                 switch (c) {
5269                 case 'l':
5270                         cbdata.longfmt = B_TRUE;
5271                         break;
5272                 case 'i':
5273                         cbdata.internal = B_TRUE;
5274                         break;
5275                 case '?':
5276                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5277                             optopt);
5278                         usage(B_FALSE);
5279                 }
5280         }
5281         argc -= optind;
5282         argv += optind;
5283
5284         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
5285             &cbdata);
5286
5287         if (argc == 0 && cbdata.first == B_TRUE) {
5288                 (void) fprintf(stderr, gettext("no pools available\n"));
5289                 return (0);
5290         }
5291
5292         return (ret);
5293 }
5294
5295 typedef struct ev_opts {
5296         int verbose;
5297         int scripted;
5298         int follow;
5299         int clear;
5300 } ev_opts_t;
5301
5302 static void
5303 zpool_do_events_short(nvlist_t *nvl)
5304 {
5305         char ctime_str[26], str[32], *ptr;
5306         int64_t *tv;
5307         uint_t n;
5308
5309         verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
5310         memset(str, ' ', 32);
5311         (void) ctime_r((const time_t *)&tv[0], ctime_str);
5312         (void) strncpy(str, ctime_str+4,  6);           /* 'Jun 30' */
5313         (void) strncpy(str+7, ctime_str+20, 4);         /* '1993' */
5314         (void) strncpy(str+12, ctime_str+11, 8);        /* '21:49:08' */
5315         (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */
5316         (void) printf(gettext("%s "), str);
5317
5318         verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0);
5319         (void) printf(gettext("%s\n"), ptr);
5320 }
5321
5322 static void
5323 zpool_do_events_nvprint(nvlist_t *nvl, int depth)
5324 {
5325         nvpair_t *nvp;
5326
5327         for (nvp = nvlist_next_nvpair(nvl, NULL);
5328             nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
5329
5330                 data_type_t type = nvpair_type(nvp);
5331                 const char *name = nvpair_name(nvp);
5332
5333                 boolean_t b;
5334                 uint8_t i8;
5335                 uint16_t i16;
5336                 uint32_t i32;
5337                 uint64_t i64;
5338                 char *str;
5339                 nvlist_t *cnv;
5340
5341                 printf(gettext("%*s%s = "), depth, "", name);
5342
5343                 switch (type) {
5344                 case DATA_TYPE_BOOLEAN:
5345                         printf(gettext("%s"), "1");
5346                         break;
5347
5348                 case DATA_TYPE_BOOLEAN_VALUE:
5349                         (void) nvpair_value_boolean_value(nvp, &b);
5350                         printf(gettext("%s"), b ? "1" : "0");
5351                         break;
5352
5353                 case DATA_TYPE_BYTE:
5354                         (void) nvpair_value_byte(nvp, &i8);
5355                         printf(gettext("0x%x"), i8);
5356                         break;
5357
5358                 case DATA_TYPE_INT8:
5359                         (void) nvpair_value_int8(nvp, (void *)&i8);
5360                         printf(gettext("0x%x"), i8);
5361                         break;
5362
5363                 case DATA_TYPE_UINT8:
5364                         (void) nvpair_value_uint8(nvp, &i8);
5365                         printf(gettext("0x%x"), i8);
5366                         break;
5367
5368                 case DATA_TYPE_INT16:
5369                         (void) nvpair_value_int16(nvp, (void *)&i16);
5370                         printf(gettext("0x%x"), i16);
5371                         break;
5372
5373                 case DATA_TYPE_UINT16:
5374                         (void) nvpair_value_uint16(nvp, &i16);
5375                         printf(gettext("0x%x"), i16);
5376                         break;
5377
5378                 case DATA_TYPE_INT32:
5379                         (void) nvpair_value_int32(nvp, (void *)&i32);
5380                         printf(gettext("0x%x"), i32);
5381                         break;
5382
5383                 case DATA_TYPE_UINT32:
5384                         (void) nvpair_value_uint32(nvp, &i32);
5385                         printf(gettext("0x%x"), i32);
5386                         break;
5387
5388                 case DATA_TYPE_INT64:
5389                         (void) nvpair_value_int64(nvp, (void *)&i64);
5390                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5391                         break;
5392
5393                 case DATA_TYPE_UINT64:
5394                         (void) nvpair_value_uint64(nvp, &i64);
5395                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5396                         break;
5397
5398                 case DATA_TYPE_HRTIME:
5399                         (void) nvpair_value_hrtime(nvp, (void *)&i64);
5400                         printf(gettext("0x%llx"), (u_longlong_t)i64);
5401                         break;
5402
5403                 case DATA_TYPE_STRING:
5404                         (void) nvpair_value_string(nvp, &str);
5405                         printf(gettext("\"%s\""), str ? str : "<NULL>");
5406                         break;
5407
5408                 case DATA_TYPE_NVLIST:
5409                         printf(gettext("(embedded nvlist)\n"));
5410                         (void) nvpair_value_nvlist(nvp, &cnv);
5411                         zpool_do_events_nvprint(cnv, depth + 8);
5412                         printf(gettext("%*s(end %s)"), depth, "", name);
5413                         break;
5414
5415                 case DATA_TYPE_NVLIST_ARRAY: {
5416                         nvlist_t **val;
5417                         uint_t i, nelem;
5418
5419                         (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
5420                         printf(gettext("(%d embedded nvlists)\n"), nelem);
5421                         for (i = 0; i < nelem; i++) {
5422                                 printf(gettext("%*s%s[%d] = %s\n"),
5423                                     depth, "", name, i, "(embedded nvlist)");
5424                                 zpool_do_events_nvprint(val[i], depth + 8);
5425                                 printf(gettext("%*s(end %s[%i])\n"),
5426                                     depth, "", name, i);
5427                         }
5428                         printf(gettext("%*s(end %s)\n"), depth, "", name);
5429                         }
5430                         break;
5431
5432                 case DATA_TYPE_INT8_ARRAY: {
5433                         int8_t *val;
5434                         uint_t i, nelem;
5435
5436                         (void) nvpair_value_int8_array(nvp, &val, &nelem);
5437                         for (i = 0; i < nelem; i++)
5438                                 printf(gettext("0x%x "), val[i]);
5439
5440                         break;
5441                         }
5442
5443                 case DATA_TYPE_UINT8_ARRAY: {
5444                         uint8_t *val;
5445                         uint_t i, nelem;
5446
5447                         (void) nvpair_value_uint8_array(nvp, &val, &nelem);
5448                         for (i = 0; i < nelem; i++)
5449                                 printf(gettext("0x%x "), val[i]);
5450
5451                         break;
5452                         }
5453
5454                 case DATA_TYPE_INT16_ARRAY: {
5455                         int16_t *val;
5456                         uint_t i, nelem;
5457
5458                         (void) nvpair_value_int16_array(nvp, &val, &nelem);
5459                         for (i = 0; i < nelem; i++)
5460                                 printf(gettext("0x%x "), val[i]);
5461
5462                         break;
5463                         }
5464
5465                 case DATA_TYPE_UINT16_ARRAY: {
5466                         uint16_t *val;
5467                         uint_t i, nelem;
5468
5469                         (void) nvpair_value_uint16_array(nvp, &val, &nelem);
5470                         for (i = 0; i < nelem; i++)
5471                                 printf(gettext("0x%x "), val[i]);
5472
5473                         break;
5474                         }
5475
5476                 case DATA_TYPE_INT32_ARRAY: {
5477                         int32_t *val;
5478                         uint_t i, nelem;
5479
5480                         (void) nvpair_value_int32_array(nvp, &val, &nelem);
5481                         for (i = 0; i < nelem; i++)
5482                                 printf(gettext("0x%x "), val[i]);
5483
5484                         break;
5485                         }
5486
5487                 case DATA_TYPE_UINT32_ARRAY: {
5488                         uint32_t *val;
5489                         uint_t i, nelem;
5490
5491                         (void) nvpair_value_uint32_array(nvp, &val, &nelem);
5492                         for (i = 0; i < nelem; i++)
5493                                 printf(gettext("0x%x "), val[i]);
5494
5495                         break;
5496                         }
5497
5498                 case DATA_TYPE_INT64_ARRAY: {
5499                         int64_t *val;
5500                         uint_t i, nelem;
5501
5502                         (void) nvpair_value_int64_array(nvp, &val, &nelem);
5503                         for (i = 0; i < nelem; i++)
5504                                 printf(gettext("0x%llx "),
5505                                     (u_longlong_t)val[i]);
5506
5507                         break;
5508                         }
5509
5510                 case DATA_TYPE_UINT64_ARRAY: {
5511                         uint64_t *val;
5512                         uint_t i, nelem;
5513
5514                         (void) nvpair_value_uint64_array(nvp, &val, &nelem);
5515                         for (i = 0; i < nelem; i++)
5516                                 printf(gettext("0x%llx "),
5517                                     (u_longlong_t)val[i]);
5518
5519                         break;
5520                         }
5521
5522                 case DATA_TYPE_STRING_ARRAY: {
5523                         char **str;
5524                         uint_t i, nelem;
5525
5526                         (void) nvpair_value_string_array(nvp, &str, &nelem);
5527                         for (i = 0; i < nelem; i++)
5528                                 printf(gettext("\"%s\" "),
5529                                     str[i] ? str[i] : "<NULL>");
5530
5531                         break;
5532                         }
5533
5534                 case DATA_TYPE_BOOLEAN_ARRAY:
5535                 case DATA_TYPE_BYTE_ARRAY:
5536                 case DATA_TYPE_DOUBLE:
5537                 case DATA_TYPE_UNKNOWN:
5538                         printf(gettext("<unknown>"));
5539                         break;
5540                 }
5541
5542                 printf(gettext("\n"));
5543         }
5544 }
5545
5546 static int
5547 zpool_do_events_next(ev_opts_t *opts)
5548 {
5549         nvlist_t *nvl;
5550         int zevent_fd, ret, dropped;
5551
5552         zevent_fd = open(ZFS_DEV, O_RDWR);
5553         VERIFY(zevent_fd >= 0);
5554
5555         if (!opts->scripted)
5556                 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
5557
5558         while (1) {
5559                 ret = zpool_events_next(g_zfs, &nvl, &dropped,
5560                     (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd);
5561                 if (ret || nvl == NULL)
5562                         break;
5563
5564                 if (dropped > 0)
5565                         (void) printf(gettext("dropped %d events\n"), dropped);
5566
5567                 zpool_do_events_short(nvl);
5568
5569                 if (opts->verbose) {
5570                         zpool_do_events_nvprint(nvl, 8);
5571                         printf(gettext("\n"));
5572                 }
5573                 (void) fflush(stdout);
5574
5575                 nvlist_free(nvl);
5576         }
5577
5578         VERIFY(0 == close(zevent_fd));
5579
5580         return (ret);
5581 }
5582
5583 static int
5584 zpool_do_events_clear(ev_opts_t *opts)
5585 {
5586         int count, ret;
5587
5588         ret = zpool_events_clear(g_zfs, &count);
5589         if (!ret)
5590                 (void) printf(gettext("cleared %d events\n"), count);
5591
5592         return (ret);
5593 }
5594
5595 /*
5596  * zpool events [-vfc]
5597  *
5598  * Displays events logs by ZFS.
5599  */
5600 int
5601 zpool_do_events(int argc, char **argv)
5602 {
5603         ev_opts_t opts = { 0 };
5604         int ret;
5605         int c;
5606
5607         /* check options */
5608         while ((c = getopt(argc, argv, "vHfc")) != -1) {
5609                 switch (c) {
5610                 case 'v':
5611                         opts.verbose = 1;
5612                         break;
5613                 case 'H':
5614                         opts.scripted = 1;
5615                         break;
5616                 case 'f':
5617                         opts.follow = 1;
5618                         break;
5619                 case 'c':
5620                         opts.clear = 1;
5621                         break;
5622                 case '?':
5623                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5624                             optopt);
5625                         usage(B_FALSE);
5626                 }
5627         }
5628         argc -= optind;
5629         argv += optind;
5630
5631         if (opts.clear)
5632                 ret = zpool_do_events_clear(&opts);
5633         else
5634                 ret = zpool_do_events_next(&opts);
5635
5636         return (ret);
5637 }
5638
5639 static int
5640 get_callback(zpool_handle_t *zhp, void *data)
5641 {
5642         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
5643         char value[MAXNAMELEN];
5644         zprop_source_t srctype;
5645         zprop_list_t *pl;
5646
5647         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
5648
5649                 /*
5650                  * Skip the special fake placeholder. This will also skip
5651                  * over the name property when 'all' is specified.
5652                  */
5653                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
5654                     pl == cbp->cb_proplist)
5655                         continue;
5656
5657                 if (pl->pl_prop == ZPROP_INVAL &&
5658                     (zpool_prop_feature(pl->pl_user_prop) ||
5659                     zpool_prop_unsupported(pl->pl_user_prop))) {
5660                         srctype = ZPROP_SRC_LOCAL;
5661
5662                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
5663                             value, sizeof (value)) == 0) {
5664                                 zprop_print_one_property(zpool_get_name(zhp),
5665                                     cbp, pl->pl_user_prop, value, srctype,
5666                                     NULL, NULL);
5667                         }
5668                 } else {
5669                         if (zpool_get_prop_literal(zhp, pl->pl_prop, value,
5670                             sizeof (value), &srctype, cbp->cb_literal) != 0)
5671                                 continue;
5672
5673                         zprop_print_one_property(zpool_get_name(zhp), cbp,
5674                             zpool_prop_to_name(pl->pl_prop), value, srctype,
5675                             NULL, NULL);
5676                 }
5677         }
5678         return (0);
5679 }
5680
5681 int
5682 zpool_do_get(int argc, char **argv)
5683 {
5684         zprop_get_cbdata_t cb = { 0 };
5685         zprop_list_t fake_name = { 0 };
5686         int c, ret;
5687
5688         /* check options */
5689         while ((c = getopt(argc, argv, "pH")) != -1) {
5690                 switch (c) {
5691                 case 'p':
5692                         cb.cb_literal = B_TRUE;
5693                         break;
5694
5695                 case 'H':
5696                         cb.cb_scripted = B_TRUE;
5697                         break;
5698
5699                 case '?':
5700                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5701                             optopt);
5702                         usage(B_FALSE);
5703                 }
5704         }
5705
5706         argc -= optind;
5707         argv += optind;
5708
5709         if (argc < 1) {
5710                 (void) fprintf(stderr, gettext("missing property "
5711                     "argument\n"));
5712                 usage(B_FALSE);
5713         }
5714
5715         cb.cb_first = B_TRUE;
5716         cb.cb_sources = ZPROP_SRC_ALL;
5717         cb.cb_columns[0] = GET_COL_NAME;
5718         cb.cb_columns[1] = GET_COL_PROPERTY;
5719         cb.cb_columns[2] = GET_COL_VALUE;
5720         cb.cb_columns[3] = GET_COL_SOURCE;
5721         cb.cb_type = ZFS_TYPE_POOL;
5722
5723         if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
5724                 usage(B_FALSE);
5725
5726         argc--;
5727         argv++;
5728
5729         if (cb.cb_proplist != NULL) {
5730                 fake_name.pl_prop = ZPOOL_PROP_NAME;
5731                 fake_name.pl_width = strlen(gettext("NAME"));
5732                 fake_name.pl_next = cb.cb_proplist;
5733                 cb.cb_proplist = &fake_name;
5734         }
5735
5736         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
5737             get_callback, &cb);
5738
5739         if (cb.cb_proplist == &fake_name)
5740                 zprop_free_list(fake_name.pl_next);
5741         else
5742                 zprop_free_list(cb.cb_proplist);
5743
5744         return (ret);
5745 }
5746
5747 typedef struct set_cbdata {
5748         char *cb_propname;
5749         char *cb_value;
5750         boolean_t cb_any_successful;
5751 } set_cbdata_t;
5752
5753 int
5754 set_callback(zpool_handle_t *zhp, void *data)
5755 {
5756         int error;
5757         set_cbdata_t *cb = (set_cbdata_t *)data;
5758
5759         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
5760
5761         if (!error)
5762                 cb->cb_any_successful = B_TRUE;
5763
5764         return (error);
5765 }
5766
5767 int
5768 zpool_do_set(int argc, char **argv)
5769 {
5770         set_cbdata_t cb = { 0 };
5771         int error;
5772
5773         if (argc > 1 && argv[1][0] == '-') {
5774                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5775                     argv[1][1]);
5776                 usage(B_FALSE);
5777         }
5778
5779         if (argc < 2) {
5780                 (void) fprintf(stderr, gettext("missing property=value "
5781                     "argument\n"));
5782                 usage(B_FALSE);
5783         }
5784
5785         if (argc < 3) {
5786                 (void) fprintf(stderr, gettext("missing pool name\n"));
5787                 usage(B_FALSE);
5788         }
5789
5790         if (argc > 3) {
5791                 (void) fprintf(stderr, gettext("too many pool names\n"));
5792                 usage(B_FALSE);
5793         }
5794
5795         cb.cb_propname = argv[1];
5796         cb.cb_value = strchr(cb.cb_propname, '=');
5797         if (cb.cb_value == NULL) {
5798                 (void) fprintf(stderr, gettext("missing value in "
5799                     "property=value argument\n"));
5800                 usage(B_FALSE);
5801         }
5802
5803         *(cb.cb_value) = '\0';
5804         cb.cb_value++;
5805
5806         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
5807             set_callback, &cb);
5808
5809         return (error);
5810 }
5811
5812 static int
5813 find_command_idx(char *command, int *idx)
5814 {
5815         int i;
5816
5817         for (i = 0; i < NCOMMAND; i++) {
5818                 if (command_table[i].name == NULL)
5819                         continue;
5820
5821                 if (strcmp(command, command_table[i].name) == 0) {
5822                         *idx = i;
5823                         return (0);
5824                 }
5825         }
5826         return (1);
5827 }
5828
5829 int
5830 main(int argc, char **argv)
5831 {
5832         int ret;
5833         int i = 0;
5834         char *cmdname;
5835
5836         (void) setlocale(LC_ALL, "");
5837         (void) textdomain(TEXT_DOMAIN);
5838
5839         opterr = 0;
5840
5841         /*
5842          * Make sure the user has specified some command.
5843          */
5844         if (argc < 2) {
5845                 (void) fprintf(stderr, gettext("missing command\n"));
5846                 usage(B_FALSE);
5847         }
5848
5849         cmdname = argv[1];
5850
5851         /*
5852          * Special case '-?'
5853          */
5854         if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0)
5855                 usage(B_TRUE);
5856
5857         if ((g_zfs = libzfs_init()) == NULL)
5858                 return (1);
5859
5860         libzfs_print_on_error(g_zfs, B_TRUE);
5861
5862         zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
5863
5864         /*
5865          * Run the appropriate command.
5866          */
5867         if (find_command_idx(cmdname, &i) == 0) {
5868                 current_command = &command_table[i];
5869                 ret = command_table[i].func(argc - 1, argv + 1);
5870         } else if (strchr(cmdname, '=')) {
5871                 verify(find_command_idx("set", &i) == 0);
5872                 current_command = &command_table[i];
5873                 ret = command_table[i].func(argc, argv);
5874         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
5875                 /*
5876                  * 'freeze' is a vile debugging abomination, so we treat
5877                  * it as such.
5878                  */
5879                 char buf[16384];
5880                 int fd = open(ZFS_DEV, O_RDWR);
5881                 (void) strcpy((void *)buf, argv[2]);
5882                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
5883         } else {
5884                 (void) fprintf(stderr, gettext("unrecognized "
5885                     "command '%s'\n"), cmdname);
5886                 usage(B_FALSE);
5887                 ret = 1;
5888         }
5889
5890         if (ret == 0 && log_history)
5891                 (void) zpool_log_history(g_zfs, history_str);
5892
5893         libzfs_fini(g_zfs);
5894
5895         /*
5896          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
5897          * for the purposes of running ::findleaks.
5898          */
5899         if (getenv("ZFS_ABORT") != NULL) {
5900                 (void) printf("dumping core by request\n");
5901                 abort();
5902         }
5903
5904         return (ret);
5905 }