Initial Linux ZFS GIT Repo
[zfs.git] / zfs / zcmd / 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 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #pragma ident   "@(#)zpool_main.c       1.54    08/02/13 SMI"
28
29 #include <assert.h>
30 #include <ctype.h>
31 #include <dirent.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <libgen.h>
35 #include <libintl.h>
36 #include <libuutil.h>
37 #include <locale.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <unistd.h>
43 #include <priv.h>
44 #include <pwd.h>
45 #include <zone.h>
46 #include <sys/fs/zfs.h>
47
48 #include <sys/stat.h>
49
50 #include <libzfs.h>
51
52 #include "zpool_util.h"
53 #include "zfs_comutil.h"
54
55 static int zpool_do_create(int, char **);
56 static int zpool_do_destroy(int, char **);
57
58 static int zpool_do_add(int, char **);
59 static int zpool_do_remove(int, char **);
60
61 static int zpool_do_list(int, char **);
62 static int zpool_do_iostat(int, char **);
63 static int zpool_do_status(int, char **);
64
65 static int zpool_do_online(int, char **);
66 static int zpool_do_offline(int, char **);
67 static int zpool_do_clear(int, char **);
68
69 static int zpool_do_attach(int, char **);
70 static int zpool_do_detach(int, char **);
71 static int zpool_do_replace(int, char **);
72
73 static int zpool_do_scrub(int, char **);
74
75 static int zpool_do_import(int, char **);
76 static int zpool_do_export(int, char **);
77
78 static int zpool_do_upgrade(int, char **);
79
80 static int zpool_do_history(int, char **);
81
82 static int zpool_do_get(int, char **);
83 static int zpool_do_set(int, char **);
84
85 /*
86  * These libumem hooks provide a reasonable set of defaults for the allocator's
87  * debugging facilities.
88  */
89 const char *
90 _umem_debug_init(void)
91 {
92         return ("default,verbose"); /* $UMEM_DEBUG setting */
93 }
94
95 const char *
96 _umem_logging_init(void)
97 {
98         return ("fail,contents"); /* $UMEM_LOGGING setting */
99 }
100
101 typedef enum {
102         HELP_ADD,
103         HELP_ATTACH,
104         HELP_CLEAR,
105         HELP_CREATE,
106         HELP_DESTROY,
107         HELP_DETACH,
108         HELP_EXPORT,
109         HELP_HISTORY,
110         HELP_IMPORT,
111         HELP_IOSTAT,
112         HELP_LIST,
113         HELP_OFFLINE,
114         HELP_ONLINE,
115         HELP_REPLACE,
116         HELP_REMOVE,
117         HELP_SCRUB,
118         HELP_STATUS,
119         HELP_UPGRADE,
120         HELP_GET,
121         HELP_SET
122 } zpool_help_t;
123
124
125 typedef struct zpool_command {
126         const char      *name;
127         int             (*func)(int, char **);
128         zpool_help_t    usage;
129 } zpool_command_t;
130
131 /*
132  * Master command table.  Each ZFS command has a name, associated function, and
133  * usage message.  The usage messages need to be internationalized, so we have
134  * to have a function to return the usage message based on a command index.
135  *
136  * These commands are organized according to how they are displayed in the usage
137  * message.  An empty command (one with a NULL name) indicates an empty line in
138  * the generic usage message.
139  */
140 static zpool_command_t command_table[] = {
141         { "create",     zpool_do_create,        HELP_CREATE             },
142         { "destroy",    zpool_do_destroy,       HELP_DESTROY            },
143         { NULL },
144         { "add",        zpool_do_add,           HELP_ADD                },
145         { "remove",     zpool_do_remove,        HELP_REMOVE             },
146         { NULL },
147         { "list",       zpool_do_list,          HELP_LIST               },
148         { "iostat",     zpool_do_iostat,        HELP_IOSTAT             },
149         { "status",     zpool_do_status,        HELP_STATUS             },
150         { NULL },
151         { "online",     zpool_do_online,        HELP_ONLINE             },
152         { "offline",    zpool_do_offline,       HELP_OFFLINE            },
153         { "clear",      zpool_do_clear,         HELP_CLEAR              },
154         { NULL },
155         { "attach",     zpool_do_attach,        HELP_ATTACH             },
156         { "detach",     zpool_do_detach,        HELP_DETACH             },
157         { "replace",    zpool_do_replace,       HELP_REPLACE            },
158         { NULL },
159         { "scrub",      zpool_do_scrub,         HELP_SCRUB              },
160         { NULL },
161         { "import",     zpool_do_import,        HELP_IMPORT             },
162         { "export",     zpool_do_export,        HELP_EXPORT             },
163         { "upgrade",    zpool_do_upgrade,       HELP_UPGRADE            },
164         { NULL },
165         { "history",    zpool_do_history,       HELP_HISTORY            },
166         { "get",        zpool_do_get,           HELP_GET                },
167         { "set",        zpool_do_set,           HELP_SET                },
168 };
169
170 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
171
172 zpool_command_t *current_command;
173 static char history_str[HIS_MAX_RECORD_LEN];
174
175 static const char *
176 get_usage(zpool_help_t idx) {
177         switch (idx) {
178         case HELP_ADD:
179                 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
180         case HELP_ATTACH:
181                 return (gettext("\tattach [-f] <pool> <device> "
182                     "<new-device>\n"));
183         case HELP_CLEAR:
184                 return (gettext("\tclear <pool> [device]\n"));
185         case HELP_CREATE:
186                 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
187                     "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
188         case HELP_DESTROY:
189                 return (gettext("\tdestroy [-f] <pool>\n"));
190         case HELP_DETACH:
191                 return (gettext("\tdetach <pool> <device>\n"));
192         case HELP_EXPORT:
193                 return (gettext("\texport [-f] <pool> ...\n"));
194         case HELP_HISTORY:
195                 return (gettext("\thistory [-il] [<pool>] ...\n"));
196         case HELP_IMPORT:
197                 return (gettext("\timport [-d dir] [-D]\n"
198                     "\timport [-o mntopts] [-o property=value] ... \n"
199                     "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
200                     "\timport [-o mntopts] [-o property=value] ... \n"
201                     "\t    [-d dir | -c cachefile] [-D] [-f] [-R root] "
202                     "<pool | id> [newpool]\n"));
203         case HELP_IOSTAT:
204                 return (gettext("\tiostat [-v] [pool] ... [interval "
205                     "[count]]\n"));
206         case HELP_LIST:
207                 return (gettext("\tlist [-H] [-o property[,...]] "
208                     "[pool] ...\n"));
209         case HELP_OFFLINE:
210                 return (gettext("\toffline [-t] <pool> <device> ...\n"));
211         case HELP_ONLINE:
212                 return (gettext("\tonline <pool> <device> ...\n"));
213         case HELP_REPLACE:
214                 return (gettext("\treplace [-f] <pool> <device> "
215                     "[new-device]\n"));
216         case HELP_REMOVE:
217                 return (gettext("\tremove <pool> <device> ...\n"));
218         case HELP_SCRUB:
219                 return (gettext("\tscrub [-s] <pool> ...\n"));
220         case HELP_STATUS:
221                 return (gettext("\tstatus [-vx] [pool] ...\n"));
222         case HELP_UPGRADE:
223                 return (gettext("\tupgrade\n"
224                     "\tupgrade -v\n"
225                     "\tupgrade [-V version] <-a | pool ...>\n"));
226         case HELP_GET:
227                 return (gettext("\tget <\"all\" | property[,...]> "
228                     "<pool> ...\n"));
229         case HELP_SET:
230                 return (gettext("\tset <property=value> <pool> \n"));
231         }
232
233         abort();
234         /* NOTREACHED */
235 }
236
237
238 /*
239  * Callback routine that will print out a pool property value.
240  */
241 static int
242 print_prop_cb(int prop, void *cb)
243 {
244         FILE *fp = cb;
245
246         (void) fprintf(fp, "\t%-13s  ", zpool_prop_to_name(prop));
247
248         if (zpool_prop_readonly(prop))
249                 (void) fprintf(fp, "  NO   ");
250         else
251                 (void) fprintf(fp, " YES    ");
252
253         if (zpool_prop_values(prop) == NULL)
254                 (void) fprintf(fp, "-\n");
255         else
256                 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
257
258         return (ZPROP_CONT);
259 }
260
261 /*
262  * Display usage message.  If we're inside a command, display only the usage for
263  * that command.  Otherwise, iterate over the entire command table and display
264  * a complete usage message.
265  */
266 void
267 usage(boolean_t requested)
268 {
269         FILE *fp = requested ? stdout : stderr;
270
271         if (current_command == NULL) {
272                 int i;
273
274                 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
275                 (void) fprintf(fp,
276                     gettext("where 'command' is one of the following:\n\n"));
277
278                 for (i = 0; i < NCOMMAND; i++) {
279                         if (command_table[i].name == NULL)
280                                 (void) fprintf(fp, "\n");
281                         else
282                                 (void) fprintf(fp, "%s",
283                                     get_usage(command_table[i].usage));
284                 }
285         } else {
286                 (void) fprintf(fp, gettext("usage:\n"));
287                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
288         }
289
290         if (current_command != NULL &&
291             ((strcmp(current_command->name, "set") == 0) ||
292             (strcmp(current_command->name, "get") == 0) ||
293             (strcmp(current_command->name, "list") == 0))) {
294
295                 (void) fprintf(fp,
296                     gettext("\nthe following properties are supported:\n"));
297
298                 (void) fprintf(fp, "\n\t%-13s  %s  %s\n\n",
299                     "PROPERTY", "EDIT", "VALUES");
300
301                 /* Iterate over all properties */
302                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
303                     ZFS_TYPE_POOL);
304         }
305
306         /*
307          * See comments at end of main().
308          */
309         if (getenv("ZFS_ABORT") != NULL) {
310                 (void) printf("dumping core by request\n");
311                 abort();
312         }
313
314         exit(requested ? 0 : 2);
315 }
316
317 void
318 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
319     boolean_t print_logs)
320 {
321         nvlist_t **child;
322         uint_t c, children;
323         char *vname;
324
325         if (name != NULL)
326                 (void) printf("\t%*s%s\n", indent, "", name);
327
328         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
329             &child, &children) != 0)
330                 return;
331
332         for (c = 0; c < children; c++) {
333                 uint64_t is_log = B_FALSE;
334
335                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
336                     &is_log);
337                 if ((is_log && !print_logs) || (!is_log && print_logs))
338                         continue;
339
340                 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
341                 print_vdev_tree(zhp, vname, child[c], indent + 2,
342                     B_FALSE);
343                 free(vname);
344         }
345 }
346
347 /*
348  * Add a property pair (name, string-value) into a property nvlist.
349  */
350 static int
351 add_prop_list(const char *propname, char *propval, nvlist_t **props)
352 {
353         char *strval;
354         nvlist_t *proplist;
355         zpool_prop_t prop;
356
357         if (*props == NULL &&
358             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
359                 (void) fprintf(stderr,
360                     gettext("internal error: out of memory\n"));
361                 return (1);
362         }
363
364         proplist = *props;
365
366         if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
367                 (void) fprintf(stderr, gettext("property '%s' is "
368                     "not a valid pool property\n"), propname);
369                 return (2);
370         }
371
372         /* Use normalized property name for nvlist operations */
373         if (nvlist_lookup_string(proplist, zpool_prop_to_name(prop),
374             &strval) == 0 && prop != ZPOOL_PROP_CACHEFILE) {
375                 (void) fprintf(stderr, gettext("property '%s' "
376                     "specified multiple times\n"), propname);
377                 return (2);
378         }
379
380         if (nvlist_add_string(proplist, zpool_prop_to_name(prop),
381             propval) != 0) {
382                 (void) fprintf(stderr, gettext("internal "
383                     "error: out of memory\n"));
384                 return (1);
385         }
386
387         return (0);
388 }
389
390 /*
391  * zpool add [-fn] <pool> <vdev> ...
392  *
393  *      -f      Force addition of devices, even if they appear in use
394  *      -n      Do not add the devices, but display the resulting layout if
395  *              they were to be added.
396  *
397  * Adds the given vdevs to 'pool'.  As with create, the bulk of this work is
398  * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
399  * libzfs.
400  */
401 int
402 zpool_do_add(int argc, char **argv)
403 {
404         boolean_t force = B_FALSE;
405         boolean_t dryrun = B_FALSE;
406         int c;
407         nvlist_t *nvroot;
408         char *poolname;
409         int ret;
410         zpool_handle_t *zhp;
411         nvlist_t *config;
412
413         /* check options */
414         while ((c = getopt(argc, argv, "fn")) != -1) {
415                 switch (c) {
416                 case 'f':
417                         force = B_TRUE;
418                         break;
419                 case 'n':
420                         dryrun = B_TRUE;
421                         break;
422                 case '?':
423                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
424                             optopt);
425                         usage(B_FALSE);
426                 }
427         }
428
429         argc -= optind;
430         argv += optind;
431
432         /* get pool name and check number of arguments */
433         if (argc < 1) {
434                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
435                 usage(B_FALSE);
436         }
437         if (argc < 2) {
438                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
439                 usage(B_FALSE);
440         }
441
442         poolname = argv[0];
443
444         argc--;
445         argv++;
446
447         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
448                 return (1);
449
450         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
451                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
452                     poolname);
453                 zpool_close(zhp);
454                 return (1);
455         }
456
457         /* pass off to get_vdev_spec for processing */
458         nvroot = make_root_vdev(zhp, force, !force, B_FALSE, argc, argv);
459         if (nvroot == NULL) {
460                 zpool_close(zhp);
461                 return (1);
462         }
463
464         if (dryrun) {
465                 nvlist_t *poolnvroot;
466
467                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
468                     &poolnvroot) == 0);
469
470                 (void) printf(gettext("would update '%s' to the following "
471                     "configuration:\n"), zpool_get_name(zhp));
472
473                 /* print original main pool and new tree */
474                 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
475                 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
476
477                 /* Do the same for the logs */
478                 if (num_logs(poolnvroot) > 0) {
479                         print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
480                         print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
481                 } else if (num_logs(nvroot) > 0) {
482                         print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
483                 }
484
485                 ret = 0;
486         } else {
487                 ret = (zpool_add(zhp, nvroot) != 0);
488         }
489
490         nvlist_free(nvroot);
491         zpool_close(zhp);
492
493         return (ret);
494 }
495
496 /*
497  * zpool remove <pool> <vdev> ...
498  *
499  * Removes the given vdev from the pool.  Currently, this only supports removing
500  * spares and cache devices from the pool.  Eventually, we'll want to support
501  * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
502  */
503 int
504 zpool_do_remove(int argc, char **argv)
505 {
506         char *poolname;
507         int i, ret = 0;
508         zpool_handle_t *zhp;
509
510         argc--;
511         argv++;
512
513         /* get pool name and check number of arguments */
514         if (argc < 1) {
515                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
516                 usage(B_FALSE);
517         }
518         if (argc < 2) {
519                 (void) fprintf(stderr, gettext("missing device\n"));
520                 usage(B_FALSE);
521         }
522
523         poolname = argv[0];
524
525         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
526                 return (1);
527
528         for (i = 1; i < argc; i++) {
529                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
530                         ret = 1;
531         }
532
533         return (ret);
534 }
535
536 /*
537  * zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint]
538  *              <pool> <dev> ...
539  *
540  *      -f      Force creation, even if devices appear in use
541  *      -n      Do not create the pool, but display the resulting layout if it
542  *              were to be created.
543  *      -R      Create a pool under an alternate root
544  *      -m      Set default mountpoint for the root dataset.  By default it's
545  *              '/<pool>'
546  *      -o      Set property=value.
547  *
548  * Creates the named pool according to the given vdev specification.  The
549  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
550  * we get the nvlist back from get_vdev_spec(), we either print out the contents
551  * (if '-n' was specified), or pass it to libzfs to do the creation.
552  */
553 int
554 zpool_do_create(int argc, char **argv)
555 {
556         boolean_t force = B_FALSE;
557         boolean_t dryrun = B_FALSE;
558         int c;
559         nvlist_t *nvroot = NULL;
560         char *poolname;
561         int ret = 1;
562         char *altroot = NULL;
563         char *mountpoint = NULL;
564         nvlist_t *props = NULL;
565         char *propval;
566
567         /* check options */
568         while ((c = getopt(argc, argv, ":fnR:m:o:")) != -1) {
569                 switch (c) {
570                 case 'f':
571                         force = B_TRUE;
572                         break;
573                 case 'n':
574                         dryrun = B_TRUE;
575                         break;
576                 case 'R':
577                         altroot = optarg;
578                         if (add_prop_list(zpool_prop_to_name(
579                             ZPOOL_PROP_ALTROOT), optarg, &props))
580                                 goto errout;
581                         if (nvlist_lookup_string(props,
582                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
583                             &propval) == 0)
584                                 break;
585                         if (add_prop_list(zpool_prop_to_name(
586                             ZPOOL_PROP_CACHEFILE), "none", &props))
587                                 goto errout;
588                         break;
589                 case 'm':
590                         mountpoint = optarg;
591                         break;
592                 case 'o':
593                         if ((propval = strchr(optarg, '=')) == NULL) {
594                                 (void) fprintf(stderr, gettext("missing "
595                                     "'=' for -o option\n"));
596                                 goto errout;
597                         }
598                         *propval = '\0';
599                         propval++;
600
601                         if (add_prop_list(optarg, propval, &props))
602                                 goto errout;
603                         break;
604                 case ':':
605                         (void) fprintf(stderr, gettext("missing argument for "
606                             "'%c' option\n"), optopt);
607                         goto badusage;
608                 case '?':
609                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
610                             optopt);
611                         goto badusage;
612                 }
613         }
614
615         argc -= optind;
616         argv += optind;
617
618         /* get pool name and check number of arguments */
619         if (argc < 1) {
620                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
621                 goto badusage;
622         }
623         if (argc < 2) {
624                 (void) fprintf(stderr, gettext("missing vdev specification\n"));
625                 goto badusage;
626         }
627
628         poolname = argv[0];
629
630         /*
631          * As a special case, check for use of '/' in the name, and direct the
632          * user to use 'zfs create' instead.
633          */
634         if (strchr(poolname, '/') != NULL) {
635                 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
636                     "character '/' in pool name\n"), poolname);
637                 (void) fprintf(stderr, gettext("use 'zfs create' to "
638                     "create a dataset\n"));
639                 goto errout;
640         }
641
642         /* pass off to get_vdev_spec for bulk processing */
643         nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
644             argv + 1);
645         if (nvroot == NULL)
646                 return (1);
647
648         /* make_root_vdev() allows 0 toplevel children if there are spares */
649         if (!zfs_allocatable_devs(nvroot)) {
650                 (void) fprintf(stderr, gettext("invalid vdev "
651                     "specification: at least one toplevel vdev must be "
652                     "specified\n"));
653                 goto errout;
654         }
655
656
657         if (altroot != NULL && altroot[0] != '/') {
658                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
659                     "must be an absolute path\n"), altroot);
660                 goto errout;
661         }
662
663         /*
664          * Check the validity of the mountpoint and direct the user to use the
665          * '-m' mountpoint option if it looks like its in use.
666          */
667         if (mountpoint == NULL ||
668             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
669             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
670                 char buf[MAXPATHLEN];
671                 DIR *dirp;
672
673                 if (mountpoint && mountpoint[0] != '/') {
674                         (void) fprintf(stderr, gettext("invalid mountpoint "
675                             "'%s': must be an absolute path, 'legacy', or "
676                             "'none'\n"), mountpoint);
677                         goto errout;
678                 }
679
680                 if (mountpoint == NULL) {
681                         if (altroot != NULL)
682                                 (void) snprintf(buf, sizeof (buf), "%s/%s",
683                                     altroot, poolname);
684                         else
685                                 (void) snprintf(buf, sizeof (buf), "/%s",
686                                     poolname);
687                 } else {
688                         if (altroot != NULL)
689                                 (void) snprintf(buf, sizeof (buf), "%s%s",
690                                     altroot, mountpoint);
691                         else
692                                 (void) snprintf(buf, sizeof (buf), "%s",
693                                     mountpoint);
694                 }
695
696                 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
697                         (void) fprintf(stderr, gettext("mountpoint '%s' : "
698                             "%s\n"), buf, strerror(errno));
699                         (void) fprintf(stderr, gettext("use '-m' "
700                             "option to provide a different default\n"));
701                         goto errout;
702                 } else if (dirp) {
703                         int count = 0;
704
705                         while (count < 3 && readdir(dirp) != NULL)
706                                 count++;
707                         (void) closedir(dirp);
708
709                         if (count > 2) {
710                                 (void) fprintf(stderr, gettext("mountpoint "
711                                     "'%s' exists and is not empty\n"), buf);
712                                 (void) fprintf(stderr, gettext("use '-m' "
713                                     "option to provide a "
714                                     "different default\n"));
715                                 goto errout;
716                         }
717                 }
718         }
719
720         if (dryrun) {
721                 /*
722                  * For a dry run invocation, print out a basic message and run
723                  * through all the vdevs in the list and print out in an
724                  * appropriate hierarchy.
725                  */
726                 (void) printf(gettext("would create '%s' with the "
727                     "following layout:\n\n"), poolname);
728
729                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
730                 if (num_logs(nvroot) > 0)
731                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
732
733                 ret = 0;
734         } else {
735                 /*
736                  * Hand off to libzfs.
737                  */
738                 if (zpool_create(g_zfs, poolname, nvroot, props) == 0) {
739                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
740                             ZFS_TYPE_FILESYSTEM);
741                         if (pool != NULL) {
742                                 if (mountpoint != NULL)
743                                         verify(zfs_prop_set(pool,
744                                             zfs_prop_to_name(
745                                             ZFS_PROP_MOUNTPOINT),
746                                             mountpoint) == 0);
747                                 if (zfs_mount(pool, NULL, 0) == 0)
748                                         ret = zfs_shareall(pool);
749                                 zfs_close(pool);
750                         }
751                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
752                         (void) fprintf(stderr, gettext("pool name may have "
753                             "been omitted\n"));
754                 }
755         }
756
757 errout:
758         nvlist_free(nvroot);
759         nvlist_free(props);
760         return (ret);
761 badusage:
762         nvlist_free(props);
763         usage(B_FALSE);
764         return (2);
765 }
766
767 /*
768  * zpool destroy <pool>
769  *
770  *      -f      Forcefully unmount any datasets
771  *
772  * Destroy the given pool.  Automatically unmounts any datasets in the pool.
773  */
774 int
775 zpool_do_destroy(int argc, char **argv)
776 {
777         boolean_t force = B_FALSE;
778         int c;
779         char *pool;
780         zpool_handle_t *zhp;
781         int ret;
782
783         /* check options */
784         while ((c = getopt(argc, argv, "f")) != -1) {
785                 switch (c) {
786                 case 'f':
787                         force = B_TRUE;
788                         break;
789                 case '?':
790                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
791                             optopt);
792                         usage(B_FALSE);
793                 }
794         }
795
796         argc -= optind;
797         argv += optind;
798
799         /* check arguments */
800         if (argc < 1) {
801                 (void) fprintf(stderr, gettext("missing pool argument\n"));
802                 usage(B_FALSE);
803         }
804         if (argc > 1) {
805                 (void) fprintf(stderr, gettext("too many arguments\n"));
806                 usage(B_FALSE);
807         }
808
809         pool = argv[0];
810
811         if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
812                 /*
813                  * As a special case, check for use of '/' in the name, and
814                  * direct the user to use 'zfs destroy' instead.
815                  */
816                 if (strchr(pool, '/') != NULL)
817                         (void) fprintf(stderr, gettext("use 'zfs destroy' to "
818                             "destroy a dataset\n"));
819                 return (1);
820         }
821
822         if (zpool_disable_datasets(zhp, force) != 0) {
823                 (void) fprintf(stderr, gettext("could not destroy '%s': "
824                     "could not unmount datasets\n"), zpool_get_name(zhp));
825                 return (1);
826         }
827
828         ret = (zpool_destroy(zhp) != 0);
829
830         zpool_close(zhp);
831
832         return (ret);
833 }
834
835 /*
836  * zpool export [-f] <pool> ...
837  *
838  *      -f      Forcefully unmount datasets
839  *
840  * Export the given pools.  By default, the command will attempt to cleanly
841  * unmount any active datasets within the pool.  If the '-f' flag is specified,
842  * then the datasets will be forcefully unmounted.
843  */
844 int
845 zpool_do_export(int argc, char **argv)
846 {
847         boolean_t force = B_FALSE;
848         int c;
849         zpool_handle_t *zhp;
850         int ret;
851         int i;
852
853         /* check options */
854         while ((c = getopt(argc, argv, "f")) != -1) {
855                 switch (c) {
856                 case 'f':
857                         force = B_TRUE;
858                         break;
859                 case '?':
860                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
861                             optopt);
862                         usage(B_FALSE);
863                 }
864         }
865
866         argc -= optind;
867         argv += optind;
868
869         /* check arguments */
870         if (argc < 1) {
871                 (void) fprintf(stderr, gettext("missing pool argument\n"));
872                 usage(B_FALSE);
873         }
874
875         ret = 0;
876         for (i = 0; i < argc; i++) {
877                 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
878                         ret = 1;
879                         continue;
880                 }
881
882                 if (zpool_disable_datasets(zhp, force) != 0) {
883                         ret = 1;
884                         zpool_close(zhp);
885                         continue;
886                 }
887
888                 if (zpool_export(zhp) != 0)
889                         ret = 1;
890
891                 zpool_close(zhp);
892         }
893
894         return (ret);
895 }
896
897 /*
898  * Given a vdev configuration, determine the maximum width needed for the device
899  * name column.
900  */
901 static int
902 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
903 {
904         char *name = zpool_vdev_name(g_zfs, zhp, nv);
905         nvlist_t **child;
906         uint_t c, children;
907         int ret;
908
909         if (strlen(name) + depth > max)
910                 max = strlen(name) + depth;
911
912         free(name);
913
914         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
915             &child, &children) == 0) {
916                 for (c = 0; c < children; c++)
917                         if ((ret = max_width(zhp, child[c], depth + 2,
918                             max)) > max)
919                                 max = ret;
920         }
921
922         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
923             &child, &children) == 0) {
924                 for (c = 0; c < children; c++)
925                         if ((ret = max_width(zhp, child[c], depth + 2,
926                             max)) > max)
927                                 max = ret;
928         }
929
930         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
931             &child, &children) == 0) {
932                 for (c = 0; c < children; c++)
933                         if ((ret = max_width(zhp, child[c], depth + 2,
934                             max)) > max)
935                                 max = ret;
936         }
937
938
939         return (max);
940 }
941
942
943 /*
944  * Print the configuration of an exported pool.  Iterate over all vdevs in the
945  * pool, printing out the name and status for each one.
946  */
947 void
948 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
949     boolean_t print_logs)
950 {
951         nvlist_t **child;
952         uint_t c, children;
953         vdev_stat_t *vs;
954         char *type, *vname;
955
956         verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
957         if (strcmp(type, VDEV_TYPE_MISSING) == 0)
958                 return;
959
960         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
961             (uint64_t **)&vs, &c) == 0);
962
963         (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
964         (void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
965
966         if (vs->vs_aux != 0) {
967                 (void) printf("  ");
968
969                 switch (vs->vs_aux) {
970                 case VDEV_AUX_OPEN_FAILED:
971                         (void) printf(gettext("cannot open"));
972                         break;
973
974                 case VDEV_AUX_BAD_GUID_SUM:
975                         (void) printf(gettext("missing device"));
976                         break;
977
978                 case VDEV_AUX_NO_REPLICAS:
979                         (void) printf(gettext("insufficient replicas"));
980                         break;
981
982                 case VDEV_AUX_VERSION_NEWER:
983                         (void) printf(gettext("newer version"));
984                         break;
985
986                 case VDEV_AUX_ERR_EXCEEDED:
987                         (void) printf(gettext("too many errors"));
988                         break;
989
990                 default:
991                         (void) printf(gettext("corrupted data"));
992                         break;
993                 }
994         }
995         (void) printf("\n");
996
997         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
998             &child, &children) != 0)
999                 return;
1000
1001         for (c = 0; c < children; c++) {
1002                 uint64_t is_log = B_FALSE;
1003
1004                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1005                     &is_log);
1006                 if ((is_log && !print_logs) || (!is_log && print_logs))
1007                         continue;
1008
1009                 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1010                 print_import_config(vname, child[c],
1011                     namewidth, depth + 2, B_FALSE);
1012                 free(vname);
1013         }
1014
1015         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1016             &child, &children) == 0) {
1017                 (void) printf(gettext("\tcache\n"));
1018                 for (c = 0; c < children; c++) {
1019                         vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1020                         (void) printf("\t  %s\n", vname);
1021                         free(vname);
1022                 }
1023         }
1024
1025         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1026             &child, &children) == 0) {
1027                 (void) printf(gettext("\tspares\n"));
1028                 for (c = 0; c < children; c++) {
1029                         vname = zpool_vdev_name(g_zfs, NULL, child[c]);
1030                         (void) printf("\t  %s\n", vname);
1031                         free(vname);
1032                 }
1033         }
1034 }
1035
1036 /*
1037  * Display the status for the given pool.
1038  */
1039 static void
1040 show_import(nvlist_t *config)
1041 {
1042         uint64_t pool_state;
1043         vdev_stat_t *vs;
1044         char *name;
1045         uint64_t guid;
1046         char *msgid;
1047         nvlist_t *nvroot;
1048         int reason;
1049         const char *health;
1050         uint_t vsc;
1051         int namewidth;
1052
1053         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1054             &name) == 0);
1055         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1056             &guid) == 0);
1057         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1058             &pool_state) == 0);
1059         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1060             &nvroot) == 0);
1061
1062         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
1063             (uint64_t **)&vs, &vsc) == 0);
1064         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1065
1066         reason = zpool_import_status(config, &msgid);
1067
1068         (void) printf(gettext("  pool: %s\n"), name);
1069         (void) printf(gettext("    id: %llu\n"), (u_longlong_t)guid);
1070         (void) printf(gettext(" state: %s"), health);
1071         if (pool_state == POOL_STATE_DESTROYED)
1072                 (void) printf(gettext(" (DESTROYED)"));
1073         (void) printf("\n");
1074
1075         switch (reason) {
1076         case ZPOOL_STATUS_MISSING_DEV_R:
1077         case ZPOOL_STATUS_MISSING_DEV_NR:
1078         case ZPOOL_STATUS_BAD_GUID_SUM:
1079                 (void) printf(gettext("status: One or more devices are missing "
1080                     "from the system.\n"));
1081                 break;
1082
1083         case ZPOOL_STATUS_CORRUPT_LABEL_R:
1084         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1085                 (void) printf(gettext("status: One or more devices contains "
1086                     "corrupted data.\n"));
1087                 break;
1088
1089         case ZPOOL_STATUS_CORRUPT_DATA:
1090                 (void) printf(gettext("status: The pool data is corrupted.\n"));
1091                 break;
1092
1093         case ZPOOL_STATUS_OFFLINE_DEV:
1094                 (void) printf(gettext("status: One or more devices "
1095                     "are offlined.\n"));
1096                 break;
1097
1098         case ZPOOL_STATUS_CORRUPT_POOL:
1099                 (void) printf(gettext("status: The pool metadata is "
1100                     "corrupted.\n"));
1101                 break;
1102
1103         case ZPOOL_STATUS_VERSION_OLDER:
1104                 (void) printf(gettext("status: The pool is formatted using an "
1105                     "older on-disk version.\n"));
1106                 break;
1107
1108         case ZPOOL_STATUS_VERSION_NEWER:
1109                 (void) printf(gettext("status: The pool is formatted using an "
1110                     "incompatible version.\n"));
1111                 break;
1112         case ZPOOL_STATUS_HOSTID_MISMATCH:
1113                 (void) printf(gettext("status: The pool was last accessed by "
1114                     "another system.\n"));
1115                 break;
1116         case ZPOOL_STATUS_FAULTED_DEV_R:
1117         case ZPOOL_STATUS_FAULTED_DEV_NR:
1118                 (void) printf(gettext("status: One or more devices are "
1119                     "faulted.\n"));
1120                 break;
1121
1122         default:
1123                 /*
1124                  * No other status can be seen when importing pools.
1125                  */
1126                 assert(reason == ZPOOL_STATUS_OK);
1127         }
1128
1129         /*
1130          * Print out an action according to the overall state of the pool.
1131          */
1132         if (vs->vs_state == VDEV_STATE_HEALTHY) {
1133                 if (reason == ZPOOL_STATUS_VERSION_OLDER)
1134                         (void) printf(gettext("action: The pool can be "
1135                             "imported using its name or numeric identifier, "
1136                             "though\n\tsome features will not be available "
1137                             "without an explicit 'zpool upgrade'.\n"));
1138                 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1139                         (void) printf(gettext("action: The pool can be "
1140                             "imported using its name or numeric "
1141                             "identifier and\n\tthe '-f' flag.\n"));
1142                 else
1143                         (void) printf(gettext("action: The pool can be "
1144                             "imported using its name or numeric "
1145                             "identifier.\n"));
1146         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1147                 (void) printf(gettext("action: The pool can be imported "
1148                     "despite missing or damaged devices.  The\n\tfault "
1149                     "tolerance of the pool may be compromised if imported.\n"));
1150         } else {
1151                 switch (reason) {
1152                 case ZPOOL_STATUS_VERSION_NEWER:
1153                         (void) printf(gettext("action: The pool cannot be "
1154                             "imported.  Access the pool on a system running "
1155                             "newer\n\tsoftware, or recreate the pool from "
1156                             "backup.\n"));
1157                         break;
1158                 case ZPOOL_STATUS_MISSING_DEV_R:
1159                 case ZPOOL_STATUS_MISSING_DEV_NR:
1160                 case ZPOOL_STATUS_BAD_GUID_SUM:
1161                         (void) printf(gettext("action: The pool cannot be "
1162                             "imported. Attach the missing\n\tdevices and try "
1163                             "again.\n"));
1164                         break;
1165                 default:
1166                         (void) printf(gettext("action: The pool cannot be "
1167                             "imported due to damaged devices or data.\n"));
1168                 }
1169         }
1170
1171         /*
1172          * If the state is "closed" or "can't open", and the aux state
1173          * is "corrupt data":
1174          */
1175         if (((vs->vs_state == VDEV_STATE_CLOSED) ||
1176             (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
1177             (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
1178                 if (pool_state == POOL_STATE_DESTROYED)
1179                         (void) printf(gettext("\tThe pool was destroyed, "
1180                             "but can be imported using the '-Df' flags.\n"));
1181                 else if (pool_state != POOL_STATE_EXPORTED)
1182                         (void) printf(gettext("\tThe pool may be active on "
1183                             "another system, but can be imported using\n\t"
1184                             "the '-f' flag.\n"));
1185         }
1186
1187         if (msgid != NULL)
1188                 (void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
1189                     msgid);
1190
1191         (void) printf(gettext("config:\n\n"));
1192
1193         namewidth = max_width(NULL, nvroot, 0, 0);
1194         if (namewidth < 10)
1195                 namewidth = 10;
1196
1197         print_import_config(name, nvroot, namewidth, 0, B_FALSE);
1198         if (num_logs(nvroot) > 0) {
1199                 (void) printf(gettext("\tlogs\n"));
1200                 print_import_config(name, nvroot, namewidth, 0, B_TRUE);
1201         }
1202
1203         if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
1204                 (void) printf(gettext("\n\tAdditional devices are known to "
1205                     "be part of this pool, though their\n\texact "
1206                     "configuration cannot be determined.\n"));
1207         }
1208 }
1209
1210 /*
1211  * Perform the import for the given configuration.  This passes the heavy
1212  * lifting off to zpool_import_props(), and then mounts the datasets contained
1213  * within the pool.
1214  */
1215 static int
1216 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1217     int force, nvlist_t *props)
1218 {
1219         zpool_handle_t *zhp;
1220         char *name;
1221         uint64_t state;
1222         uint64_t version;
1223         int error = 0;
1224
1225         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1226             &name) == 0);
1227
1228         verify(nvlist_lookup_uint64(config,
1229             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1230         verify(nvlist_lookup_uint64(config,
1231             ZPOOL_CONFIG_VERSION, &version) == 0);
1232         if (version > SPA_VERSION) {
1233                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1234                     "is formatted using a newer ZFS version\n"), name);
1235                 return (1);
1236         } else if (state != POOL_STATE_EXPORTED && !force) {
1237                 uint64_t hostid;
1238
1239                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1240                     &hostid) == 0) {
1241                         if ((unsigned long)hostid != gethostid()) {
1242                                 char *hostname;
1243                                 uint64_t timestamp;
1244                                 time_t t;
1245
1246                                 verify(nvlist_lookup_string(config,
1247                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1248                                 verify(nvlist_lookup_uint64(config,
1249                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1250                                 t = timestamp;
1251                                 (void) fprintf(stderr, gettext("cannot import "
1252                                     "'%s': pool may be in use from other "
1253                                     "system, it was last accessed by %s "
1254                                     "(hostid: 0x%lx) on %s"), name, hostname,
1255                                     (unsigned long)hostid,
1256                                     asctime(localtime(&t)));
1257                                 (void) fprintf(stderr, gettext("use '-f' to "
1258                                     "import anyway\n"));
1259                                 return (1);
1260                         }
1261                 } else {
1262                         (void) fprintf(stderr, gettext("cannot import '%s': "
1263                             "pool may be in use from other system\n"), name);
1264                         (void) fprintf(stderr, gettext("use '-f' to import "
1265                             "anyway\n"));
1266                         return (1);
1267                 }
1268         }
1269
1270         if (zpool_import_props(g_zfs, config, newname, props) != 0)
1271                 return (1);
1272
1273         if (newname != NULL)
1274                 name = (char *)newname;
1275
1276         verify((zhp = zpool_open(g_zfs, name)) != NULL);
1277
1278         if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
1279                 zpool_close(zhp);
1280                 return (1);
1281         }
1282
1283         zpool_close(zhp);
1284         return (error);
1285 }
1286
1287 /*
1288  * zpool import [-d dir] [-D]
1289  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1290  *              [-d dir | -c cachefile] [-f] -a
1291  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
1292  *              [-d dir | -c cachefile] [-f] <pool | id> [newpool]
1293  *
1294  *       -c     Read pool information from a cachefile instead of searching
1295  *              devices.
1296  *
1297  *       -d     Scan in a specific directory, other than /dev/dsk.  More than
1298  *              one directory can be specified using multiple '-d' options.
1299  *
1300  *       -D     Scan for previously destroyed pools or import all or only
1301  *              specified destroyed pools.
1302  *
1303  *       -R     Temporarily import the pool, with all mountpoints relative to
1304  *              the given root.  The pool will remain exported when the machine
1305  *              is rebooted.
1306  *
1307  *       -f     Force import, even if it appears that the pool is active.
1308  *
1309  *       -a     Import all pools found.
1310  *
1311  *       -o     Set property=value and/or temporary mount options (without '=').
1312  *
1313  * The import command scans for pools to import, and import pools based on pool
1314  * name and GUID.  The pool can also be renamed as part of the import process.
1315  */
1316 int
1317 zpool_do_import(int argc, char **argv)
1318 {
1319         char **searchdirs = NULL;
1320         int nsearch = 0;
1321         int c;
1322         int err;
1323         nvlist_t *pools = NULL;
1324         boolean_t do_all = B_FALSE;
1325         boolean_t do_destroyed = B_FALSE;
1326         char *mntopts = NULL;
1327         boolean_t do_force = B_FALSE;
1328         nvpair_t *elem;
1329         nvlist_t *config;
1330         uint64_t searchguid;
1331         char *searchname;
1332         char *propval;
1333         nvlist_t *found_config;
1334         nvlist_t *props = NULL;
1335         boolean_t first;
1336         uint64_t pool_state;
1337         char *cachefile = NULL;
1338
1339         /* check options */
1340         while ((c = getopt(argc, argv, ":afc:d:Do:p:R:")) != -1) {
1341                 switch (c) {
1342                 case 'a':
1343                         do_all = B_TRUE;
1344                         break;
1345                 case 'c':
1346                         cachefile = optarg;
1347                         break;
1348                 case 'd':
1349                         if (searchdirs == NULL) {
1350                                 searchdirs = safe_malloc(sizeof (char *));
1351                         } else {
1352                                 char **tmp = safe_malloc((nsearch + 1) *
1353                                     sizeof (char *));
1354                                 bcopy(searchdirs, tmp, nsearch *
1355                                     sizeof (char *));
1356                                 free(searchdirs);
1357                                 searchdirs = tmp;
1358                         }
1359                         searchdirs[nsearch++] = optarg;
1360                         break;
1361                 case 'D':
1362                         do_destroyed = B_TRUE;
1363                         break;
1364                 case 'f':
1365                         do_force = B_TRUE;
1366                         break;
1367                 case 'o':
1368                         if ((propval = strchr(optarg, '=')) != NULL) {
1369                                 *propval = '\0';
1370                                 propval++;
1371                                 if (add_prop_list(optarg, propval, &props))
1372                                         goto error;
1373                         } else {
1374                                 mntopts = optarg;
1375                         }
1376                         break;
1377                 case 'R':
1378                         if (add_prop_list(zpool_prop_to_name(
1379                             ZPOOL_PROP_ALTROOT), optarg, &props))
1380                                 goto error;
1381                         if (nvlist_lookup_string(props,
1382                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1383                             &propval) == 0)
1384                                 break;
1385                         if (add_prop_list(zpool_prop_to_name(
1386                             ZPOOL_PROP_CACHEFILE), "none", &props))
1387                                 goto error;
1388                         break;
1389                 case ':':
1390                         (void) fprintf(stderr, gettext("missing argument for "
1391                             "'%c' option\n"), optopt);
1392                         usage(B_FALSE);
1393                         break;
1394                 case '?':
1395                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1396                             optopt);
1397                         usage(B_FALSE);
1398                 }
1399         }
1400
1401         argc -= optind;
1402         argv += optind;
1403
1404         if (cachefile && nsearch != 0) {
1405                 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1406                 usage(B_FALSE);
1407         }
1408
1409         if (searchdirs == NULL) {
1410                 searchdirs = safe_malloc(sizeof (char *));
1411                 searchdirs[0] = "/dev/dsk";
1412                 nsearch = 1;
1413         }
1414
1415         /* check argument count */
1416         if (do_all) {
1417                 if (argc != 0) {
1418                         (void) fprintf(stderr, gettext("too many arguments\n"));
1419                         usage(B_FALSE);
1420                 }
1421         } else {
1422                 if (argc > 2) {
1423                         (void) fprintf(stderr, gettext("too many arguments\n"));
1424                         usage(B_FALSE);
1425                 }
1426
1427                 /*
1428                  * Check for the SYS_CONFIG privilege.  We do this explicitly
1429                  * here because otherwise any attempt to discover pools will
1430                  * silently fail.
1431                  */
1432                 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1433                         (void) fprintf(stderr, gettext("cannot "
1434                             "discover pools: permission denied\n"));
1435                         free(searchdirs);
1436                         return (1);
1437                 }
1438         }
1439
1440         if (cachefile)
1441                 pools = zpool_find_import_cached(g_zfs, cachefile, B_FALSE);
1442         else
1443                 pools = zpool_find_import(g_zfs, nsearch, searchdirs, B_FALSE);
1444
1445         if (pools == NULL) {
1446                 free(searchdirs);
1447                 return (1);
1448         }
1449
1450         /*
1451          * We now have a list of all available pools in the given directories.
1452          * Depending on the arguments given, we do one of the following:
1453          *
1454          *      <none>  Iterate through all pools and display information about
1455          *              each one.
1456          *
1457          *      -a      Iterate through all pools and try to import each one.
1458          *
1459          *      <id>    Find the pool that corresponds to the given GUID/pool
1460          *              name and import that one.
1461          *
1462          *      -D      Above options applies only to destroyed pools.
1463          */
1464         if (argc != 0) {
1465                 char *endptr;
1466
1467                 errno = 0;
1468                 searchguid = strtoull(argv[0], &endptr, 10);
1469                 if (errno != 0 || *endptr != '\0')
1470                         searchname = argv[0];
1471                 else
1472                         searchname = NULL;
1473                 found_config = NULL;
1474         }
1475
1476         err = 0;
1477         elem = NULL;
1478         first = B_TRUE;
1479         while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1480
1481                 verify(nvpair_value_nvlist(elem, &config) == 0);
1482
1483                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1484                     &pool_state) == 0);
1485                 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1486                         continue;
1487                 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1488                         continue;
1489
1490                 if (argc == 0) {
1491                         if (first)
1492                                 first = B_FALSE;
1493                         else if (!do_all)
1494                                 (void) printf("\n");
1495
1496                         if (do_all)
1497                                 err |= do_import(config, NULL, mntopts,
1498                                     do_force, props);
1499                         else
1500                                 show_import(config);
1501                 } else if (searchname != NULL) {
1502                         char *name;
1503
1504                         /*
1505                          * We are searching for a pool based on name.
1506                          */
1507                         verify(nvlist_lookup_string(config,
1508                             ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1509
1510                         if (strcmp(name, searchname) == 0) {
1511                                 if (found_config != NULL) {
1512                                         (void) fprintf(stderr, gettext(
1513                                             "cannot import '%s': more than "
1514                                             "one matching pool\n"), searchname);
1515                                         (void) fprintf(stderr, gettext(
1516                                             "import by numeric ID instead\n"));
1517                                         err = B_TRUE;
1518                                 }
1519                                 found_config = config;
1520                         }
1521                 } else {
1522                         uint64_t guid;
1523
1524                         /*
1525                          * Search for a pool by guid.
1526                          */
1527                         verify(nvlist_lookup_uint64(config,
1528                             ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1529
1530                         if (guid == searchguid)
1531                                 found_config = config;
1532                 }
1533         }
1534
1535         /*
1536          * If we were searching for a specific pool, verify that we found a
1537          * pool, and then do the import.
1538          */
1539         if (argc != 0 && err == 0) {
1540                 if (found_config == NULL) {
1541                         (void) fprintf(stderr, gettext("cannot import '%s': "
1542                             "no such pool available\n"), argv[0]);
1543                         err = B_TRUE;
1544                 } else {
1545                         err |= do_import(found_config, argc == 1 ? NULL :
1546                             argv[1], mntopts, do_force, props);
1547                 }
1548         }
1549
1550         /*
1551          * If we were just looking for pools, report an error if none were
1552          * found.
1553          */
1554         if (argc == 0 && first)
1555                 (void) fprintf(stderr,
1556                     gettext("no pools available to import\n"));
1557
1558 error:
1559         nvlist_free(props);
1560         nvlist_free(pools);
1561         free(searchdirs);
1562
1563         return (err ? 1 : 0);
1564 }
1565
1566 typedef struct iostat_cbdata {
1567         zpool_list_t *cb_list;
1568         int cb_verbose;
1569         int cb_iteration;
1570         int cb_namewidth;
1571 } iostat_cbdata_t;
1572
1573 static void
1574 print_iostat_separator(iostat_cbdata_t *cb)
1575 {
1576         int i = 0;
1577
1578         for (i = 0; i < cb->cb_namewidth; i++)
1579                 (void) printf("-");
1580         (void) printf("  -----  -----  -----  -----  -----  -----\n");
1581 }
1582
1583 static void
1584 print_iostat_header(iostat_cbdata_t *cb)
1585 {
1586         (void) printf("%*s     capacity     operations    bandwidth\n",
1587             cb->cb_namewidth, "");
1588         (void) printf("%-*s   used  avail   read  write   read  write\n",
1589             cb->cb_namewidth, "pool");
1590         print_iostat_separator(cb);
1591 }
1592
1593 /*
1594  * Display a single statistic.
1595  */
1596 static void
1597 print_one_stat(uint64_t value)
1598 {
1599         char buf[64];
1600
1601         zfs_nicenum(value, buf, sizeof (buf));
1602         (void) printf("  %5s", buf);
1603 }
1604
1605 /*
1606  * Print out all the statistics for the given vdev.  This can either be the
1607  * toplevel configuration, or called recursively.  If 'name' is NULL, then this
1608  * is a verbose output, and we don't want to display the toplevel pool stats.
1609  */
1610 void
1611 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1612     nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1613 {
1614         nvlist_t **oldchild, **newchild;
1615         uint_t c, children;
1616         vdev_stat_t *oldvs, *newvs;
1617         vdev_stat_t zerovs = { 0 };
1618         uint64_t tdelta;
1619         double scale;
1620         char *vname;
1621
1622         if (oldnv != NULL) {
1623                 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1624                     (uint64_t **)&oldvs, &c) == 0);
1625         } else {
1626                 oldvs = &zerovs;
1627         }
1628
1629         verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1630             (uint64_t **)&newvs, &c) == 0);
1631
1632         if (strlen(name) + depth > cb->cb_namewidth)
1633                 (void) printf("%*s%s", depth, "", name);
1634         else
1635                 (void) printf("%*s%s%*s", depth, "", name,
1636                     (int)(cb->cb_namewidth - strlen(name) - depth), "");
1637
1638         tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1639
1640         if (tdelta == 0)
1641                 scale = 1.0;
1642         else
1643                 scale = (double)NANOSEC / tdelta;
1644
1645         /* only toplevel vdevs have capacity stats */
1646         if (newvs->vs_space == 0) {
1647                 (void) printf("      -      -");
1648         } else {
1649                 print_one_stat(newvs->vs_alloc);
1650                 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1651         }
1652
1653         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1654             oldvs->vs_ops[ZIO_TYPE_READ])));
1655
1656         print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1657             oldvs->vs_ops[ZIO_TYPE_WRITE])));
1658
1659         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1660             oldvs->vs_bytes[ZIO_TYPE_READ])));
1661
1662         print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1663             oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1664
1665         (void) printf("\n");
1666
1667         if (!cb->cb_verbose)
1668                 return;
1669
1670         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1671             &newchild, &children) != 0)
1672                 return;
1673
1674         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1675             &oldchild, &c) != 0)
1676                 return;
1677
1678         for (c = 0; c < children; c++) {
1679                 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1680                 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1681                     newchild[c], cb, depth + 2);
1682                 free(vname);
1683         }
1684
1685         /*
1686          * Include level 2 ARC devices in iostat output
1687          */
1688         if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1689             &newchild, &children) != 0)
1690                 return;
1691
1692         if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1693             &oldchild, &c) != 0)
1694                 return;
1695
1696         if (children > 0) {
1697                 (void) printf("%-*s      -      -      -      -      -      "
1698                     "-\n", cb->cb_namewidth, "cache");
1699                 for (c = 0; c < children; c++) {
1700                         vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1701                         print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1702                             newchild[c], cb, depth + 2);
1703                         free(vname);
1704                 }
1705         }
1706 }
1707
1708 static int
1709 refresh_iostat(zpool_handle_t *zhp, void *data)
1710 {
1711         iostat_cbdata_t *cb = data;
1712         boolean_t missing;
1713
1714         /*
1715          * If the pool has disappeared, remove it from the list and continue.
1716          */
1717         if (zpool_refresh_stats(zhp, &missing) != 0)
1718                 return (-1);
1719
1720         if (missing)
1721                 pool_list_remove(cb->cb_list, zhp);
1722
1723         return (0);
1724 }
1725
1726 /*
1727  * Callback to print out the iostats for the given pool.
1728  */
1729 int
1730 print_iostat(zpool_handle_t *zhp, void *data)
1731 {
1732         iostat_cbdata_t *cb = data;
1733         nvlist_t *oldconfig, *newconfig;
1734         nvlist_t *oldnvroot, *newnvroot;
1735
1736         newconfig = zpool_get_config(zhp, &oldconfig);
1737
1738         if (cb->cb_iteration == 1)
1739                 oldconfig = NULL;
1740
1741         verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
1742             &newnvroot) == 0);
1743
1744         if (oldconfig == NULL)
1745                 oldnvroot = NULL;
1746         else
1747                 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
1748                     &oldnvroot) == 0);
1749
1750         /*
1751          * Print out the statistics for the pool.
1752          */
1753         print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
1754
1755         if (cb->cb_verbose)
1756                 print_iostat_separator(cb);
1757
1758         return (0);
1759 }
1760
1761 int
1762 get_namewidth(zpool_handle_t *zhp, void *data)
1763 {
1764         iostat_cbdata_t *cb = data;
1765         nvlist_t *config, *nvroot;
1766
1767         if ((config = zpool_get_config(zhp, NULL)) != NULL) {
1768                 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1769                     &nvroot) == 0);
1770                 if (!cb->cb_verbose)
1771                         cb->cb_namewidth = strlen(zpool_get_name(zhp));
1772                 else
1773                         cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
1774         }
1775
1776         /*
1777          * The width must fall into the range [10,38].  The upper limit is the
1778          * maximum we can have and still fit in 80 columns.
1779          */
1780         if (cb->cb_namewidth < 10)
1781                 cb->cb_namewidth = 10;
1782         if (cb->cb_namewidth > 38)
1783                 cb->cb_namewidth = 38;
1784
1785         return (0);
1786 }
1787
1788 /*
1789  * zpool iostat [-v] [pool] ... [interval [count]]
1790  *
1791  *      -v      Display statistics for individual vdevs
1792  *
1793  * This command can be tricky because we want to be able to deal with pool
1794  * creation/destruction as well as vdev configuration changes.  The bulk of this
1795  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
1796  * on pool_list_update() to detect the addition of new pools.  Configuration
1797  * changes are all handled within libzfs.
1798  */
1799 int
1800 zpool_do_iostat(int argc, char **argv)
1801 {
1802         int c;
1803         int ret;
1804         int npools;
1805         unsigned long interval = 0, count = 0;
1806         zpool_list_t *list;
1807         boolean_t verbose = B_FALSE;
1808         iostat_cbdata_t cb;
1809
1810         /* check options */
1811         while ((c = getopt(argc, argv, "v")) != -1) {
1812                 switch (c) {
1813                 case 'v':
1814                         verbose = B_TRUE;
1815                         break;
1816                 case '?':
1817                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1818                             optopt);
1819                         usage(B_FALSE);
1820                 }
1821         }
1822
1823         argc -= optind;
1824         argv += optind;
1825
1826         /*
1827          * Determine if the last argument is an integer or a pool name
1828          */
1829         if (argc > 0 && isdigit(argv[argc - 1][0])) {
1830                 char *end;
1831
1832                 errno = 0;
1833                 interval = strtoul(argv[argc - 1], &end, 10);
1834
1835                 if (*end == '\0' && errno == 0) {
1836                         if (interval == 0) {
1837                                 (void) fprintf(stderr, gettext("interval "
1838                                     "cannot be zero\n"));
1839                                 usage(B_FALSE);
1840                         }
1841
1842                         /*
1843                          * Ignore the last parameter
1844                          */
1845                         argc--;
1846                 } else {
1847                         /*
1848                          * If this is not a valid number, just plow on.  The
1849                          * user will get a more informative error message later
1850                          * on.
1851                          */
1852                         interval = 0;
1853                 }
1854         }
1855
1856         /*
1857          * If the last argument is also an integer, then we have both a count
1858          * and an integer.
1859          */
1860         if (argc > 0 && isdigit(argv[argc - 1][0])) {
1861                 char *end;
1862
1863                 errno = 0;
1864                 count = interval;
1865                 interval = strtoul(argv[argc - 1], &end, 10);
1866
1867                 if (*end == '\0' && errno == 0) {
1868                         if (interval == 0) {
1869                                 (void) fprintf(stderr, gettext("interval "
1870                                     "cannot be zero\n"));
1871                                 usage(B_FALSE);
1872                         }
1873
1874                         /*
1875                          * Ignore the last parameter
1876                          */
1877                         argc--;
1878                 } else {
1879                         interval = 0;
1880                 }
1881         }
1882
1883         /*
1884          * Construct the list of all interesting pools.
1885          */
1886         ret = 0;
1887         if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
1888                 return (1);
1889
1890         if (pool_list_count(list) == 0 && argc != 0) {
1891                 pool_list_free(list);
1892                 return (1);
1893         }
1894
1895         if (pool_list_count(list) == 0 && interval == 0) {
1896                 pool_list_free(list);
1897                 (void) fprintf(stderr, gettext("no pools available\n"));
1898                 return (1);
1899         }
1900
1901         /*
1902          * Enter the main iostat loop.
1903          */
1904         cb.cb_list = list;
1905         cb.cb_verbose = verbose;
1906         cb.cb_iteration = 0;
1907         cb.cb_namewidth = 0;
1908
1909         for (;;) {
1910                 pool_list_update(list);
1911
1912                 if ((npools = pool_list_count(list)) == 0)
1913                         break;
1914
1915                 /*
1916                  * Refresh all statistics.  This is done as an explicit step
1917                  * before calculating the maximum name width, so that any
1918                  * configuration changes are properly accounted for.
1919                  */
1920                 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
1921
1922                 /*
1923                  * Iterate over all pools to determine the maximum width
1924                  * for the pool / device name column across all pools.
1925                  */
1926                 cb.cb_namewidth = 0;
1927                 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
1928
1929                 /*
1930                  * If it's the first time, or verbose mode, print the header.
1931                  */
1932                 if (++cb.cb_iteration == 1 || verbose)
1933                         print_iostat_header(&cb);
1934
1935                 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
1936
1937                 /*
1938                  * If there's more than one pool, and we're not in verbose mode
1939                  * (which prints a separator for us), then print a separator.
1940                  */
1941                 if (npools > 1 && !verbose)
1942                         print_iostat_separator(&cb);
1943
1944                 if (verbose)
1945                         (void) printf("\n");
1946
1947                 /*
1948                  * Flush the output so that redirection to a file isn't buffered
1949                  * indefinitely.
1950                  */
1951                 (void) fflush(stdout);
1952
1953                 if (interval == 0)
1954                         break;
1955
1956                 if (count != 0 && --count == 0)
1957                         break;
1958
1959                 (void) sleep(interval);
1960         }
1961
1962         pool_list_free(list);
1963
1964         return (ret);
1965 }
1966
1967 typedef struct list_cbdata {
1968         boolean_t       cb_scripted;
1969         boolean_t       cb_first;
1970         zprop_list_t    *cb_proplist;
1971 } list_cbdata_t;
1972
1973 /*
1974  * Given a list of columns to display, output appropriate headers for each one.
1975  */
1976 static void
1977 print_header(zprop_list_t *pl)
1978 {
1979         const char *header;
1980         boolean_t first = B_TRUE;
1981         boolean_t right_justify;
1982
1983         for (; pl != NULL; pl = pl->pl_next) {
1984                 if (pl->pl_prop == ZPROP_INVAL)
1985                         continue;
1986
1987                 if (!first)
1988                         (void) printf("  ");
1989                 else
1990                         first = B_FALSE;
1991
1992                 header = zpool_prop_column_name(pl->pl_prop);
1993                 right_justify = zpool_prop_align_right(pl->pl_prop);
1994
1995                 if (pl->pl_next == NULL && !right_justify)
1996                         (void) printf("%s", header);
1997                 else if (right_justify)
1998                         (void) printf("%*s", pl->pl_width, header);
1999                 else
2000                         (void) printf("%-*s", pl->pl_width, header);
2001         }
2002
2003         (void) printf("\n");
2004 }
2005
2006 /*
2007  * Given a pool and a list of properties, print out all the properties according
2008  * to the described layout.
2009  */
2010 static void
2011 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2012 {
2013         boolean_t first = B_TRUE;
2014         char property[ZPOOL_MAXPROPLEN];
2015         char *propstr;
2016         boolean_t right_justify;
2017         int width;
2018
2019         for (; pl != NULL; pl = pl->pl_next) {
2020                 if (!first) {
2021                         if (scripted)
2022                                 (void) printf("\t");
2023                         else
2024                                 (void) printf("  ");
2025                 } else {
2026                         first = B_FALSE;
2027                 }
2028
2029                 right_justify = B_FALSE;
2030                 if (pl->pl_prop != ZPROP_INVAL) {
2031                         if (zpool_get_prop(zhp, pl->pl_prop, property,
2032                             sizeof (property), NULL) != 0)
2033                                 propstr = "-";
2034                         else
2035                                 propstr = property;
2036
2037                         right_justify = zpool_prop_align_right(pl->pl_prop);
2038                 } else {
2039                         propstr = "-";
2040                 }
2041
2042                 width = pl->pl_width;
2043
2044                 /*
2045                  * If this is being called in scripted mode, or if this is the
2046                  * last column and it is left-justified, don't include a width
2047                  * format specifier.
2048                  */
2049                 if (scripted || (pl->pl_next == NULL && !right_justify))
2050                         (void) printf("%s", propstr);
2051                 else if (right_justify)
2052                         (void) printf("%*s", width, propstr);
2053                 else
2054                         (void) printf("%-*s", width, propstr);
2055         }
2056
2057         (void) printf("\n");
2058 }
2059
2060 /*
2061  * Generic callback function to list a pool.
2062  */
2063 int
2064 list_callback(zpool_handle_t *zhp, void *data)
2065 {
2066         list_cbdata_t *cbp = data;
2067
2068         if (cbp->cb_first) {
2069                 if (!cbp->cb_scripted)
2070                         print_header(cbp->cb_proplist);
2071                 cbp->cb_first = B_FALSE;
2072         }
2073
2074         print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2075
2076         return (0);
2077 }
2078
2079 /*
2080  * zpool list [-H] [-o prop[,prop]*] [pool] ...
2081  *
2082  *      -H      Scripted mode.  Don't display headers, and separate properties
2083  *              by a single tab.
2084  *      -o      List of properties to display.  Defaults to
2085  *              "name,size,used,available,capacity,health,altroot"
2086  *
2087  * List all pools in the system, whether or not they're healthy.  Output space
2088  * statistics for each one, as well as health status summary.
2089  */
2090 int
2091 zpool_do_list(int argc, char **argv)
2092 {
2093         int c;
2094         int ret;
2095         list_cbdata_t cb = { 0 };
2096         static char default_props[] =
2097             "name,size,used,available,capacity,health,altroot";
2098         char *props = default_props;
2099
2100         /* check options */
2101         while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2102                 switch (c) {
2103                 case 'H':
2104                         cb.cb_scripted = B_TRUE;
2105                         break;
2106                 case 'o':
2107                         props = optarg;
2108                         break;
2109                 case ':':
2110                         (void) fprintf(stderr, gettext("missing argument for "
2111                             "'%c' option\n"), optopt);
2112                         usage(B_FALSE);
2113                         break;
2114                 case '?':
2115                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2116                             optopt);
2117                         usage(B_FALSE);
2118                 }
2119         }
2120
2121         argc -= optind;
2122         argv += optind;
2123
2124         if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2125                 usage(B_FALSE);
2126
2127         cb.cb_first = B_TRUE;
2128
2129         ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2130             list_callback, &cb);
2131
2132         zprop_free_list(cb.cb_proplist);
2133
2134         if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2135                 (void) printf(gettext("no pools available\n"));
2136                 return (0);
2137         }
2138
2139         return (ret);
2140 }
2141
2142 static nvlist_t *
2143 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2144 {
2145         nvlist_t **child;
2146         uint_t c, children;
2147         nvlist_t *match;
2148         char *path;
2149
2150         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2151             &child, &children) != 0) {
2152                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2153                 if (strncmp(name, "/dev/dsk/", 9) == 0)
2154                         name += 9;
2155                 if (strncmp(path, "/dev/dsk/", 9) == 0)
2156                         path += 9;
2157                 if (strcmp(name, path) == 0)
2158                         return (nv);
2159                 return (NULL);
2160         }
2161
2162         for (c = 0; c < children; c++)
2163                 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2164                         return (match);
2165
2166         return (NULL);
2167 }
2168
2169 static int
2170 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2171 {
2172         boolean_t force = B_FALSE;
2173         int c;
2174         nvlist_t *nvroot;
2175         char *poolname, *old_disk, *new_disk;
2176         zpool_handle_t *zhp;
2177         int ret;
2178
2179         /* check options */
2180         while ((c = getopt(argc, argv, "f")) != -1) {
2181                 switch (c) {
2182                 case 'f':
2183                         force = B_TRUE;
2184                         break;
2185                 case '?':
2186                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2187                             optopt);
2188                         usage(B_FALSE);
2189                 }
2190         }
2191
2192         argc -= optind;
2193         argv += optind;
2194
2195         /* get pool name and check number of arguments */
2196         if (argc < 1) {
2197                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2198                 usage(B_FALSE);
2199         }
2200
2201         poolname = argv[0];
2202
2203         if (argc < 2) {
2204                 (void) fprintf(stderr,
2205                     gettext("missing <device> specification\n"));
2206                 usage(B_FALSE);
2207         }
2208
2209         old_disk = argv[1];
2210
2211         if (argc < 3) {
2212                 if (!replacing) {
2213                         (void) fprintf(stderr,
2214                             gettext("missing <new_device> specification\n"));
2215                         usage(B_FALSE);
2216                 }
2217                 new_disk = old_disk;
2218                 argc -= 1;
2219                 argv += 1;
2220         } else {
2221                 new_disk = argv[2];
2222                 argc -= 2;
2223                 argv += 2;
2224         }
2225
2226         if (argc > 1) {
2227                 (void) fprintf(stderr, gettext("too many arguments\n"));
2228                 usage(B_FALSE);
2229         }
2230
2231         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2232                 return (1);
2233
2234         if (zpool_get_config(zhp, NULL) == NULL) {
2235                 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2236                     poolname);
2237                 zpool_close(zhp);
2238                 return (1);
2239         }
2240
2241         nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv);
2242         if (nvroot == NULL) {
2243                 zpool_close(zhp);
2244                 return (1);
2245         }
2246
2247         ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2248
2249         nvlist_free(nvroot);
2250         zpool_close(zhp);
2251
2252         return (ret);
2253 }
2254
2255 /*
2256  * zpool replace [-f] <pool> <device> <new_device>
2257  *
2258  *      -f      Force attach, even if <new_device> appears to be in use.
2259  *
2260  * Replace <device> with <new_device>.
2261  */
2262 /* ARGSUSED */
2263 int
2264 zpool_do_replace(int argc, char **argv)
2265 {
2266         return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2267 }
2268
2269 /*
2270  * zpool attach [-f] <pool> <device> <new_device>
2271  *
2272  *      -f      Force attach, even if <new_device> appears to be in use.
2273  *
2274  * Attach <new_device> to the mirror containing <device>.  If <device> is not
2275  * part of a mirror, then <device> will be transformed into a mirror of
2276  * <device> and <new_device>.  In either case, <new_device> will begin life
2277  * with a DTL of [0, now], and will immediately begin to resilver itself.
2278  */
2279 int
2280 zpool_do_attach(int argc, char **argv)
2281 {
2282         return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2283 }
2284
2285 /*
2286  * zpool detach [-f] <pool> <device>
2287  *
2288  *      -f      Force detach of <device>, even if DTLs argue against it
2289  *              (not supported yet)
2290  *
2291  * Detach a device from a mirror.  The operation will be refused if <device>
2292  * is the last device in the mirror, or if the DTLs indicate that this device
2293  * has the only valid copy of some data.
2294  */
2295 /* ARGSUSED */
2296 int
2297 zpool_do_detach(int argc, char **argv)
2298 {
2299         int c;
2300         char *poolname, *path;
2301         zpool_handle_t *zhp;
2302         int ret;
2303
2304         /* check options */
2305         while ((c = getopt(argc, argv, "f")) != -1) {
2306                 switch (c) {
2307                 case 'f':
2308                 case '?':
2309                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2310                             optopt);
2311                         usage(B_FALSE);
2312                 }
2313         }
2314
2315         argc -= optind;
2316         argv += optind;
2317
2318         /* get pool name and check number of arguments */
2319         if (argc < 1) {
2320                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2321                 usage(B_FALSE);
2322         }
2323
2324         if (argc < 2) {
2325                 (void) fprintf(stderr,
2326                     gettext("missing <device> specification\n"));
2327                 usage(B_FALSE);
2328         }
2329
2330         poolname = argv[0];
2331         path = argv[1];
2332
2333         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2334                 return (1);
2335
2336         ret = zpool_vdev_detach(zhp, path);
2337
2338         zpool_close(zhp);
2339
2340         return (ret);
2341 }
2342
2343 /*
2344  * zpool online <pool> <device> ...
2345  */
2346 int
2347 zpool_do_online(int argc, char **argv)
2348 {
2349         int c, i;
2350         char *poolname;
2351         zpool_handle_t *zhp;
2352         int ret = 0;
2353         vdev_state_t newstate;
2354
2355         /* check options */
2356         while ((c = getopt(argc, argv, "t")) != -1) {
2357                 switch (c) {
2358                 case 't':
2359                 case '?':
2360                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2361                             optopt);
2362                         usage(B_FALSE);
2363                 }
2364         }
2365
2366         argc -= optind;
2367         argv += optind;
2368
2369         /* get pool name and check number of arguments */
2370         if (argc < 1) {
2371                 (void) fprintf(stderr, gettext("missing pool name\n"));
2372                 usage(B_FALSE);
2373         }
2374         if (argc < 2) {
2375                 (void) fprintf(stderr, gettext("missing device name\n"));
2376                 usage(B_FALSE);
2377         }
2378
2379         poolname = argv[0];
2380
2381         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2382                 return (1);
2383
2384         for (i = 1; i < argc; i++) {
2385                 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
2386                         if (newstate != VDEV_STATE_HEALTHY) {
2387                                 (void) printf(gettext("warning: device '%s' "
2388                                     "onlined, but remains in faulted state\n"),
2389                                     argv[i]);
2390                                 if (newstate == VDEV_STATE_FAULTED)
2391                                         (void) printf(gettext("use 'zpool "
2392                                             "clear' to restore a faulted "
2393                                             "device\n"));
2394                                 else
2395                                         (void) printf(gettext("use 'zpool "
2396                                             "replace' to replace devices "
2397                                             "that are no longer present\n"));
2398                         }
2399                 } else {
2400                         ret = 1;
2401                 }
2402         }
2403
2404         zpool_close(zhp);
2405
2406         return (ret);
2407 }
2408
2409 /*
2410  * zpool offline [-ft] <pool> <device> ...
2411  *
2412  *      -f      Force the device into the offline state, even if doing
2413  *              so would appear to compromise pool availability.
2414  *              (not supported yet)
2415  *
2416  *      -t      Only take the device off-line temporarily.  The offline
2417  *              state will not be persistent across reboots.
2418  */
2419 /* ARGSUSED */
2420 int
2421 zpool_do_offline(int argc, char **argv)
2422 {
2423         int c, i;
2424         char *poolname;
2425         zpool_handle_t *zhp;
2426         int ret = 0;
2427         boolean_t istmp = B_FALSE;
2428
2429         /* check options */
2430         while ((c = getopt(argc, argv, "ft")) != -1) {
2431                 switch (c) {
2432                 case 't':
2433                         istmp = B_TRUE;
2434                         break;
2435                 case 'f':
2436                 case '?':
2437                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2438                             optopt);
2439                         usage(B_FALSE);
2440                 }
2441         }
2442
2443         argc -= optind;
2444         argv += optind;
2445
2446         /* get pool name and check number of arguments */
2447         if (argc < 1) {
2448                 (void) fprintf(stderr, gettext("missing pool name\n"));
2449                 usage(B_FALSE);
2450         }
2451         if (argc < 2) {
2452                 (void) fprintf(stderr, gettext("missing device name\n"));
2453                 usage(B_FALSE);
2454         }
2455
2456         poolname = argv[0];
2457
2458         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2459                 return (1);
2460
2461         for (i = 1; i < argc; i++) {
2462                 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2463                         ret = 1;
2464         }
2465
2466         zpool_close(zhp);
2467
2468         return (ret);
2469 }
2470
2471 /*
2472  * zpool clear <pool> [device]
2473  *
2474  * Clear all errors associated with a pool or a particular device.
2475  */
2476 int
2477 zpool_do_clear(int argc, char **argv)
2478 {
2479         int ret = 0;
2480         zpool_handle_t *zhp;
2481         char *pool, *device;
2482
2483         if (argc < 2) {
2484                 (void) fprintf(stderr, gettext("missing pool name\n"));
2485                 usage(B_FALSE);
2486         }
2487
2488         if (argc > 3) {
2489                 (void) fprintf(stderr, gettext("too many arguments\n"));
2490                 usage(B_FALSE);
2491         }
2492
2493         pool = argv[1];
2494         device = argc == 3 ? argv[2] : NULL;
2495
2496         if ((zhp = zpool_open(g_zfs, pool)) == NULL)
2497                 return (1);
2498
2499         if (zpool_clear(zhp, device) != 0)
2500                 ret = 1;
2501
2502         zpool_close(zhp);
2503
2504         return (ret);
2505 }
2506
2507 typedef struct scrub_cbdata {
2508         int     cb_type;
2509         int     cb_argc;
2510         char    **cb_argv;
2511 } scrub_cbdata_t;
2512
2513 int
2514 scrub_callback(zpool_handle_t *zhp, void *data)
2515 {
2516         scrub_cbdata_t *cb = data;
2517         int err;
2518
2519         /*
2520          * Ignore faulted pools.
2521          */
2522         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2523                 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2524                     "currently unavailable\n"), zpool_get_name(zhp));
2525                 return (1);
2526         }
2527
2528         err = zpool_scrub(zhp, cb->cb_type);
2529
2530         return (err != 0);
2531 }
2532
2533 /*
2534  * zpool scrub [-s] <pool> ...
2535  *
2536  *      -s      Stop.  Stops any in-progress scrub.
2537  */
2538 int
2539 zpool_do_scrub(int argc, char **argv)
2540 {
2541         int c;
2542         scrub_cbdata_t cb;
2543
2544         cb.cb_type = POOL_SCRUB_EVERYTHING;
2545
2546         /* check options */
2547         while ((c = getopt(argc, argv, "s")) != -1) {
2548                 switch (c) {
2549                 case 's':
2550                         cb.cb_type = POOL_SCRUB_NONE;
2551                         break;
2552                 case '?':
2553                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2554                             optopt);
2555                         usage(B_FALSE);
2556                 }
2557         }
2558
2559         cb.cb_argc = argc;
2560         cb.cb_argv = argv;
2561         argc -= optind;
2562         argv += optind;
2563
2564         if (argc < 1) {
2565                 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2566                 usage(B_FALSE);
2567         }
2568
2569         return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2570 }
2571
2572 typedef struct status_cbdata {
2573         int             cb_count;
2574         boolean_t       cb_allpools;
2575         boolean_t       cb_verbose;
2576         boolean_t       cb_explain;
2577         boolean_t       cb_first;
2578 } status_cbdata_t;
2579
2580 /*
2581  * Print out detailed scrub status.
2582  */
2583 void
2584 print_scrub_status(nvlist_t *nvroot)
2585 {
2586         vdev_stat_t *vs;
2587         uint_t vsc;
2588         time_t start, end, now;
2589         double fraction_done;
2590         uint64_t examined, total, minutes_left, minutes_taken;
2591         char *scrub_type;
2592
2593         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2594             (uint64_t **)&vs, &vsc) == 0);
2595
2596         /*
2597          * If there's never been a scrub, there's not much to say.
2598          */
2599         if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2600                 (void) printf(gettext("none requested\n"));
2601                 return;
2602         }
2603
2604         scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2605             "resilver" : "scrub";
2606
2607         start = vs->vs_scrub_start;
2608         end = vs->vs_scrub_end;
2609         now = time(NULL);
2610         examined = vs->vs_scrub_examined;
2611         total = vs->vs_alloc;
2612
2613         if (end != 0) {
2614                 minutes_taken = (uint64_t)((end - start) / 60);
2615
2616                 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2617                     "on %s"),
2618                     scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2619                     (u_longlong_t)(minutes_taken / 60),
2620                     (uint_t)(minutes_taken % 60),
2621                     (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2622                 return;
2623         }
2624
2625         if (examined == 0)
2626                 examined = 1;
2627         if (examined > total)
2628                 total = examined;
2629
2630         fraction_done = (double)examined / total;
2631         minutes_left = (uint64_t)((now - start) *
2632             (1 - fraction_done) / fraction_done / 60);
2633         minutes_taken = (uint64_t)((now - start) / 60);
2634
2635         (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2636             "%lluh%um to go\n"),
2637             scrub_type, (u_longlong_t)(minutes_taken / 60),
2638             (uint_t)(minutes_taken % 60), 100 * fraction_done,
2639             (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2640 }
2641
2642 typedef struct spare_cbdata {
2643         uint64_t        cb_guid;
2644         zpool_handle_t  *cb_zhp;
2645 } spare_cbdata_t;
2646
2647 static boolean_t
2648 find_vdev(nvlist_t *nv, uint64_t search)
2649 {
2650         uint64_t guid;
2651         nvlist_t **child;
2652         uint_t c, children;
2653
2654         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
2655             search == guid)
2656                 return (B_TRUE);
2657
2658         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2659             &child, &children) == 0) {
2660                 for (c = 0; c < children; c++)
2661                         if (find_vdev(child[c], search))
2662                                 return (B_TRUE);
2663         }
2664
2665         return (B_FALSE);
2666 }
2667
2668 static int
2669 find_spare(zpool_handle_t *zhp, void *data)
2670 {
2671         spare_cbdata_t *cbp = data;
2672         nvlist_t *config, *nvroot;
2673
2674         config = zpool_get_config(zhp, NULL);
2675         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2676             &nvroot) == 0);
2677
2678         if (find_vdev(nvroot, cbp->cb_guid)) {
2679                 cbp->cb_zhp = zhp;
2680                 return (1);
2681         }
2682
2683         zpool_close(zhp);
2684         return (0);
2685 }
2686
2687 /*
2688  * Print out configuration state as requested by status_callback.
2689  */
2690 void
2691 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
2692     int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
2693 {
2694         nvlist_t **child;
2695         uint_t c, children;
2696         vdev_stat_t *vs;
2697         char rbuf[6], wbuf[6], cbuf[6], repaired[7];
2698         char *vname;
2699         uint64_t notpresent;
2700         spare_cbdata_t cb;
2701         char *state;
2702
2703         verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
2704             (uint64_t **)&vs, &c) == 0);
2705
2706         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2707             &child, &children) != 0)
2708                 children = 0;
2709
2710         state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2711         if (isspare) {
2712                 /*
2713                  * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
2714                  * online drives.
2715                  */
2716                 if (vs->vs_aux == VDEV_AUX_SPARED)
2717                         state = "INUSE";
2718                 else if (vs->vs_state == VDEV_STATE_HEALTHY)
2719                         state = "AVAIL";
2720         }
2721
2722         (void) printf("\t%*s%-*s  %-8s", depth, "", namewidth - depth,
2723             name, state);
2724
2725         if (!isspare) {
2726                 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
2727                 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
2728                 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
2729                 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
2730         }
2731
2732         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
2733             &notpresent) == 0) {
2734                 char *path;
2735                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2736                 (void) printf("  was %s", path);
2737         } else if (vs->vs_aux != 0) {
2738                 (void) printf("  ");
2739
2740                 switch (vs->vs_aux) {
2741                 case VDEV_AUX_OPEN_FAILED:
2742                         (void) printf(gettext("cannot open"));
2743                         break;
2744
2745                 case VDEV_AUX_BAD_GUID_SUM:
2746                         (void) printf(gettext("missing device"));
2747                         break;
2748
2749                 case VDEV_AUX_NO_REPLICAS:
2750                         (void) printf(gettext("insufficient replicas"));
2751                         break;
2752
2753                 case VDEV_AUX_VERSION_NEWER:
2754                         (void) printf(gettext("newer version"));
2755                         break;
2756
2757                 case VDEV_AUX_SPARED:
2758                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
2759                             &cb.cb_guid) == 0);
2760                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
2761                                 if (strcmp(zpool_get_name(cb.cb_zhp),
2762                                     zpool_get_name(zhp)) == 0)
2763                                         (void) printf(gettext("currently in "
2764                                             "use"));
2765                                 else
2766                                         (void) printf(gettext("in use by "
2767                                             "pool '%s'"),
2768                                             zpool_get_name(cb.cb_zhp));
2769                                 zpool_close(cb.cb_zhp);
2770                         } else {
2771                                 (void) printf(gettext("currently in use"));
2772                         }
2773                         break;
2774
2775                 case VDEV_AUX_ERR_EXCEEDED:
2776                         (void) printf(gettext("too many errors"));
2777                         break;
2778
2779                 default:
2780                         (void) printf(gettext("corrupted data"));
2781                         break;
2782                 }
2783         } else if (vs->vs_scrub_repaired != 0 && children == 0) {
2784                 /*
2785                  * Report bytes resilvered/repaired on leaf devices.
2786                  */
2787                 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
2788                 (void) printf(gettext("  %s %s"), repaired,
2789                     (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2790                     "resilvered" : "repaired");
2791         }
2792
2793         (void) printf("\n");
2794
2795         for (c = 0; c < children; c++) {
2796                 uint64_t is_log = B_FALSE;
2797
2798                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2799                     &is_log);
2800                 if ((is_log && !print_logs) || (!is_log && print_logs))
2801                         continue;
2802                 vname = zpool_vdev_name(g_zfs, zhp, child[c]);
2803                 print_status_config(zhp, vname, child[c],
2804                     namewidth, depth + 2, isspare, B_FALSE);
2805                 free(vname);
2806         }
2807 }
2808
2809 static void
2810 print_error_log(zpool_handle_t *zhp)
2811 {
2812         nvlist_t *nverrlist = NULL;
2813         nvpair_t *elem;
2814         char *pathname;
2815         size_t len = MAXPATHLEN * 2;
2816
2817         if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2818                 (void) printf("errors: List of errors unavailable "
2819                     "(insufficient privileges)\n");
2820                 return;
2821         }
2822
2823         (void) printf("errors: Permanent errors have been "
2824             "detected in the following files:\n\n");
2825
2826         pathname = safe_malloc(len);
2827         elem = NULL;
2828         while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2829                 nvlist_t *nv;
2830                 uint64_t dsobj, obj;
2831
2832                 verify(nvpair_value_nvlist(elem, &nv) == 0);
2833                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2834                     &dsobj) == 0);
2835                 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2836                     &obj) == 0);
2837                 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2838                 (void) printf("%7s %s\n", "", pathname);
2839         }
2840         free(pathname);
2841         nvlist_free(nverrlist);
2842 }
2843
2844 static void
2845 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2846     int namewidth)
2847 {
2848         uint_t i;
2849         char *name;
2850
2851         if (nspares == 0)
2852                 return;
2853
2854         (void) printf(gettext("\tspares\n"));
2855
2856         for (i = 0; i < nspares; i++) {
2857                 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2858                 print_status_config(zhp, name, spares[i],
2859                     namewidth, 2, B_TRUE, B_FALSE);
2860                 free(name);
2861         }
2862 }
2863
2864 static void
2865 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2866     int namewidth)
2867 {
2868         uint_t i;
2869         char *name;
2870
2871         if (nl2cache == 0)
2872                 return;
2873
2874         (void) printf(gettext("\tcache\n"));
2875
2876         for (i = 0; i < nl2cache; i++) {
2877                 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
2878                 print_status_config(zhp, name, l2cache[i],
2879                     namewidth, 2, B_FALSE, B_FALSE);
2880                 free(name);
2881         }
2882 }
2883
2884 /*
2885  * Display a summary of pool status.  Displays a summary such as:
2886  *
2887  *        pool: tank
2888  *      status: DEGRADED
2889  *      reason: One or more devices ...
2890  *         see: http://www.sun.com/msg/ZFS-xxxx-01
2891  *      config:
2892  *              mirror          DEGRADED
2893  *                c1t0d0        OK
2894  *                c2t0d0        UNAVAIL
2895  *
2896  * When given the '-v' option, we print out the complete config.  If the '-e'
2897  * option is specified, then we print out error rate information as well.
2898  */
2899 int
2900 status_callback(zpool_handle_t *zhp, void *data)
2901 {
2902         status_cbdata_t *cbp = data;
2903         nvlist_t *config, *nvroot;
2904         char *msgid;
2905         int reason;
2906         const char *health;
2907         uint_t c;
2908         vdev_stat_t *vs;
2909
2910         config = zpool_get_config(zhp, NULL);
2911         reason = zpool_get_status(zhp, &msgid);
2912
2913         cbp->cb_count++;
2914
2915         /*
2916          * If we were given 'zpool status -x', only report those pools with
2917          * problems.
2918          */
2919         if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
2920                 if (!cbp->cb_allpools) {
2921                         (void) printf(gettext("pool '%s' is healthy\n"),
2922                             zpool_get_name(zhp));
2923                         if (cbp->cb_first)
2924                                 cbp->cb_first = B_FALSE;
2925                 }
2926                 return (0);
2927         }
2928
2929         if (cbp->cb_first)
2930                 cbp->cb_first = B_FALSE;
2931         else
2932                 (void) printf("\n");
2933
2934         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2935             &nvroot) == 0);
2936         verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2937             (uint64_t **)&vs, &c) == 0);
2938         health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
2939
2940         (void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
2941         (void) printf(gettext(" state: %s\n"), health);
2942
2943         switch (reason) {
2944         case ZPOOL_STATUS_MISSING_DEV_R:
2945                 (void) printf(gettext("status: One or more devices could not "
2946                     "be opened.  Sufficient replicas exist for\n\tthe pool to "
2947                     "continue functioning in a degraded state.\n"));
2948                 (void) printf(gettext("action: Attach the missing device and "
2949                     "online it using 'zpool online'.\n"));
2950                 break;
2951
2952         case ZPOOL_STATUS_MISSING_DEV_NR:
2953                 (void) printf(gettext("status: One or more devices could not "
2954                     "be opened.  There are insufficient\n\treplicas for the "
2955                     "pool to continue functioning.\n"));
2956                 (void) printf(gettext("action: Attach the missing device and "
2957                     "online it using 'zpool online'.\n"));
2958                 break;
2959
2960         case ZPOOL_STATUS_CORRUPT_LABEL_R:
2961                 (void) printf(gettext("status: One or more devices could not "
2962                     "be used because the label is missing or\n\tinvalid.  "
2963                     "Sufficient replicas exist for the pool to continue\n\t"
2964                     "functioning in a degraded state.\n"));
2965                 (void) printf(gettext("action: Replace the device using "
2966                     "'zpool replace'.\n"));
2967                 break;
2968
2969         case ZPOOL_STATUS_CORRUPT_LABEL_NR:
2970                 (void) printf(gettext("status: One or more devices could not "
2971                     "be used because the label is missing \n\tor invalid.  "
2972                     "There are insufficient replicas for the pool to "
2973                     "continue\n\tfunctioning.\n"));
2974                 (void) printf(gettext("action: Destroy and re-create the pool "
2975                     "from a backup source.\n"));
2976                 break;
2977
2978         case ZPOOL_STATUS_FAILING_DEV:
2979                 (void) printf(gettext("status: One or more devices has "
2980                     "experienced an unrecoverable error.  An\n\tattempt was "
2981                     "made to correct the error.  Applications are "
2982                     "unaffected.\n"));
2983                 (void) printf(gettext("action: Determine if the device needs "
2984                     "to be replaced, and clear the errors\n\tusing "
2985                     "'zpool clear' or replace the device with 'zpool "
2986                     "replace'.\n"));
2987                 break;
2988
2989         case ZPOOL_STATUS_OFFLINE_DEV:
2990                 (void) printf(gettext("status: One or more devices has "
2991                     "been taken offline by the administrator.\n\tSufficient "
2992                     "replicas exist for the pool to continue functioning in "
2993                     "a\n\tdegraded state.\n"));
2994                 (void) printf(gettext("action: Online the device using "
2995                     "'zpool online' or replace the device with\n\t'zpool "
2996                     "replace'.\n"));
2997                 break;
2998
2999         case ZPOOL_STATUS_RESILVERING:
3000                 (void) printf(gettext("status: One or more devices is "
3001                     "currently being resilvered.  The pool will\n\tcontinue "
3002                     "to function, possibly in a degraded state.\n"));
3003                 (void) printf(gettext("action: Wait for the resilver to "
3004                     "complete.\n"));
3005                 break;
3006
3007         case ZPOOL_STATUS_CORRUPT_DATA:
3008                 (void) printf(gettext("status: One or more devices has "
3009                     "experienced an error resulting in data\n\tcorruption.  "
3010                     "Applications may be affected.\n"));
3011                 (void) printf(gettext("action: Restore the file in question "
3012                     "if possible.  Otherwise restore the\n\tentire pool from "
3013                     "backup.\n"));
3014                 break;
3015
3016         case ZPOOL_STATUS_CORRUPT_POOL:
3017                 (void) printf(gettext("status: The pool metadata is corrupted "
3018                     "and the pool cannot be opened.\n"));
3019                 (void) printf(gettext("action: Destroy and re-create the pool "
3020                     "from a backup source.\n"));
3021                 break;
3022
3023         case ZPOOL_STATUS_VERSION_OLDER:
3024                 (void) printf(gettext("status: The pool is formatted using an "
3025                     "older on-disk format.  The pool can\n\tstill be used, but "
3026                     "some features are unavailable.\n"));
3027                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3028                     "upgrade'.  Once this is done, the\n\tpool will no longer "
3029                     "be accessible on older software versions.\n"));
3030                 break;
3031
3032         case ZPOOL_STATUS_VERSION_NEWER:
3033                 (void) printf(gettext("status: The pool has been upgraded to a "
3034                     "newer, incompatible on-disk version.\n\tThe pool cannot "
3035                     "be accessed on this system.\n"));
3036                 (void) printf(gettext("action: Access the pool from a system "
3037                     "running more recent software, or\n\trestore the pool from "
3038                     "backup.\n"));
3039                 break;
3040
3041         case ZPOOL_STATUS_FAULTED_DEV_R:
3042                 (void) printf(gettext("status: One or more devices are "
3043                     "faulted in response to persistent errors.\n\tSufficient "
3044                     "replicas exist for the pool to continue functioning "
3045                     "in a\n\tdegraded state.\n"));
3046                 (void) printf(gettext("action: Replace the faulted device, "
3047                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3048                 break;
3049
3050         case ZPOOL_STATUS_FAULTED_DEV_NR:
3051                 (void) printf(gettext("status: One or more devices are "
3052                     "faulted in response to persistent errors.  There are "
3053                     "insufficient replicas for the pool to\n\tcontinue "
3054                     "functioning.\n"));
3055                 (void) printf(gettext("action: Destroy and re-create the pool "
3056                     "from a backup source.  Manually marking the device\n"
3057                     "\trepaired using 'zpool clear' may allow some data "
3058                     "to be recovered.\n"));
3059                 break;
3060
3061         default:
3062                 /*
3063                  * The remaining errors can't actually be generated, yet.
3064                  */
3065                 assert(reason == ZPOOL_STATUS_OK);
3066         }
3067
3068         if (msgid != NULL)
3069                 (void) printf(gettext("   see: http://www.sun.com/msg/%s\n"),
3070                     msgid);
3071
3072         if (config != NULL) {
3073                 int namewidth;
3074                 uint64_t nerr;
3075                 nvlist_t **spares, **l2cache;
3076                 uint_t nspares, nl2cache;
3077
3078
3079                 (void) printf(gettext(" scrub: "));
3080                 print_scrub_status(nvroot);
3081
3082                 namewidth = max_width(zhp, nvroot, 0, 0);
3083                 if (namewidth < 10)
3084                         namewidth = 10;
3085
3086                 (void) printf(gettext("config:\n\n"));
3087                 (void) printf(gettext("\t%-*s  %-8s %5s %5s %5s\n"), namewidth,
3088                     "NAME", "STATE", "READ", "WRITE", "CKSUM");
3089                 print_status_config(zhp, zpool_get_name(zhp), nvroot,
3090                     namewidth, 0, B_FALSE, B_FALSE);
3091                 if (num_logs(nvroot) > 0)
3092                         print_status_config(zhp, "logs", nvroot, namewidth, 0,
3093                             B_FALSE, B_TRUE);
3094
3095                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3096                     &l2cache, &nl2cache) == 0)
3097                         print_l2cache(zhp, l2cache, nl2cache, namewidth);
3098
3099                 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3100                     &spares, &nspares) == 0)
3101                         print_spares(zhp, spares, nspares, namewidth);
3102
3103                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3104                     &nerr) == 0) {
3105                         nvlist_t *nverrlist = NULL;
3106
3107                         /*
3108                          * If the approximate error count is small, get a
3109                          * precise count by fetching the entire log and
3110                          * uniquifying the results.
3111                          */
3112                         if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3113                             zpool_get_errlog(zhp, &nverrlist) == 0) {
3114                                 nvpair_t *elem;
3115
3116                                 elem = NULL;
3117                                 nerr = 0;
3118                                 while ((elem = nvlist_next_nvpair(nverrlist,
3119                                     elem)) != NULL) {
3120                                         nerr++;
3121                                 }
3122                         }
3123                         nvlist_free(nverrlist);
3124
3125                         (void) printf("\n");
3126
3127                         if (nerr == 0)
3128                                 (void) printf(gettext("errors: No known data "
3129                                     "errors\n"));
3130                         else if (!cbp->cb_verbose)
3131                                 (void) printf(gettext("errors: %llu data "
3132                                     "errors, use '-v' for a list\n"),
3133                                     (u_longlong_t)nerr);
3134                         else
3135                                 print_error_log(zhp);
3136                 }
3137         } else {
3138                 (void) printf(gettext("config: The configuration cannot be "
3139                     "determined.\n"));
3140         }
3141
3142         return (0);
3143 }
3144
3145 /*
3146  * zpool status [-vx] [pool] ...
3147  *
3148  *      -v      Display complete error logs
3149  *      -x      Display only pools with potential problems
3150  *
3151  * Describes the health status of all pools or some subset.
3152  */
3153 int
3154 zpool_do_status(int argc, char **argv)
3155 {
3156         int c;
3157         int ret;
3158         status_cbdata_t cb = { 0 };
3159
3160         /* check options */
3161         while ((c = getopt(argc, argv, "vx")) != -1) {
3162                 switch (c) {
3163                 case 'v':
3164                         cb.cb_verbose = B_TRUE;
3165                         break;
3166                 case 'x':
3167                         cb.cb_explain = B_TRUE;
3168                         break;
3169                 case '?':
3170                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3171                             optopt);
3172                         usage(B_FALSE);
3173                 }
3174         }
3175
3176         argc -= optind;
3177         argv += optind;
3178
3179         cb.cb_first = B_TRUE;
3180
3181         if (argc == 0)
3182                 cb.cb_allpools = B_TRUE;
3183
3184         ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3185
3186         if (argc == 0 && cb.cb_count == 0)
3187                 (void) printf(gettext("no pools available\n"));
3188         else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3189                 (void) printf(gettext("all pools are healthy\n"));
3190
3191         return (ret);
3192 }
3193
3194 typedef struct upgrade_cbdata {
3195         int     cb_all;
3196         int     cb_first;
3197         int     cb_newer;
3198         int     cb_argc;
3199         uint64_t cb_version;
3200         char    **cb_argv;
3201 } upgrade_cbdata_t;
3202
3203 static int
3204 upgrade_cb(zpool_handle_t *zhp, void *arg)
3205 {
3206         upgrade_cbdata_t *cbp = arg;
3207         nvlist_t *config;
3208         uint64_t version;
3209         int ret = 0;
3210
3211         config = zpool_get_config(zhp, NULL);
3212         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3213             &version) == 0);
3214
3215         if (!cbp->cb_newer && version < SPA_VERSION) {
3216                 if (!cbp->cb_all) {
3217                         if (cbp->cb_first) {
3218                                 (void) printf(gettext("The following pools are "
3219                                     "out of date, and can be upgraded.  After "
3220                                     "being\nupgraded, these pools will no "
3221                                     "longer be accessible by older software "
3222                                     "versions.\n\n"));
3223                                 (void) printf(gettext("VER  POOL\n"));
3224                                 (void) printf(gettext("---  ------------\n"));
3225                                 cbp->cb_first = B_FALSE;
3226                         }
3227
3228                         (void) printf("%2llu   %s\n", (u_longlong_t)version,
3229                             zpool_get_name(zhp));
3230                 } else {
3231                         cbp->cb_first = B_FALSE;
3232                         ret = zpool_upgrade(zhp, cbp->cb_version);
3233                         if (!ret) {
3234                                 (void) printf(gettext("Successfully upgraded "
3235                                     "'%s'\n\n"), zpool_get_name(zhp));
3236                         }
3237                 }
3238         } else if (cbp->cb_newer && version > SPA_VERSION) {
3239                 assert(!cbp->cb_all);
3240
3241                 if (cbp->cb_first) {
3242                         (void) printf(gettext("The following pools are "
3243                             "formatted using a newer software version and\n"
3244                             "cannot be accessed on the current system.\n\n"));
3245                         (void) printf(gettext("VER  POOL\n"));
3246                         (void) printf(gettext("---  ------------\n"));
3247                         cbp->cb_first = B_FALSE;
3248                 }
3249
3250                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
3251                     zpool_get_name(zhp));
3252         }
3253
3254         zpool_close(zhp);
3255         return (ret);
3256 }
3257
3258 /* ARGSUSED */
3259 static int
3260 upgrade_one(zpool_handle_t *zhp, void *data)
3261 {
3262         upgrade_cbdata_t *cbp = data;
3263         uint64_t cur_version;
3264         int ret;
3265
3266         if (strcmp("log", zpool_get_name(zhp)) == 0) {
3267                 (void) printf(gettext("'log' is now a reserved word\n"
3268                     "Pool 'log' must be renamed using export and import"
3269                     " to upgrade.\n"));
3270                 return (1);
3271         }
3272
3273         cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3274         if (cur_version > cbp->cb_version) {
3275                 (void) printf(gettext("Pool '%s' is already formatted "
3276                     "using more current version '%llu'.\n"),
3277                     zpool_get_name(zhp), cur_version);
3278                 return (0);
3279         }
3280         if (cur_version == cbp->cb_version) {
3281                 (void) printf(gettext("Pool '%s' is already formatted "
3282                     "using the current version.\n"), zpool_get_name(zhp));
3283                 return (0);
3284         }
3285
3286         ret = zpool_upgrade(zhp, cbp->cb_version);
3287
3288         if (!ret) {
3289                 (void) printf(gettext("Successfully upgraded '%s' "
3290                     "from version %llu to version %llu\n\n"),
3291                     zpool_get_name(zhp), (u_longlong_t)cur_version,
3292                     (u_longlong_t)cbp->cb_version);
3293         }
3294
3295         return (ret != 0);
3296 }
3297
3298 /*
3299  * zpool upgrade
3300  * zpool upgrade -v
3301  * zpool upgrade [-V version] <-a | pool ...>
3302  *
3303  * With no arguments, display downrev'd ZFS pool available for upgrade.
3304  * Individual pools can be upgraded by specifying the pool, and '-a' will
3305  * upgrade all pools.
3306  */
3307 int
3308 zpool_do_upgrade(int argc, char **argv)
3309 {
3310         int c;
3311         upgrade_cbdata_t cb = { 0 };
3312         int ret = 0;
3313         boolean_t showversions = B_FALSE;
3314         char *end;
3315
3316
3317         /* check options */
3318         while ((c = getopt(argc, argv, "avV:")) != -1) {
3319                 switch (c) {
3320                 case 'a':
3321                         cb.cb_all = B_TRUE;
3322                         break;
3323                 case 'v':
3324                         showversions = B_TRUE;
3325                         break;
3326                 case 'V':
3327                         cb.cb_version = strtoll(optarg, &end, 10);
3328                         if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3329                             cb.cb_version < SPA_VERSION_1) {
3330                                 (void) fprintf(stderr,
3331                                     gettext("invalid version '%s'\n"), optarg);
3332                                 usage(B_FALSE);
3333                         }
3334                         break;
3335                 case '?':
3336                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3337                             optopt);
3338                         usage(B_FALSE);
3339                 }
3340         }
3341
3342         cb.cb_argc = argc;
3343         cb.cb_argv = argv;
3344         argc -= optind;
3345         argv += optind;
3346
3347         if (cb.cb_version == 0) {
3348                 cb.cb_version = SPA_VERSION;
3349         } else if (!cb.cb_all && argc == 0) {
3350                 (void) fprintf(stderr, gettext("-V option is "
3351                     "incompatible with other arguments\n"));
3352                 usage(B_FALSE);
3353         }
3354
3355         if (showversions) {
3356                 if (cb.cb_all || argc != 0) {
3357                         (void) fprintf(stderr, gettext("-v option is "
3358                             "incompatible with other arguments\n"));
3359                         usage(B_FALSE);
3360                 }
3361         } else if (cb.cb_all) {
3362                 if (argc != 0) {
3363                         (void) fprintf(stderr, gettext("-a option should not "
3364                             "be used along with a pool name\n"));
3365                         usage(B_FALSE);
3366                 }
3367         }
3368
3369         (void) printf(gettext("This system is currently running "
3370             "ZFS pool version %llu.\n\n"), SPA_VERSION);
3371         cb.cb_first = B_TRUE;
3372         if (showversions) {
3373                 (void) printf(gettext("The following versions are "
3374                     "supported:\n\n"));
3375                 (void) printf(gettext("VER  DESCRIPTION\n"));
3376                 (void) printf("---  -----------------------------------------"
3377                     "---------------\n");
3378                 (void) printf(gettext(" 1   Initial ZFS version\n"));
3379                 (void) printf(gettext(" 2   Ditto blocks "
3380                     "(replicated metadata)\n"));
3381                 (void) printf(gettext(" 3   Hot spares and double parity "
3382                     "RAID-Z\n"));
3383                 (void) printf(gettext(" 4   zpool history\n"));
3384                 (void) printf(gettext(" 5   Compression using the gzip "
3385                     "algorithm\n"));
3386                 (void) printf(gettext(" 6   bootfs pool property\n"));
3387                 (void) printf(gettext(" 7   Separate intent log devices\n"));
3388                 (void) printf(gettext(" 8   Delegated administration\n"));
3389                 (void) printf(gettext(" 9   refquota and refreservation "
3390                     "properties\n"));
3391                 (void) printf(gettext(" 10  Cache devices\n"));
3392                 (void) printf(gettext("For more information on a particular "
3393                     "version, including supported releases, see:\n\n"));
3394                 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3395                     "version/N\n\n");
3396                 (void) printf(gettext("Where 'N' is the version number.\n"));
3397         } else if (argc == 0) {
3398                 int notfound;
3399
3400                 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3401                 notfound = cb.cb_first;
3402
3403                 if (!cb.cb_all && ret == 0) {
3404                         if (!cb.cb_first)
3405                                 (void) printf("\n");
3406                         cb.cb_first = B_TRUE;
3407                         cb.cb_newer = B_TRUE;
3408                         ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3409                         if (!cb.cb_first) {
3410                                 notfound = B_FALSE;
3411                                 (void) printf("\n");
3412                         }
3413                 }
3414
3415                 if (ret == 0) {
3416                         if (notfound)
3417                                 (void) printf(gettext("All pools are formatted "
3418                                     "using this version.\n"));
3419                         else if (!cb.cb_all)
3420                                 (void) printf(gettext("Use 'zpool upgrade -v' "
3421                                     "for a list of available versions and "
3422                                     "their associated\nfeatures.\n"));
3423                 }
3424         } else {
3425                 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3426                     upgrade_one, &cb);
3427         }
3428
3429         return (ret);
3430 }
3431
3432 typedef struct hist_cbdata {
3433         boolean_t first;
3434         int longfmt;
3435         int internal;
3436 } hist_cbdata_t;
3437
3438 char *hist_event_table[LOG_END] = {
3439         "invalid event",
3440         "pool create",
3441         "vdev add",
3442         "pool remove",
3443         "pool destroy",
3444         "pool export",
3445         "pool import",
3446         "vdev attach",
3447         "vdev replace",
3448         "vdev detach",
3449         "vdev online",
3450         "vdev offline",
3451         "vdev upgrade",
3452         "pool clear",
3453         "pool scrub",
3454         "pool property set",
3455         "create",
3456         "clone",
3457         "destroy",
3458         "destroy_begin_sync",
3459         "inherit",
3460         "property set",
3461         "quota set",
3462         "permission update",
3463         "permission remove",
3464         "permission who remove",
3465         "promote",
3466         "receive",
3467         "rename",
3468         "reservation set",
3469         "replay_inc_sync",
3470         "replay_full_sync",
3471         "rollback",
3472         "snapshot",
3473         "filesystem version upgrade",
3474         "refquota set",
3475         "refreservation set",
3476 };
3477
3478 /*
3479  * Print out the command history for a specific pool.
3480  */
3481 static int
3482 get_history_one(zpool_handle_t *zhp, void *data)
3483 {
3484         nvlist_t *nvhis;
3485         nvlist_t **records;
3486         uint_t numrecords;
3487         char *cmdstr;
3488         char *pathstr;
3489         uint64_t dst_time;
3490         time_t tsec;
3491         struct tm t;
3492         char tbuf[30];
3493         int ret, i;
3494         uint64_t who;
3495         struct passwd *pwd;
3496         char *hostname;
3497         char *zonename;
3498         char internalstr[MAXPATHLEN];
3499         hist_cbdata_t *cb = (hist_cbdata_t *)data;
3500         uint64_t txg;
3501         uint64_t ievent;
3502
3503         cb->first = B_FALSE;
3504
3505         (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3506
3507         if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3508                 return (ret);
3509
3510         verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3511             &records, &numrecords) == 0);
3512         for (i = 0; i < numrecords; i++) {
3513                 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3514                     &dst_time) != 0)
3515                         continue;
3516
3517                 /* is it an internal event or a standard event? */
3518                 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3519                     &cmdstr) != 0) {
3520                         if (cb->internal == 0)
3521                                 continue;
3522
3523                         if (nvlist_lookup_uint64(records[i],
3524                             ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3525                                 continue;
3526                         verify(nvlist_lookup_uint64(records[i],
3527                             ZPOOL_HIST_TXG, &txg) == 0);
3528                         verify(nvlist_lookup_string(records[i],
3529                             ZPOOL_HIST_INT_STR, &pathstr) == 0);
3530                         if (ievent > LOG_END)
3531                                 continue;
3532                         (void) snprintf(internalstr,
3533                             sizeof (internalstr),
3534                             "[internal %s txg:%lld] %s",
3535                             hist_event_table[ievent], txg,
3536                             pathstr);
3537                         cmdstr = internalstr;
3538                 }
3539                 tsec = dst_time;
3540                 (void) localtime_r(&tsec, &t);
3541                 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3542                 (void) printf("%s %s", tbuf, cmdstr);
3543
3544                 if (!cb->longfmt) {
3545                         (void) printf("\n");
3546                         continue;
3547                 }
3548                 (void) printf(" [");
3549                 if (nvlist_lookup_uint64(records[i],
3550                     ZPOOL_HIST_WHO, &who) == 0) {
3551                         pwd = getpwuid((uid_t)who);
3552                         if (pwd)
3553                                 (void) printf("user %s on",
3554                                     pwd->pw_name);
3555                         else
3556                                 (void) printf("user %d on",
3557                                     (int)who);
3558                 } else {
3559                         (void) printf(gettext("no info]\n"));
3560                         continue;
3561                 }
3562                 if (nvlist_lookup_string(records[i],
3563                     ZPOOL_HIST_HOST, &hostname) == 0) {
3564                         (void) printf(" %s", hostname);
3565                 }
3566                 if (nvlist_lookup_string(records[i],
3567                     ZPOOL_HIST_ZONE, &zonename) == 0) {
3568                         (void) printf(":%s", zonename);
3569                 }
3570
3571                 (void) printf("]");
3572                 (void) printf("\n");
3573         }
3574         (void) printf("\n");
3575         nvlist_free(nvhis);
3576
3577         return (ret);
3578 }
3579
3580 /*
3581  * zpool history <pool>
3582  *
3583  * Displays the history of commands that modified pools.
3584  */
3585
3586
3587 int
3588 zpool_do_history(int argc, char **argv)
3589 {
3590         hist_cbdata_t cbdata = { 0 };
3591         int ret;
3592         int c;
3593
3594         cbdata.first = B_TRUE;
3595         /* check options */
3596         while ((c = getopt(argc, argv, "li")) != -1) {
3597                 switch (c) {
3598                 case 'l':
3599                         cbdata.longfmt = 1;
3600                         break;
3601                 case 'i':
3602                         cbdata.internal = 1;
3603                         break;
3604                 case '?':
3605                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3606                             optopt);
3607                         usage(B_FALSE);
3608                 }
3609         }
3610         argc -= optind;
3611         argv += optind;
3612
3613         ret = for_each_pool(argc, argv, B_FALSE,  NULL, get_history_one,
3614             &cbdata);
3615
3616         if (argc == 0 && cbdata.first == B_TRUE) {
3617                 (void) printf(gettext("no pools available\n"));
3618                 return (0);
3619         }
3620
3621         return (ret);
3622 }
3623
3624 static int
3625 get_callback(zpool_handle_t *zhp, void *data)
3626 {
3627         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3628         char value[MAXNAMELEN];
3629         zprop_source_t srctype;
3630         zprop_list_t *pl;
3631
3632         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3633
3634                 /*
3635                  * Skip the special fake placeholder. This will also skip
3636                  * over the name property when 'all' is specified.
3637                  */
3638                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3639                     pl == cbp->cb_proplist)
3640                         continue;
3641
3642                 if (zpool_get_prop(zhp, pl->pl_prop,
3643                     value, sizeof (value), &srctype) != 0)
3644                         continue;
3645
3646                 zprop_print_one_property(zpool_get_name(zhp), cbp,
3647                     zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3648         }
3649         return (0);
3650 }
3651
3652 int
3653 zpool_do_get(int argc, char **argv)
3654 {
3655         zprop_get_cbdata_t cb = { 0 };
3656         zprop_list_t fake_name = { 0 };
3657         int ret;
3658
3659         if (argc < 3)
3660                 usage(B_FALSE);
3661
3662         cb.cb_first = B_TRUE;
3663         cb.cb_sources = ZPROP_SRC_ALL;
3664         cb.cb_columns[0] = GET_COL_NAME;
3665         cb.cb_columns[1] = GET_COL_PROPERTY;
3666         cb.cb_columns[2] = GET_COL_VALUE;
3667         cb.cb_columns[3] = GET_COL_SOURCE;
3668         cb.cb_type = ZFS_TYPE_POOL;
3669
3670         if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
3671             ZFS_TYPE_POOL) != 0)
3672                 usage(B_FALSE);
3673
3674         if (cb.cb_proplist != NULL) {
3675                 fake_name.pl_prop = ZPOOL_PROP_NAME;
3676                 fake_name.pl_width = strlen(gettext("NAME"));
3677                 fake_name.pl_next = cb.cb_proplist;
3678                 cb.cb_proplist = &fake_name;
3679         }
3680
3681         ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3682             get_callback, &cb);
3683
3684         if (cb.cb_proplist == &fake_name)
3685                 zprop_free_list(fake_name.pl_next);
3686         else
3687                 zprop_free_list(cb.cb_proplist);
3688
3689         return (ret);
3690 }
3691
3692 typedef struct set_cbdata {
3693         char *cb_propname;
3694         char *cb_value;
3695         boolean_t cb_any_successful;
3696 } set_cbdata_t;
3697
3698 int
3699 set_callback(zpool_handle_t *zhp, void *data)
3700 {
3701         int error;
3702         set_cbdata_t *cb = (set_cbdata_t *)data;
3703
3704         error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3705
3706         if (!error)
3707                 cb->cb_any_successful = B_TRUE;
3708
3709         return (error);
3710 }
3711
3712 int
3713 zpool_do_set(int argc, char **argv)
3714 {
3715         set_cbdata_t cb = { 0 };
3716         int error;
3717
3718         if (argc > 1 && argv[1][0] == '-') {
3719                 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3720                     argv[1][1]);
3721                 usage(B_FALSE);
3722         }
3723
3724         if (argc < 2) {
3725                 (void) fprintf(stderr, gettext("missing property=value "
3726                     "argument\n"));
3727                 usage(B_FALSE);
3728         }
3729
3730         if (argc < 3) {
3731                 (void) fprintf(stderr, gettext("missing pool name\n"));
3732                 usage(B_FALSE);
3733         }
3734
3735         if (argc > 3) {
3736                 (void) fprintf(stderr, gettext("too many pool names\n"));
3737                 usage(B_FALSE);
3738         }
3739
3740         cb.cb_propname = argv[1];
3741         cb.cb_value = strchr(cb.cb_propname, '=');
3742         if (cb.cb_value == NULL) {
3743                 (void) fprintf(stderr, gettext("missing value in "
3744                     "property=value argument\n"));
3745                 usage(B_FALSE);
3746         }
3747
3748         *(cb.cb_value) = '\0';
3749         cb.cb_value++;
3750
3751         error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3752             set_callback, &cb);
3753
3754         return (error);
3755 }
3756
3757 static int
3758 find_command_idx(char *command, int *idx)
3759 {
3760         int i;
3761
3762         for (i = 0; i < NCOMMAND; i++) {
3763                 if (command_table[i].name == NULL)
3764                         continue;
3765
3766                 if (strcmp(command, command_table[i].name) == 0) {
3767                         *idx = i;
3768                         return (0);
3769                 }
3770         }
3771         return (1);
3772 }
3773
3774 int
3775 main(int argc, char **argv)
3776 {
3777         int ret;
3778         int i;
3779         char *cmdname;
3780
3781         (void) setlocale(LC_ALL, "");
3782         (void) textdomain(TEXT_DOMAIN);
3783
3784         if ((g_zfs = libzfs_init()) == NULL) {
3785                 (void) fprintf(stderr, gettext("internal error: failed to "
3786                     "initialize ZFS library\n"));
3787                 return (1);
3788         }
3789
3790         libzfs_print_on_error(g_zfs, B_TRUE);
3791
3792         opterr = 0;
3793
3794         /*
3795          * Make sure the user has specified some command.
3796          */
3797         if (argc < 2) {
3798                 (void) fprintf(stderr, gettext("missing command\n"));
3799                 usage(B_FALSE);
3800         }
3801
3802         cmdname = argv[1];
3803
3804         /*
3805          * Special case '-?'
3806          */
3807         if (strcmp(cmdname, "-?") == 0)
3808                 usage(B_TRUE);
3809
3810         zpool_set_history_str("zpool", argc, argv, history_str);
3811         verify(zpool_stage_history(g_zfs, history_str) == 0);
3812
3813         /*
3814          * Run the appropriate command.
3815          */
3816         if (find_command_idx(cmdname, &i) == 0) {
3817                 current_command = &command_table[i];
3818                 ret = command_table[i].func(argc - 1, argv + 1);
3819         } else if (strchr(cmdname, '=')) {
3820                 verify(find_command_idx("set", &i) == 0);
3821                 current_command = &command_table[i];
3822                 ret = command_table[i].func(argc, argv);
3823         } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3824                 /*
3825                  * 'freeze' is a vile debugging abomination, so we treat
3826                  * it as such.
3827                  */
3828                 char buf[16384];
3829                 int fd = open(ZFS_DEV, O_RDWR);
3830                 (void) strcpy((void *)buf, argv[2]);
3831                 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3832         } else {
3833                 (void) fprintf(stderr, gettext("unrecognized "
3834                     "command '%s'\n"), cmdname);
3835                 usage(B_FALSE);
3836         }
3837
3838         libzfs_fini(g_zfs);
3839
3840         /*
3841          * The 'ZFS_ABORT' environment variable causes us to dump core on exit
3842          * for the purposes of running ::findleaks.
3843          */
3844         if (getenv("ZFS_ABORT") != NULL) {
3845                 (void) printf("dumping core by request\n");
3846                 abort();
3847         }
3848
3849         return (ret);
3850 }