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