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