]> git.proxmox.com Git - mirror_zfs.git/blame - cmd/zpool/zpool_main.c
Add AUTHORS to master branch
[mirror_zfs.git] / cmd / zpool / zpool_main.c
CommitLineData
34dc7c2f
BB
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/*
d164b209 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
34dc7c2f
BB
24 * Use is subject to license terms.
25 */
26
34dc7c2f
BB
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
53static int zpool_do_create(int, char **);
54static int zpool_do_destroy(int, char **);
55
56static int zpool_do_add(int, char **);
57static int zpool_do_remove(int, char **);
58
59static int zpool_do_list(int, char **);
60static int zpool_do_iostat(int, char **);
61static int zpool_do_status(int, char **);
62
63static int zpool_do_online(int, char **);
64static int zpool_do_offline(int, char **);
65static int zpool_do_clear(int, char **);
66
67static int zpool_do_attach(int, char **);
68static int zpool_do_detach(int, char **);
69static int zpool_do_replace(int, char **);
70
71static int zpool_do_scrub(int, char **);
72
73static int zpool_do_import(int, char **);
74static int zpool_do_export(int, char **);
75
76static int zpool_do_upgrade(int, char **);
77
78static int zpool_do_history(int, char **);
79
80static int zpool_do_get(int, char **);
81static 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 */
b128c09f
BB
87
88#ifdef DEBUG
34dc7c2f
BB
89const char *
90_umem_debug_init(void)
91{
92 return ("default,verbose"); /* $UMEM_DEBUG setting */
93}
94
95const char *
96_umem_logging_init(void)
97{
98 return ("fail,contents"); /* $UMEM_LOGGING setting */
99}
b128c09f 100#endif
34dc7c2f
BB
101
102typedef 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
126typedef 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 */
141static 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
173zpool_command_t *current_command;
174static char history_str[HIS_MAX_RECORD_LEN];
175
176static const char *
177get_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"
b128c09f 188 "\t [-O file-system-property=value] ... \n"
34dc7c2f
BB
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 */
243static int
244print_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 */
268void
269usage(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
319void
320print_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 */
352static int
b128c09f
BB
353add_prop_list(const char *propname, char *propval, nvlist_t **props,
354 boolean_t poolprop)
34dc7c2f 355{
b128c09f
BB
356 zpool_prop_t prop = ZPROP_INVAL;
357 zfs_prop_t fprop;
34dc7c2f 358 nvlist_t *proplist;
b128c09f
BB
359 const char *normnm;
360 char *strval;
34dc7c2f
BB
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
b128c09f
BB
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 {
9babb374
BB
379 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
380 normnm = zfs_prop_to_name(fprop);
381 } else {
382 normnm = propname;
b128c09f 383 }
34dc7c2f
BB
384 }
385
b128c09f
BB
386 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
387 prop != ZPOOL_PROP_CACHEFILE) {
34dc7c2f
BB
388 (void) fprintf(stderr, gettext("property '%s' "
389 "specified multiple times\n"), propname);
390 return (2);
391 }
392
b128c09f 393 if (nvlist_add_string(proplist, normnm, propval) != 0) {
34dc7c2f
BB
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 */
413int
414zpool_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 */
b128c09f
BB
470 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
471 argc, argv);
34dc7c2f
BB
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 */
516int
517zpool_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/*
b128c09f
BB
550 * zpool create [-fn] [-o property=value] ...
551 * [-O file-system-property=value] ...
552 * [-R root] [-m mountpoint] <pool> <dev> ...
34dc7c2f
BB
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.
b128c09f 561 * -O Set fsproperty=value in the pool's root file system
34dc7c2f
BB
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 */
568int
569zpool_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;
b128c09f 579 nvlist_t *fsprops = NULL;
34dc7c2f
BB
580 nvlist_t *props = NULL;
581 char *propval;
582
583 /* check options */
b128c09f 584 while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
34dc7c2f
BB
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(
b128c09f 595 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
34dc7c2f
BB
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(
b128c09f 602 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
34dc7c2f
BB
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
b128c09f
BB
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))
34dc7c2f
BB
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 */
b128c09f
BB
671 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
672 argc - 1, argv + 1);
34dc7c2f 673 if (nvroot == NULL)
b128c09f 674 goto errout;
34dc7c2f
BB
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 */
b128c09f
BB
766 if (zpool_create(g_zfs, poolname,
767 nvroot, props, fsprops) == 0) {
34dc7c2f
BB
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
786errout:
787 nvlist_free(nvroot);
b128c09f 788 nvlist_free(fsprops);
34dc7c2f
BB
789 nvlist_free(props);
790 return (ret);
791badusage:
b128c09f 792 nvlist_free(fsprops);
34dc7c2f
BB
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 */
805int
806zpool_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 */
875int
876zpool_do_export(int argc, char **argv)
877{
878 boolean_t force = B_FALSE;
fb5f0bc8 879 boolean_t hardforce = B_FALSE;
34dc7c2f
BB
880 int c;
881 zpool_handle_t *zhp;
882 int ret;
883 int i;
884
885 /* check options */
fb5f0bc8 886 while ((c = getopt(argc, argv, "fF")) != -1) {
34dc7c2f
BB
887 switch (c) {
888 case 'f':
889 force = B_TRUE;
890 break;
fb5f0bc8
BB
891 case 'F':
892 hardforce = B_TRUE;
893 break;
34dc7c2f
BB
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
fb5f0bc8
BB
923 if (hardforce) {
924 if (zpool_export_force(zhp) != 0)
925 ret = 1;
926 } else if (zpool_export(zhp, force) != 0) {
34dc7c2f 927 ret = 1;
fb5f0bc8 928 }
34dc7c2f
BB
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 */
940static int
941max_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
9babb374
BB
981typedef struct spare_cbdata {
982 uint64_t cb_guid;
983 zpool_handle_t *cb_zhp;
984} spare_cbdata_t;
985
986static boolean_t
987find_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
1007static int
1008find_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 */
1029void
1030print_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
34dc7c2f
BB
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 */
1162void
9babb374 1163print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
34dc7c2f
BB
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);
9babb374 1220 if (is_log)
34dc7c2f
BB
1221 continue;
1222
1223 vname = zpool_vdev_name(g_zfs, NULL, child[c]);
9babb374 1224 print_import_config(vname, child[c], namewidth, depth + 2);
34dc7c2f
BB
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
9babb374
BB
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 */
1257static void
1258print_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}
34dc7c2f
BB
1286/*
1287 * Display the status for the given pool.
1288 */
1289static void
1290show_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;
b128c09f 1362
34dc7c2f
BB
1363 case ZPOOL_STATUS_HOSTID_MISMATCH:
1364 (void) printf(gettext("status: The pool was last accessed by "
1365 "another system.\n"));
1366 break;
b128c09f 1367
34dc7c2f
BB
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
b128c09f
BB
1374 case ZPOOL_STATUS_BAD_LOG:
1375 (void) printf(gettext("status: An intent log record cannot be "
1376 "read.\n"));
1377 break;
1378
34dc7c2f
BB
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
9babb374
BB
1454 print_import_config(name, nvroot, namewidth, 0);
1455 if (num_logs(nvroot) > 0)
1456 print_logs(NULL, nvroot, namewidth, B_FALSE);
34dc7c2f
BB
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 */
1470static int
1471do_import(nvlist_t *config, const char *newname, const char *mntopts,
45d1cae3 1472 int force, nvlist_t *props, boolean_t do_verbatim)
34dc7c2f
BB
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
45d1cae3 1525 if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
34dc7c2f
BB
1526 return (1);
1527
1528 if (newname != NULL)
1529 name = (char *)newname;
1530
45d1cae3
BB
1531 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
1532 return (1);
34dc7c2f 1533
d164b209
BB
1534 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
1535 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
34dc7c2f
BB
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 *
b128c09f
BB
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
45d1cae3
BB
1569 * vdevs in the FAULTED state. In other words, it does verbatim
1570 * import.
b128c09f 1571 *
34dc7c2f
BB
1572 * -a Import all pools found.
1573 *
1574 * -o Set property=value and/or temporary mount options (without '=').
1575 *
1576 * The import command scans for pools to import, and import pools based on pool
1577 * name and GUID. The pool can also be renamed as part of the import process.
1578 */
1579int
1580zpool_do_import(int argc, char **argv)
1581{
1582 char **searchdirs = NULL;
1583 int nsearch = 0;
1584 int c;
1585 int err;
1586 nvlist_t *pools = NULL;
1587 boolean_t do_all = B_FALSE;
1588 boolean_t do_destroyed = B_FALSE;
1589 char *mntopts = NULL;
1590 boolean_t do_force = B_FALSE;
1591 nvpair_t *elem;
1592 nvlist_t *config;
b128c09f
BB
1593 uint64_t searchguid = 0;
1594 char *searchname = NULL;
34dc7c2f
BB
1595 char *propval;
1596 nvlist_t *found_config;
1597 nvlist_t *props = NULL;
1598 boolean_t first;
45d1cae3 1599 boolean_t do_verbatim = B_FALSE;
34dc7c2f
BB
1600 uint64_t pool_state;
1601 char *cachefile = NULL;
1602
1603 /* check options */
b128c09f 1604 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
34dc7c2f
BB
1605 switch (c) {
1606 case 'a':
1607 do_all = B_TRUE;
1608 break;
1609 case 'c':
1610 cachefile = optarg;
1611 break;
1612 case 'd':
1613 if (searchdirs == NULL) {
1614 searchdirs = safe_malloc(sizeof (char *));
1615 } else {
1616 char **tmp = safe_malloc((nsearch + 1) *
1617 sizeof (char *));
1618 bcopy(searchdirs, tmp, nsearch *
1619 sizeof (char *));
1620 free(searchdirs);
1621 searchdirs = tmp;
1622 }
1623 searchdirs[nsearch++] = optarg;
1624 break;
1625 case 'D':
1626 do_destroyed = B_TRUE;
1627 break;
1628 case 'f':
1629 do_force = B_TRUE;
1630 break;
b128c09f 1631 case 'F':
45d1cae3 1632 do_verbatim = B_TRUE;
b128c09f 1633 break;
34dc7c2f
BB
1634 case 'o':
1635 if ((propval = strchr(optarg, '=')) != NULL) {
1636 *propval = '\0';
1637 propval++;
b128c09f
BB
1638 if (add_prop_list(optarg, propval,
1639 &props, B_TRUE))
34dc7c2f
BB
1640 goto error;
1641 } else {
1642 mntopts = optarg;
1643 }
1644 break;
1645 case 'R':
1646 if (add_prop_list(zpool_prop_to_name(
b128c09f 1647 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
34dc7c2f
BB
1648 goto error;
1649 if (nvlist_lookup_string(props,
1650 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
1651 &propval) == 0)
1652 break;
1653 if (add_prop_list(zpool_prop_to_name(
b128c09f 1654 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
34dc7c2f
BB
1655 goto error;
1656 break;
1657 case ':':
1658 (void) fprintf(stderr, gettext("missing argument for "
1659 "'%c' option\n"), optopt);
1660 usage(B_FALSE);
1661 break;
1662 case '?':
1663 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1664 optopt);
1665 usage(B_FALSE);
1666 }
1667 }
1668
1669 argc -= optind;
1670 argv += optind;
1671
1672 if (cachefile && nsearch != 0) {
1673 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
1674 usage(B_FALSE);
1675 }
1676
1677 if (searchdirs == NULL) {
1678 searchdirs = safe_malloc(sizeof (char *));
1679 searchdirs[0] = "/dev/dsk";
1680 nsearch = 1;
1681 }
1682
1683 /* check argument count */
1684 if (do_all) {
1685 if (argc != 0) {
1686 (void) fprintf(stderr, gettext("too many arguments\n"));
1687 usage(B_FALSE);
1688 }
1689 } else {
1690 if (argc > 2) {
1691 (void) fprintf(stderr, gettext("too many arguments\n"));
1692 usage(B_FALSE);
1693 }
1694
1695 /*
1696 * Check for the SYS_CONFIG privilege. We do this explicitly
1697 * here because otherwise any attempt to discover pools will
1698 * silently fail.
1699 */
1700 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
1701 (void) fprintf(stderr, gettext("cannot "
1702 "discover pools: permission denied\n"));
1703 free(searchdirs);
1704 return (1);
1705 }
1706 }
1707
34dc7c2f 1708 /*
34dc7c2f
BB
1709 * Depending on the arguments given, we do one of the following:
1710 *
1711 * <none> Iterate through all pools and display information about
1712 * each one.
1713 *
1714 * -a Iterate through all pools and try to import each one.
1715 *
1716 * <id> Find the pool that corresponds to the given GUID/pool
1717 * name and import that one.
1718 *
1719 * -D Above options applies only to destroyed pools.
1720 */
1721 if (argc != 0) {
1722 char *endptr;
1723
1724 errno = 0;
1725 searchguid = strtoull(argv[0], &endptr, 10);
1726 if (errno != 0 || *endptr != '\0')
1727 searchname = argv[0];
34dc7c2f
BB
1728 found_config = NULL;
1729 }
1730
b128c09f
BB
1731 if (cachefile) {
1732 pools = zpool_find_import_cached(g_zfs, cachefile, searchname,
1733 searchguid);
1734 } else if (searchname != NULL) {
1735 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
1736 searchname);
1737 } else {
1738 /*
1739 * It's OK to search by guid even if searchguid is 0.
1740 */
1741 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
1742 searchguid);
1743 }
1744
1745 if (pools == NULL) {
1746 if (argc != 0) {
1747 (void) fprintf(stderr, gettext("cannot import '%s': "
1748 "no such pool available\n"), argv[0]);
1749 }
1750 free(searchdirs);
1751 return (1);
1752 }
1753
1754 /*
1755 * At this point we have a list of import candidate configs. Even if
1756 * we were searching by pool name or guid, we still need to
1757 * post-process the list to deal with pool state and possible
1758 * duplicate names.
1759 */
34dc7c2f
BB
1760 err = 0;
1761 elem = NULL;
1762 first = B_TRUE;
1763 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1764
1765 verify(nvpair_value_nvlist(elem, &config) == 0);
1766
1767 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1768 &pool_state) == 0);
1769 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
1770 continue;
1771 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
1772 continue;
1773
1774 if (argc == 0) {
1775 if (first)
1776 first = B_FALSE;
1777 else if (!do_all)
1778 (void) printf("\n");
1779
1780 if (do_all)
1781 err |= do_import(config, NULL, mntopts,
45d1cae3 1782 do_force, props, do_verbatim);
34dc7c2f
BB
1783 else
1784 show_import(config);
1785 } else if (searchname != NULL) {
1786 char *name;
1787
1788 /*
1789 * We are searching for a pool based on name.
1790 */
1791 verify(nvlist_lookup_string(config,
1792 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
1793
1794 if (strcmp(name, searchname) == 0) {
1795 if (found_config != NULL) {
1796 (void) fprintf(stderr, gettext(
1797 "cannot import '%s': more than "
1798 "one matching pool\n"), searchname);
1799 (void) fprintf(stderr, gettext(
1800 "import by numeric ID instead\n"));
1801 err = B_TRUE;
1802 }
1803 found_config = config;
1804 }
1805 } else {
1806 uint64_t guid;
1807
1808 /*
1809 * Search for a pool by guid.
1810 */
1811 verify(nvlist_lookup_uint64(config,
1812 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
1813
1814 if (guid == searchguid)
1815 found_config = config;
1816 }
1817 }
1818
1819 /*
1820 * If we were searching for a specific pool, verify that we found a
1821 * pool, and then do the import.
1822 */
1823 if (argc != 0 && err == 0) {
1824 if (found_config == NULL) {
1825 (void) fprintf(stderr, gettext("cannot import '%s': "
1826 "no such pool available\n"), argv[0]);
1827 err = B_TRUE;
1828 } else {
1829 err |= do_import(found_config, argc == 1 ? NULL :
45d1cae3 1830 argv[1], mntopts, do_force, props, do_verbatim);
34dc7c2f
BB
1831 }
1832 }
1833
1834 /*
1835 * If we were just looking for pools, report an error if none were
1836 * found.
1837 */
1838 if (argc == 0 && first)
1839 (void) fprintf(stderr,
1840 gettext("no pools available to import\n"));
1841
1842error:
1843 nvlist_free(props);
1844 nvlist_free(pools);
1845 free(searchdirs);
1846
1847 return (err ? 1 : 0);
1848}
1849
1850typedef struct iostat_cbdata {
1851 zpool_list_t *cb_list;
1852 int cb_verbose;
1853 int cb_iteration;
1854 int cb_namewidth;
1855} iostat_cbdata_t;
1856
1857static void
1858print_iostat_separator(iostat_cbdata_t *cb)
1859{
1860 int i = 0;
1861
1862 for (i = 0; i < cb->cb_namewidth; i++)
1863 (void) printf("-");
1864 (void) printf(" ----- ----- ----- ----- ----- -----\n");
1865}
1866
1867static void
1868print_iostat_header(iostat_cbdata_t *cb)
1869{
1870 (void) printf("%*s capacity operations bandwidth\n",
1871 cb->cb_namewidth, "");
1872 (void) printf("%-*s used avail read write read write\n",
1873 cb->cb_namewidth, "pool");
1874 print_iostat_separator(cb);
1875}
1876
1877/*
1878 * Display a single statistic.
1879 */
1880static void
1881print_one_stat(uint64_t value)
1882{
1883 char buf[64];
1884
1885 zfs_nicenum(value, buf, sizeof (buf));
1886 (void) printf(" %5s", buf);
1887}
1888
1889/*
1890 * Print out all the statistics for the given vdev. This can either be the
1891 * toplevel configuration, or called recursively. If 'name' is NULL, then this
1892 * is a verbose output, and we don't want to display the toplevel pool stats.
1893 */
1894void
1895print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
1896 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
1897{
1898 nvlist_t **oldchild, **newchild;
1899 uint_t c, children;
1900 vdev_stat_t *oldvs, *newvs;
1901 vdev_stat_t zerovs = { 0 };
1902 uint64_t tdelta;
1903 double scale;
1904 char *vname;
1905
1906 if (oldnv != NULL) {
1907 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
1908 (uint64_t **)&oldvs, &c) == 0);
1909 } else {
1910 oldvs = &zerovs;
1911 }
1912
1913 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
1914 (uint64_t **)&newvs, &c) == 0);
1915
1916 if (strlen(name) + depth > cb->cb_namewidth)
1917 (void) printf("%*s%s", depth, "", name);
1918 else
1919 (void) printf("%*s%s%*s", depth, "", name,
1920 (int)(cb->cb_namewidth - strlen(name) - depth), "");
1921
1922 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
1923
1924 if (tdelta == 0)
1925 scale = 1.0;
1926 else
1927 scale = (double)NANOSEC / tdelta;
1928
1929 /* only toplevel vdevs have capacity stats */
1930 if (newvs->vs_space == 0) {
1931 (void) printf(" - -");
1932 } else {
1933 print_one_stat(newvs->vs_alloc);
1934 print_one_stat(newvs->vs_space - newvs->vs_alloc);
1935 }
1936
1937 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
1938 oldvs->vs_ops[ZIO_TYPE_READ])));
1939
1940 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
1941 oldvs->vs_ops[ZIO_TYPE_WRITE])));
1942
1943 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
1944 oldvs->vs_bytes[ZIO_TYPE_READ])));
1945
1946 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
1947 oldvs->vs_bytes[ZIO_TYPE_WRITE])));
1948
1949 (void) printf("\n");
1950
1951 if (!cb->cb_verbose)
1952 return;
1953
1954 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
1955 &newchild, &children) != 0)
1956 return;
1957
1958 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
1959 &oldchild, &c) != 0)
1960 return;
1961
1962 for (c = 0; c < children; c++) {
1963 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1964 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1965 newchild[c], cb, depth + 2);
1966 free(vname);
1967 }
1968
1969 /*
1970 * Include level 2 ARC devices in iostat output
1971 */
1972 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
1973 &newchild, &children) != 0)
1974 return;
1975
1976 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
1977 &oldchild, &c) != 0)
1978 return;
1979
1980 if (children > 0) {
1981 (void) printf("%-*s - - - - - "
1982 "-\n", cb->cb_namewidth, "cache");
1983 for (c = 0; c < children; c++) {
1984 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
1985 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
1986 newchild[c], cb, depth + 2);
1987 free(vname);
1988 }
1989 }
1990}
1991
1992static int
1993refresh_iostat(zpool_handle_t *zhp, void *data)
1994{
1995 iostat_cbdata_t *cb = data;
1996 boolean_t missing;
1997
1998 /*
1999 * If the pool has disappeared, remove it from the list and continue.
2000 */
2001 if (zpool_refresh_stats(zhp, &missing) != 0)
2002 return (-1);
2003
2004 if (missing)
2005 pool_list_remove(cb->cb_list, zhp);
2006
2007 return (0);
2008}
2009
2010/*
2011 * Callback to print out the iostats for the given pool.
2012 */
2013int
2014print_iostat(zpool_handle_t *zhp, void *data)
2015{
2016 iostat_cbdata_t *cb = data;
2017 nvlist_t *oldconfig, *newconfig;
2018 nvlist_t *oldnvroot, *newnvroot;
2019
2020 newconfig = zpool_get_config(zhp, &oldconfig);
2021
2022 if (cb->cb_iteration == 1)
2023 oldconfig = NULL;
2024
2025 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
2026 &newnvroot) == 0);
2027
2028 if (oldconfig == NULL)
2029 oldnvroot = NULL;
2030 else
2031 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
2032 &oldnvroot) == 0);
2033
2034 /*
2035 * Print out the statistics for the pool.
2036 */
2037 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
2038
2039 if (cb->cb_verbose)
2040 print_iostat_separator(cb);
2041
2042 return (0);
2043}
2044
2045int
2046get_namewidth(zpool_handle_t *zhp, void *data)
2047{
2048 iostat_cbdata_t *cb = data;
2049 nvlist_t *config, *nvroot;
2050
2051 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
2052 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2053 &nvroot) == 0);
2054 if (!cb->cb_verbose)
2055 cb->cb_namewidth = strlen(zpool_get_name(zhp));
2056 else
2057 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
2058 }
2059
2060 /*
2061 * The width must fall into the range [10,38]. The upper limit is the
2062 * maximum we can have and still fit in 80 columns.
2063 */
2064 if (cb->cb_namewidth < 10)
2065 cb->cb_namewidth = 10;
2066 if (cb->cb_namewidth > 38)
2067 cb->cb_namewidth = 38;
2068
2069 return (0);
2070}
2071
2072/*
2073 * zpool iostat [-v] [pool] ... [interval [count]]
2074 *
2075 * -v Display statistics for individual vdevs
2076 *
2077 * This command can be tricky because we want to be able to deal with pool
2078 * creation/destruction as well as vdev configuration changes. The bulk of this
2079 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
2080 * on pool_list_update() to detect the addition of new pools. Configuration
2081 * changes are all handled within libzfs.
2082 */
2083int
2084zpool_do_iostat(int argc, char **argv)
2085{
2086 int c;
2087 int ret;
2088 int npools;
2089 unsigned long interval = 0, count = 0;
2090 zpool_list_t *list;
2091 boolean_t verbose = B_FALSE;
2092 iostat_cbdata_t cb;
2093
2094 /* check options */
2095 while ((c = getopt(argc, argv, "v")) != -1) {
2096 switch (c) {
2097 case 'v':
2098 verbose = B_TRUE;
2099 break;
2100 case '?':
2101 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2102 optopt);
2103 usage(B_FALSE);
2104 }
2105 }
2106
2107 argc -= optind;
2108 argv += optind;
2109
2110 /*
2111 * Determine if the last argument is an integer or a pool name
2112 */
2113 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2114 char *end;
2115
2116 errno = 0;
2117 interval = strtoul(argv[argc - 1], &end, 10);
2118
2119 if (*end == '\0' && errno == 0) {
2120 if (interval == 0) {
2121 (void) fprintf(stderr, gettext("interval "
2122 "cannot be zero\n"));
2123 usage(B_FALSE);
2124 }
2125
2126 /*
2127 * Ignore the last parameter
2128 */
2129 argc--;
2130 } else {
2131 /*
2132 * If this is not a valid number, just plow on. The
2133 * user will get a more informative error message later
2134 * on.
2135 */
2136 interval = 0;
2137 }
2138 }
2139
2140 /*
2141 * If the last argument is also an integer, then we have both a count
2142 * and an integer.
2143 */
2144 if (argc > 0 && isdigit(argv[argc - 1][0])) {
2145 char *end;
2146
2147 errno = 0;
2148 count = interval;
2149 interval = strtoul(argv[argc - 1], &end, 10);
2150
2151 if (*end == '\0' && errno == 0) {
2152 if (interval == 0) {
2153 (void) fprintf(stderr, gettext("interval "
2154 "cannot be zero\n"));
2155 usage(B_FALSE);
2156 }
2157
2158 /*
2159 * Ignore the last parameter
2160 */
2161 argc--;
2162 } else {
2163 interval = 0;
2164 }
2165 }
2166
2167 /*
2168 * Construct the list of all interesting pools.
2169 */
2170 ret = 0;
2171 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
2172 return (1);
2173
2174 if (pool_list_count(list) == 0 && argc != 0) {
2175 pool_list_free(list);
2176 return (1);
2177 }
2178
2179 if (pool_list_count(list) == 0 && interval == 0) {
2180 pool_list_free(list);
2181 (void) fprintf(stderr, gettext("no pools available\n"));
2182 return (1);
2183 }
2184
2185 /*
2186 * Enter the main iostat loop.
2187 */
2188 cb.cb_list = list;
2189 cb.cb_verbose = verbose;
2190 cb.cb_iteration = 0;
2191 cb.cb_namewidth = 0;
2192
2193 for (;;) {
2194 pool_list_update(list);
2195
2196 if ((npools = pool_list_count(list)) == 0)
2197 break;
2198
2199 /*
2200 * Refresh all statistics. This is done as an explicit step
2201 * before calculating the maximum name width, so that any
2202 * configuration changes are properly accounted for.
2203 */
2204 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
2205
2206 /*
2207 * Iterate over all pools to determine the maximum width
2208 * for the pool / device name column across all pools.
2209 */
2210 cb.cb_namewidth = 0;
2211 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
2212
2213 /*
2214 * If it's the first time, or verbose mode, print the header.
2215 */
2216 if (++cb.cb_iteration == 1 || verbose)
2217 print_iostat_header(&cb);
2218
2219 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
2220
2221 /*
2222 * If there's more than one pool, and we're not in verbose mode
2223 * (which prints a separator for us), then print a separator.
2224 */
2225 if (npools > 1 && !verbose)
2226 print_iostat_separator(&cb);
2227
2228 if (verbose)
2229 (void) printf("\n");
2230
2231 /*
2232 * Flush the output so that redirection to a file isn't buffered
2233 * indefinitely.
2234 */
2235 (void) fflush(stdout);
2236
2237 if (interval == 0)
2238 break;
2239
2240 if (count != 0 && --count == 0)
2241 break;
2242
2243 (void) sleep(interval);
2244 }
2245
2246 pool_list_free(list);
2247
2248 return (ret);
2249}
2250
2251typedef struct list_cbdata {
2252 boolean_t cb_scripted;
2253 boolean_t cb_first;
2254 zprop_list_t *cb_proplist;
2255} list_cbdata_t;
2256
2257/*
2258 * Given a list of columns to display, output appropriate headers for each one.
2259 */
2260static void
2261print_header(zprop_list_t *pl)
2262{
2263 const char *header;
2264 boolean_t first = B_TRUE;
2265 boolean_t right_justify;
2266
2267 for (; pl != NULL; pl = pl->pl_next) {
2268 if (pl->pl_prop == ZPROP_INVAL)
2269 continue;
2270
2271 if (!first)
2272 (void) printf(" ");
2273 else
2274 first = B_FALSE;
2275
2276 header = zpool_prop_column_name(pl->pl_prop);
2277 right_justify = zpool_prop_align_right(pl->pl_prop);
2278
2279 if (pl->pl_next == NULL && !right_justify)
2280 (void) printf("%s", header);
2281 else if (right_justify)
2282 (void) printf("%*s", pl->pl_width, header);
2283 else
2284 (void) printf("%-*s", pl->pl_width, header);
2285 }
2286
2287 (void) printf("\n");
2288}
2289
2290/*
2291 * Given a pool and a list of properties, print out all the properties according
2292 * to the described layout.
2293 */
2294static void
2295print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
2296{
2297 boolean_t first = B_TRUE;
2298 char property[ZPOOL_MAXPROPLEN];
2299 char *propstr;
2300 boolean_t right_justify;
2301 int width;
2302
2303 for (; pl != NULL; pl = pl->pl_next) {
2304 if (!first) {
2305 if (scripted)
2306 (void) printf("\t");
2307 else
2308 (void) printf(" ");
2309 } else {
2310 first = B_FALSE;
2311 }
2312
2313 right_justify = B_FALSE;
2314 if (pl->pl_prop != ZPROP_INVAL) {
2315 if (zpool_get_prop(zhp, pl->pl_prop, property,
2316 sizeof (property), NULL) != 0)
2317 propstr = "-";
2318 else
2319 propstr = property;
2320
2321 right_justify = zpool_prop_align_right(pl->pl_prop);
2322 } else {
2323 propstr = "-";
2324 }
2325
2326 width = pl->pl_width;
2327
2328 /*
2329 * If this is being called in scripted mode, or if this is the
2330 * last column and it is left-justified, don't include a width
2331 * format specifier.
2332 */
2333 if (scripted || (pl->pl_next == NULL && !right_justify))
2334 (void) printf("%s", propstr);
2335 else if (right_justify)
2336 (void) printf("%*s", width, propstr);
2337 else
2338 (void) printf("%-*s", width, propstr);
2339 }
2340
2341 (void) printf("\n");
2342}
2343
2344/*
2345 * Generic callback function to list a pool.
2346 */
2347int
2348list_callback(zpool_handle_t *zhp, void *data)
2349{
2350 list_cbdata_t *cbp = data;
2351
2352 if (cbp->cb_first) {
2353 if (!cbp->cb_scripted)
2354 print_header(cbp->cb_proplist);
2355 cbp->cb_first = B_FALSE;
2356 }
2357
2358 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
2359
2360 return (0);
2361}
2362
2363/*
2364 * zpool list [-H] [-o prop[,prop]*] [pool] ...
2365 *
2366 * -H Scripted mode. Don't display headers, and separate properties
2367 * by a single tab.
2368 * -o List of properties to display. Defaults to
2369 * "name,size,used,available,capacity,health,altroot"
2370 *
2371 * List all pools in the system, whether or not they're healthy. Output space
2372 * statistics for each one, as well as health status summary.
2373 */
2374int
2375zpool_do_list(int argc, char **argv)
2376{
2377 int c;
2378 int ret;
2379 list_cbdata_t cb = { 0 };
2380 static char default_props[] =
2381 "name,size,used,available,capacity,health,altroot";
2382 char *props = default_props;
2383
2384 /* check options */
2385 while ((c = getopt(argc, argv, ":Ho:")) != -1) {
2386 switch (c) {
2387 case 'H':
2388 cb.cb_scripted = B_TRUE;
2389 break;
2390 case 'o':
2391 props = optarg;
2392 break;
2393 case ':':
2394 (void) fprintf(stderr, gettext("missing argument for "
2395 "'%c' option\n"), optopt);
2396 usage(B_FALSE);
2397 break;
2398 case '?':
2399 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2400 optopt);
2401 usage(B_FALSE);
2402 }
2403 }
2404
2405 argc -= optind;
2406 argv += optind;
2407
2408 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
2409 usage(B_FALSE);
2410
2411 cb.cb_first = B_TRUE;
2412
2413 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
2414 list_callback, &cb);
2415
2416 zprop_free_list(cb.cb_proplist);
2417
2418 if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
2419 (void) printf(gettext("no pools available\n"));
2420 return (0);
2421 }
2422
2423 return (ret);
2424}
2425
2426static nvlist_t *
2427zpool_get_vdev_by_name(nvlist_t *nv, char *name)
2428{
2429 nvlist_t **child;
2430 uint_t c, children;
2431 nvlist_t *match;
2432 char *path;
2433
2434 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2435 &child, &children) != 0) {
2436 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
2437 if (strncmp(name, "/dev/dsk/", 9) == 0)
2438 name += 9;
2439 if (strncmp(path, "/dev/dsk/", 9) == 0)
2440 path += 9;
2441 if (strcmp(name, path) == 0)
2442 return (nv);
2443 return (NULL);
2444 }
2445
2446 for (c = 0; c < children; c++)
2447 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
2448 return (match);
2449
2450 return (NULL);
2451}
2452
2453static int
2454zpool_do_attach_or_replace(int argc, char **argv, int replacing)
2455{
2456 boolean_t force = B_FALSE;
2457 int c;
2458 nvlist_t *nvroot;
2459 char *poolname, *old_disk, *new_disk;
2460 zpool_handle_t *zhp;
2461 int ret;
2462
2463 /* check options */
2464 while ((c = getopt(argc, argv, "f")) != -1) {
2465 switch (c) {
2466 case 'f':
2467 force = B_TRUE;
2468 break;
2469 case '?':
2470 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2471 optopt);
2472 usage(B_FALSE);
2473 }
2474 }
2475
2476 argc -= optind;
2477 argv += optind;
2478
2479 /* get pool name and check number of arguments */
2480 if (argc < 1) {
2481 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2482 usage(B_FALSE);
2483 }
2484
2485 poolname = argv[0];
2486
2487 if (argc < 2) {
2488 (void) fprintf(stderr,
2489 gettext("missing <device> specification\n"));
2490 usage(B_FALSE);
2491 }
2492
2493 old_disk = argv[1];
2494
2495 if (argc < 3) {
2496 if (!replacing) {
2497 (void) fprintf(stderr,
2498 gettext("missing <new_device> specification\n"));
2499 usage(B_FALSE);
2500 }
2501 new_disk = old_disk;
2502 argc -= 1;
2503 argv += 1;
2504 } else {
2505 new_disk = argv[2];
2506 argc -= 2;
2507 argv += 2;
2508 }
2509
2510 if (argc > 1) {
2511 (void) fprintf(stderr, gettext("too many arguments\n"));
2512 usage(B_FALSE);
2513 }
2514
2515 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2516 return (1);
2517
2518 if (zpool_get_config(zhp, NULL) == NULL) {
2519 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
2520 poolname);
2521 zpool_close(zhp);
2522 return (1);
2523 }
2524
b128c09f
BB
2525 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
2526 argc, argv);
34dc7c2f
BB
2527 if (nvroot == NULL) {
2528 zpool_close(zhp);
2529 return (1);
2530 }
2531
2532 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
2533
2534 nvlist_free(nvroot);
2535 zpool_close(zhp);
2536
2537 return (ret);
2538}
2539
2540/*
2541 * zpool replace [-f] <pool> <device> <new_device>
2542 *
2543 * -f Force attach, even if <new_device> appears to be in use.
2544 *
2545 * Replace <device> with <new_device>.
2546 */
2547/* ARGSUSED */
2548int
2549zpool_do_replace(int argc, char **argv)
2550{
2551 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
2552}
2553
2554/*
2555 * zpool attach [-f] <pool> <device> <new_device>
2556 *
2557 * -f Force attach, even if <new_device> appears to be in use.
2558 *
2559 * Attach <new_device> to the mirror containing <device>. If <device> is not
2560 * part of a mirror, then <device> will be transformed into a mirror of
2561 * <device> and <new_device>. In either case, <new_device> will begin life
2562 * with a DTL of [0, now], and will immediately begin to resilver itself.
2563 */
2564int
2565zpool_do_attach(int argc, char **argv)
2566{
2567 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
2568}
2569
2570/*
2571 * zpool detach [-f] <pool> <device>
2572 *
2573 * -f Force detach of <device>, even if DTLs argue against it
2574 * (not supported yet)
2575 *
2576 * Detach a device from a mirror. The operation will be refused if <device>
2577 * is the last device in the mirror, or if the DTLs indicate that this device
2578 * has the only valid copy of some data.
2579 */
2580/* ARGSUSED */
2581int
2582zpool_do_detach(int argc, char **argv)
2583{
2584 int c;
2585 char *poolname, *path;
2586 zpool_handle_t *zhp;
2587 int ret;
2588
2589 /* check options */
2590 while ((c = getopt(argc, argv, "f")) != -1) {
2591 switch (c) {
2592 case 'f':
2593 case '?':
2594 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2595 optopt);
2596 usage(B_FALSE);
2597 }
2598 }
2599
2600 argc -= optind;
2601 argv += optind;
2602
2603 /* get pool name and check number of arguments */
2604 if (argc < 1) {
2605 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2606 usage(B_FALSE);
2607 }
2608
2609 if (argc < 2) {
2610 (void) fprintf(stderr,
2611 gettext("missing <device> specification\n"));
2612 usage(B_FALSE);
2613 }
2614
2615 poolname = argv[0];
2616 path = argv[1];
2617
2618 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2619 return (1);
2620
2621 ret = zpool_vdev_detach(zhp, path);
2622
2623 zpool_close(zhp);
2624
2625 return (ret);
2626}
2627
2628/*
2629 * zpool online <pool> <device> ...
2630 */
2631int
2632zpool_do_online(int argc, char **argv)
2633{
2634 int c, i;
2635 char *poolname;
2636 zpool_handle_t *zhp;
2637 int ret = 0;
2638 vdev_state_t newstate;
9babb374 2639 int flags = 0;
34dc7c2f
BB
2640
2641 /* check options */
9babb374 2642 while ((c = getopt(argc, argv, "et")) != -1) {
34dc7c2f 2643 switch (c) {
9babb374
BB
2644 case 'e':
2645 flags |= ZFS_ONLINE_EXPAND;
2646 break;
34dc7c2f
BB
2647 case 't':
2648 case '?':
2649 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2650 optopt);
2651 usage(B_FALSE);
2652 }
2653 }
2654
2655 argc -= optind;
2656 argv += optind;
2657
2658 /* get pool name and check number of arguments */
2659 if (argc < 1) {
2660 (void) fprintf(stderr, gettext("missing pool name\n"));
2661 usage(B_FALSE);
2662 }
2663 if (argc < 2) {
2664 (void) fprintf(stderr, gettext("missing device name\n"));
2665 usage(B_FALSE);
2666 }
2667
2668 poolname = argv[0];
2669
2670 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2671 return (1);
2672
2673 for (i = 1; i < argc; i++) {
9babb374 2674 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
34dc7c2f
BB
2675 if (newstate != VDEV_STATE_HEALTHY) {
2676 (void) printf(gettext("warning: device '%s' "
2677 "onlined, but remains in faulted state\n"),
2678 argv[i]);
2679 if (newstate == VDEV_STATE_FAULTED)
2680 (void) printf(gettext("use 'zpool "
2681 "clear' to restore a faulted "
2682 "device\n"));
2683 else
2684 (void) printf(gettext("use 'zpool "
2685 "replace' to replace devices "
2686 "that are no longer present\n"));
2687 }
2688 } else {
2689 ret = 1;
2690 }
2691 }
2692
2693 zpool_close(zhp);
2694
2695 return (ret);
2696}
2697
2698/*
2699 * zpool offline [-ft] <pool> <device> ...
2700 *
2701 * -f Force the device into the offline state, even if doing
2702 * so would appear to compromise pool availability.
2703 * (not supported yet)
2704 *
2705 * -t Only take the device off-line temporarily. The offline
2706 * state will not be persistent across reboots.
2707 */
2708/* ARGSUSED */
2709int
2710zpool_do_offline(int argc, char **argv)
2711{
2712 int c, i;
2713 char *poolname;
2714 zpool_handle_t *zhp;
2715 int ret = 0;
2716 boolean_t istmp = B_FALSE;
2717
2718 /* check options */
2719 while ((c = getopt(argc, argv, "ft")) != -1) {
2720 switch (c) {
2721 case 't':
2722 istmp = B_TRUE;
2723 break;
2724 case 'f':
2725 case '?':
2726 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2727 optopt);
2728 usage(B_FALSE);
2729 }
2730 }
2731
2732 argc -= optind;
2733 argv += optind;
2734
2735 /* get pool name and check number of arguments */
2736 if (argc < 1) {
2737 (void) fprintf(stderr, gettext("missing pool name\n"));
2738 usage(B_FALSE);
2739 }
2740 if (argc < 2) {
2741 (void) fprintf(stderr, gettext("missing device name\n"));
2742 usage(B_FALSE);
2743 }
2744
2745 poolname = argv[0];
2746
2747 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
2748 return (1);
2749
2750 for (i = 1; i < argc; i++) {
2751 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
2752 ret = 1;
2753 }
2754
2755 zpool_close(zhp);
2756
2757 return (ret);
2758}
2759
2760/*
2761 * zpool clear <pool> [device]
2762 *
2763 * Clear all errors associated with a pool or a particular device.
2764 */
2765int
2766zpool_do_clear(int argc, char **argv)
2767{
2768 int ret = 0;
2769 zpool_handle_t *zhp;
2770 char *pool, *device;
2771
2772 if (argc < 2) {
2773 (void) fprintf(stderr, gettext("missing pool name\n"));
2774 usage(B_FALSE);
2775 }
2776
2777 if (argc > 3) {
2778 (void) fprintf(stderr, gettext("too many arguments\n"));
2779 usage(B_FALSE);
2780 }
2781
2782 pool = argv[1];
2783 device = argc == 3 ? argv[2] : NULL;
2784
b128c09f 2785 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
34dc7c2f
BB
2786 return (1);
2787
2788 if (zpool_clear(zhp, device) != 0)
2789 ret = 1;
2790
2791 zpool_close(zhp);
2792
2793 return (ret);
2794}
2795
2796typedef struct scrub_cbdata {
2797 int cb_type;
2798 int cb_argc;
2799 char **cb_argv;
2800} scrub_cbdata_t;
2801
2802int
2803scrub_callback(zpool_handle_t *zhp, void *data)
2804{
2805 scrub_cbdata_t *cb = data;
2806 int err;
2807
2808 /*
2809 * Ignore faulted pools.
2810 */
2811 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
2812 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
2813 "currently unavailable\n"), zpool_get_name(zhp));
2814 return (1);
2815 }
2816
2817 err = zpool_scrub(zhp, cb->cb_type);
2818
2819 return (err != 0);
2820}
2821
2822/*
2823 * zpool scrub [-s] <pool> ...
2824 *
2825 * -s Stop. Stops any in-progress scrub.
2826 */
2827int
2828zpool_do_scrub(int argc, char **argv)
2829{
2830 int c;
2831 scrub_cbdata_t cb;
2832
2833 cb.cb_type = POOL_SCRUB_EVERYTHING;
2834
2835 /* check options */
2836 while ((c = getopt(argc, argv, "s")) != -1) {
2837 switch (c) {
2838 case 's':
2839 cb.cb_type = POOL_SCRUB_NONE;
2840 break;
2841 case '?':
2842 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2843 optopt);
2844 usage(B_FALSE);
2845 }
2846 }
2847
2848 cb.cb_argc = argc;
2849 cb.cb_argv = argv;
2850 argc -= optind;
2851 argv += optind;
2852
2853 if (argc < 1) {
2854 (void) fprintf(stderr, gettext("missing pool name argument\n"));
2855 usage(B_FALSE);
2856 }
2857
2858 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
2859}
2860
2861typedef struct status_cbdata {
2862 int cb_count;
2863 boolean_t cb_allpools;
2864 boolean_t cb_verbose;
2865 boolean_t cb_explain;
2866 boolean_t cb_first;
2867} status_cbdata_t;
2868
2869/*
2870 * Print out detailed scrub status.
2871 */
2872void
2873print_scrub_status(nvlist_t *nvroot)
2874{
2875 vdev_stat_t *vs;
2876 uint_t vsc;
2877 time_t start, end, now;
2878 double fraction_done;
2879 uint64_t examined, total, minutes_left, minutes_taken;
2880 char *scrub_type;
2881
2882 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
2883 (uint64_t **)&vs, &vsc) == 0);
2884
2885 /*
2886 * If there's never been a scrub, there's not much to say.
2887 */
2888 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
2889 (void) printf(gettext("none requested\n"));
2890 return;
2891 }
2892
2893 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
2894 "resilver" : "scrub";
2895
2896 start = vs->vs_scrub_start;
2897 end = vs->vs_scrub_end;
2898 now = time(NULL);
2899 examined = vs->vs_scrub_examined;
2900 total = vs->vs_alloc;
2901
2902 if (end != 0) {
2903 minutes_taken = (uint64_t)((end - start) / 60);
2904
2905 (void) printf(gettext("%s %s after %lluh%um with %llu errors "
2906 "on %s"),
2907 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
2908 (u_longlong_t)(minutes_taken / 60),
2909 (uint_t)(minutes_taken % 60),
2910 (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
2911 return;
2912 }
2913
2914 if (examined == 0)
2915 examined = 1;
2916 if (examined > total)
2917 total = examined;
2918
2919 fraction_done = (double)examined / total;
2920 minutes_left = (uint64_t)((now - start) *
2921 (1 - fraction_done) / fraction_done / 60);
2922 minutes_taken = (uint64_t)((now - start) / 60);
2923
2924 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
2925 "%lluh%um to go\n"),
2926 scrub_type, (u_longlong_t)(minutes_taken / 60),
2927 (uint_t)(minutes_taken % 60), 100 * fraction_done,
2928 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
2929}
2930
34dc7c2f
BB
2931static void
2932print_error_log(zpool_handle_t *zhp)
2933{
2934 nvlist_t *nverrlist = NULL;
2935 nvpair_t *elem;
2936 char *pathname;
2937 size_t len = MAXPATHLEN * 2;
2938
2939 if (zpool_get_errlog(zhp, &nverrlist) != 0) {
2940 (void) printf("errors: List of errors unavailable "
2941 "(insufficient privileges)\n");
2942 return;
2943 }
2944
2945 (void) printf("errors: Permanent errors have been "
2946 "detected in the following files:\n\n");
2947
2948 pathname = safe_malloc(len);
2949 elem = NULL;
2950 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
2951 nvlist_t *nv;
2952 uint64_t dsobj, obj;
2953
2954 verify(nvpair_value_nvlist(elem, &nv) == 0);
2955 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
2956 &dsobj) == 0);
2957 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
2958 &obj) == 0);
2959 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
2960 (void) printf("%7s %s\n", "", pathname);
2961 }
2962 free(pathname);
2963 nvlist_free(nverrlist);
2964}
2965
2966static void
2967print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
2968 int namewidth)
2969{
2970 uint_t i;
2971 char *name;
2972
2973 if (nspares == 0)
2974 return;
2975
2976 (void) printf(gettext("\tspares\n"));
2977
2978 for (i = 0; i < nspares; i++) {
2979 name = zpool_vdev_name(g_zfs, zhp, spares[i]);
2980 print_status_config(zhp, name, spares[i],
9babb374 2981 namewidth, 2, B_TRUE);
34dc7c2f
BB
2982 free(name);
2983 }
2984}
2985
2986static void
2987print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
2988 int namewidth)
2989{
2990 uint_t i;
2991 char *name;
2992
2993 if (nl2cache == 0)
2994 return;
2995
2996 (void) printf(gettext("\tcache\n"));
2997
2998 for (i = 0; i < nl2cache; i++) {
2999 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
3000 print_status_config(zhp, name, l2cache[i],
9babb374 3001 namewidth, 2, B_FALSE);
34dc7c2f
BB
3002 free(name);
3003 }
3004}
3005
3006/*
3007 * Display a summary of pool status. Displays a summary such as:
3008 *
3009 * pool: tank
3010 * status: DEGRADED
3011 * reason: One or more devices ...
3012 * see: http://www.sun.com/msg/ZFS-xxxx-01
3013 * config:
3014 * mirror DEGRADED
3015 * c1t0d0 OK
3016 * c2t0d0 UNAVAIL
3017 *
3018 * When given the '-v' option, we print out the complete config. If the '-e'
3019 * option is specified, then we print out error rate information as well.
3020 */
3021int
3022status_callback(zpool_handle_t *zhp, void *data)
3023{
3024 status_cbdata_t *cbp = data;
3025 nvlist_t *config, *nvroot;
3026 char *msgid;
3027 int reason;
3028 const char *health;
3029 uint_t c;
3030 vdev_stat_t *vs;
3031
3032 config = zpool_get_config(zhp, NULL);
3033 reason = zpool_get_status(zhp, &msgid);
3034
3035 cbp->cb_count++;
3036
3037 /*
3038 * If we were given 'zpool status -x', only report those pools with
3039 * problems.
3040 */
3041 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
3042 if (!cbp->cb_allpools) {
3043 (void) printf(gettext("pool '%s' is healthy\n"),
3044 zpool_get_name(zhp));
3045 if (cbp->cb_first)
3046 cbp->cb_first = B_FALSE;
3047 }
3048 return (0);
3049 }
3050
3051 if (cbp->cb_first)
3052 cbp->cb_first = B_FALSE;
3053 else
3054 (void) printf("\n");
3055
3056 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3057 &nvroot) == 0);
3058 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
3059 (uint64_t **)&vs, &c) == 0);
3060 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
3061
3062 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
3063 (void) printf(gettext(" state: %s\n"), health);
3064
3065 switch (reason) {
3066 case ZPOOL_STATUS_MISSING_DEV_R:
3067 (void) printf(gettext("status: One or more devices could not "
3068 "be opened. Sufficient replicas exist for\n\tthe pool to "
3069 "continue functioning in a degraded state.\n"));
3070 (void) printf(gettext("action: Attach the missing device and "
3071 "online it using 'zpool online'.\n"));
3072 break;
3073
3074 case ZPOOL_STATUS_MISSING_DEV_NR:
3075 (void) printf(gettext("status: One or more devices could not "
3076 "be opened. There are insufficient\n\treplicas for the "
3077 "pool to continue functioning.\n"));
3078 (void) printf(gettext("action: Attach the missing device and "
3079 "online it using 'zpool online'.\n"));
3080 break;
3081
3082 case ZPOOL_STATUS_CORRUPT_LABEL_R:
3083 (void) printf(gettext("status: One or more devices could not "
3084 "be used because the label is missing or\n\tinvalid. "
3085 "Sufficient replicas exist for the pool to continue\n\t"
3086 "functioning in a degraded state.\n"));
3087 (void) printf(gettext("action: Replace the device using "
3088 "'zpool replace'.\n"));
3089 break;
3090
3091 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
3092 (void) printf(gettext("status: One or more devices could not "
3093 "be used because the label is missing \n\tor invalid. "
3094 "There are insufficient replicas for the pool to "
3095 "continue\n\tfunctioning.\n"));
3096 (void) printf(gettext("action: Destroy and re-create the pool "
3097 "from a backup source.\n"));
3098 break;
3099
3100 case ZPOOL_STATUS_FAILING_DEV:
3101 (void) printf(gettext("status: One or more devices has "
3102 "experienced an unrecoverable error. An\n\tattempt was "
3103 "made to correct the error. Applications are "
3104 "unaffected.\n"));
3105 (void) printf(gettext("action: Determine if the device needs "
3106 "to be replaced, and clear the errors\n\tusing "
3107 "'zpool clear' or replace the device with 'zpool "
3108 "replace'.\n"));
3109 break;
3110
3111 case ZPOOL_STATUS_OFFLINE_DEV:
3112 (void) printf(gettext("status: One or more devices has "
3113 "been taken offline by the administrator.\n\tSufficient "
3114 "replicas exist for the pool to continue functioning in "
3115 "a\n\tdegraded state.\n"));
3116 (void) printf(gettext("action: Online the device using "
3117 "'zpool online' or replace the device with\n\t'zpool "
3118 "replace'.\n"));
3119 break;
3120
45d1cae3
BB
3121 case ZPOOL_STATUS_REMOVED_DEV:
3122 (void) printf(gettext("status: One or more devices has "
3123 "been removed by the administrator.\n\tSufficient "
3124 "replicas exist for the pool to continue functioning in "
3125 "a\n\tdegraded state.\n"));
3126 (void) printf(gettext("action: Online the device using "
3127 "'zpool online' or replace the device with\n\t'zpool "
3128 "replace'.\n"));
3129 break;
3130
3131
34dc7c2f
BB
3132 case ZPOOL_STATUS_RESILVERING:
3133 (void) printf(gettext("status: One or more devices is "
3134 "currently being resilvered. The pool will\n\tcontinue "
3135 "to function, possibly in a degraded state.\n"));
3136 (void) printf(gettext("action: Wait for the resilver to "
3137 "complete.\n"));
3138 break;
3139
3140 case ZPOOL_STATUS_CORRUPT_DATA:
3141 (void) printf(gettext("status: One or more devices has "
3142 "experienced an error resulting in data\n\tcorruption. "
3143 "Applications may be affected.\n"));
3144 (void) printf(gettext("action: Restore the file in question "
3145 "if possible. Otherwise restore the\n\tentire pool from "
3146 "backup.\n"));
3147 break;
3148
3149 case ZPOOL_STATUS_CORRUPT_POOL:
3150 (void) printf(gettext("status: The pool metadata is corrupted "
3151 "and the pool cannot be opened.\n"));
3152 (void) printf(gettext("action: Destroy and re-create the pool "
3153 "from a backup source.\n"));
3154 break;
3155
3156 case ZPOOL_STATUS_VERSION_OLDER:
3157 (void) printf(gettext("status: The pool is formatted using an "
3158 "older on-disk format. The pool can\n\tstill be used, but "
3159 "some features are unavailable.\n"));
3160 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3161 "upgrade'. Once this is done, the\n\tpool will no longer "
3162 "be accessible on older software versions.\n"));
3163 break;
3164
3165 case ZPOOL_STATUS_VERSION_NEWER:
3166 (void) printf(gettext("status: The pool has been upgraded to a "
3167 "newer, incompatible on-disk version.\n\tThe pool cannot "
3168 "be accessed on this system.\n"));
3169 (void) printf(gettext("action: Access the pool from a system "
3170 "running more recent software, or\n\trestore the pool from "
3171 "backup.\n"));
3172 break;
3173
3174 case ZPOOL_STATUS_FAULTED_DEV_R:
3175 (void) printf(gettext("status: One or more devices are "
3176 "faulted in response to persistent errors.\n\tSufficient "
3177 "replicas exist for the pool to continue functioning "
3178 "in a\n\tdegraded state.\n"));
3179 (void) printf(gettext("action: Replace the faulted device, "
3180 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3181 break;
3182
3183 case ZPOOL_STATUS_FAULTED_DEV_NR:
3184 (void) printf(gettext("status: One or more devices are "
3185 "faulted in response to persistent errors. There are "
3186 "insufficient replicas for the pool to\n\tcontinue "
3187 "functioning.\n"));
3188 (void) printf(gettext("action: Destroy and re-create the pool "
3189 "from a backup source. Manually marking the device\n"
3190 "\trepaired using 'zpool clear' may allow some data "
3191 "to be recovered.\n"));
3192 break;
3193
b128c09f
BB
3194 case ZPOOL_STATUS_IO_FAILURE_WAIT:
3195 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
3196 (void) printf(gettext("status: One or more devices are "
3197 "faulted in response to IO failures.\n"));
3198 (void) printf(gettext("action: Make sure the affected devices "
3199 "are connected, then run 'zpool clear'.\n"));
3200 break;
3201
3202 case ZPOOL_STATUS_BAD_LOG:
3203 (void) printf(gettext("status: An intent log record "
3204 "could not be read.\n"
3205 "\tWaiting for adminstrator intervention to fix the "
3206 "faulted pool.\n"));
3207 (void) printf(gettext("action: Either restore the affected "
3208 "device(s) and run 'zpool online',\n"
3209 "\tor ignore the intent log records by running "
3210 "'zpool clear'.\n"));
3211 break;
3212
34dc7c2f
BB
3213 default:
3214 /*
3215 * The remaining errors can't actually be generated, yet.
3216 */
3217 assert(reason == ZPOOL_STATUS_OK);
3218 }
3219
3220 if (msgid != NULL)
3221 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
3222 msgid);
3223
3224 if (config != NULL) {
3225 int namewidth;
3226 uint64_t nerr;
3227 nvlist_t **spares, **l2cache;
3228 uint_t nspares, nl2cache;
3229
3230
3231 (void) printf(gettext(" scrub: "));
3232 print_scrub_status(nvroot);
3233
3234 namewidth = max_width(zhp, nvroot, 0, 0);
3235 if (namewidth < 10)
3236 namewidth = 10;
3237
3238 (void) printf(gettext("config:\n\n"));
3239 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
3240 "NAME", "STATE", "READ", "WRITE", "CKSUM");
3241 print_status_config(zhp, zpool_get_name(zhp), nvroot,
9babb374 3242 namewidth, 0, B_FALSE);
34dc7c2f 3243
9babb374
BB
3244 if (num_logs(nvroot) > 0)
3245 print_logs(zhp, nvroot, namewidth, B_TRUE);
34dc7c2f
BB
3246 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
3247 &l2cache, &nl2cache) == 0)
3248 print_l2cache(zhp, l2cache, nl2cache, namewidth);
3249
3250 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
3251 &spares, &nspares) == 0)
3252 print_spares(zhp, spares, nspares, namewidth);
3253
3254 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
3255 &nerr) == 0) {
3256 nvlist_t *nverrlist = NULL;
3257
3258 /*
3259 * If the approximate error count is small, get a
3260 * precise count by fetching the entire log and
3261 * uniquifying the results.
3262 */
3263 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
3264 zpool_get_errlog(zhp, &nverrlist) == 0) {
3265 nvpair_t *elem;
3266
3267 elem = NULL;
3268 nerr = 0;
3269 while ((elem = nvlist_next_nvpair(nverrlist,
3270 elem)) != NULL) {
3271 nerr++;
3272 }
3273 }
3274 nvlist_free(nverrlist);
3275
3276 (void) printf("\n");
3277
3278 if (nerr == 0)
3279 (void) printf(gettext("errors: No known data "
3280 "errors\n"));
3281 else if (!cbp->cb_verbose)
3282 (void) printf(gettext("errors: %llu data "
3283 "errors, use '-v' for a list\n"),
3284 (u_longlong_t)nerr);
3285 else
3286 print_error_log(zhp);
3287 }
3288 } else {
3289 (void) printf(gettext("config: The configuration cannot be "
3290 "determined.\n"));
3291 }
3292
3293 return (0);
3294}
3295
3296/*
3297 * zpool status [-vx] [pool] ...
3298 *
3299 * -v Display complete error logs
3300 * -x Display only pools with potential problems
3301 *
3302 * Describes the health status of all pools or some subset.
3303 */
3304int
3305zpool_do_status(int argc, char **argv)
3306{
3307 int c;
3308 int ret;
3309 status_cbdata_t cb = { 0 };
3310
3311 /* check options */
3312 while ((c = getopt(argc, argv, "vx")) != -1) {
3313 switch (c) {
3314 case 'v':
3315 cb.cb_verbose = B_TRUE;
3316 break;
3317 case 'x':
3318 cb.cb_explain = B_TRUE;
3319 break;
3320 case '?':
3321 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3322 optopt);
3323 usage(B_FALSE);
3324 }
3325 }
3326
3327 argc -= optind;
3328 argv += optind;
3329
3330 cb.cb_first = B_TRUE;
3331
3332 if (argc == 0)
3333 cb.cb_allpools = B_TRUE;
3334
3335 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
3336
3337 if (argc == 0 && cb.cb_count == 0)
3338 (void) printf(gettext("no pools available\n"));
3339 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
3340 (void) printf(gettext("all pools are healthy\n"));
3341
3342 return (ret);
3343}
3344
3345typedef struct upgrade_cbdata {
3346 int cb_all;
3347 int cb_first;
3348 int cb_newer;
3349 int cb_argc;
3350 uint64_t cb_version;
3351 char **cb_argv;
3352} upgrade_cbdata_t;
3353
3354static int
3355upgrade_cb(zpool_handle_t *zhp, void *arg)
3356{
3357 upgrade_cbdata_t *cbp = arg;
3358 nvlist_t *config;
3359 uint64_t version;
3360 int ret = 0;
3361
3362 config = zpool_get_config(zhp, NULL);
3363 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
3364 &version) == 0);
3365
3366 if (!cbp->cb_newer && version < SPA_VERSION) {
3367 if (!cbp->cb_all) {
3368 if (cbp->cb_first) {
3369 (void) printf(gettext("The following pools are "
3370 "out of date, and can be upgraded. After "
3371 "being\nupgraded, these pools will no "
3372 "longer be accessible by older software "
3373 "versions.\n\n"));
3374 (void) printf(gettext("VER POOL\n"));
3375 (void) printf(gettext("--- ------------\n"));
3376 cbp->cb_first = B_FALSE;
3377 }
3378
3379 (void) printf("%2llu %s\n", (u_longlong_t)version,
3380 zpool_get_name(zhp));
3381 } else {
3382 cbp->cb_first = B_FALSE;
3383 ret = zpool_upgrade(zhp, cbp->cb_version);
3384 if (!ret) {
3385 (void) printf(gettext("Successfully upgraded "
3386 "'%s'\n\n"), zpool_get_name(zhp));
3387 }
3388 }
3389 } else if (cbp->cb_newer && version > SPA_VERSION) {
3390 assert(!cbp->cb_all);
3391
3392 if (cbp->cb_first) {
3393 (void) printf(gettext("The following pools are "
3394 "formatted using a newer software version and\n"
3395 "cannot be accessed on the current system.\n\n"));
3396 (void) printf(gettext("VER POOL\n"));
3397 (void) printf(gettext("--- ------------\n"));
3398 cbp->cb_first = B_FALSE;
3399 }
3400
3401 (void) printf("%2llu %s\n", (u_longlong_t)version,
3402 zpool_get_name(zhp));
3403 }
3404
3405 zpool_close(zhp);
3406 return (ret);
3407}
3408
3409/* ARGSUSED */
3410static int
3411upgrade_one(zpool_handle_t *zhp, void *data)
3412{
3413 upgrade_cbdata_t *cbp = data;
3414 uint64_t cur_version;
3415 int ret;
3416
3417 if (strcmp("log", zpool_get_name(zhp)) == 0) {
3418 (void) printf(gettext("'log' is now a reserved word\n"
3419 "Pool 'log' must be renamed using export and import"
3420 " to upgrade.\n"));
3421 return (1);
3422 }
3423
3424 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3425 if (cur_version > cbp->cb_version) {
3426 (void) printf(gettext("Pool '%s' is already formatted "
3427 "using more current version '%llu'.\n"),
3428 zpool_get_name(zhp), cur_version);
3429 return (0);
3430 }
3431 if (cur_version == cbp->cb_version) {
3432 (void) printf(gettext("Pool '%s' is already formatted "
3433 "using the current version.\n"), zpool_get_name(zhp));
3434 return (0);
3435 }
3436
3437 ret = zpool_upgrade(zhp, cbp->cb_version);
3438
3439 if (!ret) {
3440 (void) printf(gettext("Successfully upgraded '%s' "
3441 "from version %llu to version %llu\n\n"),
3442 zpool_get_name(zhp), (u_longlong_t)cur_version,
3443 (u_longlong_t)cbp->cb_version);
3444 }
3445
3446 return (ret != 0);
3447}
3448
3449/*
3450 * zpool upgrade
3451 * zpool upgrade -v
3452 * zpool upgrade [-V version] <-a | pool ...>
3453 *
3454 * With no arguments, display downrev'd ZFS pool available for upgrade.
3455 * Individual pools can be upgraded by specifying the pool, and '-a' will
3456 * upgrade all pools.
3457 */
3458int
3459zpool_do_upgrade(int argc, char **argv)
3460{
3461 int c;
3462 upgrade_cbdata_t cb = { 0 };
3463 int ret = 0;
3464 boolean_t showversions = B_FALSE;
3465 char *end;
3466
3467
3468 /* check options */
9babb374 3469 while ((c = getopt(argc, argv, ":avV:")) != -1) {
34dc7c2f
BB
3470 switch (c) {
3471 case 'a':
3472 cb.cb_all = B_TRUE;
3473 break;
3474 case 'v':
3475 showversions = B_TRUE;
3476 break;
3477 case 'V':
3478 cb.cb_version = strtoll(optarg, &end, 10);
3479 if (*end != '\0' || cb.cb_version > SPA_VERSION ||
3480 cb.cb_version < SPA_VERSION_1) {
3481 (void) fprintf(stderr,
3482 gettext("invalid version '%s'\n"), optarg);
3483 usage(B_FALSE);
3484 }
3485 break;
9babb374
BB
3486 case ':':
3487 (void) fprintf(stderr, gettext("missing argument for "
3488 "'%c' option\n"), optopt);
3489 usage(B_FALSE);
3490 break;
34dc7c2f
BB
3491 case '?':
3492 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3493 optopt);
3494 usage(B_FALSE);
3495 }
3496 }
3497
3498 cb.cb_argc = argc;
3499 cb.cb_argv = argv;
3500 argc -= optind;
3501 argv += optind;
3502
3503 if (cb.cb_version == 0) {
3504 cb.cb_version = SPA_VERSION;
3505 } else if (!cb.cb_all && argc == 0) {
3506 (void) fprintf(stderr, gettext("-V option is "
3507 "incompatible with other arguments\n"));
3508 usage(B_FALSE);
3509 }
3510
3511 if (showversions) {
3512 if (cb.cb_all || argc != 0) {
3513 (void) fprintf(stderr, gettext("-v option is "
3514 "incompatible with other arguments\n"));
3515 usage(B_FALSE);
3516 }
3517 } else if (cb.cb_all) {
3518 if (argc != 0) {
3519 (void) fprintf(stderr, gettext("-a option should not "
3520 "be used along with a pool name\n"));
3521 usage(B_FALSE);
3522 }
3523 }
3524
3525 (void) printf(gettext("This system is currently running "
3526 "ZFS pool version %llu.\n\n"), SPA_VERSION);
3527 cb.cb_first = B_TRUE;
3528 if (showversions) {
3529 (void) printf(gettext("The following versions are "
3530 "supported:\n\n"));
3531 (void) printf(gettext("VER DESCRIPTION\n"));
3532 (void) printf("--- -----------------------------------------"
3533 "---------------\n");
3534 (void) printf(gettext(" 1 Initial ZFS version\n"));
3535 (void) printf(gettext(" 2 Ditto blocks "
3536 "(replicated metadata)\n"));
3537 (void) printf(gettext(" 3 Hot spares and double parity "
3538 "RAID-Z\n"));
3539 (void) printf(gettext(" 4 zpool history\n"));
3540 (void) printf(gettext(" 5 Compression using the gzip "
3541 "algorithm\n"));
3542 (void) printf(gettext(" 6 bootfs pool property\n"));
3543 (void) printf(gettext(" 7 Separate intent log devices\n"));
3544 (void) printf(gettext(" 8 Delegated administration\n"));
3545 (void) printf(gettext(" 9 refquota and refreservation "
3546 "properties\n"));
3547 (void) printf(gettext(" 10 Cache devices\n"));
b128c09f
BB
3548 (void) printf(gettext(" 11 Improved scrub performance\n"));
3549 (void) printf(gettext(" 12 Snapshot properties\n"));
3550 (void) printf(gettext(" 13 snapused property\n"));
9babb374
BB
3551 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
3552 (void) printf(gettext(" 15 user/group space accounting\n"));
3553 (void) printf(gettext(" 16 stmf property support\n"));
45d1cae3
BB
3554 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
3555 (void) printf(gettext(" 18 snapshot user holds\n"));
34dc7c2f
BB
3556 (void) printf(gettext("For more information on a particular "
3557 "version, including supported releases, see:\n\n"));
3558 (void) printf("http://www.opensolaris.org/os/community/zfs/"
3559 "version/N\n\n");
3560 (void) printf(gettext("Where 'N' is the version number.\n"));
3561 } else if (argc == 0) {
3562 int notfound;
3563
3564 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3565 notfound = cb.cb_first;
3566
3567 if (!cb.cb_all && ret == 0) {
3568 if (!cb.cb_first)
3569 (void) printf("\n");
3570 cb.cb_first = B_TRUE;
3571 cb.cb_newer = B_TRUE;
3572 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
3573 if (!cb.cb_first) {
3574 notfound = B_FALSE;
3575 (void) printf("\n");
3576 }
3577 }
3578
3579 if (ret == 0) {
3580 if (notfound)
3581 (void) printf(gettext("All pools are formatted "
3582 "using this version.\n"));
3583 else if (!cb.cb_all)
3584 (void) printf(gettext("Use 'zpool upgrade -v' "
3585 "for a list of available versions and "
3586 "their associated\nfeatures.\n"));
3587 }
3588 } else {
3589 ret = for_each_pool(argc, argv, B_FALSE, NULL,
3590 upgrade_one, &cb);
3591 }
3592
3593 return (ret);
3594}
3595
3596typedef struct hist_cbdata {
3597 boolean_t first;
3598 int longfmt;
3599 int internal;
3600} hist_cbdata_t;
3601
3602char *hist_event_table[LOG_END] = {
3603 "invalid event",
3604 "pool create",
3605 "vdev add",
3606 "pool remove",
3607 "pool destroy",
3608 "pool export",
3609 "pool import",
3610 "vdev attach",
3611 "vdev replace",
3612 "vdev detach",
3613 "vdev online",
3614 "vdev offline",
3615 "vdev upgrade",
3616 "pool clear",
3617 "pool scrub",
3618 "pool property set",
3619 "create",
3620 "clone",
3621 "destroy",
3622 "destroy_begin_sync",
3623 "inherit",
3624 "property set",
3625 "quota set",
3626 "permission update",
3627 "permission remove",
3628 "permission who remove",
3629 "promote",
3630 "receive",
3631 "rename",
3632 "reservation set",
3633 "replay_inc_sync",
3634 "replay_full_sync",
3635 "rollback",
3636 "snapshot",
3637 "filesystem version upgrade",
3638 "refquota set",
3639 "refreservation set",
b128c09f 3640 "pool scrub done",
45d1cae3
BB
3641 "user hold",
3642 "user release",
34dc7c2f
BB
3643};
3644
3645/*
3646 * Print out the command history for a specific pool.
3647 */
3648static int
3649get_history_one(zpool_handle_t *zhp, void *data)
3650{
3651 nvlist_t *nvhis;
3652 nvlist_t **records;
3653 uint_t numrecords;
3654 char *cmdstr;
3655 char *pathstr;
3656 uint64_t dst_time;
3657 time_t tsec;
3658 struct tm t;
3659 char tbuf[30];
3660 int ret, i;
3661 uint64_t who;
3662 struct passwd *pwd;
3663 char *hostname;
3664 char *zonename;
3665 char internalstr[MAXPATHLEN];
3666 hist_cbdata_t *cb = (hist_cbdata_t *)data;
3667 uint64_t txg;
3668 uint64_t ievent;
3669
3670 cb->first = B_FALSE;
3671
3672 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
3673
3674 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
3675 return (ret);
3676
3677 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
3678 &records, &numrecords) == 0);
3679 for (i = 0; i < numrecords; i++) {
3680 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
3681 &dst_time) != 0)
3682 continue;
3683
3684 /* is it an internal event or a standard event? */
3685 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
3686 &cmdstr) != 0) {
3687 if (cb->internal == 0)
3688 continue;
3689
3690 if (nvlist_lookup_uint64(records[i],
3691 ZPOOL_HIST_INT_EVENT, &ievent) != 0)
3692 continue;
3693 verify(nvlist_lookup_uint64(records[i],
3694 ZPOOL_HIST_TXG, &txg) == 0);
3695 verify(nvlist_lookup_string(records[i],
3696 ZPOOL_HIST_INT_STR, &pathstr) == 0);
b128c09f 3697 if (ievent >= LOG_END)
34dc7c2f
BB
3698 continue;
3699 (void) snprintf(internalstr,
3700 sizeof (internalstr),
3701 "[internal %s txg:%lld] %s",
3702 hist_event_table[ievent], txg,
3703 pathstr);
3704 cmdstr = internalstr;
3705 }
3706 tsec = dst_time;
3707 (void) localtime_r(&tsec, &t);
3708 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
3709 (void) printf("%s %s", tbuf, cmdstr);
3710
3711 if (!cb->longfmt) {
3712 (void) printf("\n");
3713 continue;
3714 }
3715 (void) printf(" [");
3716 if (nvlist_lookup_uint64(records[i],
3717 ZPOOL_HIST_WHO, &who) == 0) {
3718 pwd = getpwuid((uid_t)who);
3719 if (pwd)
3720 (void) printf("user %s on",
3721 pwd->pw_name);
3722 else
3723 (void) printf("user %d on",
3724 (int)who);
3725 } else {
3726 (void) printf(gettext("no info]\n"));
3727 continue;
3728 }
3729 if (nvlist_lookup_string(records[i],
3730 ZPOOL_HIST_HOST, &hostname) == 0) {
3731 (void) printf(" %s", hostname);
3732 }
3733 if (nvlist_lookup_string(records[i],
3734 ZPOOL_HIST_ZONE, &zonename) == 0) {
3735 (void) printf(":%s", zonename);
3736 }
3737
3738 (void) printf("]");
3739 (void) printf("\n");
3740 }
3741 (void) printf("\n");
3742 nvlist_free(nvhis);
3743
3744 return (ret);
3745}
3746
3747/*
3748 * zpool history <pool>
3749 *
3750 * Displays the history of commands that modified pools.
3751 */
3752
3753
3754int
3755zpool_do_history(int argc, char **argv)
3756{
3757 hist_cbdata_t cbdata = { 0 };
3758 int ret;
3759 int c;
3760
3761 cbdata.first = B_TRUE;
3762 /* check options */
3763 while ((c = getopt(argc, argv, "li")) != -1) {
3764 switch (c) {
3765 case 'l':
3766 cbdata.longfmt = 1;
3767 break;
3768 case 'i':
3769 cbdata.internal = 1;
3770 break;
3771 case '?':
3772 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3773 optopt);
3774 usage(B_FALSE);
3775 }
3776 }
3777 argc -= optind;
3778 argv += optind;
3779
3780 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
3781 &cbdata);
3782
3783 if (argc == 0 && cbdata.first == B_TRUE) {
3784 (void) printf(gettext("no pools available\n"));
3785 return (0);
3786 }
3787
3788 return (ret);
3789}
3790
3791static int
3792get_callback(zpool_handle_t *zhp, void *data)
3793{
3794 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
3795 char value[MAXNAMELEN];
3796 zprop_source_t srctype;
3797 zprop_list_t *pl;
3798
3799 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
3800
3801 /*
3802 * Skip the special fake placeholder. This will also skip
3803 * over the name property when 'all' is specified.
3804 */
3805 if (pl->pl_prop == ZPOOL_PROP_NAME &&
3806 pl == cbp->cb_proplist)
3807 continue;
3808
3809 if (zpool_get_prop(zhp, pl->pl_prop,
3810 value, sizeof (value), &srctype) != 0)
3811 continue;
3812
3813 zprop_print_one_property(zpool_get_name(zhp), cbp,
3814 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
3815 }
3816 return (0);
3817}
3818
3819int
3820zpool_do_get(int argc, char **argv)
3821{
3822 zprop_get_cbdata_t cb = { 0 };
3823 zprop_list_t fake_name = { 0 };
3824 int ret;
3825
3826 if (argc < 3)
3827 usage(B_FALSE);
3828
3829 cb.cb_first = B_TRUE;
3830 cb.cb_sources = ZPROP_SRC_ALL;
3831 cb.cb_columns[0] = GET_COL_NAME;
3832 cb.cb_columns[1] = GET_COL_PROPERTY;
3833 cb.cb_columns[2] = GET_COL_VALUE;
3834 cb.cb_columns[3] = GET_COL_SOURCE;
3835 cb.cb_type = ZFS_TYPE_POOL;
3836
3837 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
3838 ZFS_TYPE_POOL) != 0)
3839 usage(B_FALSE);
3840
3841 if (cb.cb_proplist != NULL) {
3842 fake_name.pl_prop = ZPOOL_PROP_NAME;
3843 fake_name.pl_width = strlen(gettext("NAME"));
3844 fake_name.pl_next = cb.cb_proplist;
3845 cb.cb_proplist = &fake_name;
3846 }
3847
3848 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
3849 get_callback, &cb);
3850
3851 if (cb.cb_proplist == &fake_name)
3852 zprop_free_list(fake_name.pl_next);
3853 else
3854 zprop_free_list(cb.cb_proplist);
3855
3856 return (ret);
3857}
3858
3859typedef struct set_cbdata {
3860 char *cb_propname;
3861 char *cb_value;
3862 boolean_t cb_any_successful;
3863} set_cbdata_t;
3864
3865int
3866set_callback(zpool_handle_t *zhp, void *data)
3867{
3868 int error;
3869 set_cbdata_t *cb = (set_cbdata_t *)data;
3870
3871 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
3872
3873 if (!error)
3874 cb->cb_any_successful = B_TRUE;
3875
3876 return (error);
3877}
3878
3879int
3880zpool_do_set(int argc, char **argv)
3881{
3882 set_cbdata_t cb = { 0 };
3883 int error;
3884
3885 if (argc > 1 && argv[1][0] == '-') {
3886 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
3887 argv[1][1]);
3888 usage(B_FALSE);
3889 }
3890
3891 if (argc < 2) {
3892 (void) fprintf(stderr, gettext("missing property=value "
3893 "argument\n"));
3894 usage(B_FALSE);
3895 }
3896
3897 if (argc < 3) {
3898 (void) fprintf(stderr, gettext("missing pool name\n"));
3899 usage(B_FALSE);
3900 }
3901
3902 if (argc > 3) {
3903 (void) fprintf(stderr, gettext("too many pool names\n"));
3904 usage(B_FALSE);
3905 }
3906
3907 cb.cb_propname = argv[1];
3908 cb.cb_value = strchr(cb.cb_propname, '=');
3909 if (cb.cb_value == NULL) {
3910 (void) fprintf(stderr, gettext("missing value in "
3911 "property=value argument\n"));
3912 usage(B_FALSE);
3913 }
3914
3915 *(cb.cb_value) = '\0';
3916 cb.cb_value++;
3917
3918 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
3919 set_callback, &cb);
3920
3921 return (error);
3922}
3923
3924static int
3925find_command_idx(char *command, int *idx)
3926{
3927 int i;
3928
3929 for (i = 0; i < NCOMMAND; i++) {
3930 if (command_table[i].name == NULL)
3931 continue;
3932
3933 if (strcmp(command, command_table[i].name) == 0) {
3934 *idx = i;
3935 return (0);
3936 }
3937 }
3938 return (1);
3939}
3940
3941int
3942main(int argc, char **argv)
3943{
3944 int ret;
3945 int i;
3946 char *cmdname;
3947
3948 (void) setlocale(LC_ALL, "");
3949 (void) textdomain(TEXT_DOMAIN);
3950
3951 if ((g_zfs = libzfs_init()) == NULL) {
3952 (void) fprintf(stderr, gettext("internal error: failed to "
3953 "initialize ZFS library\n"));
3954 return (1);
3955 }
3956
3957 libzfs_print_on_error(g_zfs, B_TRUE);
3958
3959 opterr = 0;
3960
3961 /*
3962 * Make sure the user has specified some command.
3963 */
3964 if (argc < 2) {
3965 (void) fprintf(stderr, gettext("missing command\n"));
3966 usage(B_FALSE);
3967 }
3968
3969 cmdname = argv[1];
3970
3971 /*
3972 * Special case '-?'
3973 */
3974 if (strcmp(cmdname, "-?") == 0)
3975 usage(B_TRUE);
3976
3977 zpool_set_history_str("zpool", argc, argv, history_str);
3978 verify(zpool_stage_history(g_zfs, history_str) == 0);
3979
3980 /*
3981 * Run the appropriate command.
3982 */
3983 if (find_command_idx(cmdname, &i) == 0) {
3984 current_command = &command_table[i];
3985 ret = command_table[i].func(argc - 1, argv + 1);
3986 } else if (strchr(cmdname, '=')) {
3987 verify(find_command_idx("set", &i) == 0);
3988 current_command = &command_table[i];
3989 ret = command_table[i].func(argc, argv);
3990 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
3991 /*
3992 * 'freeze' is a vile debugging abomination, so we treat
3993 * it as such.
3994 */
3995 char buf[16384];
3996 int fd = open(ZFS_DEV, O_RDWR);
3997 (void) strcpy((void *)buf, argv[2]);
3998 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
3999 } else {
4000 (void) fprintf(stderr, gettext("unrecognized "
4001 "command '%s'\n"), cmdname);
4002 usage(B_FALSE);
4003 }
4004
4005 libzfs_fini(g_zfs);
4006
4007 /*
4008 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
4009 * for the purposes of running ::findleaks.
4010 */
4011 if (getenv("ZFS_ABORT") != NULL) {
4012 (void) printf("dumping core by request\n");
4013 abort();
4014 }
4015
4016 return (ret);
4017}