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