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