]> git.proxmox.com Git - mirror_zfs-debian.git/blob - cmd/zpool/zpool_main.c
New upstream version 0.7.9
[mirror_zfs-debian.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 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
30 * Copyright (c) 2017 Datto Inc.
31 */
32
33 #include <assert.h>
34 #include <ctype.h>
35 #include <dirent.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <libgen.h>
39 #include <libintl.h>
40 #include <libuutil.h>
41 #include <locale.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <strings.h>
46 #include <unistd.h>
47 #include <pwd.h>
48 #include <zone.h>
49 #include <sys/wait.h>
50 #include <zfs_prop.h>
51 #include <sys/fs/zfs.h>
52 #include <sys/stat.h>
53 #include <sys/fm/fs/zfs.h>
54 #include <sys/fm/util.h>
55 #include <sys/fm/protocol.h>
56 #include <sys/zfs_ioctl.h>
57
58 #include <math.h>
59
60 #include <libzfs.h>
61
62 #include "zpool_util.h"
63 #include "zfs_comutil.h"
64 #include "zfeature_common.h"
65
66 #include "statcommon.h"
67
68 static int zpool_do_create(int, char **);
69 static int zpool_do_destroy(int, char **);
70
71 static int zpool_do_add(int, char **);
72 static int zpool_do_remove(int, char **);
73 static int zpool_do_labelclear(int, char **);
74
75 static int zpool_do_list(int, char **);
76 static int zpool_do_iostat(int, char **);
77 static int zpool_do_status(int, char **);
78
79 static int zpool_do_online(int, char **);
80 static int zpool_do_offline(int, char **);
81 static int zpool_do_clear(int, char **);
82 static int zpool_do_reopen(int, char **);
83
84 static int zpool_do_reguid(int, char **);
85
86 static int zpool_do_attach(int, char **);
87 static int zpool_do_detach(int, char **);
88 static int zpool_do_replace(int, char **);
89 static int zpool_do_split(int, char **);
90
91 static int zpool_do_scrub(int, char **);
92
93 static int zpool_do_import(int, char **);
94 static int zpool_do_export(int, char **);
95
96 static int zpool_do_upgrade(int, char **);
97
98 static int zpool_do_history(int, char **);
99 static int zpool_do_events(int, char **);
100
101 static int zpool_do_get(int, char **);
102 static int zpool_do_set(int, char **);
103
104 static int zpool_do_sync(int, char **);
105
106 /*
107 * These libumem hooks provide a reasonable set of defaults for the allocator's
108 * debugging facilities.
109 */
110
111 #ifdef DEBUG
112 const char *
113 _umem_debug_init(void)
114 {
115 return ("default,verbose"); /* $UMEM_DEBUG setting */
116 }
117
118 const char *
119 _umem_logging_init(void)
120 {
121 return ("fail,contents"); /* $UMEM_LOGGING setting */
122 }
123 #endif
124
125 typedef enum {
126 HELP_ADD,
127 HELP_ATTACH,
128 HELP_CLEAR,
129 HELP_CREATE,
130 HELP_DESTROY,
131 HELP_DETACH,
132 HELP_EXPORT,
133 HELP_HISTORY,
134 HELP_IMPORT,
135 HELP_IOSTAT,
136 HELP_LABELCLEAR,
137 HELP_LIST,
138 HELP_OFFLINE,
139 HELP_ONLINE,
140 HELP_REPLACE,
141 HELP_REMOVE,
142 HELP_SCRUB,
143 HELP_STATUS,
144 HELP_UPGRADE,
145 HELP_EVENTS,
146 HELP_GET,
147 HELP_SET,
148 HELP_SPLIT,
149 HELP_SYNC,
150 HELP_REGUID,
151 HELP_REOPEN
152 } zpool_help_t;
153
154
155 /*
156 * Flags for stats to display with "zpool iostats"
157 */
158 enum iostat_type {
159 IOS_DEFAULT = 0,
160 IOS_LATENCY = 1,
161 IOS_QUEUES = 2,
162 IOS_L_HISTO = 3,
163 IOS_RQ_HISTO = 4,
164 IOS_COUNT, /* always last element */
165 };
166
167 /* iostat_type entries as bitmasks */
168 #define IOS_DEFAULT_M (1ULL << IOS_DEFAULT)
169 #define IOS_LATENCY_M (1ULL << IOS_LATENCY)
170 #define IOS_QUEUES_M (1ULL << IOS_QUEUES)
171 #define IOS_L_HISTO_M (1ULL << IOS_L_HISTO)
172 #define IOS_RQ_HISTO_M (1ULL << IOS_RQ_HISTO)
173
174 /* Mask of all the histo bits */
175 #define IOS_ANYHISTO_M (IOS_L_HISTO_M | IOS_RQ_HISTO_M)
176
177 /*
178 * Lookup table for iostat flags to nvlist names. Basically a list
179 * of all the nvlists a flag requires. Also specifies the order in
180 * which data gets printed in zpool iostat.
181 */
182 static const char *vsx_type_to_nvlist[IOS_COUNT][11] = {
183 [IOS_L_HISTO] = {
184 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
185 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
186 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
187 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
188 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
189 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
190 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
191 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
192 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
193 NULL},
194 [IOS_LATENCY] = {
195 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
196 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
197 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
198 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
199 NULL},
200 [IOS_QUEUES] = {
201 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
202 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
203 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
204 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
205 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
206 NULL},
207 [IOS_RQ_HISTO] = {
208 ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO,
209 ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO,
210 ZPOOL_CONFIG_VDEV_SYNC_IND_W_HISTO,
211 ZPOOL_CONFIG_VDEV_SYNC_AGG_W_HISTO,
212 ZPOOL_CONFIG_VDEV_ASYNC_IND_R_HISTO,
213 ZPOOL_CONFIG_VDEV_ASYNC_AGG_R_HISTO,
214 ZPOOL_CONFIG_VDEV_ASYNC_IND_W_HISTO,
215 ZPOOL_CONFIG_VDEV_ASYNC_AGG_W_HISTO,
216 ZPOOL_CONFIG_VDEV_IND_SCRUB_HISTO,
217 ZPOOL_CONFIG_VDEV_AGG_SCRUB_HISTO,
218 NULL},
219 };
220
221
222 /*
223 * Given a cb->cb_flags with a histogram bit set, return the iostat_type.
224 * Right now, only one histo bit is ever set at one time, so we can
225 * just do a highbit64(a)
226 */
227 #define IOS_HISTO_IDX(a) (highbit64(a & IOS_ANYHISTO_M) - 1)
228
229 typedef struct zpool_command {
230 const char *name;
231 int (*func)(int, char **);
232 zpool_help_t usage;
233 } zpool_command_t;
234
235 /*
236 * Master command table. Each ZFS command has a name, associated function, and
237 * usage message. The usage messages need to be internationalized, so we have
238 * to have a function to return the usage message based on a command index.
239 *
240 * These commands are organized according to how they are displayed in the usage
241 * message. An empty command (one with a NULL name) indicates an empty line in
242 * the generic usage message.
243 */
244 static zpool_command_t command_table[] = {
245 { "create", zpool_do_create, HELP_CREATE },
246 { "destroy", zpool_do_destroy, HELP_DESTROY },
247 { NULL },
248 { "add", zpool_do_add, HELP_ADD },
249 { "remove", zpool_do_remove, HELP_REMOVE },
250 { NULL },
251 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR },
252 { NULL },
253 { "list", zpool_do_list, HELP_LIST },
254 { "iostat", zpool_do_iostat, HELP_IOSTAT },
255 { "status", zpool_do_status, HELP_STATUS },
256 { NULL },
257 { "online", zpool_do_online, HELP_ONLINE },
258 { "offline", zpool_do_offline, HELP_OFFLINE },
259 { "clear", zpool_do_clear, HELP_CLEAR },
260 { "reopen", zpool_do_reopen, HELP_REOPEN },
261 { NULL },
262 { "attach", zpool_do_attach, HELP_ATTACH },
263 { "detach", zpool_do_detach, HELP_DETACH },
264 { "replace", zpool_do_replace, HELP_REPLACE },
265 { "split", zpool_do_split, HELP_SPLIT },
266 { NULL },
267 { "scrub", zpool_do_scrub, HELP_SCRUB },
268 { NULL },
269 { "import", zpool_do_import, HELP_IMPORT },
270 { "export", zpool_do_export, HELP_EXPORT },
271 { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
272 { "reguid", zpool_do_reguid, HELP_REGUID },
273 { NULL },
274 { "history", zpool_do_history, HELP_HISTORY },
275 { "events", zpool_do_events, HELP_EVENTS },
276 { NULL },
277 { "get", zpool_do_get, HELP_GET },
278 { "set", zpool_do_set, HELP_SET },
279 { "sync", zpool_do_sync, HELP_SYNC },
280 };
281
282 #define NCOMMAND (ARRAY_SIZE(command_table))
283
284 static zpool_command_t *current_command;
285 static char history_str[HIS_MAX_RECORD_LEN];
286 static boolean_t log_history = B_TRUE;
287 static uint_t timestamp_fmt = NODATE;
288
289 static const char *
290 get_usage(zpool_help_t idx)
291 {
292 switch (idx) {
293 case HELP_ADD:
294 return (gettext("\tadd [-fgLnP] [-o property=value] "
295 "<pool> <vdev> ...\n"));
296 case HELP_ATTACH:
297 return (gettext("\tattach [-f] [-o property=value] "
298 "<pool> <device> <new-device>\n"));
299 case HELP_CLEAR:
300 return (gettext("\tclear [-nF] <pool> [device]\n"));
301 case HELP_CREATE:
302 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
303 "\t [-O file-system-property=value] ... \n"
304 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
305 case HELP_DESTROY:
306 return (gettext("\tdestroy [-f] <pool>\n"));
307 case HELP_DETACH:
308 return (gettext("\tdetach <pool> <device>\n"));
309 case HELP_EXPORT:
310 return (gettext("\texport [-af] <pool> ...\n"));
311 case HELP_HISTORY:
312 return (gettext("\thistory [-il] [<pool>] ...\n"));
313 case HELP_IMPORT:
314 return (gettext("\timport [-d dir] [-D]\n"
315 "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
316 "\timport [-o mntopts] [-o property=value] ... \n"
317 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
318 "[-R root] [-F [-n]] -a\n"
319 "\timport [-o mntopts] [-o property=value] ... \n"
320 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
321 "[-R root] [-F [-n]]\n"
322 "\t <pool | id> [newpool]\n"));
323 case HELP_IOSTAT:
324 return (gettext("\tiostat [[[-c [script1,script2,...]"
325 "[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
326 "\t [[pool ...]|[pool vdev ...]|[vdev ...]]"
327 " [interval [count]]\n"));
328 case HELP_LABELCLEAR:
329 return (gettext("\tlabelclear [-f] <vdev>\n"));
330 case HELP_LIST:
331 return (gettext("\tlist [-gHLpPv] [-o property[,...]] "
332 "[-T d|u] [pool] ... [interval [count]]\n"));
333 case HELP_OFFLINE:
334 return (gettext("\toffline [-f] [-t] <pool> <device> ...\n"));
335 case HELP_ONLINE:
336 return (gettext("\tonline <pool> <device> ...\n"));
337 case HELP_REPLACE:
338 return (gettext("\treplace [-f] [-o property=value] "
339 "<pool> <device> [new-device]\n"));
340 case HELP_REMOVE:
341 return (gettext("\tremove <pool> <device> ...\n"));
342 case HELP_REOPEN:
343 return (gettext("\treopen <pool>\n"));
344 case HELP_SCRUB:
345 return (gettext("\tscrub [-s | -p] <pool> ...\n"));
346 case HELP_STATUS:
347 return (gettext("\tstatus [-c [script1,script2,...]] [-gLPvxD]"
348 "[-T d|u] [pool] ... [interval [count]]\n"));
349 case HELP_UPGRADE:
350 return (gettext("\tupgrade\n"
351 "\tupgrade -v\n"
352 "\tupgrade [-V version] <-a | pool ...>\n"));
353 case HELP_EVENTS:
354 return (gettext("\tevents [-vHfc]\n"));
355 case HELP_GET:
356 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
357 "<\"all\" | property[,...]> <pool> ...\n"));
358 case HELP_SET:
359 return (gettext("\tset <property=value> <pool> \n"));
360 case HELP_SPLIT:
361 return (gettext("\tsplit [-gLnP] [-R altroot] [-o mntopts]\n"
362 "\t [-o property=value] <pool> <newpool> "
363 "[<device> ...]\n"));
364 case HELP_REGUID:
365 return (gettext("\treguid <pool>\n"));
366 case HELP_SYNC:
367 return (gettext("\tsync [pool] ...\n"));
368 }
369
370 abort();
371 /* NOTREACHED */
372 }
373
374
375 /*
376 * Callback routine that will print out a pool property value.
377 */
378 static int
379 print_prop_cb(int prop, void *cb)
380 {
381 FILE *fp = cb;
382
383 (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop));
384
385 if (zpool_prop_readonly(prop))
386 (void) fprintf(fp, " NO ");
387 else
388 (void) fprintf(fp, " YES ");
389
390 if (zpool_prop_values(prop) == NULL)
391 (void) fprintf(fp, "-\n");
392 else
393 (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
394
395 return (ZPROP_CONT);
396 }
397
398 /*
399 * Display usage message. If we're inside a command, display only the usage for
400 * that command. Otherwise, iterate over the entire command table and display
401 * a complete usage message.
402 */
403 void
404 usage(boolean_t requested)
405 {
406 FILE *fp = requested ? stdout : stderr;
407
408 if (current_command == NULL) {
409 int i;
410
411 (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
412 (void) fprintf(fp,
413 gettext("where 'command' is one of the following:\n\n"));
414
415 for (i = 0; i < NCOMMAND; i++) {
416 if (command_table[i].name == NULL)
417 (void) fprintf(fp, "\n");
418 else
419 (void) fprintf(fp, "%s",
420 get_usage(command_table[i].usage));
421 }
422 } else {
423 (void) fprintf(fp, gettext("usage:\n"));
424 (void) fprintf(fp, "%s", get_usage(current_command->usage));
425 }
426
427 if (current_command != NULL &&
428 ((strcmp(current_command->name, "set") == 0) ||
429 (strcmp(current_command->name, "get") == 0) ||
430 (strcmp(current_command->name, "list") == 0))) {
431
432 (void) fprintf(fp,
433 gettext("\nthe following properties are supported:\n"));
434
435 (void) fprintf(fp, "\n\t%-15s %s %s\n\n",
436 "PROPERTY", "EDIT", "VALUES");
437
438 /* Iterate over all properties */
439 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
440 ZFS_TYPE_POOL);
441
442 (void) fprintf(fp, "\t%-15s ", "feature@...");
443 (void) fprintf(fp, "YES disabled | enabled | active\n");
444
445 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
446 "appended with a feature name.\nSee zpool-features(5).\n"));
447 }
448
449 /*
450 * See comments at end of main().
451 */
452 if (getenv("ZFS_ABORT") != NULL) {
453 (void) printf("dumping core by request\n");
454 abort();
455 }
456
457 exit(requested ? 0 : 2);
458 }
459
460 void
461 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
462 boolean_t print_logs, int name_flags)
463 {
464 nvlist_t **child;
465 uint_t c, children;
466 char *vname;
467
468 if (name != NULL)
469 (void) printf("\t%*s%s\n", indent, "", name);
470
471 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
472 &child, &children) != 0)
473 return;
474
475 for (c = 0; c < children; c++) {
476 uint64_t is_log = B_FALSE;
477
478 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
479 &is_log);
480 if ((is_log && !print_logs) || (!is_log && print_logs))
481 continue;
482
483 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
484 print_vdev_tree(zhp, vname, child[c], indent + 2,
485 B_FALSE, name_flags);
486 free(vname);
487 }
488 }
489
490 static boolean_t
491 prop_list_contains_feature(nvlist_t *proplist)
492 {
493 nvpair_t *nvp;
494 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp;
495 nvp = nvlist_next_nvpair(proplist, nvp)) {
496 if (zpool_prop_feature(nvpair_name(nvp)))
497 return (B_TRUE);
498 }
499 return (B_FALSE);
500 }
501
502 /*
503 * Add a property pair (name, string-value) into a property nvlist.
504 */
505 static int
506 add_prop_list(const char *propname, char *propval, nvlist_t **props,
507 boolean_t poolprop)
508 {
509 zpool_prop_t prop = ZPROP_INVAL;
510 zfs_prop_t fprop;
511 nvlist_t *proplist;
512 const char *normnm;
513 char *strval;
514
515 if (*props == NULL &&
516 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
517 (void) fprintf(stderr,
518 gettext("internal error: out of memory\n"));
519 return (1);
520 }
521
522 proplist = *props;
523
524 if (poolprop) {
525 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
526
527 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
528 !zpool_prop_feature(propname)) {
529 (void) fprintf(stderr, gettext("property '%s' is "
530 "not a valid pool property\n"), propname);
531 return (2);
532 }
533
534 /*
535 * feature@ properties and version should not be specified
536 * at the same time.
537 */
538 if ((prop == ZPROP_INVAL && zpool_prop_feature(propname) &&
539 nvlist_exists(proplist, vname)) ||
540 (prop == ZPOOL_PROP_VERSION &&
541 prop_list_contains_feature(proplist))) {
542 (void) fprintf(stderr, gettext("'feature@' and "
543 "'version' properties cannot be specified "
544 "together\n"));
545 return (2);
546 }
547
548
549 if (zpool_prop_feature(propname))
550 normnm = propname;
551 else
552 normnm = zpool_prop_to_name(prop);
553 } else {
554 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
555 normnm = zfs_prop_to_name(fprop);
556 } else {
557 normnm = propname;
558 }
559 }
560
561 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
562 prop != ZPOOL_PROP_CACHEFILE) {
563 (void) fprintf(stderr, gettext("property '%s' "
564 "specified multiple times\n"), propname);
565 return (2);
566 }
567
568 if (nvlist_add_string(proplist, normnm, propval) != 0) {
569 (void) fprintf(stderr, gettext("internal "
570 "error: out of memory\n"));
571 return (1);
572 }
573
574 return (0);
575 }
576
577 /*
578 * Set a default property pair (name, string-value) in a property nvlist
579 */
580 static int
581 add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
582 boolean_t poolprop)
583 {
584 char *pval;
585
586 if (nvlist_lookup_string(*props, propname, &pval) == 0)
587 return (0);
588
589 return (add_prop_list(propname, propval, props, B_TRUE));
590 }
591
592 /*
593 * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
594 *
595 * -f Force addition of devices, even if they appear in use
596 * -g Display guid for individual vdev name.
597 * -L Follow links when resolving vdev path name.
598 * -n Do not add the devices, but display the resulting layout if
599 * they were to be added.
600 * -o Set property=value.
601 * -P Display full path for vdev name.
602 *
603 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
604 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
605 * libzfs.
606 */
607 int
608 zpool_do_add(int argc, char **argv)
609 {
610 boolean_t force = B_FALSE;
611 boolean_t dryrun = B_FALSE;
612 int name_flags = 0;
613 int c;
614 nvlist_t *nvroot;
615 char *poolname;
616 int ret;
617 zpool_handle_t *zhp;
618 nvlist_t *config;
619 nvlist_t *props = NULL;
620 char *propval;
621
622 /* check options */
623 while ((c = getopt(argc, argv, "fgLno:P")) != -1) {
624 switch (c) {
625 case 'f':
626 force = B_TRUE;
627 break;
628 case 'g':
629 name_flags |= VDEV_NAME_GUID;
630 break;
631 case 'L':
632 name_flags |= VDEV_NAME_FOLLOW_LINKS;
633 break;
634 case 'n':
635 dryrun = B_TRUE;
636 break;
637 case 'o':
638 if ((propval = strchr(optarg, '=')) == NULL) {
639 (void) fprintf(stderr, gettext("missing "
640 "'=' for -o option\n"));
641 usage(B_FALSE);
642 }
643 *propval = '\0';
644 propval++;
645
646 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
647 (add_prop_list(optarg, propval, &props, B_TRUE)))
648 usage(B_FALSE);
649 break;
650 case 'P':
651 name_flags |= VDEV_NAME_PATH;
652 break;
653 case '?':
654 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
655 optopt);
656 usage(B_FALSE);
657 }
658 }
659
660 argc -= optind;
661 argv += optind;
662
663 /* get pool name and check number of arguments */
664 if (argc < 1) {
665 (void) fprintf(stderr, gettext("missing pool name argument\n"));
666 usage(B_FALSE);
667 }
668 if (argc < 2) {
669 (void) fprintf(stderr, gettext("missing vdev specification\n"));
670 usage(B_FALSE);
671 }
672
673 poolname = argv[0];
674
675 argc--;
676 argv++;
677
678 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
679 return (1);
680
681 if ((config = zpool_get_config(zhp, NULL)) == NULL) {
682 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
683 poolname);
684 zpool_close(zhp);
685 return (1);
686 }
687
688 /* unless manually specified use "ashift" pool property (if set) */
689 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
690 int intval;
691 zprop_source_t src;
692 char strval[ZPOOL_MAXPROPLEN];
693
694 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
695 if (src != ZPROP_SRC_DEFAULT) {
696 (void) sprintf(strval, "%" PRId32, intval);
697 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
698 &props, B_TRUE) == 0);
699 }
700 }
701
702 /* pass off to get_vdev_spec for processing */
703 nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun,
704 argc, argv);
705 if (nvroot == NULL) {
706 zpool_close(zhp);
707 return (1);
708 }
709
710 if (dryrun) {
711 nvlist_t *poolnvroot;
712 nvlist_t **l2child;
713 uint_t l2children, c;
714 char *vname;
715 boolean_t hadcache = B_FALSE;
716
717 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
718 &poolnvroot) == 0);
719
720 (void) printf(gettext("would update '%s' to the following "
721 "configuration:\n"), zpool_get_name(zhp));
722
723 /* print original main pool and new tree */
724 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE,
725 name_flags);
726 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE, name_flags);
727
728 /* Do the same for the logs */
729 if (num_logs(poolnvroot) > 0) {
730 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE,
731 name_flags);
732 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE,
733 name_flags);
734 } else if (num_logs(nvroot) > 0) {
735 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE,
736 name_flags);
737 }
738
739 /* Do the same for the caches */
740 if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_L2CACHE,
741 &l2child, &l2children) == 0 && l2children) {
742 hadcache = B_TRUE;
743 (void) printf(gettext("\tcache\n"));
744 for (c = 0; c < l2children; c++) {
745 vname = zpool_vdev_name(g_zfs, NULL,
746 l2child[c], name_flags);
747 (void) printf("\t %s\n", vname);
748 free(vname);
749 }
750 }
751 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
752 &l2child, &l2children) == 0 && l2children) {
753 if (!hadcache)
754 (void) printf(gettext("\tcache\n"));
755 for (c = 0; c < l2children; c++) {
756 vname = zpool_vdev_name(g_zfs, NULL,
757 l2child[c], name_flags);
758 (void) printf("\t %s\n", vname);
759 free(vname);
760 }
761 }
762
763 ret = 0;
764 } else {
765 ret = (zpool_add(zhp, nvroot) != 0);
766 }
767
768 nvlist_free(props);
769 nvlist_free(nvroot);
770 zpool_close(zhp);
771
772 return (ret);
773 }
774
775 /*
776 * zpool remove <pool> <vdev> ...
777 *
778 * Removes the given vdev from the pool. Currently, this supports removing
779 * spares, cache, and log devices from the pool.
780 */
781 int
782 zpool_do_remove(int argc, char **argv)
783 {
784 char *poolname;
785 int i, ret = 0;
786 zpool_handle_t *zhp = NULL;
787
788 argc--;
789 argv++;
790
791 /* get pool name and check number of arguments */
792 if (argc < 1) {
793 (void) fprintf(stderr, gettext("missing pool name argument\n"));
794 usage(B_FALSE);
795 }
796 if (argc < 2) {
797 (void) fprintf(stderr, gettext("missing device\n"));
798 usage(B_FALSE);
799 }
800
801 poolname = argv[0];
802
803 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
804 return (1);
805
806 for (i = 1; i < argc; i++) {
807 if (zpool_vdev_remove(zhp, argv[i]) != 0)
808 ret = 1;
809 }
810 zpool_close(zhp);
811
812 return (ret);
813 }
814
815 /*
816 * zpool labelclear [-f] <vdev>
817 *
818 * -f Force clearing the label for the vdevs which are members of
819 * the exported or foreign pools.
820 *
821 * Verifies that the vdev is not active and zeros out the label information
822 * on the device.
823 */
824 int
825 zpool_do_labelclear(int argc, char **argv)
826 {
827 char vdev[MAXPATHLEN];
828 char *name = NULL;
829 struct stat st;
830 int c, fd = -1, ret = 0;
831 nvlist_t *config;
832 pool_state_t state;
833 boolean_t inuse = B_FALSE;
834 boolean_t force = B_FALSE;
835
836 /* check options */
837 while ((c = getopt(argc, argv, "f")) != -1) {
838 switch (c) {
839 case 'f':
840 force = B_TRUE;
841 break;
842 default:
843 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
844 optopt);
845 usage(B_FALSE);
846 }
847 }
848
849 argc -= optind;
850 argv += optind;
851
852 /* get vdev name */
853 if (argc < 1) {
854 (void) fprintf(stderr, gettext("missing vdev name\n"));
855 usage(B_FALSE);
856 }
857 if (argc > 1) {
858 (void) fprintf(stderr, gettext("too many arguments\n"));
859 usage(B_FALSE);
860 }
861
862 /*
863 * Check if we were given absolute path and use it as is.
864 * Otherwise if the provided vdev name doesn't point to a file,
865 * try prepending expected disk paths and partition numbers.
866 */
867 (void) strlcpy(vdev, argv[0], sizeof (vdev));
868 if (vdev[0] != '/' && stat(vdev, &st) != 0) {
869 int error;
870
871 error = zfs_resolve_shortname(argv[0], vdev, MAXPATHLEN);
872 if (error == 0 && zfs_dev_is_whole_disk(vdev)) {
873 if (zfs_append_partition(vdev, MAXPATHLEN) == -1)
874 error = ENOENT;
875 }
876
877 if (error || (stat(vdev, &st) != 0)) {
878 (void) fprintf(stderr, gettext(
879 "failed to find device %s, try specifying absolute "
880 "path instead\n"), argv[0]);
881 return (1);
882 }
883 }
884
885 if ((fd = open(vdev, O_RDWR)) < 0) {
886 (void) fprintf(stderr, gettext("failed to open %s: %s\n"),
887 vdev, strerror(errno));
888 return (1);
889 }
890
891 if (ioctl(fd, BLKFLSBUF) != 0)
892 (void) fprintf(stderr, gettext("failed to invalidate "
893 "cache for %s: %s\n"), vdev, strerror(errno));
894
895 if (zpool_read_label(fd, &config, NULL) != 0 || config == NULL) {
896 (void) fprintf(stderr,
897 gettext("failed to check state for %s\n"), vdev);
898 return (1);
899 }
900 nvlist_free(config);
901
902 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
903 if (ret != 0) {
904 (void) fprintf(stderr,
905 gettext("failed to check state for %s\n"), vdev);
906 return (1);
907 }
908
909 if (!inuse)
910 goto wipe_label;
911
912 switch (state) {
913 default:
914 case POOL_STATE_ACTIVE:
915 case POOL_STATE_SPARE:
916 case POOL_STATE_L2CACHE:
917 (void) fprintf(stderr, gettext(
918 "%s is a member (%s) of pool \"%s\"\n"),
919 vdev, zpool_pool_state_to_name(state), name);
920 ret = 1;
921 goto errout;
922
923 case POOL_STATE_EXPORTED:
924 if (force)
925 break;
926 (void) fprintf(stderr, gettext(
927 "use '-f' to override the following error:\n"
928 "%s is a member of exported pool \"%s\"\n"),
929 vdev, name);
930 ret = 1;
931 goto errout;
932
933 case POOL_STATE_POTENTIALLY_ACTIVE:
934 if (force)
935 break;
936 (void) fprintf(stderr, gettext(
937 "use '-f' to override the following error:\n"
938 "%s is a member of potentially active pool \"%s\"\n"),
939 vdev, name);
940 ret = 1;
941 goto errout;
942
943 case POOL_STATE_DESTROYED:
944 /* inuse should never be set for a destroyed pool */
945 assert(0);
946 break;
947 }
948
949 wipe_label:
950 ret = zpool_clear_label(fd);
951 if (ret != 0) {
952 (void) fprintf(stderr,
953 gettext("failed to clear label for %s\n"), vdev);
954 }
955
956 errout:
957 free(name);
958 (void) close(fd);
959
960 return (ret);
961 }
962
963 /*
964 * zpool create [-fnd] [-o property=value] ...
965 * [-O file-system-property=value] ...
966 * [-R root] [-m mountpoint] <pool> <dev> ...
967 *
968 * -f Force creation, even if devices appear in use
969 * -n Do not create the pool, but display the resulting layout if it
970 * were to be created.
971 * -R Create a pool under an alternate root
972 * -m Set default mountpoint for the root dataset. By default it's
973 * '/<pool>'
974 * -o Set property=value.
975 * -o Set feature@feature=enabled|disabled.
976 * -d Don't automatically enable all supported pool features
977 * (individual features can be enabled with -o).
978 * -O Set fsproperty=value in the pool's root file system
979 *
980 * Creates the named pool according to the given vdev specification. The
981 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
982 * we get the nvlist back from get_vdev_spec(), we either print out the contents
983 * (if '-n' was specified), or pass it to libzfs to do the creation.
984 */
985 int
986 zpool_do_create(int argc, char **argv)
987 {
988 boolean_t force = B_FALSE;
989 boolean_t dryrun = B_FALSE;
990 boolean_t enable_all_pool_feat = B_TRUE;
991 int c;
992 nvlist_t *nvroot = NULL;
993 char *poolname;
994 char *tname = NULL;
995 int ret = 1;
996 char *altroot = NULL;
997 char *mountpoint = NULL;
998 nvlist_t *fsprops = NULL;
999 nvlist_t *props = NULL;
1000 char *propval;
1001
1002 /* check options */
1003 while ((c = getopt(argc, argv, ":fndR:m:o:O:t:")) != -1) {
1004 switch (c) {
1005 case 'f':
1006 force = B_TRUE;
1007 break;
1008 case 'n':
1009 dryrun = B_TRUE;
1010 break;
1011 case 'd':
1012 enable_all_pool_feat = B_FALSE;
1013 break;
1014 case 'R':
1015 altroot = optarg;
1016 if (add_prop_list(zpool_prop_to_name(
1017 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
1018 goto errout;
1019 if (add_prop_list_default(zpool_prop_to_name(
1020 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1021 goto errout;
1022 break;
1023 case 'm':
1024 /* Equivalent to -O mountpoint=optarg */
1025 mountpoint = optarg;
1026 break;
1027 case 'o':
1028 if ((propval = strchr(optarg, '=')) == NULL) {
1029 (void) fprintf(stderr, gettext("missing "
1030 "'=' for -o option\n"));
1031 goto errout;
1032 }
1033 *propval = '\0';
1034 propval++;
1035
1036 if (add_prop_list(optarg, propval, &props, B_TRUE))
1037 goto errout;
1038
1039 /*
1040 * If the user is creating a pool that doesn't support
1041 * feature flags, don't enable any features.
1042 */
1043 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
1044 char *end;
1045 u_longlong_t ver;
1046
1047 ver = strtoull(propval, &end, 10);
1048 if (*end == '\0' &&
1049 ver < SPA_VERSION_FEATURES) {
1050 enable_all_pool_feat = B_FALSE;
1051 }
1052 }
1053 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
1054 altroot = propval;
1055 break;
1056 case 'O':
1057 if ((propval = strchr(optarg, '=')) == NULL) {
1058 (void) fprintf(stderr, gettext("missing "
1059 "'=' for -O option\n"));
1060 goto errout;
1061 }
1062 *propval = '\0';
1063 propval++;
1064
1065 /*
1066 * Mountpoints are checked and then added later.
1067 * Uniquely among properties, they can be specified
1068 * more than once, to avoid conflict with -m.
1069 */
1070 if (0 == strcmp(optarg,
1071 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) {
1072 mountpoint = propval;
1073 } else if (add_prop_list(optarg, propval, &fsprops,
1074 B_FALSE)) {
1075 goto errout;
1076 }
1077 break;
1078 case 't':
1079 /*
1080 * Sanity check temporary pool name.
1081 */
1082 if (strchr(optarg, '/') != NULL) {
1083 (void) fprintf(stderr, gettext("cannot create "
1084 "'%s': invalid character '/' in temporary "
1085 "name\n"), optarg);
1086 (void) fprintf(stderr, gettext("use 'zfs "
1087 "create' to create a dataset\n"));
1088 goto errout;
1089 }
1090
1091 if (add_prop_list(zpool_prop_to_name(
1092 ZPOOL_PROP_TNAME), optarg, &props, B_TRUE))
1093 goto errout;
1094 if (add_prop_list_default(zpool_prop_to_name(
1095 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
1096 goto errout;
1097 tname = optarg;
1098 break;
1099 case ':':
1100 (void) fprintf(stderr, gettext("missing argument for "
1101 "'%c' option\n"), optopt);
1102 goto badusage;
1103 case '?':
1104 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1105 optopt);
1106 goto badusage;
1107 }
1108 }
1109
1110 argc -= optind;
1111 argv += optind;
1112
1113 /* get pool name and check number of arguments */
1114 if (argc < 1) {
1115 (void) fprintf(stderr, gettext("missing pool name argument\n"));
1116 goto badusage;
1117 }
1118 if (argc < 2) {
1119 (void) fprintf(stderr, gettext("missing vdev specification\n"));
1120 goto badusage;
1121 }
1122
1123 poolname = argv[0];
1124
1125 /*
1126 * As a special case, check for use of '/' in the name, and direct the
1127 * user to use 'zfs create' instead.
1128 */
1129 if (strchr(poolname, '/') != NULL) {
1130 (void) fprintf(stderr, gettext("cannot create '%s': invalid "
1131 "character '/' in pool name\n"), poolname);
1132 (void) fprintf(stderr, gettext("use 'zfs create' to "
1133 "create a dataset\n"));
1134 goto errout;
1135 }
1136
1137 /* pass off to get_vdev_spec for bulk processing */
1138 nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
1139 argc - 1, argv + 1);
1140 if (nvroot == NULL)
1141 goto errout;
1142
1143 /* make_root_vdev() allows 0 toplevel children if there are spares */
1144 if (!zfs_allocatable_devs(nvroot)) {
1145 (void) fprintf(stderr, gettext("invalid vdev "
1146 "specification: at least one toplevel vdev must be "
1147 "specified\n"));
1148 goto errout;
1149 }
1150
1151 if (altroot != NULL && altroot[0] != '/') {
1152 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
1153 "must be an absolute path\n"), altroot);
1154 goto errout;
1155 }
1156
1157 /*
1158 * Check the validity of the mountpoint and direct the user to use the
1159 * '-m' mountpoint option if it looks like its in use.
1160 */
1161 if (mountpoint == NULL ||
1162 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
1163 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
1164 char buf[MAXPATHLEN];
1165 DIR *dirp;
1166
1167 if (mountpoint && mountpoint[0] != '/') {
1168 (void) fprintf(stderr, gettext("invalid mountpoint "
1169 "'%s': must be an absolute path, 'legacy', or "
1170 "'none'\n"), mountpoint);
1171 goto errout;
1172 }
1173
1174 if (mountpoint == NULL) {
1175 if (altroot != NULL)
1176 (void) snprintf(buf, sizeof (buf), "%s/%s",
1177 altroot, poolname);
1178 else
1179 (void) snprintf(buf, sizeof (buf), "/%s",
1180 poolname);
1181 } else {
1182 if (altroot != NULL)
1183 (void) snprintf(buf, sizeof (buf), "%s%s",
1184 altroot, mountpoint);
1185 else
1186 (void) snprintf(buf, sizeof (buf), "%s",
1187 mountpoint);
1188 }
1189
1190 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
1191 (void) fprintf(stderr, gettext("mountpoint '%s' : "
1192 "%s\n"), buf, strerror(errno));
1193 (void) fprintf(stderr, gettext("use '-m' "
1194 "option to provide a different default\n"));
1195 goto errout;
1196 } else if (dirp) {
1197 int count = 0;
1198
1199 while (count < 3 && readdir(dirp) != NULL)
1200 count++;
1201 (void) closedir(dirp);
1202
1203 if (count > 2) {
1204 (void) fprintf(stderr, gettext("mountpoint "
1205 "'%s' exists and is not empty\n"), buf);
1206 (void) fprintf(stderr, gettext("use '-m' "
1207 "option to provide a "
1208 "different default\n"));
1209 goto errout;
1210 }
1211 }
1212 }
1213
1214 /*
1215 * Now that the mountpoint's validity has been checked, ensure that
1216 * the property is set appropriately prior to creating the pool.
1217 */
1218 if (mountpoint != NULL) {
1219 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
1220 mountpoint, &fsprops, B_FALSE);
1221 if (ret != 0)
1222 goto errout;
1223 }
1224
1225 ret = 1;
1226 if (dryrun) {
1227 /*
1228 * For a dry run invocation, print out a basic message and run
1229 * through all the vdevs in the list and print out in an
1230 * appropriate hierarchy.
1231 */
1232 (void) printf(gettext("would create '%s' with the "
1233 "following layout:\n\n"), poolname);
1234
1235 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE, 0);
1236 if (num_logs(nvroot) > 0)
1237 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE, 0);
1238
1239 ret = 0;
1240 } else {
1241 /*
1242 * Hand off to libzfs.
1243 */
1244 spa_feature_t i;
1245 for (i = 0; i < SPA_FEATURES; i++) {
1246 char propname[MAXPATHLEN];
1247 char *propval;
1248 zfeature_info_t *feat = &spa_feature_table[i];
1249
1250 (void) snprintf(propname, sizeof (propname),
1251 "feature@%s", feat->fi_uname);
1252
1253 /*
1254 * Only features contained in props will be enabled:
1255 * remove from the nvlist every ZFS_FEATURE_DISABLED
1256 * value and add every missing ZFS_FEATURE_ENABLED if
1257 * enable_all_pool_feat is set.
1258 */
1259 if (!nvlist_lookup_string(props, propname, &propval)) {
1260 if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
1261 (void) nvlist_remove_all(props,
1262 propname);
1263 } else if (enable_all_pool_feat) {
1264 ret = add_prop_list(propname,
1265 ZFS_FEATURE_ENABLED, &props, B_TRUE);
1266 if (ret != 0)
1267 goto errout;
1268 }
1269 }
1270
1271 ret = 1;
1272 if (zpool_create(g_zfs, poolname,
1273 nvroot, props, fsprops) == 0) {
1274 zfs_handle_t *pool = zfs_open(g_zfs,
1275 tname ? tname : poolname, ZFS_TYPE_FILESYSTEM);
1276 if (pool != NULL) {
1277 if (zfs_mount(pool, NULL, 0) == 0)
1278 ret = zfs_shareall(pool);
1279 zfs_close(pool);
1280 }
1281 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
1282 (void) fprintf(stderr, gettext("pool name may have "
1283 "been omitted\n"));
1284 }
1285 }
1286
1287 errout:
1288 nvlist_free(nvroot);
1289 nvlist_free(fsprops);
1290 nvlist_free(props);
1291 return (ret);
1292 badusage:
1293 nvlist_free(fsprops);
1294 nvlist_free(props);
1295 usage(B_FALSE);
1296 return (2);
1297 }
1298
1299 /*
1300 * zpool destroy <pool>
1301 *
1302 * -f Forcefully unmount any datasets
1303 *
1304 * Destroy the given pool. Automatically unmounts any datasets in the pool.
1305 */
1306 int
1307 zpool_do_destroy(int argc, char **argv)
1308 {
1309 boolean_t force = B_FALSE;
1310 int c;
1311 char *pool;
1312 zpool_handle_t *zhp;
1313 int ret;
1314
1315 /* check options */
1316 while ((c = getopt(argc, argv, "f")) != -1) {
1317 switch (c) {
1318 case 'f':
1319 force = B_TRUE;
1320 break;
1321 case '?':
1322 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1323 optopt);
1324 usage(B_FALSE);
1325 }
1326 }
1327
1328 argc -= optind;
1329 argv += optind;
1330
1331 /* check arguments */
1332 if (argc < 1) {
1333 (void) fprintf(stderr, gettext("missing pool argument\n"));
1334 usage(B_FALSE);
1335 }
1336 if (argc > 1) {
1337 (void) fprintf(stderr, gettext("too many arguments\n"));
1338 usage(B_FALSE);
1339 }
1340
1341 pool = argv[0];
1342
1343 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
1344 /*
1345 * As a special case, check for use of '/' in the name, and
1346 * direct the user to use 'zfs destroy' instead.
1347 */
1348 if (strchr(pool, '/') != NULL)
1349 (void) fprintf(stderr, gettext("use 'zfs destroy' to "
1350 "destroy a dataset\n"));
1351 return (1);
1352 }
1353
1354 if (zpool_disable_datasets(zhp, force) != 0) {
1355 (void) fprintf(stderr, gettext("could not destroy '%s': "
1356 "could not unmount datasets\n"), zpool_get_name(zhp));
1357 zpool_close(zhp);
1358 return (1);
1359 }
1360
1361 /* The history must be logged as part of the export */
1362 log_history = B_FALSE;
1363
1364 ret = (zpool_destroy(zhp, history_str) != 0);
1365
1366 zpool_close(zhp);
1367
1368 return (ret);
1369 }
1370
1371 typedef struct export_cbdata {
1372 boolean_t force;
1373 boolean_t hardforce;
1374 } export_cbdata_t;
1375
1376 /*
1377 * Export one pool
1378 */
1379 int
1380 zpool_export_one(zpool_handle_t *zhp, void *data)
1381 {
1382 export_cbdata_t *cb = data;
1383
1384 if (zpool_disable_datasets(zhp, cb->force) != 0)
1385 return (1);
1386
1387 /* The history must be logged as part of the export */
1388 log_history = B_FALSE;
1389
1390 if (cb->hardforce) {
1391 if (zpool_export_force(zhp, history_str) != 0)
1392 return (1);
1393 } else if (zpool_export(zhp, cb->force, history_str) != 0) {
1394 return (1);
1395 }
1396
1397 return (0);
1398 }
1399
1400 /*
1401 * zpool export [-f] <pool> ...
1402 *
1403 * -a Export all pools
1404 * -f Forcefully unmount datasets
1405 *
1406 * Export the given pools. By default, the command will attempt to cleanly
1407 * unmount any active datasets within the pool. If the '-f' flag is specified,
1408 * then the datasets will be forcefully unmounted.
1409 */
1410 int
1411 zpool_do_export(int argc, char **argv)
1412 {
1413 export_cbdata_t cb;
1414 boolean_t do_all = B_FALSE;
1415 boolean_t force = B_FALSE;
1416 boolean_t hardforce = B_FALSE;
1417 int c, ret;
1418
1419 /* check options */
1420 while ((c = getopt(argc, argv, "afF")) != -1) {
1421 switch (c) {
1422 case 'a':
1423 do_all = B_TRUE;
1424 break;
1425 case 'f':
1426 force = B_TRUE;
1427 break;
1428 case 'F':
1429 hardforce = B_TRUE;
1430 break;
1431 case '?':
1432 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
1433 optopt);
1434 usage(B_FALSE);
1435 }
1436 }
1437
1438 cb.force = force;
1439 cb.hardforce = hardforce;
1440 argc -= optind;
1441 argv += optind;
1442
1443 if (do_all) {
1444 if (argc != 0) {
1445 (void) fprintf(stderr, gettext("too many arguments\n"));
1446 usage(B_FALSE);
1447 }
1448
1449 return (for_each_pool(argc, argv, B_TRUE, NULL,
1450 zpool_export_one, &cb));
1451 }
1452
1453 /* check arguments */
1454 if (argc < 1) {
1455 (void) fprintf(stderr, gettext("missing pool argument\n"));
1456 usage(B_FALSE);
1457 }
1458
1459 ret = for_each_pool(argc, argv, B_TRUE, NULL, zpool_export_one, &cb);
1460
1461 return (ret);
1462 }
1463
1464 /*
1465 * Given a vdev configuration, determine the maximum width needed for the device
1466 * name column.
1467 */
1468 static int
1469 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
1470 int name_flags)
1471 {
1472 char *name;
1473 nvlist_t **child;
1474 uint_t c, children;
1475 int ret;
1476
1477 name = zpool_vdev_name(g_zfs, zhp, nv, name_flags);
1478 if (strlen(name) + depth > max)
1479 max = strlen(name) + depth;
1480
1481 free(name);
1482
1483 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1484 &child, &children) == 0) {
1485 for (c = 0; c < children; c++)
1486 if ((ret = max_width(zhp, child[c], depth + 2,
1487 max, name_flags)) > max)
1488 max = ret;
1489 }
1490
1491 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1492 &child, &children) == 0) {
1493 for (c = 0; c < children; c++)
1494 if ((ret = max_width(zhp, child[c], depth + 2,
1495 max, name_flags)) > max)
1496 max = ret;
1497 }
1498
1499 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1500 &child, &children) == 0) {
1501 for (c = 0; c < children; c++)
1502 if ((ret = max_width(zhp, child[c], depth + 2,
1503 max, name_flags)) > max)
1504 max = ret;
1505 }
1506
1507 return (max);
1508 }
1509
1510 typedef struct spare_cbdata {
1511 uint64_t cb_guid;
1512 zpool_handle_t *cb_zhp;
1513 } spare_cbdata_t;
1514
1515 static boolean_t
1516 find_vdev(nvlist_t *nv, uint64_t search)
1517 {
1518 uint64_t guid;
1519 nvlist_t **child;
1520 uint_t c, children;
1521
1522 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
1523 search == guid)
1524 return (B_TRUE);
1525
1526 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1527 &child, &children) == 0) {
1528 for (c = 0; c < children; c++)
1529 if (find_vdev(child[c], search))
1530 return (B_TRUE);
1531 }
1532
1533 return (B_FALSE);
1534 }
1535
1536 static int
1537 find_spare(zpool_handle_t *zhp, void *data)
1538 {
1539 spare_cbdata_t *cbp = data;
1540 nvlist_t *config, *nvroot;
1541
1542 config = zpool_get_config(zhp, NULL);
1543 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1544 &nvroot) == 0);
1545
1546 if (find_vdev(nvroot, cbp->cb_guid)) {
1547 cbp->cb_zhp = zhp;
1548 return (1);
1549 }
1550
1551 zpool_close(zhp);
1552 return (0);
1553 }
1554
1555 typedef struct status_cbdata {
1556 int cb_count;
1557 int cb_name_flags;
1558 int cb_namewidth;
1559 boolean_t cb_allpools;
1560 boolean_t cb_verbose;
1561 boolean_t cb_explain;
1562 boolean_t cb_first;
1563 boolean_t cb_dedup_stats;
1564 boolean_t cb_print_status;
1565 vdev_cmd_data_list_t *vcdl;
1566 } status_cbdata_t;
1567
1568 /* Return 1 if string is NULL, empty, or whitespace; return 0 otherwise. */
1569 static int
1570 is_blank_str(char *str)
1571 {
1572 while (str != NULL && *str != '\0') {
1573 if (!isblank(*str))
1574 return (0);
1575 str++;
1576 }
1577 return (1);
1578 }
1579
1580 /* Print command output lines for specific vdev in a specific pool */
1581 static void
1582 zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, char *path)
1583 {
1584 vdev_cmd_data_t *data;
1585 int i, j;
1586 char *val;
1587
1588 for (i = 0; i < vcdl->count; i++) {
1589 if ((strcmp(vcdl->data[i].path, path) != 0) ||
1590 (strcmp(vcdl->data[i].pool, pool) != 0)) {
1591 /* Not the vdev we're looking for */
1592 continue;
1593 }
1594
1595 data = &vcdl->data[i];
1596 /* Print out all the output values for this vdev */
1597 for (j = 0; j < vcdl->uniq_cols_cnt; j++) {
1598 val = NULL;
1599 /* Does this vdev have values for this column? */
1600 for (int k = 0; k < data->cols_cnt; k++) {
1601 if (strcmp(data->cols[k],
1602 vcdl->uniq_cols[j]) == 0) {
1603 /* yes it does, record the value */
1604 val = data->lines[k];
1605 break;
1606 }
1607 }
1608 /*
1609 * Mark empty values with dashes to make output
1610 * awk-able.
1611 */
1612 if (is_blank_str(val))
1613 val = "-";
1614
1615 printf("%*s", vcdl->uniq_cols_width[j], val);
1616 if (j < vcdl->uniq_cols_cnt - 1)
1617 printf(" ");
1618 }
1619
1620 /* Print out any values that aren't in a column at the end */
1621 for (j = data->cols_cnt; j < data->lines_cnt; j++) {
1622 /* Did we have any columns? If so print a spacer. */
1623 if (vcdl->uniq_cols_cnt > 0)
1624 printf(" ");
1625
1626 val = data->lines[j];
1627 printf("%s", val ? val : "");
1628 }
1629 break;
1630 }
1631 }
1632
1633 /*
1634 * Print out configuration state as requested by status_callback.
1635 */
1636 static void
1637 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
1638 nvlist_t *nv, int depth, boolean_t isspare)
1639 {
1640 nvlist_t **child;
1641 uint_t c, children;
1642 pool_scan_stat_t *ps = NULL;
1643 vdev_stat_t *vs;
1644 char rbuf[6], wbuf[6], cbuf[6];
1645 char *vname;
1646 uint64_t notpresent;
1647 spare_cbdata_t spare_cb;
1648 char *state;
1649 char *path = NULL;
1650
1651 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1652 &child, &children) != 0)
1653 children = 0;
1654
1655 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1656 (uint64_t **)&vs, &c) == 0);
1657
1658 state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1659 if (isspare) {
1660 /*
1661 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
1662 * online drives.
1663 */
1664 if (vs->vs_aux == VDEV_AUX_SPARED)
1665 state = "INUSE";
1666 else if (vs->vs_state == VDEV_STATE_HEALTHY)
1667 state = "AVAIL";
1668 }
1669
1670 (void) printf("\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth,
1671 name, state);
1672
1673 if (!isspare) {
1674 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
1675 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
1676 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
1677 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
1678 }
1679
1680 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
1681 &notpresent) == 0) {
1682 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
1683 (void) printf(" was %s", path);
1684 } else if (vs->vs_aux != 0) {
1685 (void) printf(" ");
1686
1687 switch (vs->vs_aux) {
1688 case VDEV_AUX_OPEN_FAILED:
1689 (void) printf(gettext("cannot open"));
1690 break;
1691
1692 case VDEV_AUX_BAD_GUID_SUM:
1693 (void) printf(gettext("missing device"));
1694 break;
1695
1696 case VDEV_AUX_NO_REPLICAS:
1697 (void) printf(gettext("insufficient replicas"));
1698 break;
1699
1700 case VDEV_AUX_VERSION_NEWER:
1701 (void) printf(gettext("newer version"));
1702 break;
1703
1704 case VDEV_AUX_UNSUP_FEAT:
1705 (void) printf(gettext("unsupported feature(s)"));
1706 break;
1707
1708 case VDEV_AUX_SPARED:
1709 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1710 &spare_cb.cb_guid) == 0);
1711 if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) {
1712 if (strcmp(zpool_get_name(spare_cb.cb_zhp),
1713 zpool_get_name(zhp)) == 0)
1714 (void) printf(gettext("currently in "
1715 "use"));
1716 else
1717 (void) printf(gettext("in use by "
1718 "pool '%s'"),
1719 zpool_get_name(spare_cb.cb_zhp));
1720 zpool_close(spare_cb.cb_zhp);
1721 } else {
1722 (void) printf(gettext("currently in use"));
1723 }
1724 break;
1725
1726 case VDEV_AUX_ERR_EXCEEDED:
1727 (void) printf(gettext("too many errors"));
1728 break;
1729
1730 case VDEV_AUX_IO_FAILURE:
1731 (void) printf(gettext("experienced I/O failures"));
1732 break;
1733
1734 case VDEV_AUX_BAD_LOG:
1735 (void) printf(gettext("bad intent log"));
1736 break;
1737
1738 case VDEV_AUX_EXTERNAL:
1739 (void) printf(gettext("external device fault"));
1740 break;
1741
1742 case VDEV_AUX_SPLIT_POOL:
1743 (void) printf(gettext("split into new pool"));
1744 break;
1745
1746 case VDEV_AUX_ACTIVE:
1747 (void) printf(gettext("currently in use"));
1748 break;
1749
1750 default:
1751 (void) printf(gettext("corrupted data"));
1752 break;
1753 }
1754 }
1755
1756 (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
1757 (uint64_t **)&ps, &c);
1758
1759 if (ps && ps->pss_state == DSS_SCANNING &&
1760 vs->vs_scan_processed != 0 && children == 0) {
1761 (void) printf(gettext(" (%s)"),
1762 (ps->pss_func == POOL_SCAN_RESILVER) ?
1763 "resilvering" : "repairing");
1764 }
1765
1766 if (cb->vcdl != NULL) {
1767 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
1768 printf(" ");
1769 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path);
1770 }
1771 }
1772
1773 (void) printf("\n");
1774
1775 for (c = 0; c < children; c++) {
1776 uint64_t islog = B_FALSE, ishole = B_FALSE;
1777
1778 /* Don't print logs or holes here */
1779 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1780 &islog);
1781 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1782 &ishole);
1783 if (islog || ishole)
1784 continue;
1785 vname = zpool_vdev_name(g_zfs, zhp, child[c],
1786 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1787 print_status_config(zhp, cb, vname, child[c], depth + 2,
1788 isspare);
1789 free(vname);
1790 }
1791 }
1792
1793 /*
1794 * Print the configuration of an exported pool. Iterate over all vdevs in the
1795 * pool, printing out the name and status for each one.
1796 */
1797 static void
1798 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv,
1799 int depth)
1800 {
1801 nvlist_t **child;
1802 uint_t c, children;
1803 vdev_stat_t *vs;
1804 char *type, *vname;
1805
1806 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
1807 if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
1808 strcmp(type, VDEV_TYPE_HOLE) == 0)
1809 return;
1810
1811 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
1812 (uint64_t **)&vs, &c) == 0);
1813
1814 (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name);
1815 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
1816
1817 if (vs->vs_aux != 0) {
1818 (void) printf(" ");
1819
1820 switch (vs->vs_aux) {
1821 case VDEV_AUX_OPEN_FAILED:
1822 (void) printf(gettext("cannot open"));
1823 break;
1824
1825 case VDEV_AUX_BAD_GUID_SUM:
1826 (void) printf(gettext("missing device"));
1827 break;
1828
1829 case VDEV_AUX_NO_REPLICAS:
1830 (void) printf(gettext("insufficient replicas"));
1831 break;
1832
1833 case VDEV_AUX_VERSION_NEWER:
1834 (void) printf(gettext("newer version"));
1835 break;
1836
1837 case VDEV_AUX_UNSUP_FEAT:
1838 (void) printf(gettext("unsupported feature(s)"));
1839 break;
1840
1841 case VDEV_AUX_ERR_EXCEEDED:
1842 (void) printf(gettext("too many errors"));
1843 break;
1844
1845 case VDEV_AUX_ACTIVE:
1846 (void) printf(gettext("currently in use"));
1847 break;
1848
1849 default:
1850 (void) printf(gettext("corrupted data"));
1851 break;
1852 }
1853 }
1854 (void) printf("\n");
1855
1856 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1857 &child, &children) != 0)
1858 return;
1859
1860 for (c = 0; c < children; c++) {
1861 uint64_t is_log = B_FALSE;
1862
1863 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1864 &is_log);
1865 if (is_log)
1866 continue;
1867
1868 vname = zpool_vdev_name(g_zfs, NULL, child[c],
1869 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1870 print_import_config(cb, vname, child[c], depth + 2);
1871 free(vname);
1872 }
1873
1874 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
1875 &child, &children) == 0) {
1876 (void) printf(gettext("\tcache\n"));
1877 for (c = 0; c < children; c++) {
1878 vname = zpool_vdev_name(g_zfs, NULL, child[c],
1879 cb->cb_name_flags);
1880 (void) printf("\t %s\n", vname);
1881 free(vname);
1882 }
1883 }
1884
1885 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
1886 &child, &children) == 0) {
1887 (void) printf(gettext("\tspares\n"));
1888 for (c = 0; c < children; c++) {
1889 vname = zpool_vdev_name(g_zfs, NULL, child[c],
1890 cb->cb_name_flags);
1891 (void) printf("\t %s\n", vname);
1892 free(vname);
1893 }
1894 }
1895 }
1896
1897 /*
1898 * Print log vdevs.
1899 * Logs are recorded as top level vdevs in the main pool child array
1900 * but with "is_log" set to 1. We use either print_status_config() or
1901 * print_import_config() to print the top level logs then any log
1902 * children (eg mirrored slogs) are printed recursively - which
1903 * works because only the top level vdev is marked "is_log"
1904 */
1905 static void
1906 print_logs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv)
1907 {
1908 uint_t c, children;
1909 nvlist_t **child;
1910
1911 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child,
1912 &children) != 0)
1913 return;
1914
1915 (void) printf(gettext("\tlogs\n"));
1916
1917 for (c = 0; c < children; c++) {
1918 uint64_t is_log = B_FALSE;
1919 char *name;
1920
1921 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1922 &is_log);
1923 if (!is_log)
1924 continue;
1925 name = zpool_vdev_name(g_zfs, zhp, child[c],
1926 cb->cb_name_flags | VDEV_NAME_TYPE_ID);
1927 if (cb->cb_print_status)
1928 print_status_config(zhp, cb, name, child[c], 2,
1929 B_FALSE);
1930 else
1931 print_import_config(cb, name, child[c], 2);
1932 free(name);
1933 }
1934 }
1935
1936 /*
1937 * Display the status for the given pool.
1938 */
1939 static void
1940 show_import(nvlist_t *config)
1941 {
1942 uint64_t pool_state;
1943 vdev_stat_t *vs;
1944 char *name;
1945 uint64_t guid;
1946 uint64_t hostid = 0;
1947 char *msgid;
1948 char *hostname = "unknown";
1949 nvlist_t *nvroot, *nvinfo;
1950 zpool_status_t reason;
1951 zpool_errata_t errata;
1952 const char *health;
1953 uint_t vsc;
1954 char *comment;
1955 status_cbdata_t cb = { 0 };
1956
1957 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1958 &name) == 0);
1959 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1960 &guid) == 0);
1961 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1962 &pool_state) == 0);
1963 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
1964 &nvroot) == 0);
1965
1966 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
1967 (uint64_t **)&vs, &vsc) == 0);
1968 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
1969
1970 reason = zpool_import_status(config, &msgid, &errata);
1971
1972 (void) printf(gettext(" pool: %s\n"), name);
1973 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
1974 (void) printf(gettext(" state: %s"), health);
1975 if (pool_state == POOL_STATE_DESTROYED)
1976 (void) printf(gettext(" (DESTROYED)"));
1977 (void) printf("\n");
1978
1979 switch (reason) {
1980 case ZPOOL_STATUS_MISSING_DEV_R:
1981 case ZPOOL_STATUS_MISSING_DEV_NR:
1982 case ZPOOL_STATUS_BAD_GUID_SUM:
1983 (void) printf(gettext(" status: One or more devices are "
1984 "missing from the system.\n"));
1985 break;
1986
1987 case ZPOOL_STATUS_CORRUPT_LABEL_R:
1988 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
1989 (void) printf(gettext(" status: One or more devices contains "
1990 "corrupted data.\n"));
1991 break;
1992
1993 case ZPOOL_STATUS_CORRUPT_DATA:
1994 (void) printf(
1995 gettext(" status: The pool data is corrupted.\n"));
1996 break;
1997
1998 case ZPOOL_STATUS_OFFLINE_DEV:
1999 (void) printf(gettext(" status: One or more devices "
2000 "are offlined.\n"));
2001 break;
2002
2003 case ZPOOL_STATUS_CORRUPT_POOL:
2004 (void) printf(gettext(" status: The pool metadata is "
2005 "corrupted.\n"));
2006 break;
2007
2008 case ZPOOL_STATUS_VERSION_OLDER:
2009 (void) printf(gettext(" status: The pool is formatted using a "
2010 "legacy on-disk version.\n"));
2011 break;
2012
2013 case ZPOOL_STATUS_VERSION_NEWER:
2014 (void) printf(gettext(" status: The pool is formatted using an "
2015 "incompatible version.\n"));
2016 break;
2017
2018 case ZPOOL_STATUS_FEAT_DISABLED:
2019 (void) printf(gettext(" status: Some supported features are "
2020 "not enabled on the pool.\n"));
2021 break;
2022
2023 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2024 (void) printf(gettext("status: The pool uses the following "
2025 "feature(s) not supported on this system:\n"));
2026 zpool_print_unsup_feat(config);
2027 break;
2028
2029 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2030 (void) printf(gettext("status: The pool can only be accessed "
2031 "in read-only mode on this system. It\n\tcannot be "
2032 "accessed in read-write mode because it uses the "
2033 "following\n\tfeature(s) not supported on this system:\n"));
2034 zpool_print_unsup_feat(config);
2035 break;
2036
2037 case ZPOOL_STATUS_HOSTID_ACTIVE:
2038 (void) printf(gettext(" status: The pool is currently "
2039 "imported by another system.\n"));
2040 break;
2041
2042 case ZPOOL_STATUS_HOSTID_REQUIRED:
2043 (void) printf(gettext(" status: The pool has the "
2044 "multihost property on. It cannot\n\tbe safely imported "
2045 "when the system hostid is not set.\n"));
2046 break;
2047
2048 case ZPOOL_STATUS_HOSTID_MISMATCH:
2049 (void) printf(gettext(" status: The pool was last accessed by "
2050 "another system.\n"));
2051 break;
2052
2053 case ZPOOL_STATUS_FAULTED_DEV_R:
2054 case ZPOOL_STATUS_FAULTED_DEV_NR:
2055 (void) printf(gettext(" status: One or more devices are "
2056 "faulted.\n"));
2057 break;
2058
2059 case ZPOOL_STATUS_BAD_LOG:
2060 (void) printf(gettext(" status: An intent log record cannot be "
2061 "read.\n"));
2062 break;
2063
2064 case ZPOOL_STATUS_RESILVERING:
2065 (void) printf(gettext(" status: One or more devices were being "
2066 "resilvered.\n"));
2067 break;
2068
2069 case ZPOOL_STATUS_ERRATA:
2070 (void) printf(gettext(" status: Errata #%d detected.\n"),
2071 errata);
2072 break;
2073
2074 default:
2075 /*
2076 * No other status can be seen when importing pools.
2077 */
2078 assert(reason == ZPOOL_STATUS_OK);
2079 }
2080
2081 /*
2082 * Print out an action according to the overall state of the pool.
2083 */
2084 if (vs->vs_state == VDEV_STATE_HEALTHY) {
2085 if (reason == ZPOOL_STATUS_VERSION_OLDER ||
2086 reason == ZPOOL_STATUS_FEAT_DISABLED) {
2087 (void) printf(gettext(" action: The pool can be "
2088 "imported using its name or numeric identifier, "
2089 "though\n\tsome features will not be available "
2090 "without an explicit 'zpool upgrade'.\n"));
2091 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
2092 (void) printf(gettext(" action: The pool can be "
2093 "imported using its name or numeric "
2094 "identifier and\n\tthe '-f' flag.\n"));
2095 } else if (reason == ZPOOL_STATUS_ERRATA) {
2096 switch (errata) {
2097 case ZPOOL_ERRATA_NONE:
2098 break;
2099
2100 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
2101 (void) printf(gettext(" action: The pool can "
2102 "be imported using its name or numeric "
2103 "identifier,\n\thowever there is a compat"
2104 "ibility issue which should be corrected"
2105 "\n\tby running 'zpool scrub'\n"));
2106 break;
2107
2108 case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
2109 (void) printf(gettext(" action: The pool can"
2110 "not be imported with this version of ZFS "
2111 "due to\n\tan active asynchronous destroy. "
2112 "Revert to an earlier version\n\tand "
2113 "allow the destroy to complete before "
2114 "updating.\n"));
2115 break;
2116
2117 default:
2118 /*
2119 * All errata must contain an action message.
2120 */
2121 assert(0);
2122 }
2123 } else {
2124 (void) printf(gettext(" action: The pool can be "
2125 "imported using its name or numeric "
2126 "identifier.\n"));
2127 }
2128 } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
2129 (void) printf(gettext(" action: The pool can be imported "
2130 "despite missing or damaged devices. The\n\tfault "
2131 "tolerance of the pool may be compromised if imported.\n"));
2132 } else {
2133 switch (reason) {
2134 case ZPOOL_STATUS_VERSION_NEWER:
2135 (void) printf(gettext(" action: The pool cannot be "
2136 "imported. Access the pool on a system running "
2137 "newer\n\tsoftware, or recreate the pool from "
2138 "backup.\n"));
2139 break;
2140 case ZPOOL_STATUS_UNSUP_FEAT_READ:
2141 (void) printf(gettext("action: The pool cannot be "
2142 "imported. Access the pool on a system that "
2143 "supports\n\tthe required feature(s), or recreate "
2144 "the pool from backup.\n"));
2145 break;
2146 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
2147 (void) printf(gettext("action: The pool cannot be "
2148 "imported in read-write mode. Import the pool "
2149 "with\n"
2150 "\t\"-o readonly=on\", access the pool on a system "
2151 "that supports the\n\trequired feature(s), or "
2152 "recreate the pool from backup.\n"));
2153 break;
2154 case ZPOOL_STATUS_MISSING_DEV_R:
2155 case ZPOOL_STATUS_MISSING_DEV_NR:
2156 case ZPOOL_STATUS_BAD_GUID_SUM:
2157 (void) printf(gettext(" action: The pool cannot be "
2158 "imported. Attach the missing\n\tdevices and try "
2159 "again.\n"));
2160 break;
2161 case ZPOOL_STATUS_HOSTID_ACTIVE:
2162 VERIFY0(nvlist_lookup_nvlist(config,
2163 ZPOOL_CONFIG_LOAD_INFO, &nvinfo));
2164
2165 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2166 hostname = fnvlist_lookup_string(nvinfo,
2167 ZPOOL_CONFIG_MMP_HOSTNAME);
2168
2169 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2170 hostid = fnvlist_lookup_uint64(nvinfo,
2171 ZPOOL_CONFIG_MMP_HOSTID);
2172
2173 (void) printf(gettext(" action: The pool must be "
2174 "exported from %s (hostid=%lx)\n\tbefore it "
2175 "can be safely imported.\n"), hostname,
2176 (unsigned long) hostid);
2177 break;
2178 case ZPOOL_STATUS_HOSTID_REQUIRED:
2179 (void) printf(gettext(" action: Set a unique system "
2180 "hostid with the zgenhostid(8) command.\n"));
2181 break;
2182 default:
2183 (void) printf(gettext(" action: The pool cannot be "
2184 "imported due to damaged devices or data.\n"));
2185 }
2186 }
2187
2188 /* Print the comment attached to the pool. */
2189 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
2190 (void) printf(gettext("comment: %s\n"), comment);
2191
2192 /*
2193 * If the state is "closed" or "can't open", and the aux state
2194 * is "corrupt data":
2195 */
2196 if (((vs->vs_state == VDEV_STATE_CLOSED) ||
2197 (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
2198 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
2199 if (pool_state == POOL_STATE_DESTROYED)
2200 (void) printf(gettext("\tThe pool was destroyed, "
2201 "but can be imported using the '-Df' flags.\n"));
2202 else if (pool_state != POOL_STATE_EXPORTED)
2203 (void) printf(gettext("\tThe pool may be active on "
2204 "another system, but can be imported using\n\t"
2205 "the '-f' flag.\n"));
2206 }
2207
2208 if (msgid != NULL)
2209 (void) printf(gettext(" see: http://zfsonlinux.org/msg/%s\n"),
2210 msgid);
2211
2212 (void) printf(gettext(" config:\n\n"));
2213
2214 cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name),
2215 VDEV_NAME_TYPE_ID);
2216 if (cb.cb_namewidth < 10)
2217 cb.cb_namewidth = 10;
2218
2219 print_import_config(&cb, name, nvroot, 0);
2220 if (num_logs(nvroot) > 0)
2221 print_logs(NULL, &cb, nvroot);
2222
2223 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
2224 (void) printf(gettext("\n\tAdditional devices are known to "
2225 "be part of this pool, though their\n\texact "
2226 "configuration cannot be determined.\n"));
2227 }
2228 }
2229
2230 static boolean_t
2231 zfs_force_import_required(nvlist_t *config)
2232 {
2233 uint64_t state;
2234 uint64_t hostid = 0;
2235 nvlist_t *nvinfo;
2236
2237 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2238 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
2239
2240 if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid())
2241 return (B_TRUE);
2242
2243 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2244 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) {
2245 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo,
2246 ZPOOL_CONFIG_MMP_STATE);
2247
2248 if (mmp_state != MMP_STATE_INACTIVE)
2249 return (B_TRUE);
2250 }
2251
2252 return (B_FALSE);
2253 }
2254
2255 /*
2256 * Perform the import for the given configuration. This passes the heavy
2257 * lifting off to zpool_import_props(), and then mounts the datasets contained
2258 * within the pool.
2259 */
2260 static int
2261 do_import(nvlist_t *config, const char *newname, const char *mntopts,
2262 nvlist_t *props, int flags)
2263 {
2264 zpool_handle_t *zhp;
2265 char *name;
2266 uint64_t state;
2267 uint64_t version;
2268
2269 name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2270 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
2271 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2272
2273 if (!SPA_VERSION_IS_SUPPORTED(version)) {
2274 (void) fprintf(stderr, gettext("cannot import '%s': pool "
2275 "is formatted using an unsupported ZFS version\n"), name);
2276 return (1);
2277 } else if (zfs_force_import_required(config) &&
2278 !(flags & ZFS_IMPORT_ANY_HOST)) {
2279 mmp_state_t mmp_state = MMP_STATE_INACTIVE;
2280 nvlist_t *nvinfo;
2281
2282 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
2283 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE))
2284 mmp_state = fnvlist_lookup_uint64(nvinfo,
2285 ZPOOL_CONFIG_MMP_STATE);
2286
2287 if (mmp_state == MMP_STATE_ACTIVE) {
2288 char *hostname = "<unknown>";
2289 uint64_t hostid = 0;
2290
2291 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME))
2292 hostname = fnvlist_lookup_string(nvinfo,
2293 ZPOOL_CONFIG_MMP_HOSTNAME);
2294
2295 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID))
2296 hostid = fnvlist_lookup_uint64(nvinfo,
2297 ZPOOL_CONFIG_MMP_HOSTID);
2298
2299 (void) fprintf(stderr, gettext("cannot import '%s': "
2300 "pool is imported on %s (hostid: "
2301 "0x%lx)\nExport the pool on the other system, "
2302 "then run 'zpool import'.\n"),
2303 name, hostname, (unsigned long) hostid);
2304 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2305 (void) fprintf(stderr, gettext("Cannot import '%s': "
2306 "pool has the multihost property on and the\n"
2307 "system's hostid is not set. Set a unique hostid "
2308 "with the zgenhostid(8) command.\n"), name);
2309 } else {
2310 char *hostname = "<unknown>";
2311 uint64_t timestamp = 0;
2312 uint64_t hostid = 0;
2313
2314 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME))
2315 hostname = fnvlist_lookup_string(config,
2316 ZPOOL_CONFIG_HOSTNAME);
2317
2318 if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP))
2319 timestamp = fnvlist_lookup_uint64(config,
2320 ZPOOL_CONFIG_TIMESTAMP);
2321
2322 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID))
2323 hostid = fnvlist_lookup_uint64(config,
2324 ZPOOL_CONFIG_HOSTID);
2325
2326 (void) fprintf(stderr, gettext("cannot import '%s': "
2327 "pool was previously in use from another system.\n"
2328 "Last accessed by %s (hostid=%lx) at %s"
2329 "The pool can be imported, use 'zpool import -f' "
2330 "to import the pool.\n"), name, hostname,
2331 (unsigned long)hostid, ctime((time_t *)&timestamp));
2332 }
2333
2334 return (1);
2335 }
2336
2337 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
2338 return (1);
2339
2340 if (newname != NULL)
2341 name = (char *)newname;
2342
2343 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
2344 return (1);
2345
2346 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
2347 !(flags & ZFS_IMPORT_ONLY) &&
2348 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
2349 zpool_close(zhp);
2350 return (1);
2351 }
2352
2353 zpool_close(zhp);
2354 return (0);
2355 }
2356
2357 /*
2358 * zpool import [-d dir] [-D]
2359 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2360 * [-d dir | -c cachefile] [-f] -a
2361 * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2362 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
2363 *
2364 * -c Read pool information from a cachefile instead of searching
2365 * devices.
2366 *
2367 * -d Scan in a specific directory, other than /dev/. More than
2368 * one directory can be specified using multiple '-d' options.
2369 *
2370 * -D Scan for previously destroyed pools or import all or only
2371 * specified destroyed pools.
2372 *
2373 * -R Temporarily import the pool, with all mountpoints relative to
2374 * the given root. The pool will remain exported when the machine
2375 * is rebooted.
2376 *
2377 * -V Import even in the presence of faulted vdevs. This is an
2378 * intentionally undocumented option for testing purposes, and
2379 * treats the pool configuration as complete, leaving any bad
2380 * vdevs in the FAULTED state. In other words, it does verbatim
2381 * import.
2382 *
2383 * -f Force import, even if it appears that the pool is active.
2384 *
2385 * -F Attempt rewind if necessary.
2386 *
2387 * -n See if rewind would work, but don't actually rewind.
2388 *
2389 * -N Import the pool but don't mount datasets.
2390 *
2391 * -T Specify a starting txg to use for import. This option is
2392 * intentionally undocumented option for testing purposes.
2393 *
2394 * -a Import all pools found.
2395 *
2396 * -o Set property=value and/or temporary mount options (without '=').
2397 *
2398 * -s Scan using the default search path, the libblkid cache will
2399 * not be consulted.
2400 *
2401 * The import command scans for pools to import, and import pools based on pool
2402 * name and GUID. The pool can also be renamed as part of the import process.
2403 */
2404 int
2405 zpool_do_import(int argc, char **argv)
2406 {
2407 char **searchdirs = NULL;
2408 char *env, *envdup = NULL;
2409 int nsearch = 0;
2410 int c;
2411 int err = 0;
2412 nvlist_t *pools = NULL;
2413 boolean_t do_all = B_FALSE;
2414 boolean_t do_destroyed = B_FALSE;
2415 char *mntopts = NULL;
2416 nvpair_t *elem;
2417 nvlist_t *config;
2418 uint64_t searchguid = 0;
2419 char *searchname = NULL;
2420 char *propval;
2421 nvlist_t *found_config;
2422 nvlist_t *policy = NULL;
2423 nvlist_t *props = NULL;
2424 boolean_t first;
2425 int flags = ZFS_IMPORT_NORMAL;
2426 uint32_t rewind_policy = ZPOOL_NO_REWIND;
2427 boolean_t dryrun = B_FALSE;
2428 boolean_t do_rewind = B_FALSE;
2429 boolean_t xtreme_rewind = B_FALSE;
2430 boolean_t do_scan = B_FALSE;
2431 uint64_t pool_state, txg = -1ULL;
2432 char *cachefile = NULL;
2433 importargs_t idata = { 0 };
2434 char *endptr;
2435
2436 /* check options */
2437 while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:stT:VX")) != -1) {
2438 switch (c) {
2439 case 'a':
2440 do_all = B_TRUE;
2441 break;
2442 case 'c':
2443 cachefile = optarg;
2444 break;
2445 case 'd':
2446 if (searchdirs == NULL) {
2447 searchdirs = safe_malloc(sizeof (char *));
2448 } else {
2449 char **tmp = safe_malloc((nsearch + 1) *
2450 sizeof (char *));
2451 bcopy(searchdirs, tmp, nsearch *
2452 sizeof (char *));
2453 free(searchdirs);
2454 searchdirs = tmp;
2455 }
2456 searchdirs[nsearch++] = optarg;
2457 break;
2458 case 'D':
2459 do_destroyed = B_TRUE;
2460 break;
2461 case 'f':
2462 flags |= ZFS_IMPORT_ANY_HOST;
2463 break;
2464 case 'F':
2465 do_rewind = B_TRUE;
2466 break;
2467 case 'm':
2468 flags |= ZFS_IMPORT_MISSING_LOG;
2469 break;
2470 case 'n':
2471 dryrun = B_TRUE;
2472 break;
2473 case 'N':
2474 flags |= ZFS_IMPORT_ONLY;
2475 break;
2476 case 'o':
2477 if ((propval = strchr(optarg, '=')) != NULL) {
2478 *propval = '\0';
2479 propval++;
2480 if (add_prop_list(optarg, propval,
2481 &props, B_TRUE))
2482 goto error;
2483 } else {
2484 mntopts = optarg;
2485 }
2486 break;
2487 case 'R':
2488 if (add_prop_list(zpool_prop_to_name(
2489 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
2490 goto error;
2491 if (add_prop_list_default(zpool_prop_to_name(
2492 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2493 goto error;
2494 break;
2495 case 's':
2496 do_scan = B_TRUE;
2497 break;
2498 case 't':
2499 flags |= ZFS_IMPORT_TEMP_NAME;
2500 if (add_prop_list_default(zpool_prop_to_name(
2501 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
2502 goto error;
2503 break;
2504
2505 case 'T':
2506 errno = 0;
2507 txg = strtoull(optarg, &endptr, 0);
2508 if (errno != 0 || *endptr != '\0') {
2509 (void) fprintf(stderr,
2510 gettext("invalid txg value\n"));
2511 usage(B_FALSE);
2512 }
2513 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
2514 break;
2515 case 'V':
2516 flags |= ZFS_IMPORT_VERBATIM;
2517 break;
2518 case 'X':
2519 xtreme_rewind = B_TRUE;
2520 break;
2521 case ':':
2522 (void) fprintf(stderr, gettext("missing argument for "
2523 "'%c' option\n"), optopt);
2524 usage(B_FALSE);
2525 break;
2526 case '?':
2527 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2528 optopt);
2529 usage(B_FALSE);
2530 }
2531 }
2532
2533 argc -= optind;
2534 argv += optind;
2535
2536 if (cachefile && nsearch != 0) {
2537 (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2538 usage(B_FALSE);
2539 }
2540
2541 if ((dryrun || xtreme_rewind) && !do_rewind) {
2542 (void) fprintf(stderr,
2543 gettext("-n or -X only meaningful with -F\n"));
2544 usage(B_FALSE);
2545 }
2546 if (dryrun)
2547 rewind_policy = ZPOOL_TRY_REWIND;
2548 else if (do_rewind)
2549 rewind_policy = ZPOOL_DO_REWIND;
2550 if (xtreme_rewind)
2551 rewind_policy |= ZPOOL_EXTREME_REWIND;
2552
2553 /* In the future, we can capture further policy and include it here */
2554 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
2555 nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
2556 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
2557 goto error;
2558
2559 /* check argument count */
2560 if (do_all) {
2561 if (argc != 0) {
2562 (void) fprintf(stderr, gettext("too many arguments\n"));
2563 usage(B_FALSE);
2564 }
2565 } else {
2566 if (argc > 2) {
2567 (void) fprintf(stderr, gettext("too many arguments\n"));
2568 usage(B_FALSE);
2569 }
2570 }
2571
2572 /*
2573 * Check for the effective uid. We do this explicitly here because
2574 * otherwise any attempt to discover pools will silently fail.
2575 */
2576 if (argc == 0 && geteuid() != 0) {
2577 (void) fprintf(stderr, gettext("cannot "
2578 "discover pools: permission denied\n"));
2579 if (searchdirs != NULL)
2580 free(searchdirs);
2581
2582 nvlist_free(props);
2583 nvlist_free(policy);
2584 return (1);
2585 }
2586
2587 /*
2588 * Depending on the arguments given, we do one of the following:
2589 *
2590 * <none> Iterate through all pools and display information about
2591 * each one.
2592 *
2593 * -a Iterate through all pools and try to import each one.
2594 *
2595 * <id> Find the pool that corresponds to the given GUID/pool
2596 * name and import that one.
2597 *
2598 * -D Above options applies only to destroyed pools.
2599 */
2600 if (argc != 0) {
2601 char *endptr;
2602
2603 errno = 0;
2604 searchguid = strtoull(argv[0], &endptr, 10);
2605 if (errno != 0 || *endptr != '\0') {
2606 searchname = argv[0];
2607 searchguid = 0;
2608 }
2609 found_config = NULL;
2610
2611 /*
2612 * User specified a name or guid. Ensure it's unique.
2613 */
2614 idata.unique = B_TRUE;
2615 }
2616
2617 /*
2618 * Check the environment for the preferred search path.
2619 */
2620 if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) {
2621 char *dir;
2622
2623 envdup = strdup(env);
2624
2625 dir = strtok(envdup, ":");
2626 while (dir != NULL) {
2627 if (searchdirs == NULL) {
2628 searchdirs = safe_malloc(sizeof (char *));
2629 } else {
2630 char **tmp = safe_malloc((nsearch + 1) *
2631 sizeof (char *));
2632 bcopy(searchdirs, tmp, nsearch *
2633 sizeof (char *));
2634 free(searchdirs);
2635 searchdirs = tmp;
2636 }
2637 searchdirs[nsearch++] = dir;
2638 dir = strtok(NULL, ":");
2639 }
2640 }
2641
2642 idata.path = searchdirs;
2643 idata.paths = nsearch;
2644 idata.poolname = searchname;
2645 idata.guid = searchguid;
2646 idata.cachefile = cachefile;
2647 idata.scan = do_scan;
2648
2649 /*
2650 * Under Linux the zpool_find_import_impl() function leverages the
2651 * taskq implementation to parallelize device scanning. It is
2652 * therefore necessary to initialize this functionality for the
2653 * duration of the zpool_search_import() function.
2654 */
2655 thread_init();
2656 pools = zpool_search_import(g_zfs, &idata);
2657 thread_fini();
2658
2659 if (pools != NULL && idata.exists &&
2660 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
2661 (void) fprintf(stderr, gettext("cannot import '%s': "
2662 "a pool with that name already exists\n"),
2663 argv[0]);
2664 (void) fprintf(stderr, gettext("use the form '%s "
2665 "<pool | id> <newpool>' to give it a new name\n"),
2666 "zpool import");
2667 err = 1;
2668 } else if (pools == NULL && idata.exists) {
2669 (void) fprintf(stderr, gettext("cannot import '%s': "
2670 "a pool with that name is already created/imported,\n"),
2671 argv[0]);
2672 (void) fprintf(stderr, gettext("and no additional pools "
2673 "with that name were found\n"));
2674 err = 1;
2675 } else if (pools == NULL) {
2676 if (argc != 0) {
2677 (void) fprintf(stderr, gettext("cannot import '%s': "
2678 "no such pool available\n"), argv[0]);
2679 }
2680 err = 1;
2681 }
2682
2683 if (err == 1) {
2684 if (searchdirs != NULL)
2685 free(searchdirs);
2686 if (envdup != NULL)
2687 free(envdup);
2688 nvlist_free(policy);
2689 nvlist_free(pools);
2690 nvlist_free(props);
2691 return (1);
2692 }
2693
2694 /*
2695 * At this point we have a list of import candidate configs. Even if
2696 * we were searching by pool name or guid, we still need to
2697 * post-process the list to deal with pool state and possible
2698 * duplicate names.
2699 */
2700 err = 0;
2701 elem = NULL;
2702 first = B_TRUE;
2703 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2704
2705 verify(nvpair_value_nvlist(elem, &config) == 0);
2706
2707 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
2708 &pool_state) == 0);
2709 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
2710 continue;
2711 if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
2712 continue;
2713
2714 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
2715 policy) == 0);
2716
2717 if (argc == 0) {
2718 if (first)
2719 first = B_FALSE;
2720 else if (!do_all)
2721 (void) printf("\n");
2722
2723 if (do_all) {
2724 err |= do_import(config, NULL, mntopts,
2725 props, flags);
2726 } else {
2727 show_import(config);
2728 }
2729 } else if (searchname != NULL) {
2730 char *name;
2731
2732 /*
2733 * We are searching for a pool based on name.
2734 */
2735 verify(nvlist_lookup_string(config,
2736 ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2737
2738 if (strcmp(name, searchname) == 0) {
2739 if (found_config != NULL) {
2740 (void) fprintf(stderr, gettext(
2741 "cannot import '%s': more than "
2742 "one matching pool\n"), searchname);
2743 (void) fprintf(stderr, gettext(
2744 "import by numeric ID instead\n"));
2745 err = B_TRUE;
2746 }
2747 found_config = config;
2748 }
2749 } else {
2750 uint64_t guid;
2751
2752 /*
2753 * Search for a pool by guid.
2754 */
2755 verify(nvlist_lookup_uint64(config,
2756 ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2757
2758 if (guid == searchguid)
2759 found_config = config;
2760 }
2761 }
2762
2763 /*
2764 * If we were searching for a specific pool, verify that we found a
2765 * pool, and then do the import.
2766 */
2767 if (argc != 0 && err == 0) {
2768 if (found_config == NULL) {
2769 (void) fprintf(stderr, gettext("cannot import '%s': "
2770 "no such pool available\n"), argv[0]);
2771 err = B_TRUE;
2772 } else {
2773 err |= do_import(found_config, argc == 1 ? NULL :
2774 argv[1], mntopts, props, flags);
2775 }
2776 }
2777
2778 /*
2779 * If we were just looking for pools, report an error if none were
2780 * found.
2781 */
2782 if (argc == 0 && first)
2783 (void) fprintf(stderr,
2784 gettext("no pools available to import\n"));
2785
2786 error:
2787 nvlist_free(props);
2788 nvlist_free(pools);
2789 nvlist_free(policy);
2790 if (searchdirs != NULL)
2791 free(searchdirs);
2792 if (envdup != NULL)
2793 free(envdup);
2794
2795 return (err ? 1 : 0);
2796 }
2797
2798 /*
2799 * zpool sync [-f] [pool] ...
2800 *
2801 * -f (undocumented) force uberblock (and config including zpool cache file)
2802 * update.
2803 *
2804 * Sync the specified pool(s).
2805 * Without arguments "zpool sync" will sync all pools.
2806 * This command initiates TXG sync(s) and will return after the TXG(s) commit.
2807 *
2808 */
2809 static int
2810 zpool_do_sync(int argc, char **argv)
2811 {
2812 int ret;
2813 boolean_t force = B_FALSE;
2814
2815 /* check options */
2816 while ((ret = getopt(argc, argv, "f")) != -1) {
2817 switch (ret) {
2818 case 'f':
2819 force = B_TRUE;
2820 break;
2821 case '?':
2822 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
2823 optopt);
2824 usage(B_FALSE);
2825 }
2826 }
2827
2828 argc -= optind;
2829 argv += optind;
2830
2831 /* if argc == 0 we will execute zpool_sync_one on all pools */
2832 ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
2833
2834 return (ret);
2835 }
2836
2837 typedef struct iostat_cbdata {
2838 uint64_t cb_flags;
2839 int cb_name_flags;
2840 int cb_namewidth;
2841 int cb_iteration;
2842 char **cb_vdev_names; /* Only show these vdevs */
2843 unsigned int cb_vdev_names_count;
2844 boolean_t cb_verbose;
2845 boolean_t cb_literal;
2846 boolean_t cb_scripted;
2847 zpool_list_t *cb_list;
2848 vdev_cmd_data_list_t *vcdl;
2849 } iostat_cbdata_t;
2850
2851 /* iostat labels */
2852 typedef struct name_and_columns {
2853 const char *name; /* Column name */
2854 unsigned int columns; /* Center name to this number of columns */
2855 } name_and_columns_t;
2856
2857 #define IOSTAT_MAX_LABELS 11 /* Max number of labels on one line */
2858
2859 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] =
2860 {
2861 [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2},
2862 {NULL}},
2863 [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2},
2864 {"asyncq_wait", 2}, {"scrub"}},
2865 [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2},
2866 {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2},
2867 {NULL}},
2868 [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2},
2869 {"sync_queue", 2}, {"async_queue", 2}, {NULL}},
2870 [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2},
2871 {"async_read", 2}, {"async_write", 2}, {"scrub", 2}, {NULL}},
2872
2873 };
2874
2875 /* Shorthand - if "columns" field not set, default to 1 column */
2876 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] =
2877 {
2878 [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"},
2879 {"write"}, {NULL}},
2880 [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
2881 {"write"}, {"read"}, {"write"}, {"wait"}, {NULL}},
2882 [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"},
2883 {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, {NULL}},
2884 [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"},
2885 {"write"}, {"read"}, {"write"}, {"scrub"}, {NULL}},
2886 [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"},
2887 {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}},
2888 };
2889
2890 static const char *histo_to_title[] = {
2891 [IOS_L_HISTO] = "latency",
2892 [IOS_RQ_HISTO] = "req_size",
2893 };
2894
2895 /*
2896 * Return the number of labels in a null-terminated name_and_columns_t
2897 * array.
2898 *
2899 */
2900 static unsigned int
2901 label_array_len(const name_and_columns_t *labels)
2902 {
2903 int i = 0;
2904
2905 while (labels[i].name)
2906 i++;
2907
2908 return (i);
2909 }
2910
2911 /*
2912 * Return the number of strings in a null-terminated string array.
2913 * For example:
2914 *
2915 * const char foo[] = {"bar", "baz", NULL}
2916 *
2917 * returns 2
2918 */
2919 static uint64_t
2920 str_array_len(const char *array[])
2921 {
2922 uint64_t i = 0;
2923 while (array[i])
2924 i++;
2925
2926 return (i);
2927 }
2928
2929
2930 /*
2931 * Return a default column width for default/latency/queue columns. This does
2932 * not include histograms, which have their columns autosized.
2933 */
2934 static unsigned int
2935 default_column_width(iostat_cbdata_t *cb, enum iostat_type type)
2936 {
2937 unsigned long column_width = 5; /* Normal niceprint */
2938 static unsigned long widths[] = {
2939 /*
2940 * Choose some sane default column sizes for printing the
2941 * raw numbers.
2942 */
2943 [IOS_DEFAULT] = 15, /* 1PB capacity */
2944 [IOS_LATENCY] = 10, /* 1B ns = 10sec */
2945 [IOS_QUEUES] = 6, /* 1M queue entries */
2946 };
2947
2948 if (cb->cb_literal)
2949 column_width = widths[type];
2950
2951 return (column_width);
2952 }
2953
2954 /*
2955 * Print the column labels, i.e:
2956 *
2957 * capacity operations bandwidth
2958 * alloc free read write read write ...
2959 *
2960 * If force_column_width is set, use it for the column width. If not set, use
2961 * the default column width.
2962 */
2963 void
2964 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width,
2965 const name_and_columns_t labels[][IOSTAT_MAX_LABELS])
2966 {
2967 int i, idx, s;
2968 unsigned int text_start, rw_column_width, spaces_to_end;
2969 uint64_t flags = cb->cb_flags;
2970 uint64_t f;
2971 unsigned int column_width = force_column_width;
2972
2973 /* For each bit set in flags */
2974 for (f = flags; f; f &= ~(1ULL << idx)) {
2975 idx = lowbit64(f) - 1;
2976 if (!force_column_width)
2977 column_width = default_column_width(cb, idx);
2978 /* Print our top labels centered over "read write" label. */
2979 for (i = 0; i < label_array_len(labels[idx]); i++) {
2980 const char *name = labels[idx][i].name;
2981 /*
2982 * We treat labels[][].columns == 0 as shorthand
2983 * for one column. It makes writing out the label
2984 * tables more concise.
2985 */
2986 unsigned int columns = MAX(1, labels[idx][i].columns);
2987 unsigned int slen = strlen(name);
2988
2989 rw_column_width = (column_width * columns) +
2990 (2 * (columns - 1));
2991
2992 text_start = (int)((rw_column_width)/columns -
2993 slen/columns);
2994
2995 printf(" "); /* Two spaces between columns */
2996
2997 /* Space from beginning of column to label */
2998 for (s = 0; s < text_start; s++)
2999 printf(" ");
3000
3001 printf("%s", name);
3002
3003 /* Print space after label to end of column */
3004 spaces_to_end = rw_column_width - text_start - slen;
3005 for (s = 0; s < spaces_to_end; s++)
3006 printf(" ");
3007
3008 }
3009 }
3010 }
3011
3012
3013 /*
3014 * print_cmd_columns - Print custom column titles from -c
3015 *
3016 * If the user specified the "zpool status|iostat -c" then print their custom
3017 * column titles in the header. For example, print_cmd_columns() would print
3018 * the " col1 col2" part of this:
3019 *
3020 * $ zpool iostat -vc 'echo col1=val1; echo col2=val2'
3021 * ...
3022 * capacity operations bandwidth
3023 * pool alloc free read write read write col1 col2
3024 * ---------- ----- ----- ----- ----- ----- ----- ---- ----
3025 * mypool 269K 1008M 0 0 107 946
3026 * mirror 269K 1008M 0 0 107 946
3027 * sdb - - 0 0 102 473 val1 val2
3028 * sdc - - 0 0 5 473 val1 val2
3029 * ---------- ----- ----- ----- ----- ----- ----- ---- ----
3030 */
3031 void
3032 print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes)
3033 {
3034 int i, j;
3035 vdev_cmd_data_t *data = &vcdl->data[0];
3036
3037 if (vcdl->count == 0 || data == NULL)
3038 return;
3039
3040 /*
3041 * Each vdev cmd should have the same column names unless the user did
3042 * something weird with their cmd. Just take the column names from the
3043 * first vdev and assume it works for all of them.
3044 */
3045 for (i = 0; i < vcdl->uniq_cols_cnt; i++) {
3046 printf(" ");
3047 if (use_dashes) {
3048 for (j = 0; j < vcdl->uniq_cols_width[i]; j++)
3049 printf("-");
3050 } else {
3051 printf("%*s", vcdl->uniq_cols_width[i],
3052 vcdl->uniq_cols[i]);
3053 }
3054 }
3055 }
3056
3057
3058 /*
3059 * Utility function to print out a line of dashes like:
3060 *
3061 * -------------------------------- ----- ----- ----- ----- -----
3062 *
3063 * ...or a dashed named-row line like:
3064 *
3065 * logs - - - - -
3066 *
3067 * @cb: iostat data
3068 *
3069 * @force_column_width If non-zero, use the value as the column width.
3070 * Otherwise use the default column widths.
3071 *
3072 * @name: Print a dashed named-row line starting
3073 * with @name. Otherwise, print a regular
3074 * dashed line.
3075 */
3076 static void
3077 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width,
3078 const char *name)
3079 {
3080 int i;
3081 unsigned int namewidth;
3082 uint64_t flags = cb->cb_flags;
3083 uint64_t f;
3084 int idx;
3085 const name_and_columns_t *labels;
3086 const char *title;
3087
3088
3089 if (cb->cb_flags & IOS_ANYHISTO_M) {
3090 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3091 } else if (cb->cb_vdev_names_count) {
3092 title = "vdev";
3093 } else {
3094 title = "pool";
3095 }
3096
3097 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3098 name ? strlen(name) : 0);
3099
3100
3101 if (name) {
3102 printf("%-*s", namewidth, name);
3103 } else {
3104 for (i = 0; i < namewidth; i++)
3105 (void) printf("-");
3106 }
3107
3108 /* For each bit in flags */
3109 for (f = flags; f; f &= ~(1ULL << idx)) {
3110 unsigned int column_width;
3111 idx = lowbit64(f) - 1;
3112 if (force_column_width)
3113 column_width = force_column_width;
3114 else
3115 column_width = default_column_width(cb, idx);
3116
3117 labels = iostat_bottom_labels[idx];
3118 for (i = 0; i < label_array_len(labels); i++) {
3119 if (name)
3120 printf(" %*s-", column_width - 1, " ");
3121 else
3122 printf(" %.*s", column_width,
3123 "--------------------");
3124 }
3125 }
3126 }
3127
3128
3129 static void
3130 print_iostat_separator_impl(iostat_cbdata_t *cb,
3131 unsigned int force_column_width)
3132 {
3133 print_iostat_dashes(cb, force_column_width, NULL);
3134 }
3135
3136 static void
3137 print_iostat_separator(iostat_cbdata_t *cb)
3138 {
3139 print_iostat_separator_impl(cb, 0);
3140 }
3141
3142 static void
3143 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width,
3144 const char *histo_vdev_name)
3145 {
3146 unsigned int namewidth;
3147 const char *title;
3148
3149 if (cb->cb_flags & IOS_ANYHISTO_M) {
3150 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)];
3151 } else if (cb->cb_vdev_names_count) {
3152 title = "vdev";
3153 } else {
3154 title = "pool";
3155 }
3156
3157 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth),
3158 histo_vdev_name ? strlen(histo_vdev_name) : 0);
3159
3160 if (histo_vdev_name)
3161 printf("%-*s", namewidth, histo_vdev_name);
3162 else
3163 printf("%*s", namewidth, "");
3164
3165
3166 print_iostat_labels(cb, force_column_width, iostat_top_labels);
3167 printf("\n");
3168
3169 printf("%-*s", namewidth, title);
3170
3171 print_iostat_labels(cb, force_column_width, iostat_bottom_labels);
3172 if (cb->vcdl != NULL)
3173 print_cmd_columns(cb->vcdl, 0);
3174
3175 printf("\n");
3176
3177 print_iostat_separator_impl(cb, force_column_width);
3178
3179 if (cb->vcdl != NULL)
3180 print_cmd_columns(cb->vcdl, 1);
3181
3182 printf("\n");
3183 }
3184
3185 static void
3186 print_iostat_header(iostat_cbdata_t *cb)
3187 {
3188 print_iostat_header_impl(cb, 0, NULL);
3189 }
3190
3191
3192 /*
3193 * Display a single statistic.
3194 */
3195 static void
3196 print_one_stat(uint64_t value, enum zfs_nicenum_format format,
3197 unsigned int column_size, boolean_t scripted)
3198 {
3199 char buf[64];
3200
3201 zfs_nicenum_format(value, buf, sizeof (buf), format);
3202
3203 if (scripted)
3204 printf("\t%s", buf);
3205 else
3206 printf(" %*s", column_size, buf);
3207 }
3208
3209 /*
3210 * Calculate the default vdev stats
3211 *
3212 * Subtract oldvs from newvs, apply a scaling factor, and save the resulting
3213 * stats into calcvs.
3214 */
3215 static void
3216 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs,
3217 vdev_stat_t *calcvs)
3218 {
3219 int i;
3220
3221 memcpy(calcvs, newvs, sizeof (*calcvs));
3222 for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++)
3223 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]);
3224
3225 for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++)
3226 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]);
3227 }
3228
3229 /*
3230 * Internal representation of the extended iostats data.
3231 *
3232 * The extended iostat stats are exported in nvlists as either uint64_t arrays
3233 * or single uint64_t's. We make both look like arrays to make them easier
3234 * to process. In order to make single uint64_t's look like arrays, we set
3235 * __data to the stat data, and then set *data = &__data with count = 1. Then,
3236 * we can just use *data and count.
3237 */
3238 struct stat_array {
3239 uint64_t *data;
3240 uint_t count; /* Number of entries in data[] */
3241 uint64_t __data; /* Only used when data is a single uint64_t */
3242 };
3243
3244 static uint64_t
3245 stat_histo_max(struct stat_array *nva, unsigned int len)
3246 {
3247 uint64_t max = 0;
3248 int i;
3249 for (i = 0; i < len; i++)
3250 max = MAX(max, array64_max(nva[i].data, nva[i].count));
3251
3252 return (max);
3253 }
3254
3255 /*
3256 * Helper function to lookup a uint64_t array or uint64_t value and store its
3257 * data as a stat_array. If the nvpair is a single uint64_t value, then we make
3258 * it look like a one element array to make it easier to process.
3259 */
3260 static int
3261 nvpair64_to_stat_array(nvlist_t *nvl, const char *name,
3262 struct stat_array *nva)
3263 {
3264 nvpair_t *tmp;
3265 int ret;
3266
3267 verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0);
3268 switch (nvpair_type(tmp)) {
3269 case DATA_TYPE_UINT64_ARRAY:
3270 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count);
3271 break;
3272 case DATA_TYPE_UINT64:
3273 ret = nvpair_value_uint64(tmp, &nva->__data);
3274 nva->data = &nva->__data;
3275 nva->count = 1;
3276 break;
3277 default:
3278 /* Not a uint64_t */
3279 ret = EINVAL;
3280 break;
3281 }
3282
3283 return (ret);
3284 }
3285
3286 /*
3287 * Given a list of nvlist names, look up the extended stats in newnv and oldnv,
3288 * subtract them, and return the results in a newly allocated stat_array.
3289 * You must free the returned array after you are done with it with
3290 * free_calc_stats().
3291 *
3292 * Additionally, you can set "oldnv" to NULL if you simply want the newnv
3293 * values.
3294 */
3295 static struct stat_array *
3296 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv,
3297 nvlist_t *newnv)
3298 {
3299 nvlist_t *oldnvx = NULL, *newnvx;
3300 struct stat_array *oldnva, *newnva, *calcnva;
3301 int i, j;
3302 unsigned int alloc_size = (sizeof (struct stat_array)) * len;
3303
3304 /* Extract our extended stats nvlist from the main list */
3305 verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3306 &newnvx) == 0);
3307 if (oldnv) {
3308 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX,
3309 &oldnvx) == 0);
3310 }
3311
3312 newnva = safe_malloc(alloc_size);
3313 oldnva = safe_malloc(alloc_size);
3314 calcnva = safe_malloc(alloc_size);
3315
3316 for (j = 0; j < len; j++) {
3317 verify(nvpair64_to_stat_array(newnvx, names[j],
3318 &newnva[j]) == 0);
3319 calcnva[j].count = newnva[j].count;
3320 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]);
3321 calcnva[j].data = safe_malloc(alloc_size);
3322 memcpy(calcnva[j].data, newnva[j].data, alloc_size);
3323
3324 if (oldnvx) {
3325 verify(nvpair64_to_stat_array(oldnvx, names[j],
3326 &oldnva[j]) == 0);
3327 for (i = 0; i < oldnva[j].count; i++)
3328 calcnva[j].data[i] -= oldnva[j].data[i];
3329 }
3330 }
3331 free(newnva);
3332 free(oldnva);
3333 return (calcnva);
3334 }
3335
3336 static void
3337 free_calc_stats(struct stat_array *nva, unsigned int len)
3338 {
3339 int i;
3340 for (i = 0; i < len; i++)
3341 free(nva[i].data);
3342
3343 free(nva);
3344 }
3345
3346 static void
3347 print_iostat_histo(struct stat_array *nva, unsigned int len,
3348 iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth,
3349 double scale)
3350 {
3351 int i, j;
3352 char buf[6];
3353 uint64_t val;
3354 enum zfs_nicenum_format format;
3355 unsigned int buckets;
3356 unsigned int start_bucket;
3357
3358 if (cb->cb_literal)
3359 format = ZFS_NICENUM_RAW;
3360 else
3361 format = ZFS_NICENUM_1024;
3362
3363 /* All these histos are the same size, so just use nva[0].count */
3364 buckets = nva[0].count;
3365
3366 if (cb->cb_flags & IOS_RQ_HISTO_M) {
3367 /* Start at 512 - req size should never be lower than this */
3368 start_bucket = 9;
3369 } else {
3370 start_bucket = 0;
3371 }
3372
3373 for (j = start_bucket; j < buckets; j++) {
3374 /* Print histogram bucket label */
3375 if (cb->cb_flags & IOS_L_HISTO_M) {
3376 /* Ending range of this bucket */
3377 val = (1UL << (j + 1)) - 1;
3378 zfs_nicetime(val, buf, sizeof (buf));
3379 } else {
3380 /* Request size (starting range of bucket) */
3381 val = (1UL << j);
3382 zfs_nicenum(val, buf, sizeof (buf));
3383 }
3384
3385 if (cb->cb_scripted)
3386 printf("%llu", (u_longlong_t)val);
3387 else
3388 printf("%-*s", namewidth, buf);
3389
3390 /* Print the values on the line */
3391 for (i = 0; i < len; i++) {
3392 print_one_stat(nva[i].data[j] * scale, format,
3393 column_width, cb->cb_scripted);
3394 }
3395 printf("\n");
3396 }
3397 }
3398
3399 static void
3400 print_solid_separator(unsigned int length)
3401 {
3402 while (length--)
3403 printf("-");
3404 printf("\n");
3405 }
3406
3407 static void
3408 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv,
3409 nvlist_t *newnv, double scale, const char *name)
3410 {
3411 unsigned int column_width;
3412 unsigned int namewidth;
3413 unsigned int entire_width;
3414 enum iostat_type type;
3415 struct stat_array *nva;
3416 const char **names;
3417 unsigned int names_len;
3418
3419 /* What type of histo are we? */
3420 type = IOS_HISTO_IDX(cb->cb_flags);
3421
3422 /* Get NULL-terminated array of nvlist names for our histo */
3423 names = vsx_type_to_nvlist[type];
3424 names_len = str_array_len(names); /* num of names */
3425
3426 nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv);
3427
3428 if (cb->cb_literal) {
3429 column_width = MAX(5,
3430 (unsigned int) log10(stat_histo_max(nva, names_len)) + 1);
3431 } else {
3432 column_width = 5;
3433 }
3434
3435 namewidth = MAX(cb->cb_namewidth,
3436 strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]));
3437
3438 /*
3439 * Calculate the entire line width of what we're printing. The
3440 * +2 is for the two spaces between columns:
3441 */
3442 /* read write */
3443 /* ----- ----- */
3444 /* |___| <---------- column_width */
3445 /* */
3446 /* |__________| <--- entire_width */
3447 /* */
3448 entire_width = namewidth + (column_width + 2) *
3449 label_array_len(iostat_bottom_labels[type]);
3450
3451 if (cb->cb_scripted)
3452 printf("%s\n", name);
3453 else
3454 print_iostat_header_impl(cb, column_width, name);
3455
3456 print_iostat_histo(nva, names_len, cb, column_width,
3457 namewidth, scale);
3458
3459 free_calc_stats(nva, names_len);
3460 if (!cb->cb_scripted)
3461 print_solid_separator(entire_width);
3462 }
3463
3464 /*
3465 * Calculate the average latency of a power-of-two latency histogram
3466 */
3467 static uint64_t
3468 single_histo_average(uint64_t *histo, unsigned int buckets)
3469 {
3470 int i;
3471 uint64_t count = 0, total = 0;
3472
3473 for (i = 0; i < buckets; i++) {
3474 /*
3475 * Our buckets are power-of-two latency ranges. Use the
3476 * midpoint latency of each bucket to calculate the average.
3477 * For example:
3478 *
3479 * Bucket Midpoint
3480 * 8ns-15ns: 12ns
3481 * 16ns-31ns: 24ns
3482 * ...
3483 */
3484 if (histo[i] != 0) {
3485 total += histo[i] * (((1UL << i) + ((1UL << i)/2)));
3486 count += histo[i];
3487 }
3488 }
3489
3490 /* Prevent divide by zero */
3491 return (count == 0 ? 0 : total / count);
3492 }
3493
3494 static void
3495 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv,
3496 nvlist_t *newnv, double scale)
3497 {
3498 int i;
3499 uint64_t val;
3500 const char *names[] = {
3501 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE,
3502 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE,
3503 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE,
3504 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE,
3505 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE,
3506 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE,
3507 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE,
3508 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE,
3509 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE,
3510 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE,
3511 };
3512
3513 struct stat_array *nva;
3514
3515 unsigned int column_width = default_column_width(cb, IOS_QUEUES);
3516 enum zfs_nicenum_format format;
3517
3518 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv);
3519
3520 if (cb->cb_literal)
3521 format = ZFS_NICENUM_RAW;
3522 else
3523 format = ZFS_NICENUM_1024;
3524
3525 for (i = 0; i < ARRAY_SIZE(names); i++) {
3526 val = nva[i].data[0] * scale;
3527 print_one_stat(val, format, column_width, cb->cb_scripted);
3528 }
3529
3530 free_calc_stats(nva, ARRAY_SIZE(names));
3531 }
3532
3533 static void
3534 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv,
3535 nvlist_t *newnv, double scale)
3536 {
3537 int i;
3538 uint64_t val;
3539 const char *names[] = {
3540 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO,
3541 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO,
3542 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO,
3543 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO,
3544 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO,
3545 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO,
3546 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO,
3547 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO,
3548 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO,
3549 };
3550 struct stat_array *nva;
3551
3552 unsigned int column_width = default_column_width(cb, IOS_LATENCY);
3553 enum zfs_nicenum_format format;
3554
3555 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv);
3556
3557 if (cb->cb_literal)
3558 format = ZFS_NICENUM_RAWTIME;
3559 else
3560 format = ZFS_NICENUM_TIME;
3561
3562 /* Print our avg latencies on the line */
3563 for (i = 0; i < ARRAY_SIZE(names); i++) {
3564 /* Compute average latency for a latency histo */
3565 val = single_histo_average(nva[i].data, nva[i].count) * scale;
3566 print_one_stat(val, format, column_width, cb->cb_scripted);
3567 }
3568 free_calc_stats(nva, ARRAY_SIZE(names));
3569 }
3570
3571 /*
3572 * Print default statistics (capacity/operations/bandwidth)
3573 */
3574 static void
3575 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale)
3576 {
3577 unsigned int column_width = default_column_width(cb, IOS_DEFAULT);
3578 enum zfs_nicenum_format format;
3579 char na; /* char to print for "not applicable" values */
3580
3581 if (cb->cb_literal) {
3582 format = ZFS_NICENUM_RAW;
3583 na = '0';
3584 } else {
3585 format = ZFS_NICENUM_1024;
3586 na = '-';
3587 }
3588
3589 /* only toplevel vdevs have capacity stats */
3590 if (vs->vs_space == 0) {
3591 if (cb->cb_scripted)
3592 printf("\t%c\t%c", na, na);
3593 else
3594 printf(" %*c %*c", column_width, na, column_width,
3595 na);
3596 } else {
3597 print_one_stat(vs->vs_alloc, format, column_width,
3598 cb->cb_scripted);
3599 print_one_stat(vs->vs_space - vs->vs_alloc, format,
3600 column_width, cb->cb_scripted);
3601 }
3602
3603 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale),
3604 format, column_width, cb->cb_scripted);
3605 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale),
3606 format, column_width, cb->cb_scripted);
3607 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale),
3608 format, column_width, cb->cb_scripted);
3609 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale),
3610 format, column_width, cb->cb_scripted);
3611 }
3612
3613 /*
3614 * Print out all the statistics for the given vdev. This can either be the
3615 * toplevel configuration, or called recursively. If 'name' is NULL, then this
3616 * is a verbose output, and we don't want to display the toplevel pool stats.
3617 *
3618 * Returns the number of stat lines printed.
3619 */
3620 unsigned int
3621 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
3622 nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
3623 {
3624 nvlist_t **oldchild, **newchild;
3625 uint_t c, children;
3626 vdev_stat_t *oldvs, *newvs, *calcvs;
3627 vdev_stat_t zerovs = { 0 };
3628 char *vname;
3629 int i;
3630 int ret = 0;
3631 uint64_t tdelta;
3632 double scale;
3633
3634 calcvs = safe_malloc(sizeof (*calcvs));
3635
3636 if (oldnv != NULL) {
3637 verify(nvlist_lookup_uint64_array(oldnv,
3638 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
3639 } else {
3640 oldvs = &zerovs;
3641 }
3642
3643 /* Do we only want to see a specific vdev? */
3644 for (i = 0; i < cb->cb_vdev_names_count; i++) {
3645 /* Yes we do. Is this the vdev? */
3646 if (strcmp(name, cb->cb_vdev_names[i]) == 0) {
3647 /*
3648 * This is our vdev. Since it is the only vdev we
3649 * will be displaying, make depth = 0 so that it
3650 * doesn't get indented.
3651 */
3652 depth = 0;
3653 break;
3654 }
3655 }
3656
3657 if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) {
3658 /* Couldn't match the name */
3659 goto children;
3660 }
3661
3662
3663 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
3664 (uint64_t **)&newvs, &c) == 0);
3665
3666 /*
3667 * Print the vdev name unless it's is a histogram. Histograms
3668 * display the vdev name in the header itself.
3669 */
3670 if (!(cb->cb_flags & IOS_ANYHISTO_M)) {
3671 if (cb->cb_scripted) {
3672 printf("%s", name);
3673 } else {
3674 if (strlen(name) + depth > cb->cb_namewidth)
3675 (void) printf("%*s%s", depth, "", name);
3676 else
3677 (void) printf("%*s%s%*s", depth, "", name,
3678 (int)(cb->cb_namewidth - strlen(name) -
3679 depth), "");
3680 }
3681 }
3682
3683 /* Calculate our scaling factor */
3684 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
3685 if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) {
3686 /*
3687 * If we specify printing histograms with no time interval, then
3688 * print the histogram numbers over the entire lifetime of the
3689 * vdev.
3690 */
3691 scale = 1;
3692 } else {
3693 if (tdelta == 0)
3694 scale = 1.0;
3695 else
3696 scale = (double)NANOSEC / tdelta;
3697 }
3698
3699 if (cb->cb_flags & IOS_DEFAULT_M) {
3700 calc_default_iostats(oldvs, newvs, calcvs);
3701 print_iostat_default(calcvs, cb, scale);
3702 }
3703 if (cb->cb_flags & IOS_LATENCY_M)
3704 print_iostat_latency(cb, oldnv, newnv, scale);
3705 if (cb->cb_flags & IOS_QUEUES_M)
3706 print_iostat_queues(cb, oldnv, newnv, scale);
3707 if (cb->cb_flags & IOS_ANYHISTO_M) {
3708 printf("\n");
3709 print_iostat_histos(cb, oldnv, newnv, scale, name);
3710 }
3711
3712 if (cb->vcdl != NULL) {
3713 char *path;
3714 if (nvlist_lookup_string(newnv, ZPOOL_CONFIG_PATH,
3715 &path) == 0) {
3716 printf(" ");
3717 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path);
3718 }
3719 }
3720
3721 if (!(cb->cb_flags & IOS_ANYHISTO_M))
3722 printf("\n");
3723
3724 ret++;
3725
3726 children:
3727
3728 free(calcvs);
3729
3730 if (!cb->cb_verbose)
3731 return (ret);
3732
3733 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
3734 &newchild, &children) != 0)
3735 return (ret);
3736
3737 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
3738 &oldchild, &c) != 0)
3739 return (ret);
3740
3741 for (c = 0; c < children; c++) {
3742 uint64_t ishole = B_FALSE, islog = B_FALSE;
3743
3744 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE,
3745 &ishole);
3746
3747 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG,
3748 &islog);
3749
3750 if (ishole || islog)
3751 continue;
3752
3753 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3754 cb->cb_name_flags);
3755 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
3756 newchild[c], cb, depth + 2);
3757 free(vname);
3758 }
3759
3760 /*
3761 * Log device section
3762 */
3763
3764 if (num_logs(newnv) > 0) {
3765 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
3766 !cb->cb_vdev_names) {
3767 print_iostat_dashes(cb, 0, "logs");
3768 }
3769 printf("\n");
3770
3771 for (c = 0; c < children; c++) {
3772 uint64_t islog = B_FALSE;
3773 (void) nvlist_lookup_uint64(newchild[c],
3774 ZPOOL_CONFIG_IS_LOG, &islog);
3775
3776 if (islog) {
3777 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3778 cb->cb_name_flags);
3779 ret += print_vdev_stats(zhp, vname, oldnv ?
3780 oldchild[c] : NULL, newchild[c],
3781 cb, depth + 2);
3782 free(vname);
3783 }
3784 }
3785
3786 }
3787
3788 /*
3789 * Include level 2 ARC devices in iostat output
3790 */
3791 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
3792 &newchild, &children) != 0)
3793 return (ret);
3794
3795 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
3796 &oldchild, &c) != 0)
3797 return (ret);
3798
3799 if (children > 0) {
3800 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted &&
3801 !cb->cb_vdev_names) {
3802 print_iostat_dashes(cb, 0, "cache");
3803 }
3804 printf("\n");
3805
3806 for (c = 0; c < children; c++) {
3807 vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
3808 cb->cb_name_flags);
3809 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c]
3810 : NULL, newchild[c], cb, depth + 2);
3811 free(vname);
3812 }
3813 }
3814
3815 return (ret);
3816 }
3817
3818 static int
3819 refresh_iostat(zpool_handle_t *zhp, void *data)
3820 {
3821 iostat_cbdata_t *cb = data;
3822 boolean_t missing;
3823
3824 /*
3825 * If the pool has disappeared, remove it from the list and continue.
3826 */
3827 if (zpool_refresh_stats(zhp, &missing) != 0)
3828 return (-1);
3829
3830 if (missing)
3831 pool_list_remove(cb->cb_list, zhp);
3832
3833 return (0);
3834 }
3835
3836 /*
3837 * Callback to print out the iostats for the given pool.
3838 */
3839 int
3840 print_iostat(zpool_handle_t *zhp, void *data)
3841 {
3842 iostat_cbdata_t *cb = data;
3843 nvlist_t *oldconfig, *newconfig;
3844 nvlist_t *oldnvroot, *newnvroot;
3845 int ret;
3846
3847 newconfig = zpool_get_config(zhp, &oldconfig);
3848
3849 if (cb->cb_iteration == 1)
3850 oldconfig = NULL;
3851
3852 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
3853 &newnvroot) == 0);
3854
3855 if (oldconfig == NULL)
3856 oldnvroot = NULL;
3857 else
3858 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
3859 &oldnvroot) == 0);
3860
3861 ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot,
3862 cb, 0);
3863 if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) &&
3864 !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) {
3865 print_iostat_separator(cb);
3866 if (cb->vcdl != NULL) {
3867 print_cmd_columns(cb->vcdl, 1);
3868 }
3869 printf("\n");
3870 }
3871
3872 return (ret);
3873 }
3874
3875 static int
3876 get_columns(void)
3877 {
3878 struct winsize ws;
3879 int columns = 80;
3880 int error;
3881
3882 if (isatty(STDOUT_FILENO)) {
3883 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
3884 if (error == 0)
3885 columns = ws.ws_col;
3886 } else {
3887 columns = 999;
3888 }
3889
3890 return (columns);
3891 }
3892
3893 int
3894 get_namewidth(zpool_handle_t *zhp, void *data)
3895 {
3896 iostat_cbdata_t *cb = data;
3897 nvlist_t *config, *nvroot;
3898 int columns;
3899
3900 if ((config = zpool_get_config(zhp, NULL)) != NULL) {
3901 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3902 &nvroot) == 0);
3903 unsigned int poolname_len = strlen(zpool_get_name(zhp));
3904 if (!cb->cb_verbose)
3905 cb->cb_namewidth = MAX(poolname_len, cb->cb_namewidth);
3906 else
3907 cb->cb_namewidth = MAX(poolname_len,
3908 max_width(zhp, nvroot, 0, cb->cb_namewidth,
3909 cb->cb_name_flags));
3910 }
3911 /*
3912 * The width must be at least 10, but may be as large as the
3913 * column width - 42 so that we can still fit in one line.
3914 */
3915 columns = get_columns();
3916
3917 if (cb->cb_namewidth < 10)
3918 cb->cb_namewidth = 10;
3919 if (cb->cb_namewidth > columns - 42)
3920 cb->cb_namewidth = columns - 42;
3921
3922 return (0);
3923 }
3924
3925 /*
3926 * Parse the input string, get the 'interval' and 'count' value if there is one.
3927 */
3928 static void
3929 get_interval_count(int *argcp, char **argv, float *iv,
3930 unsigned long *cnt)
3931 {
3932 float interval = 0;
3933 unsigned long count = 0;
3934 int argc = *argcp;
3935
3936 /*
3937 * Determine if the last argument is an integer or a pool name
3938 */
3939 if (argc > 0 && isnumber(argv[argc - 1])) {
3940 char *end;
3941
3942 errno = 0;
3943 interval = strtof(argv[argc - 1], &end);
3944
3945 if (*end == '\0' && errno == 0) {
3946 if (interval == 0) {
3947 (void) fprintf(stderr, gettext("interval "
3948 "cannot be zero\n"));
3949 usage(B_FALSE);
3950 }
3951 /*
3952 * Ignore the last parameter
3953 */
3954 argc--;
3955 } else {
3956 /*
3957 * If this is not a valid number, just plow on. The
3958 * user will get a more informative error message later
3959 * on.
3960 */
3961 interval = 0;
3962 }
3963 }
3964
3965 /*
3966 * If the last argument is also an integer, then we have both a count
3967 * and an interval.
3968 */
3969 if (argc > 0 && isnumber(argv[argc - 1])) {
3970 char *end;
3971
3972 errno = 0;
3973 count = interval;
3974 interval = strtof(argv[argc - 1], &end);
3975
3976 if (*end == '\0' && errno == 0) {
3977 if (interval == 0) {
3978 (void) fprintf(stderr, gettext("interval "
3979 "cannot be zero\n"));
3980 usage(B_FALSE);
3981 }
3982
3983 /*
3984 * Ignore the last parameter
3985 */
3986 argc--;
3987 } else {
3988 interval = 0;
3989 }
3990 }
3991
3992 *iv = interval;
3993 *cnt = count;
3994 *argcp = argc;
3995 }
3996
3997 static void
3998 get_timestamp_arg(char c)
3999 {
4000 if (c == 'u')
4001 timestamp_fmt = UDATE;
4002 else if (c == 'd')
4003 timestamp_fmt = DDATE;
4004 else
4005 usage(B_FALSE);
4006 }
4007
4008 /*
4009 * Return stat flags that are supported by all pools by both the module and
4010 * zpool iostat. "*data" should be initialized to all 0xFFs before running.
4011 * It will get ANDed down until only the flags that are supported on all pools
4012 * remain.
4013 */
4014 static int
4015 get_stat_flags_cb(zpool_handle_t *zhp, void *data)
4016 {
4017 uint64_t *mask = data;
4018 nvlist_t *config, *nvroot, *nvx;
4019 uint64_t flags = 0;
4020 int i, j;
4021
4022 config = zpool_get_config(zhp, NULL);
4023 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4024 &nvroot) == 0);
4025
4026 /* Default stats are always supported, but for completeness.. */
4027 if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS))
4028 flags |= IOS_DEFAULT_M;
4029
4030 /* Get our extended stats nvlist from the main list */
4031 if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX,
4032 &nvx) != 0) {
4033 /*
4034 * No extended stats; they're probably running an older
4035 * module. No big deal, we support that too.
4036 */
4037 goto end;
4038 }
4039
4040 /* For each extended stat, make sure all its nvpairs are supported */
4041 for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) {
4042 if (!vsx_type_to_nvlist[j][0])
4043 continue;
4044
4045 /* Start off by assuming the flag is supported, then check */
4046 flags |= (1ULL << j);
4047 for (i = 0; vsx_type_to_nvlist[j][i]; i++) {
4048 if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) {
4049 /* flag isn't supported */
4050 flags = flags & ~(1ULL << j);
4051 break;
4052 }
4053 }
4054 }
4055 end:
4056 *mask = *mask & flags;
4057 return (0);
4058 }
4059
4060 /*
4061 * Return a bitmask of stats that are supported on all pools by both the module
4062 * and zpool iostat.
4063 */
4064 static uint64_t
4065 get_stat_flags(zpool_list_t *list)
4066 {
4067 uint64_t mask = -1;
4068
4069 /*
4070 * get_stat_flags_cb() will lop off bits from "mask" until only the
4071 * flags that are supported on all pools remain.
4072 */
4073 pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask);
4074 return (mask);
4075 }
4076
4077 /*
4078 * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise.
4079 */
4080 static int
4081 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data)
4082 {
4083 iostat_cbdata_t *cb = cb_data;
4084 char *name = NULL;
4085 int ret = 0;
4086
4087 name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
4088
4089 if (strcmp(name, cb->cb_vdev_names[0]) == 0)
4090 ret = 1; /* match */
4091 free(name);
4092
4093 return (ret);
4094 }
4095
4096 /*
4097 * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise.
4098 */
4099 static int
4100 is_vdev(zpool_handle_t *zhp, void *cb_data)
4101 {
4102 return (for_each_vdev(zhp, is_vdev_cb, cb_data));
4103 }
4104
4105 /*
4106 * Check if vdevs are in a pool
4107 *
4108 * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise
4109 * return 0. If pool_name is NULL, then search all pools.
4110 */
4111 static int
4112 are_vdevs_in_pool(int argc, char **argv, char *pool_name,
4113 iostat_cbdata_t *cb)
4114 {
4115 char **tmp_name;
4116 int ret = 0;
4117 int i;
4118 int pool_count = 0;
4119
4120 if ((argc == 0) || !*argv)
4121 return (0);
4122
4123 if (pool_name)
4124 pool_count = 1;
4125
4126 /* Temporarily hijack cb_vdev_names for a second... */
4127 tmp_name = cb->cb_vdev_names;
4128
4129 /* Go though our list of prospective vdev names */
4130 for (i = 0; i < argc; i++) {
4131 cb->cb_vdev_names = argv + i;
4132
4133 /* Is this name a vdev in our pools? */
4134 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL,
4135 is_vdev, cb);
4136 if (!ret) {
4137 /* No match */
4138 break;
4139 }
4140 }
4141
4142 cb->cb_vdev_names = tmp_name;
4143
4144 return (ret);
4145 }
4146
4147 static int
4148 is_pool_cb(zpool_handle_t *zhp, void *data)
4149 {
4150 char *name = data;
4151 if (strcmp(name, zpool_get_name(zhp)) == 0)
4152 return (1);
4153
4154 return (0);
4155 }
4156
4157 /*
4158 * Do we have a pool named *name? If so, return 1, otherwise 0.
4159 */
4160 static int
4161 is_pool(char *name)
4162 {
4163 return (for_each_pool(0, NULL, B_TRUE, NULL, is_pool_cb, name));
4164 }
4165
4166 /* Are all our argv[] strings pool names? If so return 1, 0 otherwise. */
4167 static int
4168 are_all_pools(int argc, char **argv)
4169 {
4170 if ((argc == 0) || !*argv)
4171 return (0);
4172
4173 while (--argc >= 0)
4174 if (!is_pool(argv[argc]))
4175 return (0);
4176
4177 return (1);
4178 }
4179
4180 /*
4181 * Helper function to print out vdev/pool names we can't resolve. Used for an
4182 * error message.
4183 */
4184 static void
4185 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name,
4186 iostat_cbdata_t *cb)
4187 {
4188 int i;
4189 char *name;
4190 char *str;
4191 for (i = 0; i < argc; i++) {
4192 name = argv[i];
4193
4194 if (is_pool(name))
4195 str = gettext("pool");
4196 else if (are_vdevs_in_pool(1, &name, pool_name, cb))
4197 str = gettext("vdev in this pool");
4198 else if (are_vdevs_in_pool(1, &name, NULL, cb))
4199 str = gettext("vdev in another pool");
4200 else
4201 str = gettext("unknown");
4202
4203 fprintf(stderr, "\t%s (%s)\n", name, str);
4204 }
4205 }
4206
4207 /*
4208 * Same as get_interval_count(), but with additional checks to not misinterpret
4209 * guids as interval/count values. Assumes VDEV_NAME_GUID is set in
4210 * cb.cb_name_flags.
4211 */
4212 static void
4213 get_interval_count_filter_guids(int *argc, char **argv, float *interval,
4214 unsigned long *count, iostat_cbdata_t *cb)
4215 {
4216 char **tmpargv = argv;
4217 int argc_for_interval = 0;
4218
4219 /* Is the last arg an interval value? Or a guid? */
4220 if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) {
4221 /*
4222 * The last arg is not a guid, so it's probably an
4223 * interval value.
4224 */
4225 argc_for_interval++;
4226
4227 if (*argc >= 2 &&
4228 !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) {
4229 /*
4230 * The 2nd to last arg is not a guid, so it's probably
4231 * an interval value.
4232 */
4233 argc_for_interval++;
4234 }
4235 }
4236
4237 /* Point to our list of possible intervals */
4238 tmpargv = &argv[*argc - argc_for_interval];
4239
4240 *argc = *argc - argc_for_interval;
4241 get_interval_count(&argc_for_interval, tmpargv,
4242 interval, count);
4243 }
4244
4245 /*
4246 * Floating point sleep(). Allows you to pass in a floating point value for
4247 * seconds.
4248 */
4249 static void
4250 fsleep(float sec)
4251 {
4252 struct timespec req;
4253 req.tv_sec = floor(sec);
4254 req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC;
4255 nanosleep(&req, NULL);
4256 }
4257
4258 /*
4259 * Run one of the zpool status/iostat -c scripts with the help (-h) option and
4260 * print the result.
4261 *
4262 * name: Short name of the script ('iostat').
4263 * path: Full path to the script ('/usr/local/etc/zfs/zpool.d/iostat');
4264 */
4265 static void
4266 print_zpool_script_help(char *name, char *path)
4267 {
4268 char *argv[] = {path, "-h", NULL};
4269 char **lines = NULL;
4270 int lines_cnt = 0;
4271 int rc;
4272
4273 rc = libzfs_run_process_get_stdout_nopath(path, argv, NULL, &lines,
4274 &lines_cnt);
4275 if (rc != 0 || lines == NULL || lines_cnt <= 0) {
4276 if (lines != NULL)
4277 libzfs_free_str_array(lines, lines_cnt);
4278 return;
4279 }
4280
4281 for (int i = 0; i < lines_cnt; i++)
4282 if (!is_blank_str(lines[i]))
4283 printf(" %-14s %s\n", name, lines[i]);
4284
4285 libzfs_free_str_array(lines, lines_cnt);
4286 }
4287
4288 /*
4289 * Go though the zpool status/iostat -c scripts in the user's path, run their
4290 * help option (-h), and print out the results.
4291 */
4292 static void
4293 print_zpool_dir_scripts(char *dirpath)
4294 {
4295 DIR *dir;
4296 struct dirent *ent;
4297 char fullpath[MAXPATHLEN];
4298 struct stat dir_stat;
4299
4300 if ((dir = opendir(dirpath)) != NULL) {
4301 /* print all the files and directories within directory */
4302 while ((ent = readdir(dir)) != NULL) {
4303 sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
4304
4305 /* Print the scripts */
4306 if (stat(fullpath, &dir_stat) == 0)
4307 if (dir_stat.st_mode & S_IXUSR &&
4308 S_ISREG(dir_stat.st_mode))
4309 print_zpool_script_help(ent->d_name,
4310 fullpath);
4311 }
4312 closedir(dir);
4313 }
4314 }
4315
4316 /*
4317 * Print out help text for all zpool status/iostat -c scripts.
4318 */
4319 static void
4320 print_zpool_script_list(char *subcommand)
4321 {
4322 char *dir, *sp;
4323
4324 printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand);
4325
4326 sp = zpool_get_cmd_search_path();
4327 if (sp == NULL)
4328 return;
4329
4330 dir = strtok(sp, ":");
4331 while (dir != NULL) {
4332 print_zpool_dir_scripts(dir);
4333 dir = strtok(NULL, ":");
4334 }
4335
4336 free(sp);
4337 }
4338
4339 /*
4340 * zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name]
4341 * [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]]
4342 * [interval [count]]
4343 *
4344 * -c CMD For each vdev, run command CMD
4345 * -g Display guid for individual vdev name.
4346 * -L Follow links when resolving vdev path name.
4347 * -P Display full path for vdev name.
4348 * -v Display statistics for individual vdevs
4349 * -h Display help
4350 * -p Display values in parsable (exact) format.
4351 * -H Scripted mode. Don't display headers, and separate properties
4352 * by a single tab.
4353 * -l Display average latency
4354 * -q Display queue depths
4355 * -w Display latency histograms
4356 * -r Display request size histogram
4357 * -T Display a timestamp in date(1) or Unix format
4358 *
4359 * This command can be tricky because we want to be able to deal with pool
4360 * creation/destruction as well as vdev configuration changes. The bulk of this
4361 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
4362 * on pool_list_update() to detect the addition of new pools. Configuration
4363 * changes are all handled within libzfs.
4364 */
4365 int
4366 zpool_do_iostat(int argc, char **argv)
4367 {
4368 int c;
4369 int ret;
4370 int npools;
4371 float interval = 0;
4372 unsigned long count = 0;
4373 zpool_list_t *list;
4374 boolean_t verbose = B_FALSE;
4375 boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE;
4376 boolean_t queues = B_FALSE, parsable = B_FALSE, scripted = B_FALSE;
4377 boolean_t omit_since_boot = B_FALSE;
4378 boolean_t guid = B_FALSE;
4379 boolean_t follow_links = B_FALSE;
4380 boolean_t full_name = B_FALSE;
4381 iostat_cbdata_t cb = { 0 };
4382 char *cmd = NULL;
4383
4384 /* Used for printing error message */
4385 const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q',
4386 [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'};
4387
4388 uint64_t unsupported_flags;
4389
4390 /* check options */
4391 while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwH")) != -1) {
4392 switch (c) {
4393 case 'c':
4394 if (cmd != NULL) {
4395 fprintf(stderr,
4396 gettext("Can't set -c flag twice\n"));
4397 exit(1);
4398 }
4399
4400 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
4401 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
4402 fprintf(stderr, gettext(
4403 "Can't run -c, disabled by "
4404 "ZPOOL_SCRIPTS_ENABLED.\n"));
4405 exit(1);
4406 }
4407
4408 if ((getuid() <= 0 || geteuid() <= 0) &&
4409 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
4410 fprintf(stderr, gettext(
4411 "Can't run -c with root privileges "
4412 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
4413 exit(1);
4414 }
4415 cmd = optarg;
4416 verbose = B_TRUE;
4417 break;
4418 case 'g':
4419 guid = B_TRUE;
4420 break;
4421 case 'L':
4422 follow_links = B_TRUE;
4423 break;
4424 case 'P':
4425 full_name = B_TRUE;
4426 break;
4427 case 'T':
4428 get_timestamp_arg(*optarg);
4429 break;
4430 case 'v':
4431 verbose = B_TRUE;
4432 break;
4433 case 'p':
4434 parsable = B_TRUE;
4435 break;
4436 case 'l':
4437 latency = B_TRUE;
4438 break;
4439 case 'q':
4440 queues = B_TRUE;
4441 break;
4442 case 'H':
4443 scripted = B_TRUE;
4444 break;
4445 case 'w':
4446 l_histo = B_TRUE;
4447 break;
4448 case 'r':
4449 rq_histo = B_TRUE;
4450 break;
4451 case 'y':
4452 omit_since_boot = B_TRUE;
4453 break;
4454 case 'h':
4455 usage(B_FALSE);
4456 break;
4457 case '?':
4458 if (optopt == 'c') {
4459 print_zpool_script_list("iostat");
4460 exit(0);
4461 } else {
4462 fprintf(stderr,
4463 gettext("invalid option '%c'\n"), optopt);
4464 }
4465 usage(B_FALSE);
4466 }
4467 }
4468
4469 argc -= optind;
4470 argv += optind;
4471
4472 cb.cb_literal = parsable;
4473 cb.cb_scripted = scripted;
4474
4475 if (guid)
4476 cb.cb_name_flags |= VDEV_NAME_GUID;
4477 if (follow_links)
4478 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
4479 if (full_name)
4480 cb.cb_name_flags |= VDEV_NAME_PATH;
4481 cb.cb_iteration = 0;
4482 cb.cb_namewidth = 0;
4483 cb.cb_verbose = verbose;
4484
4485 /* Get our interval and count values (if any) */
4486 if (guid) {
4487 get_interval_count_filter_guids(&argc, argv, &interval,
4488 &count, &cb);
4489 } else {
4490 get_interval_count(&argc, argv, &interval, &count);
4491 }
4492
4493 if (argc == 0) {
4494 /* No args, so just print the defaults. */
4495 } else if (are_all_pools(argc, argv)) {
4496 /* All the args are pool names */
4497 } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) {
4498 /* All the args are vdevs */
4499 cb.cb_vdev_names = argv;
4500 cb.cb_vdev_names_count = argc;
4501 argc = 0; /* No pools to process */
4502 } else if (are_all_pools(1, argv)) {
4503 /* The first arg is a pool name */
4504 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) {
4505 /* ...and the rest are vdev names */
4506 cb.cb_vdev_names = argv + 1;
4507 cb.cb_vdev_names_count = argc - 1;
4508 argc = 1; /* One pool to process */
4509 } else {
4510 fprintf(stderr, gettext("Expected either a list of "));
4511 fprintf(stderr, gettext("pools, or list of vdevs in"));
4512 fprintf(stderr, " \"%s\", ", argv[0]);
4513 fprintf(stderr, gettext("but got:\n"));
4514 error_list_unresolved_vdevs(argc - 1, argv + 1,
4515 argv[0], &cb);
4516 fprintf(stderr, "\n");
4517 usage(B_FALSE);
4518 return (1);
4519 }
4520 } else {
4521 /*
4522 * The args don't make sense. The first arg isn't a pool name,
4523 * nor are all the args vdevs.
4524 */
4525 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n"));
4526 fprintf(stderr, "\n");
4527 return (1);
4528 }
4529
4530 if (cb.cb_vdev_names_count != 0) {
4531 /*
4532 * If user specified vdevs, it implies verbose.
4533 */
4534 cb.cb_verbose = B_TRUE;
4535 }
4536
4537 /*
4538 * Construct the list of all interesting pools.
4539 */
4540 ret = 0;
4541 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
4542 return (1);
4543
4544 if (pool_list_count(list) == 0 && argc != 0) {
4545 pool_list_free(list);
4546 return (1);
4547 }
4548
4549 if (pool_list_count(list) == 0 && interval == 0) {
4550 pool_list_free(list);
4551 (void) fprintf(stderr, gettext("no pools available\n"));
4552 return (1);
4553 }
4554
4555 if ((l_histo || rq_histo) && (cmd != NULL || latency || queues)) {
4556 pool_list_free(list);
4557 (void) fprintf(stderr,
4558 gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n"));
4559 usage(B_FALSE);
4560 return (1);
4561 }
4562
4563 if (l_histo && rq_histo) {
4564 pool_list_free(list);
4565 (void) fprintf(stderr,
4566 gettext("Only one of [-r|-w] can be passed at a time\n"));
4567 usage(B_FALSE);
4568 return (1);
4569 }
4570
4571 /*
4572 * Enter the main iostat loop.
4573 */
4574 cb.cb_list = list;
4575
4576 if (l_histo) {
4577 /*
4578 * Histograms tables look out of place when you try to display
4579 * them with the other stats, so make a rule that you can only
4580 * print histograms by themselves.
4581 */
4582 cb.cb_flags = IOS_L_HISTO_M;
4583 } else if (rq_histo) {
4584 cb.cb_flags = IOS_RQ_HISTO_M;
4585 } else {
4586 cb.cb_flags = IOS_DEFAULT_M;
4587 if (latency)
4588 cb.cb_flags |= IOS_LATENCY_M;
4589 if (queues)
4590 cb.cb_flags |= IOS_QUEUES_M;
4591 }
4592
4593 /*
4594 * See if the module supports all the stats we want to display.
4595 */
4596 unsupported_flags = cb.cb_flags & ~get_stat_flags(list);
4597 if (unsupported_flags) {
4598 uint64_t f;
4599 int idx;
4600 fprintf(stderr,
4601 gettext("The loaded zfs module doesn't support:"));
4602
4603 /* for each bit set in unsupported_flags */
4604 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) {
4605 idx = lowbit64(f) - 1;
4606 fprintf(stderr, " -%c", flag_to_arg[idx]);
4607 }
4608
4609 fprintf(stderr, ". Try running a newer module.\n");
4610 pool_list_free(list);
4611
4612 return (1);
4613 }
4614
4615 for (;;) {
4616 if ((npools = pool_list_count(list)) == 0)
4617 (void) fprintf(stderr, gettext("no pools available\n"));
4618 else {
4619 /*
4620 * If this is the first iteration and -y was supplied
4621 * we skip any printing.
4622 */
4623 boolean_t skip = (omit_since_boot &&
4624 cb.cb_iteration == 0);
4625
4626 /*
4627 * Refresh all statistics. This is done as an
4628 * explicit step before calculating the maximum name
4629 * width, so that any * configuration changes are
4630 * properly accounted for.
4631 */
4632 (void) pool_list_iter(list, B_FALSE, refresh_iostat,
4633 &cb);
4634
4635 /*
4636 * Iterate over all pools to determine the maximum width
4637 * for the pool / device name column across all pools.
4638 */
4639 cb.cb_namewidth = 0;
4640 (void) pool_list_iter(list, B_FALSE, get_namewidth,
4641 &cb);
4642
4643 if (timestamp_fmt != NODATE)
4644 print_timestamp(timestamp_fmt);
4645
4646 if (cmd != NULL && cb.cb_verbose &&
4647 !(cb.cb_flags & IOS_ANYHISTO_M)) {
4648 cb.vcdl = all_pools_for_each_vdev_run(argc,
4649 argv, cmd, g_zfs, cb.cb_vdev_names,
4650 cb.cb_vdev_names_count, cb.cb_name_flags);
4651 } else {
4652 cb.vcdl = NULL;
4653 }
4654
4655 /*
4656 * If it's the first time and we're not skipping it,
4657 * or either skip or verbose mode, print the header.
4658 *
4659 * The histogram code explicitly prints its header on
4660 * every vdev, so skip this for histograms.
4661 */
4662 if (((++cb.cb_iteration == 1 && !skip) ||
4663 (skip != verbose)) &&
4664 (!(cb.cb_flags & IOS_ANYHISTO_M)) &&
4665 !cb.cb_scripted)
4666 print_iostat_header(&cb);
4667
4668 if (skip) {
4669 (void) fsleep(interval);
4670 continue;
4671 }
4672
4673
4674 pool_list_iter(list, B_FALSE, print_iostat, &cb);
4675
4676 /*
4677 * If there's more than one pool, and we're not in
4678 * verbose mode (which prints a separator for us),
4679 * then print a separator.
4680 *
4681 * In addition, if we're printing specific vdevs then
4682 * we also want an ending separator.
4683 */
4684 if (((npools > 1 && !verbose &&
4685 !(cb.cb_flags & IOS_ANYHISTO_M)) ||
4686 (!(cb.cb_flags & IOS_ANYHISTO_M) &&
4687 cb.cb_vdev_names_count)) &&
4688 !cb.cb_scripted) {
4689 print_iostat_separator(&cb);
4690 if (cb.vcdl != NULL)
4691 print_cmd_columns(cb.vcdl, 1);
4692 printf("\n");
4693 }
4694
4695 if (cb.vcdl != NULL)
4696 free_vdev_cmd_data_list(cb.vcdl);
4697
4698 }
4699
4700 /*
4701 * Flush the output so that redirection to a file isn't buffered
4702 * indefinitely.
4703 */
4704 (void) fflush(stdout);
4705
4706 if (interval == 0)
4707 break;
4708
4709 if (count != 0 && --count == 0)
4710 break;
4711
4712 (void) fsleep(interval);
4713 }
4714
4715 pool_list_free(list);
4716
4717 return (ret);
4718 }
4719
4720 typedef struct list_cbdata {
4721 boolean_t cb_verbose;
4722 int cb_name_flags;
4723 int cb_namewidth;
4724 boolean_t cb_scripted;
4725 zprop_list_t *cb_proplist;
4726 boolean_t cb_literal;
4727 } list_cbdata_t;
4728
4729 /*
4730 * Given a list of columns to display, output appropriate headers for each one.
4731 */
4732 static void
4733 print_header(list_cbdata_t *cb)
4734 {
4735 zprop_list_t *pl = cb->cb_proplist;
4736 char headerbuf[ZPOOL_MAXPROPLEN];
4737 const char *header;
4738 boolean_t first = B_TRUE;
4739 boolean_t right_justify;
4740 size_t width = 0;
4741
4742 for (; pl != NULL; pl = pl->pl_next) {
4743 width = pl->pl_width;
4744 if (first && cb->cb_verbose) {
4745 /*
4746 * Reset the width to accommodate the verbose listing
4747 * of devices.
4748 */
4749 width = cb->cb_namewidth;
4750 }
4751
4752 if (!first)
4753 (void) printf(" ");
4754 else
4755 first = B_FALSE;
4756
4757 right_justify = B_FALSE;
4758 if (pl->pl_prop != ZPROP_INVAL) {
4759 header = zpool_prop_column_name(pl->pl_prop);
4760 right_justify = zpool_prop_align_right(pl->pl_prop);
4761 } else {
4762 int i;
4763
4764 for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
4765 headerbuf[i] = toupper(pl->pl_user_prop[i]);
4766 headerbuf[i] = '\0';
4767 header = headerbuf;
4768 }
4769
4770 if (pl->pl_next == NULL && !right_justify)
4771 (void) printf("%s", header);
4772 else if (right_justify)
4773 (void) printf("%*s", (int)width, header);
4774 else
4775 (void) printf("%-*s", (int)width, header);
4776 }
4777
4778 (void) printf("\n");
4779 }
4780
4781 /*
4782 * Given a pool and a list of properties, print out all the properties according
4783 * to the described layout.
4784 */
4785 static void
4786 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
4787 {
4788 zprop_list_t *pl = cb->cb_proplist;
4789 boolean_t first = B_TRUE;
4790 char property[ZPOOL_MAXPROPLEN];
4791 char *propstr;
4792 boolean_t right_justify;
4793 size_t width;
4794
4795 for (; pl != NULL; pl = pl->pl_next) {
4796
4797 width = pl->pl_width;
4798 if (first && cb->cb_verbose) {
4799 /*
4800 * Reset the width to accommodate the verbose listing
4801 * of devices.
4802 */
4803 width = cb->cb_namewidth;
4804 }
4805
4806 if (!first) {
4807 if (cb->cb_scripted)
4808 (void) printf("\t");
4809 else
4810 (void) printf(" ");
4811 } else {
4812 first = B_FALSE;
4813 }
4814
4815 right_justify = B_FALSE;
4816 if (pl->pl_prop != ZPROP_INVAL) {
4817 if (zpool_get_prop(zhp, pl->pl_prop, property,
4818 sizeof (property), NULL, cb->cb_literal) != 0)
4819 propstr = "-";
4820 else
4821 propstr = property;
4822
4823 right_justify = zpool_prop_align_right(pl->pl_prop);
4824 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
4825 zpool_prop_unsupported(pl->pl_user_prop)) &&
4826 zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
4827 sizeof (property)) == 0) {
4828 propstr = property;
4829 } else {
4830 propstr = "-";
4831 }
4832
4833
4834 /*
4835 * If this is being called in scripted mode, or if this is the
4836 * last column and it is left-justified, don't include a width
4837 * format specifier.
4838 */
4839 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
4840 (void) printf("%s", propstr);
4841 else if (right_justify)
4842 (void) printf("%*s", (int)width, propstr);
4843 else
4844 (void) printf("%-*s", (int)width, propstr);
4845 }
4846
4847 (void) printf("\n");
4848 }
4849
4850 static void
4851 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted,
4852 boolean_t valid, enum zfs_nicenum_format format)
4853 {
4854 char propval[64];
4855 boolean_t fixed;
4856 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
4857
4858 switch (prop) {
4859 case ZPOOL_PROP_EXPANDSZ:
4860 if (value == 0)
4861 (void) strlcpy(propval, "-", sizeof (propval));
4862 else
4863 zfs_nicenum_format(value, propval, sizeof (propval),
4864 format);
4865 break;
4866 case ZPOOL_PROP_FRAGMENTATION:
4867 if (value == ZFS_FRAG_INVALID) {
4868 (void) strlcpy(propval, "-", sizeof (propval));
4869 } else if (format == ZFS_NICENUM_RAW) {
4870 (void) snprintf(propval, sizeof (propval), "%llu",
4871 (unsigned long long)value);
4872 } else {
4873 (void) snprintf(propval, sizeof (propval), "%llu%%",
4874 (unsigned long long)value);
4875 }
4876 break;
4877 case ZPOOL_PROP_CAPACITY:
4878 if (format == ZFS_NICENUM_RAW)
4879 (void) snprintf(propval, sizeof (propval), "%llu",
4880 (unsigned long long)value);
4881 else
4882 (void) snprintf(propval, sizeof (propval), "%llu%%",
4883 (unsigned long long)value);
4884 break;
4885 default:
4886 zfs_nicenum_format(value, propval, sizeof (propval), format);
4887 }
4888
4889 if (!valid)
4890 (void) strlcpy(propval, "-", sizeof (propval));
4891
4892 if (scripted)
4893 (void) printf("\t%s", propval);
4894 else
4895 (void) printf(" %*s", (int)width, propval);
4896 }
4897
4898 void
4899 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
4900 list_cbdata_t *cb, int depth)
4901 {
4902 nvlist_t **child;
4903 vdev_stat_t *vs;
4904 uint_t c, children;
4905 char *vname;
4906 boolean_t scripted = cb->cb_scripted;
4907 uint64_t islog = B_FALSE;
4908 boolean_t haslog = B_FALSE;
4909 char *dashes = "%-*s - - - - - -\n";
4910
4911 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
4912 (uint64_t **)&vs, &c) == 0);
4913
4914 if (name != NULL) {
4915 boolean_t toplevel = (vs->vs_space != 0);
4916 uint64_t cap;
4917 enum zfs_nicenum_format format;
4918
4919 if (cb->cb_literal)
4920 format = ZFS_NICENUM_RAW;
4921 else
4922 format = ZFS_NICENUM_1024;
4923
4924 if (scripted)
4925 (void) printf("\t%s", name);
4926 else if (strlen(name) + depth > cb->cb_namewidth)
4927 (void) printf("%*s%s", depth, "", name);
4928 else
4929 (void) printf("%*s%s%*s", depth, "", name,
4930 (int)(cb->cb_namewidth - strlen(name) - depth), "");
4931
4932 /*
4933 * Print the properties for the individual vdevs. Some
4934 * properties are only applicable to toplevel vdevs. The
4935 * 'toplevel' boolean value is passed to the print_one_column()
4936 * to indicate that the value is valid.
4937 */
4938 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted,
4939 toplevel, format);
4940 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted,
4941 toplevel, format);
4942 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
4943 scripted, toplevel, format);
4944 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted,
4945 B_TRUE, format);
4946 print_one_column(ZPOOL_PROP_FRAGMENTATION,
4947 vs->vs_fragmentation, scripted,
4948 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
4949 format);
4950 cap = (vs->vs_space == 0) ? 0 :
4951 (vs->vs_alloc * 100 / vs->vs_space);
4952 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel,
4953 format);
4954 (void) printf("\n");
4955 }
4956
4957 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
4958 &child, &children) != 0)
4959 return;
4960
4961 for (c = 0; c < children; c++) {
4962 uint64_t ishole = B_FALSE;
4963
4964 if (nvlist_lookup_uint64(child[c],
4965 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
4966 continue;
4967
4968 if (nvlist_lookup_uint64(child[c],
4969 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) {
4970 haslog = B_TRUE;
4971 continue;
4972 }
4973
4974 vname = zpool_vdev_name(g_zfs, zhp, child[c],
4975 cb->cb_name_flags);
4976 print_list_stats(zhp, vname, child[c], cb, depth + 2);
4977 free(vname);
4978 }
4979
4980 if (haslog == B_TRUE) {
4981 /* LINTED E_SEC_PRINTF_VAR_FMT */
4982 (void) printf(dashes, cb->cb_namewidth, "log");
4983 for (c = 0; c < children; c++) {
4984 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
4985 &islog) != 0 || !islog)
4986 continue;
4987 vname = zpool_vdev_name(g_zfs, zhp, child[c],
4988 cb->cb_name_flags);
4989 print_list_stats(zhp, vname, child[c], cb, depth + 2);
4990 free(vname);
4991 }
4992 }
4993
4994 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
4995 &child, &children) == 0 && children > 0) {
4996 /* LINTED E_SEC_PRINTF_VAR_FMT */
4997 (void) printf(dashes, cb->cb_namewidth, "cache");
4998 for (c = 0; c < children; c++) {
4999 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5000 cb->cb_name_flags);
5001 print_list_stats(zhp, vname, child[c], cb, depth + 2);
5002 free(vname);
5003 }
5004 }
5005
5006 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
5007 &children) == 0 && children > 0) {
5008 /* LINTED E_SEC_PRINTF_VAR_FMT */
5009 (void) printf(dashes, cb->cb_namewidth, "spare");
5010 for (c = 0; c < children; c++) {
5011 vname = zpool_vdev_name(g_zfs, zhp, child[c],
5012 cb->cb_name_flags);
5013 print_list_stats(zhp, vname, child[c], cb, depth + 2);
5014 free(vname);
5015 }
5016 }
5017 }
5018
5019
5020 /*
5021 * Generic callback function to list a pool.
5022 */
5023 int
5024 list_callback(zpool_handle_t *zhp, void *data)
5025 {
5026 list_cbdata_t *cbp = data;
5027 nvlist_t *config;
5028 nvlist_t *nvroot;
5029
5030 config = zpool_get_config(zhp, NULL);
5031
5032 print_pool(zhp, cbp);
5033 if (!cbp->cb_verbose)
5034 return (0);
5035
5036 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
5037 &nvroot) == 0);
5038 print_list_stats(zhp, NULL, nvroot, cbp, 0);
5039
5040 return (0);
5041 }
5042
5043 /*
5044 * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
5045 *
5046 * -g Display guid for individual vdev name.
5047 * -H Scripted mode. Don't display headers, and separate properties
5048 * by a single tab.
5049 * -L Follow links when resolving vdev path name.
5050 * -o List of properties to display. Defaults to
5051 * "name,size,allocated,free,expandsize,fragmentation,capacity,"
5052 * "dedupratio,health,altroot"
5053 * -p Display values in parsable (exact) format.
5054 * -P Display full path for vdev name.
5055 * -T Display a timestamp in date(1) or Unix format
5056 *
5057 * List all pools in the system, whether or not they're healthy. Output space
5058 * statistics for each one, as well as health status summary.
5059 */
5060 int
5061 zpool_do_list(int argc, char **argv)
5062 {
5063 int c;
5064 int ret = 0;
5065 list_cbdata_t cb = { 0 };
5066 static char default_props[] =
5067 "name,size,allocated,free,expandsize,fragmentation,capacity,"
5068 "dedupratio,health,altroot";
5069 char *props = default_props;
5070 float interval = 0;
5071 unsigned long count = 0;
5072 zpool_list_t *list;
5073 boolean_t first = B_TRUE;
5074
5075 /* check options */
5076 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) {
5077 switch (c) {
5078 case 'g':
5079 cb.cb_name_flags |= VDEV_NAME_GUID;
5080 break;
5081 case 'H':
5082 cb.cb_scripted = B_TRUE;
5083 break;
5084 case 'L':
5085 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
5086 break;
5087 case 'o':
5088 props = optarg;
5089 break;
5090 case 'P':
5091 cb.cb_name_flags |= VDEV_NAME_PATH;
5092 break;
5093 case 'p':
5094 cb.cb_literal = B_TRUE;
5095 break;
5096 case 'T':
5097 get_timestamp_arg(*optarg);
5098 break;
5099 case 'v':
5100 cb.cb_verbose = B_TRUE;
5101 break;
5102 case ':':
5103 (void) fprintf(stderr, gettext("missing argument for "
5104 "'%c' option\n"), optopt);
5105 usage(B_FALSE);
5106 break;
5107 case '?':
5108 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5109 optopt);
5110 usage(B_FALSE);
5111 }
5112 }
5113
5114 argc -= optind;
5115 argv += optind;
5116
5117 get_interval_count(&argc, argv, &interval, &count);
5118
5119 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
5120 usage(B_FALSE);
5121
5122 for (;;) {
5123 if ((list = pool_list_get(argc, argv, &cb.cb_proplist,
5124 &ret)) == NULL)
5125 return (1);
5126
5127 if (pool_list_count(list) == 0)
5128 break;
5129
5130 if (timestamp_fmt != NODATE)
5131 print_timestamp(timestamp_fmt);
5132
5133 if (!cb.cb_scripted && (first || cb.cb_verbose)) {
5134 print_header(&cb);
5135 first = B_FALSE;
5136 }
5137 ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
5138
5139 if (interval == 0)
5140 break;
5141
5142 if (count != 0 && --count == 0)
5143 break;
5144
5145 pool_list_free(list);
5146 (void) fsleep(interval);
5147 }
5148
5149 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
5150 (void) printf(gettext("no pools available\n"));
5151 ret = 0;
5152 }
5153
5154 pool_list_free(list);
5155 zprop_free_list(cb.cb_proplist);
5156 return (ret);
5157 }
5158
5159 static int
5160 zpool_do_attach_or_replace(int argc, char **argv, int replacing)
5161 {
5162 boolean_t force = B_FALSE;
5163 int c;
5164 nvlist_t *nvroot;
5165 char *poolname, *old_disk, *new_disk;
5166 zpool_handle_t *zhp;
5167 nvlist_t *props = NULL;
5168 char *propval;
5169 int ret;
5170
5171 /* check options */
5172 while ((c = getopt(argc, argv, "fo:")) != -1) {
5173 switch (c) {
5174 case 'f':
5175 force = B_TRUE;
5176 break;
5177 case 'o':
5178 if ((propval = strchr(optarg, '=')) == NULL) {
5179 (void) fprintf(stderr, gettext("missing "
5180 "'=' for -o option\n"));
5181 usage(B_FALSE);
5182 }
5183 *propval = '\0';
5184 propval++;
5185
5186 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) ||
5187 (add_prop_list(optarg, propval, &props, B_TRUE)))
5188 usage(B_FALSE);
5189 break;
5190 case '?':
5191 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5192 optopt);
5193 usage(B_FALSE);
5194 }
5195 }
5196
5197 argc -= optind;
5198 argv += optind;
5199
5200 /* get pool name and check number of arguments */
5201 if (argc < 1) {
5202 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5203 usage(B_FALSE);
5204 }
5205
5206 poolname = argv[0];
5207
5208 if (argc < 2) {
5209 (void) fprintf(stderr,
5210 gettext("missing <device> specification\n"));
5211 usage(B_FALSE);
5212 }
5213
5214 old_disk = argv[1];
5215
5216 if (argc < 3) {
5217 if (!replacing) {
5218 (void) fprintf(stderr,
5219 gettext("missing <new_device> specification\n"));
5220 usage(B_FALSE);
5221 }
5222 new_disk = old_disk;
5223 argc -= 1;
5224 argv += 1;
5225 } else {
5226 new_disk = argv[2];
5227 argc -= 2;
5228 argv += 2;
5229 }
5230
5231 if (argc > 1) {
5232 (void) fprintf(stderr, gettext("too many arguments\n"));
5233 usage(B_FALSE);
5234 }
5235
5236 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
5237 nvlist_free(props);
5238 return (1);
5239 }
5240
5241 if (zpool_get_config(zhp, NULL) == NULL) {
5242 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
5243 poolname);
5244 zpool_close(zhp);
5245 nvlist_free(props);
5246 return (1);
5247 }
5248
5249 /* unless manually specified use "ashift" pool property (if set) */
5250 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) {
5251 int intval;
5252 zprop_source_t src;
5253 char strval[ZPOOL_MAXPROPLEN];
5254
5255 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src);
5256 if (src != ZPROP_SRC_DEFAULT) {
5257 (void) sprintf(strval, "%" PRId32, intval);
5258 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval,
5259 &props, B_TRUE) == 0);
5260 }
5261 }
5262
5263 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE,
5264 argc, argv);
5265 if (nvroot == NULL) {
5266 zpool_close(zhp);
5267 nvlist_free(props);
5268 return (1);
5269 }
5270
5271 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
5272
5273 nvlist_free(props);
5274 nvlist_free(nvroot);
5275 zpool_close(zhp);
5276
5277 return (ret);
5278 }
5279
5280 /*
5281 * zpool replace [-f] <pool> <device> <new_device>
5282 *
5283 * -f Force attach, even if <new_device> appears to be in use.
5284 *
5285 * Replace <device> with <new_device>.
5286 */
5287 /* ARGSUSED */
5288 int
5289 zpool_do_replace(int argc, char **argv)
5290 {
5291 return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
5292 }
5293
5294 /*
5295 * zpool attach [-f] [-o property=value] <pool> <device> <new_device>
5296 *
5297 * -f Force attach, even if <new_device> appears to be in use.
5298 * -o Set property=value.
5299 *
5300 * Attach <new_device> to the mirror containing <device>. If <device> is not
5301 * part of a mirror, then <device> will be transformed into a mirror of
5302 * <device> and <new_device>. In either case, <new_device> will begin life
5303 * with a DTL of [0, now], and will immediately begin to resilver itself.
5304 */
5305 int
5306 zpool_do_attach(int argc, char **argv)
5307 {
5308 return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
5309 }
5310
5311 /*
5312 * zpool detach [-f] <pool> <device>
5313 *
5314 * -f Force detach of <device>, even if DTLs argue against it
5315 * (not supported yet)
5316 *
5317 * Detach a device from a mirror. The operation will be refused if <device>
5318 * is the last device in the mirror, or if the DTLs indicate that this device
5319 * has the only valid copy of some data.
5320 */
5321 /* ARGSUSED */
5322 int
5323 zpool_do_detach(int argc, char **argv)
5324 {
5325 int c;
5326 char *poolname, *path;
5327 zpool_handle_t *zhp;
5328 int ret;
5329
5330 /* check options */
5331 while ((c = getopt(argc, argv, "f")) != -1) {
5332 switch (c) {
5333 case 'f':
5334 case '?':
5335 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5336 optopt);
5337 usage(B_FALSE);
5338 }
5339 }
5340
5341 argc -= optind;
5342 argv += optind;
5343
5344 /* get pool name and check number of arguments */
5345 if (argc < 1) {
5346 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5347 usage(B_FALSE);
5348 }
5349
5350 if (argc < 2) {
5351 (void) fprintf(stderr,
5352 gettext("missing <device> specification\n"));
5353 usage(B_FALSE);
5354 }
5355
5356 poolname = argv[0];
5357 path = argv[1];
5358
5359 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5360 return (1);
5361
5362 ret = zpool_vdev_detach(zhp, path);
5363
5364 zpool_close(zhp);
5365
5366 return (ret);
5367 }
5368
5369 /*
5370 * zpool split [-gLnP] [-o prop=val] ...
5371 * [-o mntopt] ...
5372 * [-R altroot] <pool> <newpool> [<device> ...]
5373 *
5374 * -g Display guid for individual vdev name.
5375 * -L Follow links when resolving vdev path name.
5376 * -n Do not split the pool, but display the resulting layout if
5377 * it were to be split.
5378 * -o Set property=value, or set mount options.
5379 * -P Display full path for vdev name.
5380 * -R Mount the split-off pool under an alternate root.
5381 *
5382 * Splits the named pool and gives it the new pool name. Devices to be split
5383 * off may be listed, provided that no more than one device is specified
5384 * per top-level vdev mirror. The newly split pool is left in an exported
5385 * state unless -R is specified.
5386 *
5387 * Restrictions: the top-level of the pool pool must only be made up of
5388 * mirrors; all devices in the pool must be healthy; no device may be
5389 * undergoing a resilvering operation.
5390 */
5391 int
5392 zpool_do_split(int argc, char **argv)
5393 {
5394 char *srcpool, *newpool, *propval;
5395 char *mntopts = NULL;
5396 splitflags_t flags;
5397 int c, ret = 0;
5398 zpool_handle_t *zhp;
5399 nvlist_t *config, *props = NULL;
5400
5401 flags.dryrun = B_FALSE;
5402 flags.import = B_FALSE;
5403 flags.name_flags = 0;
5404
5405 /* check options */
5406 while ((c = getopt(argc, argv, ":gLR:no:P")) != -1) {
5407 switch (c) {
5408 case 'g':
5409 flags.name_flags |= VDEV_NAME_GUID;
5410 break;
5411 case 'L':
5412 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
5413 break;
5414 case 'R':
5415 flags.import = B_TRUE;
5416 if (add_prop_list(
5417 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg,
5418 &props, B_TRUE) != 0) {
5419 nvlist_free(props);
5420 usage(B_FALSE);
5421 }
5422 break;
5423 case 'n':
5424 flags.dryrun = B_TRUE;
5425 break;
5426 case 'o':
5427 if ((propval = strchr(optarg, '=')) != NULL) {
5428 *propval = '\0';
5429 propval++;
5430 if (add_prop_list(optarg, propval,
5431 &props, B_TRUE) != 0) {
5432 nvlist_free(props);
5433 usage(B_FALSE);
5434 }
5435 } else {
5436 mntopts = optarg;
5437 }
5438 break;
5439 case 'P':
5440 flags.name_flags |= VDEV_NAME_PATH;
5441 break;
5442 case ':':
5443 (void) fprintf(stderr, gettext("missing argument for "
5444 "'%c' option\n"), optopt);
5445 usage(B_FALSE);
5446 break;
5447 case '?':
5448 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5449 optopt);
5450 usage(B_FALSE);
5451 break;
5452 }
5453 }
5454
5455 if (!flags.import && mntopts != NULL) {
5456 (void) fprintf(stderr, gettext("setting mntopts is only "
5457 "valid when importing the pool\n"));
5458 usage(B_FALSE);
5459 }
5460
5461 argc -= optind;
5462 argv += optind;
5463
5464 if (argc < 1) {
5465 (void) fprintf(stderr, gettext("Missing pool name\n"));
5466 usage(B_FALSE);
5467 }
5468 if (argc < 2) {
5469 (void) fprintf(stderr, gettext("Missing new pool name\n"));
5470 usage(B_FALSE);
5471 }
5472
5473 srcpool = argv[0];
5474 newpool = argv[1];
5475
5476 argc -= 2;
5477 argv += 2;
5478
5479 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) {
5480 nvlist_free(props);
5481 return (1);
5482 }
5483
5484 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
5485 if (config == NULL) {
5486 ret = 1;
5487 } else {
5488 if (flags.dryrun) {
5489 (void) printf(gettext("would create '%s' with the "
5490 "following layout:\n\n"), newpool);
5491 print_vdev_tree(NULL, newpool, config, 0, B_FALSE,
5492 flags.name_flags);
5493 }
5494 }
5495
5496 zpool_close(zhp);
5497
5498 if (ret != 0 || flags.dryrun || !flags.import) {
5499 nvlist_free(config);
5500 nvlist_free(props);
5501 return (ret);
5502 }
5503
5504 /*
5505 * The split was successful. Now we need to open the new
5506 * pool and import it.
5507 */
5508 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) {
5509 nvlist_free(config);
5510 nvlist_free(props);
5511 return (1);
5512 }
5513 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
5514 zpool_enable_datasets(zhp, mntopts, 0) != 0) {
5515 ret = 1;
5516 (void) fprintf(stderr, gettext("Split was successful, but "
5517 "the datasets could not all be mounted\n"));
5518 (void) fprintf(stderr, gettext("Try doing '%s' with a "
5519 "different altroot\n"), "zpool import");
5520 }
5521 zpool_close(zhp);
5522 nvlist_free(config);
5523 nvlist_free(props);
5524
5525 return (ret);
5526 }
5527
5528
5529
5530 /*
5531 * zpool online <pool> <device> ...
5532 */
5533 int
5534 zpool_do_online(int argc, char **argv)
5535 {
5536 int c, i;
5537 char *poolname;
5538 zpool_handle_t *zhp;
5539 int ret = 0;
5540 vdev_state_t newstate;
5541 int flags = 0;
5542
5543 /* check options */
5544 while ((c = getopt(argc, argv, "et")) != -1) {
5545 switch (c) {
5546 case 'e':
5547 flags |= ZFS_ONLINE_EXPAND;
5548 break;
5549 case 't':
5550 case '?':
5551 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5552 optopt);
5553 usage(B_FALSE);
5554 }
5555 }
5556
5557 argc -= optind;
5558 argv += optind;
5559
5560 /* get pool name and check number of arguments */
5561 if (argc < 1) {
5562 (void) fprintf(stderr, gettext("missing pool name\n"));
5563 usage(B_FALSE);
5564 }
5565 if (argc < 2) {
5566 (void) fprintf(stderr, gettext("missing device name\n"));
5567 usage(B_FALSE);
5568 }
5569
5570 poolname = argv[0];
5571
5572 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5573 return (1);
5574
5575 for (i = 1; i < argc; i++) {
5576 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) {
5577 if (newstate != VDEV_STATE_HEALTHY) {
5578 (void) printf(gettext("warning: device '%s' "
5579 "onlined, but remains in faulted state\n"),
5580 argv[i]);
5581 if (newstate == VDEV_STATE_FAULTED)
5582 (void) printf(gettext("use 'zpool "
5583 "clear' to restore a faulted "
5584 "device\n"));
5585 else
5586 (void) printf(gettext("use 'zpool "
5587 "replace' to replace devices "
5588 "that are no longer present\n"));
5589 }
5590 } else {
5591 ret = 1;
5592 }
5593 }
5594
5595 zpool_close(zhp);
5596
5597 return (ret);
5598 }
5599
5600 /*
5601 * zpool offline [-ft] <pool> <device> ...
5602 *
5603 * -f Force the device into a faulted state.
5604 *
5605 * -t Only take the device off-line temporarily. The offline/faulted
5606 * state will not be persistent across reboots.
5607 */
5608 /* ARGSUSED */
5609 int
5610 zpool_do_offline(int argc, char **argv)
5611 {
5612 int c, i;
5613 char *poolname;
5614 zpool_handle_t *zhp;
5615 int ret = 0;
5616 boolean_t istmp = B_FALSE;
5617 boolean_t fault = B_FALSE;
5618
5619 /* check options */
5620 while ((c = getopt(argc, argv, "ft")) != -1) {
5621 switch (c) {
5622 case 'f':
5623 fault = B_TRUE;
5624 break;
5625 case 't':
5626 istmp = B_TRUE;
5627 break;
5628 case '?':
5629 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5630 optopt);
5631 usage(B_FALSE);
5632 }
5633 }
5634
5635 argc -= optind;
5636 argv += optind;
5637
5638 /* get pool name and check number of arguments */
5639 if (argc < 1) {
5640 (void) fprintf(stderr, gettext("missing pool name\n"));
5641 usage(B_FALSE);
5642 }
5643 if (argc < 2) {
5644 (void) fprintf(stderr, gettext("missing device name\n"));
5645 usage(B_FALSE);
5646 }
5647
5648 poolname = argv[0];
5649
5650 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5651 return (1);
5652
5653 for (i = 1; i < argc; i++) {
5654 if (fault) {
5655 uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]);
5656 vdev_aux_t aux;
5657 if (istmp == B_FALSE) {
5658 /* Force the fault to persist across imports */
5659 aux = VDEV_AUX_EXTERNAL_PERSIST;
5660 } else {
5661 aux = VDEV_AUX_EXTERNAL;
5662 }
5663
5664 if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0)
5665 ret = 1;
5666 } else {
5667 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
5668 ret = 1;
5669 }
5670 }
5671
5672 zpool_close(zhp);
5673
5674 return (ret);
5675 }
5676
5677 /*
5678 * zpool clear <pool> [device]
5679 *
5680 * Clear all errors associated with a pool or a particular device.
5681 */
5682 int
5683 zpool_do_clear(int argc, char **argv)
5684 {
5685 int c;
5686 int ret = 0;
5687 boolean_t dryrun = B_FALSE;
5688 boolean_t do_rewind = B_FALSE;
5689 boolean_t xtreme_rewind = B_FALSE;
5690 uint32_t rewind_policy = ZPOOL_NO_REWIND;
5691 nvlist_t *policy = NULL;
5692 zpool_handle_t *zhp;
5693 char *pool, *device;
5694
5695 /* check options */
5696 while ((c = getopt(argc, argv, "FnX")) != -1) {
5697 switch (c) {
5698 case 'F':
5699 do_rewind = B_TRUE;
5700 break;
5701 case 'n':
5702 dryrun = B_TRUE;
5703 break;
5704 case 'X':
5705 xtreme_rewind = B_TRUE;
5706 break;
5707 case '?':
5708 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5709 optopt);
5710 usage(B_FALSE);
5711 }
5712 }
5713
5714 argc -= optind;
5715 argv += optind;
5716
5717 if (argc < 1) {
5718 (void) fprintf(stderr, gettext("missing pool name\n"));
5719 usage(B_FALSE);
5720 }
5721
5722 if (argc > 2) {
5723 (void) fprintf(stderr, gettext("too many arguments\n"));
5724 usage(B_FALSE);
5725 }
5726
5727 if ((dryrun || xtreme_rewind) && !do_rewind) {
5728 (void) fprintf(stderr,
5729 gettext("-n or -X only meaningful with -F\n"));
5730 usage(B_FALSE);
5731 }
5732 if (dryrun)
5733 rewind_policy = ZPOOL_TRY_REWIND;
5734 else if (do_rewind)
5735 rewind_policy = ZPOOL_DO_REWIND;
5736 if (xtreme_rewind)
5737 rewind_policy |= ZPOOL_EXTREME_REWIND;
5738
5739 /* In future, further rewind policy choices can be passed along here */
5740 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
5741 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
5742 return (1);
5743
5744 pool = argv[0];
5745 device = argc == 2 ? argv[1] : NULL;
5746
5747 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
5748 nvlist_free(policy);
5749 return (1);
5750 }
5751
5752 if (zpool_clear(zhp, device, policy) != 0)
5753 ret = 1;
5754
5755 zpool_close(zhp);
5756
5757 nvlist_free(policy);
5758
5759 return (ret);
5760 }
5761
5762 /*
5763 * zpool reguid <pool>
5764 */
5765 int
5766 zpool_do_reguid(int argc, char **argv)
5767 {
5768 int c;
5769 char *poolname;
5770 zpool_handle_t *zhp;
5771 int ret = 0;
5772
5773 /* check options */
5774 while ((c = getopt(argc, argv, "")) != -1) {
5775 switch (c) {
5776 case '?':
5777 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5778 optopt);
5779 usage(B_FALSE);
5780 }
5781 }
5782
5783 argc -= optind;
5784 argv += optind;
5785
5786 /* get pool name and check number of arguments */
5787 if (argc < 1) {
5788 (void) fprintf(stderr, gettext("missing pool name\n"));
5789 usage(B_FALSE);
5790 }
5791
5792 if (argc > 1) {
5793 (void) fprintf(stderr, gettext("too many arguments\n"));
5794 usage(B_FALSE);
5795 }
5796
5797 poolname = argv[0];
5798 if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
5799 return (1);
5800
5801 ret = zpool_reguid(zhp);
5802
5803 zpool_close(zhp);
5804 return (ret);
5805 }
5806
5807
5808 /*
5809 * zpool reopen <pool>
5810 *
5811 * Reopen the pool so that the kernel can update the sizes of all vdevs.
5812 */
5813 int
5814 zpool_do_reopen(int argc, char **argv)
5815 {
5816 int c;
5817 int ret = 0;
5818 zpool_handle_t *zhp;
5819 char *pool;
5820
5821 /* check options */
5822 while ((c = getopt(argc, argv, "")) != -1) {
5823 switch (c) {
5824 case '?':
5825 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5826 optopt);
5827 usage(B_FALSE);
5828 }
5829 }
5830
5831 argc--;
5832 argv++;
5833
5834 if (argc < 1) {
5835 (void) fprintf(stderr, gettext("missing pool name\n"));
5836 usage(B_FALSE);
5837 }
5838
5839 if (argc > 1) {
5840 (void) fprintf(stderr, gettext("too many arguments\n"));
5841 usage(B_FALSE);
5842 }
5843
5844 pool = argv[0];
5845 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
5846 return (1);
5847
5848 ret = zpool_reopen(zhp);
5849 zpool_close(zhp);
5850 return (ret);
5851 }
5852
5853 typedef struct scrub_cbdata {
5854 int cb_type;
5855 int cb_argc;
5856 char **cb_argv;
5857 pool_scrub_cmd_t cb_scrub_cmd;
5858 } scrub_cbdata_t;
5859
5860 int
5861 scrub_callback(zpool_handle_t *zhp, void *data)
5862 {
5863 scrub_cbdata_t *cb = data;
5864 int err;
5865
5866 /*
5867 * Ignore faulted pools.
5868 */
5869 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5870 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
5871 "currently unavailable\n"), zpool_get_name(zhp));
5872 return (1);
5873 }
5874
5875 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
5876
5877 return (err != 0);
5878 }
5879
5880 /*
5881 * zpool scrub [-s | -p] <pool> ...
5882 *
5883 * -s Stop. Stops any in-progress scrub.
5884 * -p Pause. Pause in-progress scrub.
5885 */
5886 int
5887 zpool_do_scrub(int argc, char **argv)
5888 {
5889 int c;
5890 scrub_cbdata_t cb;
5891
5892 cb.cb_type = POOL_SCAN_SCRUB;
5893 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
5894
5895 /* check options */
5896 while ((c = getopt(argc, argv, "sp")) != -1) {
5897 switch (c) {
5898 case 's':
5899 cb.cb_type = POOL_SCAN_NONE;
5900 break;
5901 case 'p':
5902 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
5903 break;
5904 case '?':
5905 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
5906 optopt);
5907 usage(B_FALSE);
5908 }
5909 }
5910
5911 if (cb.cb_type == POOL_SCAN_NONE &&
5912 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
5913 (void) fprintf(stderr, gettext("invalid option combination: "
5914 "-s and -p are mutually exclusive\n"));
5915 usage(B_FALSE);
5916 }
5917
5918 cb.cb_argc = argc;
5919 cb.cb_argv = argv;
5920 argc -= optind;
5921 argv += optind;
5922
5923 if (argc < 1) {
5924 (void) fprintf(stderr, gettext("missing pool name argument\n"));
5925 usage(B_FALSE);
5926 }
5927
5928 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
5929 }
5930
5931 /*
5932 * Print out detailed scrub status.
5933 */
5934 void
5935 print_scan_status(pool_scan_stat_t *ps)
5936 {
5937 time_t start, end, pause;
5938 uint64_t elapsed, mins_left, hours_left;
5939 uint64_t pass_exam, examined, total;
5940 uint_t rate;
5941 double fraction_done;
5942 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
5943
5944 (void) printf(gettext(" scan: "));
5945
5946 /* If there's never been a scan, there's not much to say. */
5947 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
5948 ps->pss_func >= POOL_SCAN_FUNCS) {
5949 (void) printf(gettext("none requested\n"));
5950 return;
5951 }
5952
5953 start = ps->pss_start_time;
5954 end = ps->pss_end_time;
5955 pause = ps->pss_pass_scrub_pause;
5956 zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf));
5957
5958 assert(ps->pss_func == POOL_SCAN_SCRUB ||
5959 ps->pss_func == POOL_SCAN_RESILVER);
5960 /*
5961 * Scan is finished or canceled.
5962 */
5963 if (ps->pss_state == DSS_FINISHED) {
5964 uint64_t minutes_taken = (end - start) / 60;
5965 char *fmt = NULL;
5966
5967 if (ps->pss_func == POOL_SCAN_SCRUB) {
5968 fmt = gettext("scrub repaired %s in %lluh%um with "
5969 "%llu errors on %s");
5970 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
5971 fmt = gettext("resilvered %s in %lluh%um with "
5972 "%llu errors on %s");
5973 }
5974 /* LINTED */
5975 (void) printf(fmt, processed_buf,
5976 (u_longlong_t)(minutes_taken / 60),
5977 (uint_t)(minutes_taken % 60),
5978 (u_longlong_t)ps->pss_errors,
5979 ctime((time_t *)&end));
5980 return;
5981 } else if (ps->pss_state == DSS_CANCELED) {
5982 if (ps->pss_func == POOL_SCAN_SCRUB) {
5983 (void) printf(gettext("scrub canceled on %s"),
5984 ctime(&end));
5985 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
5986 (void) printf(gettext("resilver canceled on %s"),
5987 ctime(&end));
5988 }
5989 return;
5990 }
5991
5992 assert(ps->pss_state == DSS_SCANNING);
5993
5994 /*
5995 * Scan is in progress.
5996 */
5997 if (ps->pss_func == POOL_SCAN_SCRUB) {
5998 if (pause == 0) {
5999 (void) printf(gettext("scrub in progress since %s"),
6000 ctime(&start));
6001 } else {
6002 char buf[32];
6003 struct tm *p = localtime(&pause);
6004 (void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
6005 (void) printf(gettext("scrub paused since %s\n"), buf);
6006 (void) printf(gettext("\tscrub started on %s"),
6007 ctime(&start));
6008 }
6009 } else if (ps->pss_func == POOL_SCAN_RESILVER) {
6010 (void) printf(gettext("resilver in progress since %s"),
6011 ctime(&start));
6012 }
6013
6014 examined = ps->pss_examined ? ps->pss_examined : 1;
6015 total = ps->pss_to_examine;
6016 fraction_done = (double)examined / total;
6017
6018 /* elapsed time for this pass */
6019 elapsed = time(NULL) - ps->pss_pass_start;
6020 elapsed -= ps->pss_pass_scrub_spent_paused;
6021 elapsed = elapsed ? elapsed : 1;
6022 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
6023 rate = pass_exam / elapsed;
6024 rate = rate ? rate : 1;
6025 mins_left = ((total - examined) / rate) / 60;
6026 hours_left = mins_left / 60;
6027
6028 zfs_nicebytes(examined, examined_buf, sizeof (examined_buf));
6029 zfs_nicebytes(total, total_buf, sizeof (total_buf));
6030
6031 /*
6032 * do not print estimated time if hours_left is more than 30 days
6033 * or we have a paused scrub
6034 */
6035 if (pause == 0) {
6036 zfs_nicebytes(rate, rate_buf, sizeof (rate_buf));
6037 (void) printf(gettext("\t%s scanned out of %s at %s/s"),
6038 examined_buf, total_buf, rate_buf);
6039 if (hours_left < (30 * 24)) {
6040 (void) printf(gettext(", %lluh%um to go\n"),
6041 (u_longlong_t)hours_left, (uint_t)(mins_left % 60));
6042 } else {
6043 (void) printf(gettext(
6044 ", (scan is slow, no estimated time)\n"));
6045 }
6046 } else {
6047 (void) printf(gettext("\t%s scanned out of %s\n"),
6048 examined_buf, total_buf);
6049 }
6050
6051 if (ps->pss_func == POOL_SCAN_RESILVER) {
6052 (void) printf(gettext("\t%s resilvered, %.2f%% done\n"),
6053 processed_buf, 100 * fraction_done);
6054 } else if (ps->pss_func == POOL_SCAN_SCRUB) {
6055 (void) printf(gettext("\t%s repaired, %.2f%% done\n"),
6056 processed_buf, 100 * fraction_done);
6057 }
6058 }
6059
6060 static void
6061 print_error_log(zpool_handle_t *zhp)
6062 {
6063 nvlist_t *nverrlist = NULL;
6064 nvpair_t *elem;
6065 char *pathname;
6066 size_t len = MAXPATHLEN * 2;
6067
6068 if (zpool_get_errlog(zhp, &nverrlist) != 0)
6069 return;
6070
6071 (void) printf("errors: Permanent errors have been "
6072 "detected in the following files:\n\n");
6073
6074 pathname = safe_malloc(len);
6075 elem = NULL;
6076 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
6077 nvlist_t *nv;
6078 uint64_t dsobj, obj;
6079
6080 verify(nvpair_value_nvlist(elem, &nv) == 0);
6081 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
6082 &dsobj) == 0);
6083 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
6084 &obj) == 0);
6085 zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
6086 (void) printf("%7s %s\n", "", pathname);
6087 }
6088 free(pathname);
6089 nvlist_free(nverrlist);
6090 }
6091
6092 static void
6093 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares,
6094 uint_t nspares)
6095 {
6096 uint_t i;
6097 char *name;
6098
6099 if (nspares == 0)
6100 return;
6101
6102 (void) printf(gettext("\tspares\n"));
6103
6104 for (i = 0; i < nspares; i++) {
6105 name = zpool_vdev_name(g_zfs, zhp, spares[i],
6106 cb->cb_name_flags);
6107 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE);
6108 free(name);
6109 }
6110 }
6111
6112 static void
6113 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache,
6114 uint_t nl2cache)
6115 {
6116 uint_t i;
6117 char *name;
6118
6119 if (nl2cache == 0)
6120 return;
6121
6122 (void) printf(gettext("\tcache\n"));
6123
6124 for (i = 0; i < nl2cache; i++) {
6125 name = zpool_vdev_name(g_zfs, zhp, l2cache[i],
6126 cb->cb_name_flags);
6127 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE);
6128 free(name);
6129 }
6130 }
6131
6132 static void
6133 print_dedup_stats(nvlist_t *config)
6134 {
6135 ddt_histogram_t *ddh;
6136 ddt_stat_t *dds;
6137 ddt_object_t *ddo;
6138 uint_t c;
6139 char dspace[6], mspace[6];
6140
6141 /*
6142 * If the pool was faulted then we may not have been able to
6143 * obtain the config. Otherwise, if we have anything in the dedup
6144 * table continue processing the stats.
6145 */
6146 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS,
6147 (uint64_t **)&ddo, &c) != 0)
6148 return;
6149
6150 (void) printf("\n");
6151 (void) printf(gettext(" dedup: "));
6152 if (ddo->ddo_count == 0) {
6153 (void) printf(gettext("no DDT entries\n"));
6154 return;
6155 }
6156
6157 zfs_nicebytes(ddo->ddo_dspace, dspace, sizeof (dspace));
6158 zfs_nicebytes(ddo->ddo_mspace, mspace, sizeof (mspace));
6159 (void) printf("DDT entries %llu, size %s on disk, %s in core\n",
6160 (u_longlong_t)ddo->ddo_count,
6161 dspace,
6162 mspace);
6163
6164 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS,
6165 (uint64_t **)&dds, &c) == 0);
6166 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM,
6167 (uint64_t **)&ddh, &c) == 0);
6168 zpool_dump_ddt(dds, ddh);
6169 }
6170
6171 /*
6172 * Display a summary of pool status. Displays a summary such as:
6173 *
6174 * pool: tank
6175 * status: DEGRADED
6176 * reason: One or more devices ...
6177 * see: http://zfsonlinux.org/msg/ZFS-xxxx-01
6178 * config:
6179 * mirror DEGRADED
6180 * c1t0d0 OK
6181 * c2t0d0 UNAVAIL
6182 *
6183 * When given the '-v' option, we print out the complete config. If the '-e'
6184 * option is specified, then we print out error rate information as well.
6185 */
6186 int
6187 status_callback(zpool_handle_t *zhp, void *data)
6188 {
6189 status_cbdata_t *cbp = data;
6190 nvlist_t *config, *nvroot;
6191 char *msgid;
6192 zpool_status_t reason;
6193 zpool_errata_t errata;
6194 const char *health;
6195 uint_t c;
6196 vdev_stat_t *vs;
6197
6198 config = zpool_get_config(zhp, NULL);
6199 reason = zpool_get_status(zhp, &msgid, &errata);
6200
6201 cbp->cb_count++;
6202
6203 /*
6204 * If we were given 'zpool status -x', only report those pools with
6205 * problems.
6206 */
6207 if (cbp->cb_explain &&
6208 (reason == ZPOOL_STATUS_OK ||
6209 reason == ZPOOL_STATUS_VERSION_OLDER ||
6210 reason == ZPOOL_STATUS_FEAT_DISABLED)) {
6211 if (!cbp->cb_allpools) {
6212 (void) printf(gettext("pool '%s' is healthy\n"),
6213 zpool_get_name(zhp));
6214 if (cbp->cb_first)
6215 cbp->cb_first = B_FALSE;
6216 }
6217 return (0);
6218 }
6219
6220 if (cbp->cb_first)
6221 cbp->cb_first = B_FALSE;
6222 else
6223 (void) printf("\n");
6224
6225 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
6226 &nvroot) == 0);
6227 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
6228 (uint64_t **)&vs, &c) == 0);
6229 health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
6230
6231 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
6232 (void) printf(gettext(" state: %s\n"), health);
6233
6234 switch (reason) {
6235 case ZPOOL_STATUS_MISSING_DEV_R:
6236 (void) printf(gettext("status: One or more devices could not "
6237 "be opened. Sufficient replicas exist for\n\tthe pool to "
6238 "continue functioning in a degraded state.\n"));
6239 (void) printf(gettext("action: Attach the missing device and "
6240 "online it using 'zpool online'.\n"));
6241 break;
6242
6243 case ZPOOL_STATUS_MISSING_DEV_NR:
6244 (void) printf(gettext("status: One or more devices could not "
6245 "be opened. There are insufficient\n\treplicas for the "
6246 "pool to continue functioning.\n"));
6247 (void) printf(gettext("action: Attach the missing device and "
6248 "online it using 'zpool online'.\n"));
6249 break;
6250
6251 case ZPOOL_STATUS_CORRUPT_LABEL_R:
6252 (void) printf(gettext("status: One or more devices could not "
6253 "be used because the label is missing or\n\tinvalid. "
6254 "Sufficient replicas exist for the pool to continue\n\t"
6255 "functioning in a degraded state.\n"));
6256 (void) printf(gettext("action: Replace the device using "
6257 "'zpool replace'.\n"));
6258 break;
6259
6260 case ZPOOL_STATUS_CORRUPT_LABEL_NR:
6261 (void) printf(gettext("status: One or more devices could not "
6262 "be used because the label is missing \n\tor invalid. "
6263 "There are insufficient replicas for the pool to "
6264 "continue\n\tfunctioning.\n"));
6265 zpool_explain_recover(zpool_get_handle(zhp),
6266 zpool_get_name(zhp), reason, config);
6267 break;
6268
6269 case ZPOOL_STATUS_FAILING_DEV:
6270 (void) printf(gettext("status: One or more devices has "
6271 "experienced an unrecoverable error. An\n\tattempt was "
6272 "made to correct the error. Applications are "
6273 "unaffected.\n"));
6274 (void) printf(gettext("action: Determine if the device needs "
6275 "to be replaced, and clear the errors\n\tusing "
6276 "'zpool clear' or replace the device with 'zpool "
6277 "replace'.\n"));
6278 break;
6279
6280 case ZPOOL_STATUS_OFFLINE_DEV:
6281 (void) printf(gettext("status: One or more devices has "
6282 "been taken offline by the administrator.\n\tSufficient "
6283 "replicas exist for the pool to continue functioning in "
6284 "a\n\tdegraded state.\n"));
6285 (void) printf(gettext("action: Online the device using "
6286 "'zpool online' or replace the device with\n\t'zpool "
6287 "replace'.\n"));
6288 break;
6289
6290 case ZPOOL_STATUS_REMOVED_DEV:
6291 (void) printf(gettext("status: One or more devices has "
6292 "been removed by the administrator.\n\tSufficient "
6293 "replicas exist for the pool to continue functioning in "
6294 "a\n\tdegraded state.\n"));
6295 (void) printf(gettext("action: Online the device using "
6296 "'zpool online' or replace the device with\n\t'zpool "
6297 "replace'.\n"));
6298 break;
6299
6300 case ZPOOL_STATUS_RESILVERING:
6301 (void) printf(gettext("status: One or more devices is "
6302 "currently being resilvered. The pool will\n\tcontinue "
6303 "to function, possibly in a degraded state.\n"));
6304 (void) printf(gettext("action: Wait for the resilver to "
6305 "complete.\n"));
6306 break;
6307
6308 case ZPOOL_STATUS_CORRUPT_DATA:
6309 (void) printf(gettext("status: One or more devices has "
6310 "experienced an error resulting in data\n\tcorruption. "
6311 "Applications may be affected.\n"));
6312 (void) printf(gettext("action: Restore the file in question "
6313 "if possible. Otherwise restore the\n\tentire pool from "
6314 "backup.\n"));
6315 break;
6316
6317 case ZPOOL_STATUS_CORRUPT_POOL:
6318 (void) printf(gettext("status: The pool metadata is corrupted "
6319 "and the pool cannot be opened.\n"));
6320 zpool_explain_recover(zpool_get_handle(zhp),
6321 zpool_get_name(zhp), reason, config);
6322 break;
6323
6324 case ZPOOL_STATUS_VERSION_OLDER:
6325 (void) printf(gettext("status: The pool is formatted using a "
6326 "legacy on-disk format. The pool can\n\tstill be used, "
6327 "but some features are unavailable.\n"));
6328 (void) printf(gettext("action: Upgrade the pool using 'zpool "
6329 "upgrade'. Once this is done, the\n\tpool will no longer "
6330 "be accessible on software that does not support\n\t"
6331 "feature flags.\n"));
6332 break;
6333
6334 case ZPOOL_STATUS_VERSION_NEWER:
6335 (void) printf(gettext("status: The pool has been upgraded to a "
6336 "newer, incompatible on-disk version.\n\tThe pool cannot "
6337 "be accessed on this system.\n"));
6338 (void) printf(gettext("action: Access the pool from a system "
6339 "running more recent software, or\n\trestore the pool from "
6340 "backup.\n"));
6341 break;
6342
6343 case ZPOOL_STATUS_FEAT_DISABLED:
6344 (void) printf(gettext("status: Some supported features are not "
6345 "enabled on the pool. The pool can\n\tstill be used, but "
6346 "some features are unavailable.\n"));
6347 (void) printf(gettext("action: Enable all features using "
6348 "'zpool upgrade'. Once this is done,\n\tthe pool may no "
6349 "longer be accessible by software that does not support\n\t"
6350 "the features. See zpool-features(5) for details.\n"));
6351 break;
6352
6353 case ZPOOL_STATUS_UNSUP_FEAT_READ:
6354 (void) printf(gettext("status: The pool cannot be accessed on "
6355 "this system because it uses the\n\tfollowing feature(s) "
6356 "not supported on this system:\n"));
6357 zpool_print_unsup_feat(config);
6358 (void) printf("\n");
6359 (void) printf(gettext("action: Access the pool from a system "
6360 "that supports the required feature(s),\n\tor restore the "
6361 "pool from backup.\n"));
6362 break;
6363
6364 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
6365 (void) printf(gettext("status: The pool can only be accessed "
6366 "in read-only mode on this system. It\n\tcannot be "
6367 "accessed in read-write mode because it uses the "
6368 "following\n\tfeature(s) not supported on this system:\n"));
6369 zpool_print_unsup_feat(config);
6370 (void) printf("\n");
6371 (void) printf(gettext("action: The pool cannot be accessed in "
6372 "read-write mode. Import the pool with\n"
6373 "\t\"-o readonly=on\", access the pool from a system that "
6374 "supports the\n\trequired feature(s), or restore the "
6375 "pool from backup.\n"));
6376 break;
6377
6378 case ZPOOL_STATUS_FAULTED_DEV_R:
6379 (void) printf(gettext("status: One or more devices are "
6380 "faulted in response to persistent errors.\n\tSufficient "
6381 "replicas exist for the pool to continue functioning "
6382 "in a\n\tdegraded state.\n"));
6383 (void) printf(gettext("action: Replace the faulted device, "
6384 "or use 'zpool clear' to mark the device\n\trepaired.\n"));
6385 break;
6386
6387 case ZPOOL_STATUS_FAULTED_DEV_NR:
6388 (void) printf(gettext("status: One or more devices are "
6389 "faulted in response to persistent errors. There are "
6390 "insufficient replicas for the pool to\n\tcontinue "
6391 "functioning.\n"));
6392 (void) printf(gettext("action: Destroy and re-create the pool "
6393 "from a backup source. Manually marking the device\n"
6394 "\trepaired using 'zpool clear' may allow some data "
6395 "to be recovered.\n"));
6396 break;
6397
6398 case ZPOOL_STATUS_IO_FAILURE_MMP:
6399 (void) printf(gettext("status: The pool is suspended because "
6400 "multihost writes failed or were delayed;\n\tanother "
6401 "system could import the pool undetected.\n"));
6402 (void) printf(gettext("action: Make sure the pool's devices "
6403 "are connected, then reboot your system and\n\timport the "
6404 "pool.\n"));
6405 break;
6406
6407 case ZPOOL_STATUS_IO_FAILURE_WAIT:
6408 case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
6409 (void) printf(gettext("status: One or more devices are "
6410 "faulted in response to IO failures.\n"));
6411 (void) printf(gettext("action: Make sure the affected devices "
6412 "are connected, then run 'zpool clear'.\n"));
6413 break;
6414
6415 case ZPOOL_STATUS_BAD_LOG:
6416 (void) printf(gettext("status: An intent log record "
6417 "could not be read.\n"
6418 "\tWaiting for administrator intervention to fix the "
6419 "faulted pool.\n"));
6420 (void) printf(gettext("action: Either restore the affected "
6421 "device(s) and run 'zpool online',\n"
6422 "\tor ignore the intent log records by running "
6423 "'zpool clear'.\n"));
6424 break;
6425
6426 case ZPOOL_STATUS_HOSTID_MISMATCH:
6427 (void) printf(gettext("status: Mismatch between pool hostid "
6428 "and system hostid on imported pool.\n\tThis pool was "
6429 "previously imported into a system with a different "
6430 "hostid,\n\tand then was verbatim imported into this "
6431 "system.\n"));
6432 (void) printf(gettext("action: Export this pool on all systems "
6433 "on which it is imported.\n"
6434 "\tThen import it to correct the mismatch.\n"));
6435 break;
6436
6437 case ZPOOL_STATUS_ERRATA:
6438 (void) printf(gettext("status: Errata #%d detected.\n"),
6439 errata);
6440
6441 switch (errata) {
6442 case ZPOOL_ERRATA_NONE:
6443 break;
6444
6445 case ZPOOL_ERRATA_ZOL_2094_SCRUB:
6446 (void) printf(gettext("action: To correct the issue "
6447 "run 'zpool scrub'.\n"));
6448 break;
6449
6450 default:
6451 /*
6452 * All errata which allow the pool to be imported
6453 * must contain an action message.
6454 */
6455 assert(0);
6456 }
6457 break;
6458
6459 default:
6460 /*
6461 * The remaining errors can't actually be generated, yet.
6462 */
6463 assert(reason == ZPOOL_STATUS_OK);
6464 }
6465
6466 if (msgid != NULL)
6467 (void) printf(gettext(" see: http://zfsonlinux.org/msg/%s\n"),
6468 msgid);
6469
6470 if (config != NULL) {
6471 uint64_t nerr;
6472 nvlist_t **spares, **l2cache;
6473 uint_t nspares, nl2cache;
6474 pool_scan_stat_t *ps = NULL;
6475
6476 (void) nvlist_lookup_uint64_array(nvroot,
6477 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
6478 print_scan_status(ps);
6479
6480 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0,
6481 cbp->cb_name_flags | VDEV_NAME_TYPE_ID);
6482 if (cbp->cb_namewidth < 10)
6483 cbp->cb_namewidth = 10;
6484
6485 (void) printf(gettext("config:\n\n"));
6486 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s"),
6487 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE",
6488 "CKSUM");
6489
6490 if (cbp->vcdl != NULL)
6491 print_cmd_columns(cbp->vcdl, 0);
6492
6493 printf("\n");
6494 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0,
6495 B_FALSE);
6496
6497 if (num_logs(nvroot) > 0)
6498 print_logs(zhp, cbp, nvroot);
6499 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
6500 &l2cache, &nl2cache) == 0)
6501 print_l2cache(zhp, cbp, l2cache, nl2cache);
6502
6503 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
6504 &spares, &nspares) == 0)
6505 print_spares(zhp, cbp, spares, nspares);
6506
6507 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
6508 &nerr) == 0) {
6509 nvlist_t *nverrlist = NULL;
6510
6511 /*
6512 * If the approximate error count is small, get a
6513 * precise count by fetching the entire log and
6514 * uniquifying the results.
6515 */
6516 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
6517 zpool_get_errlog(zhp, &nverrlist) == 0) {
6518 nvpair_t *elem;
6519
6520 elem = NULL;
6521 nerr = 0;
6522 while ((elem = nvlist_next_nvpair(nverrlist,
6523 elem)) != NULL) {
6524 nerr++;
6525 }
6526 }
6527 nvlist_free(nverrlist);
6528
6529 (void) printf("\n");
6530
6531 if (nerr == 0)
6532 (void) printf(gettext("errors: No known data "
6533 "errors\n"));
6534 else if (!cbp->cb_verbose)
6535 (void) printf(gettext("errors: %llu data "
6536 "errors, use '-v' for a list\n"),
6537 (u_longlong_t)nerr);
6538 else
6539 print_error_log(zhp);
6540 }
6541
6542 if (cbp->cb_dedup_stats)
6543 print_dedup_stats(config);
6544 } else {
6545 (void) printf(gettext("config: The configuration cannot be "
6546 "determined.\n"));
6547 }
6548
6549 return (0);
6550 }
6551
6552 /*
6553 * zpool status [-c [script1,script2,...]] [-gLPvx] [-T d|u] [pool] ...
6554 * [interval [count]]
6555 *
6556 * -c CMD For each vdev, run command CMD
6557 * -g Display guid for individual vdev name.
6558 * -L Follow links when resolving vdev path name.
6559 * -P Display full path for vdev name.
6560 * -v Display complete error logs
6561 * -x Display only pools with potential problems
6562 * -D Display dedup status (undocumented)
6563 * -T Display a timestamp in date(1) or Unix format
6564 *
6565 * Describes the health status of all pools or some subset.
6566 */
6567 int
6568 zpool_do_status(int argc, char **argv)
6569 {
6570 int c;
6571 int ret;
6572 float interval = 0;
6573 unsigned long count = 0;
6574 status_cbdata_t cb = { 0 };
6575 char *cmd = NULL;
6576
6577 /* check options */
6578 while ((c = getopt(argc, argv, "c:gLPvxDT:")) != -1) {
6579 switch (c) {
6580 case 'c':
6581 if (cmd != NULL) {
6582 fprintf(stderr,
6583 gettext("Can't set -c flag twice\n"));
6584 exit(1);
6585 }
6586
6587 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL &&
6588 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) {
6589 fprintf(stderr, gettext(
6590 "Can't run -c, disabled by "
6591 "ZPOOL_SCRIPTS_ENABLED.\n"));
6592 exit(1);
6593 }
6594
6595 if ((getuid() <= 0 || geteuid() <= 0) &&
6596 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) {
6597 fprintf(stderr, gettext(
6598 "Can't run -c with root privileges "
6599 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n"));
6600 exit(1);
6601 }
6602 cmd = optarg;
6603 break;
6604 case 'g':
6605 cb.cb_name_flags |= VDEV_NAME_GUID;
6606 break;
6607 case 'L':
6608 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
6609 break;
6610 case 'P':
6611 cb.cb_name_flags |= VDEV_NAME_PATH;
6612 break;
6613 case 'v':
6614 cb.cb_verbose = B_TRUE;
6615 break;
6616 case 'x':
6617 cb.cb_explain = B_TRUE;
6618 break;
6619 case 'D':
6620 cb.cb_dedup_stats = B_TRUE;
6621 break;
6622 case 'T':
6623 get_timestamp_arg(*optarg);
6624 break;
6625 case '?':
6626 if (optopt == 'c') {
6627 print_zpool_script_list("status");
6628 exit(0);
6629 } else {
6630 fprintf(stderr,
6631 gettext("invalid option '%c'\n"), optopt);
6632 }
6633 usage(B_FALSE);
6634 }
6635 }
6636
6637 argc -= optind;
6638 argv += optind;
6639
6640 get_interval_count(&argc, argv, &interval, &count);
6641
6642 if (argc == 0)
6643 cb.cb_allpools = B_TRUE;
6644
6645 cb.cb_first = B_TRUE;
6646 cb.cb_print_status = B_TRUE;
6647
6648 for (;;) {
6649 if (timestamp_fmt != NODATE)
6650 print_timestamp(timestamp_fmt);
6651
6652 if (cmd != NULL)
6653 cb.vcdl = all_pools_for_each_vdev_run(argc, argv, cmd,
6654 NULL, NULL, 0, 0);
6655
6656 ret = for_each_pool(argc, argv, B_TRUE, NULL,
6657 status_callback, &cb);
6658
6659 if (cb.vcdl != NULL)
6660 free_vdev_cmd_data_list(cb.vcdl);
6661
6662 if (argc == 0 && cb.cb_count == 0)
6663 (void) fprintf(stderr, gettext("no pools available\n"));
6664 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
6665 (void) printf(gettext("all pools are healthy\n"));
6666
6667 if (ret != 0)
6668 return (ret);
6669
6670 if (interval == 0)
6671 break;
6672
6673 if (count != 0 && --count == 0)
6674 break;
6675
6676 (void) fsleep(interval);
6677 }
6678
6679 return (0);
6680 }
6681
6682 typedef struct upgrade_cbdata {
6683 int cb_first;
6684 int cb_argc;
6685 uint64_t cb_version;
6686 char **cb_argv;
6687 } upgrade_cbdata_t;
6688
6689 static int
6690 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
6691 {
6692 int zfs_version = (int)zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
6693 int *count = (int *)unsupp_fs;
6694
6695 if (zfs_version > ZPL_VERSION) {
6696 (void) printf(gettext("%s (v%d) is not supported by this "
6697 "implementation of ZFS.\n"),
6698 zfs_get_name(zhp), zfs_version);
6699 (*count)++;
6700 }
6701
6702 zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
6703
6704 zfs_close(zhp);
6705
6706 return (0);
6707 }
6708
6709 static int
6710 upgrade_version(zpool_handle_t *zhp, uint64_t version)
6711 {
6712 int ret;
6713 nvlist_t *config;
6714 uint64_t oldversion;
6715 int unsupp_fs = 0;
6716
6717 config = zpool_get_config(zhp, NULL);
6718 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6719 &oldversion) == 0);
6720
6721 assert(SPA_VERSION_IS_SUPPORTED(oldversion));
6722 assert(oldversion < version);
6723
6724 ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs);
6725 if (ret != 0)
6726 return (ret);
6727
6728 if (unsupp_fs) {
6729 (void) fprintf(stderr, gettext("Upgrade not performed due "
6730 "to %d unsupported filesystems (max v%d).\n"),
6731 unsupp_fs, (int)ZPL_VERSION);
6732 return (1);
6733 }
6734
6735 ret = zpool_upgrade(zhp, version);
6736 if (ret != 0)
6737 return (ret);
6738
6739 if (version >= SPA_VERSION_FEATURES) {
6740 (void) printf(gettext("Successfully upgraded "
6741 "'%s' from version %llu to feature flags.\n"),
6742 zpool_get_name(zhp), (u_longlong_t)oldversion);
6743 } else {
6744 (void) printf(gettext("Successfully upgraded "
6745 "'%s' from version %llu to version %llu.\n"),
6746 zpool_get_name(zhp), (u_longlong_t)oldversion,
6747 (u_longlong_t)version);
6748 }
6749
6750 return (0);
6751 }
6752
6753 static int
6754 upgrade_enable_all(zpool_handle_t *zhp, int *countp)
6755 {
6756 int i, ret, count;
6757 boolean_t firstff = B_TRUE;
6758 nvlist_t *enabled = zpool_get_features(zhp);
6759
6760 count = 0;
6761 for (i = 0; i < SPA_FEATURES; i++) {
6762 const char *fname = spa_feature_table[i].fi_uname;
6763 const char *fguid = spa_feature_table[i].fi_guid;
6764 if (!nvlist_exists(enabled, fguid)) {
6765 char *propname;
6766 verify(-1 != asprintf(&propname, "feature@%s", fname));
6767 ret = zpool_set_prop(zhp, propname,
6768 ZFS_FEATURE_ENABLED);
6769 if (ret != 0) {
6770 free(propname);
6771 return (ret);
6772 }
6773 count++;
6774
6775 if (firstff) {
6776 (void) printf(gettext("Enabled the "
6777 "following features on '%s':\n"),
6778 zpool_get_name(zhp));
6779 firstff = B_FALSE;
6780 }
6781 (void) printf(gettext(" %s\n"), fname);
6782 free(propname);
6783 }
6784 }
6785
6786 if (countp != NULL)
6787 *countp = count;
6788 return (0);
6789 }
6790
6791 static int
6792 upgrade_cb(zpool_handle_t *zhp, void *arg)
6793 {
6794 upgrade_cbdata_t *cbp = arg;
6795 nvlist_t *config;
6796 uint64_t version;
6797 boolean_t printnl = B_FALSE;
6798 int ret;
6799
6800 config = zpool_get_config(zhp, NULL);
6801 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6802 &version) == 0);
6803
6804 assert(SPA_VERSION_IS_SUPPORTED(version));
6805
6806 if (version < cbp->cb_version) {
6807 cbp->cb_first = B_FALSE;
6808 ret = upgrade_version(zhp, cbp->cb_version);
6809 if (ret != 0)
6810 return (ret);
6811 printnl = B_TRUE;
6812
6813 /*
6814 * If they did "zpool upgrade -a", then we could
6815 * be doing ioctls to different pools. We need
6816 * to log this history once to each pool, and bypass
6817 * the normal history logging that happens in main().
6818 */
6819 (void) zpool_log_history(g_zfs, history_str);
6820 log_history = B_FALSE;
6821 }
6822
6823 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
6824 int count;
6825 ret = upgrade_enable_all(zhp, &count);
6826 if (ret != 0)
6827 return (ret);
6828
6829 if (count > 0) {
6830 cbp->cb_first = B_FALSE;
6831 printnl = B_TRUE;
6832 }
6833 }
6834
6835 if (printnl) {
6836 (void) printf(gettext("\n"));
6837 }
6838
6839 return (0);
6840 }
6841
6842 static int
6843 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
6844 {
6845 upgrade_cbdata_t *cbp = arg;
6846 nvlist_t *config;
6847 uint64_t version;
6848
6849 config = zpool_get_config(zhp, NULL);
6850 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6851 &version) == 0);
6852
6853 assert(SPA_VERSION_IS_SUPPORTED(version));
6854
6855 if (version < SPA_VERSION_FEATURES) {
6856 if (cbp->cb_first) {
6857 (void) printf(gettext("The following pools are "
6858 "formatted with legacy version numbers and can\n"
6859 "be upgraded to use feature flags. After "
6860 "being upgraded, these pools\nwill no "
6861 "longer be accessible by software that does not "
6862 "support feature\nflags.\n\n"));
6863 (void) printf(gettext("VER POOL\n"));
6864 (void) printf(gettext("--- ------------\n"));
6865 cbp->cb_first = B_FALSE;
6866 }
6867
6868 (void) printf("%2llu %s\n", (u_longlong_t)version,
6869 zpool_get_name(zhp));
6870 }
6871
6872 return (0);
6873 }
6874
6875 static int
6876 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
6877 {
6878 upgrade_cbdata_t *cbp = arg;
6879 nvlist_t *config;
6880 uint64_t version;
6881
6882 config = zpool_get_config(zhp, NULL);
6883 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
6884 &version) == 0);
6885
6886 if (version >= SPA_VERSION_FEATURES) {
6887 int i;
6888 boolean_t poolfirst = B_TRUE;
6889 nvlist_t *enabled = zpool_get_features(zhp);
6890
6891 for (i = 0; i < SPA_FEATURES; i++) {
6892 const char *fguid = spa_feature_table[i].fi_guid;
6893 const char *fname = spa_feature_table[i].fi_uname;
6894 if (!nvlist_exists(enabled, fguid)) {
6895 if (cbp->cb_first) {
6896 (void) printf(gettext("\nSome "
6897 "supported features are not "
6898 "enabled on the following pools. "
6899 "Once a\nfeature is enabled the "
6900 "pool may become incompatible with "
6901 "software\nthat does not support "
6902 "the feature. See "
6903 "zpool-features(5) for "
6904 "details.\n\n"));
6905 (void) printf(gettext("POOL "
6906 "FEATURE\n"));
6907 (void) printf(gettext("------"
6908 "---------\n"));
6909 cbp->cb_first = B_FALSE;
6910 }
6911
6912 if (poolfirst) {
6913 (void) printf(gettext("%s\n"),
6914 zpool_get_name(zhp));
6915 poolfirst = B_FALSE;
6916 }
6917
6918 (void) printf(gettext(" %s\n"), fname);
6919 }
6920 /*
6921 * If they did "zpool upgrade -a", then we could
6922 * be doing ioctls to different pools. We need
6923 * to log this history once to each pool, and bypass
6924 * the normal history logging that happens in main().
6925 */
6926 (void) zpool_log_history(g_zfs, history_str);
6927 log_history = B_FALSE;
6928 }
6929 }
6930
6931 return (0);
6932 }
6933
6934 /* ARGSUSED */
6935 static int
6936 upgrade_one(zpool_handle_t *zhp, void *data)
6937 {
6938 boolean_t printnl = B_FALSE;
6939 upgrade_cbdata_t *cbp = data;
6940 uint64_t cur_version;
6941 int ret;
6942
6943 if (strcmp("log", zpool_get_name(zhp)) == 0) {
6944 (void) fprintf(stderr, gettext("'log' is now a reserved word\n"
6945 "Pool 'log' must be renamed using export and import"
6946 " to upgrade.\n"));
6947 return (1);
6948 }
6949
6950 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
6951 if (cur_version > cbp->cb_version) {
6952 (void) printf(gettext("Pool '%s' is already formatted "
6953 "using more current version '%llu'.\n\n"),
6954 zpool_get_name(zhp), (u_longlong_t)cur_version);
6955 return (0);
6956 }
6957
6958 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) {
6959 (void) printf(gettext("Pool '%s' is already formatted "
6960 "using version %llu.\n\n"), zpool_get_name(zhp),
6961 (u_longlong_t)cbp->cb_version);
6962 return (0);
6963 }
6964
6965 if (cur_version != cbp->cb_version) {
6966 printnl = B_TRUE;
6967 ret = upgrade_version(zhp, cbp->cb_version);
6968 if (ret != 0)
6969 return (ret);
6970 }
6971
6972 if (cbp->cb_version >= SPA_VERSION_FEATURES) {
6973 int count = 0;
6974 ret = upgrade_enable_all(zhp, &count);
6975 if (ret != 0)
6976 return (ret);
6977
6978 if (count != 0) {
6979 printnl = B_TRUE;
6980 } else if (cur_version == SPA_VERSION) {
6981 (void) printf(gettext("Pool '%s' already has all "
6982 "supported features enabled.\n"),
6983 zpool_get_name(zhp));
6984 }
6985 }
6986
6987 if (printnl) {
6988 (void) printf(gettext("\n"));
6989 }
6990
6991 return (0);
6992 }
6993
6994 /*
6995 * zpool upgrade
6996 * zpool upgrade -v
6997 * zpool upgrade [-V version] <-a | pool ...>
6998 *
6999 * With no arguments, display downrev'd ZFS pool available for upgrade.
7000 * Individual pools can be upgraded by specifying the pool, and '-a' will
7001 * upgrade all pools.
7002 */
7003 int
7004 zpool_do_upgrade(int argc, char **argv)
7005 {
7006 int c;
7007 upgrade_cbdata_t cb = { 0 };
7008 int ret = 0;
7009 boolean_t showversions = B_FALSE;
7010 boolean_t upgradeall = B_FALSE;
7011 char *end;
7012
7013
7014 /* check options */
7015 while ((c = getopt(argc, argv, ":avV:")) != -1) {
7016 switch (c) {
7017 case 'a':
7018 upgradeall = B_TRUE;
7019 break;
7020 case 'v':
7021 showversions = B_TRUE;
7022 break;
7023 case 'V':
7024 cb.cb_version = strtoll(optarg, &end, 10);
7025 if (*end != '\0' ||
7026 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
7027 (void) fprintf(stderr,
7028 gettext("invalid version '%s'\n"), optarg);
7029 usage(B_FALSE);
7030 }
7031 break;
7032 case ':':
7033 (void) fprintf(stderr, gettext("missing argument for "
7034 "'%c' option\n"), optopt);
7035 usage(B_FALSE);
7036 break;
7037 case '?':
7038 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7039 optopt);
7040 usage(B_FALSE);
7041 }
7042 }
7043
7044 cb.cb_argc = argc;
7045 cb.cb_argv = argv;
7046 argc -= optind;
7047 argv += optind;
7048
7049 if (cb.cb_version == 0) {
7050 cb.cb_version = SPA_VERSION;
7051 } else if (!upgradeall && argc == 0) {
7052 (void) fprintf(stderr, gettext("-V option is "
7053 "incompatible with other arguments\n"));
7054 usage(B_FALSE);
7055 }
7056
7057 if (showversions) {
7058 if (upgradeall || argc != 0) {
7059 (void) fprintf(stderr, gettext("-v option is "
7060 "incompatible with other arguments\n"));
7061 usage(B_FALSE);
7062 }
7063 } else if (upgradeall) {
7064 if (argc != 0) {
7065 (void) fprintf(stderr, gettext("-a option should not "
7066 "be used along with a pool name\n"));
7067 usage(B_FALSE);
7068 }
7069 }
7070
7071 (void) printf(gettext("This system supports ZFS pool feature "
7072 "flags.\n\n"));
7073 if (showversions) {
7074 int i;
7075
7076 (void) printf(gettext("The following features are "
7077 "supported:\n\n"));
7078 (void) printf(gettext("FEAT DESCRIPTION\n"));
7079 (void) printf("----------------------------------------------"
7080 "---------------\n");
7081 for (i = 0; i < SPA_FEATURES; i++) {
7082 zfeature_info_t *fi = &spa_feature_table[i];
7083 const char *ro =
7084 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
7085 " (read-only compatible)" : "";
7086
7087 (void) printf("%-37s%s\n", fi->fi_uname, ro);
7088 (void) printf(" %s\n", fi->fi_desc);
7089 }
7090 (void) printf("\n");
7091
7092 (void) printf(gettext("The following legacy versions are also "
7093 "supported:\n\n"));
7094 (void) printf(gettext("VER DESCRIPTION\n"));
7095 (void) printf("--- -----------------------------------------"
7096 "---------------\n");
7097 (void) printf(gettext(" 1 Initial ZFS version\n"));
7098 (void) printf(gettext(" 2 Ditto blocks "
7099 "(replicated metadata)\n"));
7100 (void) printf(gettext(" 3 Hot spares and double parity "
7101 "RAID-Z\n"));
7102 (void) printf(gettext(" 4 zpool history\n"));
7103 (void) printf(gettext(" 5 Compression using the gzip "
7104 "algorithm\n"));
7105 (void) printf(gettext(" 6 bootfs pool property\n"));
7106 (void) printf(gettext(" 7 Separate intent log devices\n"));
7107 (void) printf(gettext(" 8 Delegated administration\n"));
7108 (void) printf(gettext(" 9 refquota and refreservation "
7109 "properties\n"));
7110 (void) printf(gettext(" 10 Cache devices\n"));
7111 (void) printf(gettext(" 11 Improved scrub performance\n"));
7112 (void) printf(gettext(" 12 Snapshot properties\n"));
7113 (void) printf(gettext(" 13 snapused property\n"));
7114 (void) printf(gettext(" 14 passthrough-x aclinherit\n"));
7115 (void) printf(gettext(" 15 user/group space accounting\n"));
7116 (void) printf(gettext(" 16 stmf property support\n"));
7117 (void) printf(gettext(" 17 Triple-parity RAID-Z\n"));
7118 (void) printf(gettext(" 18 Snapshot user holds\n"));
7119 (void) printf(gettext(" 19 Log device removal\n"));
7120 (void) printf(gettext(" 20 Compression using zle "
7121 "(zero-length encoding)\n"));
7122 (void) printf(gettext(" 21 Deduplication\n"));
7123 (void) printf(gettext(" 22 Received properties\n"));
7124 (void) printf(gettext(" 23 Slim ZIL\n"));
7125 (void) printf(gettext(" 24 System attributes\n"));
7126 (void) printf(gettext(" 25 Improved scrub stats\n"));
7127 (void) printf(gettext(" 26 Improved snapshot deletion "
7128 "performance\n"));
7129 (void) printf(gettext(" 27 Improved snapshot creation "
7130 "performance\n"));
7131 (void) printf(gettext(" 28 Multiple vdev replacements\n"));
7132 (void) printf(gettext("\nFor more information on a particular "
7133 "version, including supported releases,\n"));
7134 (void) printf(gettext("see the ZFS Administration Guide.\n\n"));
7135 } else if (argc == 0 && upgradeall) {
7136 cb.cb_first = B_TRUE;
7137 ret = zpool_iter(g_zfs, upgrade_cb, &cb);
7138 if (ret == 0 && cb.cb_first) {
7139 if (cb.cb_version == SPA_VERSION) {
7140 (void) printf(gettext("All pools are already "
7141 "formatted using feature flags.\n\n"));
7142 (void) printf(gettext("Every feature flags "
7143 "pool already has all supported features "
7144 "enabled.\n"));
7145 } else {
7146 (void) printf(gettext("All pools are already "
7147 "formatted with version %llu or higher.\n"),
7148 (u_longlong_t)cb.cb_version);
7149 }
7150 }
7151 } else if (argc == 0) {
7152 cb.cb_first = B_TRUE;
7153 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
7154 assert(ret == 0);
7155
7156 if (cb.cb_first) {
7157 (void) printf(gettext("All pools are formatted "
7158 "using feature flags.\n\n"));
7159 } else {
7160 (void) printf(gettext("\nUse 'zpool upgrade -v' "
7161 "for a list of available legacy versions.\n"));
7162 }
7163
7164 cb.cb_first = B_TRUE;
7165 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb);
7166 assert(ret == 0);
7167
7168 if (cb.cb_first) {
7169 (void) printf(gettext("Every feature flags pool has "
7170 "all supported features enabled.\n"));
7171 } else {
7172 (void) printf(gettext("\n"));
7173 }
7174 } else {
7175 ret = for_each_pool(argc, argv, B_FALSE, NULL,
7176 upgrade_one, &cb);
7177 }
7178
7179 return (ret);
7180 }
7181
7182 typedef struct hist_cbdata {
7183 boolean_t first;
7184 boolean_t longfmt;
7185 boolean_t internal;
7186 } hist_cbdata_t;
7187
7188 /*
7189 * Print out the command history for a specific pool.
7190 */
7191 static int
7192 get_history_one(zpool_handle_t *zhp, void *data)
7193 {
7194 nvlist_t *nvhis;
7195 nvlist_t **records;
7196 uint_t numrecords;
7197 int ret, i;
7198 hist_cbdata_t *cb = (hist_cbdata_t *)data;
7199
7200 cb->first = B_FALSE;
7201
7202 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
7203
7204 if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
7205 return (ret);
7206
7207 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
7208 &records, &numrecords) == 0);
7209 for (i = 0; i < numrecords; i++) {
7210 nvlist_t *rec = records[i];
7211 char tbuf[30] = "";
7212
7213 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) {
7214 time_t tsec;
7215 struct tm t;
7216
7217 tsec = fnvlist_lookup_uint64(records[i],
7218 ZPOOL_HIST_TIME);
7219 (void) localtime_r(&tsec, &t);
7220 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
7221 }
7222
7223 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) {
7224 (void) printf("%s %s", tbuf,
7225 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD));
7226 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) {
7227 int ievent =
7228 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT);
7229 if (!cb->internal)
7230 continue;
7231 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) {
7232 (void) printf("%s unrecognized record:\n",
7233 tbuf);
7234 dump_nvlist(rec, 4);
7235 continue;
7236 }
7237 (void) printf("%s [internal %s txg:%lld] %s", tbuf,
7238 zfs_history_event_names[ievent],
7239 (longlong_t)fnvlist_lookup_uint64(
7240 rec, ZPOOL_HIST_TXG),
7241 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR));
7242 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) {
7243 if (!cb->internal)
7244 continue;
7245 (void) printf("%s [txg:%lld] %s", tbuf,
7246 (longlong_t)fnvlist_lookup_uint64(
7247 rec, ZPOOL_HIST_TXG),
7248 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME));
7249 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) {
7250 (void) printf(" %s (%llu)",
7251 fnvlist_lookup_string(rec,
7252 ZPOOL_HIST_DSNAME),
7253 (u_longlong_t)fnvlist_lookup_uint64(rec,
7254 ZPOOL_HIST_DSID));
7255 }
7256 (void) printf(" %s", fnvlist_lookup_string(rec,
7257 ZPOOL_HIST_INT_STR));
7258 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) {
7259 if (!cb->internal)
7260 continue;
7261 (void) printf("%s ioctl %s\n", tbuf,
7262 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL));
7263 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) {
7264 (void) printf(" input:\n");
7265 dump_nvlist(fnvlist_lookup_nvlist(rec,
7266 ZPOOL_HIST_INPUT_NVL), 8);
7267 }
7268 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) {
7269 (void) printf(" output:\n");
7270 dump_nvlist(fnvlist_lookup_nvlist(rec,
7271 ZPOOL_HIST_OUTPUT_NVL), 8);
7272 }
7273 } else {
7274 if (!cb->internal)
7275 continue;
7276 (void) printf("%s unrecognized record:\n", tbuf);
7277 dump_nvlist(rec, 4);
7278 }
7279
7280 if (!cb->longfmt) {
7281 (void) printf("\n");
7282 continue;
7283 }
7284 (void) printf(" [");
7285 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) {
7286 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO);
7287 struct passwd *pwd = getpwuid(who);
7288 (void) printf("user %d ", (int)who);
7289 if (pwd != NULL)
7290 (void) printf("(%s) ", pwd->pw_name);
7291 }
7292 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) {
7293 (void) printf("on %s",
7294 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST));
7295 }
7296 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) {
7297 (void) printf(":%s",
7298 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE));
7299 }
7300
7301 (void) printf("]");
7302 (void) printf("\n");
7303 }
7304 (void) printf("\n");
7305 nvlist_free(nvhis);
7306
7307 return (ret);
7308 }
7309
7310 /*
7311 * zpool history <pool>
7312 *
7313 * Displays the history of commands that modified pools.
7314 */
7315 int
7316 zpool_do_history(int argc, char **argv)
7317 {
7318 hist_cbdata_t cbdata = { 0 };
7319 int ret;
7320 int c;
7321
7322 cbdata.first = B_TRUE;
7323 /* check options */
7324 while ((c = getopt(argc, argv, "li")) != -1) {
7325 switch (c) {
7326 case 'l':
7327 cbdata.longfmt = B_TRUE;
7328 break;
7329 case 'i':
7330 cbdata.internal = B_TRUE;
7331 break;
7332 case '?':
7333 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7334 optopt);
7335 usage(B_FALSE);
7336 }
7337 }
7338 argc -= optind;
7339 argv += optind;
7340
7341 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
7342 &cbdata);
7343
7344 if (argc == 0 && cbdata.first == B_TRUE) {
7345 (void) fprintf(stderr, gettext("no pools available\n"));
7346 return (0);
7347 }
7348
7349 return (ret);
7350 }
7351
7352 typedef struct ev_opts {
7353 int verbose;
7354 int scripted;
7355 int follow;
7356 int clear;
7357 } ev_opts_t;
7358
7359 static void
7360 zpool_do_events_short(nvlist_t *nvl)
7361 {
7362 char ctime_str[26], str[32], *ptr;
7363 int64_t *tv;
7364 uint_t n;
7365
7366 verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0);
7367 memset(str, ' ', 32);
7368 (void) ctime_r((const time_t *)&tv[0], ctime_str);
7369 (void) strncpy(str, ctime_str+4, 6); /* 'Jun 30' */
7370 (void) strncpy(str+7, ctime_str+20, 4); /* '1993' */
7371 (void) strncpy(str+12, ctime_str+11, 8); /* '21:49:08' */
7372 (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */
7373 (void) printf(gettext("%s "), str);
7374
7375 verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0);
7376 (void) printf(gettext("%s\n"), ptr);
7377 }
7378
7379 static void
7380 zpool_do_events_nvprint(nvlist_t *nvl, int depth)
7381 {
7382 nvpair_t *nvp;
7383
7384 for (nvp = nvlist_next_nvpair(nvl, NULL);
7385 nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) {
7386
7387 data_type_t type = nvpair_type(nvp);
7388 const char *name = nvpair_name(nvp);
7389
7390 boolean_t b;
7391 uint8_t i8;
7392 uint16_t i16;
7393 uint32_t i32;
7394 uint64_t i64;
7395 char *str;
7396 nvlist_t *cnv;
7397
7398 printf(gettext("%*s%s = "), depth, "", name);
7399
7400 switch (type) {
7401 case DATA_TYPE_BOOLEAN:
7402 printf(gettext("%s"), "1");
7403 break;
7404
7405 case DATA_TYPE_BOOLEAN_VALUE:
7406 (void) nvpair_value_boolean_value(nvp, &b);
7407 printf(gettext("%s"), b ? "1" : "0");
7408 break;
7409
7410 case DATA_TYPE_BYTE:
7411 (void) nvpair_value_byte(nvp, &i8);
7412 printf(gettext("0x%x"), i8);
7413 break;
7414
7415 case DATA_TYPE_INT8:
7416 (void) nvpair_value_int8(nvp, (void *)&i8);
7417 printf(gettext("0x%x"), i8);
7418 break;
7419
7420 case DATA_TYPE_UINT8:
7421 (void) nvpair_value_uint8(nvp, &i8);
7422 printf(gettext("0x%x"), i8);
7423 break;
7424
7425 case DATA_TYPE_INT16:
7426 (void) nvpair_value_int16(nvp, (void *)&i16);
7427 printf(gettext("0x%x"), i16);
7428 break;
7429
7430 case DATA_TYPE_UINT16:
7431 (void) nvpair_value_uint16(nvp, &i16);
7432 printf(gettext("0x%x"), i16);
7433 break;
7434
7435 case DATA_TYPE_INT32:
7436 (void) nvpair_value_int32(nvp, (void *)&i32);
7437 printf(gettext("0x%x"), i32);
7438 break;
7439
7440 case DATA_TYPE_UINT32:
7441 (void) nvpair_value_uint32(nvp, &i32);
7442 printf(gettext("0x%x"), i32);
7443 break;
7444
7445 case DATA_TYPE_INT64:
7446 (void) nvpair_value_int64(nvp, (void *)&i64);
7447 printf(gettext("0x%llx"), (u_longlong_t)i64);
7448 break;
7449
7450 case DATA_TYPE_UINT64:
7451 (void) nvpair_value_uint64(nvp, &i64);
7452 /*
7453 * translate vdev state values to readable
7454 * strings to aide zpool events consumers
7455 */
7456 if (strcmp(name,
7457 FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 ||
7458 strcmp(name,
7459 FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) {
7460 printf(gettext("\"%s\" (0x%llx)"),
7461 zpool_state_to_name(i64, VDEV_AUX_NONE),
7462 (u_longlong_t)i64);
7463 } else {
7464 printf(gettext("0x%llx"), (u_longlong_t)i64);
7465 }
7466 break;
7467
7468 case DATA_TYPE_HRTIME:
7469 (void) nvpair_value_hrtime(nvp, (void *)&i64);
7470 printf(gettext("0x%llx"), (u_longlong_t)i64);
7471 break;
7472
7473 case DATA_TYPE_STRING:
7474 (void) nvpair_value_string(nvp, &str);
7475 printf(gettext("\"%s\""), str ? str : "<NULL>");
7476 break;
7477
7478 case DATA_TYPE_NVLIST:
7479 printf(gettext("(embedded nvlist)\n"));
7480 (void) nvpair_value_nvlist(nvp, &cnv);
7481 zpool_do_events_nvprint(cnv, depth + 8);
7482 printf(gettext("%*s(end %s)"), depth, "", name);
7483 break;
7484
7485 case DATA_TYPE_NVLIST_ARRAY: {
7486 nvlist_t **val;
7487 uint_t i, nelem;
7488
7489 (void) nvpair_value_nvlist_array(nvp, &val, &nelem);
7490 printf(gettext("(%d embedded nvlists)\n"), nelem);
7491 for (i = 0; i < nelem; i++) {
7492 printf(gettext("%*s%s[%d] = %s\n"),
7493 depth, "", name, i, "(embedded nvlist)");
7494 zpool_do_events_nvprint(val[i], depth + 8);
7495 printf(gettext("%*s(end %s[%i])\n"),
7496 depth, "", name, i);
7497 }
7498 printf(gettext("%*s(end %s)\n"), depth, "", name);
7499 }
7500 break;
7501
7502 case DATA_TYPE_INT8_ARRAY: {
7503 int8_t *val;
7504 uint_t i, nelem;
7505
7506 (void) nvpair_value_int8_array(nvp, &val, &nelem);
7507 for (i = 0; i < nelem; i++)
7508 printf(gettext("0x%x "), val[i]);
7509
7510 break;
7511 }
7512
7513 case DATA_TYPE_UINT8_ARRAY: {
7514 uint8_t *val;
7515 uint_t i, nelem;
7516
7517 (void) nvpair_value_uint8_array(nvp, &val, &nelem);
7518 for (i = 0; i < nelem; i++)
7519 printf(gettext("0x%x "), val[i]);
7520
7521 break;
7522 }
7523
7524 case DATA_TYPE_INT16_ARRAY: {
7525 int16_t *val;
7526 uint_t i, nelem;
7527
7528 (void) nvpair_value_int16_array(nvp, &val, &nelem);
7529 for (i = 0; i < nelem; i++)
7530 printf(gettext("0x%x "), val[i]);
7531
7532 break;
7533 }
7534
7535 case DATA_TYPE_UINT16_ARRAY: {
7536 uint16_t *val;
7537 uint_t i, nelem;
7538
7539 (void) nvpair_value_uint16_array(nvp, &val, &nelem);
7540 for (i = 0; i < nelem; i++)
7541 printf(gettext("0x%x "), val[i]);
7542
7543 break;
7544 }
7545
7546 case DATA_TYPE_INT32_ARRAY: {
7547 int32_t *val;
7548 uint_t i, nelem;
7549
7550 (void) nvpair_value_int32_array(nvp, &val, &nelem);
7551 for (i = 0; i < nelem; i++)
7552 printf(gettext("0x%x "), val[i]);
7553
7554 break;
7555 }
7556
7557 case DATA_TYPE_UINT32_ARRAY: {
7558 uint32_t *val;
7559 uint_t i, nelem;
7560
7561 (void) nvpair_value_uint32_array(nvp, &val, &nelem);
7562 for (i = 0; i < nelem; i++)
7563 printf(gettext("0x%x "), val[i]);
7564
7565 break;
7566 }
7567
7568 case DATA_TYPE_INT64_ARRAY: {
7569 int64_t *val;
7570 uint_t i, nelem;
7571
7572 (void) nvpair_value_int64_array(nvp, &val, &nelem);
7573 for (i = 0; i < nelem; i++)
7574 printf(gettext("0x%llx "),
7575 (u_longlong_t)val[i]);
7576
7577 break;
7578 }
7579
7580 case DATA_TYPE_UINT64_ARRAY: {
7581 uint64_t *val;
7582 uint_t i, nelem;
7583
7584 (void) nvpair_value_uint64_array(nvp, &val, &nelem);
7585 for (i = 0; i < nelem; i++)
7586 printf(gettext("0x%llx "),
7587 (u_longlong_t)val[i]);
7588
7589 break;
7590 }
7591
7592 case DATA_TYPE_STRING_ARRAY: {
7593 char **str;
7594 uint_t i, nelem;
7595
7596 (void) nvpair_value_string_array(nvp, &str, &nelem);
7597 for (i = 0; i < nelem; i++)
7598 printf(gettext("\"%s\" "),
7599 str[i] ? str[i] : "<NULL>");
7600
7601 break;
7602 }
7603
7604 case DATA_TYPE_BOOLEAN_ARRAY:
7605 case DATA_TYPE_BYTE_ARRAY:
7606 case DATA_TYPE_DOUBLE:
7607 case DATA_TYPE_UNKNOWN:
7608 printf(gettext("<unknown>"));
7609 break;
7610 }
7611
7612 printf(gettext("\n"));
7613 }
7614 }
7615
7616 static int
7617 zpool_do_events_next(ev_opts_t *opts)
7618 {
7619 nvlist_t *nvl;
7620 int zevent_fd, ret, dropped;
7621
7622 zevent_fd = open(ZFS_DEV, O_RDWR);
7623 VERIFY(zevent_fd >= 0);
7624
7625 if (!opts->scripted)
7626 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
7627
7628 while (1) {
7629 ret = zpool_events_next(g_zfs, &nvl, &dropped,
7630 (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd);
7631 if (ret || nvl == NULL)
7632 break;
7633
7634 if (dropped > 0)
7635 (void) printf(gettext("dropped %d events\n"), dropped);
7636
7637 zpool_do_events_short(nvl);
7638
7639 if (opts->verbose) {
7640 zpool_do_events_nvprint(nvl, 8);
7641 printf(gettext("\n"));
7642 }
7643 (void) fflush(stdout);
7644
7645 nvlist_free(nvl);
7646 }
7647
7648 VERIFY(0 == close(zevent_fd));
7649
7650 return (ret);
7651 }
7652
7653 static int
7654 zpool_do_events_clear(ev_opts_t *opts)
7655 {
7656 int count, ret;
7657
7658 ret = zpool_events_clear(g_zfs, &count);
7659 if (!ret)
7660 (void) printf(gettext("cleared %d events\n"), count);
7661
7662 return (ret);
7663 }
7664
7665 /*
7666 * zpool events [-vfc]
7667 *
7668 * Displays events logs by ZFS.
7669 */
7670 int
7671 zpool_do_events(int argc, char **argv)
7672 {
7673 ev_opts_t opts = { 0 };
7674 int ret;
7675 int c;
7676
7677 /* check options */
7678 while ((c = getopt(argc, argv, "vHfc")) != -1) {
7679 switch (c) {
7680 case 'v':
7681 opts.verbose = 1;
7682 break;
7683 case 'H':
7684 opts.scripted = 1;
7685 break;
7686 case 'f':
7687 opts.follow = 1;
7688 break;
7689 case 'c':
7690 opts.clear = 1;
7691 break;
7692 case '?':
7693 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7694 optopt);
7695 usage(B_FALSE);
7696 }
7697 }
7698 argc -= optind;
7699 argv += optind;
7700
7701 if (opts.clear)
7702 ret = zpool_do_events_clear(&opts);
7703 else
7704 ret = zpool_do_events_next(&opts);
7705
7706 return (ret);
7707 }
7708
7709 static int
7710 get_callback(zpool_handle_t *zhp, void *data)
7711 {
7712 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
7713 char value[MAXNAMELEN];
7714 zprop_source_t srctype;
7715 zprop_list_t *pl;
7716
7717 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
7718
7719 /*
7720 * Skip the special fake placeholder. This will also skip
7721 * over the name property when 'all' is specified.
7722 */
7723 if (pl->pl_prop == ZPOOL_PROP_NAME &&
7724 pl == cbp->cb_proplist)
7725 continue;
7726
7727 if (pl->pl_prop == ZPROP_INVAL &&
7728 (zpool_prop_feature(pl->pl_user_prop) ||
7729 zpool_prop_unsupported(pl->pl_user_prop))) {
7730 srctype = ZPROP_SRC_LOCAL;
7731
7732 if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
7733 value, sizeof (value)) == 0) {
7734 zprop_print_one_property(zpool_get_name(zhp),
7735 cbp, pl->pl_user_prop, value, srctype,
7736 NULL, NULL);
7737 }
7738 } else {
7739 if (zpool_get_prop(zhp, pl->pl_prop, value,
7740 sizeof (value), &srctype, cbp->cb_literal) != 0)
7741 continue;
7742
7743 zprop_print_one_property(zpool_get_name(zhp), cbp,
7744 zpool_prop_to_name(pl->pl_prop), value, srctype,
7745 NULL, NULL);
7746 }
7747 }
7748 return (0);
7749 }
7750
7751 /*
7752 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
7753 *
7754 * -H Scripted mode. Don't display headers, and separate properties
7755 * by a single tab.
7756 * -o List of columns to display. Defaults to
7757 * "name,property,value,source".
7758 * -p Display values in parsable (exact) format.
7759 *
7760 * Get properties of pools in the system. Output space statistics
7761 * for each one as well as other attributes.
7762 */
7763 int
7764 zpool_do_get(int argc, char **argv)
7765 {
7766 zprop_get_cbdata_t cb = { 0 };
7767 zprop_list_t fake_name = { 0 };
7768 int ret;
7769 int c, i;
7770 char *value;
7771
7772 cb.cb_first = B_TRUE;
7773
7774 /*
7775 * Set up default columns and sources.
7776 */
7777 cb.cb_sources = ZPROP_SRC_ALL;
7778 cb.cb_columns[0] = GET_COL_NAME;
7779 cb.cb_columns[1] = GET_COL_PROPERTY;
7780 cb.cb_columns[2] = GET_COL_VALUE;
7781 cb.cb_columns[3] = GET_COL_SOURCE;
7782 cb.cb_type = ZFS_TYPE_POOL;
7783
7784 /* check options */
7785 while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
7786 switch (c) {
7787 case 'p':
7788 cb.cb_literal = B_TRUE;
7789 break;
7790 case 'H':
7791 cb.cb_scripted = B_TRUE;
7792 break;
7793 case 'o':
7794 bzero(&cb.cb_columns, sizeof (cb.cb_columns));
7795 i = 0;
7796 while (*optarg != '\0') {
7797 static char *col_subopts[] =
7798 { "name", "property", "value", "source",
7799 "all", NULL };
7800
7801 if (i == ZFS_GET_NCOLS) {
7802 (void) fprintf(stderr, gettext("too "
7803 "many fields given to -o "
7804 "option\n"));
7805 usage(B_FALSE);
7806 }
7807
7808 switch (getsubopt(&optarg, col_subopts,
7809 &value)) {
7810 case 0:
7811 cb.cb_columns[i++] = GET_COL_NAME;
7812 break;
7813 case 1:
7814 cb.cb_columns[i++] = GET_COL_PROPERTY;
7815 break;
7816 case 2:
7817 cb.cb_columns[i++] = GET_COL_VALUE;
7818 break;
7819 case 3:
7820 cb.cb_columns[i++] = GET_COL_SOURCE;
7821 break;
7822 case 4:
7823 if (i > 0) {
7824 (void) fprintf(stderr,
7825 gettext("\"all\" conflicts "
7826 "with specific fields "
7827 "given to -o option\n"));
7828 usage(B_FALSE);
7829 }
7830 cb.cb_columns[0] = GET_COL_NAME;
7831 cb.cb_columns[1] = GET_COL_PROPERTY;
7832 cb.cb_columns[2] = GET_COL_VALUE;
7833 cb.cb_columns[3] = GET_COL_SOURCE;
7834 i = ZFS_GET_NCOLS;
7835 break;
7836 default:
7837 (void) fprintf(stderr,
7838 gettext("invalid column name "
7839 "'%s'\n"), value);
7840 usage(B_FALSE);
7841 }
7842 }
7843 break;
7844 case '?':
7845 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7846 optopt);
7847 usage(B_FALSE);
7848 }
7849 }
7850
7851 argc -= optind;
7852 argv += optind;
7853
7854 if (argc < 1) {
7855 (void) fprintf(stderr, gettext("missing property "
7856 "argument\n"));
7857 usage(B_FALSE);
7858 }
7859
7860 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
7861 ZFS_TYPE_POOL) != 0)
7862 usage(B_FALSE);
7863
7864 argc--;
7865 argv++;
7866
7867 if (cb.cb_proplist != NULL) {
7868 fake_name.pl_prop = ZPOOL_PROP_NAME;
7869 fake_name.pl_width = strlen(gettext("NAME"));
7870 fake_name.pl_next = cb.cb_proplist;
7871 cb.cb_proplist = &fake_name;
7872 }
7873
7874 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
7875 get_callback, &cb);
7876
7877 if (cb.cb_proplist == &fake_name)
7878 zprop_free_list(fake_name.pl_next);
7879 else
7880 zprop_free_list(cb.cb_proplist);
7881
7882 return (ret);
7883 }
7884
7885 typedef struct set_cbdata {
7886 char *cb_propname;
7887 char *cb_value;
7888 boolean_t cb_any_successful;
7889 } set_cbdata_t;
7890
7891 int
7892 set_callback(zpool_handle_t *zhp, void *data)
7893 {
7894 int error;
7895 set_cbdata_t *cb = (set_cbdata_t *)data;
7896
7897 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
7898
7899 if (!error)
7900 cb->cb_any_successful = B_TRUE;
7901
7902 return (error);
7903 }
7904
7905 int
7906 zpool_do_set(int argc, char **argv)
7907 {
7908 set_cbdata_t cb = { 0 };
7909 int error;
7910
7911 if (argc > 1 && argv[1][0] == '-') {
7912 (void) fprintf(stderr, gettext("invalid option '%c'\n"),
7913 argv[1][1]);
7914 usage(B_FALSE);
7915 }
7916
7917 if (argc < 2) {
7918 (void) fprintf(stderr, gettext("missing property=value "
7919 "argument\n"));
7920 usage(B_FALSE);
7921 }
7922
7923 if (argc < 3) {
7924 (void) fprintf(stderr, gettext("missing pool name\n"));
7925 usage(B_FALSE);
7926 }
7927
7928 if (argc > 3) {
7929 (void) fprintf(stderr, gettext("too many pool names\n"));
7930 usage(B_FALSE);
7931 }
7932
7933 cb.cb_propname = argv[1];
7934 cb.cb_value = strchr(cb.cb_propname, '=');
7935 if (cb.cb_value == NULL) {
7936 (void) fprintf(stderr, gettext("missing value in "
7937 "property=value argument\n"));
7938 usage(B_FALSE);
7939 }
7940
7941 *(cb.cb_value) = '\0';
7942 cb.cb_value++;
7943
7944 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
7945 set_callback, &cb);
7946
7947 return (error);
7948 }
7949
7950 static int
7951 find_command_idx(char *command, int *idx)
7952 {
7953 int i;
7954
7955 for (i = 0; i < NCOMMAND; i++) {
7956 if (command_table[i].name == NULL)
7957 continue;
7958
7959 if (strcmp(command, command_table[i].name) == 0) {
7960 *idx = i;
7961 return (0);
7962 }
7963 }
7964 return (1);
7965 }
7966
7967 int
7968 main(int argc, char **argv)
7969 {
7970 int ret = 0;
7971 int i = 0;
7972 char *cmdname;
7973
7974 (void) setlocale(LC_ALL, "");
7975 (void) textdomain(TEXT_DOMAIN);
7976 srand(time(NULL));
7977
7978 dprintf_setup(&argc, argv);
7979
7980 opterr = 0;
7981
7982 /*
7983 * Make sure the user has specified some command.
7984 */
7985 if (argc < 2) {
7986 (void) fprintf(stderr, gettext("missing command\n"));
7987 usage(B_FALSE);
7988 }
7989
7990 cmdname = argv[1];
7991
7992 /*
7993 * Special case '-?'
7994 */
7995 if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0)
7996 usage(B_TRUE);
7997
7998 if ((g_zfs = libzfs_init()) == NULL) {
7999 (void) fprintf(stderr, "%s", libzfs_error_init(errno));
8000 return (1);
8001 }
8002
8003 libzfs_print_on_error(g_zfs, B_TRUE);
8004
8005 zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
8006
8007 /*
8008 * Run the appropriate command.
8009 */
8010 if (find_command_idx(cmdname, &i) == 0) {
8011 current_command = &command_table[i];
8012 ret = command_table[i].func(argc - 1, argv + 1);
8013 } else if (strchr(cmdname, '=')) {
8014 verify(find_command_idx("set", &i) == 0);
8015 current_command = &command_table[i];
8016 ret = command_table[i].func(argc, argv);
8017 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
8018 /*
8019 * 'freeze' is a vile debugging abomination, so we treat
8020 * it as such.
8021 */
8022 char buf[16384];
8023 int fd = open(ZFS_DEV, O_RDWR);
8024 (void) strlcpy((void *)buf, argv[2], sizeof (buf));
8025 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
8026 } else {
8027 (void) fprintf(stderr, gettext("unrecognized "
8028 "command '%s'\n"), cmdname);
8029 usage(B_FALSE);
8030 ret = 1;
8031 }
8032
8033 if (ret == 0 && log_history)
8034 (void) zpool_log_history(g_zfs, history_str);
8035
8036 libzfs_fini(g_zfs);
8037
8038 /*
8039 * The 'ZFS_ABORT' environment variable causes us to dump core on exit
8040 * for the purposes of running ::findleaks.
8041 */
8042 if (getenv("ZFS_ABORT") != NULL) {
8043 (void) printf("dumping core by request\n");
8044 abort();
8045 }
8046
8047 return (ret);
8048 }