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, 2020 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 * Copyright (c) 2017, Intel Corporation. 33 * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com> 34 * Copyright (c) 2021, Colm Buckley <colm@tuatha.org> 35 * Copyright [2021] Hewlett Packard Enterprise Development LP 36 */ 37 38 #include <assert.h> 39 #include <ctype.h> 40 #include <dirent.h> 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <getopt.h> 44 #include <libgen.h> 45 #include <libintl.h> 46 #include <libuutil.h> 47 #include <locale.h> 48 #include <pthread.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <strings.h> 53 #include <time.h> 54 #include <unistd.h> 55 #include <pwd.h> 56 #include <zone.h> 57 #include <sys/wait.h> 58 #include <zfs_prop.h> 59 #include <sys/fs/zfs.h> 60 #include <sys/stat.h> 61 #include <sys/systeminfo.h> 62 #include <sys/fm/fs/zfs.h> 63 #include <sys/fm/util.h> 64 #include <sys/fm/protocol.h> 65 #include <sys/zfs_ioctl.h> 66 #include <sys/mount.h> 67 #include <sys/sysmacros.h> 68 69 #include <math.h> 70 71 #include <libzfs.h> 72 #include <libzutil.h> 73 74 #include "zpool_util.h" 75 #include "zfs_comutil.h" 76 #include "zfeature_common.h" 77 78 #include "statcommon.h" 79 80 libzfs_handle_t *g_zfs; 81 82 static int zpool_do_create(int, char **); 83 static int zpool_do_destroy(int, char **); 84 85 static int zpool_do_add(int, char **); 86 static int zpool_do_remove(int, char **); 87 static int zpool_do_labelclear(int, char **); 88 89 static int zpool_do_checkpoint(int, char **); 90 91 static int zpool_do_list(int, char **); 92 static int zpool_do_iostat(int, char **); 93 static int zpool_do_status(int, char **); 94 95 static int zpool_do_online(int, char **); 96 static int zpool_do_offline(int, char **); 97 static int zpool_do_clear(int, char **); 98 static int zpool_do_reopen(int, char **); 99 100 static int zpool_do_reguid(int, char **); 101 102 static int zpool_do_attach(int, char **); 103 static int zpool_do_detach(int, char **); 104 static int zpool_do_replace(int, char **); 105 static int zpool_do_split(int, char **); 106 107 static int zpool_do_initialize(int, char **); 108 static int zpool_do_scrub(int, char **); 109 static int zpool_do_resilver(int, char **); 110 static int zpool_do_trim(int, char **); 111 112 static int zpool_do_import(int, char **); 113 static int zpool_do_export(int, char **); 114 115 static int zpool_do_upgrade(int, char **); 116 117 static int zpool_do_history(int, char **); 118 static int zpool_do_events(int, char **); 119 120 static int zpool_do_get(int, char **); 121 static int zpool_do_set(int, char **); 122 123 static int zpool_do_sync(int, char **); 124 125 static int zpool_do_version(int, char **); 126 127 static int zpool_do_wait(int, char **); 128 129 static zpool_compat_status_t zpool_do_load_compat( 130 const char *, boolean_t *); 131 132 /* 133 * These libumem hooks provide a reasonable set of defaults for the allocator's 134 * debugging facilities. 135 */ 136 137 #ifdef DEBUG 138 const char * 139 _umem_debug_init(void) 140 { 141 return ("default,verbose"); /* $UMEM_DEBUG setting */ 142 } 143 144 const char * 145 _umem_logging_init(void) 146 { 147 return ("fail,contents"); /* $UMEM_LOGGING setting */ 148 } 149 #endif 150 151 typedef enum { 152 HELP_ADD, 153 HELP_ATTACH, 154 HELP_CLEAR, 155 HELP_CREATE, 156 HELP_CHECKPOINT, 157 HELP_DESTROY, 158 HELP_DETACH, 159 HELP_EXPORT, 160 HELP_HISTORY, 161 HELP_IMPORT, 162 HELP_IOSTAT, 163 HELP_LABELCLEAR, 164 HELP_LIST, 165 HELP_OFFLINE, 166 HELP_ONLINE, 167 HELP_REPLACE, 168 HELP_REMOVE, 169 HELP_INITIALIZE, 170 HELP_SCRUB, 171 HELP_RESILVER, 172 HELP_TRIM, 173 HELP_STATUS, 174 HELP_UPGRADE, 175 HELP_EVENTS, 176 HELP_GET, 177 HELP_SET, 178 HELP_SPLIT, 179 HELP_SYNC, 180 HELP_REGUID, 181 HELP_REOPEN, 182 HELP_VERSION, 183 HELP_WAIT 184 } zpool_help_t; 185 186 187 /* 188 * Flags for stats to display with "zpool iostats" 189 */ 190 enum iostat_type { 191 IOS_DEFAULT = 0, 192 IOS_LATENCY = 1, 193 IOS_QUEUES = 2, 194 IOS_L_HISTO = 3, 195 IOS_RQ_HISTO = 4, 196 IOS_COUNT, /* always last element */ 197 }; 198 199 /* iostat_type entries as bitmasks */ 200 #define IOS_DEFAULT_M (1ULL << IOS_DEFAULT) 201 #define IOS_LATENCY_M (1ULL << IOS_LATENCY) 202 #define IOS_QUEUES_M (1ULL << IOS_QUEUES) 203 #define IOS_L_HISTO_M (1ULL << IOS_L_HISTO) 204 #define IOS_RQ_HISTO_M (1ULL << IOS_RQ_HISTO) 205 206 /* Mask of all the histo bits */ 207 #define IOS_ANYHISTO_M (IOS_L_HISTO_M | IOS_RQ_HISTO_M) 208 209 /* 210 * Lookup table for iostat flags to nvlist names. Basically a list 211 * of all the nvlists a flag requires. Also specifies the order in 212 * which data gets printed in zpool iostat. 213 */ 214 static const char *vsx_type_to_nvlist[IOS_COUNT][13] = { 215 [IOS_L_HISTO] = { 216 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 217 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 218 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 219 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 220 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO, 221 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO, 222 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO, 223 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO, 224 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO, 225 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 226 NULL}, 227 [IOS_LATENCY] = { 228 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 229 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 230 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 231 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 232 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 233 NULL}, 234 [IOS_QUEUES] = { 235 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE, 236 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE, 237 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE, 238 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE, 239 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE, 240 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE, 241 NULL}, 242 [IOS_RQ_HISTO] = { 243 ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO, 244 ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO, 245 ZPOOL_CONFIG_VDEV_SYNC_IND_W_HISTO, 246 ZPOOL_CONFIG_VDEV_SYNC_AGG_W_HISTO, 247 ZPOOL_CONFIG_VDEV_ASYNC_IND_R_HISTO, 248 ZPOOL_CONFIG_VDEV_ASYNC_AGG_R_HISTO, 249 ZPOOL_CONFIG_VDEV_ASYNC_IND_W_HISTO, 250 ZPOOL_CONFIG_VDEV_ASYNC_AGG_W_HISTO, 251 ZPOOL_CONFIG_VDEV_IND_SCRUB_HISTO, 252 ZPOOL_CONFIG_VDEV_AGG_SCRUB_HISTO, 253 ZPOOL_CONFIG_VDEV_IND_TRIM_HISTO, 254 ZPOOL_CONFIG_VDEV_AGG_TRIM_HISTO, 255 NULL}, 256 }; 257 258 259 /* 260 * Given a cb->cb_flags with a histogram bit set, return the iostat_type. 261 * Right now, only one histo bit is ever set at one time, so we can 262 * just do a highbit64(a) 263 */ 264 #define IOS_HISTO_IDX(a) (highbit64(a & IOS_ANYHISTO_M) - 1) 265 266 typedef struct zpool_command { 267 const char *name; 268 int (*func)(int, char **); 269 zpool_help_t usage; 270 } zpool_command_t; 271 272 /* 273 * Master command table. Each ZFS command has a name, associated function, and 274 * usage message. The usage messages need to be internationalized, so we have 275 * to have a function to return the usage message based on a command index. 276 * 277 * These commands are organized according to how they are displayed in the usage 278 * message. An empty command (one with a NULL name) indicates an empty line in 279 * the generic usage message. 280 */ 281 static zpool_command_t command_table[] = { 282 { "version", zpool_do_version, HELP_VERSION }, 283 { NULL }, 284 { "create", zpool_do_create, HELP_CREATE }, 285 { "destroy", zpool_do_destroy, HELP_DESTROY }, 286 { NULL }, 287 { "add", zpool_do_add, HELP_ADD }, 288 { "remove", zpool_do_remove, HELP_REMOVE }, 289 { NULL }, 290 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, 291 { NULL }, 292 { "checkpoint", zpool_do_checkpoint, HELP_CHECKPOINT }, 293 { NULL }, 294 { "list", zpool_do_list, HELP_LIST }, 295 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 296 { "status", zpool_do_status, HELP_STATUS }, 297 { NULL }, 298 { "online", zpool_do_online, HELP_ONLINE }, 299 { "offline", zpool_do_offline, HELP_OFFLINE }, 300 { "clear", zpool_do_clear, HELP_CLEAR }, 301 { "reopen", zpool_do_reopen, HELP_REOPEN }, 302 { NULL }, 303 { "attach", zpool_do_attach, HELP_ATTACH }, 304 { "detach", zpool_do_detach, HELP_DETACH }, 305 { "replace", zpool_do_replace, HELP_REPLACE }, 306 { "split", zpool_do_split, HELP_SPLIT }, 307 { NULL }, 308 { "initialize", zpool_do_initialize, HELP_INITIALIZE }, 309 { "resilver", zpool_do_resilver, HELP_RESILVER }, 310 { "scrub", zpool_do_scrub, HELP_SCRUB }, 311 { "trim", zpool_do_trim, HELP_TRIM }, 312 { NULL }, 313 { "import", zpool_do_import, HELP_IMPORT }, 314 { "export", zpool_do_export, HELP_EXPORT }, 315 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 316 { "reguid", zpool_do_reguid, HELP_REGUID }, 317 { NULL }, 318 { "history", zpool_do_history, HELP_HISTORY }, 319 { "events", zpool_do_events, HELP_EVENTS }, 320 { NULL }, 321 { "get", zpool_do_get, HELP_GET }, 322 { "set", zpool_do_set, HELP_SET }, 323 { "sync", zpool_do_sync, HELP_SYNC }, 324 { NULL }, 325 { "wait", zpool_do_wait, HELP_WAIT }, 326 }; 327 328 #define NCOMMAND (ARRAY_SIZE(command_table)) 329 330 #define VDEV_ALLOC_CLASS_LOGS "logs" 331 332 static zpool_command_t *current_command; 333 static char history_str[HIS_MAX_RECORD_LEN]; 334 static boolean_t log_history = B_TRUE; 335 static uint_t timestamp_fmt = NODATE; 336 337 static const char * 338 get_usage(zpool_help_t idx) 339 { 340 switch (idx) { 341 case HELP_ADD: 342 return (gettext("\tadd [-fgLnP] [-o property=value] " 343 "<pool> <vdev> ...\n")); 344 case HELP_ATTACH: 345 return (gettext("\tattach [-fsw] [-o property=value] " 346 "<pool> <device> <new-device>\n")); 347 case HELP_CLEAR: 348 return (gettext("\tclear [-nF] <pool> [device]\n")); 349 case HELP_CREATE: 350 return (gettext("\tcreate [-fnd] [-o property=value] ... \n" 351 "\t [-O file-system-property=value] ... \n" 352 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 353 case HELP_CHECKPOINT: 354 return (gettext("\tcheckpoint [-d [-w]] <pool> ...\n")); 355 case HELP_DESTROY: 356 return (gettext("\tdestroy [-f] <pool>\n")); 357 case HELP_DETACH: 358 return (gettext("\tdetach <pool> <device>\n")); 359 case HELP_EXPORT: 360 return (gettext("\texport [-af] <pool> ...\n")); 361 case HELP_HISTORY: 362 return (gettext("\thistory [-il] [<pool>] ...\n")); 363 case HELP_IMPORT: 364 return (gettext("\timport [-d dir] [-D]\n" 365 "\timport [-o mntopts] [-o property=value] ... \n" 366 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] " 367 "[-R root] [-F [-n]] -a\n" 368 "\timport [-o mntopts] [-o property=value] ... \n" 369 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] " 370 "[-R root] [-F [-n]]\n" 371 "\t [--rewind-to-checkpoint] <pool | id> [newpool]\n")); 372 case HELP_IOSTAT: 373 return (gettext("\tiostat [[[-c [script1,script2,...]" 374 "[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n" 375 "\t [[pool ...]|[pool vdev ...]|[vdev ...]]" 376 " [[-n] interval [count]]\n")); 377 case HELP_LABELCLEAR: 378 return (gettext("\tlabelclear [-f] <vdev>\n")); 379 case HELP_LIST: 380 return (gettext("\tlist [-gHLpPv] [-o property[,...]] " 381 "[-T d|u] [pool] ... \n" 382 "\t [interval [count]]\n")); 383 case HELP_OFFLINE: 384 return (gettext("\toffline [-f] [-t] <pool> <device> ...\n")); 385 case HELP_ONLINE: 386 return (gettext("\tonline [-e] <pool> <device> ...\n")); 387 case HELP_REPLACE: 388 return (gettext("\treplace [-fsw] [-o property=value] " 389 "<pool> <device> [new-device]\n")); 390 case HELP_REMOVE: 391 return (gettext("\tremove [-npsw] <pool> <device> ...\n")); 392 case HELP_REOPEN: 393 return (gettext("\treopen [-n] <pool>\n")); 394 case HELP_INITIALIZE: 395 return (gettext("\tinitialize [-c | -s] [-w] <pool> " 396 "[<device> ...]\n")); 397 case HELP_SCRUB: 398 return (gettext("\tscrub [-s | -p] [-w] <pool> ...\n")); 399 case HELP_RESILVER: 400 return (gettext("\tresilver <pool> ...\n")); 401 case HELP_TRIM: 402 return (gettext("\ttrim [-dw] [-r <rate>] [-c | -s] <pool> " 403 "[<device> ...]\n")); 404 case HELP_STATUS: 405 return (gettext("\tstatus [-c [script1,script2,...]] " 406 "[-igLpPstvxD] [-T d|u] [pool] ... \n" 407 "\t [interval [count]]\n")); 408 case HELP_UPGRADE: 409 return (gettext("\tupgrade\n" 410 "\tupgrade -v\n" 411 "\tupgrade [-V version] <-a | pool ...>\n")); 412 case HELP_EVENTS: 413 return (gettext("\tevents [-vHf [pool] | -c]\n")); 414 case HELP_GET: 415 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " 416 "<\"all\" | property[,...]> <pool> ...\n")); 417 case HELP_SET: 418 return (gettext("\tset <property=value> <pool> \n")); 419 case HELP_SPLIT: 420 return (gettext("\tsplit [-gLnPl] [-R altroot] [-o mntopts]\n" 421 "\t [-o property=value] <pool> <newpool> " 422 "[<device> ...]\n")); 423 case HELP_REGUID: 424 return (gettext("\treguid <pool>\n")); 425 case HELP_SYNC: 426 return (gettext("\tsync [pool] ...\n")); 427 case HELP_VERSION: 428 return (gettext("\tversion\n")); 429 case HELP_WAIT: 430 return (gettext("\twait [-Hp] [-T d|u] [-t <activity>[,...]] " 431 "<pool> [interval]\n")); 432 } 433 434 abort(); 435 /* NOTREACHED */ 436 } 437 438 static void 439 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res) 440 { 441 uint_t children = 0; 442 nvlist_t **child; 443 uint_t i; 444 445 (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 446 &child, &children); 447 448 if (children == 0) { 449 char *path = zpool_vdev_name(g_zfs, zhp, nvroot, 450 VDEV_NAME_PATH); 451 452 if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 && 453 strcmp(path, VDEV_TYPE_HOLE) != 0) 454 fnvlist_add_boolean(res, path); 455 456 free(path); 457 return; 458 } 459 460 for (i = 0; i < children; i++) { 461 zpool_collect_leaves(zhp, child[i], res); 462 } 463 } 464 465 /* 466 * Callback routine that will print out a pool property value. 467 */ 468 static int 469 print_prop_cb(int prop, void *cb) 470 { 471 FILE *fp = cb; 472 473 (void) fprintf(fp, "\t%-19s ", zpool_prop_to_name(prop)); 474 475 if (zpool_prop_readonly(prop)) 476 (void) fprintf(fp, " NO "); 477 else 478 (void) fprintf(fp, " YES "); 479 480 if (zpool_prop_values(prop) == NULL) 481 (void) fprintf(fp, "-\n"); 482 else 483 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 484 485 return (ZPROP_CONT); 486 } 487 488 /* 489 * Display usage message. If we're inside a command, display only the usage for 490 * that command. Otherwise, iterate over the entire command table and display 491 * a complete usage message. 492 */ 493 static void 494 usage(boolean_t requested) 495 { 496 FILE *fp = requested ? stdout : stderr; 497 498 if (current_command == NULL) { 499 int i; 500 501 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 502 (void) fprintf(fp, 503 gettext("where 'command' is one of the following:\n\n")); 504 505 for (i = 0; i < NCOMMAND; i++) { 506 if (command_table[i].name == NULL) 507 (void) fprintf(fp, "\n"); 508 else 509 (void) fprintf(fp, "%s", 510 get_usage(command_table[i].usage)); 511 } 512 } else { 513 (void) fprintf(fp, gettext("usage:\n")); 514 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 515 } 516 517 if (current_command != NULL && 518 ((strcmp(current_command->name, "set") == 0) || 519 (strcmp(current_command->name, "get") == 0) || 520 (strcmp(current_command->name, "list") == 0))) { 521 522 (void) fprintf(fp, 523 gettext("\nthe following properties are supported:\n")); 524 525 (void) fprintf(fp, "\n\t%-19s %s %s\n\n", 526 "PROPERTY", "EDIT", "VALUES"); 527 528 /* Iterate over all properties */ 529 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 530 ZFS_TYPE_POOL); 531 532 (void) fprintf(fp, "\t%-19s ", "feature@..."); 533 (void) fprintf(fp, "YES disabled | enabled | active\n"); 534 535 (void) fprintf(fp, gettext("\nThe feature@ properties must be " 536 "appended with a feature name.\nSee zpool-features(7).\n")); 537 } 538 539 /* 540 * See comments at end of main(). 541 */ 542 if (getenv("ZFS_ABORT") != NULL) { 543 (void) printf("dumping core by request\n"); 544 abort(); 545 } 546 547 exit(requested ? 0 : 2); 548 } 549 550 /* 551 * zpool initialize [-c | -s] [-w] <pool> [<vdev> ...] 552 * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool 553 * if none specified. 554 * 555 * -c Cancel. Ends active initializing. 556 * -s Suspend. Initializing can then be restarted with no flags. 557 * -w Wait. Blocks until initializing has completed. 558 */ 559 int 560 zpool_do_initialize(int argc, char **argv) 561 { 562 int c; 563 char *poolname; 564 zpool_handle_t *zhp; 565 nvlist_t *vdevs; 566 int err = 0; 567 boolean_t wait = B_FALSE; 568 569 struct option long_options[] = { 570 {"cancel", no_argument, NULL, 'c'}, 571 {"suspend", no_argument, NULL, 's'}, 572 {"wait", no_argument, NULL, 'w'}, 573 {0, 0, 0, 0} 574 }; 575 576 pool_initialize_func_t cmd_type = POOL_INITIALIZE_START; 577 while ((c = getopt_long(argc, argv, "csw", long_options, NULL)) != -1) { 578 switch (c) { 579 case 'c': 580 if (cmd_type != POOL_INITIALIZE_START && 581 cmd_type != POOL_INITIALIZE_CANCEL) { 582 (void) fprintf(stderr, gettext("-c cannot be " 583 "combined with other options\n")); 584 usage(B_FALSE); 585 } 586 cmd_type = POOL_INITIALIZE_CANCEL; 587 break; 588 case 's': 589 if (cmd_type != POOL_INITIALIZE_START && 590 cmd_type != POOL_INITIALIZE_SUSPEND) { 591 (void) fprintf(stderr, gettext("-s cannot be " 592 "combined with other options\n")); 593 usage(B_FALSE); 594 } 595 cmd_type = POOL_INITIALIZE_SUSPEND; 596 break; 597 case 'w': 598 wait = B_TRUE; 599 break; 600 case '?': 601 if (optopt != 0) { 602 (void) fprintf(stderr, 603 gettext("invalid option '%c'\n"), optopt); 604 } else { 605 (void) fprintf(stderr, 606 gettext("invalid option '%s'\n"), 607 argv[optind - 1]); 608 } 609 usage(B_FALSE); 610 } 611 } 612 613 argc -= optind; 614 argv += optind; 615 616 if (argc < 1) { 617 (void) fprintf(stderr, gettext("missing pool name argument\n")); 618 usage(B_FALSE); 619 return (-1); 620 } 621 622 if (wait && (cmd_type != POOL_INITIALIZE_START)) { 623 (void) fprintf(stderr, gettext("-w cannot be used with -c or " 624 "-s\n")); 625 usage(B_FALSE); 626 } 627 628 poolname = argv[0]; 629 zhp = zpool_open(g_zfs, poolname); 630 if (zhp == NULL) 631 return (-1); 632 633 vdevs = fnvlist_alloc(); 634 if (argc == 1) { 635 /* no individual leaf vdevs specified, so add them all */ 636 nvlist_t *config = zpool_get_config(zhp, NULL); 637 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 638 ZPOOL_CONFIG_VDEV_TREE); 639 zpool_collect_leaves(zhp, nvroot, vdevs); 640 } else { 641 for (int i = 1; i < argc; i++) { 642 fnvlist_add_boolean(vdevs, argv[i]); 643 } 644 } 645 646 if (wait) 647 err = zpool_initialize_wait(zhp, cmd_type, vdevs); 648 else 649 err = zpool_initialize(zhp, cmd_type, vdevs); 650 651 fnvlist_free(vdevs); 652 zpool_close(zhp); 653 654 return (err); 655 } 656 657 /* 658 * print a pool vdev config for dry runs 659 */ 660 static void 661 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 662 const char *match, int name_flags) 663 { 664 nvlist_t **child; 665 uint_t c, children; 666 char *vname; 667 boolean_t printed = B_FALSE; 668 669 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 670 &child, &children) != 0) { 671 if (name != NULL) 672 (void) printf("\t%*s%s\n", indent, "", name); 673 return; 674 } 675 676 for (c = 0; c < children; c++) { 677 uint64_t is_log = B_FALSE, is_hole = B_FALSE; 678 char *class = ""; 679 680 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 681 &is_hole); 682 683 if (is_hole == B_TRUE) { 684 continue; 685 } 686 687 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 688 &is_log); 689 if (is_log) 690 class = VDEV_ALLOC_BIAS_LOG; 691 (void) nvlist_lookup_string(child[c], 692 ZPOOL_CONFIG_ALLOCATION_BIAS, &class); 693 if (strcmp(match, class) != 0) 694 continue; 695 696 if (!printed && name != NULL) { 697 (void) printf("\t%*s%s\n", indent, "", name); 698 printed = B_TRUE; 699 } 700 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags); 701 print_vdev_tree(zhp, vname, child[c], indent + 2, "", 702 name_flags); 703 free(vname); 704 } 705 } 706 707 /* 708 * Print the list of l2cache devices for dry runs. 709 */ 710 static void 711 print_cache_list(nvlist_t *nv, int indent) 712 { 713 nvlist_t **child; 714 uint_t c, children; 715 716 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 717 &child, &children) == 0 && children > 0) { 718 (void) printf("\t%*s%s\n", indent, "", "cache"); 719 } else { 720 return; 721 } 722 for (c = 0; c < children; c++) { 723 char *vname; 724 725 vname = zpool_vdev_name(g_zfs, NULL, child[c], 0); 726 (void) printf("\t%*s%s\n", indent + 2, "", vname); 727 free(vname); 728 } 729 } 730 731 /* 732 * Print the list of spares for dry runs. 733 */ 734 static void 735 print_spare_list(nvlist_t *nv, int indent) 736 { 737 nvlist_t **child; 738 uint_t c, children; 739 740 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 741 &child, &children) == 0 && children > 0) { 742 (void) printf("\t%*s%s\n", indent, "", "spares"); 743 } else { 744 return; 745 } 746 for (c = 0; c < children; c++) { 747 char *vname; 748 749 vname = zpool_vdev_name(g_zfs, NULL, child[c], 0); 750 (void) printf("\t%*s%s\n", indent + 2, "", vname); 751 free(vname); 752 } 753 } 754 755 static boolean_t 756 prop_list_contains_feature(nvlist_t *proplist) 757 { 758 nvpair_t *nvp; 759 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp; 760 nvp = nvlist_next_nvpair(proplist, nvp)) { 761 if (zpool_prop_feature(nvpair_name(nvp))) 762 return (B_TRUE); 763 } 764 return (B_FALSE); 765 } 766 767 /* 768 * Add a property pair (name, string-value) into a property nvlist. 769 */ 770 static int 771 add_prop_list(const char *propname, char *propval, nvlist_t **props, 772 boolean_t poolprop) 773 { 774 zpool_prop_t prop = ZPOOL_PROP_INVAL; 775 nvlist_t *proplist; 776 const char *normnm; 777 char *strval; 778 779 if (*props == NULL && 780 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 781 (void) fprintf(stderr, 782 gettext("internal error: out of memory\n")); 783 return (1); 784 } 785 786 proplist = *props; 787 788 if (poolprop) { 789 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); 790 const char *cname = 791 zpool_prop_to_name(ZPOOL_PROP_COMPATIBILITY); 792 793 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL && 794 !zpool_prop_feature(propname)) { 795 (void) fprintf(stderr, gettext("property '%s' is " 796 "not a valid pool property\n"), propname); 797 return (2); 798 } 799 800 /* 801 * feature@ properties and version should not be specified 802 * at the same time. 803 */ 804 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) && 805 nvlist_exists(proplist, vname)) || 806 (prop == ZPOOL_PROP_VERSION && 807 prop_list_contains_feature(proplist))) { 808 (void) fprintf(stderr, gettext("'feature@' and " 809 "'version' properties cannot be specified " 810 "together\n")); 811 return (2); 812 } 813 814 /* 815 * if version is specified, only "legacy" compatibility 816 * may be requested 817 */ 818 if ((prop == ZPOOL_PROP_COMPATIBILITY && 819 strcmp(propval, ZPOOL_COMPAT_LEGACY) != 0 && 820 nvlist_exists(proplist, vname)) || 821 (prop == ZPOOL_PROP_VERSION && 822 nvlist_exists(proplist, cname) && 823 strcmp(fnvlist_lookup_string(proplist, cname), 824 ZPOOL_COMPAT_LEGACY) != 0)) { 825 (void) fprintf(stderr, gettext("when 'version' is " 826 "specified, the 'compatibility' feature may only " 827 "be set to '" ZPOOL_COMPAT_LEGACY "'\n")); 828 return (2); 829 } 830 831 if (zpool_prop_feature(propname)) 832 normnm = propname; 833 else 834 normnm = zpool_prop_to_name(prop); 835 } else { 836 zfs_prop_t fsprop = zfs_name_to_prop(propname); 837 838 if (zfs_prop_valid_for_type(fsprop, ZFS_TYPE_FILESYSTEM, 839 B_FALSE)) { 840 normnm = zfs_prop_to_name(fsprop); 841 } else if (zfs_prop_user(propname) || 842 zfs_prop_userquota(propname)) { 843 normnm = propname; 844 } else { 845 (void) fprintf(stderr, gettext("property '%s' is " 846 "not a valid filesystem property\n"), propname); 847 return (2); 848 } 849 } 850 851 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 852 prop != ZPOOL_PROP_CACHEFILE) { 853 (void) fprintf(stderr, gettext("property '%s' " 854 "specified multiple times\n"), propname); 855 return (2); 856 } 857 858 if (nvlist_add_string(proplist, normnm, propval) != 0) { 859 (void) fprintf(stderr, gettext("internal " 860 "error: out of memory\n")); 861 return (1); 862 } 863 864 return (0); 865 } 866 867 /* 868 * Set a default property pair (name, string-value) in a property nvlist 869 */ 870 static int 871 add_prop_list_default(const char *propname, char *propval, nvlist_t **props, 872 boolean_t poolprop) 873 { 874 char *pval; 875 876 if (nvlist_lookup_string(*props, propname, &pval) == 0) 877 return (0); 878 879 return (add_prop_list(propname, propval, props, B_TRUE)); 880 } 881 882 /* 883 * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ... 884 * 885 * -f Force addition of devices, even if they appear in use 886 * -g Display guid for individual vdev name. 887 * -L Follow links when resolving vdev path name. 888 * -n Do not add the devices, but display the resulting layout if 889 * they were to be added. 890 * -o Set property=value. 891 * -P Display full path for vdev name. 892 * 893 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 894 * handled by make_root_vdev(), which constructs the nvlist needed to pass to 895 * libzfs. 896 */ 897 int 898 zpool_do_add(int argc, char **argv) 899 { 900 boolean_t force = B_FALSE; 901 boolean_t dryrun = B_FALSE; 902 int name_flags = 0; 903 int c; 904 nvlist_t *nvroot; 905 char *poolname; 906 int ret; 907 zpool_handle_t *zhp; 908 nvlist_t *config; 909 nvlist_t *props = NULL; 910 char *propval; 911 912 /* check options */ 913 while ((c = getopt(argc, argv, "fgLno:P")) != -1) { 914 switch (c) { 915 case 'f': 916 force = B_TRUE; 917 break; 918 case 'g': 919 name_flags |= VDEV_NAME_GUID; 920 break; 921 case 'L': 922 name_flags |= VDEV_NAME_FOLLOW_LINKS; 923 break; 924 case 'n': 925 dryrun = B_TRUE; 926 break; 927 case 'o': 928 if ((propval = strchr(optarg, '=')) == NULL) { 929 (void) fprintf(stderr, gettext("missing " 930 "'=' for -o option\n")); 931 usage(B_FALSE); 932 } 933 *propval = '\0'; 934 propval++; 935 936 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 937 (add_prop_list(optarg, propval, &props, B_TRUE))) 938 usage(B_FALSE); 939 break; 940 case 'P': 941 name_flags |= VDEV_NAME_PATH; 942 break; 943 case '?': 944 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 945 optopt); 946 usage(B_FALSE); 947 } 948 } 949 950 argc -= optind; 951 argv += optind; 952 953 /* get pool name and check number of arguments */ 954 if (argc < 1) { 955 (void) fprintf(stderr, gettext("missing pool name argument\n")); 956 usage(B_FALSE); 957 } 958 if (argc < 2) { 959 (void) fprintf(stderr, gettext("missing vdev specification\n")); 960 usage(B_FALSE); 961 } 962 963 poolname = argv[0]; 964 965 argc--; 966 argv++; 967 968 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 969 return (1); 970 971 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 972 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 973 poolname); 974 zpool_close(zhp); 975 return (1); 976 } 977 978 /* unless manually specified use "ashift" pool property (if set) */ 979 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 980 int intval; 981 zprop_source_t src; 982 char strval[ZPOOL_MAXPROPLEN]; 983 984 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 985 if (src != ZPROP_SRC_DEFAULT) { 986 (void) sprintf(strval, "%" PRId32, intval); 987 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 988 &props, B_TRUE) == 0); 989 } 990 } 991 992 /* pass off to make_root_vdev for processing */ 993 nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun, 994 argc, argv); 995 if (nvroot == NULL) { 996 zpool_close(zhp); 997 return (1); 998 } 999 1000 if (dryrun) { 1001 nvlist_t *poolnvroot; 1002 nvlist_t **l2child, **sparechild; 1003 uint_t l2children, sparechildren, c; 1004 char *vname; 1005 boolean_t hadcache = B_FALSE, hadspare = B_FALSE; 1006 1007 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1008 &poolnvroot) == 0); 1009 1010 (void) printf(gettext("would update '%s' to the following " 1011 "configuration:\n\n"), zpool_get_name(zhp)); 1012 1013 /* print original main pool and new tree */ 1014 print_vdev_tree(zhp, poolname, poolnvroot, 0, "", 1015 name_flags | VDEV_NAME_TYPE_ID); 1016 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags); 1017 1018 /* print other classes: 'dedup', 'special', and 'log' */ 1019 if (zfs_special_devs(poolnvroot, VDEV_ALLOC_BIAS_DEDUP)) { 1020 print_vdev_tree(zhp, "dedup", poolnvroot, 0, 1021 VDEV_ALLOC_BIAS_DEDUP, name_flags); 1022 print_vdev_tree(zhp, NULL, nvroot, 0, 1023 VDEV_ALLOC_BIAS_DEDUP, name_flags); 1024 } else if (zfs_special_devs(nvroot, VDEV_ALLOC_BIAS_DEDUP)) { 1025 print_vdev_tree(zhp, "dedup", nvroot, 0, 1026 VDEV_ALLOC_BIAS_DEDUP, name_flags); 1027 } 1028 1029 if (zfs_special_devs(poolnvroot, VDEV_ALLOC_BIAS_SPECIAL)) { 1030 print_vdev_tree(zhp, "special", poolnvroot, 0, 1031 VDEV_ALLOC_BIAS_SPECIAL, name_flags); 1032 print_vdev_tree(zhp, NULL, nvroot, 0, 1033 VDEV_ALLOC_BIAS_SPECIAL, name_flags); 1034 } else if (zfs_special_devs(nvroot, VDEV_ALLOC_BIAS_SPECIAL)) { 1035 print_vdev_tree(zhp, "special", nvroot, 0, 1036 VDEV_ALLOC_BIAS_SPECIAL, name_flags); 1037 } 1038 1039 if (num_logs(poolnvroot) > 0) { 1040 print_vdev_tree(zhp, "logs", poolnvroot, 0, 1041 VDEV_ALLOC_BIAS_LOG, name_flags); 1042 print_vdev_tree(zhp, NULL, nvroot, 0, 1043 VDEV_ALLOC_BIAS_LOG, name_flags); 1044 } else if (num_logs(nvroot) > 0) { 1045 print_vdev_tree(zhp, "logs", nvroot, 0, 1046 VDEV_ALLOC_BIAS_LOG, name_flags); 1047 } 1048 1049 /* Do the same for the caches */ 1050 if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_L2CACHE, 1051 &l2child, &l2children) == 0 && l2children) { 1052 hadcache = B_TRUE; 1053 (void) printf(gettext("\tcache\n")); 1054 for (c = 0; c < l2children; c++) { 1055 vname = zpool_vdev_name(g_zfs, NULL, 1056 l2child[c], name_flags); 1057 (void) printf("\t %s\n", vname); 1058 free(vname); 1059 } 1060 } 1061 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 1062 &l2child, &l2children) == 0 && l2children) { 1063 if (!hadcache) 1064 (void) printf(gettext("\tcache\n")); 1065 for (c = 0; c < l2children; c++) { 1066 vname = zpool_vdev_name(g_zfs, NULL, 1067 l2child[c], name_flags); 1068 (void) printf("\t %s\n", vname); 1069 free(vname); 1070 } 1071 } 1072 /* And finally the spares */ 1073 if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_SPARES, 1074 &sparechild, &sparechildren) == 0 && sparechildren > 0) { 1075 hadspare = B_TRUE; 1076 (void) printf(gettext("\tspares\n")); 1077 for (c = 0; c < sparechildren; c++) { 1078 vname = zpool_vdev_name(g_zfs, NULL, 1079 sparechild[c], name_flags); 1080 (void) printf("\t %s\n", vname); 1081 free(vname); 1082 } 1083 } 1084 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 1085 &sparechild, &sparechildren) == 0 && sparechildren > 0) { 1086 if (!hadspare) 1087 (void) printf(gettext("\tspares\n")); 1088 for (c = 0; c < sparechildren; c++) { 1089 vname = zpool_vdev_name(g_zfs, NULL, 1090 sparechild[c], name_flags); 1091 (void) printf("\t %s\n", vname); 1092 free(vname); 1093 } 1094 } 1095 1096 ret = 0; 1097 } else { 1098 ret = (zpool_add(zhp, nvroot) != 0); 1099 } 1100 1101 nvlist_free(props); 1102 nvlist_free(nvroot); 1103 zpool_close(zhp); 1104 1105 return (ret); 1106 } 1107 1108 /* 1109 * zpool remove [-npsw] <pool> <vdev> ... 1110 * 1111 * Removes the given vdev from the pool. 1112 */ 1113 int 1114 zpool_do_remove(int argc, char **argv) 1115 { 1116 char *poolname; 1117 int i, ret = 0; 1118 zpool_handle_t *zhp = NULL; 1119 boolean_t stop = B_FALSE; 1120 int c; 1121 boolean_t noop = B_FALSE; 1122 boolean_t parsable = B_FALSE; 1123 boolean_t wait = B_FALSE; 1124 1125 /* check options */ 1126 while ((c = getopt(argc, argv, "npsw")) != -1) { 1127 switch (c) { 1128 case 'n': 1129 noop = B_TRUE; 1130 break; 1131 case 'p': 1132 parsable = B_TRUE; 1133 break; 1134 case 's': 1135 stop = B_TRUE; 1136 break; 1137 case 'w': 1138 wait = B_TRUE; 1139 break; 1140 case '?': 1141 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1142 optopt); 1143 usage(B_FALSE); 1144 } 1145 } 1146 1147 argc -= optind; 1148 argv += optind; 1149 1150 /* get pool name and check number of arguments */ 1151 if (argc < 1) { 1152 (void) fprintf(stderr, gettext("missing pool name argument\n")); 1153 usage(B_FALSE); 1154 } 1155 1156 poolname = argv[0]; 1157 1158 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 1159 return (1); 1160 1161 if (stop && noop) { 1162 (void) fprintf(stderr, gettext("stop request ignored\n")); 1163 return (0); 1164 } 1165 1166 if (stop) { 1167 if (argc > 1) { 1168 (void) fprintf(stderr, gettext("too many arguments\n")); 1169 usage(B_FALSE); 1170 } 1171 if (zpool_vdev_remove_cancel(zhp) != 0) 1172 ret = 1; 1173 if (wait) { 1174 (void) fprintf(stderr, gettext("invalid option " 1175 "combination: -w cannot be used with -s\n")); 1176 usage(B_FALSE); 1177 } 1178 } else { 1179 if (argc < 2) { 1180 (void) fprintf(stderr, gettext("missing device\n")); 1181 usage(B_FALSE); 1182 } 1183 1184 for (i = 1; i < argc; i++) { 1185 if (noop) { 1186 uint64_t size; 1187 1188 if (zpool_vdev_indirect_size(zhp, argv[i], 1189 &size) != 0) { 1190 ret = 1; 1191 break; 1192 } 1193 if (parsable) { 1194 (void) printf("%s %llu\n", 1195 argv[i], (unsigned long long)size); 1196 } else { 1197 char valstr[32]; 1198 zfs_nicenum(size, valstr, 1199 sizeof (valstr)); 1200 (void) printf("Memory that will be " 1201 "used after removing %s: %s\n", 1202 argv[i], valstr); 1203 } 1204 } else { 1205 if (zpool_vdev_remove(zhp, argv[i]) != 0) 1206 ret = 1; 1207 } 1208 } 1209 1210 if (ret == 0 && wait) 1211 ret = zpool_wait(zhp, ZPOOL_WAIT_REMOVE); 1212 } 1213 zpool_close(zhp); 1214 1215 return (ret); 1216 } 1217 1218 /* 1219 * zpool labelclear [-f] <vdev> 1220 * 1221 * -f Force clearing the label for the vdevs which are members of 1222 * the exported or foreign pools. 1223 * 1224 * Verifies that the vdev is not active and zeros out the label information 1225 * on the device. 1226 */ 1227 int 1228 zpool_do_labelclear(int argc, char **argv) 1229 { 1230 char vdev[MAXPATHLEN]; 1231 char *name = NULL; 1232 struct stat st; 1233 int c, fd = -1, ret = 0; 1234 nvlist_t *config; 1235 pool_state_t state; 1236 boolean_t inuse = B_FALSE; 1237 boolean_t force = B_FALSE; 1238 1239 /* check options */ 1240 while ((c = getopt(argc, argv, "f")) != -1) { 1241 switch (c) { 1242 case 'f': 1243 force = B_TRUE; 1244 break; 1245 default: 1246 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1247 optopt); 1248 usage(B_FALSE); 1249 } 1250 } 1251 1252 argc -= optind; 1253 argv += optind; 1254 1255 /* get vdev name */ 1256 if (argc < 1) { 1257 (void) fprintf(stderr, gettext("missing vdev name\n")); 1258 usage(B_FALSE); 1259 } 1260 if (argc > 1) { 1261 (void) fprintf(stderr, gettext("too many arguments\n")); 1262 usage(B_FALSE); 1263 } 1264 1265 /* 1266 * Check if we were given absolute path and use it as is. 1267 * Otherwise if the provided vdev name doesn't point to a file, 1268 * try prepending expected disk paths and partition numbers. 1269 */ 1270 (void) strlcpy(vdev, argv[0], sizeof (vdev)); 1271 if (vdev[0] != '/' && stat(vdev, &st) != 0) { 1272 int error; 1273 1274 error = zfs_resolve_shortname(argv[0], vdev, MAXPATHLEN); 1275 if (error == 0 && zfs_dev_is_whole_disk(vdev)) { 1276 if (zfs_append_partition(vdev, MAXPATHLEN) == -1) 1277 error = ENOENT; 1278 } 1279 1280 if (error || (stat(vdev, &st) != 0)) { 1281 (void) fprintf(stderr, gettext( 1282 "failed to find device %s, try specifying absolute " 1283 "path instead\n"), argv[0]); 1284 return (1); 1285 } 1286 } 1287 1288 if ((fd = open(vdev, O_RDWR)) < 0) { 1289 (void) fprintf(stderr, gettext("failed to open %s: %s\n"), 1290 vdev, strerror(errno)); 1291 return (1); 1292 } 1293 1294 /* 1295 * Flush all dirty pages for the block device. This should not be 1296 * fatal when the device does not support BLKFLSBUF as would be the 1297 * case for a file vdev. 1298 */ 1299 if ((zfs_dev_flush(fd) != 0) && (errno != ENOTTY)) 1300 (void) fprintf(stderr, gettext("failed to invalidate " 1301 "cache for %s: %s\n"), vdev, strerror(errno)); 1302 1303 if (zpool_read_label(fd, &config, NULL) != 0) { 1304 (void) fprintf(stderr, 1305 gettext("failed to read label from %s\n"), vdev); 1306 ret = 1; 1307 goto errout; 1308 } 1309 nvlist_free(config); 1310 1311 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse); 1312 if (ret != 0) { 1313 (void) fprintf(stderr, 1314 gettext("failed to check state for %s\n"), vdev); 1315 ret = 1; 1316 goto errout; 1317 } 1318 1319 if (!inuse) 1320 goto wipe_label; 1321 1322 switch (state) { 1323 default: 1324 case POOL_STATE_ACTIVE: 1325 case POOL_STATE_SPARE: 1326 case POOL_STATE_L2CACHE: 1327 (void) fprintf(stderr, gettext( 1328 "%s is a member (%s) of pool \"%s\"\n"), 1329 vdev, zpool_pool_state_to_name(state), name); 1330 ret = 1; 1331 goto errout; 1332 1333 case POOL_STATE_EXPORTED: 1334 if (force) 1335 break; 1336 (void) fprintf(stderr, gettext( 1337 "use '-f' to override the following error:\n" 1338 "%s is a member of exported pool \"%s\"\n"), 1339 vdev, name); 1340 ret = 1; 1341 goto errout; 1342 1343 case POOL_STATE_POTENTIALLY_ACTIVE: 1344 if (force) 1345 break; 1346 (void) fprintf(stderr, gettext( 1347 "use '-f' to override the following error:\n" 1348 "%s is a member of potentially active pool \"%s\"\n"), 1349 vdev, name); 1350 ret = 1; 1351 goto errout; 1352 1353 case POOL_STATE_DESTROYED: 1354 /* inuse should never be set for a destroyed pool */ 1355 assert(0); 1356 break; 1357 } 1358 1359 wipe_label: 1360 ret = zpool_clear_label(fd); 1361 if (ret != 0) { 1362 (void) fprintf(stderr, 1363 gettext("failed to clear label for %s\n"), vdev); 1364 } 1365 1366 errout: 1367 free(name); 1368 (void) close(fd); 1369 1370 return (ret); 1371 } 1372 1373 /* 1374 * zpool create [-fnd] [-o property=value] ... 1375 * [-O file-system-property=value] ... 1376 * [-R root] [-m mountpoint] <pool> <dev> ... 1377 * 1378 * -f Force creation, even if devices appear in use 1379 * -n Do not create the pool, but display the resulting layout if it 1380 * were to be created. 1381 * -R Create a pool under an alternate root 1382 * -m Set default mountpoint for the root dataset. By default it's 1383 * '/<pool>' 1384 * -o Set property=value. 1385 * -o Set feature@feature=enabled|disabled. 1386 * -d Don't automatically enable all supported pool features 1387 * (individual features can be enabled with -o). 1388 * -O Set fsproperty=value in the pool's root file system 1389 * 1390 * Creates the named pool according to the given vdev specification. The 1391 * bulk of the vdev processing is done in make_root_vdev() in zpool_vdev.c. 1392 * Once we get the nvlist back from make_root_vdev(), we either print out the 1393 * contents (if '-n' was specified), or pass it to libzfs to do the creation. 1394 */ 1395 int 1396 zpool_do_create(int argc, char **argv) 1397 { 1398 boolean_t force = B_FALSE; 1399 boolean_t dryrun = B_FALSE; 1400 boolean_t enable_pool_features = B_TRUE; 1401 1402 int c; 1403 nvlist_t *nvroot = NULL; 1404 char *poolname; 1405 char *tname = NULL; 1406 int ret = 1; 1407 char *altroot = NULL; 1408 char *compat = NULL; 1409 char *mountpoint = NULL; 1410 nvlist_t *fsprops = NULL; 1411 nvlist_t *props = NULL; 1412 char *propval; 1413 1414 /* check options */ 1415 while ((c = getopt(argc, argv, ":fndR:m:o:O:t:")) != -1) { 1416 switch (c) { 1417 case 'f': 1418 force = B_TRUE; 1419 break; 1420 case 'n': 1421 dryrun = B_TRUE; 1422 break; 1423 case 'd': 1424 enable_pool_features = B_FALSE; 1425 break; 1426 case 'R': 1427 altroot = optarg; 1428 if (add_prop_list(zpool_prop_to_name( 1429 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1430 goto errout; 1431 if (add_prop_list_default(zpool_prop_to_name( 1432 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1433 goto errout; 1434 break; 1435 case 'm': 1436 /* Equivalent to -O mountpoint=optarg */ 1437 mountpoint = optarg; 1438 break; 1439 case 'o': 1440 if ((propval = strchr(optarg, '=')) == NULL) { 1441 (void) fprintf(stderr, gettext("missing " 1442 "'=' for -o option\n")); 1443 goto errout; 1444 } 1445 *propval = '\0'; 1446 propval++; 1447 1448 if (add_prop_list(optarg, propval, &props, B_TRUE)) 1449 goto errout; 1450 1451 /* 1452 * If the user is creating a pool that doesn't support 1453 * feature flags, don't enable any features. 1454 */ 1455 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) { 1456 char *end; 1457 u_longlong_t ver; 1458 1459 ver = strtoull(propval, &end, 10); 1460 if (*end == '\0' && 1461 ver < SPA_VERSION_FEATURES) { 1462 enable_pool_features = B_FALSE; 1463 } 1464 } 1465 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT) 1466 altroot = propval; 1467 if (zpool_name_to_prop(optarg) == 1468 ZPOOL_PROP_COMPATIBILITY) 1469 compat = propval; 1470 break; 1471 case 'O': 1472 if ((propval = strchr(optarg, '=')) == NULL) { 1473 (void) fprintf(stderr, gettext("missing " 1474 "'=' for -O option\n")); 1475 goto errout; 1476 } 1477 *propval = '\0'; 1478 propval++; 1479 1480 /* 1481 * Mountpoints are checked and then added later. 1482 * Uniquely among properties, they can be specified 1483 * more than once, to avoid conflict with -m. 1484 */ 1485 if (0 == strcmp(optarg, 1486 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) { 1487 mountpoint = propval; 1488 } else if (add_prop_list(optarg, propval, &fsprops, 1489 B_FALSE)) { 1490 goto errout; 1491 } 1492 break; 1493 case 't': 1494 /* 1495 * Sanity check temporary pool name. 1496 */ 1497 if (strchr(optarg, '/') != NULL) { 1498 (void) fprintf(stderr, gettext("cannot create " 1499 "'%s': invalid character '/' in temporary " 1500 "name\n"), optarg); 1501 (void) fprintf(stderr, gettext("use 'zfs " 1502 "create' to create a dataset\n")); 1503 goto errout; 1504 } 1505 1506 if (add_prop_list(zpool_prop_to_name( 1507 ZPOOL_PROP_TNAME), optarg, &props, B_TRUE)) 1508 goto errout; 1509 if (add_prop_list_default(zpool_prop_to_name( 1510 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1511 goto errout; 1512 tname = optarg; 1513 break; 1514 case ':': 1515 (void) fprintf(stderr, gettext("missing argument for " 1516 "'%c' option\n"), optopt); 1517 goto badusage; 1518 case '?': 1519 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1520 optopt); 1521 goto badusage; 1522 } 1523 } 1524 1525 argc -= optind; 1526 argv += optind; 1527 1528 /* get pool name and check number of arguments */ 1529 if (argc < 1) { 1530 (void) fprintf(stderr, gettext("missing pool name argument\n")); 1531 goto badusage; 1532 } 1533 if (argc < 2) { 1534 (void) fprintf(stderr, gettext("missing vdev specification\n")); 1535 goto badusage; 1536 } 1537 1538 poolname = argv[0]; 1539 1540 /* 1541 * As a special case, check for use of '/' in the name, and direct the 1542 * user to use 'zfs create' instead. 1543 */ 1544 if (strchr(poolname, '/') != NULL) { 1545 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 1546 "character '/' in pool name\n"), poolname); 1547 (void) fprintf(stderr, gettext("use 'zfs create' to " 1548 "create a dataset\n")); 1549 goto errout; 1550 } 1551 1552 /* pass off to make_root_vdev for bulk processing */ 1553 nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun, 1554 argc - 1, argv + 1); 1555 if (nvroot == NULL) 1556 goto errout; 1557 1558 /* make_root_vdev() allows 0 toplevel children if there are spares */ 1559 if (!zfs_allocatable_devs(nvroot)) { 1560 (void) fprintf(stderr, gettext("invalid vdev " 1561 "specification: at least one toplevel vdev must be " 1562 "specified\n")); 1563 goto errout; 1564 } 1565 1566 if (altroot != NULL && altroot[0] != '/') { 1567 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 1568 "must be an absolute path\n"), altroot); 1569 goto errout; 1570 } 1571 1572 /* 1573 * Check the validity of the mountpoint and direct the user to use the 1574 * '-m' mountpoint option if it looks like its in use. 1575 */ 1576 if (mountpoint == NULL || 1577 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 1578 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 1579 char buf[MAXPATHLEN]; 1580 DIR *dirp; 1581 1582 if (mountpoint && mountpoint[0] != '/') { 1583 (void) fprintf(stderr, gettext("invalid mountpoint " 1584 "'%s': must be an absolute path, 'legacy', or " 1585 "'none'\n"), mountpoint); 1586 goto errout; 1587 } 1588 1589 if (mountpoint == NULL) { 1590 if (altroot != NULL) 1591 (void) snprintf(buf, sizeof (buf), "%s/%s", 1592 altroot, poolname); 1593 else 1594 (void) snprintf(buf, sizeof (buf), "/%s", 1595 poolname); 1596 } else { 1597 if (altroot != NULL) 1598 (void) snprintf(buf, sizeof (buf), "%s%s", 1599 altroot, mountpoint); 1600 else 1601 (void) snprintf(buf, sizeof (buf), "%s", 1602 mountpoint); 1603 } 1604 1605 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 1606 (void) fprintf(stderr, gettext("mountpoint '%s' : " 1607 "%s\n"), buf, strerror(errno)); 1608 (void) fprintf(stderr, gettext("use '-m' " 1609 "option to provide a different default\n")); 1610 goto errout; 1611 } else if (dirp) { 1612 int count = 0; 1613 1614 while (count < 3 && readdir(dirp) != NULL) 1615 count++; 1616 (void) closedir(dirp); 1617 1618 if (count > 2) { 1619 (void) fprintf(stderr, gettext("mountpoint " 1620 "'%s' exists and is not empty\n"), buf); 1621 (void) fprintf(stderr, gettext("use '-m' " 1622 "option to provide a " 1623 "different default\n")); 1624 goto errout; 1625 } 1626 } 1627 } 1628 1629 /* 1630 * Now that the mountpoint's validity has been checked, ensure that 1631 * the property is set appropriately prior to creating the pool. 1632 */ 1633 if (mountpoint != NULL) { 1634 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1635 mountpoint, &fsprops, B_FALSE); 1636 if (ret != 0) 1637 goto errout; 1638 } 1639 1640 ret = 1; 1641 if (dryrun) { 1642 /* 1643 * For a dry run invocation, print out a basic message and run 1644 * through all the vdevs in the list and print out in an 1645 * appropriate hierarchy. 1646 */ 1647 (void) printf(gettext("would create '%s' with the " 1648 "following layout:\n\n"), poolname); 1649 1650 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0); 1651 print_vdev_tree(NULL, "dedup", nvroot, 0, 1652 VDEV_ALLOC_BIAS_DEDUP, 0); 1653 print_vdev_tree(NULL, "special", nvroot, 0, 1654 VDEV_ALLOC_BIAS_SPECIAL, 0); 1655 print_vdev_tree(NULL, "logs", nvroot, 0, 1656 VDEV_ALLOC_BIAS_LOG, 0); 1657 print_cache_list(nvroot, 0); 1658 print_spare_list(nvroot, 0); 1659 1660 ret = 0; 1661 } else { 1662 /* 1663 * Load in feature set. 1664 * Note: if compatibility property not given, we'll have 1665 * NULL, which means 'all features'. 1666 */ 1667 boolean_t requested_features[SPA_FEATURES]; 1668 if (zpool_do_load_compat(compat, requested_features) != 1669 ZPOOL_COMPATIBILITY_OK) 1670 goto errout; 1671 1672 /* 1673 * props contains list of features to enable. 1674 * For each feature: 1675 * - remove it if feature@name=disabled 1676 * - leave it there if feature@name=enabled 1677 * - add it if: 1678 * - enable_pool_features (ie: no '-d' or '-o version') 1679 * - it's supported by the kernel module 1680 * - it's in the requested feature set 1681 * - warn if it's enabled but not in compat 1682 */ 1683 for (spa_feature_t i = 0; i < SPA_FEATURES; i++) { 1684 char propname[MAXPATHLEN]; 1685 char *propval; 1686 zfeature_info_t *feat = &spa_feature_table[i]; 1687 1688 (void) snprintf(propname, sizeof (propname), 1689 "feature@%s", feat->fi_uname); 1690 1691 if (!nvlist_lookup_string(props, propname, &propval)) { 1692 if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0) 1693 (void) nvlist_remove_all(props, 1694 propname); 1695 if (strcmp(propval, 1696 ZFS_FEATURE_ENABLED) == 0 && 1697 !requested_features[i]) 1698 (void) fprintf(stderr, gettext( 1699 "Warning: feature \"%s\" enabled " 1700 "but is not in specified " 1701 "'compatibility' feature set.\n"), 1702 feat->fi_uname); 1703 } else if ( 1704 enable_pool_features && 1705 feat->fi_zfs_mod_supported && 1706 requested_features[i]) { 1707 ret = add_prop_list(propname, 1708 ZFS_FEATURE_ENABLED, &props, B_TRUE); 1709 if (ret != 0) 1710 goto errout; 1711 } 1712 } 1713 1714 ret = 1; 1715 if (zpool_create(g_zfs, poolname, 1716 nvroot, props, fsprops) == 0) { 1717 zfs_handle_t *pool = zfs_open(g_zfs, 1718 tname ? tname : poolname, ZFS_TYPE_FILESYSTEM); 1719 if (pool != NULL) { 1720 if (zfs_mount(pool, NULL, 0) == 0) { 1721 ret = zfs_shareall(pool); 1722 zfs_commit_all_shares(); 1723 } 1724 zfs_close(pool); 1725 } 1726 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 1727 (void) fprintf(stderr, gettext("pool name may have " 1728 "been omitted\n")); 1729 } 1730 } 1731 1732 errout: 1733 nvlist_free(nvroot); 1734 nvlist_free(fsprops); 1735 nvlist_free(props); 1736 return (ret); 1737 badusage: 1738 nvlist_free(fsprops); 1739 nvlist_free(props); 1740 usage(B_FALSE); 1741 return (2); 1742 } 1743 1744 /* 1745 * zpool destroy <pool> 1746 * 1747 * -f Forcefully unmount any datasets 1748 * 1749 * Destroy the given pool. Automatically unmounts any datasets in the pool. 1750 */ 1751 int 1752 zpool_do_destroy(int argc, char **argv) 1753 { 1754 boolean_t force = B_FALSE; 1755 int c; 1756 char *pool; 1757 zpool_handle_t *zhp; 1758 int ret; 1759 1760 /* check options */ 1761 while ((c = getopt(argc, argv, "f")) != -1) { 1762 switch (c) { 1763 case 'f': 1764 force = B_TRUE; 1765 break; 1766 case '?': 1767 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1768 optopt); 1769 usage(B_FALSE); 1770 } 1771 } 1772 1773 argc -= optind; 1774 argv += optind; 1775 1776 /* check arguments */ 1777 if (argc < 1) { 1778 (void) fprintf(stderr, gettext("missing pool argument\n")); 1779 usage(B_FALSE); 1780 } 1781 if (argc > 1) { 1782 (void) fprintf(stderr, gettext("too many arguments\n")); 1783 usage(B_FALSE); 1784 } 1785 1786 pool = argv[0]; 1787 1788 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 1789 /* 1790 * As a special case, check for use of '/' in the name, and 1791 * direct the user to use 'zfs destroy' instead. 1792 */ 1793 if (strchr(pool, '/') != NULL) 1794 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 1795 "destroy a dataset\n")); 1796 return (1); 1797 } 1798 1799 if (zpool_disable_datasets(zhp, force) != 0) { 1800 (void) fprintf(stderr, gettext("could not destroy '%s': " 1801 "could not unmount datasets\n"), zpool_get_name(zhp)); 1802 zpool_close(zhp); 1803 return (1); 1804 } 1805 1806 /* The history must be logged as part of the export */ 1807 log_history = B_FALSE; 1808 1809 ret = (zpool_destroy(zhp, history_str) != 0); 1810 1811 zpool_close(zhp); 1812 1813 return (ret); 1814 } 1815 1816 typedef struct export_cbdata { 1817 boolean_t force; 1818 boolean_t hardforce; 1819 } export_cbdata_t; 1820 1821 /* 1822 * Export one pool 1823 */ 1824 static int 1825 zpool_export_one(zpool_handle_t *zhp, void *data) 1826 { 1827 export_cbdata_t *cb = data; 1828 1829 if (zpool_disable_datasets(zhp, cb->force) != 0) 1830 return (1); 1831 1832 /* The history must be logged as part of the export */ 1833 log_history = B_FALSE; 1834 1835 if (cb->hardforce) { 1836 if (zpool_export_force(zhp, history_str) != 0) 1837 return (1); 1838 } else if (zpool_export(zhp, cb->force, history_str) != 0) { 1839 return (1); 1840 } 1841 1842 return (0); 1843 } 1844 1845 /* 1846 * zpool export [-f] <pool> ... 1847 * 1848 * -a Export all pools 1849 * -f Forcefully unmount datasets 1850 * 1851 * Export the given pools. By default, the command will attempt to cleanly 1852 * unmount any active datasets within the pool. If the '-f' flag is specified, 1853 * then the datasets will be forcefully unmounted. 1854 */ 1855 int 1856 zpool_do_export(int argc, char **argv) 1857 { 1858 export_cbdata_t cb; 1859 boolean_t do_all = B_FALSE; 1860 boolean_t force = B_FALSE; 1861 boolean_t hardforce = B_FALSE; 1862 int c, ret; 1863 1864 /* check options */ 1865 while ((c = getopt(argc, argv, "afF")) != -1) { 1866 switch (c) { 1867 case 'a': 1868 do_all = B_TRUE; 1869 break; 1870 case 'f': 1871 force = B_TRUE; 1872 break; 1873 case 'F': 1874 hardforce = B_TRUE; 1875 break; 1876 case '?': 1877 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1878 optopt); 1879 usage(B_FALSE); 1880 } 1881 } 1882 1883 cb.force = force; 1884 cb.hardforce = hardforce; 1885 argc -= optind; 1886 argv += optind; 1887 1888 if (do_all) { 1889 if (argc != 0) { 1890 (void) fprintf(stderr, gettext("too many arguments\n")); 1891 usage(B_FALSE); 1892 } 1893 1894 return (for_each_pool(argc, argv, B_TRUE, NULL, 1895 B_FALSE, zpool_export_one, &cb)); 1896 } 1897 1898 /* check arguments */ 1899 if (argc < 1) { 1900 (void) fprintf(stderr, gettext("missing pool argument\n")); 1901 usage(B_FALSE); 1902 } 1903 1904 ret = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, zpool_export_one, 1905 &cb); 1906 1907 return (ret); 1908 } 1909 1910 /* 1911 * Given a vdev configuration, determine the maximum width needed for the device 1912 * name column. 1913 */ 1914 static int 1915 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max, 1916 int name_flags) 1917 { 1918 char *name; 1919 nvlist_t **child; 1920 uint_t c, children; 1921 int ret; 1922 1923 name = zpool_vdev_name(g_zfs, zhp, nv, name_flags); 1924 if (strlen(name) + depth > max) 1925 max = strlen(name) + depth; 1926 1927 free(name); 1928 1929 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1930 &child, &children) == 0) { 1931 for (c = 0; c < children; c++) 1932 if ((ret = max_width(zhp, child[c], depth + 2, 1933 max, name_flags)) > max) 1934 max = ret; 1935 } 1936 1937 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1938 &child, &children) == 0) { 1939 for (c = 0; c < children; c++) 1940 if ((ret = max_width(zhp, child[c], depth + 2, 1941 max, name_flags)) > max) 1942 max = ret; 1943 } 1944 1945 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1946 &child, &children) == 0) { 1947 for (c = 0; c < children; c++) 1948 if ((ret = max_width(zhp, child[c], depth + 2, 1949 max, name_flags)) > max) 1950 max = ret; 1951 } 1952 1953 return (max); 1954 } 1955 1956 typedef struct spare_cbdata { 1957 uint64_t cb_guid; 1958 zpool_handle_t *cb_zhp; 1959 } spare_cbdata_t; 1960 1961 static boolean_t 1962 find_vdev(nvlist_t *nv, uint64_t search) 1963 { 1964 uint64_t guid; 1965 nvlist_t **child; 1966 uint_t c, children; 1967 1968 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 1969 search == guid) 1970 return (B_TRUE); 1971 1972 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1973 &child, &children) == 0) { 1974 for (c = 0; c < children; c++) 1975 if (find_vdev(child[c], search)) 1976 return (B_TRUE); 1977 } 1978 1979 return (B_FALSE); 1980 } 1981 1982 static int 1983 find_spare(zpool_handle_t *zhp, void *data) 1984 { 1985 spare_cbdata_t *cbp = data; 1986 nvlist_t *config, *nvroot; 1987 1988 config = zpool_get_config(zhp, NULL); 1989 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1990 &nvroot) == 0); 1991 1992 if (find_vdev(nvroot, cbp->cb_guid)) { 1993 cbp->cb_zhp = zhp; 1994 return (1); 1995 } 1996 1997 zpool_close(zhp); 1998 return (0); 1999 } 2000 2001 typedef struct status_cbdata { 2002 int cb_count; 2003 int cb_name_flags; 2004 int cb_namewidth; 2005 boolean_t cb_allpools; 2006 boolean_t cb_verbose; 2007 boolean_t cb_literal; 2008 boolean_t cb_explain; 2009 boolean_t cb_first; 2010 boolean_t cb_dedup_stats; 2011 boolean_t cb_print_status; 2012 boolean_t cb_print_slow_ios; 2013 boolean_t cb_print_vdev_init; 2014 boolean_t cb_print_vdev_trim; 2015 vdev_cmd_data_list_t *vcdl; 2016 } status_cbdata_t; 2017 2018 /* Return 1 if string is NULL, empty, or whitespace; return 0 otherwise. */ 2019 static int 2020 is_blank_str(char *str) 2021 { 2022 while (str != NULL && *str != '\0') { 2023 if (!isblank(*str)) 2024 return (0); 2025 str++; 2026 } 2027 return (1); 2028 } 2029 2030 /* Print command output lines for specific vdev in a specific pool */ 2031 static void 2032 zpool_print_cmd(vdev_cmd_data_list_t *vcdl, const char *pool, char *path) 2033 { 2034 vdev_cmd_data_t *data; 2035 int i, j; 2036 char *val; 2037 2038 for (i = 0; i < vcdl->count; i++) { 2039 if ((strcmp(vcdl->data[i].path, path) != 0) || 2040 (strcmp(vcdl->data[i].pool, pool) != 0)) { 2041 /* Not the vdev we're looking for */ 2042 continue; 2043 } 2044 2045 data = &vcdl->data[i]; 2046 /* Print out all the output values for this vdev */ 2047 for (j = 0; j < vcdl->uniq_cols_cnt; j++) { 2048 val = NULL; 2049 /* Does this vdev have values for this column? */ 2050 for (int k = 0; k < data->cols_cnt; k++) { 2051 if (strcmp(data->cols[k], 2052 vcdl->uniq_cols[j]) == 0) { 2053 /* yes it does, record the value */ 2054 val = data->lines[k]; 2055 break; 2056 } 2057 } 2058 /* 2059 * Mark empty values with dashes to make output 2060 * awk-able. 2061 */ 2062 if (val == NULL || is_blank_str(val)) 2063 val = "-"; 2064 2065 printf("%*s", vcdl->uniq_cols_width[j], val); 2066 if (j < vcdl->uniq_cols_cnt - 1) 2067 printf(" "); 2068 } 2069 2070 /* Print out any values that aren't in a column at the end */ 2071 for (j = data->cols_cnt; j < data->lines_cnt; j++) { 2072 /* Did we have any columns? If so print a spacer. */ 2073 if (vcdl->uniq_cols_cnt > 0) 2074 printf(" "); 2075 2076 val = data->lines[j]; 2077 printf("%s", val ? val : ""); 2078 } 2079 break; 2080 } 2081 } 2082 2083 /* 2084 * Print vdev initialization status for leaves 2085 */ 2086 static void 2087 print_status_initialize(vdev_stat_t *vs, boolean_t verbose) 2088 { 2089 if (verbose) { 2090 if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE || 2091 vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED || 2092 vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) && 2093 !vs->vs_scan_removing) { 2094 char zbuf[1024]; 2095 char tbuf[256]; 2096 struct tm zaction_ts; 2097 2098 time_t t = vs->vs_initialize_action_time; 2099 int initialize_pct = 100; 2100 if (vs->vs_initialize_state != 2101 VDEV_INITIALIZE_COMPLETE) { 2102 initialize_pct = (vs->vs_initialize_bytes_done * 2103 100 / (vs->vs_initialize_bytes_est + 1)); 2104 } 2105 2106 (void) localtime_r(&t, &zaction_ts); 2107 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts); 2108 2109 switch (vs->vs_initialize_state) { 2110 case VDEV_INITIALIZE_SUSPENDED: 2111 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2112 gettext("suspended, started at"), tbuf); 2113 break; 2114 case VDEV_INITIALIZE_ACTIVE: 2115 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2116 gettext("started at"), tbuf); 2117 break; 2118 case VDEV_INITIALIZE_COMPLETE: 2119 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2120 gettext("completed at"), tbuf); 2121 break; 2122 } 2123 2124 (void) printf(gettext(" (%d%% initialized%s)"), 2125 initialize_pct, zbuf); 2126 } else { 2127 (void) printf(gettext(" (uninitialized)")); 2128 } 2129 } else if (vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) { 2130 (void) printf(gettext(" (initializing)")); 2131 } 2132 } 2133 2134 /* 2135 * Print vdev TRIM status for leaves 2136 */ 2137 static void 2138 print_status_trim(vdev_stat_t *vs, boolean_t verbose) 2139 { 2140 if (verbose) { 2141 if ((vs->vs_trim_state == VDEV_TRIM_ACTIVE || 2142 vs->vs_trim_state == VDEV_TRIM_SUSPENDED || 2143 vs->vs_trim_state == VDEV_TRIM_COMPLETE) && 2144 !vs->vs_scan_removing) { 2145 char zbuf[1024]; 2146 char tbuf[256]; 2147 struct tm zaction_ts; 2148 2149 time_t t = vs->vs_trim_action_time; 2150 int trim_pct = 100; 2151 if (vs->vs_trim_state != VDEV_TRIM_COMPLETE) { 2152 trim_pct = (vs->vs_trim_bytes_done * 2153 100 / (vs->vs_trim_bytes_est + 1)); 2154 } 2155 2156 (void) localtime_r(&t, &zaction_ts); 2157 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts); 2158 2159 switch (vs->vs_trim_state) { 2160 case VDEV_TRIM_SUSPENDED: 2161 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2162 gettext("suspended, started at"), tbuf); 2163 break; 2164 case VDEV_TRIM_ACTIVE: 2165 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2166 gettext("started at"), tbuf); 2167 break; 2168 case VDEV_TRIM_COMPLETE: 2169 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 2170 gettext("completed at"), tbuf); 2171 break; 2172 } 2173 2174 (void) printf(gettext(" (%d%% trimmed%s)"), 2175 trim_pct, zbuf); 2176 } else if (vs->vs_trim_notsup) { 2177 (void) printf(gettext(" (trim unsupported)")); 2178 } else { 2179 (void) printf(gettext(" (untrimmed)")); 2180 } 2181 } else if (vs->vs_trim_state == VDEV_TRIM_ACTIVE) { 2182 (void) printf(gettext(" (trimming)")); 2183 } 2184 } 2185 2186 /* 2187 * Return the color associated with a health string. This includes returning 2188 * NULL for no color change. 2189 */ 2190 static char * 2191 health_str_to_color(const char *health) 2192 { 2193 if (strcmp(health, gettext("FAULTED")) == 0 || 2194 strcmp(health, gettext("SUSPENDED")) == 0 || 2195 strcmp(health, gettext("UNAVAIL")) == 0) { 2196 return (ANSI_RED); 2197 } 2198 2199 if (strcmp(health, gettext("OFFLINE")) == 0 || 2200 strcmp(health, gettext("DEGRADED")) == 0 || 2201 strcmp(health, gettext("REMOVED")) == 0) { 2202 return (ANSI_YELLOW); 2203 } 2204 2205 return (NULL); 2206 } 2207 2208 /* 2209 * Print out configuration state as requested by status_callback. 2210 */ 2211 static void 2212 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, 2213 nvlist_t *nv, int depth, boolean_t isspare, vdev_rebuild_stat_t *vrs) 2214 { 2215 nvlist_t **child, *root; 2216 uint_t c, i, vsc, children; 2217 pool_scan_stat_t *ps = NULL; 2218 vdev_stat_t *vs; 2219 char rbuf[6], wbuf[6], cbuf[6]; 2220 char *vname; 2221 uint64_t notpresent; 2222 spare_cbdata_t spare_cb; 2223 const char *state; 2224 char *type; 2225 char *path = NULL; 2226 char *rcolor = NULL, *wcolor = NULL, *ccolor = NULL; 2227 2228 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2229 &child, &children) != 0) 2230 children = 0; 2231 2232 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 2233 (uint64_t **)&vs, &vsc) == 0); 2234 2235 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 2236 2237 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) 2238 return; 2239 2240 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2241 2242 if (isspare) { 2243 /* 2244 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2245 * online drives. 2246 */ 2247 if (vs->vs_aux == VDEV_AUX_SPARED) 2248 state = gettext("INUSE"); 2249 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2250 state = gettext("AVAIL"); 2251 } 2252 2253 printf_color(health_str_to_color(state), 2254 "\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth, 2255 name, state); 2256 2257 if (!isspare) { 2258 if (vs->vs_read_errors) 2259 rcolor = ANSI_RED; 2260 2261 if (vs->vs_write_errors) 2262 wcolor = ANSI_RED; 2263 2264 if (vs->vs_checksum_errors) 2265 ccolor = ANSI_RED; 2266 2267 if (cb->cb_literal) { 2268 printf(" "); 2269 printf_color(rcolor, "%5llu", 2270 (u_longlong_t)vs->vs_read_errors); 2271 printf(" "); 2272 printf_color(wcolor, "%5llu", 2273 (u_longlong_t)vs->vs_write_errors); 2274 printf(" "); 2275 printf_color(ccolor, "%5llu", 2276 (u_longlong_t)vs->vs_checksum_errors); 2277 } else { 2278 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2279 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2280 zfs_nicenum(vs->vs_checksum_errors, cbuf, 2281 sizeof (cbuf)); 2282 printf(" "); 2283 printf_color(rcolor, "%5s", rbuf); 2284 printf(" "); 2285 printf_color(wcolor, "%5s", wbuf); 2286 printf(" "); 2287 printf_color(ccolor, "%5s", cbuf); 2288 } 2289 if (cb->cb_print_slow_ios) { 2290 if (children == 0) { 2291 /* Only leafs vdevs have slow IOs */ 2292 zfs_nicenum(vs->vs_slow_ios, rbuf, 2293 sizeof (rbuf)); 2294 } else { 2295 snprintf(rbuf, sizeof (rbuf), "-"); 2296 } 2297 2298 if (cb->cb_literal) 2299 printf(" %5llu", (u_longlong_t)vs->vs_slow_ios); 2300 else 2301 printf(" %5s", rbuf); 2302 } 2303 } 2304 2305 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2306 ¬present) == 0) { 2307 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2308 (void) printf(" %s %s", gettext("was"), path); 2309 } else if (vs->vs_aux != 0) { 2310 (void) printf(" "); 2311 color_start(ANSI_RED); 2312 switch (vs->vs_aux) { 2313 case VDEV_AUX_OPEN_FAILED: 2314 (void) printf(gettext("cannot open")); 2315 break; 2316 2317 case VDEV_AUX_BAD_GUID_SUM: 2318 (void) printf(gettext("missing device")); 2319 break; 2320 2321 case VDEV_AUX_NO_REPLICAS: 2322 (void) printf(gettext("insufficient replicas")); 2323 break; 2324 2325 case VDEV_AUX_VERSION_NEWER: 2326 (void) printf(gettext("newer version")); 2327 break; 2328 2329 case VDEV_AUX_UNSUP_FEAT: 2330 (void) printf(gettext("unsupported feature(s)")); 2331 break; 2332 2333 case VDEV_AUX_ASHIFT_TOO_BIG: 2334 (void) printf(gettext("unsupported minimum blocksize")); 2335 break; 2336 2337 case VDEV_AUX_SPARED: 2338 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2339 &spare_cb.cb_guid) == 0); 2340 if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) { 2341 if (strcmp(zpool_get_name(spare_cb.cb_zhp), 2342 zpool_get_name(zhp)) == 0) 2343 (void) printf(gettext("currently in " 2344 "use")); 2345 else 2346 (void) printf(gettext("in use by " 2347 "pool '%s'"), 2348 zpool_get_name(spare_cb.cb_zhp)); 2349 zpool_close(spare_cb.cb_zhp); 2350 } else { 2351 (void) printf(gettext("currently in use")); 2352 } 2353 break; 2354 2355 case VDEV_AUX_ERR_EXCEEDED: 2356 (void) printf(gettext("too many errors")); 2357 break; 2358 2359 case VDEV_AUX_IO_FAILURE: 2360 (void) printf(gettext("experienced I/O failures")); 2361 break; 2362 2363 case VDEV_AUX_BAD_LOG: 2364 (void) printf(gettext("bad intent log")); 2365 break; 2366 2367 case VDEV_AUX_EXTERNAL: 2368 (void) printf(gettext("external device fault")); 2369 break; 2370 2371 case VDEV_AUX_SPLIT_POOL: 2372 (void) printf(gettext("split into new pool")); 2373 break; 2374 2375 case VDEV_AUX_ACTIVE: 2376 (void) printf(gettext("currently in use")); 2377 break; 2378 2379 case VDEV_AUX_CHILDREN_OFFLINE: 2380 (void) printf(gettext("all children offline")); 2381 break; 2382 2383 case VDEV_AUX_BAD_LABEL: 2384 (void) printf(gettext("invalid label")); 2385 break; 2386 2387 default: 2388 (void) printf(gettext("corrupted data")); 2389 break; 2390 } 2391 color_end(); 2392 } else if (children == 0 && !isspare && 2393 getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") == NULL && 2394 VDEV_STAT_VALID(vs_physical_ashift, vsc) && 2395 vs->vs_configured_ashift < vs->vs_physical_ashift) { 2396 (void) printf( 2397 gettext(" block size: %dB configured, %dB native"), 2398 1 << vs->vs_configured_ashift, 1 << vs->vs_physical_ashift); 2399 } 2400 2401 /* The root vdev has the scrub/resilver stats */ 2402 root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 2403 ZPOOL_CONFIG_VDEV_TREE); 2404 (void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS, 2405 (uint64_t **)&ps, &c); 2406 2407 if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) { 2408 if (vs->vs_scan_processed != 0) { 2409 (void) printf(gettext(" (%s)"), 2410 (ps->pss_func == POOL_SCAN_RESILVER) ? 2411 "resilvering" : "repairing"); 2412 } else if (vs->vs_resilver_deferred) { 2413 (void) printf(gettext(" (awaiting resilver)")); 2414 } 2415 } 2416 2417 /* The top-level vdevs have the rebuild stats */ 2418 if (vrs != NULL && vrs->vrs_state == VDEV_REBUILD_ACTIVE && 2419 children == 0) { 2420 if (vs->vs_rebuild_processed != 0) { 2421 (void) printf(gettext(" (resilvering)")); 2422 } 2423 } 2424 2425 if (cb->vcdl != NULL) { 2426 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 2427 printf(" "); 2428 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path); 2429 } 2430 } 2431 2432 /* Display vdev initialization and trim status for leaves. */ 2433 if (children == 0) { 2434 print_status_initialize(vs, cb->cb_print_vdev_init); 2435 print_status_trim(vs, cb->cb_print_vdev_trim); 2436 } 2437 2438 (void) printf("\n"); 2439 2440 for (c = 0; c < children; c++) { 2441 uint64_t islog = B_FALSE, ishole = B_FALSE; 2442 2443 /* Don't print logs or holes here */ 2444 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2445 &islog); 2446 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 2447 &ishole); 2448 if (islog || ishole) 2449 continue; 2450 /* Only print normal classes here */ 2451 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 2452 continue; 2453 2454 /* Provide vdev_rebuild_stats to children if available */ 2455 if (vrs == NULL) { 2456 (void) nvlist_lookup_uint64_array(nv, 2457 ZPOOL_CONFIG_REBUILD_STATS, 2458 (uint64_t **)&vrs, &i); 2459 } 2460 2461 vname = zpool_vdev_name(g_zfs, zhp, child[c], 2462 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2463 print_status_config(zhp, cb, vname, child[c], depth + 2, 2464 isspare, vrs); 2465 free(vname); 2466 } 2467 } 2468 2469 /* 2470 * Print the configuration of an exported pool. Iterate over all vdevs in the 2471 * pool, printing out the name and status for each one. 2472 */ 2473 static void 2474 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv, 2475 int depth) 2476 { 2477 nvlist_t **child; 2478 uint_t c, children; 2479 vdev_stat_t *vs; 2480 char *type, *vname; 2481 2482 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 2483 if (strcmp(type, VDEV_TYPE_MISSING) == 0 || 2484 strcmp(type, VDEV_TYPE_HOLE) == 0) 2485 return; 2486 2487 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 2488 (uint64_t **)&vs, &c) == 0); 2489 2490 (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name); 2491 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 2492 2493 if (vs->vs_aux != 0) { 2494 (void) printf(" "); 2495 2496 switch (vs->vs_aux) { 2497 case VDEV_AUX_OPEN_FAILED: 2498 (void) printf(gettext("cannot open")); 2499 break; 2500 2501 case VDEV_AUX_BAD_GUID_SUM: 2502 (void) printf(gettext("missing device")); 2503 break; 2504 2505 case VDEV_AUX_NO_REPLICAS: 2506 (void) printf(gettext("insufficient replicas")); 2507 break; 2508 2509 case VDEV_AUX_VERSION_NEWER: 2510 (void) printf(gettext("newer version")); 2511 break; 2512 2513 case VDEV_AUX_UNSUP_FEAT: 2514 (void) printf(gettext("unsupported feature(s)")); 2515 break; 2516 2517 case VDEV_AUX_ERR_EXCEEDED: 2518 (void) printf(gettext("too many errors")); 2519 break; 2520 2521 case VDEV_AUX_ACTIVE: 2522 (void) printf(gettext("currently in use")); 2523 break; 2524 2525 case VDEV_AUX_CHILDREN_OFFLINE: 2526 (void) printf(gettext("all children offline")); 2527 break; 2528 2529 case VDEV_AUX_BAD_LABEL: 2530 (void) printf(gettext("invalid label")); 2531 break; 2532 2533 default: 2534 (void) printf(gettext("corrupted data")); 2535 break; 2536 } 2537 } 2538 (void) printf("\n"); 2539 2540 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2541 &child, &children) != 0) 2542 return; 2543 2544 for (c = 0; c < children; c++) { 2545 uint64_t is_log = B_FALSE; 2546 2547 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2548 &is_log); 2549 if (is_log) 2550 continue; 2551 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 2552 continue; 2553 2554 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2555 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2556 print_import_config(cb, vname, child[c], depth + 2); 2557 free(vname); 2558 } 2559 2560 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 2561 &child, &children) == 0) { 2562 (void) printf(gettext("\tcache\n")); 2563 for (c = 0; c < children; c++) { 2564 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2565 cb->cb_name_flags); 2566 (void) printf("\t %s\n", vname); 2567 free(vname); 2568 } 2569 } 2570 2571 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 2572 &child, &children) == 0) { 2573 (void) printf(gettext("\tspares\n")); 2574 for (c = 0; c < children; c++) { 2575 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2576 cb->cb_name_flags); 2577 (void) printf("\t %s\n", vname); 2578 free(vname); 2579 } 2580 } 2581 } 2582 2583 /* 2584 * Print specialized class vdevs. 2585 * 2586 * These are recorded as top level vdevs in the main pool child array 2587 * but with "is_log" set to 1 or an "alloc_bias" string. We use either 2588 * print_status_config() or print_import_config() to print the top level 2589 * class vdevs then any of their children (eg mirrored slogs) are printed 2590 * recursively - which works because only the top level vdev is marked. 2591 */ 2592 static void 2593 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv, 2594 const char *class) 2595 { 2596 uint_t c, children; 2597 nvlist_t **child; 2598 boolean_t printed = B_FALSE; 2599 2600 assert(zhp != NULL || !cb->cb_verbose); 2601 2602 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, 2603 &children) != 0) 2604 return; 2605 2606 for (c = 0; c < children; c++) { 2607 uint64_t is_log = B_FALSE; 2608 char *bias = NULL; 2609 char *type = NULL; 2610 2611 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2612 &is_log); 2613 2614 if (is_log) { 2615 bias = VDEV_ALLOC_CLASS_LOGS; 2616 } else { 2617 (void) nvlist_lookup_string(child[c], 2618 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 2619 (void) nvlist_lookup_string(child[c], 2620 ZPOOL_CONFIG_TYPE, &type); 2621 } 2622 2623 if (bias == NULL || strcmp(bias, class) != 0) 2624 continue; 2625 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 2626 continue; 2627 2628 if (!printed) { 2629 (void) printf("\t%s\t\n", gettext(class)); 2630 printed = B_TRUE; 2631 } 2632 2633 char *name = zpool_vdev_name(g_zfs, zhp, child[c], 2634 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2635 if (cb->cb_print_status) 2636 print_status_config(zhp, cb, name, child[c], 2, 2637 B_FALSE, NULL); 2638 else 2639 print_import_config(cb, name, child[c], 2); 2640 free(name); 2641 } 2642 } 2643 2644 /* 2645 * Display the status for the given pool. 2646 */ 2647 static int 2648 show_import(nvlist_t *config, boolean_t report_error) 2649 { 2650 uint64_t pool_state; 2651 vdev_stat_t *vs; 2652 char *name; 2653 uint64_t guid; 2654 uint64_t hostid = 0; 2655 char *msgid; 2656 char *hostname = "unknown"; 2657 nvlist_t *nvroot, *nvinfo; 2658 zpool_status_t reason; 2659 zpool_errata_t errata; 2660 const char *health; 2661 uint_t vsc; 2662 char *comment; 2663 status_cbdata_t cb = { 0 }; 2664 2665 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 2666 &name) == 0); 2667 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 2668 &guid) == 0); 2669 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2670 &pool_state) == 0); 2671 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2672 &nvroot) == 0); 2673 2674 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 2675 (uint64_t **)&vs, &vsc) == 0); 2676 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2677 2678 reason = zpool_import_status(config, &msgid, &errata); 2679 2680 /* 2681 * If we're importing using a cachefile, then we won't report any 2682 * errors unless we are in the scan phase of the import. 2683 */ 2684 if (reason != ZPOOL_STATUS_OK && !report_error) 2685 return (reason); 2686 2687 (void) printf(gettext(" pool: %s\n"), name); 2688 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 2689 (void) printf(gettext(" state: %s"), health); 2690 if (pool_state == POOL_STATE_DESTROYED) 2691 (void) printf(gettext(" (DESTROYED)")); 2692 (void) printf("\n"); 2693 2694 switch (reason) { 2695 case ZPOOL_STATUS_MISSING_DEV_R: 2696 case ZPOOL_STATUS_MISSING_DEV_NR: 2697 case ZPOOL_STATUS_BAD_GUID_SUM: 2698 printf_color(ANSI_BOLD, gettext("status: ")); 2699 printf_color(ANSI_YELLOW, gettext("One or more devices are " 2700 "missing from the system.\n")); 2701 break; 2702 2703 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2704 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2705 printf_color(ANSI_BOLD, gettext("status: ")); 2706 printf_color(ANSI_YELLOW, gettext("One or more devices contains" 2707 " corrupted data.\n")); 2708 break; 2709 2710 case ZPOOL_STATUS_CORRUPT_DATA: 2711 (void) printf( 2712 gettext(" status: The pool data is corrupted.\n")); 2713 break; 2714 2715 case ZPOOL_STATUS_OFFLINE_DEV: 2716 printf_color(ANSI_BOLD, gettext("status: ")); 2717 printf_color(ANSI_YELLOW, gettext("One or more devices " 2718 "are offlined.\n")); 2719 break; 2720 2721 case ZPOOL_STATUS_CORRUPT_POOL: 2722 printf_color(ANSI_BOLD, gettext("status: ")); 2723 printf_color(ANSI_YELLOW, gettext("The pool metadata is " 2724 "corrupted.\n")); 2725 break; 2726 2727 case ZPOOL_STATUS_VERSION_OLDER: 2728 printf_color(ANSI_BOLD, gettext("status: ")); 2729 printf_color(ANSI_YELLOW, gettext("The pool is formatted using " 2730 "a legacy on-disk version.\n")); 2731 break; 2732 2733 case ZPOOL_STATUS_VERSION_NEWER: 2734 printf_color(ANSI_BOLD, gettext("status: ")); 2735 printf_color(ANSI_YELLOW, gettext("The pool is formatted using " 2736 "an incompatible version.\n")); 2737 break; 2738 2739 case ZPOOL_STATUS_FEAT_DISABLED: 2740 printf_color(ANSI_BOLD, gettext("status: ")); 2741 printf_color(ANSI_YELLOW, gettext("Some supported " 2742 "features are not enabled on the pool.\n\t" 2743 "(Note that they may be intentionally disabled " 2744 "if the\n\t'compatibility' property is set.)\n")); 2745 break; 2746 2747 case ZPOOL_STATUS_COMPATIBILITY_ERR: 2748 printf_color(ANSI_BOLD, gettext("status: ")); 2749 printf_color(ANSI_YELLOW, gettext("Error reading or parsing " 2750 "the file(s) indicated by the 'compatibility'\n" 2751 "property.\n")); 2752 break; 2753 2754 case ZPOOL_STATUS_INCOMPATIBLE_FEAT: 2755 printf_color(ANSI_BOLD, gettext("status: ")); 2756 printf_color(ANSI_YELLOW, gettext("One or more features " 2757 "are enabled on the pool despite not being\n" 2758 "requested by the 'compatibility' property.\n")); 2759 break; 2760 2761 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2762 printf_color(ANSI_BOLD, gettext("status: ")); 2763 printf_color(ANSI_YELLOW, gettext("The pool uses the following " 2764 "feature(s) not supported on this system:\n")); 2765 color_start(ANSI_YELLOW); 2766 zpool_print_unsup_feat(config); 2767 color_end(); 2768 break; 2769 2770 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2771 printf_color(ANSI_BOLD, gettext("status: ")); 2772 printf_color(ANSI_YELLOW, gettext("The pool can only be " 2773 "accessed in read-only mode on this system. It\n\tcannot be" 2774 " accessed in read-write mode because it uses the " 2775 "following\n\tfeature(s) not supported on this system:\n")); 2776 color_start(ANSI_YELLOW); 2777 zpool_print_unsup_feat(config); 2778 color_end(); 2779 break; 2780 2781 case ZPOOL_STATUS_HOSTID_ACTIVE: 2782 printf_color(ANSI_BOLD, gettext("status: ")); 2783 printf_color(ANSI_YELLOW, gettext("The pool is currently " 2784 "imported by another system.\n")); 2785 break; 2786 2787 case ZPOOL_STATUS_HOSTID_REQUIRED: 2788 printf_color(ANSI_BOLD, gettext("status: ")); 2789 printf_color(ANSI_YELLOW, gettext("The pool has the " 2790 "multihost property on. It cannot\n\tbe safely imported " 2791 "when the system hostid is not set.\n")); 2792 break; 2793 2794 case ZPOOL_STATUS_HOSTID_MISMATCH: 2795 printf_color(ANSI_BOLD, gettext("status: ")); 2796 printf_color(ANSI_YELLOW, gettext("The pool was last accessed " 2797 "by another system.\n")); 2798 break; 2799 2800 case ZPOOL_STATUS_FAULTED_DEV_R: 2801 case ZPOOL_STATUS_FAULTED_DEV_NR: 2802 printf_color(ANSI_BOLD, gettext("status: ")); 2803 printf_color(ANSI_YELLOW, gettext("One or more devices are " 2804 "faulted.\n")); 2805 break; 2806 2807 case ZPOOL_STATUS_BAD_LOG: 2808 printf_color(ANSI_BOLD, gettext("status: ")); 2809 printf_color(ANSI_YELLOW, gettext("An intent log record cannot " 2810 "be read.\n")); 2811 break; 2812 2813 case ZPOOL_STATUS_RESILVERING: 2814 case ZPOOL_STATUS_REBUILDING: 2815 printf_color(ANSI_BOLD, gettext("status: ")); 2816 printf_color(ANSI_YELLOW, gettext("One or more devices were " 2817 "being resilvered.\n")); 2818 break; 2819 2820 case ZPOOL_STATUS_ERRATA: 2821 printf_color(ANSI_BOLD, gettext("status: ")); 2822 printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"), 2823 errata); 2824 break; 2825 2826 case ZPOOL_STATUS_NON_NATIVE_ASHIFT: 2827 printf_color(ANSI_BOLD, gettext("status: ")); 2828 printf_color(ANSI_YELLOW, gettext("One or more devices are " 2829 "configured to use a non-native block size.\n" 2830 "\tExpect reduced performance.\n")); 2831 break; 2832 2833 default: 2834 /* 2835 * No other status can be seen when importing pools. 2836 */ 2837 assert(reason == ZPOOL_STATUS_OK); 2838 } 2839 2840 /* 2841 * Print out an action according to the overall state of the pool. 2842 */ 2843 if (vs->vs_state == VDEV_STATE_HEALTHY) { 2844 if (reason == ZPOOL_STATUS_VERSION_OLDER || 2845 reason == ZPOOL_STATUS_FEAT_DISABLED) { 2846 (void) printf(gettext(" action: The pool can be " 2847 "imported using its name or numeric identifier, " 2848 "though\n\tsome features will not be available " 2849 "without an explicit 'zpool upgrade'.\n")); 2850 } else if (reason == ZPOOL_STATUS_COMPATIBILITY_ERR) { 2851 (void) printf(gettext(" action: The pool can be " 2852 "imported using its name or numeric\n\tidentifier, " 2853 "though the file(s) indicated by its " 2854 "'compatibility'\n\tproperty cannot be parsed at " 2855 "this time.\n")); 2856 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) { 2857 (void) printf(gettext(" action: The pool can be " 2858 "imported using its name or numeric " 2859 "identifier and\n\tthe '-f' flag.\n")); 2860 } else if (reason == ZPOOL_STATUS_ERRATA) { 2861 switch (errata) { 2862 case ZPOOL_ERRATA_NONE: 2863 break; 2864 2865 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 2866 (void) printf(gettext(" action: The pool can " 2867 "be imported using its name or numeric " 2868 "identifier,\n\thowever there is a compat" 2869 "ibility issue which should be corrected" 2870 "\n\tby running 'zpool scrub'\n")); 2871 break; 2872 2873 case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY: 2874 (void) printf(gettext(" action: The pool can" 2875 "not be imported with this version of ZFS " 2876 "due to\n\tan active asynchronous destroy. " 2877 "Revert to an earlier version\n\tand " 2878 "allow the destroy to complete before " 2879 "updating.\n")); 2880 break; 2881 2882 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 2883 (void) printf(gettext(" action: Existing " 2884 "encrypted datasets contain an on-disk " 2885 "incompatibility, which\n\tneeds to be " 2886 "corrected. Backup these datasets to new " 2887 "encrypted datasets\n\tand destroy the " 2888 "old ones.\n")); 2889 break; 2890 2891 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 2892 (void) printf(gettext(" action: Existing " 2893 "encrypted snapshots and bookmarks contain " 2894 "an on-disk\n\tincompatibility. This may " 2895 "cause on-disk corruption if they are used" 2896 "\n\twith 'zfs recv'. To correct the " 2897 "issue, enable the bookmark_v2 feature.\n\t" 2898 "No additional action is needed if there " 2899 "are no encrypted snapshots or\n\t" 2900 "bookmarks. If preserving the encrypted " 2901 "snapshots and bookmarks is\n\trequired, " 2902 "use a non-raw send to backup and restore " 2903 "them. Alternately,\n\tthey may be removed" 2904 " to resolve the incompatibility.\n")); 2905 break; 2906 default: 2907 /* 2908 * All errata must contain an action message. 2909 */ 2910 assert(0); 2911 } 2912 } else { 2913 (void) printf(gettext(" action: The pool can be " 2914 "imported using its name or numeric " 2915 "identifier.\n")); 2916 } 2917 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 2918 (void) printf(gettext(" action: The pool can be imported " 2919 "despite missing or damaged devices. The\n\tfault " 2920 "tolerance of the pool may be compromised if imported.\n")); 2921 } else { 2922 switch (reason) { 2923 case ZPOOL_STATUS_VERSION_NEWER: 2924 (void) printf(gettext(" action: The pool cannot be " 2925 "imported. Access the pool on a system running " 2926 "newer\n\tsoftware, or recreate the pool from " 2927 "backup.\n")); 2928 break; 2929 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2930 printf_color(ANSI_BOLD, gettext("action: ")); 2931 printf_color(ANSI_YELLOW, gettext("The pool cannot be " 2932 "imported. Access the pool on a system that " 2933 "supports\n\tthe required feature(s), or recreate " 2934 "the pool from backup.\n")); 2935 break; 2936 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2937 printf_color(ANSI_BOLD, gettext("action: ")); 2938 printf_color(ANSI_YELLOW, gettext("The pool cannot be " 2939 "imported in read-write mode. Import the pool " 2940 "with\n" 2941 "\t\"-o readonly=on\", access the pool on a system " 2942 "that supports the\n\trequired feature(s), or " 2943 "recreate the pool from backup.\n")); 2944 break; 2945 case ZPOOL_STATUS_MISSING_DEV_R: 2946 case ZPOOL_STATUS_MISSING_DEV_NR: 2947 case ZPOOL_STATUS_BAD_GUID_SUM: 2948 (void) printf(gettext(" action: The pool cannot be " 2949 "imported. Attach the missing\n\tdevices and try " 2950 "again.\n")); 2951 break; 2952 case ZPOOL_STATUS_HOSTID_ACTIVE: 2953 VERIFY0(nvlist_lookup_nvlist(config, 2954 ZPOOL_CONFIG_LOAD_INFO, &nvinfo)); 2955 2956 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 2957 hostname = fnvlist_lookup_string(nvinfo, 2958 ZPOOL_CONFIG_MMP_HOSTNAME); 2959 2960 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 2961 hostid = fnvlist_lookup_uint64(nvinfo, 2962 ZPOOL_CONFIG_MMP_HOSTID); 2963 2964 (void) printf(gettext(" action: The pool must be " 2965 "exported from %s (hostid=%lx)\n\tbefore it " 2966 "can be safely imported.\n"), hostname, 2967 (unsigned long) hostid); 2968 break; 2969 case ZPOOL_STATUS_HOSTID_REQUIRED: 2970 (void) printf(gettext(" action: Set a unique system " 2971 "hostid with the zgenhostid(8) command.\n")); 2972 break; 2973 default: 2974 (void) printf(gettext(" action: The pool cannot be " 2975 "imported due to damaged devices or data.\n")); 2976 } 2977 } 2978 2979 /* Print the comment attached to the pool. */ 2980 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) 2981 (void) printf(gettext("comment: %s\n"), comment); 2982 2983 /* 2984 * If the state is "closed" or "can't open", and the aux state 2985 * is "corrupt data": 2986 */ 2987 if (((vs->vs_state == VDEV_STATE_CLOSED) || 2988 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 2989 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 2990 if (pool_state == POOL_STATE_DESTROYED) 2991 (void) printf(gettext("\tThe pool was destroyed, " 2992 "but can be imported using the '-Df' flags.\n")); 2993 else if (pool_state != POOL_STATE_EXPORTED) 2994 (void) printf(gettext("\tThe pool may be active on " 2995 "another system, but can be imported using\n\t" 2996 "the '-f' flag.\n")); 2997 } 2998 2999 if (msgid != NULL) { 3000 (void) printf(gettext( 3001 " see: https://openzfs.github.io/openzfs-docs/msg/%s\n"), 3002 msgid); 3003 } 3004 3005 (void) printf(gettext(" config:\n\n")); 3006 3007 cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name), 3008 VDEV_NAME_TYPE_ID); 3009 if (cb.cb_namewidth < 10) 3010 cb.cb_namewidth = 10; 3011 3012 print_import_config(&cb, name, nvroot, 0); 3013 3014 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP); 3015 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 3016 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS); 3017 3018 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 3019 (void) printf(gettext("\n\tAdditional devices are known to " 3020 "be part of this pool, though their\n\texact " 3021 "configuration cannot be determined.\n")); 3022 } 3023 return (0); 3024 } 3025 3026 static boolean_t 3027 zfs_force_import_required(nvlist_t *config) 3028 { 3029 uint64_t state; 3030 uint64_t hostid = 0; 3031 nvlist_t *nvinfo; 3032 3033 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE); 3034 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid); 3035 3036 if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid()) 3037 return (B_TRUE); 3038 3039 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 3040 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) { 3041 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo, 3042 ZPOOL_CONFIG_MMP_STATE); 3043 3044 if (mmp_state != MMP_STATE_INACTIVE) 3045 return (B_TRUE); 3046 } 3047 3048 return (B_FALSE); 3049 } 3050 3051 /* 3052 * Perform the import for the given configuration. This passes the heavy 3053 * lifting off to zpool_import_props(), and then mounts the datasets contained 3054 * within the pool. 3055 */ 3056 static int 3057 do_import(nvlist_t *config, const char *newname, const char *mntopts, 3058 nvlist_t *props, int flags) 3059 { 3060 int ret = 0; 3061 zpool_handle_t *zhp; 3062 char *name; 3063 uint64_t version; 3064 3065 name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); 3066 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION); 3067 3068 if (!SPA_VERSION_IS_SUPPORTED(version)) { 3069 (void) fprintf(stderr, gettext("cannot import '%s': pool " 3070 "is formatted using an unsupported ZFS version\n"), name); 3071 return (1); 3072 } else if (zfs_force_import_required(config) && 3073 !(flags & ZFS_IMPORT_ANY_HOST)) { 3074 mmp_state_t mmp_state = MMP_STATE_INACTIVE; 3075 nvlist_t *nvinfo; 3076 3077 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 3078 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) 3079 mmp_state = fnvlist_lookup_uint64(nvinfo, 3080 ZPOOL_CONFIG_MMP_STATE); 3081 3082 if (mmp_state == MMP_STATE_ACTIVE) { 3083 char *hostname = "<unknown>"; 3084 uint64_t hostid = 0; 3085 3086 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 3087 hostname = fnvlist_lookup_string(nvinfo, 3088 ZPOOL_CONFIG_MMP_HOSTNAME); 3089 3090 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 3091 hostid = fnvlist_lookup_uint64(nvinfo, 3092 ZPOOL_CONFIG_MMP_HOSTID); 3093 3094 (void) fprintf(stderr, gettext("cannot import '%s': " 3095 "pool is imported on %s (hostid: " 3096 "0x%lx)\nExport the pool on the other system, " 3097 "then run 'zpool import'.\n"), 3098 name, hostname, (unsigned long) hostid); 3099 } else if (mmp_state == MMP_STATE_NO_HOSTID) { 3100 (void) fprintf(stderr, gettext("Cannot import '%s': " 3101 "pool has the multihost property on and the\n" 3102 "system's hostid is not set. Set a unique hostid " 3103 "with the zgenhostid(8) command.\n"), name); 3104 } else { 3105 char *hostname = "<unknown>"; 3106 uint64_t timestamp = 0; 3107 uint64_t hostid = 0; 3108 3109 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME)) 3110 hostname = fnvlist_lookup_string(config, 3111 ZPOOL_CONFIG_HOSTNAME); 3112 3113 if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP)) 3114 timestamp = fnvlist_lookup_uint64(config, 3115 ZPOOL_CONFIG_TIMESTAMP); 3116 3117 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID)) 3118 hostid = fnvlist_lookup_uint64(config, 3119 ZPOOL_CONFIG_HOSTID); 3120 3121 (void) fprintf(stderr, gettext("cannot import '%s': " 3122 "pool was previously in use from another system.\n" 3123 "Last accessed by %s (hostid=%lx) at %s" 3124 "The pool can be imported, use 'zpool import -f' " 3125 "to import the pool.\n"), name, hostname, 3126 (unsigned long)hostid, ctime((time_t *)×tamp)); 3127 } 3128 3129 return (1); 3130 } 3131 3132 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) 3133 return (1); 3134 3135 if (newname != NULL) 3136 name = (char *)newname; 3137 3138 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) 3139 return (1); 3140 3141 /* 3142 * Loading keys is best effort. We don't want to return immediately 3143 * if it fails but we do want to give the error to the caller. 3144 */ 3145 if (flags & ZFS_IMPORT_LOAD_KEYS) { 3146 ret = zfs_crypto_attempt_load_keys(g_zfs, name); 3147 if (ret != 0) 3148 ret = 1; 3149 } 3150 3151 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 3152 !(flags & ZFS_IMPORT_ONLY) && 3153 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 3154 zpool_close(zhp); 3155 return (1); 3156 } 3157 3158 zpool_close(zhp); 3159 return (ret); 3160 } 3161 3162 static int 3163 import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags, 3164 char *orig_name, char *new_name, 3165 boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all, 3166 importargs_t *import) 3167 { 3168 nvlist_t *config = NULL; 3169 nvlist_t *found_config = NULL; 3170 uint64_t pool_state; 3171 3172 /* 3173 * At this point we have a list of import candidate configs. Even if 3174 * we were searching by pool name or guid, we still need to 3175 * post-process the list to deal with pool state and possible 3176 * duplicate names. 3177 */ 3178 int err = 0; 3179 nvpair_t *elem = NULL; 3180 boolean_t first = B_TRUE; 3181 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 3182 3183 verify(nvpair_value_nvlist(elem, &config) == 0); 3184 3185 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 3186 &pool_state) == 0); 3187 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 3188 continue; 3189 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 3190 continue; 3191 3192 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY, 3193 import->policy) == 0); 3194 3195 if (!pool_specified) { 3196 if (first) 3197 first = B_FALSE; 3198 else if (!do_all) 3199 (void) printf("\n"); 3200 3201 if (do_all) { 3202 err |= do_import(config, NULL, mntopts, 3203 props, flags); 3204 } else { 3205 /* 3206 * If we're importing from cachefile, then 3207 * we don't want to report errors until we 3208 * are in the scan phase of the import. If 3209 * we get an error, then we return that error 3210 * to invoke the scan phase. 3211 */ 3212 if (import->cachefile && !import->scan) 3213 err = show_import(config, B_FALSE); 3214 else 3215 (void) show_import(config, B_TRUE); 3216 } 3217 } else if (import->poolname != NULL) { 3218 char *name; 3219 3220 /* 3221 * We are searching for a pool based on name. 3222 */ 3223 verify(nvlist_lookup_string(config, 3224 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 3225 3226 if (strcmp(name, import->poolname) == 0) { 3227 if (found_config != NULL) { 3228 (void) fprintf(stderr, gettext( 3229 "cannot import '%s': more than " 3230 "one matching pool\n"), 3231 import->poolname); 3232 (void) fprintf(stderr, gettext( 3233 "import by numeric ID instead\n")); 3234 err = B_TRUE; 3235 } 3236 found_config = config; 3237 } 3238 } else { 3239 uint64_t guid; 3240 3241 /* 3242 * Search for a pool by guid. 3243 */ 3244 verify(nvlist_lookup_uint64(config, 3245 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 3246 3247 if (guid == import->guid) 3248 found_config = config; 3249 } 3250 } 3251 3252 /* 3253 * If we were searching for a specific pool, verify that we found a 3254 * pool, and then do the import. 3255 */ 3256 if (pool_specified && err == 0) { 3257 if (found_config == NULL) { 3258 (void) fprintf(stderr, gettext("cannot import '%s': " 3259 "no such pool available\n"), orig_name); 3260 err = B_TRUE; 3261 } else { 3262 err |= do_import(found_config, new_name, 3263 mntopts, props, flags); 3264 } 3265 } 3266 3267 /* 3268 * If we were just looking for pools, report an error if none were 3269 * found. 3270 */ 3271 if (!pool_specified && first) 3272 (void) fprintf(stderr, 3273 gettext("no pools available to import\n")); 3274 return (err); 3275 } 3276 3277 typedef struct target_exists_args { 3278 const char *poolname; 3279 uint64_t poolguid; 3280 } target_exists_args_t; 3281 3282 static int 3283 name_or_guid_exists(zpool_handle_t *zhp, void *data) 3284 { 3285 target_exists_args_t *args = data; 3286 nvlist_t *config = zpool_get_config(zhp, NULL); 3287 int found = 0; 3288 3289 if (config == NULL) 3290 return (0); 3291 3292 if (args->poolname != NULL) { 3293 char *pool_name; 3294 3295 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 3296 &pool_name) == 0); 3297 if (strcmp(pool_name, args->poolname) == 0) 3298 found = 1; 3299 } else { 3300 uint64_t pool_guid; 3301 3302 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 3303 &pool_guid) == 0); 3304 if (pool_guid == args->poolguid) 3305 found = 1; 3306 } 3307 zpool_close(zhp); 3308 3309 return (found); 3310 } 3311 /* 3312 * zpool checkpoint <pool> 3313 * checkpoint --discard <pool> 3314 * 3315 * -d Discard the checkpoint from a checkpointed 3316 * --discard pool. 3317 * 3318 * -w Wait for discarding a checkpoint to complete. 3319 * --wait 3320 * 3321 * Checkpoints the specified pool, by taking a "snapshot" of its 3322 * current state. A pool can only have one checkpoint at a time. 3323 */ 3324 int 3325 zpool_do_checkpoint(int argc, char **argv) 3326 { 3327 boolean_t discard, wait; 3328 char *pool; 3329 zpool_handle_t *zhp; 3330 int c, err; 3331 3332 struct option long_options[] = { 3333 {"discard", no_argument, NULL, 'd'}, 3334 {"wait", no_argument, NULL, 'w'}, 3335 {0, 0, 0, 0} 3336 }; 3337 3338 discard = B_FALSE; 3339 wait = B_FALSE; 3340 while ((c = getopt_long(argc, argv, ":dw", long_options, NULL)) != -1) { 3341 switch (c) { 3342 case 'd': 3343 discard = B_TRUE; 3344 break; 3345 case 'w': 3346 wait = B_TRUE; 3347 break; 3348 case '?': 3349 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3350 optopt); 3351 usage(B_FALSE); 3352 } 3353 } 3354 3355 if (wait && !discard) { 3356 (void) fprintf(stderr, gettext("--wait only valid when " 3357 "--discard also specified\n")); 3358 usage(B_FALSE); 3359 } 3360 3361 argc -= optind; 3362 argv += optind; 3363 3364 if (argc < 1) { 3365 (void) fprintf(stderr, gettext("missing pool argument\n")); 3366 usage(B_FALSE); 3367 } 3368 3369 if (argc > 1) { 3370 (void) fprintf(stderr, gettext("too many arguments\n")); 3371 usage(B_FALSE); 3372 } 3373 3374 pool = argv[0]; 3375 3376 if ((zhp = zpool_open(g_zfs, pool)) == NULL) { 3377 /* As a special case, check for use of '/' in the name */ 3378 if (strchr(pool, '/') != NULL) 3379 (void) fprintf(stderr, gettext("'zpool checkpoint' " 3380 "doesn't work on datasets. To save the state " 3381 "of a dataset from a specific point in time " 3382 "please use 'zfs snapshot'\n")); 3383 return (1); 3384 } 3385 3386 if (discard) { 3387 err = (zpool_discard_checkpoint(zhp) != 0); 3388 if (err == 0 && wait) 3389 err = zpool_wait(zhp, ZPOOL_WAIT_CKPT_DISCARD); 3390 } else { 3391 err = (zpool_checkpoint(zhp) != 0); 3392 } 3393 3394 zpool_close(zhp); 3395 3396 return (err); 3397 } 3398 3399 #define CHECKPOINT_OPT 1024 3400 3401 /* 3402 * zpool import [-d dir] [-D] 3403 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l] 3404 * [-d dir | -c cachefile | -s] [-f] -a 3405 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l] 3406 * [-d dir | -c cachefile | -s] [-f] [-n] [-F] <pool | id> 3407 * [newpool] 3408 * 3409 * -c Read pool information from a cachefile instead of searching 3410 * devices. If importing from a cachefile config fails, then 3411 * fallback to searching for devices only in the directories that 3412 * exist in the cachefile. 3413 * 3414 * -d Scan in a specific directory, other than /dev/. More than 3415 * one directory can be specified using multiple '-d' options. 3416 * 3417 * -D Scan for previously destroyed pools or import all or only 3418 * specified destroyed pools. 3419 * 3420 * -R Temporarily import the pool, with all mountpoints relative to 3421 * the given root. The pool will remain exported when the machine 3422 * is rebooted. 3423 * 3424 * -V Import even in the presence of faulted vdevs. This is an 3425 * intentionally undocumented option for testing purposes, and 3426 * treats the pool configuration as complete, leaving any bad 3427 * vdevs in the FAULTED state. In other words, it does verbatim 3428 * import. 3429 * 3430 * -f Force import, even if it appears that the pool is active. 3431 * 3432 * -F Attempt rewind if necessary. 3433 * 3434 * -n See if rewind would work, but don't actually rewind. 3435 * 3436 * -N Import the pool but don't mount datasets. 3437 * 3438 * -T Specify a starting txg to use for import. This option is 3439 * intentionally undocumented option for testing purposes. 3440 * 3441 * -a Import all pools found. 3442 * 3443 * -l Load encryption keys while importing. 3444 * 3445 * -o Set property=value and/or temporary mount options (without '='). 3446 * 3447 * -s Scan using the default search path, the libblkid cache will 3448 * not be consulted. 3449 * 3450 * --rewind-to-checkpoint 3451 * Import the pool and revert back to the checkpoint. 3452 * 3453 * The import command scans for pools to import, and import pools based on pool 3454 * name and GUID. The pool can also be renamed as part of the import process. 3455 */ 3456 int 3457 zpool_do_import(int argc, char **argv) 3458 { 3459 char **searchdirs = NULL; 3460 char *env, *envdup = NULL; 3461 int nsearch = 0; 3462 int c; 3463 int err = 0; 3464 nvlist_t *pools = NULL; 3465 boolean_t do_all = B_FALSE; 3466 boolean_t do_destroyed = B_FALSE; 3467 char *mntopts = NULL; 3468 uint64_t searchguid = 0; 3469 char *searchname = NULL; 3470 char *propval; 3471 nvlist_t *policy = NULL; 3472 nvlist_t *props = NULL; 3473 int flags = ZFS_IMPORT_NORMAL; 3474 uint32_t rewind_policy = ZPOOL_NO_REWIND; 3475 boolean_t dryrun = B_FALSE; 3476 boolean_t do_rewind = B_FALSE; 3477 boolean_t xtreme_rewind = B_FALSE; 3478 boolean_t do_scan = B_FALSE; 3479 boolean_t pool_exists = B_FALSE; 3480 boolean_t pool_specified = B_FALSE; 3481 uint64_t txg = -1ULL; 3482 char *cachefile = NULL; 3483 importargs_t idata = { 0 }; 3484 char *endptr; 3485 3486 struct option long_options[] = { 3487 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT}, 3488 {0, 0, 0, 0} 3489 }; 3490 3491 /* check options */ 3492 while ((c = getopt_long(argc, argv, ":aCc:d:DEfFlmnNo:R:stT:VX", 3493 long_options, NULL)) != -1) { 3494 switch (c) { 3495 case 'a': 3496 do_all = B_TRUE; 3497 break; 3498 case 'c': 3499 cachefile = optarg; 3500 break; 3501 case 'd': 3502 searchdirs = safe_realloc(searchdirs, 3503 (nsearch + 1) * sizeof (char *)); 3504 searchdirs[nsearch++] = optarg; 3505 break; 3506 case 'D': 3507 do_destroyed = B_TRUE; 3508 break; 3509 case 'f': 3510 flags |= ZFS_IMPORT_ANY_HOST; 3511 break; 3512 case 'F': 3513 do_rewind = B_TRUE; 3514 break; 3515 case 'l': 3516 flags |= ZFS_IMPORT_LOAD_KEYS; 3517 break; 3518 case 'm': 3519 flags |= ZFS_IMPORT_MISSING_LOG; 3520 break; 3521 case 'n': 3522 dryrun = B_TRUE; 3523 break; 3524 case 'N': 3525 flags |= ZFS_IMPORT_ONLY; 3526 break; 3527 case 'o': 3528 if ((propval = strchr(optarg, '=')) != NULL) { 3529 *propval = '\0'; 3530 propval++; 3531 if (add_prop_list(optarg, propval, 3532 &props, B_TRUE)) 3533 goto error; 3534 } else { 3535 mntopts = optarg; 3536 } 3537 break; 3538 case 'R': 3539 if (add_prop_list(zpool_prop_to_name( 3540 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 3541 goto error; 3542 if (add_prop_list_default(zpool_prop_to_name( 3543 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 3544 goto error; 3545 break; 3546 case 's': 3547 do_scan = B_TRUE; 3548 break; 3549 case 't': 3550 flags |= ZFS_IMPORT_TEMP_NAME; 3551 if (add_prop_list_default(zpool_prop_to_name( 3552 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 3553 goto error; 3554 break; 3555 3556 case 'T': 3557 errno = 0; 3558 txg = strtoull(optarg, &endptr, 0); 3559 if (errno != 0 || *endptr != '\0') { 3560 (void) fprintf(stderr, 3561 gettext("invalid txg value\n")); 3562 usage(B_FALSE); 3563 } 3564 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND; 3565 break; 3566 case 'V': 3567 flags |= ZFS_IMPORT_VERBATIM; 3568 break; 3569 case 'X': 3570 xtreme_rewind = B_TRUE; 3571 break; 3572 case CHECKPOINT_OPT: 3573 flags |= ZFS_IMPORT_CHECKPOINT; 3574 break; 3575 case ':': 3576 (void) fprintf(stderr, gettext("missing argument for " 3577 "'%c' option\n"), optopt); 3578 usage(B_FALSE); 3579 break; 3580 case '?': 3581 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3582 optopt); 3583 usage(B_FALSE); 3584 } 3585 } 3586 3587 argc -= optind; 3588 argv += optind; 3589 3590 if (cachefile && nsearch != 0) { 3591 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 3592 usage(B_FALSE); 3593 } 3594 3595 if (cachefile && do_scan) { 3596 (void) fprintf(stderr, gettext("-c is incompatible with -s\n")); 3597 usage(B_FALSE); 3598 } 3599 3600 if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) { 3601 (void) fprintf(stderr, gettext("-l is incompatible with -N\n")); 3602 usage(B_FALSE); 3603 } 3604 3605 if ((flags & ZFS_IMPORT_LOAD_KEYS) && !do_all && argc == 0) { 3606 (void) fprintf(stderr, gettext("-l is only meaningful during " 3607 "an import\n")); 3608 usage(B_FALSE); 3609 } 3610 3611 if ((dryrun || xtreme_rewind) && !do_rewind) { 3612 (void) fprintf(stderr, 3613 gettext("-n or -X only meaningful with -F\n")); 3614 usage(B_FALSE); 3615 } 3616 if (dryrun) 3617 rewind_policy = ZPOOL_TRY_REWIND; 3618 else if (do_rewind) 3619 rewind_policy = ZPOOL_DO_REWIND; 3620 if (xtreme_rewind) 3621 rewind_policy |= ZPOOL_EXTREME_REWIND; 3622 3623 /* In the future, we can capture further policy and include it here */ 3624 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 3625 nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 || 3626 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 3627 rewind_policy) != 0) 3628 goto error; 3629 3630 /* check argument count */ 3631 if (do_all) { 3632 if (argc != 0) { 3633 (void) fprintf(stderr, gettext("too many arguments\n")); 3634 usage(B_FALSE); 3635 } 3636 } else { 3637 if (argc > 2) { 3638 (void) fprintf(stderr, gettext("too many arguments\n")); 3639 usage(B_FALSE); 3640 } 3641 } 3642 3643 /* 3644 * Check for the effective uid. We do this explicitly here because 3645 * otherwise any attempt to discover pools will silently fail. 3646 */ 3647 if (argc == 0 && geteuid() != 0) { 3648 (void) fprintf(stderr, gettext("cannot " 3649 "discover pools: permission denied\n")); 3650 if (searchdirs != NULL) 3651 free(searchdirs); 3652 3653 nvlist_free(props); 3654 nvlist_free(policy); 3655 return (1); 3656 } 3657 3658 /* 3659 * Depending on the arguments given, we do one of the following: 3660 * 3661 * <none> Iterate through all pools and display information about 3662 * each one. 3663 * 3664 * -a Iterate through all pools and try to import each one. 3665 * 3666 * <id> Find the pool that corresponds to the given GUID/pool 3667 * name and import that one. 3668 * 3669 * -D Above options applies only to destroyed pools. 3670 */ 3671 if (argc != 0) { 3672 char *endptr; 3673 3674 errno = 0; 3675 searchguid = strtoull(argv[0], &endptr, 10); 3676 if (errno != 0 || *endptr != '\0') { 3677 searchname = argv[0]; 3678 searchguid = 0; 3679 } 3680 pool_specified = B_TRUE; 3681 3682 /* 3683 * User specified a name or guid. Ensure it's unique. 3684 */ 3685 target_exists_args_t search = {searchname, searchguid}; 3686 pool_exists = zpool_iter(g_zfs, name_or_guid_exists, &search); 3687 } 3688 3689 /* 3690 * Check the environment for the preferred search path. 3691 */ 3692 if ((searchdirs == NULL) && (env = getenv("ZPOOL_IMPORT_PATH"))) { 3693 char *dir, *tmp = NULL; 3694 3695 envdup = strdup(env); 3696 3697 for (dir = strtok_r(envdup, ":", &tmp); 3698 dir != NULL; 3699 dir = strtok_r(NULL, ":", &tmp)) { 3700 searchdirs = safe_realloc(searchdirs, 3701 (nsearch + 1) * sizeof (char *)); 3702 searchdirs[nsearch++] = dir; 3703 } 3704 } 3705 3706 idata.path = searchdirs; 3707 idata.paths = nsearch; 3708 idata.poolname = searchname; 3709 idata.guid = searchguid; 3710 idata.cachefile = cachefile; 3711 idata.scan = do_scan; 3712 idata.policy = policy; 3713 3714 pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); 3715 3716 if (pools != NULL && pool_exists && 3717 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 3718 (void) fprintf(stderr, gettext("cannot import '%s': " 3719 "a pool with that name already exists\n"), 3720 argv[0]); 3721 (void) fprintf(stderr, gettext("use the form '%s " 3722 "<pool | id> <newpool>' to give it a new name\n"), 3723 "zpool import"); 3724 err = 1; 3725 } else if (pools == NULL && pool_exists) { 3726 (void) fprintf(stderr, gettext("cannot import '%s': " 3727 "a pool with that name is already created/imported,\n"), 3728 argv[0]); 3729 (void) fprintf(stderr, gettext("and no additional pools " 3730 "with that name were found\n")); 3731 err = 1; 3732 } else if (pools == NULL) { 3733 if (argc != 0) { 3734 (void) fprintf(stderr, gettext("cannot import '%s': " 3735 "no such pool available\n"), argv[0]); 3736 } 3737 err = 1; 3738 } 3739 3740 if (err == 1) { 3741 free(searchdirs); 3742 free(envdup); 3743 nvlist_free(policy); 3744 nvlist_free(pools); 3745 nvlist_free(props); 3746 return (1); 3747 } 3748 3749 err = import_pools(pools, props, mntopts, flags, argv[0], 3750 argc == 1 ? NULL : argv[1], do_destroyed, pool_specified, 3751 do_all, &idata); 3752 3753 /* 3754 * If we're using the cachefile and we failed to import, then 3755 * fallback to scanning the directory for pools that match 3756 * those in the cachefile. 3757 */ 3758 if (err != 0 && cachefile != NULL) { 3759 (void) printf(gettext("cachefile import failed, retrying\n")); 3760 3761 /* 3762 * We use the scan flag to gather the directories that exist 3763 * in the cachefile. If we need to fallback to searching for 3764 * the pool config, we will only search devices in these 3765 * directories. 3766 */ 3767 idata.scan = B_TRUE; 3768 nvlist_free(pools); 3769 pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); 3770 3771 err = import_pools(pools, props, mntopts, flags, argv[0], 3772 argc == 1 ? NULL : argv[1], do_destroyed, pool_specified, 3773 do_all, &idata); 3774 } 3775 3776 error: 3777 nvlist_free(props); 3778 nvlist_free(pools); 3779 nvlist_free(policy); 3780 free(searchdirs); 3781 free(envdup); 3782 3783 return (err ? 1 : 0); 3784 } 3785 3786 /* 3787 * zpool sync [-f] [pool] ... 3788 * 3789 * -f (undocumented) force uberblock (and config including zpool cache file) 3790 * update. 3791 * 3792 * Sync the specified pool(s). 3793 * Without arguments "zpool sync" will sync all pools. 3794 * This command initiates TXG sync(s) and will return after the TXG(s) commit. 3795 * 3796 */ 3797 static int 3798 zpool_do_sync(int argc, char **argv) 3799 { 3800 int ret; 3801 boolean_t force = B_FALSE; 3802 3803 /* check options */ 3804 while ((ret = getopt(argc, argv, "f")) != -1) { 3805 switch (ret) { 3806 case 'f': 3807 force = B_TRUE; 3808 break; 3809 case '?': 3810 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3811 optopt); 3812 usage(B_FALSE); 3813 } 3814 } 3815 3816 argc -= optind; 3817 argv += optind; 3818 3819 /* if argc == 0 we will execute zpool_sync_one on all pools */ 3820 ret = for_each_pool(argc, argv, B_FALSE, NULL, B_FALSE, zpool_sync_one, 3821 &force); 3822 3823 return (ret); 3824 } 3825 3826 typedef struct iostat_cbdata { 3827 uint64_t cb_flags; 3828 int cb_name_flags; 3829 int cb_namewidth; 3830 int cb_iteration; 3831 char **cb_vdev_names; /* Only show these vdevs */ 3832 unsigned int cb_vdev_names_count; 3833 boolean_t cb_verbose; 3834 boolean_t cb_literal; 3835 boolean_t cb_scripted; 3836 zpool_list_t *cb_list; 3837 vdev_cmd_data_list_t *vcdl; 3838 } iostat_cbdata_t; 3839 3840 /* iostat labels */ 3841 typedef struct name_and_columns { 3842 const char *name; /* Column name */ 3843 unsigned int columns; /* Center name to this number of columns */ 3844 } name_and_columns_t; 3845 3846 #define IOSTAT_MAX_LABELS 13 /* Max number of labels on one line */ 3847 3848 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] = 3849 { 3850 [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2}, 3851 {NULL}}, 3852 [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2}, 3853 {"asyncq_wait", 2}, {"scrub", 1}, {"trim", 1}, {NULL}}, 3854 [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2}, 3855 {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2}, 3856 {"trimq_write", 2}, {NULL}}, 3857 [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2}, 3858 {"asyncq_wait", 2}, {NULL}}, 3859 [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2}, 3860 {"async_read", 2}, {"async_write", 2}, {"scrub", 2}, 3861 {"trim", 2}, {NULL}}, 3862 }; 3863 3864 /* Shorthand - if "columns" field not set, default to 1 column */ 3865 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] = 3866 { 3867 [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"}, 3868 {"write"}, {NULL}}, 3869 [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"}, 3870 {"write"}, {"read"}, {"write"}, {"wait"}, {"wait"}, {NULL}}, 3871 [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"}, 3872 {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, 3873 {"pend"}, {"activ"}, {NULL}}, 3874 [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"}, 3875 {"write"}, {"read"}, {"write"}, {"scrub"}, {"trim"}, {NULL}}, 3876 [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, 3877 {"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}}, 3878 }; 3879 3880 static const char *histo_to_title[] = { 3881 [IOS_L_HISTO] = "latency", 3882 [IOS_RQ_HISTO] = "req_size", 3883 }; 3884 3885 /* 3886 * Return the number of labels in a null-terminated name_and_columns_t 3887 * array. 3888 * 3889 */ 3890 static unsigned int 3891 label_array_len(const name_and_columns_t *labels) 3892 { 3893 int i = 0; 3894 3895 while (labels[i].name) 3896 i++; 3897 3898 return (i); 3899 } 3900 3901 /* 3902 * Return the number of strings in a null-terminated string array. 3903 * For example: 3904 * 3905 * const char foo[] = {"bar", "baz", NULL} 3906 * 3907 * returns 2 3908 */ 3909 static uint64_t 3910 str_array_len(const char *array[]) 3911 { 3912 uint64_t i = 0; 3913 while (array[i]) 3914 i++; 3915 3916 return (i); 3917 } 3918 3919 3920 /* 3921 * Return a default column width for default/latency/queue columns. This does 3922 * not include histograms, which have their columns autosized. 3923 */ 3924 static unsigned int 3925 default_column_width(iostat_cbdata_t *cb, enum iostat_type type) 3926 { 3927 unsigned long column_width = 5; /* Normal niceprint */ 3928 static unsigned long widths[] = { 3929 /* 3930 * Choose some sane default column sizes for printing the 3931 * raw numbers. 3932 */ 3933 [IOS_DEFAULT] = 15, /* 1PB capacity */ 3934 [IOS_LATENCY] = 10, /* 1B ns = 10sec */ 3935 [IOS_QUEUES] = 6, /* 1M queue entries */ 3936 [IOS_L_HISTO] = 10, /* 1B ns = 10sec */ 3937 [IOS_RQ_HISTO] = 6, /* 1M queue entries */ 3938 }; 3939 3940 if (cb->cb_literal) 3941 column_width = widths[type]; 3942 3943 return (column_width); 3944 } 3945 3946 /* 3947 * Print the column labels, i.e: 3948 * 3949 * capacity operations bandwidth 3950 * alloc free read write read write ... 3951 * 3952 * If force_column_width is set, use it for the column width. If not set, use 3953 * the default column width. 3954 */ 3955 static void 3956 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width, 3957 const name_and_columns_t labels[][IOSTAT_MAX_LABELS]) 3958 { 3959 int i, idx, s; 3960 int text_start, rw_column_width, spaces_to_end; 3961 uint64_t flags = cb->cb_flags; 3962 uint64_t f; 3963 unsigned int column_width = force_column_width; 3964 3965 /* For each bit set in flags */ 3966 for (f = flags; f; f &= ~(1ULL << idx)) { 3967 idx = lowbit64(f) - 1; 3968 if (!force_column_width) 3969 column_width = default_column_width(cb, idx); 3970 /* Print our top labels centered over "read write" label. */ 3971 for (i = 0; i < label_array_len(labels[idx]); i++) { 3972 const char *name = labels[idx][i].name; 3973 /* 3974 * We treat labels[][].columns == 0 as shorthand 3975 * for one column. It makes writing out the label 3976 * tables more concise. 3977 */ 3978 unsigned int columns = MAX(1, labels[idx][i].columns); 3979 unsigned int slen = strlen(name); 3980 3981 rw_column_width = (column_width * columns) + 3982 (2 * (columns - 1)); 3983 3984 text_start = (int)((rw_column_width) / columns - 3985 slen / columns); 3986 if (text_start < 0) 3987 text_start = 0; 3988 3989 printf(" "); /* Two spaces between columns */ 3990 3991 /* Space from beginning of column to label */ 3992 for (s = 0; s < text_start; s++) 3993 printf(" "); 3994 3995 printf("%s", name); 3996 3997 /* Print space after label to end of column */ 3998 spaces_to_end = rw_column_width - text_start - slen; 3999 if (spaces_to_end < 0) 4000 spaces_to_end = 0; 4001 4002 for (s = 0; s < spaces_to_end; s++) 4003 printf(" "); 4004 } 4005 } 4006 } 4007 4008 4009 /* 4010 * print_cmd_columns - Print custom column titles from -c 4011 * 4012 * If the user specified the "zpool status|iostat -c" then print their custom 4013 * column titles in the header. For example, print_cmd_columns() would print 4014 * the " col1 col2" part of this: 4015 * 4016 * $ zpool iostat -vc 'echo col1=val1; echo col2=val2' 4017 * ... 4018 * capacity operations bandwidth 4019 * pool alloc free read write read write col1 col2 4020 * ---------- ----- ----- ----- ----- ----- ----- ---- ---- 4021 * mypool 269K 1008M 0 0 107 946 4022 * mirror 269K 1008M 0 0 107 946 4023 * sdb - - 0 0 102 473 val1 val2 4024 * sdc - - 0 0 5 473 val1 val2 4025 * ---------- ----- ----- ----- ----- ----- ----- ---- ---- 4026 */ 4027 static void 4028 print_cmd_columns(vdev_cmd_data_list_t *vcdl, int use_dashes) 4029 { 4030 int i, j; 4031 vdev_cmd_data_t *data = &vcdl->data[0]; 4032 4033 if (vcdl->count == 0 || data == NULL) 4034 return; 4035 4036 /* 4037 * Each vdev cmd should have the same column names unless the user did 4038 * something weird with their cmd. Just take the column names from the 4039 * first vdev and assume it works for all of them. 4040 */ 4041 for (i = 0; i < vcdl->uniq_cols_cnt; i++) { 4042 printf(" "); 4043 if (use_dashes) { 4044 for (j = 0; j < vcdl->uniq_cols_width[i]; j++) 4045 printf("-"); 4046 } else { 4047 printf_color(ANSI_BOLD, "%*s", vcdl->uniq_cols_width[i], 4048 vcdl->uniq_cols[i]); 4049 } 4050 } 4051 } 4052 4053 4054 /* 4055 * Utility function to print out a line of dashes like: 4056 * 4057 * -------------------------------- ----- ----- ----- ----- ----- 4058 * 4059 * ...or a dashed named-row line like: 4060 * 4061 * logs - - - - - 4062 * 4063 * @cb: iostat data 4064 * 4065 * @force_column_width If non-zero, use the value as the column width. 4066 * Otherwise use the default column widths. 4067 * 4068 * @name: Print a dashed named-row line starting 4069 * with @name. Otherwise, print a regular 4070 * dashed line. 4071 */ 4072 static void 4073 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width, 4074 const char *name) 4075 { 4076 int i; 4077 unsigned int namewidth; 4078 uint64_t flags = cb->cb_flags; 4079 uint64_t f; 4080 int idx; 4081 const name_and_columns_t *labels; 4082 const char *title; 4083 4084 4085 if (cb->cb_flags & IOS_ANYHISTO_M) { 4086 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]; 4087 } else if (cb->cb_vdev_names_count) { 4088 title = "vdev"; 4089 } else { 4090 title = "pool"; 4091 } 4092 4093 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth), 4094 name ? strlen(name) : 0); 4095 4096 4097 if (name) { 4098 printf("%-*s", namewidth, name); 4099 } else { 4100 for (i = 0; i < namewidth; i++) 4101 (void) printf("-"); 4102 } 4103 4104 /* For each bit in flags */ 4105 for (f = flags; f; f &= ~(1ULL << idx)) { 4106 unsigned int column_width; 4107 idx = lowbit64(f) - 1; 4108 if (force_column_width) 4109 column_width = force_column_width; 4110 else 4111 column_width = default_column_width(cb, idx); 4112 4113 labels = iostat_bottom_labels[idx]; 4114 for (i = 0; i < label_array_len(labels); i++) { 4115 if (name) 4116 printf(" %*s-", column_width - 1, " "); 4117 else 4118 printf(" %.*s", column_width, 4119 "--------------------"); 4120 } 4121 } 4122 } 4123 4124 4125 static void 4126 print_iostat_separator_impl(iostat_cbdata_t *cb, 4127 unsigned int force_column_width) 4128 { 4129 print_iostat_dashes(cb, force_column_width, NULL); 4130 } 4131 4132 static void 4133 print_iostat_separator(iostat_cbdata_t *cb) 4134 { 4135 print_iostat_separator_impl(cb, 0); 4136 } 4137 4138 static void 4139 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width, 4140 const char *histo_vdev_name) 4141 { 4142 unsigned int namewidth; 4143 const char *title; 4144 4145 if (cb->cb_flags & IOS_ANYHISTO_M) { 4146 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]; 4147 } else if (cb->cb_vdev_names_count) { 4148 title = "vdev"; 4149 } else { 4150 title = "pool"; 4151 } 4152 4153 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth), 4154 histo_vdev_name ? strlen(histo_vdev_name) : 0); 4155 4156 if (histo_vdev_name) 4157 printf("%-*s", namewidth, histo_vdev_name); 4158 else 4159 printf("%*s", namewidth, ""); 4160 4161 4162 print_iostat_labels(cb, force_column_width, iostat_top_labels); 4163 printf("\n"); 4164 4165 printf("%-*s", namewidth, title); 4166 4167 print_iostat_labels(cb, force_column_width, iostat_bottom_labels); 4168 if (cb->vcdl != NULL) 4169 print_cmd_columns(cb->vcdl, 0); 4170 4171 printf("\n"); 4172 4173 print_iostat_separator_impl(cb, force_column_width); 4174 4175 if (cb->vcdl != NULL) 4176 print_cmd_columns(cb->vcdl, 1); 4177 4178 printf("\n"); 4179 } 4180 4181 static void 4182 print_iostat_header(iostat_cbdata_t *cb) 4183 { 4184 print_iostat_header_impl(cb, 0, NULL); 4185 } 4186 4187 4188 /* 4189 * Display a single statistic. 4190 */ 4191 static void 4192 print_one_stat(uint64_t value, enum zfs_nicenum_format format, 4193 unsigned int column_size, boolean_t scripted) 4194 { 4195 char buf[64]; 4196 4197 zfs_nicenum_format(value, buf, sizeof (buf), format); 4198 4199 if (scripted) 4200 printf("\t%s", buf); 4201 else 4202 printf(" %*s", column_size, buf); 4203 } 4204 4205 /* 4206 * Calculate the default vdev stats 4207 * 4208 * Subtract oldvs from newvs, apply a scaling factor, and save the resulting 4209 * stats into calcvs. 4210 */ 4211 static void 4212 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs, 4213 vdev_stat_t *calcvs) 4214 { 4215 int i; 4216 4217 memcpy(calcvs, newvs, sizeof (*calcvs)); 4218 for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++) 4219 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]); 4220 4221 for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++) 4222 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]); 4223 } 4224 4225 /* 4226 * Internal representation of the extended iostats data. 4227 * 4228 * The extended iostat stats are exported in nvlists as either uint64_t arrays 4229 * or single uint64_t's. We make both look like arrays to make them easier 4230 * to process. In order to make single uint64_t's look like arrays, we set 4231 * __data to the stat data, and then set *data = &__data with count = 1. Then, 4232 * we can just use *data and count. 4233 */ 4234 struct stat_array { 4235 uint64_t *data; 4236 uint_t count; /* Number of entries in data[] */ 4237 uint64_t __data; /* Only used when data is a single uint64_t */ 4238 }; 4239 4240 static uint64_t 4241 stat_histo_max(struct stat_array *nva, unsigned int len) 4242 { 4243 uint64_t max = 0; 4244 int i; 4245 for (i = 0; i < len; i++) 4246 max = MAX(max, array64_max(nva[i].data, nva[i].count)); 4247 4248 return (max); 4249 } 4250 4251 /* 4252 * Helper function to lookup a uint64_t array or uint64_t value and store its 4253 * data as a stat_array. If the nvpair is a single uint64_t value, then we make 4254 * it look like a one element array to make it easier to process. 4255 */ 4256 static int 4257 nvpair64_to_stat_array(nvlist_t *nvl, const char *name, 4258 struct stat_array *nva) 4259 { 4260 nvpair_t *tmp; 4261 int ret; 4262 4263 verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0); 4264 switch (nvpair_type(tmp)) { 4265 case DATA_TYPE_UINT64_ARRAY: 4266 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count); 4267 break; 4268 case DATA_TYPE_UINT64: 4269 ret = nvpair_value_uint64(tmp, &nva->__data); 4270 nva->data = &nva->__data; 4271 nva->count = 1; 4272 break; 4273 default: 4274 /* Not a uint64_t */ 4275 ret = EINVAL; 4276 break; 4277 } 4278 4279 return (ret); 4280 } 4281 4282 /* 4283 * Given a list of nvlist names, look up the extended stats in newnv and oldnv, 4284 * subtract them, and return the results in a newly allocated stat_array. 4285 * You must free the returned array after you are done with it with 4286 * free_calc_stats(). 4287 * 4288 * Additionally, you can set "oldnv" to NULL if you simply want the newnv 4289 * values. 4290 */ 4291 static struct stat_array * 4292 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv, 4293 nvlist_t *newnv) 4294 { 4295 nvlist_t *oldnvx = NULL, *newnvx; 4296 struct stat_array *oldnva, *newnva, *calcnva; 4297 int i, j; 4298 unsigned int alloc_size = (sizeof (struct stat_array)) * len; 4299 4300 /* Extract our extended stats nvlist from the main list */ 4301 verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX, 4302 &newnvx) == 0); 4303 if (oldnv) { 4304 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX, 4305 &oldnvx) == 0); 4306 } 4307 4308 newnva = safe_malloc(alloc_size); 4309 oldnva = safe_malloc(alloc_size); 4310 calcnva = safe_malloc(alloc_size); 4311 4312 for (j = 0; j < len; j++) { 4313 verify(nvpair64_to_stat_array(newnvx, names[j], 4314 &newnva[j]) == 0); 4315 calcnva[j].count = newnva[j].count; 4316 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]); 4317 calcnva[j].data = safe_malloc(alloc_size); 4318 memcpy(calcnva[j].data, newnva[j].data, alloc_size); 4319 4320 if (oldnvx) { 4321 verify(nvpair64_to_stat_array(oldnvx, names[j], 4322 &oldnva[j]) == 0); 4323 for (i = 0; i < oldnva[j].count; i++) 4324 calcnva[j].data[i] -= oldnva[j].data[i]; 4325 } 4326 } 4327 free(newnva); 4328 free(oldnva); 4329 return (calcnva); 4330 } 4331 4332 static void 4333 free_calc_stats(struct stat_array *nva, unsigned int len) 4334 { 4335 int i; 4336 for (i = 0; i < len; i++) 4337 free(nva[i].data); 4338 4339 free(nva); 4340 } 4341 4342 static void 4343 print_iostat_histo(struct stat_array *nva, unsigned int len, 4344 iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth, 4345 double scale) 4346 { 4347 int i, j; 4348 char buf[6]; 4349 uint64_t val; 4350 enum zfs_nicenum_format format; 4351 unsigned int buckets; 4352 unsigned int start_bucket; 4353 4354 if (cb->cb_literal) 4355 format = ZFS_NICENUM_RAW; 4356 else 4357 format = ZFS_NICENUM_1024; 4358 4359 /* All these histos are the same size, so just use nva[0].count */ 4360 buckets = nva[0].count; 4361 4362 if (cb->cb_flags & IOS_RQ_HISTO_M) { 4363 /* Start at 512 - req size should never be lower than this */ 4364 start_bucket = 9; 4365 } else { 4366 start_bucket = 0; 4367 } 4368 4369 for (j = start_bucket; j < buckets; j++) { 4370 /* Print histogram bucket label */ 4371 if (cb->cb_flags & IOS_L_HISTO_M) { 4372 /* Ending range of this bucket */ 4373 val = (1UL << (j + 1)) - 1; 4374 zfs_nicetime(val, buf, sizeof (buf)); 4375 } else { 4376 /* Request size (starting range of bucket) */ 4377 val = (1UL << j); 4378 zfs_nicenum(val, buf, sizeof (buf)); 4379 } 4380 4381 if (cb->cb_scripted) 4382 printf("%llu", (u_longlong_t)val); 4383 else 4384 printf("%-*s", namewidth, buf); 4385 4386 /* Print the values on the line */ 4387 for (i = 0; i < len; i++) { 4388 print_one_stat(nva[i].data[j] * scale, format, 4389 column_width, cb->cb_scripted); 4390 } 4391 printf("\n"); 4392 } 4393 } 4394 4395 static void 4396 print_solid_separator(unsigned int length) 4397 { 4398 while (length--) 4399 printf("-"); 4400 printf("\n"); 4401 } 4402 4403 static void 4404 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv, 4405 nvlist_t *newnv, double scale, const char *name) 4406 { 4407 unsigned int column_width; 4408 unsigned int namewidth; 4409 unsigned int entire_width; 4410 enum iostat_type type; 4411 struct stat_array *nva; 4412 const char **names; 4413 unsigned int names_len; 4414 4415 /* What type of histo are we? */ 4416 type = IOS_HISTO_IDX(cb->cb_flags); 4417 4418 /* Get NULL-terminated array of nvlist names for our histo */ 4419 names = vsx_type_to_nvlist[type]; 4420 names_len = str_array_len(names); /* num of names */ 4421 4422 nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv); 4423 4424 if (cb->cb_literal) { 4425 column_width = MAX(5, 4426 (unsigned int) log10(stat_histo_max(nva, names_len)) + 1); 4427 } else { 4428 column_width = 5; 4429 } 4430 4431 namewidth = MAX(cb->cb_namewidth, 4432 strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)])); 4433 4434 /* 4435 * Calculate the entire line width of what we're printing. The 4436 * +2 is for the two spaces between columns: 4437 */ 4438 /* read write */ 4439 /* ----- ----- */ 4440 /* |___| <---------- column_width */ 4441 /* */ 4442 /* |__________| <--- entire_width */ 4443 /* */ 4444 entire_width = namewidth + (column_width + 2) * 4445 label_array_len(iostat_bottom_labels[type]); 4446 4447 if (cb->cb_scripted) 4448 printf("%s\n", name); 4449 else 4450 print_iostat_header_impl(cb, column_width, name); 4451 4452 print_iostat_histo(nva, names_len, cb, column_width, 4453 namewidth, scale); 4454 4455 free_calc_stats(nva, names_len); 4456 if (!cb->cb_scripted) 4457 print_solid_separator(entire_width); 4458 } 4459 4460 /* 4461 * Calculate the average latency of a power-of-two latency histogram 4462 */ 4463 static uint64_t 4464 single_histo_average(uint64_t *histo, unsigned int buckets) 4465 { 4466 int i; 4467 uint64_t count = 0, total = 0; 4468 4469 for (i = 0; i < buckets; i++) { 4470 /* 4471 * Our buckets are power-of-two latency ranges. Use the 4472 * midpoint latency of each bucket to calculate the average. 4473 * For example: 4474 * 4475 * Bucket Midpoint 4476 * 8ns-15ns: 12ns 4477 * 16ns-31ns: 24ns 4478 * ... 4479 */ 4480 if (histo[i] != 0) { 4481 total += histo[i] * (((1UL << i) + ((1UL << i)/2))); 4482 count += histo[i]; 4483 } 4484 } 4485 4486 /* Prevent divide by zero */ 4487 return (count == 0 ? 0 : total / count); 4488 } 4489 4490 static void 4491 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv, 4492 nvlist_t *newnv) 4493 { 4494 int i; 4495 uint64_t val; 4496 const char *names[] = { 4497 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE, 4498 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE, 4499 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE, 4500 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE, 4501 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE, 4502 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE, 4503 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE, 4504 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE, 4505 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE, 4506 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE, 4507 ZPOOL_CONFIG_VDEV_TRIM_PEND_QUEUE, 4508 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE, 4509 }; 4510 4511 struct stat_array *nva; 4512 4513 unsigned int column_width = default_column_width(cb, IOS_QUEUES); 4514 enum zfs_nicenum_format format; 4515 4516 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv); 4517 4518 if (cb->cb_literal) 4519 format = ZFS_NICENUM_RAW; 4520 else 4521 format = ZFS_NICENUM_1024; 4522 4523 for (i = 0; i < ARRAY_SIZE(names); i++) { 4524 val = nva[i].data[0]; 4525 print_one_stat(val, format, column_width, cb->cb_scripted); 4526 } 4527 4528 free_calc_stats(nva, ARRAY_SIZE(names)); 4529 } 4530 4531 static void 4532 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv, 4533 nvlist_t *newnv) 4534 { 4535 int i; 4536 uint64_t val; 4537 const char *names[] = { 4538 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 4539 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 4540 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 4541 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 4542 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO, 4543 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO, 4544 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO, 4545 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO, 4546 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO, 4547 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 4548 }; 4549 struct stat_array *nva; 4550 4551 unsigned int column_width = default_column_width(cb, IOS_LATENCY); 4552 enum zfs_nicenum_format format; 4553 4554 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv); 4555 4556 if (cb->cb_literal) 4557 format = ZFS_NICENUM_RAWTIME; 4558 else 4559 format = ZFS_NICENUM_TIME; 4560 4561 /* Print our avg latencies on the line */ 4562 for (i = 0; i < ARRAY_SIZE(names); i++) { 4563 /* Compute average latency for a latency histo */ 4564 val = single_histo_average(nva[i].data, nva[i].count); 4565 print_one_stat(val, format, column_width, cb->cb_scripted); 4566 } 4567 free_calc_stats(nva, ARRAY_SIZE(names)); 4568 } 4569 4570 /* 4571 * Print default statistics (capacity/operations/bandwidth) 4572 */ 4573 static void 4574 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale) 4575 { 4576 unsigned int column_width = default_column_width(cb, IOS_DEFAULT); 4577 enum zfs_nicenum_format format; 4578 char na; /* char to print for "not applicable" values */ 4579 4580 if (cb->cb_literal) { 4581 format = ZFS_NICENUM_RAW; 4582 na = '0'; 4583 } else { 4584 format = ZFS_NICENUM_1024; 4585 na = '-'; 4586 } 4587 4588 /* only toplevel vdevs have capacity stats */ 4589 if (vs->vs_space == 0) { 4590 if (cb->cb_scripted) 4591 printf("\t%c\t%c", na, na); 4592 else 4593 printf(" %*c %*c", column_width, na, column_width, 4594 na); 4595 } else { 4596 print_one_stat(vs->vs_alloc, format, column_width, 4597 cb->cb_scripted); 4598 print_one_stat(vs->vs_space - vs->vs_alloc, format, 4599 column_width, cb->cb_scripted); 4600 } 4601 4602 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale), 4603 format, column_width, cb->cb_scripted); 4604 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale), 4605 format, column_width, cb->cb_scripted); 4606 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale), 4607 format, column_width, cb->cb_scripted); 4608 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale), 4609 format, column_width, cb->cb_scripted); 4610 } 4611 4612 static const char *class_name[] = { 4613 VDEV_ALLOC_BIAS_DEDUP, 4614 VDEV_ALLOC_BIAS_SPECIAL, 4615 VDEV_ALLOC_CLASS_LOGS 4616 }; 4617 4618 /* 4619 * Print out all the statistics for the given vdev. This can either be the 4620 * toplevel configuration, or called recursively. If 'name' is NULL, then this 4621 * is a verbose output, and we don't want to display the toplevel pool stats. 4622 * 4623 * Returns the number of stat lines printed. 4624 */ 4625 static unsigned int 4626 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 4627 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 4628 { 4629 nvlist_t **oldchild, **newchild; 4630 uint_t c, children, oldchildren; 4631 vdev_stat_t *oldvs, *newvs, *calcvs; 4632 vdev_stat_t zerovs = { 0 }; 4633 char *vname; 4634 int i; 4635 int ret = 0; 4636 uint64_t tdelta; 4637 double scale; 4638 4639 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 4640 return (ret); 4641 4642 calcvs = safe_malloc(sizeof (*calcvs)); 4643 4644 if (oldnv != NULL) { 4645 verify(nvlist_lookup_uint64_array(oldnv, 4646 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 4647 } else { 4648 oldvs = &zerovs; 4649 } 4650 4651 /* Do we only want to see a specific vdev? */ 4652 for (i = 0; i < cb->cb_vdev_names_count; i++) { 4653 /* Yes we do. Is this the vdev? */ 4654 if (strcmp(name, cb->cb_vdev_names[i]) == 0) { 4655 /* 4656 * This is our vdev. Since it is the only vdev we 4657 * will be displaying, make depth = 0 so that it 4658 * doesn't get indented. 4659 */ 4660 depth = 0; 4661 break; 4662 } 4663 } 4664 4665 if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) { 4666 /* Couldn't match the name */ 4667 goto children; 4668 } 4669 4670 4671 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 4672 (uint64_t **)&newvs, &c) == 0); 4673 4674 /* 4675 * Print the vdev name unless it's is a histogram. Histograms 4676 * display the vdev name in the header itself. 4677 */ 4678 if (!(cb->cb_flags & IOS_ANYHISTO_M)) { 4679 if (cb->cb_scripted) { 4680 printf("%s", name); 4681 } else { 4682 if (strlen(name) + depth > cb->cb_namewidth) 4683 (void) printf("%*s%s", depth, "", name); 4684 else 4685 (void) printf("%*s%s%*s", depth, "", name, 4686 (int)(cb->cb_namewidth - strlen(name) - 4687 depth), ""); 4688 } 4689 } 4690 4691 /* Calculate our scaling factor */ 4692 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 4693 if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) { 4694 /* 4695 * If we specify printing histograms with no time interval, then 4696 * print the histogram numbers over the entire lifetime of the 4697 * vdev. 4698 */ 4699 scale = 1; 4700 } else { 4701 if (tdelta == 0) 4702 scale = 1.0; 4703 else 4704 scale = (double)NANOSEC / tdelta; 4705 } 4706 4707 if (cb->cb_flags & IOS_DEFAULT_M) { 4708 calc_default_iostats(oldvs, newvs, calcvs); 4709 print_iostat_default(calcvs, cb, scale); 4710 } 4711 if (cb->cb_flags & IOS_LATENCY_M) 4712 print_iostat_latency(cb, oldnv, newnv); 4713 if (cb->cb_flags & IOS_QUEUES_M) 4714 print_iostat_queues(cb, oldnv, newnv); 4715 if (cb->cb_flags & IOS_ANYHISTO_M) { 4716 printf("\n"); 4717 print_iostat_histos(cb, oldnv, newnv, scale, name); 4718 } 4719 4720 if (cb->vcdl != NULL) { 4721 char *path; 4722 if (nvlist_lookup_string(newnv, ZPOOL_CONFIG_PATH, 4723 &path) == 0) { 4724 printf(" "); 4725 zpool_print_cmd(cb->vcdl, zpool_get_name(zhp), path); 4726 } 4727 } 4728 4729 if (!(cb->cb_flags & IOS_ANYHISTO_M)) 4730 printf("\n"); 4731 4732 ret++; 4733 4734 children: 4735 4736 free(calcvs); 4737 4738 if (!cb->cb_verbose) 4739 return (ret); 4740 4741 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 4742 &newchild, &children) != 0) 4743 return (ret); 4744 4745 if (oldnv) { 4746 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 4747 &oldchild, &oldchildren) != 0) 4748 return (ret); 4749 4750 children = MIN(oldchildren, children); 4751 } 4752 4753 /* 4754 * print normal top-level devices 4755 */ 4756 for (c = 0; c < children; c++) { 4757 uint64_t ishole = B_FALSE, islog = B_FALSE; 4758 4759 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 4760 &ishole); 4761 4762 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 4763 &islog); 4764 4765 if (ishole || islog) 4766 continue; 4767 4768 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 4769 continue; 4770 4771 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4772 cb->cb_name_flags); 4773 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 4774 newchild[c], cb, depth + 2); 4775 free(vname); 4776 } 4777 4778 /* 4779 * print all other top-level devices 4780 */ 4781 for (uint_t n = 0; n < 3; n++) { 4782 boolean_t printed = B_FALSE; 4783 4784 for (c = 0; c < children; c++) { 4785 uint64_t islog = B_FALSE; 4786 char *bias = NULL; 4787 char *type = NULL; 4788 4789 (void) nvlist_lookup_uint64(newchild[c], 4790 ZPOOL_CONFIG_IS_LOG, &islog); 4791 if (islog) { 4792 bias = VDEV_ALLOC_CLASS_LOGS; 4793 } else { 4794 (void) nvlist_lookup_string(newchild[c], 4795 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 4796 (void) nvlist_lookup_string(newchild[c], 4797 ZPOOL_CONFIG_TYPE, &type); 4798 } 4799 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 4800 continue; 4801 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 4802 continue; 4803 4804 if (!printed) { 4805 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && 4806 !cb->cb_scripted && !cb->cb_vdev_names) { 4807 print_iostat_dashes(cb, 0, 4808 class_name[n]); 4809 } 4810 printf("\n"); 4811 printed = B_TRUE; 4812 } 4813 4814 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4815 cb->cb_name_flags); 4816 ret += print_vdev_stats(zhp, vname, oldnv ? 4817 oldchild[c] : NULL, newchild[c], cb, depth + 2); 4818 free(vname); 4819 } 4820 } 4821 4822 /* 4823 * Include level 2 ARC devices in iostat output 4824 */ 4825 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 4826 &newchild, &children) != 0) 4827 return (ret); 4828 4829 if (oldnv) { 4830 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 4831 &oldchild, &oldchildren) != 0) 4832 return (ret); 4833 4834 children = MIN(oldchildren, children); 4835 } 4836 4837 if (children > 0) { 4838 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted && 4839 !cb->cb_vdev_names) { 4840 print_iostat_dashes(cb, 0, "cache"); 4841 } 4842 printf("\n"); 4843 4844 for (c = 0; c < children; c++) { 4845 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4846 cb->cb_name_flags); 4847 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] 4848 : NULL, newchild[c], cb, depth + 2); 4849 free(vname); 4850 } 4851 } 4852 4853 return (ret); 4854 } 4855 4856 static int 4857 refresh_iostat(zpool_handle_t *zhp, void *data) 4858 { 4859 iostat_cbdata_t *cb = data; 4860 boolean_t missing; 4861 4862 /* 4863 * If the pool has disappeared, remove it from the list and continue. 4864 */ 4865 if (zpool_refresh_stats(zhp, &missing) != 0) 4866 return (-1); 4867 4868 if (missing) 4869 pool_list_remove(cb->cb_list, zhp); 4870 4871 return (0); 4872 } 4873 4874 /* 4875 * Callback to print out the iostats for the given pool. 4876 */ 4877 static int 4878 print_iostat(zpool_handle_t *zhp, void *data) 4879 { 4880 iostat_cbdata_t *cb = data; 4881 nvlist_t *oldconfig, *newconfig; 4882 nvlist_t *oldnvroot, *newnvroot; 4883 int ret; 4884 4885 newconfig = zpool_get_config(zhp, &oldconfig); 4886 4887 if (cb->cb_iteration == 1) 4888 oldconfig = NULL; 4889 4890 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 4891 &newnvroot) == 0); 4892 4893 if (oldconfig == NULL) 4894 oldnvroot = NULL; 4895 else 4896 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 4897 &oldnvroot) == 0); 4898 4899 ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, 4900 cb, 0); 4901 if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) && 4902 !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) { 4903 print_iostat_separator(cb); 4904 if (cb->vcdl != NULL) { 4905 print_cmd_columns(cb->vcdl, 1); 4906 } 4907 printf("\n"); 4908 } 4909 4910 return (ret); 4911 } 4912 4913 static int 4914 get_columns(void) 4915 { 4916 struct winsize ws; 4917 int columns = 80; 4918 int error; 4919 4920 if (isatty(STDOUT_FILENO)) { 4921 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); 4922 if (error == 0) 4923 columns = ws.ws_col; 4924 } else { 4925 columns = 999; 4926 } 4927 4928 return (columns); 4929 } 4930 4931 /* 4932 * Return the required length of the pool/vdev name column. The minimum 4933 * allowed width and output formatting flags must be provided. 4934 */ 4935 static int 4936 get_namewidth(zpool_handle_t *zhp, int min_width, int flags, boolean_t verbose) 4937 { 4938 nvlist_t *config, *nvroot; 4939 int width = min_width; 4940 4941 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 4942 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 4943 &nvroot) == 0); 4944 unsigned int poolname_len = strlen(zpool_get_name(zhp)); 4945 if (verbose == B_FALSE) { 4946 width = MAX(poolname_len, min_width); 4947 } else { 4948 width = MAX(poolname_len, 4949 max_width(zhp, nvroot, 0, min_width, flags)); 4950 } 4951 } 4952 4953 return (width); 4954 } 4955 4956 /* 4957 * Parse the input string, get the 'interval' and 'count' value if there is one. 4958 */ 4959 static void 4960 get_interval_count(int *argcp, char **argv, float *iv, 4961 unsigned long *cnt) 4962 { 4963 float interval = 0; 4964 unsigned long count = 0; 4965 int argc = *argcp; 4966 4967 /* 4968 * Determine if the last argument is an integer or a pool name 4969 */ 4970 if (argc > 0 && zfs_isnumber(argv[argc - 1])) { 4971 char *end; 4972 4973 errno = 0; 4974 interval = strtof(argv[argc - 1], &end); 4975 4976 if (*end == '\0' && errno == 0) { 4977 if (interval == 0) { 4978 (void) fprintf(stderr, gettext( 4979 "interval cannot be zero\n")); 4980 usage(B_FALSE); 4981 } 4982 /* 4983 * Ignore the last parameter 4984 */ 4985 argc--; 4986 } else { 4987 /* 4988 * If this is not a valid number, just plow on. The 4989 * user will get a more informative error message later 4990 * on. 4991 */ 4992 interval = 0; 4993 } 4994 } 4995 4996 /* 4997 * If the last argument is also an integer, then we have both a count 4998 * and an interval. 4999 */ 5000 if (argc > 0 && zfs_isnumber(argv[argc - 1])) { 5001 char *end; 5002 5003 errno = 0; 5004 count = interval; 5005 interval = strtof(argv[argc - 1], &end); 5006 5007 if (*end == '\0' && errno == 0) { 5008 if (interval == 0) { 5009 (void) fprintf(stderr, gettext( 5010 "interval cannot be zero\n")); 5011 usage(B_FALSE); 5012 } 5013 5014 /* 5015 * Ignore the last parameter 5016 */ 5017 argc--; 5018 } else { 5019 interval = 0; 5020 } 5021 } 5022 5023 *iv = interval; 5024 *cnt = count; 5025 *argcp = argc; 5026 } 5027 5028 static void 5029 get_timestamp_arg(char c) 5030 { 5031 if (c == 'u') 5032 timestamp_fmt = UDATE; 5033 else if (c == 'd') 5034 timestamp_fmt = DDATE; 5035 else 5036 usage(B_FALSE); 5037 } 5038 5039 /* 5040 * Return stat flags that are supported by all pools by both the module and 5041 * zpool iostat. "*data" should be initialized to all 0xFFs before running. 5042 * It will get ANDed down until only the flags that are supported on all pools 5043 * remain. 5044 */ 5045 static int 5046 get_stat_flags_cb(zpool_handle_t *zhp, void *data) 5047 { 5048 uint64_t *mask = data; 5049 nvlist_t *config, *nvroot, *nvx; 5050 uint64_t flags = 0; 5051 int i, j; 5052 5053 config = zpool_get_config(zhp, NULL); 5054 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 5055 &nvroot) == 0); 5056 5057 /* Default stats are always supported, but for completeness.. */ 5058 if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS)) 5059 flags |= IOS_DEFAULT_M; 5060 5061 /* Get our extended stats nvlist from the main list */ 5062 if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX, 5063 &nvx) != 0) { 5064 /* 5065 * No extended stats; they're probably running an older 5066 * module. No big deal, we support that too. 5067 */ 5068 goto end; 5069 } 5070 5071 /* For each extended stat, make sure all its nvpairs are supported */ 5072 for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) { 5073 if (!vsx_type_to_nvlist[j][0]) 5074 continue; 5075 5076 /* Start off by assuming the flag is supported, then check */ 5077 flags |= (1ULL << j); 5078 for (i = 0; vsx_type_to_nvlist[j][i]; i++) { 5079 if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) { 5080 /* flag isn't supported */ 5081 flags = flags & ~(1ULL << j); 5082 break; 5083 } 5084 } 5085 } 5086 end: 5087 *mask = *mask & flags; 5088 return (0); 5089 } 5090 5091 /* 5092 * Return a bitmask of stats that are supported on all pools by both the module 5093 * and zpool iostat. 5094 */ 5095 static uint64_t 5096 get_stat_flags(zpool_list_t *list) 5097 { 5098 uint64_t mask = -1; 5099 5100 /* 5101 * get_stat_flags_cb() will lop off bits from "mask" until only the 5102 * flags that are supported on all pools remain. 5103 */ 5104 pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask); 5105 return (mask); 5106 } 5107 5108 /* 5109 * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise. 5110 */ 5111 static int 5112 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data) 5113 { 5114 iostat_cbdata_t *cb = cb_data; 5115 char *name = NULL; 5116 int ret = 0; 5117 5118 name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags); 5119 5120 if (strcmp(name, cb->cb_vdev_names[0]) == 0) 5121 ret = 1; /* match */ 5122 free(name); 5123 5124 return (ret); 5125 } 5126 5127 /* 5128 * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise. 5129 */ 5130 static int 5131 is_vdev(zpool_handle_t *zhp, void *cb_data) 5132 { 5133 return (for_each_vdev(zhp, is_vdev_cb, cb_data)); 5134 } 5135 5136 /* 5137 * Check if vdevs are in a pool 5138 * 5139 * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise 5140 * return 0. If pool_name is NULL, then search all pools. 5141 */ 5142 static int 5143 are_vdevs_in_pool(int argc, char **argv, char *pool_name, 5144 iostat_cbdata_t *cb) 5145 { 5146 char **tmp_name; 5147 int ret = 0; 5148 int i; 5149 int pool_count = 0; 5150 5151 if ((argc == 0) || !*argv) 5152 return (0); 5153 5154 if (pool_name) 5155 pool_count = 1; 5156 5157 /* Temporarily hijack cb_vdev_names for a second... */ 5158 tmp_name = cb->cb_vdev_names; 5159 5160 /* Go though our list of prospective vdev names */ 5161 for (i = 0; i < argc; i++) { 5162 cb->cb_vdev_names = argv + i; 5163 5164 /* Is this name a vdev in our pools? */ 5165 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL, 5166 B_FALSE, is_vdev, cb); 5167 if (!ret) { 5168 /* No match */ 5169 break; 5170 } 5171 } 5172 5173 cb->cb_vdev_names = tmp_name; 5174 5175 return (ret); 5176 } 5177 5178 static int 5179 is_pool_cb(zpool_handle_t *zhp, void *data) 5180 { 5181 char *name = data; 5182 if (strcmp(name, zpool_get_name(zhp)) == 0) 5183 return (1); 5184 5185 return (0); 5186 } 5187 5188 /* 5189 * Do we have a pool named *name? If so, return 1, otherwise 0. 5190 */ 5191 static int 5192 is_pool(char *name) 5193 { 5194 return (for_each_pool(0, NULL, B_TRUE, NULL, B_FALSE, is_pool_cb, 5195 name)); 5196 } 5197 5198 /* Are all our argv[] strings pool names? If so return 1, 0 otherwise. */ 5199 static int 5200 are_all_pools(int argc, char **argv) 5201 { 5202 if ((argc == 0) || !*argv) 5203 return (0); 5204 5205 while (--argc >= 0) 5206 if (!is_pool(argv[argc])) 5207 return (0); 5208 5209 return (1); 5210 } 5211 5212 /* 5213 * Helper function to print out vdev/pool names we can't resolve. Used for an 5214 * error message. 5215 */ 5216 static void 5217 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name, 5218 iostat_cbdata_t *cb) 5219 { 5220 int i; 5221 char *name; 5222 char *str; 5223 for (i = 0; i < argc; i++) { 5224 name = argv[i]; 5225 5226 if (is_pool(name)) 5227 str = gettext("pool"); 5228 else if (are_vdevs_in_pool(1, &name, pool_name, cb)) 5229 str = gettext("vdev in this pool"); 5230 else if (are_vdevs_in_pool(1, &name, NULL, cb)) 5231 str = gettext("vdev in another pool"); 5232 else 5233 str = gettext("unknown"); 5234 5235 fprintf(stderr, "\t%s (%s)\n", name, str); 5236 } 5237 } 5238 5239 /* 5240 * Same as get_interval_count(), but with additional checks to not misinterpret 5241 * guids as interval/count values. Assumes VDEV_NAME_GUID is set in 5242 * cb.cb_name_flags. 5243 */ 5244 static void 5245 get_interval_count_filter_guids(int *argc, char **argv, float *interval, 5246 unsigned long *count, iostat_cbdata_t *cb) 5247 { 5248 char **tmpargv = argv; 5249 int argc_for_interval = 0; 5250 5251 /* Is the last arg an interval value? Or a guid? */ 5252 if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) { 5253 /* 5254 * The last arg is not a guid, so it's probably an 5255 * interval value. 5256 */ 5257 argc_for_interval++; 5258 5259 if (*argc >= 2 && 5260 !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) { 5261 /* 5262 * The 2nd to last arg is not a guid, so it's probably 5263 * an interval value. 5264 */ 5265 argc_for_interval++; 5266 } 5267 } 5268 5269 /* Point to our list of possible intervals */ 5270 tmpargv = &argv[*argc - argc_for_interval]; 5271 5272 *argc = *argc - argc_for_interval; 5273 get_interval_count(&argc_for_interval, tmpargv, 5274 interval, count); 5275 } 5276 5277 /* 5278 * Floating point sleep(). Allows you to pass in a floating point value for 5279 * seconds. 5280 */ 5281 static void 5282 fsleep(float sec) 5283 { 5284 struct timespec req; 5285 req.tv_sec = floor(sec); 5286 req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC; 5287 nanosleep(&req, NULL); 5288 } 5289 5290 /* 5291 * Terminal height, in rows. Returns -1 if stdout is not connected to a TTY or 5292 * if we were unable to determine its size. 5293 */ 5294 static int 5295 terminal_height(void) 5296 { 5297 struct winsize win; 5298 5299 if (isatty(STDOUT_FILENO) == 0) 5300 return (-1); 5301 5302 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 && win.ws_row > 0) 5303 return (win.ws_row); 5304 5305 return (-1); 5306 } 5307 5308 /* 5309 * Run one of the zpool status/iostat -c scripts with the help (-h) option and 5310 * print the result. 5311 * 5312 * name: Short name of the script ('iostat'). 5313 * path: Full path to the script ('/usr/local/etc/zfs/zpool.d/iostat'); 5314 */ 5315 static void 5316 print_zpool_script_help(char *name, char *path) 5317 { 5318 char *argv[] = {path, "-h", NULL}; 5319 char **lines = NULL; 5320 int lines_cnt = 0; 5321 int rc; 5322 5323 rc = libzfs_run_process_get_stdout_nopath(path, argv, NULL, &lines, 5324 &lines_cnt); 5325 if (rc != 0 || lines == NULL || lines_cnt <= 0) { 5326 if (lines != NULL) 5327 libzfs_free_str_array(lines, lines_cnt); 5328 return; 5329 } 5330 5331 for (int i = 0; i < lines_cnt; i++) 5332 if (!is_blank_str(lines[i])) 5333 printf(" %-14s %s\n", name, lines[i]); 5334 5335 libzfs_free_str_array(lines, lines_cnt); 5336 } 5337 5338 /* 5339 * Go though the zpool status/iostat -c scripts in the user's path, run their 5340 * help option (-h), and print out the results. 5341 */ 5342 static void 5343 print_zpool_dir_scripts(char *dirpath) 5344 { 5345 DIR *dir; 5346 struct dirent *ent; 5347 char fullpath[MAXPATHLEN]; 5348 struct stat dir_stat; 5349 5350 if ((dir = opendir(dirpath)) != NULL) { 5351 /* print all the files and directories within directory */ 5352 while ((ent = readdir(dir)) != NULL) { 5353 sprintf(fullpath, "%s/%s", dirpath, ent->d_name); 5354 5355 /* Print the scripts */ 5356 if (stat(fullpath, &dir_stat) == 0) 5357 if (dir_stat.st_mode & S_IXUSR && 5358 S_ISREG(dir_stat.st_mode)) 5359 print_zpool_script_help(ent->d_name, 5360 fullpath); 5361 } 5362 closedir(dir); 5363 } 5364 } 5365 5366 /* 5367 * Print out help text for all zpool status/iostat -c scripts. 5368 */ 5369 static void 5370 print_zpool_script_list(char *subcommand) 5371 { 5372 char *dir, *sp, *tmp; 5373 5374 printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand); 5375 5376 sp = zpool_get_cmd_search_path(); 5377 if (sp == NULL) 5378 return; 5379 5380 for (dir = strtok_r(sp, ":", &tmp); 5381 dir != NULL; 5382 dir = strtok_r(NULL, ":", &tmp)) 5383 print_zpool_dir_scripts(dir); 5384 5385 free(sp); 5386 } 5387 5388 /* 5389 * Set the minimum pool/vdev name column width. The width must be at least 10, 5390 * but may be as large as the column width - 42 so it still fits on one line. 5391 * NOTE: 42 is the width of the default capacity/operations/bandwidth output 5392 */ 5393 static int 5394 get_namewidth_iostat(zpool_handle_t *zhp, void *data) 5395 { 5396 iostat_cbdata_t *cb = data; 5397 int width, available_width; 5398 5399 /* 5400 * get_namewidth() returns the maximum width of any name in that column 5401 * for any pool/vdev/device line that will be output. 5402 */ 5403 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 5404 cb->cb_verbose); 5405 5406 /* 5407 * The width we are calculating is the width of the header and also the 5408 * padding width for names that are less than maximum width. The stats 5409 * take up 42 characters, so the width available for names is: 5410 */ 5411 available_width = get_columns() - 42; 5412 5413 /* 5414 * If the maximum width fits on a screen, then great! Make everything 5415 * line up by justifying all lines to the same width. If that max 5416 * width is larger than what's available, the name plus stats won't fit 5417 * on one line, and justifying to that width would cause every line to 5418 * wrap on the screen. We only want lines with long names to wrap. 5419 * Limit the padding to what won't wrap. 5420 */ 5421 if (width > available_width) 5422 width = available_width; 5423 5424 /* 5425 * And regardless of whatever the screen width is (get_columns can 5426 * return 0 if the width is not known or less than 42 for a narrow 5427 * terminal) have the width be a minimum of 10. 5428 */ 5429 if (width < 10) 5430 width = 10; 5431 5432 /* Save the calculated width */ 5433 cb->cb_namewidth = width; 5434 5435 return (0); 5436 } 5437 5438 /* 5439 * zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name] 5440 * [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]] 5441 * [interval [count]] 5442 * 5443 * -c CMD For each vdev, run command CMD 5444 * -g Display guid for individual vdev name. 5445 * -L Follow links when resolving vdev path name. 5446 * -P Display full path for vdev name. 5447 * -v Display statistics for individual vdevs 5448 * -h Display help 5449 * -p Display values in parsable (exact) format. 5450 * -H Scripted mode. Don't display headers, and separate properties 5451 * by a single tab. 5452 * -l Display average latency 5453 * -q Display queue depths 5454 * -w Display latency histograms 5455 * -r Display request size histogram 5456 * -T Display a timestamp in date(1) or Unix format 5457 * -n Only print headers once 5458 * 5459 * This command can be tricky because we want to be able to deal with pool 5460 * creation/destruction as well as vdev configuration changes. The bulk of this 5461 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 5462 * on pool_list_update() to detect the addition of new pools. Configuration 5463 * changes are all handled within libzfs. 5464 */ 5465 int 5466 zpool_do_iostat(int argc, char **argv) 5467 { 5468 int c; 5469 int ret; 5470 int npools; 5471 float interval = 0; 5472 unsigned long count = 0; 5473 int winheight = 24; 5474 zpool_list_t *list; 5475 boolean_t verbose = B_FALSE; 5476 boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE; 5477 boolean_t queues = B_FALSE, parsable = B_FALSE, scripted = B_FALSE; 5478 boolean_t omit_since_boot = B_FALSE; 5479 boolean_t guid = B_FALSE; 5480 boolean_t follow_links = B_FALSE; 5481 boolean_t full_name = B_FALSE; 5482 boolean_t headers_once = B_FALSE; 5483 iostat_cbdata_t cb = { 0 }; 5484 char *cmd = NULL; 5485 5486 /* Used for printing error message */ 5487 const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q', 5488 [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'}; 5489 5490 uint64_t unsupported_flags; 5491 5492 /* check options */ 5493 while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwnH")) != -1) { 5494 switch (c) { 5495 case 'c': 5496 if (cmd != NULL) { 5497 fprintf(stderr, 5498 gettext("Can't set -c flag twice\n")); 5499 exit(1); 5500 } 5501 5502 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL && 5503 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) { 5504 fprintf(stderr, gettext( 5505 "Can't run -c, disabled by " 5506 "ZPOOL_SCRIPTS_ENABLED.\n")); 5507 exit(1); 5508 } 5509 5510 if ((getuid() <= 0 || geteuid() <= 0) && 5511 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) { 5512 fprintf(stderr, gettext( 5513 "Can't run -c with root privileges " 5514 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n")); 5515 exit(1); 5516 } 5517 cmd = optarg; 5518 verbose = B_TRUE; 5519 break; 5520 case 'g': 5521 guid = B_TRUE; 5522 break; 5523 case 'L': 5524 follow_links = B_TRUE; 5525 break; 5526 case 'P': 5527 full_name = B_TRUE; 5528 break; 5529 case 'T': 5530 get_timestamp_arg(*optarg); 5531 break; 5532 case 'v': 5533 verbose = B_TRUE; 5534 break; 5535 case 'p': 5536 parsable = B_TRUE; 5537 break; 5538 case 'l': 5539 latency = B_TRUE; 5540 break; 5541 case 'q': 5542 queues = B_TRUE; 5543 break; 5544 case 'H': 5545 scripted = B_TRUE; 5546 break; 5547 case 'w': 5548 l_histo = B_TRUE; 5549 break; 5550 case 'r': 5551 rq_histo = B_TRUE; 5552 break; 5553 case 'y': 5554 omit_since_boot = B_TRUE; 5555 break; 5556 case 'n': 5557 headers_once = B_TRUE; 5558 break; 5559 case 'h': 5560 usage(B_FALSE); 5561 break; 5562 case '?': 5563 if (optopt == 'c') { 5564 print_zpool_script_list("iostat"); 5565 exit(0); 5566 } else { 5567 fprintf(stderr, 5568 gettext("invalid option '%c'\n"), optopt); 5569 } 5570 usage(B_FALSE); 5571 } 5572 } 5573 5574 argc -= optind; 5575 argv += optind; 5576 5577 cb.cb_literal = parsable; 5578 cb.cb_scripted = scripted; 5579 5580 if (guid) 5581 cb.cb_name_flags |= VDEV_NAME_GUID; 5582 if (follow_links) 5583 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 5584 if (full_name) 5585 cb.cb_name_flags |= VDEV_NAME_PATH; 5586 cb.cb_iteration = 0; 5587 cb.cb_namewidth = 0; 5588 cb.cb_verbose = verbose; 5589 5590 /* Get our interval and count values (if any) */ 5591 if (guid) { 5592 get_interval_count_filter_guids(&argc, argv, &interval, 5593 &count, &cb); 5594 } else { 5595 get_interval_count(&argc, argv, &interval, &count); 5596 } 5597 5598 if (argc == 0) { 5599 /* No args, so just print the defaults. */ 5600 } else if (are_all_pools(argc, argv)) { 5601 /* All the args are pool names */ 5602 } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) { 5603 /* All the args are vdevs */ 5604 cb.cb_vdev_names = argv; 5605 cb.cb_vdev_names_count = argc; 5606 argc = 0; /* No pools to process */ 5607 } else if (are_all_pools(1, argv)) { 5608 /* The first arg is a pool name */ 5609 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) { 5610 /* ...and the rest are vdev names */ 5611 cb.cb_vdev_names = argv + 1; 5612 cb.cb_vdev_names_count = argc - 1; 5613 argc = 1; /* One pool to process */ 5614 } else { 5615 fprintf(stderr, gettext("Expected either a list of ")); 5616 fprintf(stderr, gettext("pools, or list of vdevs in")); 5617 fprintf(stderr, " \"%s\", ", argv[0]); 5618 fprintf(stderr, gettext("but got:\n")); 5619 error_list_unresolved_vdevs(argc - 1, argv + 1, 5620 argv[0], &cb); 5621 fprintf(stderr, "\n"); 5622 usage(B_FALSE); 5623 return (1); 5624 } 5625 } else { 5626 /* 5627 * The args don't make sense. The first arg isn't a pool name, 5628 * nor are all the args vdevs. 5629 */ 5630 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n")); 5631 fprintf(stderr, "\n"); 5632 return (1); 5633 } 5634 5635 if (cb.cb_vdev_names_count != 0) { 5636 /* 5637 * If user specified vdevs, it implies verbose. 5638 */ 5639 cb.cb_verbose = B_TRUE; 5640 } 5641 5642 /* 5643 * Construct the list of all interesting pools. 5644 */ 5645 ret = 0; 5646 if ((list = pool_list_get(argc, argv, NULL, parsable, &ret)) == NULL) 5647 return (1); 5648 5649 if (pool_list_count(list) == 0 && argc != 0) { 5650 pool_list_free(list); 5651 return (1); 5652 } 5653 5654 if (pool_list_count(list) == 0 && interval == 0) { 5655 pool_list_free(list); 5656 (void) fprintf(stderr, gettext("no pools available\n")); 5657 return (1); 5658 } 5659 5660 if ((l_histo || rq_histo) && (cmd != NULL || latency || queues)) { 5661 pool_list_free(list); 5662 (void) fprintf(stderr, 5663 gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n")); 5664 usage(B_FALSE); 5665 return (1); 5666 } 5667 5668 if (l_histo && rq_histo) { 5669 pool_list_free(list); 5670 (void) fprintf(stderr, 5671 gettext("Only one of [-r|-w] can be passed at a time\n")); 5672 usage(B_FALSE); 5673 return (1); 5674 } 5675 5676 /* 5677 * Enter the main iostat loop. 5678 */ 5679 cb.cb_list = list; 5680 5681 if (l_histo) { 5682 /* 5683 * Histograms tables look out of place when you try to display 5684 * them with the other stats, so make a rule that you can only 5685 * print histograms by themselves. 5686 */ 5687 cb.cb_flags = IOS_L_HISTO_M; 5688 } else if (rq_histo) { 5689 cb.cb_flags = IOS_RQ_HISTO_M; 5690 } else { 5691 cb.cb_flags = IOS_DEFAULT_M; 5692 if (latency) 5693 cb.cb_flags |= IOS_LATENCY_M; 5694 if (queues) 5695 cb.cb_flags |= IOS_QUEUES_M; 5696 } 5697 5698 /* 5699 * See if the module supports all the stats we want to display. 5700 */ 5701 unsupported_flags = cb.cb_flags & ~get_stat_flags(list); 5702 if (unsupported_flags) { 5703 uint64_t f; 5704 int idx; 5705 fprintf(stderr, 5706 gettext("The loaded zfs module doesn't support:")); 5707 5708 /* for each bit set in unsupported_flags */ 5709 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) { 5710 idx = lowbit64(f) - 1; 5711 fprintf(stderr, " -%c", flag_to_arg[idx]); 5712 } 5713 5714 fprintf(stderr, ". Try running a newer module.\n"); 5715 pool_list_free(list); 5716 5717 return (1); 5718 } 5719 5720 for (;;) { 5721 if ((npools = pool_list_count(list)) == 0) 5722 (void) fprintf(stderr, gettext("no pools available\n")); 5723 else { 5724 /* 5725 * If this is the first iteration and -y was supplied 5726 * we skip any printing. 5727 */ 5728 boolean_t skip = (omit_since_boot && 5729 cb.cb_iteration == 0); 5730 5731 /* 5732 * Refresh all statistics. This is done as an 5733 * explicit step before calculating the maximum name 5734 * width, so that any * configuration changes are 5735 * properly accounted for. 5736 */ 5737 (void) pool_list_iter(list, B_FALSE, refresh_iostat, 5738 &cb); 5739 5740 /* 5741 * Iterate over all pools to determine the maximum width 5742 * for the pool / device name column across all pools. 5743 */ 5744 cb.cb_namewidth = 0; 5745 (void) pool_list_iter(list, B_FALSE, 5746 get_namewidth_iostat, &cb); 5747 5748 if (timestamp_fmt != NODATE) 5749 print_timestamp(timestamp_fmt); 5750 5751 if (cmd != NULL && cb.cb_verbose && 5752 !(cb.cb_flags & IOS_ANYHISTO_M)) { 5753 cb.vcdl = all_pools_for_each_vdev_run(argc, 5754 argv, cmd, g_zfs, cb.cb_vdev_names, 5755 cb.cb_vdev_names_count, cb.cb_name_flags); 5756 } else { 5757 cb.vcdl = NULL; 5758 } 5759 5760 5761 /* 5762 * Check terminal size so we can print headers 5763 * even when terminal window has its height 5764 * changed. 5765 */ 5766 winheight = terminal_height(); 5767 /* 5768 * Are we connected to TTY? If not, headers_once 5769 * should be true, to avoid breaking scripts. 5770 */ 5771 if (winheight < 0) 5772 headers_once = B_TRUE; 5773 5774 /* 5775 * If it's the first time and we're not skipping it, 5776 * or either skip or verbose mode, print the header. 5777 * 5778 * The histogram code explicitly prints its header on 5779 * every vdev, so skip this for histograms. 5780 */ 5781 if (((++cb.cb_iteration == 1 && !skip) || 5782 (skip != verbose) || 5783 (!headers_once && 5784 (cb.cb_iteration % winheight) == 0)) && 5785 (!(cb.cb_flags & IOS_ANYHISTO_M)) && 5786 !cb.cb_scripted) 5787 print_iostat_header(&cb); 5788 5789 if (skip) { 5790 (void) fsleep(interval); 5791 continue; 5792 } 5793 5794 pool_list_iter(list, B_FALSE, print_iostat, &cb); 5795 5796 /* 5797 * If there's more than one pool, and we're not in 5798 * verbose mode (which prints a separator for us), 5799 * then print a separator. 5800 * 5801 * In addition, if we're printing specific vdevs then 5802 * we also want an ending separator. 5803 */ 5804 if (((npools > 1 && !verbose && 5805 !(cb.cb_flags & IOS_ANYHISTO_M)) || 5806 (!(cb.cb_flags & IOS_ANYHISTO_M) && 5807 cb.cb_vdev_names_count)) && 5808 !cb.cb_scripted) { 5809 print_iostat_separator(&cb); 5810 if (cb.vcdl != NULL) 5811 print_cmd_columns(cb.vcdl, 1); 5812 printf("\n"); 5813 } 5814 5815 if (cb.vcdl != NULL) 5816 free_vdev_cmd_data_list(cb.vcdl); 5817 5818 } 5819 5820 /* 5821 * Flush the output so that redirection to a file isn't buffered 5822 * indefinitely. 5823 */ 5824 (void) fflush(stdout); 5825 5826 if (interval == 0) 5827 break; 5828 5829 if (count != 0 && --count == 0) 5830 break; 5831 5832 (void) fsleep(interval); 5833 } 5834 5835 pool_list_free(list); 5836 5837 return (ret); 5838 } 5839 5840 typedef struct list_cbdata { 5841 boolean_t cb_verbose; 5842 int cb_name_flags; 5843 int cb_namewidth; 5844 boolean_t cb_scripted; 5845 zprop_list_t *cb_proplist; 5846 boolean_t cb_literal; 5847 } list_cbdata_t; 5848 5849 5850 /* 5851 * Given a list of columns to display, output appropriate headers for each one. 5852 */ 5853 static void 5854 print_header(list_cbdata_t *cb) 5855 { 5856 zprop_list_t *pl = cb->cb_proplist; 5857 char headerbuf[ZPOOL_MAXPROPLEN]; 5858 const char *header; 5859 boolean_t first = B_TRUE; 5860 boolean_t right_justify; 5861 size_t width = 0; 5862 5863 for (; pl != NULL; pl = pl->pl_next) { 5864 width = pl->pl_width; 5865 if (first && cb->cb_verbose) { 5866 /* 5867 * Reset the width to accommodate the verbose listing 5868 * of devices. 5869 */ 5870 width = cb->cb_namewidth; 5871 } 5872 5873 if (!first) 5874 (void) printf(" "); 5875 else 5876 first = B_FALSE; 5877 5878 right_justify = B_FALSE; 5879 if (pl->pl_prop != ZPROP_INVAL) { 5880 header = zpool_prop_column_name(pl->pl_prop); 5881 right_justify = zpool_prop_align_right(pl->pl_prop); 5882 } else { 5883 int i; 5884 5885 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 5886 headerbuf[i] = toupper(pl->pl_user_prop[i]); 5887 headerbuf[i] = '\0'; 5888 header = headerbuf; 5889 } 5890 5891 if (pl->pl_next == NULL && !right_justify) 5892 (void) printf("%s", header); 5893 else if (right_justify) 5894 (void) printf("%*s", (int)width, header); 5895 else 5896 (void) printf("%-*s", (int)width, header); 5897 } 5898 5899 (void) printf("\n"); 5900 } 5901 5902 /* 5903 * Given a pool and a list of properties, print out all the properties according 5904 * to the described layout. Used by zpool_do_list(). 5905 */ 5906 static void 5907 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 5908 { 5909 zprop_list_t *pl = cb->cb_proplist; 5910 boolean_t first = B_TRUE; 5911 char property[ZPOOL_MAXPROPLEN]; 5912 char *propstr; 5913 boolean_t right_justify; 5914 size_t width; 5915 5916 for (; pl != NULL; pl = pl->pl_next) { 5917 5918 width = pl->pl_width; 5919 if (first && cb->cb_verbose) { 5920 /* 5921 * Reset the width to accommodate the verbose listing 5922 * of devices. 5923 */ 5924 width = cb->cb_namewidth; 5925 } 5926 5927 if (!first) { 5928 if (cb->cb_scripted) 5929 (void) printf("\t"); 5930 else 5931 (void) printf(" "); 5932 } else { 5933 first = B_FALSE; 5934 } 5935 5936 right_justify = B_FALSE; 5937 if (pl->pl_prop != ZPROP_INVAL) { 5938 if (zpool_get_prop(zhp, pl->pl_prop, property, 5939 sizeof (property), NULL, cb->cb_literal) != 0) 5940 propstr = "-"; 5941 else 5942 propstr = property; 5943 5944 right_justify = zpool_prop_align_right(pl->pl_prop); 5945 } else if ((zpool_prop_feature(pl->pl_user_prop) || 5946 zpool_prop_unsupported(pl->pl_user_prop)) && 5947 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 5948 sizeof (property)) == 0) { 5949 propstr = property; 5950 } else { 5951 propstr = "-"; 5952 } 5953 5954 5955 /* 5956 * If this is being called in scripted mode, or if this is the 5957 * last column and it is left-justified, don't include a width 5958 * format specifier. 5959 */ 5960 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 5961 (void) printf("%s", propstr); 5962 else if (right_justify) 5963 (void) printf("%*s", (int)width, propstr); 5964 else 5965 (void) printf("%-*s", (int)width, propstr); 5966 } 5967 5968 (void) printf("\n"); 5969 } 5970 5971 static void 5972 print_one_column(zpool_prop_t prop, uint64_t value, const char *str, 5973 boolean_t scripted, boolean_t valid, enum zfs_nicenum_format format) 5974 { 5975 char propval[64]; 5976 boolean_t fixed; 5977 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 5978 5979 switch (prop) { 5980 case ZPOOL_PROP_EXPANDSZ: 5981 case ZPOOL_PROP_CHECKPOINT: 5982 case ZPOOL_PROP_DEDUPRATIO: 5983 if (value == 0) 5984 (void) strlcpy(propval, "-", sizeof (propval)); 5985 else 5986 zfs_nicenum_format(value, propval, sizeof (propval), 5987 format); 5988 break; 5989 case ZPOOL_PROP_FRAGMENTATION: 5990 if (value == ZFS_FRAG_INVALID) { 5991 (void) strlcpy(propval, "-", sizeof (propval)); 5992 } else if (format == ZFS_NICENUM_RAW) { 5993 (void) snprintf(propval, sizeof (propval), "%llu", 5994 (unsigned long long)value); 5995 } else { 5996 (void) snprintf(propval, sizeof (propval), "%llu%%", 5997 (unsigned long long)value); 5998 } 5999 break; 6000 case ZPOOL_PROP_CAPACITY: 6001 /* capacity value is in parts-per-10,000 (aka permyriad) */ 6002 if (format == ZFS_NICENUM_RAW) 6003 (void) snprintf(propval, sizeof (propval), "%llu", 6004 (unsigned long long)value / 100); 6005 else 6006 (void) snprintf(propval, sizeof (propval), 6007 value < 1000 ? "%1.2f%%" : value < 10000 ? 6008 "%2.1f%%" : "%3.0f%%", value / 100.0); 6009 break; 6010 case ZPOOL_PROP_HEALTH: 6011 width = 8; 6012 (void) strlcpy(propval, str, sizeof (propval)); 6013 break; 6014 default: 6015 zfs_nicenum_format(value, propval, sizeof (propval), format); 6016 } 6017 6018 if (!valid) 6019 (void) strlcpy(propval, "-", sizeof (propval)); 6020 6021 if (scripted) 6022 (void) printf("\t%s", propval); 6023 else 6024 (void) printf(" %*s", (int)width, propval); 6025 } 6026 6027 /* 6028 * print static default line per vdev 6029 * not compatible with '-o' <proplist> option 6030 */ 6031 static void 6032 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 6033 list_cbdata_t *cb, int depth, boolean_t isspare) 6034 { 6035 nvlist_t **child; 6036 vdev_stat_t *vs; 6037 uint_t c, children; 6038 char *vname; 6039 boolean_t scripted = cb->cb_scripted; 6040 uint64_t islog = B_FALSE; 6041 char *dashes = "%-*s - - - - " 6042 "- - - - -\n"; 6043 6044 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 6045 (uint64_t **)&vs, &c) == 0); 6046 6047 if (name != NULL) { 6048 boolean_t toplevel = (vs->vs_space != 0); 6049 uint64_t cap; 6050 enum zfs_nicenum_format format; 6051 const char *state; 6052 6053 if (cb->cb_literal) 6054 format = ZFS_NICENUM_RAW; 6055 else 6056 format = ZFS_NICENUM_1024; 6057 6058 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 6059 return; 6060 6061 if (scripted) 6062 (void) printf("\t%s", name); 6063 else if (strlen(name) + depth > cb->cb_namewidth) 6064 (void) printf("%*s%s", depth, "", name); 6065 else 6066 (void) printf("%*s%s%*s", depth, "", name, 6067 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 6068 6069 /* 6070 * Print the properties for the individual vdevs. Some 6071 * properties are only applicable to toplevel vdevs. The 6072 * 'toplevel' boolean value is passed to the print_one_column() 6073 * to indicate that the value is valid. 6074 */ 6075 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL, scripted, 6076 toplevel, format); 6077 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL, 6078 scripted, toplevel, format); 6079 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 6080 NULL, scripted, toplevel, format); 6081 print_one_column(ZPOOL_PROP_CHECKPOINT, 6082 vs->vs_checkpoint_space, NULL, scripted, toplevel, format); 6083 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL, 6084 scripted, B_TRUE, format); 6085 print_one_column(ZPOOL_PROP_FRAGMENTATION, 6086 vs->vs_fragmentation, NULL, scripted, 6087 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel), 6088 format); 6089 cap = (vs->vs_space == 0) ? 0 : 6090 (vs->vs_alloc * 10000 / vs->vs_space); 6091 print_one_column(ZPOOL_PROP_CAPACITY, cap, NULL, 6092 scripted, toplevel, format); 6093 print_one_column(ZPOOL_PROP_DEDUPRATIO, 0, NULL, 6094 scripted, toplevel, format); 6095 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 6096 if (isspare) { 6097 if (vs->vs_aux == VDEV_AUX_SPARED) 6098 state = "INUSE"; 6099 else if (vs->vs_state == VDEV_STATE_HEALTHY) 6100 state = "AVAIL"; 6101 } 6102 print_one_column(ZPOOL_PROP_HEALTH, 0, state, scripted, 6103 B_TRUE, format); 6104 (void) printf("\n"); 6105 } 6106 6107 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 6108 &child, &children) != 0) 6109 return; 6110 6111 /* list the normal vdevs first */ 6112 for (c = 0; c < children; c++) { 6113 uint64_t ishole = B_FALSE; 6114 6115 if (nvlist_lookup_uint64(child[c], 6116 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 6117 continue; 6118 6119 if (nvlist_lookup_uint64(child[c], 6120 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) 6121 continue; 6122 6123 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 6124 continue; 6125 6126 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6127 cb->cb_name_flags); 6128 print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE); 6129 free(vname); 6130 } 6131 6132 /* list the classes: 'logs', 'dedup', and 'special' */ 6133 for (uint_t n = 0; n < 3; n++) { 6134 boolean_t printed = B_FALSE; 6135 6136 for (c = 0; c < children; c++) { 6137 char *bias = NULL; 6138 char *type = NULL; 6139 6140 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 6141 &islog) == 0 && islog) { 6142 bias = VDEV_ALLOC_CLASS_LOGS; 6143 } else { 6144 (void) nvlist_lookup_string(child[c], 6145 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 6146 (void) nvlist_lookup_string(child[c], 6147 ZPOOL_CONFIG_TYPE, &type); 6148 } 6149 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 6150 continue; 6151 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 6152 continue; 6153 6154 if (!printed) { 6155 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6156 (void) printf(dashes, cb->cb_namewidth, 6157 class_name[n]); 6158 printed = B_TRUE; 6159 } 6160 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6161 cb->cb_name_flags); 6162 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6163 B_FALSE); 6164 free(vname); 6165 } 6166 } 6167 6168 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 6169 &child, &children) == 0 && children > 0) { 6170 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6171 (void) printf(dashes, cb->cb_namewidth, "cache"); 6172 for (c = 0; c < children; c++) { 6173 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6174 cb->cb_name_flags); 6175 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6176 B_FALSE); 6177 free(vname); 6178 } 6179 } 6180 6181 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 6182 &children) == 0 && children > 0) { 6183 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6184 (void) printf(dashes, cb->cb_namewidth, "spare"); 6185 for (c = 0; c < children; c++) { 6186 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6187 cb->cb_name_flags); 6188 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6189 B_TRUE); 6190 free(vname); 6191 } 6192 } 6193 } 6194 6195 /* 6196 * Generic callback function to list a pool. 6197 */ 6198 static int 6199 list_callback(zpool_handle_t *zhp, void *data) 6200 { 6201 list_cbdata_t *cbp = data; 6202 6203 print_pool(zhp, cbp); 6204 6205 if (cbp->cb_verbose) { 6206 nvlist_t *config, *nvroot; 6207 6208 config = zpool_get_config(zhp, NULL); 6209 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 6210 &nvroot) == 0); 6211 print_list_stats(zhp, NULL, nvroot, cbp, 0, B_FALSE); 6212 } 6213 6214 return (0); 6215 } 6216 6217 /* 6218 * Set the minimum pool/vdev name column width. The width must be at least 9, 6219 * but may be as large as needed. 6220 */ 6221 static int 6222 get_namewidth_list(zpool_handle_t *zhp, void *data) 6223 { 6224 list_cbdata_t *cb = data; 6225 int width; 6226 6227 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 6228 cb->cb_verbose); 6229 6230 if (width < 9) 6231 width = 9; 6232 6233 cb->cb_namewidth = width; 6234 6235 return (0); 6236 } 6237 6238 /* 6239 * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 6240 * 6241 * -g Display guid for individual vdev name. 6242 * -H Scripted mode. Don't display headers, and separate properties 6243 * by a single tab. 6244 * -L Follow links when resolving vdev path name. 6245 * -o List of properties to display. Defaults to 6246 * "name,size,allocated,free,expandsize,fragmentation,capacity," 6247 * "dedupratio,health,altroot" 6248 * -p Display values in parsable (exact) format. 6249 * -P Display full path for vdev name. 6250 * -T Display a timestamp in date(1) or Unix format 6251 * 6252 * List all pools in the system, whether or not they're healthy. Output space 6253 * statistics for each one, as well as health status summary. 6254 */ 6255 int 6256 zpool_do_list(int argc, char **argv) 6257 { 6258 int c; 6259 int ret = 0; 6260 list_cbdata_t cb = { 0 }; 6261 static char default_props[] = 6262 "name,size,allocated,free,checkpoint,expandsize,fragmentation," 6263 "capacity,dedupratio,health,altroot"; 6264 char *props = default_props; 6265 float interval = 0; 6266 unsigned long count = 0; 6267 zpool_list_t *list; 6268 boolean_t first = B_TRUE; 6269 6270 /* check options */ 6271 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) { 6272 switch (c) { 6273 case 'g': 6274 cb.cb_name_flags |= VDEV_NAME_GUID; 6275 break; 6276 case 'H': 6277 cb.cb_scripted = B_TRUE; 6278 break; 6279 case 'L': 6280 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 6281 break; 6282 case 'o': 6283 props = optarg; 6284 break; 6285 case 'P': 6286 cb.cb_name_flags |= VDEV_NAME_PATH; 6287 break; 6288 case 'p': 6289 cb.cb_literal = B_TRUE; 6290 break; 6291 case 'T': 6292 get_timestamp_arg(*optarg); 6293 break; 6294 case 'v': 6295 cb.cb_verbose = B_TRUE; 6296 cb.cb_namewidth = 8; /* 8 until precalc is avail */ 6297 break; 6298 case ':': 6299 (void) fprintf(stderr, gettext("missing argument for " 6300 "'%c' option\n"), optopt); 6301 usage(B_FALSE); 6302 break; 6303 case '?': 6304 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6305 optopt); 6306 usage(B_FALSE); 6307 } 6308 } 6309 6310 argc -= optind; 6311 argv += optind; 6312 6313 get_interval_count(&argc, argv, &interval, &count); 6314 6315 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 6316 usage(B_FALSE); 6317 6318 for (;;) { 6319 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 6320 cb.cb_literal, &ret)) == NULL) 6321 return (1); 6322 6323 if (pool_list_count(list) == 0) 6324 break; 6325 6326 cb.cb_namewidth = 0; 6327 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb); 6328 6329 if (timestamp_fmt != NODATE) 6330 print_timestamp(timestamp_fmt); 6331 6332 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 6333 print_header(&cb); 6334 first = B_FALSE; 6335 } 6336 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 6337 6338 if (interval == 0) 6339 break; 6340 6341 if (count != 0 && --count == 0) 6342 break; 6343 6344 pool_list_free(list); 6345 (void) fsleep(interval); 6346 } 6347 6348 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 6349 (void) printf(gettext("no pools available\n")); 6350 ret = 0; 6351 } 6352 6353 pool_list_free(list); 6354 zprop_free_list(cb.cb_proplist); 6355 return (ret); 6356 } 6357 6358 static int 6359 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 6360 { 6361 boolean_t force = B_FALSE; 6362 boolean_t rebuild = B_FALSE; 6363 boolean_t wait = B_FALSE; 6364 int c; 6365 nvlist_t *nvroot; 6366 char *poolname, *old_disk, *new_disk; 6367 zpool_handle_t *zhp; 6368 nvlist_t *props = NULL; 6369 char *propval; 6370 int ret; 6371 6372 /* check options */ 6373 while ((c = getopt(argc, argv, "fo:sw")) != -1) { 6374 switch (c) { 6375 case 'f': 6376 force = B_TRUE; 6377 break; 6378 case 'o': 6379 if ((propval = strchr(optarg, '=')) == NULL) { 6380 (void) fprintf(stderr, gettext("missing " 6381 "'=' for -o option\n")); 6382 usage(B_FALSE); 6383 } 6384 *propval = '\0'; 6385 propval++; 6386 6387 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 6388 (add_prop_list(optarg, propval, &props, B_TRUE))) 6389 usage(B_FALSE); 6390 break; 6391 case 's': 6392 rebuild = B_TRUE; 6393 break; 6394 case 'w': 6395 wait = B_TRUE; 6396 break; 6397 case '?': 6398 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6399 optopt); 6400 usage(B_FALSE); 6401 } 6402 } 6403 6404 argc -= optind; 6405 argv += optind; 6406 6407 /* get pool name and check number of arguments */ 6408 if (argc < 1) { 6409 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6410 usage(B_FALSE); 6411 } 6412 6413 poolname = argv[0]; 6414 6415 if (argc < 2) { 6416 (void) fprintf(stderr, 6417 gettext("missing <device> specification\n")); 6418 usage(B_FALSE); 6419 } 6420 6421 old_disk = argv[1]; 6422 6423 if (argc < 3) { 6424 if (!replacing) { 6425 (void) fprintf(stderr, 6426 gettext("missing <new_device> specification\n")); 6427 usage(B_FALSE); 6428 } 6429 new_disk = old_disk; 6430 argc -= 1; 6431 argv += 1; 6432 } else { 6433 new_disk = argv[2]; 6434 argc -= 2; 6435 argv += 2; 6436 } 6437 6438 if (argc > 1) { 6439 (void) fprintf(stderr, gettext("too many arguments\n")); 6440 usage(B_FALSE); 6441 } 6442 6443 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) { 6444 nvlist_free(props); 6445 return (1); 6446 } 6447 6448 if (zpool_get_config(zhp, NULL) == NULL) { 6449 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 6450 poolname); 6451 zpool_close(zhp); 6452 nvlist_free(props); 6453 return (1); 6454 } 6455 6456 /* unless manually specified use "ashift" pool property (if set) */ 6457 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 6458 int intval; 6459 zprop_source_t src; 6460 char strval[ZPOOL_MAXPROPLEN]; 6461 6462 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 6463 if (src != ZPROP_SRC_DEFAULT) { 6464 (void) sprintf(strval, "%" PRId32, intval); 6465 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 6466 &props, B_TRUE) == 0); 6467 } 6468 } 6469 6470 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE, 6471 argc, argv); 6472 if (nvroot == NULL) { 6473 zpool_close(zhp); 6474 nvlist_free(props); 6475 return (1); 6476 } 6477 6478 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing, 6479 rebuild); 6480 6481 if (ret == 0 && wait) 6482 ret = zpool_wait(zhp, 6483 replacing ? ZPOOL_WAIT_REPLACE : ZPOOL_WAIT_RESILVER); 6484 6485 nvlist_free(props); 6486 nvlist_free(nvroot); 6487 zpool_close(zhp); 6488 6489 return (ret); 6490 } 6491 6492 /* 6493 * zpool replace [-fsw] [-o property=value] <pool> <device> <new_device> 6494 * 6495 * -f Force attach, even if <new_device> appears to be in use. 6496 * -s Use sequential instead of healing reconstruction for resilver. 6497 * -o Set property=value. 6498 * -w Wait for replacing to complete before returning 6499 * 6500 * Replace <device> with <new_device>. 6501 */ 6502 /* ARGSUSED */ 6503 int 6504 zpool_do_replace(int argc, char **argv) 6505 { 6506 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 6507 } 6508 6509 /* 6510 * zpool attach [-fsw] [-o property=value] <pool> <device> <new_device> 6511 * 6512 * -f Force attach, even if <new_device> appears to be in use. 6513 * -s Use sequential instead of healing reconstruction for resilver. 6514 * -o Set property=value. 6515 * -w Wait for resilvering to complete before returning 6516 * 6517 * Attach <new_device> to the mirror containing <device>. If <device> is not 6518 * part of a mirror, then <device> will be transformed into a mirror of 6519 * <device> and <new_device>. In either case, <new_device> will begin life 6520 * with a DTL of [0, now], and will immediately begin to resilver itself. 6521 */ 6522 int 6523 zpool_do_attach(int argc, char **argv) 6524 { 6525 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 6526 } 6527 6528 /* 6529 * zpool detach [-f] <pool> <device> 6530 * 6531 * -f Force detach of <device>, even if DTLs argue against it 6532 * (not supported yet) 6533 * 6534 * Detach a device from a mirror. The operation will be refused if <device> 6535 * is the last device in the mirror, or if the DTLs indicate that this device 6536 * has the only valid copy of some data. 6537 */ 6538 /* ARGSUSED */ 6539 int 6540 zpool_do_detach(int argc, char **argv) 6541 { 6542 int c; 6543 char *poolname, *path; 6544 zpool_handle_t *zhp; 6545 int ret; 6546 6547 /* check options */ 6548 while ((c = getopt(argc, argv, "")) != -1) { 6549 switch (c) { 6550 case '?': 6551 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6552 optopt); 6553 usage(B_FALSE); 6554 } 6555 } 6556 6557 argc -= optind; 6558 argv += optind; 6559 6560 /* get pool name and check number of arguments */ 6561 if (argc < 1) { 6562 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6563 usage(B_FALSE); 6564 } 6565 6566 if (argc < 2) { 6567 (void) fprintf(stderr, 6568 gettext("missing <device> specification\n")); 6569 usage(B_FALSE); 6570 } 6571 6572 poolname = argv[0]; 6573 path = argv[1]; 6574 6575 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6576 return (1); 6577 6578 ret = zpool_vdev_detach(zhp, path); 6579 6580 zpool_close(zhp); 6581 6582 return (ret); 6583 } 6584 6585 /* 6586 * zpool split [-gLnP] [-o prop=val] ... 6587 * [-o mntopt] ... 6588 * [-R altroot] <pool> <newpool> [<device> ...] 6589 * 6590 * -g Display guid for individual vdev name. 6591 * -L Follow links when resolving vdev path name. 6592 * -n Do not split the pool, but display the resulting layout if 6593 * it were to be split. 6594 * -o Set property=value, or set mount options. 6595 * -P Display full path for vdev name. 6596 * -R Mount the split-off pool under an alternate root. 6597 * -l Load encryption keys while importing. 6598 * 6599 * Splits the named pool and gives it the new pool name. Devices to be split 6600 * off may be listed, provided that no more than one device is specified 6601 * per top-level vdev mirror. The newly split pool is left in an exported 6602 * state unless -R is specified. 6603 * 6604 * Restrictions: the top-level of the pool pool must only be made up of 6605 * mirrors; all devices in the pool must be healthy; no device may be 6606 * undergoing a resilvering operation. 6607 */ 6608 int 6609 zpool_do_split(int argc, char **argv) 6610 { 6611 char *srcpool, *newpool, *propval; 6612 char *mntopts = NULL; 6613 splitflags_t flags; 6614 int c, ret = 0; 6615 boolean_t loadkeys = B_FALSE; 6616 zpool_handle_t *zhp; 6617 nvlist_t *config, *props = NULL; 6618 6619 flags.dryrun = B_FALSE; 6620 flags.import = B_FALSE; 6621 flags.name_flags = 0; 6622 6623 /* check options */ 6624 while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) { 6625 switch (c) { 6626 case 'g': 6627 flags.name_flags |= VDEV_NAME_GUID; 6628 break; 6629 case 'L': 6630 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS; 6631 break; 6632 case 'R': 6633 flags.import = B_TRUE; 6634 if (add_prop_list( 6635 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 6636 &props, B_TRUE) != 0) { 6637 nvlist_free(props); 6638 usage(B_FALSE); 6639 } 6640 break; 6641 case 'l': 6642 loadkeys = B_TRUE; 6643 break; 6644 case 'n': 6645 flags.dryrun = B_TRUE; 6646 break; 6647 case 'o': 6648 if ((propval = strchr(optarg, '=')) != NULL) { 6649 *propval = '\0'; 6650 propval++; 6651 if (add_prop_list(optarg, propval, 6652 &props, B_TRUE) != 0) { 6653 nvlist_free(props); 6654 usage(B_FALSE); 6655 } 6656 } else { 6657 mntopts = optarg; 6658 } 6659 break; 6660 case 'P': 6661 flags.name_flags |= VDEV_NAME_PATH; 6662 break; 6663 case ':': 6664 (void) fprintf(stderr, gettext("missing argument for " 6665 "'%c' option\n"), optopt); 6666 usage(B_FALSE); 6667 break; 6668 case '?': 6669 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6670 optopt); 6671 usage(B_FALSE); 6672 break; 6673 } 6674 } 6675 6676 if (!flags.import && mntopts != NULL) { 6677 (void) fprintf(stderr, gettext("setting mntopts is only " 6678 "valid when importing the pool\n")); 6679 usage(B_FALSE); 6680 } 6681 6682 if (!flags.import && loadkeys) { 6683 (void) fprintf(stderr, gettext("loading keys is only " 6684 "valid when importing the pool\n")); 6685 usage(B_FALSE); 6686 } 6687 6688 argc -= optind; 6689 argv += optind; 6690 6691 if (argc < 1) { 6692 (void) fprintf(stderr, gettext("Missing pool name\n")); 6693 usage(B_FALSE); 6694 } 6695 if (argc < 2) { 6696 (void) fprintf(stderr, gettext("Missing new pool name\n")); 6697 usage(B_FALSE); 6698 } 6699 6700 srcpool = argv[0]; 6701 newpool = argv[1]; 6702 6703 argc -= 2; 6704 argv += 2; 6705 6706 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) { 6707 nvlist_free(props); 6708 return (1); 6709 } 6710 6711 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 6712 if (config == NULL) { 6713 ret = 1; 6714 } else { 6715 if (flags.dryrun) { 6716 (void) printf(gettext("would create '%s' with the " 6717 "following layout:\n\n"), newpool); 6718 print_vdev_tree(NULL, newpool, config, 0, "", 6719 flags.name_flags); 6720 print_vdev_tree(NULL, "dedup", config, 0, 6721 VDEV_ALLOC_BIAS_DEDUP, 0); 6722 print_vdev_tree(NULL, "special", config, 0, 6723 VDEV_ALLOC_BIAS_SPECIAL, 0); 6724 } 6725 } 6726 6727 zpool_close(zhp); 6728 6729 if (ret != 0 || flags.dryrun || !flags.import) { 6730 nvlist_free(config); 6731 nvlist_free(props); 6732 return (ret); 6733 } 6734 6735 /* 6736 * The split was successful. Now we need to open the new 6737 * pool and import it. 6738 */ 6739 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) { 6740 nvlist_free(config); 6741 nvlist_free(props); 6742 return (1); 6743 } 6744 6745 if (loadkeys) { 6746 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool); 6747 if (ret != 0) 6748 ret = 1; 6749 } 6750 6751 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 6752 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 6753 ret = 1; 6754 (void) fprintf(stderr, gettext("Split was successful, but " 6755 "the datasets could not all be mounted\n")); 6756 (void) fprintf(stderr, gettext("Try doing '%s' with a " 6757 "different altroot\n"), "zpool import"); 6758 } 6759 zpool_close(zhp); 6760 nvlist_free(config); 6761 nvlist_free(props); 6762 6763 return (ret); 6764 } 6765 6766 6767 6768 /* 6769 * zpool online <pool> <device> ... 6770 */ 6771 int 6772 zpool_do_online(int argc, char **argv) 6773 { 6774 int c, i; 6775 char *poolname; 6776 zpool_handle_t *zhp; 6777 int ret = 0; 6778 vdev_state_t newstate; 6779 int flags = 0; 6780 6781 /* check options */ 6782 while ((c = getopt(argc, argv, "e")) != -1) { 6783 switch (c) { 6784 case 'e': 6785 flags |= ZFS_ONLINE_EXPAND; 6786 break; 6787 case '?': 6788 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6789 optopt); 6790 usage(B_FALSE); 6791 } 6792 } 6793 6794 argc -= optind; 6795 argv += optind; 6796 6797 /* get pool name and check number of arguments */ 6798 if (argc < 1) { 6799 (void) fprintf(stderr, gettext("missing pool name\n")); 6800 usage(B_FALSE); 6801 } 6802 if (argc < 2) { 6803 (void) fprintf(stderr, gettext("missing device name\n")); 6804 usage(B_FALSE); 6805 } 6806 6807 poolname = argv[0]; 6808 6809 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6810 return (1); 6811 6812 for (i = 1; i < argc; i++) { 6813 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 6814 if (newstate != VDEV_STATE_HEALTHY) { 6815 (void) printf(gettext("warning: device '%s' " 6816 "onlined, but remains in faulted state\n"), 6817 argv[i]); 6818 if (newstate == VDEV_STATE_FAULTED) 6819 (void) printf(gettext("use 'zpool " 6820 "clear' to restore a faulted " 6821 "device\n")); 6822 else 6823 (void) printf(gettext("use 'zpool " 6824 "replace' to replace devices " 6825 "that are no longer present\n")); 6826 } 6827 } else { 6828 ret = 1; 6829 } 6830 } 6831 6832 zpool_close(zhp); 6833 6834 return (ret); 6835 } 6836 6837 /* 6838 * zpool offline [-ft] <pool> <device> ... 6839 * 6840 * -f Force the device into a faulted state. 6841 * 6842 * -t Only take the device off-line temporarily. The offline/faulted 6843 * state will not be persistent across reboots. 6844 */ 6845 /* ARGSUSED */ 6846 int 6847 zpool_do_offline(int argc, char **argv) 6848 { 6849 int c, i; 6850 char *poolname; 6851 zpool_handle_t *zhp; 6852 int ret = 0; 6853 boolean_t istmp = B_FALSE; 6854 boolean_t fault = B_FALSE; 6855 6856 /* check options */ 6857 while ((c = getopt(argc, argv, "ft")) != -1) { 6858 switch (c) { 6859 case 'f': 6860 fault = B_TRUE; 6861 break; 6862 case 't': 6863 istmp = B_TRUE; 6864 break; 6865 case '?': 6866 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6867 optopt); 6868 usage(B_FALSE); 6869 } 6870 } 6871 6872 argc -= optind; 6873 argv += optind; 6874 6875 /* get pool name and check number of arguments */ 6876 if (argc < 1) { 6877 (void) fprintf(stderr, gettext("missing pool name\n")); 6878 usage(B_FALSE); 6879 } 6880 if (argc < 2) { 6881 (void) fprintf(stderr, gettext("missing device name\n")); 6882 usage(B_FALSE); 6883 } 6884 6885 poolname = argv[0]; 6886 6887 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6888 return (1); 6889 6890 for (i = 1; i < argc; i++) { 6891 if (fault) { 6892 uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]); 6893 vdev_aux_t aux; 6894 if (istmp == B_FALSE) { 6895 /* Force the fault to persist across imports */ 6896 aux = VDEV_AUX_EXTERNAL_PERSIST; 6897 } else { 6898 aux = VDEV_AUX_EXTERNAL; 6899 } 6900 6901 if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0) 6902 ret = 1; 6903 } else { 6904 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 6905 ret = 1; 6906 } 6907 } 6908 6909 zpool_close(zhp); 6910 6911 return (ret); 6912 } 6913 6914 /* 6915 * zpool clear <pool> [device] 6916 * 6917 * Clear all errors associated with a pool or a particular device. 6918 */ 6919 int 6920 zpool_do_clear(int argc, char **argv) 6921 { 6922 int c; 6923 int ret = 0; 6924 boolean_t dryrun = B_FALSE; 6925 boolean_t do_rewind = B_FALSE; 6926 boolean_t xtreme_rewind = B_FALSE; 6927 uint32_t rewind_policy = ZPOOL_NO_REWIND; 6928 nvlist_t *policy = NULL; 6929 zpool_handle_t *zhp; 6930 char *pool, *device; 6931 6932 /* check options */ 6933 while ((c = getopt(argc, argv, "FnX")) != -1) { 6934 switch (c) { 6935 case 'F': 6936 do_rewind = B_TRUE; 6937 break; 6938 case 'n': 6939 dryrun = B_TRUE; 6940 break; 6941 case 'X': 6942 xtreme_rewind = B_TRUE; 6943 break; 6944 case '?': 6945 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6946 optopt); 6947 usage(B_FALSE); 6948 } 6949 } 6950 6951 argc -= optind; 6952 argv += optind; 6953 6954 if (argc < 1) { 6955 (void) fprintf(stderr, gettext("missing pool name\n")); 6956 usage(B_FALSE); 6957 } 6958 6959 if (argc > 2) { 6960 (void) fprintf(stderr, gettext("too many arguments\n")); 6961 usage(B_FALSE); 6962 } 6963 6964 if ((dryrun || xtreme_rewind) && !do_rewind) { 6965 (void) fprintf(stderr, 6966 gettext("-n or -X only meaningful with -F\n")); 6967 usage(B_FALSE); 6968 } 6969 if (dryrun) 6970 rewind_policy = ZPOOL_TRY_REWIND; 6971 else if (do_rewind) 6972 rewind_policy = ZPOOL_DO_REWIND; 6973 if (xtreme_rewind) 6974 rewind_policy |= ZPOOL_EXTREME_REWIND; 6975 6976 /* In future, further rewind policy choices can be passed along here */ 6977 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 6978 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 6979 rewind_policy) != 0) { 6980 return (1); 6981 } 6982 6983 pool = argv[0]; 6984 device = argc == 2 ? argv[1] : NULL; 6985 6986 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 6987 nvlist_free(policy); 6988 return (1); 6989 } 6990 6991 if (zpool_clear(zhp, device, policy) != 0) 6992 ret = 1; 6993 6994 zpool_close(zhp); 6995 6996 nvlist_free(policy); 6997 6998 return (ret); 6999 } 7000 7001 /* 7002 * zpool reguid <pool> 7003 */ 7004 int 7005 zpool_do_reguid(int argc, char **argv) 7006 { 7007 int c; 7008 char *poolname; 7009 zpool_handle_t *zhp; 7010 int ret = 0; 7011 7012 /* check options */ 7013 while ((c = getopt(argc, argv, "")) != -1) { 7014 switch (c) { 7015 case '?': 7016 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7017 optopt); 7018 usage(B_FALSE); 7019 } 7020 } 7021 7022 argc -= optind; 7023 argv += optind; 7024 7025 /* get pool name and check number of arguments */ 7026 if (argc < 1) { 7027 (void) fprintf(stderr, gettext("missing pool name\n")); 7028 usage(B_FALSE); 7029 } 7030 7031 if (argc > 1) { 7032 (void) fprintf(stderr, gettext("too many arguments\n")); 7033 usage(B_FALSE); 7034 } 7035 7036 poolname = argv[0]; 7037 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 7038 return (1); 7039 7040 ret = zpool_reguid(zhp); 7041 7042 zpool_close(zhp); 7043 return (ret); 7044 } 7045 7046 7047 /* 7048 * zpool reopen <pool> 7049 * 7050 * Reopen the pool so that the kernel can update the sizes of all vdevs. 7051 */ 7052 int 7053 zpool_do_reopen(int argc, char **argv) 7054 { 7055 int c; 7056 int ret = 0; 7057 boolean_t scrub_restart = B_TRUE; 7058 7059 /* check options */ 7060 while ((c = getopt(argc, argv, "n")) != -1) { 7061 switch (c) { 7062 case 'n': 7063 scrub_restart = B_FALSE; 7064 break; 7065 case '?': 7066 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7067 optopt); 7068 usage(B_FALSE); 7069 } 7070 } 7071 7072 argc -= optind; 7073 argv += optind; 7074 7075 /* if argc == 0 we will execute zpool_reopen_one on all pools */ 7076 ret = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, zpool_reopen_one, 7077 &scrub_restart); 7078 7079 return (ret); 7080 } 7081 7082 typedef struct scrub_cbdata { 7083 int cb_type; 7084 pool_scrub_cmd_t cb_scrub_cmd; 7085 } scrub_cbdata_t; 7086 7087 static boolean_t 7088 zpool_has_checkpoint(zpool_handle_t *zhp) 7089 { 7090 nvlist_t *config, *nvroot; 7091 7092 config = zpool_get_config(zhp, NULL); 7093 7094 if (config != NULL) { 7095 pool_checkpoint_stat_t *pcs = NULL; 7096 uint_t c; 7097 7098 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 7099 (void) nvlist_lookup_uint64_array(nvroot, 7100 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7101 7102 if (pcs == NULL || pcs->pcs_state == CS_NONE) 7103 return (B_FALSE); 7104 7105 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS || 7106 pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 7107 return (B_TRUE); 7108 } 7109 7110 return (B_FALSE); 7111 } 7112 7113 static int 7114 scrub_callback(zpool_handle_t *zhp, void *data) 7115 { 7116 scrub_cbdata_t *cb = data; 7117 int err; 7118 7119 /* 7120 * Ignore faulted pools. 7121 */ 7122 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 7123 (void) fprintf(stderr, gettext("cannot scan '%s': pool is " 7124 "currently unavailable\n"), zpool_get_name(zhp)); 7125 return (1); 7126 } 7127 7128 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 7129 7130 if (err == 0 && zpool_has_checkpoint(zhp) && 7131 cb->cb_type == POOL_SCAN_SCRUB) { 7132 (void) printf(gettext("warning: will not scrub state that " 7133 "belongs to the checkpoint of pool '%s'\n"), 7134 zpool_get_name(zhp)); 7135 } 7136 7137 return (err != 0); 7138 } 7139 7140 static int 7141 wait_callback(zpool_handle_t *zhp, void *data) 7142 { 7143 zpool_wait_activity_t *act = data; 7144 return (zpool_wait(zhp, *act)); 7145 } 7146 7147 /* 7148 * zpool scrub [-s | -p] [-w] <pool> ... 7149 * 7150 * -s Stop. Stops any in-progress scrub. 7151 * -p Pause. Pause in-progress scrub. 7152 * -w Wait. Blocks until scrub has completed. 7153 */ 7154 int 7155 zpool_do_scrub(int argc, char **argv) 7156 { 7157 int c; 7158 scrub_cbdata_t cb; 7159 boolean_t wait = B_FALSE; 7160 int error; 7161 7162 cb.cb_type = POOL_SCAN_SCRUB; 7163 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 7164 7165 /* check options */ 7166 while ((c = getopt(argc, argv, "spw")) != -1) { 7167 switch (c) { 7168 case 's': 7169 cb.cb_type = POOL_SCAN_NONE; 7170 break; 7171 case 'p': 7172 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 7173 break; 7174 case 'w': 7175 wait = B_TRUE; 7176 break; 7177 case '?': 7178 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7179 optopt); 7180 usage(B_FALSE); 7181 } 7182 } 7183 7184 if (cb.cb_type == POOL_SCAN_NONE && 7185 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 7186 (void) fprintf(stderr, gettext("invalid option combination: " 7187 "-s and -p are mutually exclusive\n")); 7188 usage(B_FALSE); 7189 } 7190 7191 if (wait && (cb.cb_type == POOL_SCAN_NONE || 7192 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE)) { 7193 (void) fprintf(stderr, gettext("invalid option combination: " 7194 "-w cannot be used with -p or -s\n")); 7195 usage(B_FALSE); 7196 } 7197 7198 argc -= optind; 7199 argv += optind; 7200 7201 if (argc < 1) { 7202 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7203 usage(B_FALSE); 7204 } 7205 7206 error = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7207 scrub_callback, &cb); 7208 7209 if (wait && !error) { 7210 zpool_wait_activity_t act = ZPOOL_WAIT_SCRUB; 7211 error = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7212 wait_callback, &act); 7213 } 7214 7215 return (error); 7216 } 7217 7218 /* 7219 * zpool resilver <pool> ... 7220 * 7221 * Restarts any in-progress resilver 7222 */ 7223 int 7224 zpool_do_resilver(int argc, char **argv) 7225 { 7226 int c; 7227 scrub_cbdata_t cb; 7228 7229 cb.cb_type = POOL_SCAN_RESILVER; 7230 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 7231 7232 /* check options */ 7233 while ((c = getopt(argc, argv, "")) != -1) { 7234 switch (c) { 7235 case '?': 7236 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7237 optopt); 7238 usage(B_FALSE); 7239 } 7240 } 7241 7242 argc -= optind; 7243 argv += optind; 7244 7245 if (argc < 1) { 7246 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7247 usage(B_FALSE); 7248 } 7249 7250 return (for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7251 scrub_callback, &cb)); 7252 } 7253 7254 /* 7255 * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...] 7256 * 7257 * -c Cancel. Ends any in-progress trim. 7258 * -d Secure trim. Requires kernel and device support. 7259 * -r <rate> Sets the TRIM rate in bytes (per second). Supports 7260 * adding a multiplier suffix such as 'k' or 'm'. 7261 * -s Suspend. TRIM can then be restarted with no flags. 7262 * -w Wait. Blocks until trimming has completed. 7263 */ 7264 int 7265 zpool_do_trim(int argc, char **argv) 7266 { 7267 struct option long_options[] = { 7268 {"cancel", no_argument, NULL, 'c'}, 7269 {"secure", no_argument, NULL, 'd'}, 7270 {"rate", required_argument, NULL, 'r'}, 7271 {"suspend", no_argument, NULL, 's'}, 7272 {"wait", no_argument, NULL, 'w'}, 7273 {0, 0, 0, 0} 7274 }; 7275 7276 pool_trim_func_t cmd_type = POOL_TRIM_START; 7277 uint64_t rate = 0; 7278 boolean_t secure = B_FALSE; 7279 boolean_t wait = B_FALSE; 7280 7281 int c; 7282 while ((c = getopt_long(argc, argv, "cdr:sw", long_options, NULL)) 7283 != -1) { 7284 switch (c) { 7285 case 'c': 7286 if (cmd_type != POOL_TRIM_START && 7287 cmd_type != POOL_TRIM_CANCEL) { 7288 (void) fprintf(stderr, gettext("-c cannot be " 7289 "combined with other options\n")); 7290 usage(B_FALSE); 7291 } 7292 cmd_type = POOL_TRIM_CANCEL; 7293 break; 7294 case 'd': 7295 if (cmd_type != POOL_TRIM_START) { 7296 (void) fprintf(stderr, gettext("-d cannot be " 7297 "combined with the -c or -s options\n")); 7298 usage(B_FALSE); 7299 } 7300 secure = B_TRUE; 7301 break; 7302 case 'r': 7303 if (cmd_type != POOL_TRIM_START) { 7304 (void) fprintf(stderr, gettext("-r cannot be " 7305 "combined with the -c or -s options\n")); 7306 usage(B_FALSE); 7307 } 7308 if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) { 7309 (void) fprintf(stderr, 7310 gettext("invalid value for rate\n")); 7311 usage(B_FALSE); 7312 } 7313 break; 7314 case 's': 7315 if (cmd_type != POOL_TRIM_START && 7316 cmd_type != POOL_TRIM_SUSPEND) { 7317 (void) fprintf(stderr, gettext("-s cannot be " 7318 "combined with other options\n")); 7319 usage(B_FALSE); 7320 } 7321 cmd_type = POOL_TRIM_SUSPEND; 7322 break; 7323 case 'w': 7324 wait = B_TRUE; 7325 break; 7326 case '?': 7327 if (optopt != 0) { 7328 (void) fprintf(stderr, 7329 gettext("invalid option '%c'\n"), optopt); 7330 } else { 7331 (void) fprintf(stderr, 7332 gettext("invalid option '%s'\n"), 7333 argv[optind - 1]); 7334 } 7335 usage(B_FALSE); 7336 } 7337 } 7338 7339 argc -= optind; 7340 argv += optind; 7341 7342 if (argc < 1) { 7343 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7344 usage(B_FALSE); 7345 return (-1); 7346 } 7347 7348 if (wait && (cmd_type != POOL_TRIM_START)) { 7349 (void) fprintf(stderr, gettext("-w cannot be used with -c or " 7350 "-s\n")); 7351 usage(B_FALSE); 7352 } 7353 7354 char *poolname = argv[0]; 7355 zpool_handle_t *zhp = zpool_open(g_zfs, poolname); 7356 if (zhp == NULL) 7357 return (-1); 7358 7359 trimflags_t trim_flags = { 7360 .secure = secure, 7361 .rate = rate, 7362 .wait = wait, 7363 }; 7364 7365 nvlist_t *vdevs = fnvlist_alloc(); 7366 if (argc == 1) { 7367 /* no individual leaf vdevs specified, so add them all */ 7368 nvlist_t *config = zpool_get_config(zhp, NULL); 7369 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 7370 ZPOOL_CONFIG_VDEV_TREE); 7371 zpool_collect_leaves(zhp, nvroot, vdevs); 7372 trim_flags.fullpool = B_TRUE; 7373 } else { 7374 trim_flags.fullpool = B_FALSE; 7375 for (int i = 1; i < argc; i++) { 7376 fnvlist_add_boolean(vdevs, argv[i]); 7377 } 7378 } 7379 7380 int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags); 7381 7382 fnvlist_free(vdevs); 7383 zpool_close(zhp); 7384 7385 return (error); 7386 } 7387 7388 /* 7389 * Converts a total number of seconds to a human readable string broken 7390 * down in to days/hours/minutes/seconds. 7391 */ 7392 static void 7393 secs_to_dhms(uint64_t total, char *buf) 7394 { 7395 uint64_t days = total / 60 / 60 / 24; 7396 uint64_t hours = (total / 60 / 60) % 24; 7397 uint64_t mins = (total / 60) % 60; 7398 uint64_t secs = (total % 60); 7399 7400 if (days > 0) { 7401 (void) sprintf(buf, "%llu days %02llu:%02llu:%02llu", 7402 (u_longlong_t)days, (u_longlong_t)hours, 7403 (u_longlong_t)mins, (u_longlong_t)secs); 7404 } else { 7405 (void) sprintf(buf, "%02llu:%02llu:%02llu", 7406 (u_longlong_t)hours, (u_longlong_t)mins, 7407 (u_longlong_t)secs); 7408 } 7409 } 7410 7411 /* 7412 * Print out detailed scrub status. 7413 */ 7414 static void 7415 print_scan_scrub_resilver_status(pool_scan_stat_t *ps) 7416 { 7417 time_t start, end, pause; 7418 uint64_t pass_scanned, scanned, pass_issued, issued, total; 7419 uint64_t elapsed, scan_rate, issue_rate; 7420 double fraction_done; 7421 char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7]; 7422 char srate_buf[7], irate_buf[7], time_buf[32]; 7423 7424 printf(" "); 7425 printf_color(ANSI_BOLD, gettext("scan:")); 7426 printf(" "); 7427 7428 /* If there's never been a scan, there's not much to say. */ 7429 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 7430 ps->pss_func >= POOL_SCAN_FUNCS) { 7431 (void) printf(gettext("none requested\n")); 7432 return; 7433 } 7434 7435 start = ps->pss_start_time; 7436 end = ps->pss_end_time; 7437 pause = ps->pss_pass_scrub_pause; 7438 7439 zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf)); 7440 7441 assert(ps->pss_func == POOL_SCAN_SCRUB || 7442 ps->pss_func == POOL_SCAN_RESILVER); 7443 7444 /* Scan is finished or canceled. */ 7445 if (ps->pss_state == DSS_FINISHED) { 7446 secs_to_dhms(end - start, time_buf); 7447 7448 if (ps->pss_func == POOL_SCAN_SCRUB) { 7449 (void) printf(gettext("scrub repaired %s " 7450 "in %s with %llu errors on %s"), processed_buf, 7451 time_buf, (u_longlong_t)ps->pss_errors, 7452 ctime(&end)); 7453 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7454 (void) printf(gettext("resilvered %s " 7455 "in %s with %llu errors on %s"), processed_buf, 7456 time_buf, (u_longlong_t)ps->pss_errors, 7457 ctime(&end)); 7458 } 7459 return; 7460 } else if (ps->pss_state == DSS_CANCELED) { 7461 if (ps->pss_func == POOL_SCAN_SCRUB) { 7462 (void) printf(gettext("scrub canceled on %s"), 7463 ctime(&end)); 7464 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7465 (void) printf(gettext("resilver canceled on %s"), 7466 ctime(&end)); 7467 } 7468 return; 7469 } 7470 7471 assert(ps->pss_state == DSS_SCANNING); 7472 7473 /* Scan is in progress. Resilvers can't be paused. */ 7474 if (ps->pss_func == POOL_SCAN_SCRUB) { 7475 if (pause == 0) { 7476 (void) printf(gettext("scrub in progress since %s"), 7477 ctime(&start)); 7478 } else { 7479 (void) printf(gettext("scrub paused since %s"), 7480 ctime(&pause)); 7481 (void) printf(gettext("\tscrub started on %s"), 7482 ctime(&start)); 7483 } 7484 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7485 (void) printf(gettext("resilver in progress since %s"), 7486 ctime(&start)); 7487 } 7488 7489 scanned = ps->pss_examined; 7490 pass_scanned = ps->pss_pass_exam; 7491 issued = ps->pss_issued; 7492 pass_issued = ps->pss_pass_issued; 7493 total = ps->pss_to_examine; 7494 7495 /* we are only done with a block once we have issued the IO for it */ 7496 fraction_done = (double)issued / total; 7497 7498 /* elapsed time for this pass, rounding up to 1 if it's 0 */ 7499 elapsed = time(NULL) - ps->pss_pass_start; 7500 elapsed -= ps->pss_pass_scrub_spent_paused; 7501 elapsed = (elapsed != 0) ? elapsed : 1; 7502 7503 scan_rate = pass_scanned / elapsed; 7504 issue_rate = pass_issued / elapsed; 7505 uint64_t total_secs_left = (issue_rate != 0 && total >= issued) ? 7506 ((total - issued) / issue_rate) : UINT64_MAX; 7507 secs_to_dhms(total_secs_left, time_buf); 7508 7509 /* format all of the numbers we will be reporting */ 7510 zfs_nicebytes(scanned, scanned_buf, sizeof (scanned_buf)); 7511 zfs_nicebytes(issued, issued_buf, sizeof (issued_buf)); 7512 zfs_nicebytes(total, total_buf, sizeof (total_buf)); 7513 zfs_nicebytes(scan_rate, srate_buf, sizeof (srate_buf)); 7514 zfs_nicebytes(issue_rate, irate_buf, sizeof (irate_buf)); 7515 7516 /* do not print estimated time if we have a paused scrub */ 7517 if (pause == 0) { 7518 (void) printf(gettext("\t%s scanned at %s/s, " 7519 "%s issued at %s/s, %s total\n"), 7520 scanned_buf, srate_buf, issued_buf, irate_buf, total_buf); 7521 } else { 7522 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"), 7523 scanned_buf, issued_buf, total_buf); 7524 } 7525 7526 if (ps->pss_func == POOL_SCAN_RESILVER) { 7527 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 7528 processed_buf, 100 * fraction_done); 7529 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 7530 (void) printf(gettext("\t%s repaired, %.2f%% done"), 7531 processed_buf, 100 * fraction_done); 7532 } 7533 7534 if (pause == 0) { 7535 if (total_secs_left != UINT64_MAX && 7536 issue_rate >= 10 * 1024 * 1024) { 7537 (void) printf(gettext(", %s to go\n"), time_buf); 7538 } else { 7539 (void) printf(gettext(", no estimated " 7540 "completion time\n")); 7541 } 7542 } else { 7543 (void) printf(gettext("\n")); 7544 } 7545 } 7546 7547 static void 7548 print_rebuild_status_impl(vdev_rebuild_stat_t *vrs, char *vdev_name) 7549 { 7550 if (vrs == NULL || vrs->vrs_state == VDEV_REBUILD_NONE) 7551 return; 7552 7553 printf(" "); 7554 printf_color(ANSI_BOLD, gettext("scan:")); 7555 printf(" "); 7556 7557 uint64_t bytes_scanned = vrs->vrs_bytes_scanned; 7558 uint64_t bytes_issued = vrs->vrs_bytes_issued; 7559 uint64_t bytes_rebuilt = vrs->vrs_bytes_rebuilt; 7560 uint64_t bytes_est = vrs->vrs_bytes_est; 7561 uint64_t scan_rate = (vrs->vrs_pass_bytes_scanned / 7562 (vrs->vrs_pass_time_ms + 1)) * 1000; 7563 uint64_t issue_rate = (vrs->vrs_pass_bytes_issued / 7564 (vrs->vrs_pass_time_ms + 1)) * 1000; 7565 double scan_pct = MIN((double)bytes_scanned * 100 / 7566 (bytes_est + 1), 100); 7567 7568 /* Format all of the numbers we will be reporting */ 7569 char bytes_scanned_buf[7], bytes_issued_buf[7]; 7570 char bytes_rebuilt_buf[7], bytes_est_buf[7]; 7571 char scan_rate_buf[7], issue_rate_buf[7], time_buf[32]; 7572 zfs_nicebytes(bytes_scanned, bytes_scanned_buf, 7573 sizeof (bytes_scanned_buf)); 7574 zfs_nicebytes(bytes_issued, bytes_issued_buf, 7575 sizeof (bytes_issued_buf)); 7576 zfs_nicebytes(bytes_rebuilt, bytes_rebuilt_buf, 7577 sizeof (bytes_rebuilt_buf)); 7578 zfs_nicebytes(bytes_est, bytes_est_buf, sizeof (bytes_est_buf)); 7579 zfs_nicebytes(scan_rate, scan_rate_buf, sizeof (scan_rate_buf)); 7580 zfs_nicebytes(issue_rate, issue_rate_buf, sizeof (issue_rate_buf)); 7581 7582 time_t start = vrs->vrs_start_time; 7583 time_t end = vrs->vrs_end_time; 7584 7585 /* Rebuild is finished or canceled. */ 7586 if (vrs->vrs_state == VDEV_REBUILD_COMPLETE) { 7587 secs_to_dhms(vrs->vrs_scan_time_ms / 1000, time_buf); 7588 (void) printf(gettext("resilvered (%s) %s in %s " 7589 "with %llu errors on %s"), vdev_name, bytes_rebuilt_buf, 7590 time_buf, (u_longlong_t)vrs->vrs_errors, ctime(&end)); 7591 return; 7592 } else if (vrs->vrs_state == VDEV_REBUILD_CANCELED) { 7593 (void) printf(gettext("resilver (%s) canceled on %s"), 7594 vdev_name, ctime(&end)); 7595 return; 7596 } else if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7597 (void) printf(gettext("resilver (%s) in progress since %s"), 7598 vdev_name, ctime(&start)); 7599 } 7600 7601 assert(vrs->vrs_state == VDEV_REBUILD_ACTIVE); 7602 7603 secs_to_dhms(MAX((int64_t)bytes_est - (int64_t)bytes_scanned, 0) / 7604 MAX(scan_rate, 1), time_buf); 7605 7606 (void) printf(gettext("\t%s scanned at %s/s, %s issued %s/s, " 7607 "%s total\n"), bytes_scanned_buf, scan_rate_buf, 7608 bytes_issued_buf, issue_rate_buf, bytes_est_buf); 7609 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 7610 bytes_rebuilt_buf, scan_pct); 7611 7612 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7613 if (scan_rate >= 10 * 1024 * 1024) { 7614 (void) printf(gettext(", %s to go\n"), time_buf); 7615 } else { 7616 (void) printf(gettext(", no estimated " 7617 "completion time\n")); 7618 } 7619 } else { 7620 (void) printf(gettext("\n")); 7621 } 7622 } 7623 7624 /* 7625 * Print rebuild status for top-level vdevs. 7626 */ 7627 static void 7628 print_rebuild_status(zpool_handle_t *zhp, nvlist_t *nvroot) 7629 { 7630 nvlist_t **child; 7631 uint_t children; 7632 7633 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7634 &child, &children) != 0) 7635 children = 0; 7636 7637 for (uint_t c = 0; c < children; c++) { 7638 vdev_rebuild_stat_t *vrs; 7639 uint_t i; 7640 7641 if (nvlist_lookup_uint64_array(child[c], 7642 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) { 7643 char *name = zpool_vdev_name(g_zfs, zhp, 7644 child[c], VDEV_NAME_TYPE_ID); 7645 print_rebuild_status_impl(vrs, name); 7646 free(name); 7647 } 7648 } 7649 } 7650 7651 /* 7652 * As we don't scrub checkpointed blocks, we want to warn the user that we 7653 * skipped scanning some blocks if a checkpoint exists or existed at any 7654 * time during the scan. If a sequential instead of healing reconstruction 7655 * was performed then the blocks were reconstructed. However, their checksums 7656 * have not been verified so we still print the warning. 7657 */ 7658 static void 7659 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs) 7660 { 7661 if (ps == NULL || pcs == NULL) 7662 return; 7663 7664 if (pcs->pcs_state == CS_NONE || 7665 pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 7666 return; 7667 7668 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS); 7669 7670 if (ps->pss_state == DSS_NONE) 7671 return; 7672 7673 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) && 7674 ps->pss_end_time < pcs->pcs_start_time) 7675 return; 7676 7677 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) { 7678 (void) printf(gettext(" scan warning: skipped blocks " 7679 "that are only referenced by the checkpoint.\n")); 7680 } else { 7681 assert(ps->pss_state == DSS_SCANNING); 7682 (void) printf(gettext(" scan warning: skipping blocks " 7683 "that are only referenced by the checkpoint.\n")); 7684 } 7685 } 7686 7687 /* 7688 * Returns B_TRUE if there is an active rebuild in progress. Otherwise, 7689 * B_FALSE is returned and 'rebuild_end_time' is set to the end time for 7690 * the last completed (or cancelled) rebuild. 7691 */ 7692 static boolean_t 7693 check_rebuilding(nvlist_t *nvroot, uint64_t *rebuild_end_time) 7694 { 7695 nvlist_t **child; 7696 uint_t children; 7697 boolean_t rebuilding = B_FALSE; 7698 uint64_t end_time = 0; 7699 7700 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7701 &child, &children) != 0) 7702 children = 0; 7703 7704 for (uint_t c = 0; c < children; c++) { 7705 vdev_rebuild_stat_t *vrs; 7706 uint_t i; 7707 7708 if (nvlist_lookup_uint64_array(child[c], 7709 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) { 7710 7711 if (vrs->vrs_end_time > end_time) 7712 end_time = vrs->vrs_end_time; 7713 7714 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7715 rebuilding = B_TRUE; 7716 end_time = 0; 7717 break; 7718 } 7719 } 7720 } 7721 7722 if (rebuild_end_time != NULL) 7723 *rebuild_end_time = end_time; 7724 7725 return (rebuilding); 7726 } 7727 7728 /* 7729 * Print the scan status. 7730 */ 7731 static void 7732 print_scan_status(zpool_handle_t *zhp, nvlist_t *nvroot) 7733 { 7734 uint64_t rebuild_end_time = 0, resilver_end_time = 0; 7735 boolean_t have_resilver = B_FALSE, have_scrub = B_FALSE; 7736 boolean_t active_resilver = B_FALSE; 7737 pool_checkpoint_stat_t *pcs = NULL; 7738 pool_scan_stat_t *ps = NULL; 7739 uint_t c; 7740 7741 if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS, 7742 (uint64_t **)&ps, &c) == 0) { 7743 if (ps->pss_func == POOL_SCAN_RESILVER) { 7744 resilver_end_time = ps->pss_end_time; 7745 active_resilver = (ps->pss_state == DSS_SCANNING); 7746 } 7747 7748 have_resilver = (ps->pss_func == POOL_SCAN_RESILVER); 7749 have_scrub = (ps->pss_func == POOL_SCAN_SCRUB); 7750 } 7751 7752 boolean_t active_rebuild = check_rebuilding(nvroot, &rebuild_end_time); 7753 boolean_t have_rebuild = (active_rebuild || (rebuild_end_time > 0)); 7754 7755 /* Always print the scrub status when available. */ 7756 if (have_scrub) 7757 print_scan_scrub_resilver_status(ps); 7758 7759 /* 7760 * When there is an active resilver or rebuild print its status. 7761 * Otherwise print the status of the last resilver or rebuild. 7762 */ 7763 if (active_resilver || (!active_rebuild && have_resilver && 7764 resilver_end_time && resilver_end_time > rebuild_end_time)) { 7765 print_scan_scrub_resilver_status(ps); 7766 } else if (active_rebuild || (!active_resilver && have_rebuild && 7767 rebuild_end_time && rebuild_end_time > resilver_end_time)) { 7768 print_rebuild_status(zhp, nvroot); 7769 } 7770 7771 (void) nvlist_lookup_uint64_array(nvroot, 7772 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7773 print_checkpoint_scan_warning(ps, pcs); 7774 } 7775 7776 /* 7777 * Print out detailed removal status. 7778 */ 7779 static void 7780 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 7781 { 7782 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 7783 time_t start, end; 7784 nvlist_t *config, *nvroot; 7785 nvlist_t **child; 7786 uint_t children; 7787 char *vdev_name; 7788 7789 if (prs == NULL || prs->prs_state == DSS_NONE) 7790 return; 7791 7792 /* 7793 * Determine name of vdev. 7794 */ 7795 config = zpool_get_config(zhp, NULL); 7796 nvroot = fnvlist_lookup_nvlist(config, 7797 ZPOOL_CONFIG_VDEV_TREE); 7798 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7799 &child, &children) == 0); 7800 assert(prs->prs_removing_vdev < children); 7801 vdev_name = zpool_vdev_name(g_zfs, zhp, 7802 child[prs->prs_removing_vdev], B_TRUE); 7803 7804 printf_color(ANSI_BOLD, gettext("remove: ")); 7805 7806 start = prs->prs_start_time; 7807 end = prs->prs_end_time; 7808 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 7809 7810 /* 7811 * Removal is finished or canceled. 7812 */ 7813 if (prs->prs_state == DSS_FINISHED) { 7814 uint64_t minutes_taken = (end - start) / 60; 7815 7816 (void) printf(gettext("Removal of vdev %llu copied %s " 7817 "in %lluh%um, completed on %s"), 7818 (longlong_t)prs->prs_removing_vdev, 7819 copied_buf, 7820 (u_longlong_t)(minutes_taken / 60), 7821 (uint_t)(minutes_taken % 60), 7822 ctime((time_t *)&end)); 7823 } else if (prs->prs_state == DSS_CANCELED) { 7824 (void) printf(gettext("Removal of %s canceled on %s"), 7825 vdev_name, ctime(&end)); 7826 } else { 7827 uint64_t copied, total, elapsed, mins_left, hours_left; 7828 double fraction_done; 7829 uint_t rate; 7830 7831 assert(prs->prs_state == DSS_SCANNING); 7832 7833 /* 7834 * Removal is in progress. 7835 */ 7836 (void) printf(gettext( 7837 "Evacuation of %s in progress since %s"), 7838 vdev_name, ctime(&start)); 7839 7840 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 7841 total = prs->prs_to_copy; 7842 fraction_done = (double)copied / total; 7843 7844 /* elapsed time for this pass */ 7845 elapsed = time(NULL) - prs->prs_start_time; 7846 elapsed = elapsed > 0 ? elapsed : 1; 7847 rate = copied / elapsed; 7848 rate = rate > 0 ? rate : 1; 7849 mins_left = ((total - copied) / rate) / 60; 7850 hours_left = mins_left / 60; 7851 7852 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 7853 zfs_nicenum(total, total_buf, sizeof (total_buf)); 7854 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 7855 7856 /* 7857 * do not print estimated time if hours_left is more than 7858 * 30 days 7859 */ 7860 (void) printf(gettext( 7861 "\t%s copied out of %s at %s/s, %.2f%% done"), 7862 examined_buf, total_buf, rate_buf, 100 * fraction_done); 7863 if (hours_left < (30 * 24)) { 7864 (void) printf(gettext(", %lluh%um to go\n"), 7865 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 7866 } else { 7867 (void) printf(gettext( 7868 ", (copy is slow, no estimated time)\n")); 7869 } 7870 } 7871 free(vdev_name); 7872 7873 if (prs->prs_mapping_memory > 0) { 7874 char mem_buf[7]; 7875 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 7876 (void) printf(gettext( 7877 "\t%s memory used for removed device mappings\n"), 7878 mem_buf); 7879 } 7880 } 7881 7882 static void 7883 print_checkpoint_status(pool_checkpoint_stat_t *pcs) 7884 { 7885 time_t start; 7886 char space_buf[7]; 7887 7888 if (pcs == NULL || pcs->pcs_state == CS_NONE) 7889 return; 7890 7891 (void) printf(gettext("checkpoint: ")); 7892 7893 start = pcs->pcs_start_time; 7894 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf)); 7895 7896 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) { 7897 char *date = ctime(&start); 7898 7899 /* 7900 * ctime() adds a newline at the end of the generated 7901 * string, thus the weird format specifier and the 7902 * strlen() call used to chop it off from the output. 7903 */ 7904 (void) printf(gettext("created %.*s, consumes %s\n"), 7905 (int)(strlen(date) - 1), date, space_buf); 7906 return; 7907 } 7908 7909 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 7910 7911 (void) printf(gettext("discarding, %s remaining.\n"), 7912 space_buf); 7913 } 7914 7915 static void 7916 print_error_log(zpool_handle_t *zhp) 7917 { 7918 nvlist_t *nverrlist = NULL; 7919 nvpair_t *elem; 7920 char *pathname; 7921 size_t len = MAXPATHLEN * 2; 7922 7923 if (zpool_get_errlog(zhp, &nverrlist) != 0) 7924 return; 7925 7926 (void) printf("errors: Permanent errors have been " 7927 "detected in the following files:\n\n"); 7928 7929 pathname = safe_malloc(len); 7930 elem = NULL; 7931 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 7932 nvlist_t *nv; 7933 uint64_t dsobj, obj; 7934 7935 verify(nvpair_value_nvlist(elem, &nv) == 0); 7936 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 7937 &dsobj) == 0); 7938 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 7939 &obj) == 0); 7940 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 7941 (void) printf("%7s %s\n", "", pathname); 7942 } 7943 free(pathname); 7944 nvlist_free(nverrlist); 7945 } 7946 7947 static void 7948 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares, 7949 uint_t nspares) 7950 { 7951 uint_t i; 7952 char *name; 7953 7954 if (nspares == 0) 7955 return; 7956 7957 (void) printf(gettext("\tspares\n")); 7958 7959 for (i = 0; i < nspares; i++) { 7960 name = zpool_vdev_name(g_zfs, zhp, spares[i], 7961 cb->cb_name_flags); 7962 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE, NULL); 7963 free(name); 7964 } 7965 } 7966 7967 static void 7968 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache, 7969 uint_t nl2cache) 7970 { 7971 uint_t i; 7972 char *name; 7973 7974 if (nl2cache == 0) 7975 return; 7976 7977 (void) printf(gettext("\tcache\n")); 7978 7979 for (i = 0; i < nl2cache; i++) { 7980 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], 7981 cb->cb_name_flags); 7982 print_status_config(zhp, cb, name, l2cache[i], 2, 7983 B_FALSE, NULL); 7984 free(name); 7985 } 7986 } 7987 7988 static void 7989 print_dedup_stats(nvlist_t *config) 7990 { 7991 ddt_histogram_t *ddh; 7992 ddt_stat_t *dds; 7993 ddt_object_t *ddo; 7994 uint_t c; 7995 char dspace[6], mspace[6]; 7996 7997 /* 7998 * If the pool was faulted then we may not have been able to 7999 * obtain the config. Otherwise, if we have anything in the dedup 8000 * table continue processing the stats. 8001 */ 8002 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 8003 (uint64_t **)&ddo, &c) != 0) 8004 return; 8005 8006 (void) printf("\n"); 8007 (void) printf(gettext(" dedup: ")); 8008 if (ddo->ddo_count == 0) { 8009 (void) printf(gettext("no DDT entries\n")); 8010 return; 8011 } 8012 8013 zfs_nicebytes(ddo->ddo_dspace, dspace, sizeof (dspace)); 8014 zfs_nicebytes(ddo->ddo_mspace, mspace, sizeof (mspace)); 8015 (void) printf("DDT entries %llu, size %s on disk, %s in core\n", 8016 (u_longlong_t)ddo->ddo_count, 8017 dspace, 8018 mspace); 8019 8020 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 8021 (uint64_t **)&dds, &c) == 0); 8022 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 8023 (uint64_t **)&ddh, &c) == 0); 8024 zpool_dump_ddt(dds, ddh); 8025 } 8026 8027 /* 8028 * Display a summary of pool status. Displays a summary such as: 8029 * 8030 * pool: tank 8031 * status: DEGRADED 8032 * reason: One or more devices ... 8033 * see: https://openzfs.github.io/openzfs-docs/msg/ZFS-xxxx-01 8034 * config: 8035 * mirror DEGRADED 8036 * c1t0d0 OK 8037 * c2t0d0 UNAVAIL 8038 * 8039 * When given the '-v' option, we print out the complete config. If the '-e' 8040 * option is specified, then we print out error rate information as well. 8041 */ 8042 static int 8043 status_callback(zpool_handle_t *zhp, void *data) 8044 { 8045 status_cbdata_t *cbp = data; 8046 nvlist_t *config, *nvroot; 8047 char *msgid; 8048 zpool_status_t reason; 8049 zpool_errata_t errata; 8050 const char *health; 8051 uint_t c; 8052 vdev_stat_t *vs; 8053 8054 config = zpool_get_config(zhp, NULL); 8055 reason = zpool_get_status(zhp, &msgid, &errata); 8056 8057 cbp->cb_count++; 8058 8059 /* 8060 * If we were given 'zpool status -x', only report those pools with 8061 * problems. 8062 */ 8063 if (cbp->cb_explain && 8064 (reason == ZPOOL_STATUS_OK || 8065 reason == ZPOOL_STATUS_VERSION_OLDER || 8066 reason == ZPOOL_STATUS_FEAT_DISABLED || 8067 reason == ZPOOL_STATUS_COMPATIBILITY_ERR || 8068 reason == ZPOOL_STATUS_INCOMPATIBLE_FEAT)) { 8069 if (!cbp->cb_allpools) { 8070 (void) printf(gettext("pool '%s' is healthy\n"), 8071 zpool_get_name(zhp)); 8072 if (cbp->cb_first) 8073 cbp->cb_first = B_FALSE; 8074 } 8075 return (0); 8076 } 8077 8078 if (cbp->cb_first) 8079 cbp->cb_first = B_FALSE; 8080 else 8081 (void) printf("\n"); 8082 8083 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 8084 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 8085 (uint64_t **)&vs, &c) == 0); 8086 8087 health = zpool_get_state_str(zhp); 8088 8089 printf(" "); 8090 printf_color(ANSI_BOLD, gettext("pool:")); 8091 printf(" %s\n", zpool_get_name(zhp)); 8092 printf(" "); 8093 printf_color(ANSI_BOLD, gettext("state: ")); 8094 8095 printf_color(health_str_to_color(health), "%s", health); 8096 8097 printf("\n"); 8098 8099 switch (reason) { 8100 case ZPOOL_STATUS_MISSING_DEV_R: 8101 printf_color(ANSI_BOLD, gettext("status: ")); 8102 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8103 "not be opened. Sufficient replicas exist for\n\tthe pool " 8104 "to continue functioning in a degraded state.\n")); 8105 printf_color(ANSI_BOLD, gettext("action: ")); 8106 printf_color(ANSI_YELLOW, gettext("Attach the missing device " 8107 "and online it using 'zpool online'.\n")); 8108 break; 8109 8110 case ZPOOL_STATUS_MISSING_DEV_NR: 8111 printf_color(ANSI_BOLD, gettext("status: ")); 8112 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8113 "not be opened. There are insufficient\n\treplicas for the" 8114 " pool to continue functioning.\n")); 8115 printf_color(ANSI_BOLD, gettext("action: ")); 8116 printf_color(ANSI_YELLOW, gettext("Attach the missing device " 8117 "and online it using 'zpool online'.\n")); 8118 break; 8119 8120 case ZPOOL_STATUS_CORRUPT_LABEL_R: 8121 printf_color(ANSI_BOLD, gettext("status: ")); 8122 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8123 "not be used because the label is missing or\n\tinvalid. " 8124 "Sufficient replicas exist for the pool to continue\n\t" 8125 "functioning in a degraded state.\n")); 8126 printf_color(ANSI_BOLD, gettext("action: ")); 8127 printf_color(ANSI_YELLOW, gettext("Replace the device using " 8128 "'zpool replace'.\n")); 8129 break; 8130 8131 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 8132 printf_color(ANSI_BOLD, gettext("status: ")); 8133 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8134 "not be used because the label is missing \n\tor invalid. " 8135 "There are insufficient replicas for the pool to " 8136 "continue\n\tfunctioning.\n")); 8137 zpool_explain_recover(zpool_get_handle(zhp), 8138 zpool_get_name(zhp), reason, config); 8139 break; 8140 8141 case ZPOOL_STATUS_FAILING_DEV: 8142 printf_color(ANSI_BOLD, gettext("status: ")); 8143 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8144 "experienced an unrecoverable error. An\n\tattempt was " 8145 "made to correct the error. Applications are " 8146 "unaffected.\n")); 8147 printf_color(ANSI_BOLD, gettext("action: ")); 8148 printf_color(ANSI_YELLOW, gettext("Determine if the " 8149 "device needs to be replaced, and clear the errors\n\tusing" 8150 " 'zpool clear' or replace the device with 'zpool " 8151 "replace'.\n")); 8152 break; 8153 8154 case ZPOOL_STATUS_OFFLINE_DEV: 8155 printf_color(ANSI_BOLD, gettext("status: ")); 8156 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8157 "been taken offline by the administrator.\n\tSufficient " 8158 "replicas exist for the pool to continue functioning in " 8159 "a\n\tdegraded state.\n")); 8160 printf_color(ANSI_BOLD, gettext("action: ")); 8161 printf_color(ANSI_YELLOW, gettext("Online the device " 8162 "using 'zpool online' or replace the device with\n\t'zpool " 8163 "replace'.\n")); 8164 break; 8165 8166 case ZPOOL_STATUS_REMOVED_DEV: 8167 printf_color(ANSI_BOLD, gettext("status: ")); 8168 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8169 "been removed by the administrator.\n\tSufficient " 8170 "replicas exist for the pool to continue functioning in " 8171 "a\n\tdegraded state.\n")); 8172 printf_color(ANSI_BOLD, gettext("action: ")); 8173 printf_color(ANSI_YELLOW, gettext("Online the device " 8174 "using zpool online' or replace the device with\n\t'zpool " 8175 "replace'.\n")); 8176 break; 8177 8178 case ZPOOL_STATUS_RESILVERING: 8179 case ZPOOL_STATUS_REBUILDING: 8180 printf_color(ANSI_BOLD, gettext("status: ")); 8181 printf_color(ANSI_YELLOW, gettext("One or more devices is " 8182 "currently being resilvered. The pool will\n\tcontinue " 8183 "to function, possibly in a degraded state.\n")); 8184 printf_color(ANSI_BOLD, gettext("action: ")); 8185 printf_color(ANSI_YELLOW, gettext("Wait for the resilver to " 8186 "complete.\n")); 8187 break; 8188 8189 case ZPOOL_STATUS_REBUILD_SCRUB: 8190 printf_color(ANSI_BOLD, gettext("status: ")); 8191 printf_color(ANSI_YELLOW, gettext("One or more devices have " 8192 "been sequentially resilvered, scrubbing\n\tthe pool " 8193 "is recommended.\n")); 8194 printf_color(ANSI_BOLD, gettext("action: ")); 8195 printf_color(ANSI_YELLOW, gettext("Use 'zpool scrub' to " 8196 "verify all data checksums.\n")); 8197 break; 8198 8199 case ZPOOL_STATUS_CORRUPT_DATA: 8200 printf_color(ANSI_BOLD, gettext("status: ")); 8201 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8202 "experienced an error resulting in data\n\tcorruption. " 8203 "Applications may be affected.\n")); 8204 printf_color(ANSI_BOLD, gettext("action: ")); 8205 printf_color(ANSI_YELLOW, gettext("Restore the file in question" 8206 " if possible. Otherwise restore the\n\tentire pool from " 8207 "backup.\n")); 8208 break; 8209 8210 case ZPOOL_STATUS_CORRUPT_POOL: 8211 printf_color(ANSI_BOLD, gettext("status: ")); 8212 printf_color(ANSI_YELLOW, gettext("The pool metadata is " 8213 "corrupted and the pool cannot be opened.\n")); 8214 zpool_explain_recover(zpool_get_handle(zhp), 8215 zpool_get_name(zhp), reason, config); 8216 break; 8217 8218 case ZPOOL_STATUS_VERSION_OLDER: 8219 printf_color(ANSI_BOLD, gettext("status: ")); 8220 printf_color(ANSI_YELLOW, gettext("The pool is formatted using " 8221 "a legacy on-disk format. The pool can\n\tstill be used, " 8222 "but some features are unavailable.\n")); 8223 printf_color(ANSI_BOLD, gettext("action: ")); 8224 printf_color(ANSI_YELLOW, gettext("Upgrade the pool using " 8225 "'zpool upgrade'. Once this is done, the\n\tpool will no " 8226 "longer be accessible on software that does not support\n\t" 8227 "feature flags.\n")); 8228 break; 8229 8230 case ZPOOL_STATUS_VERSION_NEWER: 8231 printf_color(ANSI_BOLD, gettext("status: ")); 8232 printf_color(ANSI_YELLOW, gettext("The pool has been upgraded " 8233 "to a newer, incompatible on-disk version.\n\tThe pool " 8234 "cannot be accessed on this system.\n")); 8235 printf_color(ANSI_BOLD, gettext("action: ")); 8236 printf_color(ANSI_YELLOW, gettext("Access the pool from a " 8237 "system running more recent software, or\n\trestore the " 8238 "pool from backup.\n")); 8239 break; 8240 8241 case ZPOOL_STATUS_FEAT_DISABLED: 8242 printf_color(ANSI_BOLD, gettext("status: ")); 8243 printf_color(ANSI_YELLOW, gettext("Some supported and " 8244 "requested features are not enabled on the pool.\n\t" 8245 "The pool can still be used, but some features are " 8246 "unavailable.\n")); 8247 printf_color(ANSI_BOLD, gettext("action: ")); 8248 printf_color(ANSI_YELLOW, gettext("Enable all features using " 8249 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 8250 "longer be accessible by software that does not support\n\t" 8251 "the features. See zpool-features(7) for details.\n")); 8252 break; 8253 8254 case ZPOOL_STATUS_COMPATIBILITY_ERR: 8255 printf_color(ANSI_BOLD, gettext("status: ")); 8256 printf_color(ANSI_YELLOW, gettext("This pool has a " 8257 "compatibility list specified, but it could not be\n\t" 8258 "read/parsed at this time. The pool can still be used, " 8259 "but this\n\tshould be investigated.\n")); 8260 printf_color(ANSI_BOLD, gettext("action: ")); 8261 printf_color(ANSI_YELLOW, gettext("Check the value of the " 8262 "'compatibility' property against the\n\t" 8263 "appropriate file in " ZPOOL_SYSCONF_COMPAT_D " or " 8264 ZPOOL_DATA_COMPAT_D ".\n")); 8265 break; 8266 8267 case ZPOOL_STATUS_INCOMPATIBLE_FEAT: 8268 printf_color(ANSI_BOLD, gettext("status: ")); 8269 printf_color(ANSI_YELLOW, gettext("One or more features " 8270 "are enabled on the pool despite not being\n\t" 8271 "requested by the 'compatibility' property.\n")); 8272 printf_color(ANSI_BOLD, gettext("action: ")); 8273 printf_color(ANSI_YELLOW, gettext("Consider setting " 8274 "'compatibility' to an appropriate value, or\n\t" 8275 "adding needed features to the relevant file in\n\t" 8276 ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n")); 8277 break; 8278 8279 case ZPOOL_STATUS_UNSUP_FEAT_READ: 8280 printf_color(ANSI_BOLD, gettext("status: ")); 8281 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed " 8282 "on this system because it uses the\n\tfollowing feature(s)" 8283 " not supported on this system:\n")); 8284 zpool_print_unsup_feat(config); 8285 (void) printf("\n"); 8286 printf_color(ANSI_BOLD, gettext("action: ")); 8287 printf_color(ANSI_YELLOW, gettext("Access the pool from a " 8288 "system that supports the required feature(s),\n\tor " 8289 "restore the pool from backup.\n")); 8290 break; 8291 8292 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 8293 printf_color(ANSI_BOLD, gettext("status: ")); 8294 printf_color(ANSI_YELLOW, gettext("The pool can only be " 8295 "accessed in read-only mode on this system. It\n\tcannot be" 8296 " accessed in read-write mode because it uses the " 8297 "following\n\tfeature(s) not supported on this system:\n")); 8298 zpool_print_unsup_feat(config); 8299 (void) printf("\n"); 8300 printf_color(ANSI_BOLD, gettext("action: ")); 8301 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed " 8302 "in read-write mode. Import the pool with\n" 8303 "\t\"-o readonly=on\", access the pool from a system that " 8304 "supports the\n\trequired feature(s), or restore the " 8305 "pool from backup.\n")); 8306 break; 8307 8308 case ZPOOL_STATUS_FAULTED_DEV_R: 8309 printf_color(ANSI_BOLD, gettext("status: ")); 8310 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8311 "faulted in response to persistent errors.\n\tSufficient " 8312 "replicas exist for the pool to continue functioning " 8313 "in a\n\tdegraded state.\n")); 8314 printf_color(ANSI_BOLD, gettext("action: ")); 8315 printf_color(ANSI_YELLOW, gettext("Replace the faulted device, " 8316 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 8317 break; 8318 8319 case ZPOOL_STATUS_FAULTED_DEV_NR: 8320 printf_color(ANSI_BOLD, gettext("status: ")); 8321 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8322 "faulted in response to persistent errors. There are " 8323 "insufficient replicas for the pool to\n\tcontinue " 8324 "functioning.\n")); 8325 printf_color(ANSI_BOLD, gettext("action: ")); 8326 printf_color(ANSI_YELLOW, gettext("Destroy and re-create the " 8327 "pool from a backup source. Manually marking the device\n" 8328 "\trepaired using 'zpool clear' may allow some data " 8329 "to be recovered.\n")); 8330 break; 8331 8332 case ZPOOL_STATUS_IO_FAILURE_MMP: 8333 printf_color(ANSI_BOLD, gettext("status: ")); 8334 printf_color(ANSI_YELLOW, gettext("The pool is suspended " 8335 "because multihost writes failed or were delayed;\n\t" 8336 "another system could import the pool undetected.\n")); 8337 printf_color(ANSI_BOLD, gettext("action: ")); 8338 printf_color(ANSI_YELLOW, gettext("Make sure the pool's devices" 8339 " are connected, then reboot your system and\n\timport the " 8340 "pool.\n")); 8341 break; 8342 8343 case ZPOOL_STATUS_IO_FAILURE_WAIT: 8344 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 8345 printf_color(ANSI_BOLD, gettext("status: ")); 8346 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8347 "faulted in response to IO failures.\n")); 8348 printf_color(ANSI_BOLD, gettext("action: ")); 8349 printf_color(ANSI_YELLOW, gettext("Make sure the affected " 8350 "devices are connected, then run 'zpool clear'.\n")); 8351 break; 8352 8353 case ZPOOL_STATUS_BAD_LOG: 8354 printf_color(ANSI_BOLD, gettext("status: ")); 8355 printf_color(ANSI_YELLOW, gettext("An intent log record " 8356 "could not be read.\n" 8357 "\tWaiting for administrator intervention to fix the " 8358 "faulted pool.\n")); 8359 printf_color(ANSI_BOLD, gettext("action: ")); 8360 printf_color(ANSI_YELLOW, gettext("Either restore the affected " 8361 "device(s) and run 'zpool online',\n" 8362 "\tor ignore the intent log records by running " 8363 "'zpool clear'.\n")); 8364 break; 8365 8366 case ZPOOL_STATUS_NON_NATIVE_ASHIFT: 8367 (void) printf(gettext("status: One or more devices are " 8368 "configured to use a non-native block size.\n" 8369 "\tExpect reduced performance.\n")); 8370 (void) printf(gettext("action: Replace affected devices with " 8371 "devices that support the\n\tconfigured block size, or " 8372 "migrate data to a properly configured\n\tpool.\n")); 8373 break; 8374 8375 case ZPOOL_STATUS_HOSTID_MISMATCH: 8376 printf_color(ANSI_BOLD, gettext("status: ")); 8377 printf_color(ANSI_YELLOW, gettext("Mismatch between pool hostid" 8378 " and system hostid on imported pool.\n\tThis pool was " 8379 "previously imported into a system with a different " 8380 "hostid,\n\tand then was verbatim imported into this " 8381 "system.\n")); 8382 printf_color(ANSI_BOLD, gettext("action: ")); 8383 printf_color(ANSI_YELLOW, gettext("Export this pool on all " 8384 "systems on which it is imported.\n" 8385 "\tThen import it to correct the mismatch.\n")); 8386 break; 8387 8388 case ZPOOL_STATUS_ERRATA: 8389 printf_color(ANSI_BOLD, gettext("status: ")); 8390 printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"), 8391 errata); 8392 8393 switch (errata) { 8394 case ZPOOL_ERRATA_NONE: 8395 break; 8396 8397 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 8398 printf_color(ANSI_BOLD, gettext("action: ")); 8399 printf_color(ANSI_YELLOW, gettext("To correct the issue" 8400 " run 'zpool scrub'.\n")); 8401 break; 8402 8403 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 8404 (void) printf(gettext("\tExisting encrypted datasets " 8405 "contain an on-disk incompatibility\n\twhich " 8406 "needs to be corrected.\n")); 8407 printf_color(ANSI_BOLD, gettext("action: ")); 8408 printf_color(ANSI_YELLOW, gettext("To correct the issue" 8409 " backup existing encrypted datasets to new\n\t" 8410 "encrypted datasets and destroy the old ones. " 8411 "'zfs mount -o ro' can\n\tbe used to temporarily " 8412 "mount existing encrypted datasets readonly.\n")); 8413 break; 8414 8415 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 8416 (void) printf(gettext("\tExisting encrypted snapshots " 8417 "and bookmarks contain an on-disk\n\tincompat" 8418 "ibility. This may cause on-disk corruption if " 8419 "they are used\n\twith 'zfs recv'.\n")); 8420 printf_color(ANSI_BOLD, gettext("action: ")); 8421 printf_color(ANSI_YELLOW, gettext("To correct the" 8422 "issue, enable the bookmark_v2 feature. No " 8423 "additional\n\taction is needed if there are no " 8424 "encrypted snapshots or bookmarks.\n\tIf preserving" 8425 "the encrypted snapshots and bookmarks is required," 8426 " use\n\ta non-raw send to backup and restore them." 8427 " Alternately, they may be\n\tremoved to resolve " 8428 "the incompatibility.\n")); 8429 break; 8430 8431 default: 8432 /* 8433 * All errata which allow the pool to be imported 8434 * must contain an action message. 8435 */ 8436 assert(0); 8437 } 8438 break; 8439 8440 default: 8441 /* 8442 * The remaining errors can't actually be generated, yet. 8443 */ 8444 assert(reason == ZPOOL_STATUS_OK); 8445 } 8446 8447 if (msgid != NULL) { 8448 printf(" "); 8449 printf_color(ANSI_BOLD, gettext("see:")); 8450 printf(gettext( 8451 " https://openzfs.github.io/openzfs-docs/msg/%s\n"), 8452 msgid); 8453 } 8454 8455 if (config != NULL) { 8456 uint64_t nerr; 8457 nvlist_t **spares, **l2cache; 8458 uint_t nspares, nl2cache; 8459 pool_checkpoint_stat_t *pcs = NULL; 8460 pool_removal_stat_t *prs = NULL; 8461 8462 print_scan_status(zhp, nvroot); 8463 8464 (void) nvlist_lookup_uint64_array(nvroot, 8465 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 8466 print_removal_status(zhp, prs); 8467 8468 (void) nvlist_lookup_uint64_array(nvroot, 8469 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 8470 print_checkpoint_status(pcs); 8471 8472 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 8473 cbp->cb_name_flags | VDEV_NAME_TYPE_ID); 8474 if (cbp->cb_namewidth < 10) 8475 cbp->cb_namewidth = 10; 8476 8477 color_start(ANSI_BOLD); 8478 (void) printf(gettext("config:\n\n")); 8479 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s"), 8480 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE", 8481 "CKSUM"); 8482 color_end(); 8483 8484 if (cbp->cb_print_slow_ios) { 8485 printf_color(ANSI_BOLD, " %5s", gettext("SLOW")); 8486 } 8487 8488 if (cbp->vcdl != NULL) 8489 print_cmd_columns(cbp->vcdl, 0); 8490 8491 printf("\n"); 8492 8493 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0, 8494 B_FALSE, NULL); 8495 8496 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP); 8497 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 8498 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS); 8499 8500 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 8501 &l2cache, &nl2cache) == 0) 8502 print_l2cache(zhp, cbp, l2cache, nl2cache); 8503 8504 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 8505 &spares, &nspares) == 0) 8506 print_spares(zhp, cbp, spares, nspares); 8507 8508 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 8509 &nerr) == 0) { 8510 nvlist_t *nverrlist = NULL; 8511 8512 /* 8513 * If the approximate error count is small, get a 8514 * precise count by fetching the entire log and 8515 * uniquifying the results. 8516 */ 8517 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 8518 zpool_get_errlog(zhp, &nverrlist) == 0) { 8519 nvpair_t *elem; 8520 8521 elem = NULL; 8522 nerr = 0; 8523 while ((elem = nvlist_next_nvpair(nverrlist, 8524 elem)) != NULL) { 8525 nerr++; 8526 } 8527 } 8528 nvlist_free(nverrlist); 8529 8530 (void) printf("\n"); 8531 8532 if (nerr == 0) 8533 (void) printf(gettext("errors: No known data " 8534 "errors\n")); 8535 else if (!cbp->cb_verbose) 8536 (void) printf(gettext("errors: %llu data " 8537 "errors, use '-v' for a list\n"), 8538 (u_longlong_t)nerr); 8539 else 8540 print_error_log(zhp); 8541 } 8542 8543 if (cbp->cb_dedup_stats) 8544 print_dedup_stats(config); 8545 } else { 8546 (void) printf(gettext("config: The configuration cannot be " 8547 "determined.\n")); 8548 } 8549 8550 return (0); 8551 } 8552 8553 /* 8554 * zpool status [-c [script1,script2,...]] [-igLpPstvx] [-T d|u] [pool] ... 8555 * [interval [count]] 8556 * 8557 * -c CMD For each vdev, run command CMD 8558 * -i Display vdev initialization status. 8559 * -g Display guid for individual vdev name. 8560 * -L Follow links when resolving vdev path name. 8561 * -p Display values in parsable (exact) format. 8562 * -P Display full path for vdev name. 8563 * -s Display slow IOs column. 8564 * -v Display complete error logs 8565 * -x Display only pools with potential problems 8566 * -D Display dedup status (undocumented) 8567 * -t Display vdev TRIM status. 8568 * -T Display a timestamp in date(1) or Unix format 8569 * 8570 * Describes the health status of all pools or some subset. 8571 */ 8572 int 8573 zpool_do_status(int argc, char **argv) 8574 { 8575 int c; 8576 int ret; 8577 float interval = 0; 8578 unsigned long count = 0; 8579 status_cbdata_t cb = { 0 }; 8580 char *cmd = NULL; 8581 8582 /* check options */ 8583 while ((c = getopt(argc, argv, "c:igLpPsvxDtT:")) != -1) { 8584 switch (c) { 8585 case 'c': 8586 if (cmd != NULL) { 8587 fprintf(stderr, 8588 gettext("Can't set -c flag twice\n")); 8589 exit(1); 8590 } 8591 8592 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL && 8593 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) { 8594 fprintf(stderr, gettext( 8595 "Can't run -c, disabled by " 8596 "ZPOOL_SCRIPTS_ENABLED.\n")); 8597 exit(1); 8598 } 8599 8600 if ((getuid() <= 0 || geteuid() <= 0) && 8601 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) { 8602 fprintf(stderr, gettext( 8603 "Can't run -c with root privileges " 8604 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n")); 8605 exit(1); 8606 } 8607 cmd = optarg; 8608 break; 8609 case 'i': 8610 cb.cb_print_vdev_init = B_TRUE; 8611 break; 8612 case 'g': 8613 cb.cb_name_flags |= VDEV_NAME_GUID; 8614 break; 8615 case 'L': 8616 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 8617 break; 8618 case 'p': 8619 cb.cb_literal = B_TRUE; 8620 break; 8621 case 'P': 8622 cb.cb_name_flags |= VDEV_NAME_PATH; 8623 break; 8624 case 's': 8625 cb.cb_print_slow_ios = B_TRUE; 8626 break; 8627 case 'v': 8628 cb.cb_verbose = B_TRUE; 8629 break; 8630 case 'x': 8631 cb.cb_explain = B_TRUE; 8632 break; 8633 case 'D': 8634 cb.cb_dedup_stats = B_TRUE; 8635 break; 8636 case 't': 8637 cb.cb_print_vdev_trim = B_TRUE; 8638 break; 8639 case 'T': 8640 get_timestamp_arg(*optarg); 8641 break; 8642 case '?': 8643 if (optopt == 'c') { 8644 print_zpool_script_list("status"); 8645 exit(0); 8646 } else { 8647 fprintf(stderr, 8648 gettext("invalid option '%c'\n"), optopt); 8649 } 8650 usage(B_FALSE); 8651 } 8652 } 8653 8654 argc -= optind; 8655 argv += optind; 8656 8657 get_interval_count(&argc, argv, &interval, &count); 8658 8659 if (argc == 0) 8660 cb.cb_allpools = B_TRUE; 8661 8662 cb.cb_first = B_TRUE; 8663 cb.cb_print_status = B_TRUE; 8664 8665 for (;;) { 8666 if (timestamp_fmt != NODATE) 8667 print_timestamp(timestamp_fmt); 8668 8669 if (cmd != NULL) 8670 cb.vcdl = all_pools_for_each_vdev_run(argc, argv, cmd, 8671 NULL, NULL, 0, 0); 8672 8673 ret = for_each_pool(argc, argv, B_TRUE, NULL, cb.cb_literal, 8674 status_callback, &cb); 8675 8676 if (cb.vcdl != NULL) 8677 free_vdev_cmd_data_list(cb.vcdl); 8678 8679 if (argc == 0 && cb.cb_count == 0) 8680 (void) fprintf(stderr, gettext("no pools available\n")); 8681 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 8682 (void) printf(gettext("all pools are healthy\n")); 8683 8684 if (ret != 0) 8685 return (ret); 8686 8687 if (interval == 0) 8688 break; 8689 8690 if (count != 0 && --count == 0) 8691 break; 8692 8693 (void) fsleep(interval); 8694 } 8695 8696 return (0); 8697 } 8698 8699 typedef struct upgrade_cbdata { 8700 int cb_first; 8701 int cb_argc; 8702 uint64_t cb_version; 8703 char **cb_argv; 8704 } upgrade_cbdata_t; 8705 8706 static int 8707 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs) 8708 { 8709 int zfs_version = (int)zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 8710 int *count = (int *)unsupp_fs; 8711 8712 if (zfs_version > ZPL_VERSION) { 8713 (void) printf(gettext("%s (v%d) is not supported by this " 8714 "implementation of ZFS.\n"), 8715 zfs_get_name(zhp), zfs_version); 8716 (*count)++; 8717 } 8718 8719 zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs); 8720 8721 zfs_close(zhp); 8722 8723 return (0); 8724 } 8725 8726 static int 8727 upgrade_version(zpool_handle_t *zhp, uint64_t version) 8728 { 8729 int ret; 8730 nvlist_t *config; 8731 uint64_t oldversion; 8732 int unsupp_fs = 0; 8733 8734 config = zpool_get_config(zhp, NULL); 8735 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8736 &oldversion) == 0); 8737 8738 char compat[ZFS_MAXPROPLEN]; 8739 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat, 8740 ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 8741 compat[0] = '\0'; 8742 8743 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 8744 assert(oldversion < version); 8745 8746 ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs); 8747 if (ret != 0) 8748 return (ret); 8749 8750 if (unsupp_fs) { 8751 (void) fprintf(stderr, gettext("Upgrade not performed due " 8752 "to %d unsupported filesystems (max v%d).\n"), 8753 unsupp_fs, (int)ZPL_VERSION); 8754 return (1); 8755 } 8756 8757 if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) { 8758 (void) fprintf(stderr, gettext("Upgrade not performed because " 8759 "'compatibility' property set to '" 8760 ZPOOL_COMPAT_LEGACY "'.\n")); 8761 return (1); 8762 } 8763 8764 ret = zpool_upgrade(zhp, version); 8765 if (ret != 0) 8766 return (ret); 8767 8768 if (version >= SPA_VERSION_FEATURES) { 8769 (void) printf(gettext("Successfully upgraded " 8770 "'%s' from version %llu to feature flags.\n"), 8771 zpool_get_name(zhp), (u_longlong_t)oldversion); 8772 } else { 8773 (void) printf(gettext("Successfully upgraded " 8774 "'%s' from version %llu to version %llu.\n"), 8775 zpool_get_name(zhp), (u_longlong_t)oldversion, 8776 (u_longlong_t)version); 8777 } 8778 8779 return (0); 8780 } 8781 8782 static int 8783 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 8784 { 8785 int i, ret, count; 8786 boolean_t firstff = B_TRUE; 8787 nvlist_t *enabled = zpool_get_features(zhp); 8788 8789 char compat[ZFS_MAXPROPLEN]; 8790 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat, 8791 ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 8792 compat[0] = '\0'; 8793 8794 boolean_t requested_features[SPA_FEATURES]; 8795 if (zpool_do_load_compat(compat, requested_features) != 8796 ZPOOL_COMPATIBILITY_OK) 8797 return (-1); 8798 8799 count = 0; 8800 for (i = 0; i < SPA_FEATURES; i++) { 8801 const char *fname = spa_feature_table[i].fi_uname; 8802 const char *fguid = spa_feature_table[i].fi_guid; 8803 8804 if (!spa_feature_table[i].fi_zfs_mod_supported) 8805 continue; 8806 8807 if (!nvlist_exists(enabled, fguid) && requested_features[i]) { 8808 char *propname; 8809 verify(-1 != asprintf(&propname, "feature@%s", fname)); 8810 ret = zpool_set_prop(zhp, propname, 8811 ZFS_FEATURE_ENABLED); 8812 if (ret != 0) { 8813 free(propname); 8814 return (ret); 8815 } 8816 count++; 8817 8818 if (firstff) { 8819 (void) printf(gettext("Enabled the " 8820 "following features on '%s':\n"), 8821 zpool_get_name(zhp)); 8822 firstff = B_FALSE; 8823 } 8824 (void) printf(gettext(" %s\n"), fname); 8825 free(propname); 8826 } 8827 } 8828 8829 if (countp != NULL) 8830 *countp = count; 8831 return (0); 8832 } 8833 8834 static int 8835 upgrade_cb(zpool_handle_t *zhp, void *arg) 8836 { 8837 upgrade_cbdata_t *cbp = arg; 8838 nvlist_t *config; 8839 uint64_t version; 8840 boolean_t modified_pool = B_FALSE; 8841 int ret; 8842 8843 config = zpool_get_config(zhp, NULL); 8844 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8845 &version) == 0); 8846 8847 assert(SPA_VERSION_IS_SUPPORTED(version)); 8848 8849 if (version < cbp->cb_version) { 8850 cbp->cb_first = B_FALSE; 8851 ret = upgrade_version(zhp, cbp->cb_version); 8852 if (ret != 0) 8853 return (ret); 8854 modified_pool = B_TRUE; 8855 8856 /* 8857 * If they did "zpool upgrade -a", then we could 8858 * be doing ioctls to different pools. We need 8859 * to log this history once to each pool, and bypass 8860 * the normal history logging that happens in main(). 8861 */ 8862 (void) zpool_log_history(g_zfs, history_str); 8863 log_history = B_FALSE; 8864 } 8865 8866 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 8867 int count; 8868 ret = upgrade_enable_all(zhp, &count); 8869 if (ret != 0) 8870 return (ret); 8871 8872 if (count > 0) { 8873 cbp->cb_first = B_FALSE; 8874 modified_pool = B_TRUE; 8875 } 8876 } 8877 8878 if (modified_pool) { 8879 (void) printf("\n"); 8880 (void) after_zpool_upgrade(zhp); 8881 } 8882 8883 return (0); 8884 } 8885 8886 static int 8887 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 8888 { 8889 upgrade_cbdata_t *cbp = arg; 8890 nvlist_t *config; 8891 uint64_t version; 8892 8893 config = zpool_get_config(zhp, NULL); 8894 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8895 &version) == 0); 8896 8897 assert(SPA_VERSION_IS_SUPPORTED(version)); 8898 8899 if (version < SPA_VERSION_FEATURES) { 8900 if (cbp->cb_first) { 8901 (void) printf(gettext("The following pools are " 8902 "formatted with legacy version numbers and can\n" 8903 "be upgraded to use feature flags. After " 8904 "being upgraded, these pools\nwill no " 8905 "longer be accessible by software that does not " 8906 "support feature\nflags.\n\n" 8907 "Note that setting a pool's 'compatibility' " 8908 "feature to '" ZPOOL_COMPAT_LEGACY "' will\n" 8909 "inhibit upgrades.\n\n")); 8910 (void) printf(gettext("VER POOL\n")); 8911 (void) printf(gettext("--- ------------\n")); 8912 cbp->cb_first = B_FALSE; 8913 } 8914 8915 (void) printf("%2llu %s\n", (u_longlong_t)version, 8916 zpool_get_name(zhp)); 8917 } 8918 8919 return (0); 8920 } 8921 8922 static int 8923 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 8924 { 8925 upgrade_cbdata_t *cbp = arg; 8926 nvlist_t *config; 8927 uint64_t version; 8928 8929 config = zpool_get_config(zhp, NULL); 8930 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8931 &version) == 0); 8932 8933 if (version >= SPA_VERSION_FEATURES) { 8934 int i; 8935 boolean_t poolfirst = B_TRUE; 8936 nvlist_t *enabled = zpool_get_features(zhp); 8937 8938 for (i = 0; i < SPA_FEATURES; i++) { 8939 const char *fguid = spa_feature_table[i].fi_guid; 8940 const char *fname = spa_feature_table[i].fi_uname; 8941 8942 if (!spa_feature_table[i].fi_zfs_mod_supported) 8943 continue; 8944 8945 if (!nvlist_exists(enabled, fguid)) { 8946 if (cbp->cb_first) { 8947 (void) printf(gettext("\nSome " 8948 "supported features are not " 8949 "enabled on the following pools. " 8950 "Once a\nfeature is enabled the " 8951 "pool may become incompatible with " 8952 "software\nthat does not support " 8953 "the feature. See " 8954 "zpool-features(7) for " 8955 "details.\n\n" 8956 "Note that the pool " 8957 "'compatibility' feature can be " 8958 "used to inhibit\nfeature " 8959 "upgrades.\n\n")); 8960 (void) printf(gettext("POOL " 8961 "FEATURE\n")); 8962 (void) printf(gettext("------" 8963 "---------\n")); 8964 cbp->cb_first = B_FALSE; 8965 } 8966 8967 if (poolfirst) { 8968 (void) printf(gettext("%s\n"), 8969 zpool_get_name(zhp)); 8970 poolfirst = B_FALSE; 8971 } 8972 8973 (void) printf(gettext(" %s\n"), fname); 8974 } 8975 /* 8976 * If they did "zpool upgrade -a", then we could 8977 * be doing ioctls to different pools. We need 8978 * to log this history once to each pool, and bypass 8979 * the normal history logging that happens in main(). 8980 */ 8981 (void) zpool_log_history(g_zfs, history_str); 8982 log_history = B_FALSE; 8983 } 8984 } 8985 8986 return (0); 8987 } 8988 8989 /* ARGSUSED */ 8990 static int 8991 upgrade_one(zpool_handle_t *zhp, void *data) 8992 { 8993 boolean_t modified_pool = B_FALSE; 8994 upgrade_cbdata_t *cbp = data; 8995 uint64_t cur_version; 8996 int ret; 8997 8998 if (strcmp("log", zpool_get_name(zhp)) == 0) { 8999 (void) fprintf(stderr, gettext("'log' is now a reserved word\n" 9000 "Pool 'log' must be renamed using export and import" 9001 " to upgrade.\n")); 9002 return (1); 9003 } 9004 9005 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 9006 if (cur_version > cbp->cb_version) { 9007 (void) printf(gettext("Pool '%s' is already formatted " 9008 "using more current version '%llu'.\n\n"), 9009 zpool_get_name(zhp), (u_longlong_t)cur_version); 9010 return (0); 9011 } 9012 9013 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 9014 (void) printf(gettext("Pool '%s' is already formatted " 9015 "using version %llu.\n\n"), zpool_get_name(zhp), 9016 (u_longlong_t)cbp->cb_version); 9017 return (0); 9018 } 9019 9020 if (cur_version != cbp->cb_version) { 9021 modified_pool = B_TRUE; 9022 ret = upgrade_version(zhp, cbp->cb_version); 9023 if (ret != 0) 9024 return (ret); 9025 } 9026 9027 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 9028 int count = 0; 9029 ret = upgrade_enable_all(zhp, &count); 9030 if (ret != 0) 9031 return (ret); 9032 9033 if (count != 0) { 9034 modified_pool = B_TRUE; 9035 } else if (cur_version == SPA_VERSION) { 9036 (void) printf(gettext("Pool '%s' already has all " 9037 "supported and requested features enabled.\n"), 9038 zpool_get_name(zhp)); 9039 } 9040 } 9041 9042 if (modified_pool) { 9043 (void) printf("\n"); 9044 (void) after_zpool_upgrade(zhp); 9045 } 9046 9047 return (0); 9048 } 9049 9050 /* 9051 * zpool upgrade 9052 * zpool upgrade -v 9053 * zpool upgrade [-V version] <-a | pool ...> 9054 * 9055 * With no arguments, display downrev'd ZFS pool available for upgrade. 9056 * Individual pools can be upgraded by specifying the pool, and '-a' will 9057 * upgrade all pools. 9058 */ 9059 int 9060 zpool_do_upgrade(int argc, char **argv) 9061 { 9062 int c; 9063 upgrade_cbdata_t cb = { 0 }; 9064 int ret = 0; 9065 boolean_t showversions = B_FALSE; 9066 boolean_t upgradeall = B_FALSE; 9067 char *end; 9068 9069 9070 /* check options */ 9071 while ((c = getopt(argc, argv, ":avV:")) != -1) { 9072 switch (c) { 9073 case 'a': 9074 upgradeall = B_TRUE; 9075 break; 9076 case 'v': 9077 showversions = B_TRUE; 9078 break; 9079 case 'V': 9080 cb.cb_version = strtoll(optarg, &end, 10); 9081 if (*end != '\0' || 9082 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 9083 (void) fprintf(stderr, 9084 gettext("invalid version '%s'\n"), optarg); 9085 usage(B_FALSE); 9086 } 9087 break; 9088 case ':': 9089 (void) fprintf(stderr, gettext("missing argument for " 9090 "'%c' option\n"), optopt); 9091 usage(B_FALSE); 9092 break; 9093 case '?': 9094 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9095 optopt); 9096 usage(B_FALSE); 9097 } 9098 } 9099 9100 cb.cb_argc = argc; 9101 cb.cb_argv = argv; 9102 argc -= optind; 9103 argv += optind; 9104 9105 if (cb.cb_version == 0) { 9106 cb.cb_version = SPA_VERSION; 9107 } else if (!upgradeall && argc == 0) { 9108 (void) fprintf(stderr, gettext("-V option is " 9109 "incompatible with other arguments\n")); 9110 usage(B_FALSE); 9111 } 9112 9113 if (showversions) { 9114 if (upgradeall || argc != 0) { 9115 (void) fprintf(stderr, gettext("-v option is " 9116 "incompatible with other arguments\n")); 9117 usage(B_FALSE); 9118 } 9119 } else if (upgradeall) { 9120 if (argc != 0) { 9121 (void) fprintf(stderr, gettext("-a option should not " 9122 "be used along with a pool name\n")); 9123 usage(B_FALSE); 9124 } 9125 } 9126 9127 (void) printf(gettext("This system supports ZFS pool feature " 9128 "flags.\n\n")); 9129 if (showversions) { 9130 int i; 9131 9132 (void) printf(gettext("The following features are " 9133 "supported:\n\n")); 9134 (void) printf(gettext("FEAT DESCRIPTION\n")); 9135 (void) printf("----------------------------------------------" 9136 "---------------\n"); 9137 for (i = 0; i < SPA_FEATURES; i++) { 9138 zfeature_info_t *fi = &spa_feature_table[i]; 9139 if (!fi->fi_zfs_mod_supported) 9140 continue; 9141 const char *ro = 9142 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 9143 " (read-only compatible)" : ""; 9144 9145 (void) printf("%-37s%s\n", fi->fi_uname, ro); 9146 (void) printf(" %s\n", fi->fi_desc); 9147 } 9148 (void) printf("\n"); 9149 9150 (void) printf(gettext("The following legacy versions are also " 9151 "supported:\n\n")); 9152 (void) printf(gettext("VER DESCRIPTION\n")); 9153 (void) printf("--- -----------------------------------------" 9154 "---------------\n"); 9155 (void) printf(gettext(" 1 Initial ZFS version\n")); 9156 (void) printf(gettext(" 2 Ditto blocks " 9157 "(replicated metadata)\n")); 9158 (void) printf(gettext(" 3 Hot spares and double parity " 9159 "RAID-Z\n")); 9160 (void) printf(gettext(" 4 zpool history\n")); 9161 (void) printf(gettext(" 5 Compression using the gzip " 9162 "algorithm\n")); 9163 (void) printf(gettext(" 6 bootfs pool property\n")); 9164 (void) printf(gettext(" 7 Separate intent log devices\n")); 9165 (void) printf(gettext(" 8 Delegated administration\n")); 9166 (void) printf(gettext(" 9 refquota and refreservation " 9167 "properties\n")); 9168 (void) printf(gettext(" 10 Cache devices\n")); 9169 (void) printf(gettext(" 11 Improved scrub performance\n")); 9170 (void) printf(gettext(" 12 Snapshot properties\n")); 9171 (void) printf(gettext(" 13 snapused property\n")); 9172 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 9173 (void) printf(gettext(" 15 user/group space accounting\n")); 9174 (void) printf(gettext(" 16 stmf property support\n")); 9175 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 9176 (void) printf(gettext(" 18 Snapshot user holds\n")); 9177 (void) printf(gettext(" 19 Log device removal\n")); 9178 (void) printf(gettext(" 20 Compression using zle " 9179 "(zero-length encoding)\n")); 9180 (void) printf(gettext(" 21 Deduplication\n")); 9181 (void) printf(gettext(" 22 Received properties\n")); 9182 (void) printf(gettext(" 23 Slim ZIL\n")); 9183 (void) printf(gettext(" 24 System attributes\n")); 9184 (void) printf(gettext(" 25 Improved scrub stats\n")); 9185 (void) printf(gettext(" 26 Improved snapshot deletion " 9186 "performance\n")); 9187 (void) printf(gettext(" 27 Improved snapshot creation " 9188 "performance\n")); 9189 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 9190 (void) printf(gettext("\nFor more information on a particular " 9191 "version, including supported releases,\n")); 9192 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 9193 } else if (argc == 0 && upgradeall) { 9194 cb.cb_first = B_TRUE; 9195 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 9196 if (ret == 0 && cb.cb_first) { 9197 if (cb.cb_version == SPA_VERSION) { 9198 (void) printf(gettext("All pools are already " 9199 "formatted using feature flags.\n\n")); 9200 (void) printf(gettext("Every feature flags " 9201 "pool already has all supported and " 9202 "requested features enabled.\n")); 9203 } else { 9204 (void) printf(gettext("All pools are already " 9205 "formatted with version %llu or higher.\n"), 9206 (u_longlong_t)cb.cb_version); 9207 } 9208 } 9209 } else if (argc == 0) { 9210 cb.cb_first = B_TRUE; 9211 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 9212 assert(ret == 0); 9213 9214 if (cb.cb_first) { 9215 (void) printf(gettext("All pools are formatted " 9216 "using feature flags.\n\n")); 9217 } else { 9218 (void) printf(gettext("\nUse 'zpool upgrade -v' " 9219 "for a list of available legacy versions.\n")); 9220 } 9221 9222 cb.cb_first = B_TRUE; 9223 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 9224 assert(ret == 0); 9225 9226 if (cb.cb_first) { 9227 (void) printf(gettext("Every feature flags pool has " 9228 "all supported and requested features enabled.\n")); 9229 } else { 9230 (void) printf(gettext("\n")); 9231 } 9232 } else { 9233 ret = for_each_pool(argc, argv, B_FALSE, NULL, B_FALSE, 9234 upgrade_one, &cb); 9235 } 9236 9237 return (ret); 9238 } 9239 9240 typedef struct hist_cbdata { 9241 boolean_t first; 9242 boolean_t longfmt; 9243 boolean_t internal; 9244 } hist_cbdata_t; 9245 9246 static void 9247 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb) 9248 { 9249 nvlist_t **records; 9250 uint_t numrecords; 9251 int i; 9252 9253 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 9254 &records, &numrecords) == 0); 9255 for (i = 0; i < numrecords; i++) { 9256 nvlist_t *rec = records[i]; 9257 char tbuf[64] = ""; 9258 9259 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 9260 time_t tsec; 9261 struct tm t; 9262 9263 tsec = fnvlist_lookup_uint64(records[i], 9264 ZPOOL_HIST_TIME); 9265 (void) localtime_r(&tsec, &t); 9266 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 9267 } 9268 9269 if (nvlist_exists(rec, ZPOOL_HIST_ELAPSED_NS)) { 9270 uint64_t elapsed_ns = fnvlist_lookup_int64(records[i], 9271 ZPOOL_HIST_ELAPSED_NS); 9272 (void) snprintf(tbuf + strlen(tbuf), 9273 sizeof (tbuf) - strlen(tbuf), 9274 " (%lldms)", (long long)elapsed_ns / 1000 / 1000); 9275 } 9276 9277 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 9278 (void) printf("%s %s", tbuf, 9279 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 9280 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 9281 int ievent = 9282 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 9283 if (!cb->internal) 9284 continue; 9285 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 9286 (void) printf("%s unrecognized record:\n", 9287 tbuf); 9288 dump_nvlist(rec, 4); 9289 continue; 9290 } 9291 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 9292 zfs_history_event_names[ievent], 9293 (longlong_t)fnvlist_lookup_uint64( 9294 rec, ZPOOL_HIST_TXG), 9295 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 9296 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 9297 if (!cb->internal) 9298 continue; 9299 (void) printf("%s [txg:%lld] %s", tbuf, 9300 (longlong_t)fnvlist_lookup_uint64( 9301 rec, ZPOOL_HIST_TXG), 9302 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 9303 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 9304 (void) printf(" %s (%llu)", 9305 fnvlist_lookup_string(rec, 9306 ZPOOL_HIST_DSNAME), 9307 (u_longlong_t)fnvlist_lookup_uint64(rec, 9308 ZPOOL_HIST_DSID)); 9309 } 9310 (void) printf(" %s", fnvlist_lookup_string(rec, 9311 ZPOOL_HIST_INT_STR)); 9312 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 9313 if (!cb->internal) 9314 continue; 9315 (void) printf("%s ioctl %s\n", tbuf, 9316 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 9317 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 9318 (void) printf(" input:\n"); 9319 dump_nvlist(fnvlist_lookup_nvlist(rec, 9320 ZPOOL_HIST_INPUT_NVL), 8); 9321 } 9322 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 9323 (void) printf(" output:\n"); 9324 dump_nvlist(fnvlist_lookup_nvlist(rec, 9325 ZPOOL_HIST_OUTPUT_NVL), 8); 9326 } 9327 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_SIZE)) { 9328 (void) printf(" output nvlist omitted; " 9329 "original size: %lldKB\n", 9330 (longlong_t)fnvlist_lookup_int64(rec, 9331 ZPOOL_HIST_OUTPUT_SIZE) / 1024); 9332 } 9333 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 9334 (void) printf(" errno: %lld\n", 9335 (longlong_t)fnvlist_lookup_int64(rec, 9336 ZPOOL_HIST_ERRNO)); 9337 } 9338 } else { 9339 if (!cb->internal) 9340 continue; 9341 (void) printf("%s unrecognized record:\n", tbuf); 9342 dump_nvlist(rec, 4); 9343 } 9344 9345 if (!cb->longfmt) { 9346 (void) printf("\n"); 9347 continue; 9348 } 9349 (void) printf(" ["); 9350 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 9351 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 9352 struct passwd *pwd = getpwuid(who); 9353 (void) printf("user %d ", (int)who); 9354 if (pwd != NULL) 9355 (void) printf("(%s) ", pwd->pw_name); 9356 } 9357 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 9358 (void) printf("on %s", 9359 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 9360 } 9361 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 9362 (void) printf(":%s", 9363 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 9364 } 9365 9366 (void) printf("]"); 9367 (void) printf("\n"); 9368 } 9369 } 9370 9371 /* 9372 * Print out the command history for a specific pool. 9373 */ 9374 static int 9375 get_history_one(zpool_handle_t *zhp, void *data) 9376 { 9377 nvlist_t *nvhis; 9378 int ret; 9379 hist_cbdata_t *cb = (hist_cbdata_t *)data; 9380 uint64_t off = 0; 9381 boolean_t eof = B_FALSE; 9382 9383 cb->first = B_FALSE; 9384 9385 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 9386 9387 while (!eof) { 9388 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0) 9389 return (ret); 9390 9391 print_history_records(nvhis, cb); 9392 nvlist_free(nvhis); 9393 } 9394 (void) printf("\n"); 9395 9396 return (ret); 9397 } 9398 9399 /* 9400 * zpool history <pool> 9401 * 9402 * Displays the history of commands that modified pools. 9403 */ 9404 int 9405 zpool_do_history(int argc, char **argv) 9406 { 9407 hist_cbdata_t cbdata = { 0 }; 9408 int ret; 9409 int c; 9410 9411 cbdata.first = B_TRUE; 9412 /* check options */ 9413 while ((c = getopt(argc, argv, "li")) != -1) { 9414 switch (c) { 9415 case 'l': 9416 cbdata.longfmt = B_TRUE; 9417 break; 9418 case 'i': 9419 cbdata.internal = B_TRUE; 9420 break; 9421 case '?': 9422 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9423 optopt); 9424 usage(B_FALSE); 9425 } 9426 } 9427 argc -= optind; 9428 argv += optind; 9429 9430 ret = for_each_pool(argc, argv, B_FALSE, NULL, B_FALSE, get_history_one, 9431 &cbdata); 9432 9433 if (argc == 0 && cbdata.first == B_TRUE) { 9434 (void) fprintf(stderr, gettext("no pools available\n")); 9435 return (0); 9436 } 9437 9438 return (ret); 9439 } 9440 9441 typedef struct ev_opts { 9442 int verbose; 9443 int scripted; 9444 int follow; 9445 int clear; 9446 char poolname[ZFS_MAX_DATASET_NAME_LEN]; 9447 } ev_opts_t; 9448 9449 static void 9450 zpool_do_events_short(nvlist_t *nvl, ev_opts_t *opts) 9451 { 9452 char ctime_str[26], str[32], *ptr; 9453 int64_t *tv; 9454 uint_t n; 9455 9456 verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0); 9457 memset(str, ' ', 32); 9458 (void) ctime_r((const time_t *)&tv[0], ctime_str); 9459 (void) memcpy(str, ctime_str+4, 6); /* 'Jun 30' */ 9460 (void) memcpy(str+7, ctime_str+20, 4); /* '1993' */ 9461 (void) memcpy(str+12, ctime_str+11, 8); /* '21:49:08' */ 9462 (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */ 9463 if (opts->scripted) 9464 (void) printf(gettext("%s\t"), str); 9465 else 9466 (void) printf(gettext("%s "), str); 9467 9468 verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0); 9469 (void) printf(gettext("%s\n"), ptr); 9470 } 9471 9472 static void 9473 zpool_do_events_nvprint(nvlist_t *nvl, int depth) 9474 { 9475 nvpair_t *nvp; 9476 9477 for (nvp = nvlist_next_nvpair(nvl, NULL); 9478 nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) { 9479 9480 data_type_t type = nvpair_type(nvp); 9481 const char *name = nvpair_name(nvp); 9482 9483 boolean_t b; 9484 uint8_t i8; 9485 uint16_t i16; 9486 uint32_t i32; 9487 uint64_t i64; 9488 char *str; 9489 nvlist_t *cnv; 9490 9491 printf(gettext("%*s%s = "), depth, "", name); 9492 9493 switch (type) { 9494 case DATA_TYPE_BOOLEAN: 9495 printf(gettext("%s"), "1"); 9496 break; 9497 9498 case DATA_TYPE_BOOLEAN_VALUE: 9499 (void) nvpair_value_boolean_value(nvp, &b); 9500 printf(gettext("%s"), b ? "1" : "0"); 9501 break; 9502 9503 case DATA_TYPE_BYTE: 9504 (void) nvpair_value_byte(nvp, &i8); 9505 printf(gettext("0x%x"), i8); 9506 break; 9507 9508 case DATA_TYPE_INT8: 9509 (void) nvpair_value_int8(nvp, (void *)&i8); 9510 printf(gettext("0x%x"), i8); 9511 break; 9512 9513 case DATA_TYPE_UINT8: 9514 (void) nvpair_value_uint8(nvp, &i8); 9515 printf(gettext("0x%x"), i8); 9516 break; 9517 9518 case DATA_TYPE_INT16: 9519 (void) nvpair_value_int16(nvp, (void *)&i16); 9520 printf(gettext("0x%x"), i16); 9521 break; 9522 9523 case DATA_TYPE_UINT16: 9524 (void) nvpair_value_uint16(nvp, &i16); 9525 printf(gettext("0x%x"), i16); 9526 break; 9527 9528 case DATA_TYPE_INT32: 9529 (void) nvpair_value_int32(nvp, (void *)&i32); 9530 printf(gettext("0x%x"), i32); 9531 break; 9532 9533 case DATA_TYPE_UINT32: 9534 (void) nvpair_value_uint32(nvp, &i32); 9535 printf(gettext("0x%x"), i32); 9536 break; 9537 9538 case DATA_TYPE_INT64: 9539 (void) nvpair_value_int64(nvp, (void *)&i64); 9540 printf(gettext("0x%llx"), (u_longlong_t)i64); 9541 break; 9542 9543 case DATA_TYPE_UINT64: 9544 (void) nvpair_value_uint64(nvp, &i64); 9545 /* 9546 * translate vdev state values to readable 9547 * strings to aide zpool events consumers 9548 */ 9549 if (strcmp(name, 9550 FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 || 9551 strcmp(name, 9552 FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) { 9553 printf(gettext("\"%s\" (0x%llx)"), 9554 zpool_state_to_name(i64, VDEV_AUX_NONE), 9555 (u_longlong_t)i64); 9556 } else { 9557 printf(gettext("0x%llx"), (u_longlong_t)i64); 9558 } 9559 break; 9560 9561 case DATA_TYPE_HRTIME: 9562 (void) nvpair_value_hrtime(nvp, (void *)&i64); 9563 printf(gettext("0x%llx"), (u_longlong_t)i64); 9564 break; 9565 9566 case DATA_TYPE_STRING: 9567 (void) nvpair_value_string(nvp, &str); 9568 printf(gettext("\"%s\""), str ? str : "<NULL>"); 9569 break; 9570 9571 case DATA_TYPE_NVLIST: 9572 printf(gettext("(embedded nvlist)\n")); 9573 (void) nvpair_value_nvlist(nvp, &cnv); 9574 zpool_do_events_nvprint(cnv, depth + 8); 9575 printf(gettext("%*s(end %s)"), depth, "", name); 9576 break; 9577 9578 case DATA_TYPE_NVLIST_ARRAY: { 9579 nvlist_t **val; 9580 uint_t i, nelem; 9581 9582 (void) nvpair_value_nvlist_array(nvp, &val, &nelem); 9583 printf(gettext("(%d embedded nvlists)\n"), nelem); 9584 for (i = 0; i < nelem; i++) { 9585 printf(gettext("%*s%s[%d] = %s\n"), 9586 depth, "", name, i, "(embedded nvlist)"); 9587 zpool_do_events_nvprint(val[i], depth + 8); 9588 printf(gettext("%*s(end %s[%i])\n"), 9589 depth, "", name, i); 9590 } 9591 printf(gettext("%*s(end %s)\n"), depth, "", name); 9592 } 9593 break; 9594 9595 case DATA_TYPE_INT8_ARRAY: { 9596 int8_t *val; 9597 uint_t i, nelem; 9598 9599 (void) nvpair_value_int8_array(nvp, &val, &nelem); 9600 for (i = 0; i < nelem; i++) 9601 printf(gettext("0x%x "), val[i]); 9602 9603 break; 9604 } 9605 9606 case DATA_TYPE_UINT8_ARRAY: { 9607 uint8_t *val; 9608 uint_t i, nelem; 9609 9610 (void) nvpair_value_uint8_array(nvp, &val, &nelem); 9611 for (i = 0; i < nelem; i++) 9612 printf(gettext("0x%x "), val[i]); 9613 9614 break; 9615 } 9616 9617 case DATA_TYPE_INT16_ARRAY: { 9618 int16_t *val; 9619 uint_t i, nelem; 9620 9621 (void) nvpair_value_int16_array(nvp, &val, &nelem); 9622 for (i = 0; i < nelem; i++) 9623 printf(gettext("0x%x "), val[i]); 9624 9625 break; 9626 } 9627 9628 case DATA_TYPE_UINT16_ARRAY: { 9629 uint16_t *val; 9630 uint_t i, nelem; 9631 9632 (void) nvpair_value_uint16_array(nvp, &val, &nelem); 9633 for (i = 0; i < nelem; i++) 9634 printf(gettext("0x%x "), val[i]); 9635 9636 break; 9637 } 9638 9639 case DATA_TYPE_INT32_ARRAY: { 9640 int32_t *val; 9641 uint_t i, nelem; 9642 9643 (void) nvpair_value_int32_array(nvp, &val, &nelem); 9644 for (i = 0; i < nelem; i++) 9645 printf(gettext("0x%x "), val[i]); 9646 9647 break; 9648 } 9649 9650 case DATA_TYPE_UINT32_ARRAY: { 9651 uint32_t *val; 9652 uint_t i, nelem; 9653 9654 (void) nvpair_value_uint32_array(nvp, &val, &nelem); 9655 for (i = 0; i < nelem; i++) 9656 printf(gettext("0x%x "), val[i]); 9657 9658 break; 9659 } 9660 9661 case DATA_TYPE_INT64_ARRAY: { 9662 int64_t *val; 9663 uint_t i, nelem; 9664 9665 (void) nvpair_value_int64_array(nvp, &val, &nelem); 9666 for (i = 0; i < nelem; i++) 9667 printf(gettext("0x%llx "), 9668 (u_longlong_t)val[i]); 9669 9670 break; 9671 } 9672 9673 case DATA_TYPE_UINT64_ARRAY: { 9674 uint64_t *val; 9675 uint_t i, nelem; 9676 9677 (void) nvpair_value_uint64_array(nvp, &val, &nelem); 9678 for (i = 0; i < nelem; i++) 9679 printf(gettext("0x%llx "), 9680 (u_longlong_t)val[i]); 9681 9682 break; 9683 } 9684 9685 case DATA_TYPE_STRING_ARRAY: { 9686 char **str; 9687 uint_t i, nelem; 9688 9689 (void) nvpair_value_string_array(nvp, &str, &nelem); 9690 for (i = 0; i < nelem; i++) 9691 printf(gettext("\"%s\" "), 9692 str[i] ? str[i] : "<NULL>"); 9693 9694 break; 9695 } 9696 9697 case DATA_TYPE_BOOLEAN_ARRAY: 9698 case DATA_TYPE_BYTE_ARRAY: 9699 case DATA_TYPE_DOUBLE: 9700 case DATA_TYPE_DONTCARE: 9701 case DATA_TYPE_UNKNOWN: 9702 printf(gettext("<unknown>")); 9703 break; 9704 } 9705 9706 printf(gettext("\n")); 9707 } 9708 } 9709 9710 static int 9711 zpool_do_events_next(ev_opts_t *opts) 9712 { 9713 nvlist_t *nvl; 9714 int zevent_fd, ret, dropped; 9715 char *pool; 9716 9717 zevent_fd = open(ZFS_DEV, O_RDWR); 9718 VERIFY(zevent_fd >= 0); 9719 9720 if (!opts->scripted) 9721 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS"); 9722 9723 while (1) { 9724 ret = zpool_events_next(g_zfs, &nvl, &dropped, 9725 (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd); 9726 if (ret || nvl == NULL) 9727 break; 9728 9729 if (dropped > 0) 9730 (void) printf(gettext("dropped %d events\n"), dropped); 9731 9732 if (strlen(opts->poolname) > 0 && 9733 nvlist_lookup_string(nvl, FM_FMRI_ZFS_POOL, &pool) == 0 && 9734 strcmp(opts->poolname, pool) != 0) 9735 continue; 9736 9737 zpool_do_events_short(nvl, opts); 9738 9739 if (opts->verbose) { 9740 zpool_do_events_nvprint(nvl, 8); 9741 printf(gettext("\n")); 9742 } 9743 (void) fflush(stdout); 9744 9745 nvlist_free(nvl); 9746 } 9747 9748 VERIFY(0 == close(zevent_fd)); 9749 9750 return (ret); 9751 } 9752 9753 static int 9754 zpool_do_events_clear(ev_opts_t *opts) 9755 { 9756 int count, ret; 9757 9758 ret = zpool_events_clear(g_zfs, &count); 9759 if (!ret) 9760 (void) printf(gettext("cleared %d events\n"), count); 9761 9762 return (ret); 9763 } 9764 9765 /* 9766 * zpool events [-vHf [pool] | -c] 9767 * 9768 * Displays events logs by ZFS. 9769 */ 9770 int 9771 zpool_do_events(int argc, char **argv) 9772 { 9773 ev_opts_t opts = { 0 }; 9774 int ret; 9775 int c; 9776 9777 /* check options */ 9778 while ((c = getopt(argc, argv, "vHfc")) != -1) { 9779 switch (c) { 9780 case 'v': 9781 opts.verbose = 1; 9782 break; 9783 case 'H': 9784 opts.scripted = 1; 9785 break; 9786 case 'f': 9787 opts.follow = 1; 9788 break; 9789 case 'c': 9790 opts.clear = 1; 9791 break; 9792 case '?': 9793 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9794 optopt); 9795 usage(B_FALSE); 9796 } 9797 } 9798 argc -= optind; 9799 argv += optind; 9800 9801 if (argc > 1) { 9802 (void) fprintf(stderr, gettext("too many arguments\n")); 9803 usage(B_FALSE); 9804 } else if (argc == 1) { 9805 (void) strlcpy(opts.poolname, argv[0], sizeof (opts.poolname)); 9806 if (!zfs_name_valid(opts.poolname, ZFS_TYPE_POOL)) { 9807 (void) fprintf(stderr, 9808 gettext("invalid pool name '%s'\n"), opts.poolname); 9809 usage(B_FALSE); 9810 } 9811 } 9812 9813 if ((argc == 1 || opts.verbose || opts.scripted || opts.follow) && 9814 opts.clear) { 9815 (void) fprintf(stderr, 9816 gettext("invalid options combined with -c\n")); 9817 usage(B_FALSE); 9818 } 9819 9820 if (opts.clear) 9821 ret = zpool_do_events_clear(&opts); 9822 else 9823 ret = zpool_do_events_next(&opts); 9824 9825 return (ret); 9826 } 9827 9828 static int 9829 get_callback(zpool_handle_t *zhp, void *data) 9830 { 9831 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 9832 char value[MAXNAMELEN]; 9833 zprop_source_t srctype; 9834 zprop_list_t *pl; 9835 9836 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 9837 9838 /* 9839 * Skip the special fake placeholder. This will also skip 9840 * over the name property when 'all' is specified. 9841 */ 9842 if (pl->pl_prop == ZPOOL_PROP_NAME && 9843 pl == cbp->cb_proplist) 9844 continue; 9845 9846 if (pl->pl_prop == ZPROP_INVAL && 9847 (zpool_prop_feature(pl->pl_user_prop) || 9848 zpool_prop_unsupported(pl->pl_user_prop))) { 9849 srctype = ZPROP_SRC_LOCAL; 9850 9851 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 9852 value, sizeof (value)) == 0) { 9853 zprop_print_one_property(zpool_get_name(zhp), 9854 cbp, pl->pl_user_prop, value, srctype, 9855 NULL, NULL); 9856 } 9857 } else { 9858 if (zpool_get_prop(zhp, pl->pl_prop, value, 9859 sizeof (value), &srctype, cbp->cb_literal) != 0) 9860 continue; 9861 9862 zprop_print_one_property(zpool_get_name(zhp), cbp, 9863 zpool_prop_to_name(pl->pl_prop), value, srctype, 9864 NULL, NULL); 9865 } 9866 } 9867 return (0); 9868 } 9869 9870 /* 9871 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 9872 * 9873 * -H Scripted mode. Don't display headers, and separate properties 9874 * by a single tab. 9875 * -o List of columns to display. Defaults to 9876 * "name,property,value,source". 9877 * -p Display values in parsable (exact) format. 9878 * 9879 * Get properties of pools in the system. Output space statistics 9880 * for each one as well as other attributes. 9881 */ 9882 int 9883 zpool_do_get(int argc, char **argv) 9884 { 9885 zprop_get_cbdata_t cb = { 0 }; 9886 zprop_list_t fake_name = { 0 }; 9887 int ret; 9888 int c, i; 9889 char *value; 9890 9891 cb.cb_first = B_TRUE; 9892 9893 /* 9894 * Set up default columns and sources. 9895 */ 9896 cb.cb_sources = ZPROP_SRC_ALL; 9897 cb.cb_columns[0] = GET_COL_NAME; 9898 cb.cb_columns[1] = GET_COL_PROPERTY; 9899 cb.cb_columns[2] = GET_COL_VALUE; 9900 cb.cb_columns[3] = GET_COL_SOURCE; 9901 cb.cb_type = ZFS_TYPE_POOL; 9902 9903 /* check options */ 9904 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 9905 switch (c) { 9906 case 'p': 9907 cb.cb_literal = B_TRUE; 9908 break; 9909 case 'H': 9910 cb.cb_scripted = B_TRUE; 9911 break; 9912 case 'o': 9913 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 9914 i = 0; 9915 while (*optarg != '\0') { 9916 static char *col_subopts[] = 9917 { "name", "property", "value", "source", 9918 "all", NULL }; 9919 9920 if (i == ZFS_GET_NCOLS) { 9921 (void) fprintf(stderr, gettext("too " 9922 "many fields given to -o " 9923 "option\n")); 9924 usage(B_FALSE); 9925 } 9926 9927 switch (getsubopt(&optarg, col_subopts, 9928 &value)) { 9929 case 0: 9930 cb.cb_columns[i++] = GET_COL_NAME; 9931 break; 9932 case 1: 9933 cb.cb_columns[i++] = GET_COL_PROPERTY; 9934 break; 9935 case 2: 9936 cb.cb_columns[i++] = GET_COL_VALUE; 9937 break; 9938 case 3: 9939 cb.cb_columns[i++] = GET_COL_SOURCE; 9940 break; 9941 case 4: 9942 if (i > 0) { 9943 (void) fprintf(stderr, 9944 gettext("\"all\" conflicts " 9945 "with specific fields " 9946 "given to -o option\n")); 9947 usage(B_FALSE); 9948 } 9949 cb.cb_columns[0] = GET_COL_NAME; 9950 cb.cb_columns[1] = GET_COL_PROPERTY; 9951 cb.cb_columns[2] = GET_COL_VALUE; 9952 cb.cb_columns[3] = GET_COL_SOURCE; 9953 i = ZFS_GET_NCOLS; 9954 break; 9955 default: 9956 (void) fprintf(stderr, 9957 gettext("invalid column name " 9958 "'%s'\n"), value); 9959 usage(B_FALSE); 9960 } 9961 } 9962 break; 9963 case '?': 9964 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9965 optopt); 9966 usage(B_FALSE); 9967 } 9968 } 9969 9970 argc -= optind; 9971 argv += optind; 9972 9973 if (argc < 1) { 9974 (void) fprintf(stderr, gettext("missing property " 9975 "argument\n")); 9976 usage(B_FALSE); 9977 } 9978 9979 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 9980 ZFS_TYPE_POOL) != 0) 9981 usage(B_FALSE); 9982 9983 argc--; 9984 argv++; 9985 9986 if (cb.cb_proplist != NULL) { 9987 fake_name.pl_prop = ZPOOL_PROP_NAME; 9988 fake_name.pl_width = strlen(gettext("NAME")); 9989 fake_name.pl_next = cb.cb_proplist; 9990 cb.cb_proplist = &fake_name; 9991 } 9992 9993 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, cb.cb_literal, 9994 get_callback, &cb); 9995 9996 if (cb.cb_proplist == &fake_name) 9997 zprop_free_list(fake_name.pl_next); 9998 else 9999 zprop_free_list(cb.cb_proplist); 10000 10001 return (ret); 10002 } 10003 10004 typedef struct set_cbdata { 10005 char *cb_propname; 10006 char *cb_value; 10007 boolean_t cb_any_successful; 10008 } set_cbdata_t; 10009 10010 static int 10011 set_callback(zpool_handle_t *zhp, void *data) 10012 { 10013 int error; 10014 set_cbdata_t *cb = (set_cbdata_t *)data; 10015 10016 /* Check if we have out-of-bounds features */ 10017 if (strcmp(cb->cb_propname, ZPOOL_CONFIG_COMPATIBILITY) == 0) { 10018 boolean_t features[SPA_FEATURES]; 10019 if (zpool_do_load_compat(cb->cb_value, features) != 10020 ZPOOL_COMPATIBILITY_OK) 10021 return (-1); 10022 10023 nvlist_t *enabled = zpool_get_features(zhp); 10024 spa_feature_t i; 10025 for (i = 0; i < SPA_FEATURES; i++) { 10026 const char *fguid = spa_feature_table[i].fi_guid; 10027 if (nvlist_exists(enabled, fguid) && !features[i]) 10028 break; 10029 } 10030 if (i < SPA_FEATURES) 10031 (void) fprintf(stderr, gettext("Warning: one or " 10032 "more features already enabled on pool '%s'\n" 10033 "are not present in this compatibility set.\n"), 10034 zpool_get_name(zhp)); 10035 } 10036 10037 /* if we're setting a feature, check it's in compatibility set */ 10038 if (zpool_prop_feature(cb->cb_propname) && 10039 strcmp(cb->cb_value, ZFS_FEATURE_ENABLED) == 0) { 10040 char *fname = strchr(cb->cb_propname, '@') + 1; 10041 spa_feature_t f; 10042 10043 if (zfeature_lookup_name(fname, &f) == 0) { 10044 char compat[ZFS_MAXPROPLEN]; 10045 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, 10046 compat, ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 10047 compat[0] = '\0'; 10048 10049 boolean_t features[SPA_FEATURES]; 10050 if (zpool_do_load_compat(compat, features) != 10051 ZPOOL_COMPATIBILITY_OK) { 10052 (void) fprintf(stderr, gettext("Error: " 10053 "cannot enable feature '%s' on pool '%s'\n" 10054 "because the pool's 'compatibility' " 10055 "property cannot be parsed.\n"), 10056 fname, zpool_get_name(zhp)); 10057 return (-1); 10058 } 10059 10060 if (!features[f]) { 10061 (void) fprintf(stderr, gettext("Error: " 10062 "cannot enable feature '%s' on pool '%s'\n" 10063 "as it is not specified in this pool's " 10064 "current compatibility set.\n" 10065 "Consider setting 'compatibility' to a " 10066 "less restrictive set, or to 'off'.\n"), 10067 fname, zpool_get_name(zhp)); 10068 return (-1); 10069 } 10070 } 10071 } 10072 10073 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 10074 10075 if (!error) 10076 cb->cb_any_successful = B_TRUE; 10077 10078 return (error); 10079 } 10080 10081 int 10082 zpool_do_set(int argc, char **argv) 10083 { 10084 set_cbdata_t cb = { 0 }; 10085 int error; 10086 10087 if (argc > 1 && argv[1][0] == '-') { 10088 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 10089 argv[1][1]); 10090 usage(B_FALSE); 10091 } 10092 10093 if (argc < 2) { 10094 (void) fprintf(stderr, gettext("missing property=value " 10095 "argument\n")); 10096 usage(B_FALSE); 10097 } 10098 10099 if (argc < 3) { 10100 (void) fprintf(stderr, gettext("missing pool name\n")); 10101 usage(B_FALSE); 10102 } 10103 10104 if (argc > 3) { 10105 (void) fprintf(stderr, gettext("too many pool names\n")); 10106 usage(B_FALSE); 10107 } 10108 10109 cb.cb_propname = argv[1]; 10110 cb.cb_value = strchr(cb.cb_propname, '='); 10111 if (cb.cb_value == NULL) { 10112 (void) fprintf(stderr, gettext("missing value in " 10113 "property=value argument\n")); 10114 usage(B_FALSE); 10115 } 10116 10117 *(cb.cb_value) = '\0'; 10118 cb.cb_value++; 10119 10120 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, B_FALSE, 10121 set_callback, &cb); 10122 10123 return (error); 10124 } 10125 10126 /* Add up the total number of bytes left to initialize/trim across all vdevs */ 10127 static uint64_t 10128 vdev_activity_remaining(nvlist_t *nv, zpool_wait_activity_t activity) 10129 { 10130 uint64_t bytes_remaining; 10131 nvlist_t **child; 10132 uint_t c, children; 10133 vdev_stat_t *vs; 10134 10135 assert(activity == ZPOOL_WAIT_INITIALIZE || 10136 activity == ZPOOL_WAIT_TRIM); 10137 10138 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 10139 (uint64_t **)&vs, &c) == 0); 10140 10141 if (activity == ZPOOL_WAIT_INITIALIZE && 10142 vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) 10143 bytes_remaining = vs->vs_initialize_bytes_est - 10144 vs->vs_initialize_bytes_done; 10145 else if (activity == ZPOOL_WAIT_TRIM && 10146 vs->vs_trim_state == VDEV_TRIM_ACTIVE) 10147 bytes_remaining = vs->vs_trim_bytes_est - 10148 vs->vs_trim_bytes_done; 10149 else 10150 bytes_remaining = 0; 10151 10152 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10153 &child, &children) != 0) 10154 children = 0; 10155 10156 for (c = 0; c < children; c++) 10157 bytes_remaining += vdev_activity_remaining(child[c], activity); 10158 10159 return (bytes_remaining); 10160 } 10161 10162 /* Add up the total number of bytes left to rebuild across top-level vdevs */ 10163 static uint64_t 10164 vdev_activity_top_remaining(nvlist_t *nv) 10165 { 10166 uint64_t bytes_remaining = 0; 10167 nvlist_t **child; 10168 uint_t children; 10169 int error; 10170 10171 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10172 &child, &children) != 0) 10173 children = 0; 10174 10175 for (uint_t c = 0; c < children; c++) { 10176 vdev_rebuild_stat_t *vrs; 10177 uint_t i; 10178 10179 error = nvlist_lookup_uint64_array(child[c], 10180 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i); 10181 if (error == 0) { 10182 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 10183 bytes_remaining += (vrs->vrs_bytes_est - 10184 vrs->vrs_bytes_rebuilt); 10185 } 10186 } 10187 } 10188 10189 return (bytes_remaining); 10190 } 10191 10192 /* Whether any vdevs are 'spare' or 'replacing' vdevs */ 10193 static boolean_t 10194 vdev_any_spare_replacing(nvlist_t *nv) 10195 { 10196 nvlist_t **child; 10197 uint_t c, children; 10198 char *vdev_type; 10199 10200 (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &vdev_type); 10201 10202 if (strcmp(vdev_type, VDEV_TYPE_REPLACING) == 0 || 10203 strcmp(vdev_type, VDEV_TYPE_SPARE) == 0 || 10204 strcmp(vdev_type, VDEV_TYPE_DRAID_SPARE) == 0) { 10205 return (B_TRUE); 10206 } 10207 10208 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10209 &child, &children) != 0) 10210 children = 0; 10211 10212 for (c = 0; c < children; c++) { 10213 if (vdev_any_spare_replacing(child[c])) 10214 return (B_TRUE); 10215 } 10216 10217 return (B_FALSE); 10218 } 10219 10220 typedef struct wait_data { 10221 char *wd_poolname; 10222 boolean_t wd_scripted; 10223 boolean_t wd_exact; 10224 boolean_t wd_headers_once; 10225 boolean_t wd_should_exit; 10226 /* Which activities to wait for */ 10227 boolean_t wd_enabled[ZPOOL_WAIT_NUM_ACTIVITIES]; 10228 float wd_interval; 10229 pthread_cond_t wd_cv; 10230 pthread_mutex_t wd_mutex; 10231 } wait_data_t; 10232 10233 /* 10234 * Print to stdout a single line, containing one column for each activity that 10235 * we are waiting for specifying how many bytes of work are left for that 10236 * activity. 10237 */ 10238 static void 10239 print_wait_status_row(wait_data_t *wd, zpool_handle_t *zhp, int row) 10240 { 10241 nvlist_t *config, *nvroot; 10242 uint_t c; 10243 int i; 10244 pool_checkpoint_stat_t *pcs = NULL; 10245 pool_scan_stat_t *pss = NULL; 10246 pool_removal_stat_t *prs = NULL; 10247 char *headers[] = {"DISCARD", "FREE", "INITIALIZE", "REPLACE", 10248 "REMOVE", "RESILVER", "SCRUB", "TRIM"}; 10249 int col_widths[ZPOOL_WAIT_NUM_ACTIVITIES]; 10250 10251 /* Calculate the width of each column */ 10252 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10253 /* 10254 * Make sure we have enough space in the col for pretty-printed 10255 * numbers and for the column header, and then leave a couple 10256 * spaces between cols for readability. 10257 */ 10258 col_widths[i] = MAX(strlen(headers[i]), 6) + 2; 10259 } 10260 10261 /* Print header if appropriate */ 10262 int term_height = terminal_height(); 10263 boolean_t reprint_header = (!wd->wd_headers_once && term_height > 0 && 10264 row % (term_height-1) == 0); 10265 if (!wd->wd_scripted && (row == 0 || reprint_header)) { 10266 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10267 if (wd->wd_enabled[i]) 10268 (void) printf("%*s", col_widths[i], headers[i]); 10269 } 10270 (void) printf("\n"); 10271 } 10272 10273 /* Bytes of work remaining in each activity */ 10274 int64_t bytes_rem[ZPOOL_WAIT_NUM_ACTIVITIES] = {0}; 10275 10276 bytes_rem[ZPOOL_WAIT_FREE] = 10277 zpool_get_prop_int(zhp, ZPOOL_PROP_FREEING, NULL); 10278 10279 config = zpool_get_config(zhp, NULL); 10280 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 10281 10282 (void) nvlist_lookup_uint64_array(nvroot, 10283 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 10284 if (pcs != NULL && pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 10285 bytes_rem[ZPOOL_WAIT_CKPT_DISCARD] = pcs->pcs_space; 10286 10287 (void) nvlist_lookup_uint64_array(nvroot, 10288 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 10289 if (prs != NULL && prs->prs_state == DSS_SCANNING) 10290 bytes_rem[ZPOOL_WAIT_REMOVE] = prs->prs_to_copy - 10291 prs->prs_copied; 10292 10293 (void) nvlist_lookup_uint64_array(nvroot, 10294 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&pss, &c); 10295 if (pss != NULL && pss->pss_state == DSS_SCANNING && 10296 pss->pss_pass_scrub_pause == 0) { 10297 int64_t rem = pss->pss_to_examine - pss->pss_issued; 10298 if (pss->pss_func == POOL_SCAN_SCRUB) 10299 bytes_rem[ZPOOL_WAIT_SCRUB] = rem; 10300 else 10301 bytes_rem[ZPOOL_WAIT_RESILVER] = rem; 10302 } else if (check_rebuilding(nvroot, NULL)) { 10303 bytes_rem[ZPOOL_WAIT_RESILVER] = 10304 vdev_activity_top_remaining(nvroot); 10305 } 10306 10307 bytes_rem[ZPOOL_WAIT_INITIALIZE] = 10308 vdev_activity_remaining(nvroot, ZPOOL_WAIT_INITIALIZE); 10309 bytes_rem[ZPOOL_WAIT_TRIM] = 10310 vdev_activity_remaining(nvroot, ZPOOL_WAIT_TRIM); 10311 10312 /* 10313 * A replace finishes after resilvering finishes, so the amount of work 10314 * left for a replace is the same as for resilvering. 10315 * 10316 * It isn't quite correct to say that if we have any 'spare' or 10317 * 'replacing' vdevs and a resilver is happening, then a replace is in 10318 * progress, like we do here. When a hot spare is used, the faulted vdev 10319 * is not removed after the hot spare is resilvered, so parent 'spare' 10320 * vdev is not removed either. So we could have a 'spare' vdev, but be 10321 * resilvering for a different reason. However, we use it as a heuristic 10322 * because we don't have access to the DTLs, which could tell us whether 10323 * or not we have really finished resilvering a hot spare. 10324 */ 10325 if (vdev_any_spare_replacing(nvroot)) 10326 bytes_rem[ZPOOL_WAIT_REPLACE] = bytes_rem[ZPOOL_WAIT_RESILVER]; 10327 10328 if (timestamp_fmt != NODATE) 10329 print_timestamp(timestamp_fmt); 10330 10331 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10332 char buf[64]; 10333 if (!wd->wd_enabled[i]) 10334 continue; 10335 10336 if (wd->wd_exact) 10337 (void) snprintf(buf, sizeof (buf), "%" PRIi64, 10338 bytes_rem[i]); 10339 else 10340 zfs_nicenum(bytes_rem[i], buf, sizeof (buf)); 10341 10342 if (wd->wd_scripted) 10343 (void) printf(i == 0 ? "%s" : "\t%s", buf); 10344 else 10345 (void) printf(" %*s", col_widths[i] - 1, buf); 10346 } 10347 (void) printf("\n"); 10348 (void) fflush(stdout); 10349 } 10350 10351 static void * 10352 wait_status_thread(void *arg) 10353 { 10354 wait_data_t *wd = (wait_data_t *)arg; 10355 zpool_handle_t *zhp; 10356 10357 if ((zhp = zpool_open(g_zfs, wd->wd_poolname)) == NULL) 10358 return (void *)(1); 10359 10360 for (int row = 0; ; row++) { 10361 boolean_t missing; 10362 struct timespec timeout; 10363 int ret = 0; 10364 (void) clock_gettime(CLOCK_REALTIME, &timeout); 10365 10366 if (zpool_refresh_stats(zhp, &missing) != 0 || missing || 10367 zpool_props_refresh(zhp) != 0) { 10368 zpool_close(zhp); 10369 return (void *)(uintptr_t)(missing ? 0 : 1); 10370 } 10371 10372 print_wait_status_row(wd, zhp, row); 10373 10374 timeout.tv_sec += floor(wd->wd_interval); 10375 long nanos = timeout.tv_nsec + 10376 (wd->wd_interval - floor(wd->wd_interval)) * NANOSEC; 10377 if (nanos >= NANOSEC) { 10378 timeout.tv_sec++; 10379 timeout.tv_nsec = nanos - NANOSEC; 10380 } else { 10381 timeout.tv_nsec = nanos; 10382 } 10383 pthread_mutex_lock(&wd->wd_mutex); 10384 if (!wd->wd_should_exit) 10385 ret = pthread_cond_timedwait(&wd->wd_cv, &wd->wd_mutex, 10386 &timeout); 10387 pthread_mutex_unlock(&wd->wd_mutex); 10388 if (ret == 0) { 10389 break; /* signaled by main thread */ 10390 } else if (ret != ETIMEDOUT) { 10391 (void) fprintf(stderr, gettext("pthread_cond_timedwait " 10392 "failed: %s\n"), strerror(ret)); 10393 zpool_close(zhp); 10394 return (void *)(uintptr_t)(1); 10395 } 10396 } 10397 10398 zpool_close(zhp); 10399 return (void *)(0); 10400 } 10401 10402 int 10403 zpool_do_wait(int argc, char **argv) 10404 { 10405 boolean_t verbose = B_FALSE; 10406 int c; 10407 char *value; 10408 int i; 10409 unsigned long count; 10410 pthread_t status_thr; 10411 int error = 0; 10412 zpool_handle_t *zhp; 10413 10414 wait_data_t wd; 10415 wd.wd_scripted = B_FALSE; 10416 wd.wd_exact = B_FALSE; 10417 wd.wd_headers_once = B_FALSE; 10418 wd.wd_should_exit = B_FALSE; 10419 10420 pthread_mutex_init(&wd.wd_mutex, NULL); 10421 pthread_cond_init(&wd.wd_cv, NULL); 10422 10423 /* By default, wait for all types of activity. */ 10424 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) 10425 wd.wd_enabled[i] = B_TRUE; 10426 10427 while ((c = getopt(argc, argv, "HpT:t:")) != -1) { 10428 switch (c) { 10429 case 'H': 10430 wd.wd_scripted = B_TRUE; 10431 break; 10432 case 'n': 10433 wd.wd_headers_once = B_TRUE; 10434 break; 10435 case 'p': 10436 wd.wd_exact = B_TRUE; 10437 break; 10438 case 'T': 10439 get_timestamp_arg(*optarg); 10440 break; 10441 case 't': 10442 { 10443 static char *col_subopts[] = { "discard", "free", 10444 "initialize", "replace", "remove", "resilver", 10445 "scrub", "trim", NULL }; 10446 10447 /* Reset activities array */ 10448 bzero(&wd.wd_enabled, sizeof (wd.wd_enabled)); 10449 while (*optarg != '\0') { 10450 int activity = getsubopt(&optarg, col_subopts, 10451 &value); 10452 10453 if (activity < 0) { 10454 (void) fprintf(stderr, 10455 gettext("invalid activity '%s'\n"), 10456 value); 10457 usage(B_FALSE); 10458 } 10459 10460 wd.wd_enabled[activity] = B_TRUE; 10461 } 10462 break; 10463 } 10464 case '?': 10465 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 10466 optopt); 10467 usage(B_FALSE); 10468 } 10469 } 10470 10471 argc -= optind; 10472 argv += optind; 10473 10474 get_interval_count(&argc, argv, &wd.wd_interval, &count); 10475 if (count != 0) { 10476 /* This subcmd only accepts an interval, not a count */ 10477 (void) fprintf(stderr, gettext("too many arguments\n")); 10478 usage(B_FALSE); 10479 } 10480 10481 if (wd.wd_interval != 0) 10482 verbose = B_TRUE; 10483 10484 if (argc < 1) { 10485 (void) fprintf(stderr, gettext("missing 'pool' argument\n")); 10486 usage(B_FALSE); 10487 } 10488 if (argc > 1) { 10489 (void) fprintf(stderr, gettext("too many arguments\n")); 10490 usage(B_FALSE); 10491 } 10492 10493 wd.wd_poolname = argv[0]; 10494 10495 if ((zhp = zpool_open(g_zfs, wd.wd_poolname)) == NULL) 10496 return (1); 10497 10498 if (verbose) { 10499 /* 10500 * We use a separate thread for printing status updates because 10501 * the main thread will call lzc_wait(), which blocks as long 10502 * as an activity is in progress, which can be a long time. 10503 */ 10504 if (pthread_create(&status_thr, NULL, wait_status_thread, &wd) 10505 != 0) { 10506 (void) fprintf(stderr, gettext("failed to create status" 10507 "thread: %s\n"), strerror(errno)); 10508 zpool_close(zhp); 10509 return (1); 10510 } 10511 } 10512 10513 /* 10514 * Loop over all activities that we are supposed to wait for until none 10515 * of them are in progress. Note that this means we can end up waiting 10516 * for more activities to complete than just those that were in progress 10517 * when we began waiting; if an activity we are interested in begins 10518 * while we are waiting for another activity, we will wait for both to 10519 * complete before exiting. 10520 */ 10521 for (;;) { 10522 boolean_t missing = B_FALSE; 10523 boolean_t any_waited = B_FALSE; 10524 10525 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10526 boolean_t waited; 10527 10528 if (!wd.wd_enabled[i]) 10529 continue; 10530 10531 error = zpool_wait_status(zhp, i, &missing, &waited); 10532 if (error != 0 || missing) 10533 break; 10534 10535 any_waited = (any_waited || waited); 10536 } 10537 10538 if (error != 0 || missing || !any_waited) 10539 break; 10540 } 10541 10542 zpool_close(zhp); 10543 10544 if (verbose) { 10545 uintptr_t status; 10546 pthread_mutex_lock(&wd.wd_mutex); 10547 wd.wd_should_exit = B_TRUE; 10548 pthread_cond_signal(&wd.wd_cv); 10549 pthread_mutex_unlock(&wd.wd_mutex); 10550 (void) pthread_join(status_thr, (void *)&status); 10551 if (status != 0) 10552 error = status; 10553 } 10554 10555 pthread_mutex_destroy(&wd.wd_mutex); 10556 pthread_cond_destroy(&wd.wd_cv); 10557 return (error); 10558 } 10559 10560 static int 10561 find_command_idx(char *command, int *idx) 10562 { 10563 int i; 10564 10565 for (i = 0; i < NCOMMAND; i++) { 10566 if (command_table[i].name == NULL) 10567 continue; 10568 10569 if (strcmp(command, command_table[i].name) == 0) { 10570 *idx = i; 10571 return (0); 10572 } 10573 } 10574 return (1); 10575 } 10576 10577 /* 10578 * Display version message 10579 */ 10580 static int 10581 zpool_do_version(int argc, char **argv) 10582 { 10583 if (zfs_version_print() == -1) 10584 return (1); 10585 10586 return (0); 10587 } 10588 10589 /* 10590 * Do zpool_load_compat() and print error message on failure 10591 */ 10592 static zpool_compat_status_t 10593 zpool_do_load_compat(const char *compat, boolean_t *list) 10594 { 10595 char report[1024]; 10596 10597 zpool_compat_status_t ret; 10598 10599 ret = zpool_load_compat(compat, list, report, 1024); 10600 switch (ret) { 10601 10602 case ZPOOL_COMPATIBILITY_OK: 10603 break; 10604 10605 case ZPOOL_COMPATIBILITY_NOFILES: 10606 case ZPOOL_COMPATIBILITY_BADFILE: 10607 case ZPOOL_COMPATIBILITY_BADTOKEN: 10608 (void) fprintf(stderr, "Error: %s\n", report); 10609 break; 10610 10611 case ZPOOL_COMPATIBILITY_WARNTOKEN: 10612 (void) fprintf(stderr, "Warning: %s\n", report); 10613 ret = ZPOOL_COMPATIBILITY_OK; 10614 break; 10615 } 10616 return (ret); 10617 } 10618 10619 int 10620 main(int argc, char **argv) 10621 { 10622 int ret = 0; 10623 int i = 0; 10624 char *cmdname; 10625 char **newargv; 10626 10627 (void) setlocale(LC_ALL, ""); 10628 (void) setlocale(LC_NUMERIC, "C"); 10629 (void) textdomain(TEXT_DOMAIN); 10630 srand(time(NULL)); 10631 10632 opterr = 0; 10633 10634 /* 10635 * Make sure the user has specified some command. 10636 */ 10637 if (argc < 2) { 10638 (void) fprintf(stderr, gettext("missing command\n")); 10639 usage(B_FALSE); 10640 } 10641 10642 cmdname = argv[1]; 10643 10644 /* 10645 * Special case '-?' 10646 */ 10647 if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0) 10648 usage(B_TRUE); 10649 10650 /* 10651 * Special case '-V|--version' 10652 */ 10653 if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0)) 10654 return (zpool_do_version(argc, argv)); 10655 10656 if ((g_zfs = libzfs_init()) == NULL) { 10657 (void) fprintf(stderr, "%s\n", libzfs_error_init(errno)); 10658 return (1); 10659 } 10660 10661 libzfs_print_on_error(g_zfs, B_TRUE); 10662 10663 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 10664 10665 /* 10666 * Many commands modify input strings for string parsing reasons. 10667 * We create a copy to protect the original argv. 10668 */ 10669 newargv = malloc((argc + 1) * sizeof (newargv[0])); 10670 for (i = 0; i < argc; i++) 10671 newargv[i] = strdup(argv[i]); 10672 newargv[argc] = NULL; 10673 10674 /* 10675 * Run the appropriate command. 10676 */ 10677 if (find_command_idx(cmdname, &i) == 0) { 10678 current_command = &command_table[i]; 10679 ret = command_table[i].func(argc - 1, newargv + 1); 10680 } else if (strchr(cmdname, '=')) { 10681 verify(find_command_idx("set", &i) == 0); 10682 current_command = &command_table[i]; 10683 ret = command_table[i].func(argc, newargv); 10684 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 10685 /* 10686 * 'freeze' is a vile debugging abomination, so we treat 10687 * it as such. 10688 */ 10689 zfs_cmd_t zc = {"\0"}; 10690 10691 (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name)); 10692 ret = zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc); 10693 if (ret != 0) { 10694 (void) fprintf(stderr, 10695 gettext("failed to freeze pool: %d\n"), errno); 10696 ret = 1; 10697 } 10698 10699 log_history = 0; 10700 } else { 10701 (void) fprintf(stderr, gettext("unrecognized " 10702 "command '%s'\n"), cmdname); 10703 usage(B_FALSE); 10704 ret = 1; 10705 } 10706 10707 for (i = 0; i < argc; i++) 10708 free(newargv[i]); 10709 free(newargv); 10710 10711 if (ret == 0 && log_history) 10712 (void) zpool_log_history(g_zfs, history_str); 10713 10714 libzfs_fini(g_zfs); 10715 10716 /* 10717 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 10718 * for the purposes of running ::findleaks. 10719 */ 10720 if (getenv("ZFS_ABORT") != NULL) { 10721 (void) printf("dumping core by request\n"); 10722 abort(); 10723 } 10724 10725 return (ret); 10726 } 10727