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