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