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