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