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