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