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