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