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