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