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