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