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