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