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