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