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