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