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