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(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data) 5160 { 5161 iostat_cbdata_t *cb = cb_data; 5162 char *name = NULL; 5163 int ret = 0; 5164 5165 name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags); 5166 5167 if (strcmp(name, cb->cb_vdev_names[0]) == 0) 5168 ret = 1; /* match */ 5169 free(name); 5170 5171 return (ret); 5172 } 5173 5174 /* 5175 * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise. 5176 */ 5177 static int 5178 is_vdev(zpool_handle_t *zhp, void *cb_data) 5179 { 5180 return (for_each_vdev(zhp, is_vdev_cb, cb_data)); 5181 } 5182 5183 /* 5184 * Check if vdevs are in a pool 5185 * 5186 * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise 5187 * return 0. If pool_name is NULL, then search all pools. 5188 */ 5189 static int 5190 are_vdevs_in_pool(int argc, char **argv, char *pool_name, 5191 iostat_cbdata_t *cb) 5192 { 5193 char **tmp_name; 5194 int ret = 0; 5195 int i; 5196 int pool_count = 0; 5197 5198 if ((argc == 0) || !*argv) 5199 return (0); 5200 5201 if (pool_name) 5202 pool_count = 1; 5203 5204 /* Temporarily hijack cb_vdev_names for a second... */ 5205 tmp_name = cb->cb_vdev_names; 5206 5207 /* Go though our list of prospective vdev names */ 5208 for (i = 0; i < argc; i++) { 5209 cb->cb_vdev_names = argv + i; 5210 5211 /* Is this name a vdev in our pools? */ 5212 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL, 5213 B_FALSE, is_vdev, cb); 5214 if (!ret) { 5215 /* No match */ 5216 break; 5217 } 5218 } 5219 5220 cb->cb_vdev_names = tmp_name; 5221 5222 return (ret); 5223 } 5224 5225 static int 5226 is_pool_cb(zpool_handle_t *zhp, void *data) 5227 { 5228 char *name = data; 5229 if (strcmp(name, zpool_get_name(zhp)) == 0) 5230 return (1); 5231 5232 return (0); 5233 } 5234 5235 /* 5236 * Do we have a pool named *name? If so, return 1, otherwise 0. 5237 */ 5238 static int 5239 is_pool(char *name) 5240 { 5241 return (for_each_pool(0, NULL, B_TRUE, NULL, B_FALSE, is_pool_cb, 5242 name)); 5243 } 5244 5245 /* Are all our argv[] strings pool names? If so return 1, 0 otherwise. */ 5246 static int 5247 are_all_pools(int argc, char **argv) 5248 { 5249 if ((argc == 0) || !*argv) 5250 return (0); 5251 5252 while (--argc >= 0) 5253 if (!is_pool(argv[argc])) 5254 return (0); 5255 5256 return (1); 5257 } 5258 5259 /* 5260 * Helper function to print out vdev/pool names we can't resolve. Used for an 5261 * error message. 5262 */ 5263 static void 5264 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name, 5265 iostat_cbdata_t *cb) 5266 { 5267 int i; 5268 char *name; 5269 char *str; 5270 for (i = 0; i < argc; i++) { 5271 name = argv[i]; 5272 5273 if (is_pool(name)) 5274 str = gettext("pool"); 5275 else if (are_vdevs_in_pool(1, &name, pool_name, cb)) 5276 str = gettext("vdev in this pool"); 5277 else if (are_vdevs_in_pool(1, &name, NULL, cb)) 5278 str = gettext("vdev in another pool"); 5279 else 5280 str = gettext("unknown"); 5281 5282 fprintf(stderr, "\t%s (%s)\n", name, str); 5283 } 5284 } 5285 5286 /* 5287 * Same as get_interval_count(), but with additional checks to not misinterpret 5288 * guids as interval/count values. Assumes VDEV_NAME_GUID is set in 5289 * cb.cb_name_flags. 5290 */ 5291 static void 5292 get_interval_count_filter_guids(int *argc, char **argv, float *interval, 5293 unsigned long *count, iostat_cbdata_t *cb) 5294 { 5295 char **tmpargv = argv; 5296 int argc_for_interval = 0; 5297 5298 /* Is the last arg an interval value? Or a guid? */ 5299 if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) { 5300 /* 5301 * The last arg is not a guid, so it's probably an 5302 * interval value. 5303 */ 5304 argc_for_interval++; 5305 5306 if (*argc >= 2 && 5307 !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) { 5308 /* 5309 * The 2nd to last arg is not a guid, so it's probably 5310 * an interval value. 5311 */ 5312 argc_for_interval++; 5313 } 5314 } 5315 5316 /* Point to our list of possible intervals */ 5317 tmpargv = &argv[*argc - argc_for_interval]; 5318 5319 *argc = *argc - argc_for_interval; 5320 get_interval_count(&argc_for_interval, tmpargv, 5321 interval, count); 5322 } 5323 5324 /* 5325 * Floating point sleep(). Allows you to pass in a floating point value for 5326 * seconds. 5327 */ 5328 static void 5329 fsleep(float sec) 5330 { 5331 struct timespec req; 5332 req.tv_sec = floor(sec); 5333 req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC; 5334 nanosleep(&req, NULL); 5335 } 5336 5337 /* 5338 * Terminal height, in rows. Returns -1 if stdout is not connected to a TTY or 5339 * if we were unable to determine its size. 5340 */ 5341 static int 5342 terminal_height(void) 5343 { 5344 struct winsize win; 5345 5346 if (isatty(STDOUT_FILENO) == 0) 5347 return (-1); 5348 5349 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 && win.ws_row > 0) 5350 return (win.ws_row); 5351 5352 return (-1); 5353 } 5354 5355 /* 5356 * Run one of the zpool status/iostat -c scripts with the help (-h) option and 5357 * print the result. 5358 * 5359 * name: Short name of the script ('iostat'). 5360 * path: Full path to the script ('/usr/local/etc/zfs/zpool.d/iostat'); 5361 */ 5362 static void 5363 print_zpool_script_help(char *name, char *path) 5364 { 5365 char *argv[] = {path, "-h", NULL}; 5366 char **lines = NULL; 5367 int lines_cnt = 0; 5368 int rc; 5369 5370 rc = libzfs_run_process_get_stdout_nopath(path, argv, NULL, &lines, 5371 &lines_cnt); 5372 if (rc != 0 || lines == NULL || lines_cnt <= 0) { 5373 if (lines != NULL) 5374 libzfs_free_str_array(lines, lines_cnt); 5375 return; 5376 } 5377 5378 for (int i = 0; i < lines_cnt; i++) 5379 if (!is_blank_str(lines[i])) 5380 printf(" %-14s %s\n", name, lines[i]); 5381 5382 libzfs_free_str_array(lines, lines_cnt); 5383 } 5384 5385 /* 5386 * Go though the zpool status/iostat -c scripts in the user's path, run their 5387 * help option (-h), and print out the results. 5388 */ 5389 static void 5390 print_zpool_dir_scripts(char *dirpath) 5391 { 5392 DIR *dir; 5393 struct dirent *ent; 5394 char fullpath[MAXPATHLEN]; 5395 struct stat dir_stat; 5396 5397 if ((dir = opendir(dirpath)) != NULL) { 5398 /* print all the files and directories within directory */ 5399 while ((ent = readdir(dir)) != NULL) { 5400 sprintf(fullpath, "%s/%s", dirpath, ent->d_name); 5401 5402 /* Print the scripts */ 5403 if (stat(fullpath, &dir_stat) == 0) 5404 if (dir_stat.st_mode & S_IXUSR && 5405 S_ISREG(dir_stat.st_mode)) 5406 print_zpool_script_help(ent->d_name, 5407 fullpath); 5408 } 5409 closedir(dir); 5410 } 5411 } 5412 5413 /* 5414 * Print out help text for all zpool status/iostat -c scripts. 5415 */ 5416 static void 5417 print_zpool_script_list(char *subcommand) 5418 { 5419 char *dir, *sp, *tmp; 5420 5421 printf(gettext("Available 'zpool %s -c' commands:\n"), subcommand); 5422 5423 sp = zpool_get_cmd_search_path(); 5424 if (sp == NULL) 5425 return; 5426 5427 for (dir = strtok_r(sp, ":", &tmp); 5428 dir != NULL; 5429 dir = strtok_r(NULL, ":", &tmp)) 5430 print_zpool_dir_scripts(dir); 5431 5432 free(sp); 5433 } 5434 5435 /* 5436 * Set the minimum pool/vdev name column width. The width must be at least 10, 5437 * but may be as large as the column width - 42 so it still fits on one line. 5438 * NOTE: 42 is the width of the default capacity/operations/bandwidth output 5439 */ 5440 static int 5441 get_namewidth_iostat(zpool_handle_t *zhp, void *data) 5442 { 5443 iostat_cbdata_t *cb = data; 5444 int width, available_width; 5445 5446 /* 5447 * get_namewidth() returns the maximum width of any name in that column 5448 * for any pool/vdev/device line that will be output. 5449 */ 5450 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 5451 cb->cb_verbose); 5452 5453 /* 5454 * The width we are calculating is the width of the header and also the 5455 * padding width for names that are less than maximum width. The stats 5456 * take up 42 characters, so the width available for names is: 5457 */ 5458 available_width = get_columns() - 42; 5459 5460 /* 5461 * If the maximum width fits on a screen, then great! Make everything 5462 * line up by justifying all lines to the same width. If that max 5463 * width is larger than what's available, the name plus stats won't fit 5464 * on one line, and justifying to that width would cause every line to 5465 * wrap on the screen. We only want lines with long names to wrap. 5466 * Limit the padding to what won't wrap. 5467 */ 5468 if (width > available_width) 5469 width = available_width; 5470 5471 /* 5472 * And regardless of whatever the screen width is (get_columns can 5473 * return 0 if the width is not known or less than 42 for a narrow 5474 * terminal) have the width be a minimum of 10. 5475 */ 5476 if (width < 10) 5477 width = 10; 5478 5479 /* Save the calculated width */ 5480 cb->cb_namewidth = width; 5481 5482 return (0); 5483 } 5484 5485 /* 5486 * zpool iostat [[-c [script1,script2,...]] [-lq]|[-rw]] [-ghHLpPvy] [-n name] 5487 * [-T d|u] [[ pool ...]|[pool vdev ...]|[vdev ...]] 5488 * [interval [count]] 5489 * 5490 * -c CMD For each vdev, run command CMD 5491 * -g Display guid for individual vdev name. 5492 * -L Follow links when resolving vdev path name. 5493 * -P Display full path for vdev name. 5494 * -v Display statistics for individual vdevs 5495 * -h Display help 5496 * -p Display values in parsable (exact) format. 5497 * -H Scripted mode. Don't display headers, and separate properties 5498 * by a single tab. 5499 * -l Display average latency 5500 * -q Display queue depths 5501 * -w Display latency histograms 5502 * -r Display request size histogram 5503 * -T Display a timestamp in date(1) or Unix format 5504 * -n Only print headers once 5505 * 5506 * This command can be tricky because we want to be able to deal with pool 5507 * creation/destruction as well as vdev configuration changes. The bulk of this 5508 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 5509 * on pool_list_update() to detect the addition of new pools. Configuration 5510 * changes are all handled within libzfs. 5511 */ 5512 int 5513 zpool_do_iostat(int argc, char **argv) 5514 { 5515 int c; 5516 int ret; 5517 int npools; 5518 float interval = 0; 5519 unsigned long count = 0; 5520 int winheight = 24; 5521 zpool_list_t *list; 5522 boolean_t verbose = B_FALSE; 5523 boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE; 5524 boolean_t queues = B_FALSE, parsable = B_FALSE, scripted = B_FALSE; 5525 boolean_t omit_since_boot = B_FALSE; 5526 boolean_t guid = B_FALSE; 5527 boolean_t follow_links = B_FALSE; 5528 boolean_t full_name = B_FALSE; 5529 boolean_t headers_once = B_FALSE; 5530 iostat_cbdata_t cb = { 0 }; 5531 char *cmd = NULL; 5532 5533 /* Used for printing error message */ 5534 const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q', 5535 [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'}; 5536 5537 uint64_t unsupported_flags; 5538 5539 /* check options */ 5540 while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwnH")) != -1) { 5541 switch (c) { 5542 case 'c': 5543 if (cmd != NULL) { 5544 fprintf(stderr, 5545 gettext("Can't set -c flag twice\n")); 5546 exit(1); 5547 } 5548 5549 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL && 5550 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) { 5551 fprintf(stderr, gettext( 5552 "Can't run -c, disabled by " 5553 "ZPOOL_SCRIPTS_ENABLED.\n")); 5554 exit(1); 5555 } 5556 5557 if ((getuid() <= 0 || geteuid() <= 0) && 5558 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) { 5559 fprintf(stderr, gettext( 5560 "Can't run -c with root privileges " 5561 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n")); 5562 exit(1); 5563 } 5564 cmd = optarg; 5565 verbose = B_TRUE; 5566 break; 5567 case 'g': 5568 guid = B_TRUE; 5569 break; 5570 case 'L': 5571 follow_links = B_TRUE; 5572 break; 5573 case 'P': 5574 full_name = B_TRUE; 5575 break; 5576 case 'T': 5577 get_timestamp_arg(*optarg); 5578 break; 5579 case 'v': 5580 verbose = B_TRUE; 5581 break; 5582 case 'p': 5583 parsable = B_TRUE; 5584 break; 5585 case 'l': 5586 latency = B_TRUE; 5587 break; 5588 case 'q': 5589 queues = B_TRUE; 5590 break; 5591 case 'H': 5592 scripted = B_TRUE; 5593 break; 5594 case 'w': 5595 l_histo = B_TRUE; 5596 break; 5597 case 'r': 5598 rq_histo = B_TRUE; 5599 break; 5600 case 'y': 5601 omit_since_boot = B_TRUE; 5602 break; 5603 case 'n': 5604 headers_once = B_TRUE; 5605 break; 5606 case 'h': 5607 usage(B_FALSE); 5608 break; 5609 case '?': 5610 if (optopt == 'c') { 5611 print_zpool_script_list("iostat"); 5612 exit(0); 5613 } else { 5614 fprintf(stderr, 5615 gettext("invalid option '%c'\n"), optopt); 5616 } 5617 usage(B_FALSE); 5618 } 5619 } 5620 5621 argc -= optind; 5622 argv += optind; 5623 5624 cb.cb_literal = parsable; 5625 cb.cb_scripted = scripted; 5626 5627 if (guid) 5628 cb.cb_name_flags |= VDEV_NAME_GUID; 5629 if (follow_links) 5630 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 5631 if (full_name) 5632 cb.cb_name_flags |= VDEV_NAME_PATH; 5633 cb.cb_iteration = 0; 5634 cb.cb_namewidth = 0; 5635 cb.cb_verbose = verbose; 5636 5637 /* Get our interval and count values (if any) */ 5638 if (guid) { 5639 get_interval_count_filter_guids(&argc, argv, &interval, 5640 &count, &cb); 5641 } else { 5642 get_interval_count(&argc, argv, &interval, &count); 5643 } 5644 5645 if (argc == 0) { 5646 /* No args, so just print the defaults. */ 5647 } else if (are_all_pools(argc, argv)) { 5648 /* All the args are pool names */ 5649 } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) { 5650 /* All the args are vdevs */ 5651 cb.cb_vdev_names = argv; 5652 cb.cb_vdev_names_count = argc; 5653 argc = 0; /* No pools to process */ 5654 } else if (are_all_pools(1, argv)) { 5655 /* The first arg is a pool name */ 5656 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) { 5657 /* ...and the rest are vdev names */ 5658 cb.cb_vdev_names = argv + 1; 5659 cb.cb_vdev_names_count = argc - 1; 5660 argc = 1; /* One pool to process */ 5661 } else { 5662 fprintf(stderr, gettext("Expected either a list of ")); 5663 fprintf(stderr, gettext("pools, or list of vdevs in")); 5664 fprintf(stderr, " \"%s\", ", argv[0]); 5665 fprintf(stderr, gettext("but got:\n")); 5666 error_list_unresolved_vdevs(argc - 1, argv + 1, 5667 argv[0], &cb); 5668 fprintf(stderr, "\n"); 5669 usage(B_FALSE); 5670 return (1); 5671 } 5672 } else { 5673 /* 5674 * The args don't make sense. The first arg isn't a pool name, 5675 * nor are all the args vdevs. 5676 */ 5677 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n")); 5678 fprintf(stderr, "\n"); 5679 return (1); 5680 } 5681 5682 if (cb.cb_vdev_names_count != 0) { 5683 /* 5684 * If user specified vdevs, it implies verbose. 5685 */ 5686 cb.cb_verbose = B_TRUE; 5687 } 5688 5689 /* 5690 * Construct the list of all interesting pools. 5691 */ 5692 ret = 0; 5693 if ((list = pool_list_get(argc, argv, NULL, parsable, &ret)) == NULL) 5694 return (1); 5695 5696 if (pool_list_count(list) == 0 && argc != 0) { 5697 pool_list_free(list); 5698 return (1); 5699 } 5700 5701 if (pool_list_count(list) == 0 && interval == 0) { 5702 pool_list_free(list); 5703 (void) fprintf(stderr, gettext("no pools available\n")); 5704 return (1); 5705 } 5706 5707 if ((l_histo || rq_histo) && (cmd != NULL || latency || queues)) { 5708 pool_list_free(list); 5709 (void) fprintf(stderr, 5710 gettext("[-r|-w] isn't allowed with [-c|-l|-q]\n")); 5711 usage(B_FALSE); 5712 return (1); 5713 } 5714 5715 if (l_histo && rq_histo) { 5716 pool_list_free(list); 5717 (void) fprintf(stderr, 5718 gettext("Only one of [-r|-w] can be passed at a time\n")); 5719 usage(B_FALSE); 5720 return (1); 5721 } 5722 5723 /* 5724 * Enter the main iostat loop. 5725 */ 5726 cb.cb_list = list; 5727 5728 if (l_histo) { 5729 /* 5730 * Histograms tables look out of place when you try to display 5731 * them with the other stats, so make a rule that you can only 5732 * print histograms by themselves. 5733 */ 5734 cb.cb_flags = IOS_L_HISTO_M; 5735 } else if (rq_histo) { 5736 cb.cb_flags = IOS_RQ_HISTO_M; 5737 } else { 5738 cb.cb_flags = IOS_DEFAULT_M; 5739 if (latency) 5740 cb.cb_flags |= IOS_LATENCY_M; 5741 if (queues) 5742 cb.cb_flags |= IOS_QUEUES_M; 5743 } 5744 5745 /* 5746 * See if the module supports all the stats we want to display. 5747 */ 5748 unsupported_flags = cb.cb_flags & ~get_stat_flags(list); 5749 if (unsupported_flags) { 5750 uint64_t f; 5751 int idx; 5752 fprintf(stderr, 5753 gettext("The loaded zfs module doesn't support:")); 5754 5755 /* for each bit set in unsupported_flags */ 5756 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) { 5757 idx = lowbit64(f) - 1; 5758 fprintf(stderr, " -%c", flag_to_arg[idx]); 5759 } 5760 5761 fprintf(stderr, ". Try running a newer module.\n"); 5762 pool_list_free(list); 5763 5764 return (1); 5765 } 5766 5767 for (;;) { 5768 if ((npools = pool_list_count(list)) == 0) 5769 (void) fprintf(stderr, gettext("no pools available\n")); 5770 else { 5771 /* 5772 * If this is the first iteration and -y was supplied 5773 * we skip any printing. 5774 */ 5775 boolean_t skip = (omit_since_boot && 5776 cb.cb_iteration == 0); 5777 5778 /* 5779 * Refresh all statistics. This is done as an 5780 * explicit step before calculating the maximum name 5781 * width, so that any * configuration changes are 5782 * properly accounted for. 5783 */ 5784 (void) pool_list_iter(list, B_FALSE, refresh_iostat, 5785 &cb); 5786 5787 /* 5788 * Iterate over all pools to determine the maximum width 5789 * for the pool / device name column across all pools. 5790 */ 5791 cb.cb_namewidth = 0; 5792 (void) pool_list_iter(list, B_FALSE, 5793 get_namewidth_iostat, &cb); 5794 5795 if (timestamp_fmt != NODATE) 5796 print_timestamp(timestamp_fmt); 5797 5798 if (cmd != NULL && cb.cb_verbose && 5799 !(cb.cb_flags & IOS_ANYHISTO_M)) { 5800 cb.vcdl = all_pools_for_each_vdev_run(argc, 5801 argv, cmd, g_zfs, cb.cb_vdev_names, 5802 cb.cb_vdev_names_count, cb.cb_name_flags); 5803 } else { 5804 cb.vcdl = NULL; 5805 } 5806 5807 5808 /* 5809 * Check terminal size so we can print headers 5810 * even when terminal window has its height 5811 * changed. 5812 */ 5813 winheight = terminal_height(); 5814 /* 5815 * Are we connected to TTY? If not, headers_once 5816 * should be true, to avoid breaking scripts. 5817 */ 5818 if (winheight < 0) 5819 headers_once = B_TRUE; 5820 5821 /* 5822 * If it's the first time and we're not skipping it, 5823 * or either skip or verbose mode, print the header. 5824 * 5825 * The histogram code explicitly prints its header on 5826 * every vdev, so skip this for histograms. 5827 */ 5828 if (((++cb.cb_iteration == 1 && !skip) || 5829 (skip != verbose) || 5830 (!headers_once && 5831 (cb.cb_iteration % winheight) == 0)) && 5832 (!(cb.cb_flags & IOS_ANYHISTO_M)) && 5833 !cb.cb_scripted) 5834 print_iostat_header(&cb); 5835 5836 if (skip) { 5837 (void) fsleep(interval); 5838 continue; 5839 } 5840 5841 pool_list_iter(list, B_FALSE, print_iostat, &cb); 5842 5843 /* 5844 * If there's more than one pool, and we're not in 5845 * verbose mode (which prints a separator for us), 5846 * then print a separator. 5847 * 5848 * In addition, if we're printing specific vdevs then 5849 * we also want an ending separator. 5850 */ 5851 if (((npools > 1 && !verbose && 5852 !(cb.cb_flags & IOS_ANYHISTO_M)) || 5853 (!(cb.cb_flags & IOS_ANYHISTO_M) && 5854 cb.cb_vdev_names_count)) && 5855 !cb.cb_scripted) { 5856 print_iostat_separator(&cb); 5857 if (cb.vcdl != NULL) 5858 print_cmd_columns(cb.vcdl, 1); 5859 printf("\n"); 5860 } 5861 5862 if (cb.vcdl != NULL) 5863 free_vdev_cmd_data_list(cb.vcdl); 5864 5865 } 5866 5867 /* 5868 * Flush the output so that redirection to a file isn't buffered 5869 * indefinitely. 5870 */ 5871 (void) fflush(stdout); 5872 5873 if (interval == 0) 5874 break; 5875 5876 if (count != 0 && --count == 0) 5877 break; 5878 5879 (void) fsleep(interval); 5880 } 5881 5882 pool_list_free(list); 5883 5884 return (ret); 5885 } 5886 5887 typedef struct list_cbdata { 5888 boolean_t cb_verbose; 5889 int cb_name_flags; 5890 int cb_namewidth; 5891 boolean_t cb_scripted; 5892 zprop_list_t *cb_proplist; 5893 boolean_t cb_literal; 5894 } list_cbdata_t; 5895 5896 5897 /* 5898 * Given a list of columns to display, output appropriate headers for each one. 5899 */ 5900 static void 5901 print_header(list_cbdata_t *cb) 5902 { 5903 zprop_list_t *pl = cb->cb_proplist; 5904 char headerbuf[ZPOOL_MAXPROPLEN]; 5905 const char *header; 5906 boolean_t first = B_TRUE; 5907 boolean_t right_justify; 5908 size_t width = 0; 5909 5910 for (; pl != NULL; pl = pl->pl_next) { 5911 width = pl->pl_width; 5912 if (first && cb->cb_verbose) { 5913 /* 5914 * Reset the width to accommodate the verbose listing 5915 * of devices. 5916 */ 5917 width = cb->cb_namewidth; 5918 } 5919 5920 if (!first) 5921 (void) printf(" "); 5922 else 5923 first = B_FALSE; 5924 5925 right_justify = B_FALSE; 5926 if (pl->pl_prop != ZPROP_INVAL) { 5927 header = zpool_prop_column_name(pl->pl_prop); 5928 right_justify = zpool_prop_align_right(pl->pl_prop); 5929 } else { 5930 int i; 5931 5932 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 5933 headerbuf[i] = toupper(pl->pl_user_prop[i]); 5934 headerbuf[i] = '\0'; 5935 header = headerbuf; 5936 } 5937 5938 if (pl->pl_next == NULL && !right_justify) 5939 (void) printf("%s", header); 5940 else if (right_justify) 5941 (void) printf("%*s", (int)width, header); 5942 else 5943 (void) printf("%-*s", (int)width, header); 5944 } 5945 5946 (void) printf("\n"); 5947 } 5948 5949 /* 5950 * Given a pool and a list of properties, print out all the properties according 5951 * to the described layout. Used by zpool_do_list(). 5952 */ 5953 static void 5954 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 5955 { 5956 zprop_list_t *pl = cb->cb_proplist; 5957 boolean_t first = B_TRUE; 5958 char property[ZPOOL_MAXPROPLEN]; 5959 char *propstr; 5960 boolean_t right_justify; 5961 size_t width; 5962 5963 for (; pl != NULL; pl = pl->pl_next) { 5964 5965 width = pl->pl_width; 5966 if (first && cb->cb_verbose) { 5967 /* 5968 * Reset the width to accommodate the verbose listing 5969 * of devices. 5970 */ 5971 width = cb->cb_namewidth; 5972 } 5973 5974 if (!first) { 5975 if (cb->cb_scripted) 5976 (void) printf("\t"); 5977 else 5978 (void) printf(" "); 5979 } else { 5980 first = B_FALSE; 5981 } 5982 5983 right_justify = B_FALSE; 5984 if (pl->pl_prop != ZPROP_INVAL) { 5985 if (zpool_get_prop(zhp, pl->pl_prop, property, 5986 sizeof (property), NULL, cb->cb_literal) != 0) 5987 propstr = "-"; 5988 else 5989 propstr = property; 5990 5991 right_justify = zpool_prop_align_right(pl->pl_prop); 5992 } else if ((zpool_prop_feature(pl->pl_user_prop) || 5993 zpool_prop_unsupported(pl->pl_user_prop)) && 5994 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 5995 sizeof (property)) == 0) { 5996 propstr = property; 5997 } else { 5998 propstr = "-"; 5999 } 6000 6001 6002 /* 6003 * If this is being called in scripted mode, or if this is the 6004 * last column and it is left-justified, don't include a width 6005 * format specifier. 6006 */ 6007 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 6008 (void) printf("%s", propstr); 6009 else if (right_justify) 6010 (void) printf("%*s", (int)width, propstr); 6011 else 6012 (void) printf("%-*s", (int)width, propstr); 6013 } 6014 6015 (void) printf("\n"); 6016 } 6017 6018 static void 6019 print_one_column(zpool_prop_t prop, uint64_t value, const char *str, 6020 boolean_t scripted, boolean_t valid, enum zfs_nicenum_format format) 6021 { 6022 char propval[64]; 6023 boolean_t fixed; 6024 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 6025 6026 switch (prop) { 6027 case ZPOOL_PROP_EXPANDSZ: 6028 case ZPOOL_PROP_CHECKPOINT: 6029 case ZPOOL_PROP_DEDUPRATIO: 6030 if (value == 0) 6031 (void) strlcpy(propval, "-", sizeof (propval)); 6032 else 6033 zfs_nicenum_format(value, propval, sizeof (propval), 6034 format); 6035 break; 6036 case ZPOOL_PROP_FRAGMENTATION: 6037 if (value == ZFS_FRAG_INVALID) { 6038 (void) strlcpy(propval, "-", sizeof (propval)); 6039 } else if (format == ZFS_NICENUM_RAW) { 6040 (void) snprintf(propval, sizeof (propval), "%llu", 6041 (unsigned long long)value); 6042 } else { 6043 (void) snprintf(propval, sizeof (propval), "%llu%%", 6044 (unsigned long long)value); 6045 } 6046 break; 6047 case ZPOOL_PROP_CAPACITY: 6048 /* capacity value is in parts-per-10,000 (aka permyriad) */ 6049 if (format == ZFS_NICENUM_RAW) 6050 (void) snprintf(propval, sizeof (propval), "%llu", 6051 (unsigned long long)value / 100); 6052 else 6053 (void) snprintf(propval, sizeof (propval), 6054 value < 1000 ? "%1.2f%%" : value < 10000 ? 6055 "%2.1f%%" : "%3.0f%%", value / 100.0); 6056 break; 6057 case ZPOOL_PROP_HEALTH: 6058 width = 8; 6059 (void) strlcpy(propval, str, sizeof (propval)); 6060 break; 6061 default: 6062 zfs_nicenum_format(value, propval, sizeof (propval), format); 6063 } 6064 6065 if (!valid) 6066 (void) strlcpy(propval, "-", sizeof (propval)); 6067 6068 if (scripted) 6069 (void) printf("\t%s", propval); 6070 else 6071 (void) printf(" %*s", (int)width, propval); 6072 } 6073 6074 /* 6075 * print static default line per vdev 6076 * not compatible with '-o' <proplist> option 6077 */ 6078 static void 6079 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 6080 list_cbdata_t *cb, int depth, boolean_t isspare) 6081 { 6082 nvlist_t **child; 6083 vdev_stat_t *vs; 6084 uint_t c, children; 6085 char *vname; 6086 boolean_t scripted = cb->cb_scripted; 6087 uint64_t islog = B_FALSE; 6088 char *dashes = "%-*s - - - - " 6089 "- - - - -\n"; 6090 6091 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 6092 (uint64_t **)&vs, &c) == 0); 6093 6094 if (name != NULL) { 6095 boolean_t toplevel = (vs->vs_space != 0); 6096 uint64_t cap; 6097 enum zfs_nicenum_format format; 6098 const char *state; 6099 6100 if (cb->cb_literal) 6101 format = ZFS_NICENUM_RAW; 6102 else 6103 format = ZFS_NICENUM_1024; 6104 6105 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 6106 return; 6107 6108 if (scripted) 6109 (void) printf("\t%s", name); 6110 else if (strlen(name) + depth > cb->cb_namewidth) 6111 (void) printf("%*s%s", depth, "", name); 6112 else 6113 (void) printf("%*s%s%*s", depth, "", name, 6114 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 6115 6116 /* 6117 * Print the properties for the individual vdevs. Some 6118 * properties are only applicable to toplevel vdevs. The 6119 * 'toplevel' boolean value is passed to the print_one_column() 6120 * to indicate that the value is valid. 6121 */ 6122 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, NULL, scripted, 6123 toplevel, format); 6124 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL, 6125 scripted, toplevel, format); 6126 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 6127 NULL, scripted, toplevel, format); 6128 print_one_column(ZPOOL_PROP_CHECKPOINT, 6129 vs->vs_checkpoint_space, NULL, scripted, toplevel, format); 6130 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL, 6131 scripted, B_TRUE, format); 6132 print_one_column(ZPOOL_PROP_FRAGMENTATION, 6133 vs->vs_fragmentation, NULL, scripted, 6134 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel), 6135 format); 6136 cap = (vs->vs_space == 0) ? 0 : 6137 (vs->vs_alloc * 10000 / vs->vs_space); 6138 print_one_column(ZPOOL_PROP_CAPACITY, cap, NULL, 6139 scripted, toplevel, format); 6140 print_one_column(ZPOOL_PROP_DEDUPRATIO, 0, NULL, 6141 scripted, toplevel, format); 6142 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 6143 if (isspare) { 6144 if (vs->vs_aux == VDEV_AUX_SPARED) 6145 state = "INUSE"; 6146 else if (vs->vs_state == VDEV_STATE_HEALTHY) 6147 state = "AVAIL"; 6148 } 6149 print_one_column(ZPOOL_PROP_HEALTH, 0, state, scripted, 6150 B_TRUE, format); 6151 (void) printf("\n"); 6152 } 6153 6154 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 6155 &child, &children) != 0) 6156 return; 6157 6158 /* list the normal vdevs first */ 6159 for (c = 0; c < children; c++) { 6160 uint64_t ishole = B_FALSE; 6161 6162 if (nvlist_lookup_uint64(child[c], 6163 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 6164 continue; 6165 6166 if (nvlist_lookup_uint64(child[c], 6167 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) 6168 continue; 6169 6170 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 6171 continue; 6172 6173 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6174 cb->cb_name_flags); 6175 print_list_stats(zhp, vname, child[c], cb, depth + 2, B_FALSE); 6176 free(vname); 6177 } 6178 6179 /* list the classes: 'logs', 'dedup', and 'special' */ 6180 for (uint_t n = 0; n < 3; n++) { 6181 boolean_t printed = B_FALSE; 6182 6183 for (c = 0; c < children; c++) { 6184 char *bias = NULL; 6185 char *type = NULL; 6186 6187 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 6188 &islog) == 0 && islog) { 6189 bias = VDEV_ALLOC_CLASS_LOGS; 6190 } else { 6191 (void) nvlist_lookup_string(child[c], 6192 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 6193 (void) nvlist_lookup_string(child[c], 6194 ZPOOL_CONFIG_TYPE, &type); 6195 } 6196 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 6197 continue; 6198 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 6199 continue; 6200 6201 if (!printed) { 6202 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6203 (void) printf(dashes, cb->cb_namewidth, 6204 class_name[n]); 6205 printed = B_TRUE; 6206 } 6207 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6208 cb->cb_name_flags); 6209 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6210 B_FALSE); 6211 free(vname); 6212 } 6213 } 6214 6215 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 6216 &child, &children) == 0 && children > 0) { 6217 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6218 (void) printf(dashes, cb->cb_namewidth, "cache"); 6219 for (c = 0; c < children; c++) { 6220 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6221 cb->cb_name_flags); 6222 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6223 B_FALSE); 6224 free(vname); 6225 } 6226 } 6227 6228 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 6229 &children) == 0 && children > 0) { 6230 /* LINTED E_SEC_PRINTF_VAR_FMT */ 6231 (void) printf(dashes, cb->cb_namewidth, "spare"); 6232 for (c = 0; c < children; c++) { 6233 vname = zpool_vdev_name(g_zfs, zhp, child[c], 6234 cb->cb_name_flags); 6235 print_list_stats(zhp, vname, child[c], cb, depth + 2, 6236 B_TRUE); 6237 free(vname); 6238 } 6239 } 6240 } 6241 6242 /* 6243 * Generic callback function to list a pool. 6244 */ 6245 static int 6246 list_callback(zpool_handle_t *zhp, void *data) 6247 { 6248 list_cbdata_t *cbp = data; 6249 6250 print_pool(zhp, cbp); 6251 6252 if (cbp->cb_verbose) { 6253 nvlist_t *config, *nvroot; 6254 6255 config = zpool_get_config(zhp, NULL); 6256 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 6257 &nvroot) == 0); 6258 print_list_stats(zhp, NULL, nvroot, cbp, 0, B_FALSE); 6259 } 6260 6261 return (0); 6262 } 6263 6264 /* 6265 * Set the minimum pool/vdev name column width. The width must be at least 9, 6266 * but may be as large as needed. 6267 */ 6268 static int 6269 get_namewidth_list(zpool_handle_t *zhp, void *data) 6270 { 6271 list_cbdata_t *cb = data; 6272 int width; 6273 6274 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 6275 cb->cb_verbose); 6276 6277 if (width < 9) 6278 width = 9; 6279 6280 cb->cb_namewidth = width; 6281 6282 return (0); 6283 } 6284 6285 /* 6286 * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 6287 * 6288 * -g Display guid for individual vdev name. 6289 * -H Scripted mode. Don't display headers, and separate properties 6290 * by a single tab. 6291 * -L Follow links when resolving vdev path name. 6292 * -o List of properties to display. Defaults to 6293 * "name,size,allocated,free,expandsize,fragmentation,capacity," 6294 * "dedupratio,health,altroot" 6295 * -p Display values in parsable (exact) format. 6296 * -P Display full path for vdev name. 6297 * -T Display a timestamp in date(1) or Unix format 6298 * 6299 * List all pools in the system, whether or not they're healthy. Output space 6300 * statistics for each one, as well as health status summary. 6301 */ 6302 int 6303 zpool_do_list(int argc, char **argv) 6304 { 6305 int c; 6306 int ret = 0; 6307 list_cbdata_t cb = { 0 }; 6308 static char default_props[] = 6309 "name,size,allocated,free,checkpoint,expandsize,fragmentation," 6310 "capacity,dedupratio,health,altroot"; 6311 char *props = default_props; 6312 float interval = 0; 6313 unsigned long count = 0; 6314 zpool_list_t *list; 6315 boolean_t first = B_TRUE; 6316 6317 /* check options */ 6318 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) { 6319 switch (c) { 6320 case 'g': 6321 cb.cb_name_flags |= VDEV_NAME_GUID; 6322 break; 6323 case 'H': 6324 cb.cb_scripted = B_TRUE; 6325 break; 6326 case 'L': 6327 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 6328 break; 6329 case 'o': 6330 props = optarg; 6331 break; 6332 case 'P': 6333 cb.cb_name_flags |= VDEV_NAME_PATH; 6334 break; 6335 case 'p': 6336 cb.cb_literal = B_TRUE; 6337 break; 6338 case 'T': 6339 get_timestamp_arg(*optarg); 6340 break; 6341 case 'v': 6342 cb.cb_verbose = B_TRUE; 6343 cb.cb_namewidth = 8; /* 8 until precalc is avail */ 6344 break; 6345 case ':': 6346 (void) fprintf(stderr, gettext("missing argument for " 6347 "'%c' option\n"), optopt); 6348 usage(B_FALSE); 6349 break; 6350 case '?': 6351 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6352 optopt); 6353 usage(B_FALSE); 6354 } 6355 } 6356 6357 argc -= optind; 6358 argv += optind; 6359 6360 get_interval_count(&argc, argv, &interval, &count); 6361 6362 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 6363 usage(B_FALSE); 6364 6365 for (;;) { 6366 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 6367 cb.cb_literal, &ret)) == NULL) 6368 return (1); 6369 6370 if (pool_list_count(list) == 0) 6371 break; 6372 6373 cb.cb_namewidth = 0; 6374 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb); 6375 6376 if (timestamp_fmt != NODATE) 6377 print_timestamp(timestamp_fmt); 6378 6379 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 6380 print_header(&cb); 6381 first = B_FALSE; 6382 } 6383 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 6384 6385 if (interval == 0) 6386 break; 6387 6388 if (count != 0 && --count == 0) 6389 break; 6390 6391 pool_list_free(list); 6392 (void) fsleep(interval); 6393 } 6394 6395 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 6396 (void) printf(gettext("no pools available\n")); 6397 ret = 0; 6398 } 6399 6400 pool_list_free(list); 6401 zprop_free_list(cb.cb_proplist); 6402 return (ret); 6403 } 6404 6405 static int 6406 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 6407 { 6408 boolean_t force = B_FALSE; 6409 boolean_t rebuild = B_FALSE; 6410 boolean_t wait = B_FALSE; 6411 int c; 6412 nvlist_t *nvroot; 6413 char *poolname, *old_disk, *new_disk; 6414 zpool_handle_t *zhp; 6415 nvlist_t *props = NULL; 6416 char *propval; 6417 int ret; 6418 6419 /* check options */ 6420 while ((c = getopt(argc, argv, "fo:sw")) != -1) { 6421 switch (c) { 6422 case 'f': 6423 force = B_TRUE; 6424 break; 6425 case 'o': 6426 if ((propval = strchr(optarg, '=')) == NULL) { 6427 (void) fprintf(stderr, gettext("missing " 6428 "'=' for -o option\n")); 6429 usage(B_FALSE); 6430 } 6431 *propval = '\0'; 6432 propval++; 6433 6434 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 6435 (add_prop_list(optarg, propval, &props, B_TRUE))) 6436 usage(B_FALSE); 6437 break; 6438 case 's': 6439 rebuild = B_TRUE; 6440 break; 6441 case 'w': 6442 wait = B_TRUE; 6443 break; 6444 case '?': 6445 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6446 optopt); 6447 usage(B_FALSE); 6448 } 6449 } 6450 6451 argc -= optind; 6452 argv += optind; 6453 6454 /* get pool name and check number of arguments */ 6455 if (argc < 1) { 6456 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6457 usage(B_FALSE); 6458 } 6459 6460 poolname = argv[0]; 6461 6462 if (argc < 2) { 6463 (void) fprintf(stderr, 6464 gettext("missing <device> specification\n")); 6465 usage(B_FALSE); 6466 } 6467 6468 old_disk = argv[1]; 6469 6470 if (argc < 3) { 6471 if (!replacing) { 6472 (void) fprintf(stderr, 6473 gettext("missing <new_device> specification\n")); 6474 usage(B_FALSE); 6475 } 6476 new_disk = old_disk; 6477 argc -= 1; 6478 argv += 1; 6479 } else { 6480 new_disk = argv[2]; 6481 argc -= 2; 6482 argv += 2; 6483 } 6484 6485 if (argc > 1) { 6486 (void) fprintf(stderr, gettext("too many arguments\n")); 6487 usage(B_FALSE); 6488 } 6489 6490 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) { 6491 nvlist_free(props); 6492 return (1); 6493 } 6494 6495 if (zpool_get_config(zhp, NULL) == NULL) { 6496 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 6497 poolname); 6498 zpool_close(zhp); 6499 nvlist_free(props); 6500 return (1); 6501 } 6502 6503 /* unless manually specified use "ashift" pool property (if set) */ 6504 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 6505 int intval; 6506 zprop_source_t src; 6507 char strval[ZPOOL_MAXPROPLEN]; 6508 6509 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 6510 if (src != ZPROP_SRC_DEFAULT) { 6511 (void) sprintf(strval, "%" PRId32, intval); 6512 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 6513 &props, B_TRUE) == 0); 6514 } 6515 } 6516 6517 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE, 6518 argc, argv); 6519 if (nvroot == NULL) { 6520 zpool_close(zhp); 6521 nvlist_free(props); 6522 return (1); 6523 } 6524 6525 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing, 6526 rebuild); 6527 6528 if (ret == 0 && wait) 6529 ret = zpool_wait(zhp, 6530 replacing ? ZPOOL_WAIT_REPLACE : ZPOOL_WAIT_RESILVER); 6531 6532 nvlist_free(props); 6533 nvlist_free(nvroot); 6534 zpool_close(zhp); 6535 6536 return (ret); 6537 } 6538 6539 /* 6540 * zpool replace [-fsw] [-o property=value] <pool> <device> <new_device> 6541 * 6542 * -f Force attach, even if <new_device> appears to be in use. 6543 * -s Use sequential instead of healing reconstruction for resilver. 6544 * -o Set property=value. 6545 * -w Wait for replacing to complete before returning 6546 * 6547 * Replace <device> with <new_device>. 6548 */ 6549 /* ARGSUSED */ 6550 int 6551 zpool_do_replace(int argc, char **argv) 6552 { 6553 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 6554 } 6555 6556 /* 6557 * zpool attach [-fsw] [-o property=value] <pool> <device> <new_device> 6558 * 6559 * -f Force attach, even if <new_device> appears to be in use. 6560 * -s Use sequential instead of healing reconstruction for resilver. 6561 * -o Set property=value. 6562 * -w Wait for resilvering to complete before returning 6563 * 6564 * Attach <new_device> to the mirror containing <device>. If <device> is not 6565 * part of a mirror, then <device> will be transformed into a mirror of 6566 * <device> and <new_device>. In either case, <new_device> will begin life 6567 * with a DTL of [0, now], and will immediately begin to resilver itself. 6568 */ 6569 int 6570 zpool_do_attach(int argc, char **argv) 6571 { 6572 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 6573 } 6574 6575 /* 6576 * zpool detach [-f] <pool> <device> 6577 * 6578 * -f Force detach of <device>, even if DTLs argue against it 6579 * (not supported yet) 6580 * 6581 * Detach a device from a mirror. The operation will be refused if <device> 6582 * is the last device in the mirror, or if the DTLs indicate that this device 6583 * has the only valid copy of some data. 6584 */ 6585 /* ARGSUSED */ 6586 int 6587 zpool_do_detach(int argc, char **argv) 6588 { 6589 int c; 6590 char *poolname, *path; 6591 zpool_handle_t *zhp; 6592 int ret; 6593 6594 /* check options */ 6595 while ((c = getopt(argc, argv, "")) != -1) { 6596 switch (c) { 6597 case '?': 6598 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6599 optopt); 6600 usage(B_FALSE); 6601 } 6602 } 6603 6604 argc -= optind; 6605 argv += optind; 6606 6607 /* get pool name and check number of arguments */ 6608 if (argc < 1) { 6609 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6610 usage(B_FALSE); 6611 } 6612 6613 if (argc < 2) { 6614 (void) fprintf(stderr, 6615 gettext("missing <device> specification\n")); 6616 usage(B_FALSE); 6617 } 6618 6619 poolname = argv[0]; 6620 path = argv[1]; 6621 6622 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6623 return (1); 6624 6625 ret = zpool_vdev_detach(zhp, path); 6626 6627 zpool_close(zhp); 6628 6629 return (ret); 6630 } 6631 6632 /* 6633 * zpool split [-gLnP] [-o prop=val] ... 6634 * [-o mntopt] ... 6635 * [-R altroot] <pool> <newpool> [<device> ...] 6636 * 6637 * -g Display guid for individual vdev name. 6638 * -L Follow links when resolving vdev path name. 6639 * -n Do not split the pool, but display the resulting layout if 6640 * it were to be split. 6641 * -o Set property=value, or set mount options. 6642 * -P Display full path for vdev name. 6643 * -R Mount the split-off pool under an alternate root. 6644 * -l Load encryption keys while importing. 6645 * 6646 * Splits the named pool and gives it the new pool name. Devices to be split 6647 * off may be listed, provided that no more than one device is specified 6648 * per top-level vdev mirror. The newly split pool is left in an exported 6649 * state unless -R is specified. 6650 * 6651 * Restrictions: the top-level of the pool pool must only be made up of 6652 * mirrors; all devices in the pool must be healthy; no device may be 6653 * undergoing a resilvering operation. 6654 */ 6655 int 6656 zpool_do_split(int argc, char **argv) 6657 { 6658 char *srcpool, *newpool, *propval; 6659 char *mntopts = NULL; 6660 splitflags_t flags; 6661 int c, ret = 0; 6662 boolean_t loadkeys = B_FALSE; 6663 zpool_handle_t *zhp; 6664 nvlist_t *config, *props = NULL; 6665 6666 flags.dryrun = B_FALSE; 6667 flags.import = B_FALSE; 6668 flags.name_flags = 0; 6669 6670 /* check options */ 6671 while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) { 6672 switch (c) { 6673 case 'g': 6674 flags.name_flags |= VDEV_NAME_GUID; 6675 break; 6676 case 'L': 6677 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS; 6678 break; 6679 case 'R': 6680 flags.import = B_TRUE; 6681 if (add_prop_list( 6682 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 6683 &props, B_TRUE) != 0) { 6684 nvlist_free(props); 6685 usage(B_FALSE); 6686 } 6687 break; 6688 case 'l': 6689 loadkeys = B_TRUE; 6690 break; 6691 case 'n': 6692 flags.dryrun = B_TRUE; 6693 break; 6694 case 'o': 6695 if ((propval = strchr(optarg, '=')) != NULL) { 6696 *propval = '\0'; 6697 propval++; 6698 if (add_prop_list(optarg, propval, 6699 &props, B_TRUE) != 0) { 6700 nvlist_free(props); 6701 usage(B_FALSE); 6702 } 6703 } else { 6704 mntopts = optarg; 6705 } 6706 break; 6707 case 'P': 6708 flags.name_flags |= VDEV_NAME_PATH; 6709 break; 6710 case ':': 6711 (void) fprintf(stderr, gettext("missing argument for " 6712 "'%c' option\n"), optopt); 6713 usage(B_FALSE); 6714 break; 6715 case '?': 6716 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6717 optopt); 6718 usage(B_FALSE); 6719 break; 6720 } 6721 } 6722 6723 if (!flags.import && mntopts != NULL) { 6724 (void) fprintf(stderr, gettext("setting mntopts is only " 6725 "valid when importing the pool\n")); 6726 usage(B_FALSE); 6727 } 6728 6729 if (!flags.import && loadkeys) { 6730 (void) fprintf(stderr, gettext("loading keys is only " 6731 "valid when importing the pool\n")); 6732 usage(B_FALSE); 6733 } 6734 6735 argc -= optind; 6736 argv += optind; 6737 6738 if (argc < 1) { 6739 (void) fprintf(stderr, gettext("Missing pool name\n")); 6740 usage(B_FALSE); 6741 } 6742 if (argc < 2) { 6743 (void) fprintf(stderr, gettext("Missing new pool name\n")); 6744 usage(B_FALSE); 6745 } 6746 6747 srcpool = argv[0]; 6748 newpool = argv[1]; 6749 6750 argc -= 2; 6751 argv += 2; 6752 6753 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) { 6754 nvlist_free(props); 6755 return (1); 6756 } 6757 6758 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 6759 if (config == NULL) { 6760 ret = 1; 6761 } else { 6762 if (flags.dryrun) { 6763 (void) printf(gettext("would create '%s' with the " 6764 "following layout:\n\n"), newpool); 6765 print_vdev_tree(NULL, newpool, config, 0, "", 6766 flags.name_flags); 6767 print_vdev_tree(NULL, "dedup", config, 0, 6768 VDEV_ALLOC_BIAS_DEDUP, 0); 6769 print_vdev_tree(NULL, "special", config, 0, 6770 VDEV_ALLOC_BIAS_SPECIAL, 0); 6771 } 6772 } 6773 6774 zpool_close(zhp); 6775 6776 if (ret != 0 || flags.dryrun || !flags.import) { 6777 nvlist_free(config); 6778 nvlist_free(props); 6779 return (ret); 6780 } 6781 6782 /* 6783 * The split was successful. Now we need to open the new 6784 * pool and import it. 6785 */ 6786 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) { 6787 nvlist_free(config); 6788 nvlist_free(props); 6789 return (1); 6790 } 6791 6792 if (loadkeys) { 6793 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool); 6794 if (ret != 0) 6795 ret = 1; 6796 } 6797 6798 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 6799 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 6800 ret = 1; 6801 (void) fprintf(stderr, gettext("Split was successful, but " 6802 "the datasets could not all be mounted\n")); 6803 (void) fprintf(stderr, gettext("Try doing '%s' with a " 6804 "different altroot\n"), "zpool import"); 6805 } 6806 zpool_close(zhp); 6807 nvlist_free(config); 6808 nvlist_free(props); 6809 6810 return (ret); 6811 } 6812 6813 6814 6815 /* 6816 * zpool online <pool> <device> ... 6817 */ 6818 int 6819 zpool_do_online(int argc, char **argv) 6820 { 6821 int c, i; 6822 char *poolname; 6823 zpool_handle_t *zhp; 6824 int ret = 0; 6825 vdev_state_t newstate; 6826 int flags = 0; 6827 6828 /* check options */ 6829 while ((c = getopt(argc, argv, "e")) != -1) { 6830 switch (c) { 6831 case 'e': 6832 flags |= ZFS_ONLINE_EXPAND; 6833 break; 6834 case '?': 6835 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6836 optopt); 6837 usage(B_FALSE); 6838 } 6839 } 6840 6841 argc -= optind; 6842 argv += optind; 6843 6844 /* get pool name and check number of arguments */ 6845 if (argc < 1) { 6846 (void) fprintf(stderr, gettext("missing pool name\n")); 6847 usage(B_FALSE); 6848 } 6849 if (argc < 2) { 6850 (void) fprintf(stderr, gettext("missing device name\n")); 6851 usage(B_FALSE); 6852 } 6853 6854 poolname = argv[0]; 6855 6856 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6857 return (1); 6858 6859 for (i = 1; i < argc; i++) { 6860 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 6861 if (newstate != VDEV_STATE_HEALTHY) { 6862 (void) printf(gettext("warning: device '%s' " 6863 "onlined, but remains in faulted state\n"), 6864 argv[i]); 6865 if (newstate == VDEV_STATE_FAULTED) 6866 (void) printf(gettext("use 'zpool " 6867 "clear' to restore a faulted " 6868 "device\n")); 6869 else 6870 (void) printf(gettext("use 'zpool " 6871 "replace' to replace devices " 6872 "that are no longer present\n")); 6873 } 6874 } else { 6875 ret = 1; 6876 } 6877 } 6878 6879 zpool_close(zhp); 6880 6881 return (ret); 6882 } 6883 6884 /* 6885 * zpool offline [-ft] <pool> <device> ... 6886 * 6887 * -f Force the device into a faulted state. 6888 * 6889 * -t Only take the device off-line temporarily. The offline/faulted 6890 * state will not be persistent across reboots. 6891 */ 6892 /* ARGSUSED */ 6893 int 6894 zpool_do_offline(int argc, char **argv) 6895 { 6896 int c, i; 6897 char *poolname; 6898 zpool_handle_t *zhp; 6899 int ret = 0; 6900 boolean_t istmp = B_FALSE; 6901 boolean_t fault = B_FALSE; 6902 6903 /* check options */ 6904 while ((c = getopt(argc, argv, "ft")) != -1) { 6905 switch (c) { 6906 case 'f': 6907 fault = B_TRUE; 6908 break; 6909 case 't': 6910 istmp = B_TRUE; 6911 break; 6912 case '?': 6913 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6914 optopt); 6915 usage(B_FALSE); 6916 } 6917 } 6918 6919 argc -= optind; 6920 argv += optind; 6921 6922 /* get pool name and check number of arguments */ 6923 if (argc < 1) { 6924 (void) fprintf(stderr, gettext("missing pool name\n")); 6925 usage(B_FALSE); 6926 } 6927 if (argc < 2) { 6928 (void) fprintf(stderr, gettext("missing device name\n")); 6929 usage(B_FALSE); 6930 } 6931 6932 poolname = argv[0]; 6933 6934 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6935 return (1); 6936 6937 for (i = 1; i < argc; i++) { 6938 if (fault) { 6939 uint64_t guid = zpool_vdev_path_to_guid(zhp, argv[i]); 6940 vdev_aux_t aux; 6941 if (istmp == B_FALSE) { 6942 /* Force the fault to persist across imports */ 6943 aux = VDEV_AUX_EXTERNAL_PERSIST; 6944 } else { 6945 aux = VDEV_AUX_EXTERNAL; 6946 } 6947 6948 if (guid == 0 || zpool_vdev_fault(zhp, guid, aux) != 0) 6949 ret = 1; 6950 } else { 6951 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 6952 ret = 1; 6953 } 6954 } 6955 6956 zpool_close(zhp); 6957 6958 return (ret); 6959 } 6960 6961 /* 6962 * zpool clear <pool> [device] 6963 * 6964 * Clear all errors associated with a pool or a particular device. 6965 */ 6966 int 6967 zpool_do_clear(int argc, char **argv) 6968 { 6969 int c; 6970 int ret = 0; 6971 boolean_t dryrun = B_FALSE; 6972 boolean_t do_rewind = B_FALSE; 6973 boolean_t xtreme_rewind = B_FALSE; 6974 uint32_t rewind_policy = ZPOOL_NO_REWIND; 6975 nvlist_t *policy = NULL; 6976 zpool_handle_t *zhp; 6977 char *pool, *device; 6978 6979 /* check options */ 6980 while ((c = getopt(argc, argv, "FnX")) != -1) { 6981 switch (c) { 6982 case 'F': 6983 do_rewind = B_TRUE; 6984 break; 6985 case 'n': 6986 dryrun = B_TRUE; 6987 break; 6988 case 'X': 6989 xtreme_rewind = B_TRUE; 6990 break; 6991 case '?': 6992 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6993 optopt); 6994 usage(B_FALSE); 6995 } 6996 } 6997 6998 argc -= optind; 6999 argv += optind; 7000 7001 if (argc < 1) { 7002 (void) fprintf(stderr, gettext("missing pool name\n")); 7003 usage(B_FALSE); 7004 } 7005 7006 if (argc > 2) { 7007 (void) fprintf(stderr, gettext("too many arguments\n")); 7008 usage(B_FALSE); 7009 } 7010 7011 if ((dryrun || xtreme_rewind) && !do_rewind) { 7012 (void) fprintf(stderr, 7013 gettext("-n or -X only meaningful with -F\n")); 7014 usage(B_FALSE); 7015 } 7016 if (dryrun) 7017 rewind_policy = ZPOOL_TRY_REWIND; 7018 else if (do_rewind) 7019 rewind_policy = ZPOOL_DO_REWIND; 7020 if (xtreme_rewind) 7021 rewind_policy |= ZPOOL_EXTREME_REWIND; 7022 7023 /* In future, further rewind policy choices can be passed along here */ 7024 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 7025 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 7026 rewind_policy) != 0) { 7027 return (1); 7028 } 7029 7030 pool = argv[0]; 7031 device = argc == 2 ? argv[1] : NULL; 7032 7033 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 7034 nvlist_free(policy); 7035 return (1); 7036 } 7037 7038 if (zpool_clear(zhp, device, policy) != 0) 7039 ret = 1; 7040 7041 zpool_close(zhp); 7042 7043 nvlist_free(policy); 7044 7045 return (ret); 7046 } 7047 7048 /* 7049 * zpool reguid <pool> 7050 */ 7051 int 7052 zpool_do_reguid(int argc, char **argv) 7053 { 7054 int c; 7055 char *poolname; 7056 zpool_handle_t *zhp; 7057 int ret = 0; 7058 7059 /* check options */ 7060 while ((c = getopt(argc, argv, "")) != -1) { 7061 switch (c) { 7062 case '?': 7063 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7064 optopt); 7065 usage(B_FALSE); 7066 } 7067 } 7068 7069 argc -= optind; 7070 argv += optind; 7071 7072 /* get pool name and check number of arguments */ 7073 if (argc < 1) { 7074 (void) fprintf(stderr, gettext("missing pool name\n")); 7075 usage(B_FALSE); 7076 } 7077 7078 if (argc > 1) { 7079 (void) fprintf(stderr, gettext("too many arguments\n")); 7080 usage(B_FALSE); 7081 } 7082 7083 poolname = argv[0]; 7084 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 7085 return (1); 7086 7087 ret = zpool_reguid(zhp); 7088 7089 zpool_close(zhp); 7090 return (ret); 7091 } 7092 7093 7094 /* 7095 * zpool reopen <pool> 7096 * 7097 * Reopen the pool so that the kernel can update the sizes of all vdevs. 7098 */ 7099 int 7100 zpool_do_reopen(int argc, char **argv) 7101 { 7102 int c; 7103 int ret = 0; 7104 boolean_t scrub_restart = B_TRUE; 7105 7106 /* check options */ 7107 while ((c = getopt(argc, argv, "n")) != -1) { 7108 switch (c) { 7109 case 'n': 7110 scrub_restart = B_FALSE; 7111 break; 7112 case '?': 7113 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7114 optopt); 7115 usage(B_FALSE); 7116 } 7117 } 7118 7119 argc -= optind; 7120 argv += optind; 7121 7122 /* if argc == 0 we will execute zpool_reopen_one on all pools */ 7123 ret = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, zpool_reopen_one, 7124 &scrub_restart); 7125 7126 return (ret); 7127 } 7128 7129 typedef struct scrub_cbdata { 7130 int cb_type; 7131 pool_scrub_cmd_t cb_scrub_cmd; 7132 } scrub_cbdata_t; 7133 7134 static boolean_t 7135 zpool_has_checkpoint(zpool_handle_t *zhp) 7136 { 7137 nvlist_t *config, *nvroot; 7138 7139 config = zpool_get_config(zhp, NULL); 7140 7141 if (config != NULL) { 7142 pool_checkpoint_stat_t *pcs = NULL; 7143 uint_t c; 7144 7145 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 7146 (void) nvlist_lookup_uint64_array(nvroot, 7147 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7148 7149 if (pcs == NULL || pcs->pcs_state == CS_NONE) 7150 return (B_FALSE); 7151 7152 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS || 7153 pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 7154 return (B_TRUE); 7155 } 7156 7157 return (B_FALSE); 7158 } 7159 7160 static int 7161 scrub_callback(zpool_handle_t *zhp, void *data) 7162 { 7163 scrub_cbdata_t *cb = data; 7164 int err; 7165 7166 /* 7167 * Ignore faulted pools. 7168 */ 7169 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 7170 (void) fprintf(stderr, gettext("cannot scan '%s': pool is " 7171 "currently unavailable\n"), zpool_get_name(zhp)); 7172 return (1); 7173 } 7174 7175 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 7176 7177 if (err == 0 && zpool_has_checkpoint(zhp) && 7178 cb->cb_type == POOL_SCAN_SCRUB) { 7179 (void) printf(gettext("warning: will not scrub state that " 7180 "belongs to the checkpoint of pool '%s'\n"), 7181 zpool_get_name(zhp)); 7182 } 7183 7184 return (err != 0); 7185 } 7186 7187 static int 7188 wait_callback(zpool_handle_t *zhp, void *data) 7189 { 7190 zpool_wait_activity_t *act = data; 7191 return (zpool_wait(zhp, *act)); 7192 } 7193 7194 /* 7195 * zpool scrub [-s | -p] [-w] <pool> ... 7196 * 7197 * -s Stop. Stops any in-progress scrub. 7198 * -p Pause. Pause in-progress scrub. 7199 * -w Wait. Blocks until scrub has completed. 7200 */ 7201 int 7202 zpool_do_scrub(int argc, char **argv) 7203 { 7204 int c; 7205 scrub_cbdata_t cb; 7206 boolean_t wait = B_FALSE; 7207 int error; 7208 7209 cb.cb_type = POOL_SCAN_SCRUB; 7210 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 7211 7212 /* check options */ 7213 while ((c = getopt(argc, argv, "spw")) != -1) { 7214 switch (c) { 7215 case 's': 7216 cb.cb_type = POOL_SCAN_NONE; 7217 break; 7218 case 'p': 7219 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 7220 break; 7221 case 'w': 7222 wait = B_TRUE; 7223 break; 7224 case '?': 7225 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7226 optopt); 7227 usage(B_FALSE); 7228 } 7229 } 7230 7231 if (cb.cb_type == POOL_SCAN_NONE && 7232 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 7233 (void) fprintf(stderr, gettext("invalid option combination: " 7234 "-s and -p are mutually exclusive\n")); 7235 usage(B_FALSE); 7236 } 7237 7238 if (wait && (cb.cb_type == POOL_SCAN_NONE || 7239 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE)) { 7240 (void) fprintf(stderr, gettext("invalid option combination: " 7241 "-w cannot be used with -p or -s\n")); 7242 usage(B_FALSE); 7243 } 7244 7245 argc -= optind; 7246 argv += optind; 7247 7248 if (argc < 1) { 7249 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7250 usage(B_FALSE); 7251 } 7252 7253 error = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7254 scrub_callback, &cb); 7255 7256 if (wait && !error) { 7257 zpool_wait_activity_t act = ZPOOL_WAIT_SCRUB; 7258 error = for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7259 wait_callback, &act); 7260 } 7261 7262 return (error); 7263 } 7264 7265 /* 7266 * zpool resilver <pool> ... 7267 * 7268 * Restarts any in-progress resilver 7269 */ 7270 int 7271 zpool_do_resilver(int argc, char **argv) 7272 { 7273 int c; 7274 scrub_cbdata_t cb; 7275 7276 cb.cb_type = POOL_SCAN_RESILVER; 7277 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 7278 7279 /* check options */ 7280 while ((c = getopt(argc, argv, "")) != -1) { 7281 switch (c) { 7282 case '?': 7283 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7284 optopt); 7285 usage(B_FALSE); 7286 } 7287 } 7288 7289 argc -= optind; 7290 argv += optind; 7291 7292 if (argc < 1) { 7293 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7294 usage(B_FALSE); 7295 } 7296 7297 return (for_each_pool(argc, argv, B_TRUE, NULL, B_FALSE, 7298 scrub_callback, &cb)); 7299 } 7300 7301 /* 7302 * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...] 7303 * 7304 * -c Cancel. Ends any in-progress trim. 7305 * -d Secure trim. Requires kernel and device support. 7306 * -r <rate> Sets the TRIM rate in bytes (per second). Supports 7307 * adding a multiplier suffix such as 'k' or 'm'. 7308 * -s Suspend. TRIM can then be restarted with no flags. 7309 * -w Wait. Blocks until trimming has completed. 7310 */ 7311 int 7312 zpool_do_trim(int argc, char **argv) 7313 { 7314 struct option long_options[] = { 7315 {"cancel", no_argument, NULL, 'c'}, 7316 {"secure", no_argument, NULL, 'd'}, 7317 {"rate", required_argument, NULL, 'r'}, 7318 {"suspend", no_argument, NULL, 's'}, 7319 {"wait", no_argument, NULL, 'w'}, 7320 {0, 0, 0, 0} 7321 }; 7322 7323 pool_trim_func_t cmd_type = POOL_TRIM_START; 7324 uint64_t rate = 0; 7325 boolean_t secure = B_FALSE; 7326 boolean_t wait = B_FALSE; 7327 7328 int c; 7329 while ((c = getopt_long(argc, argv, "cdr:sw", long_options, NULL)) 7330 != -1) { 7331 switch (c) { 7332 case 'c': 7333 if (cmd_type != POOL_TRIM_START && 7334 cmd_type != POOL_TRIM_CANCEL) { 7335 (void) fprintf(stderr, gettext("-c cannot be " 7336 "combined with other options\n")); 7337 usage(B_FALSE); 7338 } 7339 cmd_type = POOL_TRIM_CANCEL; 7340 break; 7341 case 'd': 7342 if (cmd_type != POOL_TRIM_START) { 7343 (void) fprintf(stderr, gettext("-d cannot be " 7344 "combined with the -c or -s options\n")); 7345 usage(B_FALSE); 7346 } 7347 secure = B_TRUE; 7348 break; 7349 case 'r': 7350 if (cmd_type != POOL_TRIM_START) { 7351 (void) fprintf(stderr, gettext("-r cannot be " 7352 "combined with the -c or -s options\n")); 7353 usage(B_FALSE); 7354 } 7355 if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) { 7356 (void) fprintf(stderr, 7357 gettext("invalid value for rate\n")); 7358 usage(B_FALSE); 7359 } 7360 break; 7361 case 's': 7362 if (cmd_type != POOL_TRIM_START && 7363 cmd_type != POOL_TRIM_SUSPEND) { 7364 (void) fprintf(stderr, gettext("-s cannot be " 7365 "combined with other options\n")); 7366 usage(B_FALSE); 7367 } 7368 cmd_type = POOL_TRIM_SUSPEND; 7369 break; 7370 case 'w': 7371 wait = B_TRUE; 7372 break; 7373 case '?': 7374 if (optopt != 0) { 7375 (void) fprintf(stderr, 7376 gettext("invalid option '%c'\n"), optopt); 7377 } else { 7378 (void) fprintf(stderr, 7379 gettext("invalid option '%s'\n"), 7380 argv[optind - 1]); 7381 } 7382 usage(B_FALSE); 7383 } 7384 } 7385 7386 argc -= optind; 7387 argv += optind; 7388 7389 if (argc < 1) { 7390 (void) fprintf(stderr, gettext("missing pool name argument\n")); 7391 usage(B_FALSE); 7392 return (-1); 7393 } 7394 7395 if (wait && (cmd_type != POOL_TRIM_START)) { 7396 (void) fprintf(stderr, gettext("-w cannot be used with -c or " 7397 "-s\n")); 7398 usage(B_FALSE); 7399 } 7400 7401 char *poolname = argv[0]; 7402 zpool_handle_t *zhp = zpool_open(g_zfs, poolname); 7403 if (zhp == NULL) 7404 return (-1); 7405 7406 trimflags_t trim_flags = { 7407 .secure = secure, 7408 .rate = rate, 7409 .wait = wait, 7410 }; 7411 7412 nvlist_t *vdevs = fnvlist_alloc(); 7413 if (argc == 1) { 7414 /* no individual leaf vdevs specified, so add them all */ 7415 nvlist_t *config = zpool_get_config(zhp, NULL); 7416 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 7417 ZPOOL_CONFIG_VDEV_TREE); 7418 zpool_collect_leaves(zhp, nvroot, vdevs); 7419 trim_flags.fullpool = B_TRUE; 7420 } else { 7421 trim_flags.fullpool = B_FALSE; 7422 for (int i = 1; i < argc; i++) { 7423 fnvlist_add_boolean(vdevs, argv[i]); 7424 } 7425 } 7426 7427 int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags); 7428 7429 fnvlist_free(vdevs); 7430 zpool_close(zhp); 7431 7432 return (error); 7433 } 7434 7435 /* 7436 * Converts a total number of seconds to a human readable string broken 7437 * down in to days/hours/minutes/seconds. 7438 */ 7439 static void 7440 secs_to_dhms(uint64_t total, char *buf) 7441 { 7442 uint64_t days = total / 60 / 60 / 24; 7443 uint64_t hours = (total / 60 / 60) % 24; 7444 uint64_t mins = (total / 60) % 60; 7445 uint64_t secs = (total % 60); 7446 7447 if (days > 0) { 7448 (void) sprintf(buf, "%llu days %02llu:%02llu:%02llu", 7449 (u_longlong_t)days, (u_longlong_t)hours, 7450 (u_longlong_t)mins, (u_longlong_t)secs); 7451 } else { 7452 (void) sprintf(buf, "%02llu:%02llu:%02llu", 7453 (u_longlong_t)hours, (u_longlong_t)mins, 7454 (u_longlong_t)secs); 7455 } 7456 } 7457 7458 /* 7459 * Print out detailed scrub status. 7460 */ 7461 static void 7462 print_scan_scrub_resilver_status(pool_scan_stat_t *ps) 7463 { 7464 time_t start, end, pause; 7465 uint64_t pass_scanned, scanned, pass_issued, issued, total; 7466 uint64_t elapsed, scan_rate, issue_rate; 7467 double fraction_done; 7468 char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7]; 7469 char srate_buf[7], irate_buf[7], time_buf[32]; 7470 7471 printf(" "); 7472 printf_color(ANSI_BOLD, gettext("scan:")); 7473 printf(" "); 7474 7475 /* If there's never been a scan, there's not much to say. */ 7476 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 7477 ps->pss_func >= POOL_SCAN_FUNCS) { 7478 (void) printf(gettext("none requested\n")); 7479 return; 7480 } 7481 7482 start = ps->pss_start_time; 7483 end = ps->pss_end_time; 7484 pause = ps->pss_pass_scrub_pause; 7485 7486 zfs_nicebytes(ps->pss_processed, processed_buf, sizeof (processed_buf)); 7487 7488 assert(ps->pss_func == POOL_SCAN_SCRUB || 7489 ps->pss_func == POOL_SCAN_RESILVER); 7490 7491 /* Scan is finished or canceled. */ 7492 if (ps->pss_state == DSS_FINISHED) { 7493 secs_to_dhms(end - start, time_buf); 7494 7495 if (ps->pss_func == POOL_SCAN_SCRUB) { 7496 (void) printf(gettext("scrub repaired %s " 7497 "in %s with %llu errors on %s"), processed_buf, 7498 time_buf, (u_longlong_t)ps->pss_errors, 7499 ctime(&end)); 7500 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7501 (void) printf(gettext("resilvered %s " 7502 "in %s with %llu errors on %s"), processed_buf, 7503 time_buf, (u_longlong_t)ps->pss_errors, 7504 ctime(&end)); 7505 } 7506 return; 7507 } else if (ps->pss_state == DSS_CANCELED) { 7508 if (ps->pss_func == POOL_SCAN_SCRUB) { 7509 (void) printf(gettext("scrub canceled on %s"), 7510 ctime(&end)); 7511 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7512 (void) printf(gettext("resilver canceled on %s"), 7513 ctime(&end)); 7514 } 7515 return; 7516 } 7517 7518 assert(ps->pss_state == DSS_SCANNING); 7519 7520 /* Scan is in progress. Resilvers can't be paused. */ 7521 if (ps->pss_func == POOL_SCAN_SCRUB) { 7522 if (pause == 0) { 7523 (void) printf(gettext("scrub in progress since %s"), 7524 ctime(&start)); 7525 } else { 7526 (void) printf(gettext("scrub paused since %s"), 7527 ctime(&pause)); 7528 (void) printf(gettext("\tscrub started on %s"), 7529 ctime(&start)); 7530 } 7531 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 7532 (void) printf(gettext("resilver in progress since %s"), 7533 ctime(&start)); 7534 } 7535 7536 scanned = ps->pss_examined; 7537 pass_scanned = ps->pss_pass_exam; 7538 issued = ps->pss_issued; 7539 pass_issued = ps->pss_pass_issued; 7540 total = ps->pss_to_examine; 7541 7542 /* we are only done with a block once we have issued the IO for it */ 7543 fraction_done = (double)issued / total; 7544 7545 /* elapsed time for this pass, rounding up to 1 if it's 0 */ 7546 elapsed = time(NULL) - ps->pss_pass_start; 7547 elapsed -= ps->pss_pass_scrub_spent_paused; 7548 elapsed = (elapsed != 0) ? elapsed : 1; 7549 7550 scan_rate = pass_scanned / elapsed; 7551 issue_rate = pass_issued / elapsed; 7552 uint64_t total_secs_left = (issue_rate != 0 && total >= issued) ? 7553 ((total - issued) / issue_rate) : UINT64_MAX; 7554 secs_to_dhms(total_secs_left, time_buf); 7555 7556 /* format all of the numbers we will be reporting */ 7557 zfs_nicebytes(scanned, scanned_buf, sizeof (scanned_buf)); 7558 zfs_nicebytes(issued, issued_buf, sizeof (issued_buf)); 7559 zfs_nicebytes(total, total_buf, sizeof (total_buf)); 7560 zfs_nicebytes(scan_rate, srate_buf, sizeof (srate_buf)); 7561 zfs_nicebytes(issue_rate, irate_buf, sizeof (irate_buf)); 7562 7563 /* do not print estimated time if we have a paused scrub */ 7564 if (pause == 0) { 7565 (void) printf(gettext("\t%s scanned at %s/s, " 7566 "%s issued at %s/s, %s total\n"), 7567 scanned_buf, srate_buf, issued_buf, irate_buf, total_buf); 7568 } else { 7569 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"), 7570 scanned_buf, issued_buf, total_buf); 7571 } 7572 7573 if (ps->pss_func == POOL_SCAN_RESILVER) { 7574 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 7575 processed_buf, 100 * fraction_done); 7576 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 7577 (void) printf(gettext("\t%s repaired, %.2f%% done"), 7578 processed_buf, 100 * fraction_done); 7579 } 7580 7581 if (pause == 0) { 7582 if (total_secs_left != UINT64_MAX && 7583 issue_rate >= 10 * 1024 * 1024) { 7584 (void) printf(gettext(", %s to go\n"), time_buf); 7585 } else { 7586 (void) printf(gettext(", no estimated " 7587 "completion time\n")); 7588 } 7589 } else { 7590 (void) printf(gettext("\n")); 7591 } 7592 } 7593 7594 static void 7595 print_rebuild_status_impl(vdev_rebuild_stat_t *vrs, char *vdev_name) 7596 { 7597 if (vrs == NULL || vrs->vrs_state == VDEV_REBUILD_NONE) 7598 return; 7599 7600 printf(" "); 7601 printf_color(ANSI_BOLD, gettext("scan:")); 7602 printf(" "); 7603 7604 uint64_t bytes_scanned = vrs->vrs_bytes_scanned; 7605 uint64_t bytes_issued = vrs->vrs_bytes_issued; 7606 uint64_t bytes_rebuilt = vrs->vrs_bytes_rebuilt; 7607 uint64_t bytes_est = vrs->vrs_bytes_est; 7608 uint64_t scan_rate = (vrs->vrs_pass_bytes_scanned / 7609 (vrs->vrs_pass_time_ms + 1)) * 1000; 7610 uint64_t issue_rate = (vrs->vrs_pass_bytes_issued / 7611 (vrs->vrs_pass_time_ms + 1)) * 1000; 7612 double scan_pct = MIN((double)bytes_scanned * 100 / 7613 (bytes_est + 1), 100); 7614 7615 /* Format all of the numbers we will be reporting */ 7616 char bytes_scanned_buf[7], bytes_issued_buf[7]; 7617 char bytes_rebuilt_buf[7], bytes_est_buf[7]; 7618 char scan_rate_buf[7], issue_rate_buf[7], time_buf[32]; 7619 zfs_nicebytes(bytes_scanned, bytes_scanned_buf, 7620 sizeof (bytes_scanned_buf)); 7621 zfs_nicebytes(bytes_issued, bytes_issued_buf, 7622 sizeof (bytes_issued_buf)); 7623 zfs_nicebytes(bytes_rebuilt, bytes_rebuilt_buf, 7624 sizeof (bytes_rebuilt_buf)); 7625 zfs_nicebytes(bytes_est, bytes_est_buf, sizeof (bytes_est_buf)); 7626 zfs_nicebytes(scan_rate, scan_rate_buf, sizeof (scan_rate_buf)); 7627 zfs_nicebytes(issue_rate, issue_rate_buf, sizeof (issue_rate_buf)); 7628 7629 time_t start = vrs->vrs_start_time; 7630 time_t end = vrs->vrs_end_time; 7631 7632 /* Rebuild is finished or canceled. */ 7633 if (vrs->vrs_state == VDEV_REBUILD_COMPLETE) { 7634 secs_to_dhms(vrs->vrs_scan_time_ms / 1000, time_buf); 7635 (void) printf(gettext("resilvered (%s) %s in %s " 7636 "with %llu errors on %s"), vdev_name, bytes_rebuilt_buf, 7637 time_buf, (u_longlong_t)vrs->vrs_errors, ctime(&end)); 7638 return; 7639 } else if (vrs->vrs_state == VDEV_REBUILD_CANCELED) { 7640 (void) printf(gettext("resilver (%s) canceled on %s"), 7641 vdev_name, ctime(&end)); 7642 return; 7643 } else if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7644 (void) printf(gettext("resilver (%s) in progress since %s"), 7645 vdev_name, ctime(&start)); 7646 } 7647 7648 assert(vrs->vrs_state == VDEV_REBUILD_ACTIVE); 7649 7650 secs_to_dhms(MAX((int64_t)bytes_est - (int64_t)bytes_scanned, 0) / 7651 MAX(scan_rate, 1), time_buf); 7652 7653 (void) printf(gettext("\t%s scanned at %s/s, %s issued %s/s, " 7654 "%s total\n"), bytes_scanned_buf, scan_rate_buf, 7655 bytes_issued_buf, issue_rate_buf, bytes_est_buf); 7656 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 7657 bytes_rebuilt_buf, scan_pct); 7658 7659 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7660 if (scan_rate >= 10 * 1024 * 1024) { 7661 (void) printf(gettext(", %s to go\n"), time_buf); 7662 } else { 7663 (void) printf(gettext(", no estimated " 7664 "completion time\n")); 7665 } 7666 } else { 7667 (void) printf(gettext("\n")); 7668 } 7669 } 7670 7671 /* 7672 * Print rebuild status for top-level vdevs. 7673 */ 7674 static void 7675 print_rebuild_status(zpool_handle_t *zhp, nvlist_t *nvroot) 7676 { 7677 nvlist_t **child; 7678 uint_t children; 7679 7680 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7681 &child, &children) != 0) 7682 children = 0; 7683 7684 for (uint_t c = 0; c < children; c++) { 7685 vdev_rebuild_stat_t *vrs; 7686 uint_t i; 7687 7688 if (nvlist_lookup_uint64_array(child[c], 7689 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) { 7690 char *name = zpool_vdev_name(g_zfs, zhp, 7691 child[c], VDEV_NAME_TYPE_ID); 7692 print_rebuild_status_impl(vrs, name); 7693 free(name); 7694 } 7695 } 7696 } 7697 7698 /* 7699 * As we don't scrub checkpointed blocks, we want to warn the user that we 7700 * skipped scanning some blocks if a checkpoint exists or existed at any 7701 * time during the scan. If a sequential instead of healing reconstruction 7702 * was performed then the blocks were reconstructed. However, their checksums 7703 * have not been verified so we still print the warning. 7704 */ 7705 static void 7706 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs) 7707 { 7708 if (ps == NULL || pcs == NULL) 7709 return; 7710 7711 if (pcs->pcs_state == CS_NONE || 7712 pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 7713 return; 7714 7715 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS); 7716 7717 if (ps->pss_state == DSS_NONE) 7718 return; 7719 7720 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) && 7721 ps->pss_end_time < pcs->pcs_start_time) 7722 return; 7723 7724 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) { 7725 (void) printf(gettext(" scan warning: skipped blocks " 7726 "that are only referenced by the checkpoint.\n")); 7727 } else { 7728 assert(ps->pss_state == DSS_SCANNING); 7729 (void) printf(gettext(" scan warning: skipping blocks " 7730 "that are only referenced by the checkpoint.\n")); 7731 } 7732 } 7733 7734 /* 7735 * Returns B_TRUE if there is an active rebuild in progress. Otherwise, 7736 * B_FALSE is returned and 'rebuild_end_time' is set to the end time for 7737 * the last completed (or cancelled) rebuild. 7738 */ 7739 static boolean_t 7740 check_rebuilding(nvlist_t *nvroot, uint64_t *rebuild_end_time) 7741 { 7742 nvlist_t **child; 7743 uint_t children; 7744 boolean_t rebuilding = B_FALSE; 7745 uint64_t end_time = 0; 7746 7747 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7748 &child, &children) != 0) 7749 children = 0; 7750 7751 for (uint_t c = 0; c < children; c++) { 7752 vdev_rebuild_stat_t *vrs; 7753 uint_t i; 7754 7755 if (nvlist_lookup_uint64_array(child[c], 7756 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i) == 0) { 7757 7758 if (vrs->vrs_end_time > end_time) 7759 end_time = vrs->vrs_end_time; 7760 7761 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 7762 rebuilding = B_TRUE; 7763 end_time = 0; 7764 break; 7765 } 7766 } 7767 } 7768 7769 if (rebuild_end_time != NULL) 7770 *rebuild_end_time = end_time; 7771 7772 return (rebuilding); 7773 } 7774 7775 /* 7776 * Print the scan status. 7777 */ 7778 static void 7779 print_scan_status(zpool_handle_t *zhp, nvlist_t *nvroot) 7780 { 7781 uint64_t rebuild_end_time = 0, resilver_end_time = 0; 7782 boolean_t have_resilver = B_FALSE, have_scrub = B_FALSE; 7783 boolean_t active_resilver = B_FALSE; 7784 pool_checkpoint_stat_t *pcs = NULL; 7785 pool_scan_stat_t *ps = NULL; 7786 uint_t c; 7787 7788 if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS, 7789 (uint64_t **)&ps, &c) == 0) { 7790 if (ps->pss_func == POOL_SCAN_RESILVER) { 7791 resilver_end_time = ps->pss_end_time; 7792 active_resilver = (ps->pss_state == DSS_SCANNING); 7793 } 7794 7795 have_resilver = (ps->pss_func == POOL_SCAN_RESILVER); 7796 have_scrub = (ps->pss_func == POOL_SCAN_SCRUB); 7797 } 7798 7799 boolean_t active_rebuild = check_rebuilding(nvroot, &rebuild_end_time); 7800 boolean_t have_rebuild = (active_rebuild || (rebuild_end_time > 0)); 7801 7802 /* Always print the scrub status when available. */ 7803 if (have_scrub) 7804 print_scan_scrub_resilver_status(ps); 7805 7806 /* 7807 * When there is an active resilver or rebuild print its status. 7808 * Otherwise print the status of the last resilver or rebuild. 7809 */ 7810 if (active_resilver || (!active_rebuild && have_resilver && 7811 resilver_end_time && resilver_end_time > rebuild_end_time)) { 7812 print_scan_scrub_resilver_status(ps); 7813 } else if (active_rebuild || (!active_resilver && have_rebuild && 7814 rebuild_end_time && rebuild_end_time > resilver_end_time)) { 7815 print_rebuild_status(zhp, nvroot); 7816 } 7817 7818 (void) nvlist_lookup_uint64_array(nvroot, 7819 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7820 print_checkpoint_scan_warning(ps, pcs); 7821 } 7822 7823 /* 7824 * Print out detailed removal status. 7825 */ 7826 static void 7827 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 7828 { 7829 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 7830 time_t start, end; 7831 nvlist_t *config, *nvroot; 7832 nvlist_t **child; 7833 uint_t children; 7834 char *vdev_name; 7835 7836 if (prs == NULL || prs->prs_state == DSS_NONE) 7837 return; 7838 7839 /* 7840 * Determine name of vdev. 7841 */ 7842 config = zpool_get_config(zhp, NULL); 7843 nvroot = fnvlist_lookup_nvlist(config, 7844 ZPOOL_CONFIG_VDEV_TREE); 7845 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 7846 &child, &children) == 0); 7847 assert(prs->prs_removing_vdev < children); 7848 vdev_name = zpool_vdev_name(g_zfs, zhp, 7849 child[prs->prs_removing_vdev], B_TRUE); 7850 7851 printf_color(ANSI_BOLD, gettext("remove: ")); 7852 7853 start = prs->prs_start_time; 7854 end = prs->prs_end_time; 7855 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 7856 7857 /* 7858 * Removal is finished or canceled. 7859 */ 7860 if (prs->prs_state == DSS_FINISHED) { 7861 uint64_t minutes_taken = (end - start) / 60; 7862 7863 (void) printf(gettext("Removal of vdev %llu copied %s " 7864 "in %lluh%um, completed on %s"), 7865 (longlong_t)prs->prs_removing_vdev, 7866 copied_buf, 7867 (u_longlong_t)(minutes_taken / 60), 7868 (uint_t)(minutes_taken % 60), 7869 ctime((time_t *)&end)); 7870 } else if (prs->prs_state == DSS_CANCELED) { 7871 (void) printf(gettext("Removal of %s canceled on %s"), 7872 vdev_name, ctime(&end)); 7873 } else { 7874 uint64_t copied, total, elapsed, mins_left, hours_left; 7875 double fraction_done; 7876 uint_t rate; 7877 7878 assert(prs->prs_state == DSS_SCANNING); 7879 7880 /* 7881 * Removal is in progress. 7882 */ 7883 (void) printf(gettext( 7884 "Evacuation of %s in progress since %s"), 7885 vdev_name, ctime(&start)); 7886 7887 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 7888 total = prs->prs_to_copy; 7889 fraction_done = (double)copied / total; 7890 7891 /* elapsed time for this pass */ 7892 elapsed = time(NULL) - prs->prs_start_time; 7893 elapsed = elapsed > 0 ? elapsed : 1; 7894 rate = copied / elapsed; 7895 rate = rate > 0 ? rate : 1; 7896 mins_left = ((total - copied) / rate) / 60; 7897 hours_left = mins_left / 60; 7898 7899 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 7900 zfs_nicenum(total, total_buf, sizeof (total_buf)); 7901 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 7902 7903 /* 7904 * do not print estimated time if hours_left is more than 7905 * 30 days 7906 */ 7907 (void) printf(gettext( 7908 "\t%s copied out of %s at %s/s, %.2f%% done"), 7909 examined_buf, total_buf, rate_buf, 100 * fraction_done); 7910 if (hours_left < (30 * 24)) { 7911 (void) printf(gettext(", %lluh%um to go\n"), 7912 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 7913 } else { 7914 (void) printf(gettext( 7915 ", (copy is slow, no estimated time)\n")); 7916 } 7917 } 7918 free(vdev_name); 7919 7920 if (prs->prs_mapping_memory > 0) { 7921 char mem_buf[7]; 7922 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 7923 (void) printf(gettext( 7924 "\t%s memory used for removed device mappings\n"), 7925 mem_buf); 7926 } 7927 } 7928 7929 static void 7930 print_checkpoint_status(pool_checkpoint_stat_t *pcs) 7931 { 7932 time_t start; 7933 char space_buf[7]; 7934 7935 if (pcs == NULL || pcs->pcs_state == CS_NONE) 7936 return; 7937 7938 (void) printf(gettext("checkpoint: ")); 7939 7940 start = pcs->pcs_start_time; 7941 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf)); 7942 7943 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) { 7944 char *date = ctime(&start); 7945 7946 /* 7947 * ctime() adds a newline at the end of the generated 7948 * string, thus the weird format specifier and the 7949 * strlen() call used to chop it off from the output. 7950 */ 7951 (void) printf(gettext("created %.*s, consumes %s\n"), 7952 (int)(strlen(date) - 1), date, space_buf); 7953 return; 7954 } 7955 7956 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 7957 7958 (void) printf(gettext("discarding, %s remaining.\n"), 7959 space_buf); 7960 } 7961 7962 static void 7963 print_error_log(zpool_handle_t *zhp) 7964 { 7965 nvlist_t *nverrlist = NULL; 7966 nvpair_t *elem; 7967 char *pathname; 7968 size_t len = MAXPATHLEN * 2; 7969 7970 if (zpool_get_errlog(zhp, &nverrlist) != 0) 7971 return; 7972 7973 (void) printf("errors: Permanent errors have been " 7974 "detected in the following files:\n\n"); 7975 7976 pathname = safe_malloc(len); 7977 elem = NULL; 7978 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 7979 nvlist_t *nv; 7980 uint64_t dsobj, obj; 7981 7982 verify(nvpair_value_nvlist(elem, &nv) == 0); 7983 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 7984 &dsobj) == 0); 7985 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 7986 &obj) == 0); 7987 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 7988 (void) printf("%7s %s\n", "", pathname); 7989 } 7990 free(pathname); 7991 nvlist_free(nverrlist); 7992 } 7993 7994 static void 7995 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares, 7996 uint_t nspares) 7997 { 7998 uint_t i; 7999 char *name; 8000 8001 if (nspares == 0) 8002 return; 8003 8004 (void) printf(gettext("\tspares\n")); 8005 8006 for (i = 0; i < nspares; i++) { 8007 name = zpool_vdev_name(g_zfs, zhp, spares[i], 8008 cb->cb_name_flags); 8009 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE, NULL); 8010 free(name); 8011 } 8012 } 8013 8014 static void 8015 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache, 8016 uint_t nl2cache) 8017 { 8018 uint_t i; 8019 char *name; 8020 8021 if (nl2cache == 0) 8022 return; 8023 8024 (void) printf(gettext("\tcache\n")); 8025 8026 for (i = 0; i < nl2cache; i++) { 8027 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], 8028 cb->cb_name_flags); 8029 print_status_config(zhp, cb, name, l2cache[i], 2, 8030 B_FALSE, NULL); 8031 free(name); 8032 } 8033 } 8034 8035 static void 8036 print_dedup_stats(nvlist_t *config) 8037 { 8038 ddt_histogram_t *ddh; 8039 ddt_stat_t *dds; 8040 ddt_object_t *ddo; 8041 uint_t c; 8042 char dspace[6], mspace[6]; 8043 8044 /* 8045 * If the pool was faulted then we may not have been able to 8046 * obtain the config. Otherwise, if we have anything in the dedup 8047 * table continue processing the stats. 8048 */ 8049 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 8050 (uint64_t **)&ddo, &c) != 0) 8051 return; 8052 8053 (void) printf("\n"); 8054 (void) printf(gettext(" dedup: ")); 8055 if (ddo->ddo_count == 0) { 8056 (void) printf(gettext("no DDT entries\n")); 8057 return; 8058 } 8059 8060 zfs_nicebytes(ddo->ddo_dspace, dspace, sizeof (dspace)); 8061 zfs_nicebytes(ddo->ddo_mspace, mspace, sizeof (mspace)); 8062 (void) printf("DDT entries %llu, size %s on disk, %s in core\n", 8063 (u_longlong_t)ddo->ddo_count, 8064 dspace, 8065 mspace); 8066 8067 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 8068 (uint64_t **)&dds, &c) == 0); 8069 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 8070 (uint64_t **)&ddh, &c) == 0); 8071 zpool_dump_ddt(dds, ddh); 8072 } 8073 8074 /* 8075 * Display a summary of pool status. Displays a summary such as: 8076 * 8077 * pool: tank 8078 * status: DEGRADED 8079 * reason: One or more devices ... 8080 * see: https://openzfs.github.io/openzfs-docs/msg/ZFS-xxxx-01 8081 * config: 8082 * mirror DEGRADED 8083 * c1t0d0 OK 8084 * c2t0d0 UNAVAIL 8085 * 8086 * When given the '-v' option, we print out the complete config. If the '-e' 8087 * option is specified, then we print out error rate information as well. 8088 */ 8089 static int 8090 status_callback(zpool_handle_t *zhp, void *data) 8091 { 8092 status_cbdata_t *cbp = data; 8093 nvlist_t *config, *nvroot; 8094 char *msgid; 8095 zpool_status_t reason; 8096 zpool_errata_t errata; 8097 const char *health; 8098 uint_t c; 8099 vdev_stat_t *vs; 8100 8101 config = zpool_get_config(zhp, NULL); 8102 reason = zpool_get_status(zhp, &msgid, &errata); 8103 8104 cbp->cb_count++; 8105 8106 /* 8107 * If we were given 'zpool status -x', only report those pools with 8108 * problems. 8109 */ 8110 if (cbp->cb_explain && 8111 (reason == ZPOOL_STATUS_OK || 8112 reason == ZPOOL_STATUS_VERSION_OLDER || 8113 reason == ZPOOL_STATUS_FEAT_DISABLED || 8114 reason == ZPOOL_STATUS_COMPATIBILITY_ERR || 8115 reason == ZPOOL_STATUS_INCOMPATIBLE_FEAT)) { 8116 if (!cbp->cb_allpools) { 8117 (void) printf(gettext("pool '%s' is healthy\n"), 8118 zpool_get_name(zhp)); 8119 if (cbp->cb_first) 8120 cbp->cb_first = B_FALSE; 8121 } 8122 return (0); 8123 } 8124 8125 if (cbp->cb_first) 8126 cbp->cb_first = B_FALSE; 8127 else 8128 (void) printf("\n"); 8129 8130 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 8131 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 8132 (uint64_t **)&vs, &c) == 0); 8133 8134 health = zpool_get_state_str(zhp); 8135 8136 printf(" "); 8137 printf_color(ANSI_BOLD, gettext("pool:")); 8138 printf(" %s\n", zpool_get_name(zhp)); 8139 printf(" "); 8140 printf_color(ANSI_BOLD, gettext("state: ")); 8141 8142 printf_color(health_str_to_color(health), "%s", health); 8143 8144 printf("\n"); 8145 8146 switch (reason) { 8147 case ZPOOL_STATUS_MISSING_DEV_R: 8148 printf_color(ANSI_BOLD, gettext("status: ")); 8149 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8150 "not be opened. Sufficient replicas exist for\n\tthe pool " 8151 "to continue functioning in a degraded state.\n")); 8152 printf_color(ANSI_BOLD, gettext("action: ")); 8153 printf_color(ANSI_YELLOW, gettext("Attach the missing device " 8154 "and online it using 'zpool online'.\n")); 8155 break; 8156 8157 case ZPOOL_STATUS_MISSING_DEV_NR: 8158 printf_color(ANSI_BOLD, gettext("status: ")); 8159 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8160 "not be opened. There are insufficient\n\treplicas for the" 8161 " pool to continue functioning.\n")); 8162 printf_color(ANSI_BOLD, gettext("action: ")); 8163 printf_color(ANSI_YELLOW, gettext("Attach the missing device " 8164 "and online it using 'zpool online'.\n")); 8165 break; 8166 8167 case ZPOOL_STATUS_CORRUPT_LABEL_R: 8168 printf_color(ANSI_BOLD, gettext("status: ")); 8169 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8170 "not be used because the label is missing or\n\tinvalid. " 8171 "Sufficient replicas exist for the pool to continue\n\t" 8172 "functioning in a degraded state.\n")); 8173 printf_color(ANSI_BOLD, gettext("action: ")); 8174 printf_color(ANSI_YELLOW, gettext("Replace the device using " 8175 "'zpool replace'.\n")); 8176 break; 8177 8178 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 8179 printf_color(ANSI_BOLD, gettext("status: ")); 8180 printf_color(ANSI_YELLOW, gettext("One or more devices could " 8181 "not be used because the label is missing \n\tor invalid. " 8182 "There are insufficient replicas for the pool to " 8183 "continue\n\tfunctioning.\n")); 8184 zpool_explain_recover(zpool_get_handle(zhp), 8185 zpool_get_name(zhp), reason, config); 8186 break; 8187 8188 case ZPOOL_STATUS_FAILING_DEV: 8189 printf_color(ANSI_BOLD, gettext("status: ")); 8190 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8191 "experienced an unrecoverable error. An\n\tattempt was " 8192 "made to correct the error. Applications are " 8193 "unaffected.\n")); 8194 printf_color(ANSI_BOLD, gettext("action: ")); 8195 printf_color(ANSI_YELLOW, gettext("Determine if the " 8196 "device needs to be replaced, and clear the errors\n\tusing" 8197 " 'zpool clear' or replace the device with 'zpool " 8198 "replace'.\n")); 8199 break; 8200 8201 case ZPOOL_STATUS_OFFLINE_DEV: 8202 printf_color(ANSI_BOLD, gettext("status: ")); 8203 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8204 "been taken offline by the administrator.\n\tSufficient " 8205 "replicas exist for the pool to continue functioning in " 8206 "a\n\tdegraded state.\n")); 8207 printf_color(ANSI_BOLD, gettext("action: ")); 8208 printf_color(ANSI_YELLOW, gettext("Online the device " 8209 "using 'zpool online' or replace the device with\n\t'zpool " 8210 "replace'.\n")); 8211 break; 8212 8213 case ZPOOL_STATUS_REMOVED_DEV: 8214 printf_color(ANSI_BOLD, gettext("status: ")); 8215 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8216 "been removed by the administrator.\n\tSufficient " 8217 "replicas exist for the pool to continue functioning in " 8218 "a\n\tdegraded state.\n")); 8219 printf_color(ANSI_BOLD, gettext("action: ")); 8220 printf_color(ANSI_YELLOW, gettext("Online the device " 8221 "using zpool online' or replace the device with\n\t'zpool " 8222 "replace'.\n")); 8223 break; 8224 8225 case ZPOOL_STATUS_RESILVERING: 8226 case ZPOOL_STATUS_REBUILDING: 8227 printf_color(ANSI_BOLD, gettext("status: ")); 8228 printf_color(ANSI_YELLOW, gettext("One or more devices is " 8229 "currently being resilvered. The pool will\n\tcontinue " 8230 "to function, possibly in a degraded state.\n")); 8231 printf_color(ANSI_BOLD, gettext("action: ")); 8232 printf_color(ANSI_YELLOW, gettext("Wait for the resilver to " 8233 "complete.\n")); 8234 break; 8235 8236 case ZPOOL_STATUS_REBUILD_SCRUB: 8237 printf_color(ANSI_BOLD, gettext("status: ")); 8238 printf_color(ANSI_YELLOW, gettext("One or more devices have " 8239 "been sequentially resilvered, scrubbing\n\tthe pool " 8240 "is recommended.\n")); 8241 printf_color(ANSI_BOLD, gettext("action: ")); 8242 printf_color(ANSI_YELLOW, gettext("Use 'zpool scrub' to " 8243 "verify all data checksums.\n")); 8244 break; 8245 8246 case ZPOOL_STATUS_CORRUPT_DATA: 8247 printf_color(ANSI_BOLD, gettext("status: ")); 8248 printf_color(ANSI_YELLOW, gettext("One or more devices has " 8249 "experienced an error resulting in data\n\tcorruption. " 8250 "Applications may be affected.\n")); 8251 printf_color(ANSI_BOLD, gettext("action: ")); 8252 printf_color(ANSI_YELLOW, gettext("Restore the file in question" 8253 " if possible. Otherwise restore the\n\tentire pool from " 8254 "backup.\n")); 8255 break; 8256 8257 case ZPOOL_STATUS_CORRUPT_POOL: 8258 printf_color(ANSI_BOLD, gettext("status: ")); 8259 printf_color(ANSI_YELLOW, gettext("The pool metadata is " 8260 "corrupted and the pool cannot be opened.\n")); 8261 zpool_explain_recover(zpool_get_handle(zhp), 8262 zpool_get_name(zhp), reason, config); 8263 break; 8264 8265 case ZPOOL_STATUS_VERSION_OLDER: 8266 printf_color(ANSI_BOLD, gettext("status: ")); 8267 printf_color(ANSI_YELLOW, gettext("The pool is formatted using " 8268 "a legacy on-disk format. The pool can\n\tstill be used, " 8269 "but some features are unavailable.\n")); 8270 printf_color(ANSI_BOLD, gettext("action: ")); 8271 printf_color(ANSI_YELLOW, gettext("Upgrade the pool using " 8272 "'zpool upgrade'. Once this is done, the\n\tpool will no " 8273 "longer be accessible on software that does not support\n\t" 8274 "feature flags.\n")); 8275 break; 8276 8277 case ZPOOL_STATUS_VERSION_NEWER: 8278 printf_color(ANSI_BOLD, gettext("status: ")); 8279 printf_color(ANSI_YELLOW, gettext("The pool has been upgraded " 8280 "to a newer, incompatible on-disk version.\n\tThe pool " 8281 "cannot be accessed on this system.\n")); 8282 printf_color(ANSI_BOLD, gettext("action: ")); 8283 printf_color(ANSI_YELLOW, gettext("Access the pool from a " 8284 "system running more recent software, or\n\trestore the " 8285 "pool from backup.\n")); 8286 break; 8287 8288 case ZPOOL_STATUS_FEAT_DISABLED: 8289 printf_color(ANSI_BOLD, gettext("status: ")); 8290 printf_color(ANSI_YELLOW, gettext("Some supported and " 8291 "requested features are not enabled on the pool.\n\t" 8292 "The pool can still be used, but some features are " 8293 "unavailable.\n")); 8294 printf_color(ANSI_BOLD, gettext("action: ")); 8295 printf_color(ANSI_YELLOW, gettext("Enable all features using " 8296 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 8297 "longer be accessible by software that does not support\n\t" 8298 "the features. See zpool-features(7) for details.\n")); 8299 break; 8300 8301 case ZPOOL_STATUS_COMPATIBILITY_ERR: 8302 printf_color(ANSI_BOLD, gettext("status: ")); 8303 printf_color(ANSI_YELLOW, gettext("This pool has a " 8304 "compatibility list specified, but it could not be\n\t" 8305 "read/parsed at this time. The pool can still be used, " 8306 "but this\n\tshould be investigated.\n")); 8307 printf_color(ANSI_BOLD, gettext("action: ")); 8308 printf_color(ANSI_YELLOW, gettext("Check the value of the " 8309 "'compatibility' property against the\n\t" 8310 "appropriate file in " ZPOOL_SYSCONF_COMPAT_D " or " 8311 ZPOOL_DATA_COMPAT_D ".\n")); 8312 break; 8313 8314 case ZPOOL_STATUS_INCOMPATIBLE_FEAT: 8315 printf_color(ANSI_BOLD, gettext("status: ")); 8316 printf_color(ANSI_YELLOW, gettext("One or more features " 8317 "are enabled on the pool despite not being\n\t" 8318 "requested by the 'compatibility' property.\n")); 8319 printf_color(ANSI_BOLD, gettext("action: ")); 8320 printf_color(ANSI_YELLOW, gettext("Consider setting " 8321 "'compatibility' to an appropriate value, or\n\t" 8322 "adding needed features to the relevant file in\n\t" 8323 ZPOOL_SYSCONF_COMPAT_D " or " ZPOOL_DATA_COMPAT_D ".\n")); 8324 break; 8325 8326 case ZPOOL_STATUS_UNSUP_FEAT_READ: 8327 printf_color(ANSI_BOLD, gettext("status: ")); 8328 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed " 8329 "on this system because it uses the\n\tfollowing feature(s)" 8330 " not supported on this system:\n")); 8331 zpool_print_unsup_feat(config); 8332 (void) printf("\n"); 8333 printf_color(ANSI_BOLD, gettext("action: ")); 8334 printf_color(ANSI_YELLOW, gettext("Access the pool from a " 8335 "system that supports the required feature(s),\n\tor " 8336 "restore the pool from backup.\n")); 8337 break; 8338 8339 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 8340 printf_color(ANSI_BOLD, gettext("status: ")); 8341 printf_color(ANSI_YELLOW, gettext("The pool can only be " 8342 "accessed in read-only mode on this system. It\n\tcannot be" 8343 " accessed in read-write mode because it uses the " 8344 "following\n\tfeature(s) not supported on this system:\n")); 8345 zpool_print_unsup_feat(config); 8346 (void) printf("\n"); 8347 printf_color(ANSI_BOLD, gettext("action: ")); 8348 printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed " 8349 "in read-write mode. Import the pool with\n" 8350 "\t\"-o readonly=on\", access the pool from a system that " 8351 "supports the\n\trequired feature(s), or restore the " 8352 "pool from backup.\n")); 8353 break; 8354 8355 case ZPOOL_STATUS_FAULTED_DEV_R: 8356 printf_color(ANSI_BOLD, gettext("status: ")); 8357 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8358 "faulted in response to persistent errors.\n\tSufficient " 8359 "replicas exist for the pool to continue functioning " 8360 "in a\n\tdegraded state.\n")); 8361 printf_color(ANSI_BOLD, gettext("action: ")); 8362 printf_color(ANSI_YELLOW, gettext("Replace the faulted device, " 8363 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 8364 break; 8365 8366 case ZPOOL_STATUS_FAULTED_DEV_NR: 8367 printf_color(ANSI_BOLD, gettext("status: ")); 8368 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8369 "faulted in response to persistent errors. There are " 8370 "insufficient replicas for the pool to\n\tcontinue " 8371 "functioning.\n")); 8372 printf_color(ANSI_BOLD, gettext("action: ")); 8373 printf_color(ANSI_YELLOW, gettext("Destroy and re-create the " 8374 "pool from a backup source. Manually marking the device\n" 8375 "\trepaired using 'zpool clear' may allow some data " 8376 "to be recovered.\n")); 8377 break; 8378 8379 case ZPOOL_STATUS_IO_FAILURE_MMP: 8380 printf_color(ANSI_BOLD, gettext("status: ")); 8381 printf_color(ANSI_YELLOW, gettext("The pool is suspended " 8382 "because multihost writes failed or were delayed;\n\t" 8383 "another system could import the pool undetected.\n")); 8384 printf_color(ANSI_BOLD, gettext("action: ")); 8385 printf_color(ANSI_YELLOW, gettext("Make sure the pool's devices" 8386 " are connected, then reboot your system and\n\timport the " 8387 "pool.\n")); 8388 break; 8389 8390 case ZPOOL_STATUS_IO_FAILURE_WAIT: 8391 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 8392 printf_color(ANSI_BOLD, gettext("status: ")); 8393 printf_color(ANSI_YELLOW, gettext("One or more devices are " 8394 "faulted in response to IO failures.\n")); 8395 printf_color(ANSI_BOLD, gettext("action: ")); 8396 printf_color(ANSI_YELLOW, gettext("Make sure the affected " 8397 "devices are connected, then run 'zpool clear'.\n")); 8398 break; 8399 8400 case ZPOOL_STATUS_BAD_LOG: 8401 printf_color(ANSI_BOLD, gettext("status: ")); 8402 printf_color(ANSI_YELLOW, gettext("An intent log record " 8403 "could not be read.\n" 8404 "\tWaiting for administrator intervention to fix the " 8405 "faulted pool.\n")); 8406 printf_color(ANSI_BOLD, gettext("action: ")); 8407 printf_color(ANSI_YELLOW, gettext("Either restore the affected " 8408 "device(s) and run 'zpool online',\n" 8409 "\tor ignore the intent log records by running " 8410 "'zpool clear'.\n")); 8411 break; 8412 8413 case ZPOOL_STATUS_NON_NATIVE_ASHIFT: 8414 (void) printf(gettext("status: One or more devices are " 8415 "configured to use a non-native block size.\n" 8416 "\tExpect reduced performance.\n")); 8417 (void) printf(gettext("action: Replace affected devices with " 8418 "devices that support the\n\tconfigured block size, or " 8419 "migrate data to a properly configured\n\tpool.\n")); 8420 break; 8421 8422 case ZPOOL_STATUS_HOSTID_MISMATCH: 8423 printf_color(ANSI_BOLD, gettext("status: ")); 8424 printf_color(ANSI_YELLOW, gettext("Mismatch between pool hostid" 8425 " and system hostid on imported pool.\n\tThis pool was " 8426 "previously imported into a system with a different " 8427 "hostid,\n\tand then was verbatim imported into this " 8428 "system.\n")); 8429 printf_color(ANSI_BOLD, gettext("action: ")); 8430 printf_color(ANSI_YELLOW, gettext("Export this pool on all " 8431 "systems on which it is imported.\n" 8432 "\tThen import it to correct the mismatch.\n")); 8433 break; 8434 8435 case ZPOOL_STATUS_ERRATA: 8436 printf_color(ANSI_BOLD, gettext("status: ")); 8437 printf_color(ANSI_YELLOW, gettext("Errata #%d detected.\n"), 8438 errata); 8439 8440 switch (errata) { 8441 case ZPOOL_ERRATA_NONE: 8442 break; 8443 8444 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 8445 printf_color(ANSI_BOLD, gettext("action: ")); 8446 printf_color(ANSI_YELLOW, gettext("To correct the issue" 8447 " run 'zpool scrub'.\n")); 8448 break; 8449 8450 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 8451 (void) printf(gettext("\tExisting encrypted datasets " 8452 "contain an on-disk incompatibility\n\twhich " 8453 "needs to be corrected.\n")); 8454 printf_color(ANSI_BOLD, gettext("action: ")); 8455 printf_color(ANSI_YELLOW, gettext("To correct the issue" 8456 " backup existing encrypted datasets to new\n\t" 8457 "encrypted datasets and destroy the old ones. " 8458 "'zfs mount -o ro' can\n\tbe used to temporarily " 8459 "mount existing encrypted datasets readonly.\n")); 8460 break; 8461 8462 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 8463 (void) printf(gettext("\tExisting encrypted snapshots " 8464 "and bookmarks contain an on-disk\n\tincompat" 8465 "ibility. This may cause on-disk corruption if " 8466 "they are used\n\twith 'zfs recv'.\n")); 8467 printf_color(ANSI_BOLD, gettext("action: ")); 8468 printf_color(ANSI_YELLOW, gettext("To correct the" 8469 "issue, enable the bookmark_v2 feature. No " 8470 "additional\n\taction is needed if there are no " 8471 "encrypted snapshots or bookmarks.\n\tIf preserving" 8472 "the encrypted snapshots and bookmarks is required," 8473 " use\n\ta non-raw send to backup and restore them." 8474 " Alternately, they may be\n\tremoved to resolve " 8475 "the incompatibility.\n")); 8476 break; 8477 8478 default: 8479 /* 8480 * All errata which allow the pool to be imported 8481 * must contain an action message. 8482 */ 8483 assert(0); 8484 } 8485 break; 8486 8487 default: 8488 /* 8489 * The remaining errors can't actually be generated, yet. 8490 */ 8491 assert(reason == ZPOOL_STATUS_OK); 8492 } 8493 8494 if (msgid != NULL) { 8495 printf(" "); 8496 printf_color(ANSI_BOLD, gettext("see:")); 8497 printf(gettext( 8498 " https://openzfs.github.io/openzfs-docs/msg/%s\n"), 8499 msgid); 8500 } 8501 8502 if (config != NULL) { 8503 uint64_t nerr; 8504 nvlist_t **spares, **l2cache; 8505 uint_t nspares, nl2cache; 8506 pool_checkpoint_stat_t *pcs = NULL; 8507 pool_removal_stat_t *prs = NULL; 8508 8509 print_scan_status(zhp, nvroot); 8510 8511 (void) nvlist_lookup_uint64_array(nvroot, 8512 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 8513 print_removal_status(zhp, prs); 8514 8515 (void) nvlist_lookup_uint64_array(nvroot, 8516 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 8517 print_checkpoint_status(pcs); 8518 8519 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 8520 cbp->cb_name_flags | VDEV_NAME_TYPE_ID); 8521 if (cbp->cb_namewidth < 10) 8522 cbp->cb_namewidth = 10; 8523 8524 color_start(ANSI_BOLD); 8525 (void) printf(gettext("config:\n\n")); 8526 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s"), 8527 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE", 8528 "CKSUM"); 8529 color_end(); 8530 8531 if (cbp->cb_print_slow_ios) { 8532 printf_color(ANSI_BOLD, " %5s", gettext("SLOW")); 8533 } 8534 8535 if (cbp->vcdl != NULL) 8536 print_cmd_columns(cbp->vcdl, 0); 8537 8538 printf("\n"); 8539 8540 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0, 8541 B_FALSE, NULL); 8542 8543 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP); 8544 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 8545 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS); 8546 8547 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 8548 &l2cache, &nl2cache) == 0) 8549 print_l2cache(zhp, cbp, l2cache, nl2cache); 8550 8551 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 8552 &spares, &nspares) == 0) 8553 print_spares(zhp, cbp, spares, nspares); 8554 8555 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 8556 &nerr) == 0) { 8557 nvlist_t *nverrlist = NULL; 8558 8559 /* 8560 * If the approximate error count is small, get a 8561 * precise count by fetching the entire log and 8562 * uniquifying the results. 8563 */ 8564 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 8565 zpool_get_errlog(zhp, &nverrlist) == 0) { 8566 nvpair_t *elem; 8567 8568 elem = NULL; 8569 nerr = 0; 8570 while ((elem = nvlist_next_nvpair(nverrlist, 8571 elem)) != NULL) { 8572 nerr++; 8573 } 8574 } 8575 nvlist_free(nverrlist); 8576 8577 (void) printf("\n"); 8578 8579 if (nerr == 0) 8580 (void) printf(gettext("errors: No known data " 8581 "errors\n")); 8582 else if (!cbp->cb_verbose) 8583 (void) printf(gettext("errors: %llu data " 8584 "errors, use '-v' for a list\n"), 8585 (u_longlong_t)nerr); 8586 else 8587 print_error_log(zhp); 8588 } 8589 8590 if (cbp->cb_dedup_stats) 8591 print_dedup_stats(config); 8592 } else { 8593 (void) printf(gettext("config: The configuration cannot be " 8594 "determined.\n")); 8595 } 8596 8597 return (0); 8598 } 8599 8600 /* 8601 * zpool status [-c [script1,script2,...]] [-igLpPstvx] [-T d|u] [pool] ... 8602 * [interval [count]] 8603 * 8604 * -c CMD For each vdev, run command CMD 8605 * -i Display vdev initialization status. 8606 * -g Display guid for individual vdev name. 8607 * -L Follow links when resolving vdev path name. 8608 * -p Display values in parsable (exact) format. 8609 * -P Display full path for vdev name. 8610 * -s Display slow IOs column. 8611 * -v Display complete error logs 8612 * -x Display only pools with potential problems 8613 * -D Display dedup status (undocumented) 8614 * -t Display vdev TRIM status. 8615 * -T Display a timestamp in date(1) or Unix format 8616 * 8617 * Describes the health status of all pools or some subset. 8618 */ 8619 int 8620 zpool_do_status(int argc, char **argv) 8621 { 8622 int c; 8623 int ret; 8624 float interval = 0; 8625 unsigned long count = 0; 8626 status_cbdata_t cb = { 0 }; 8627 char *cmd = NULL; 8628 8629 /* check options */ 8630 while ((c = getopt(argc, argv, "c:igLpPsvxDtT:")) != -1) { 8631 switch (c) { 8632 case 'c': 8633 if (cmd != NULL) { 8634 fprintf(stderr, 8635 gettext("Can't set -c flag twice\n")); 8636 exit(1); 8637 } 8638 8639 if (getenv("ZPOOL_SCRIPTS_ENABLED") != NULL && 8640 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_ENABLED")) { 8641 fprintf(stderr, gettext( 8642 "Can't run -c, disabled by " 8643 "ZPOOL_SCRIPTS_ENABLED.\n")); 8644 exit(1); 8645 } 8646 8647 if ((getuid() <= 0 || geteuid() <= 0) && 8648 !libzfs_envvar_is_set("ZPOOL_SCRIPTS_AS_ROOT")) { 8649 fprintf(stderr, gettext( 8650 "Can't run -c with root privileges " 8651 "unless ZPOOL_SCRIPTS_AS_ROOT is set.\n")); 8652 exit(1); 8653 } 8654 cmd = optarg; 8655 break; 8656 case 'i': 8657 cb.cb_print_vdev_init = B_TRUE; 8658 break; 8659 case 'g': 8660 cb.cb_name_flags |= VDEV_NAME_GUID; 8661 break; 8662 case 'L': 8663 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 8664 break; 8665 case 'p': 8666 cb.cb_literal = B_TRUE; 8667 break; 8668 case 'P': 8669 cb.cb_name_flags |= VDEV_NAME_PATH; 8670 break; 8671 case 's': 8672 cb.cb_print_slow_ios = B_TRUE; 8673 break; 8674 case 'v': 8675 cb.cb_verbose = B_TRUE; 8676 break; 8677 case 'x': 8678 cb.cb_explain = B_TRUE; 8679 break; 8680 case 'D': 8681 cb.cb_dedup_stats = B_TRUE; 8682 break; 8683 case 't': 8684 cb.cb_print_vdev_trim = B_TRUE; 8685 break; 8686 case 'T': 8687 get_timestamp_arg(*optarg); 8688 break; 8689 case '?': 8690 if (optopt == 'c') { 8691 print_zpool_script_list("status"); 8692 exit(0); 8693 } else { 8694 fprintf(stderr, 8695 gettext("invalid option '%c'\n"), optopt); 8696 } 8697 usage(B_FALSE); 8698 } 8699 } 8700 8701 argc -= optind; 8702 argv += optind; 8703 8704 get_interval_count(&argc, argv, &interval, &count); 8705 8706 if (argc == 0) 8707 cb.cb_allpools = B_TRUE; 8708 8709 cb.cb_first = B_TRUE; 8710 cb.cb_print_status = B_TRUE; 8711 8712 for (;;) { 8713 if (timestamp_fmt != NODATE) 8714 print_timestamp(timestamp_fmt); 8715 8716 if (cmd != NULL) 8717 cb.vcdl = all_pools_for_each_vdev_run(argc, argv, cmd, 8718 NULL, NULL, 0, 0); 8719 8720 ret = for_each_pool(argc, argv, B_TRUE, NULL, cb.cb_literal, 8721 status_callback, &cb); 8722 8723 if (cb.vcdl != NULL) 8724 free_vdev_cmd_data_list(cb.vcdl); 8725 8726 if (argc == 0 && cb.cb_count == 0) 8727 (void) fprintf(stderr, gettext("no pools available\n")); 8728 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 8729 (void) printf(gettext("all pools are healthy\n")); 8730 8731 if (ret != 0) 8732 return (ret); 8733 8734 if (interval == 0) 8735 break; 8736 8737 if (count != 0 && --count == 0) 8738 break; 8739 8740 (void) fsleep(interval); 8741 } 8742 8743 return (0); 8744 } 8745 8746 typedef struct upgrade_cbdata { 8747 int cb_first; 8748 int cb_argc; 8749 uint64_t cb_version; 8750 char **cb_argv; 8751 } upgrade_cbdata_t; 8752 8753 static int 8754 check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs) 8755 { 8756 int zfs_version = (int)zfs_prop_get_int(zhp, ZFS_PROP_VERSION); 8757 int *count = (int *)unsupp_fs; 8758 8759 if (zfs_version > ZPL_VERSION) { 8760 (void) printf(gettext("%s (v%d) is not supported by this " 8761 "implementation of ZFS.\n"), 8762 zfs_get_name(zhp), zfs_version); 8763 (*count)++; 8764 } 8765 8766 zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs); 8767 8768 zfs_close(zhp); 8769 8770 return (0); 8771 } 8772 8773 static int 8774 upgrade_version(zpool_handle_t *zhp, uint64_t version) 8775 { 8776 int ret; 8777 nvlist_t *config; 8778 uint64_t oldversion; 8779 int unsupp_fs = 0; 8780 8781 config = zpool_get_config(zhp, NULL); 8782 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8783 &oldversion) == 0); 8784 8785 char compat[ZFS_MAXPROPLEN]; 8786 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat, 8787 ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 8788 compat[0] = '\0'; 8789 8790 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 8791 assert(oldversion < version); 8792 8793 ret = zfs_iter_root(zpool_get_handle(zhp), check_unsupp_fs, &unsupp_fs); 8794 if (ret != 0) 8795 return (ret); 8796 8797 if (unsupp_fs) { 8798 (void) fprintf(stderr, gettext("Upgrade not performed due " 8799 "to %d unsupported filesystems (max v%d).\n"), 8800 unsupp_fs, (int)ZPL_VERSION); 8801 return (1); 8802 } 8803 8804 if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) { 8805 (void) fprintf(stderr, gettext("Upgrade not performed because " 8806 "'compatibility' property set to '" 8807 ZPOOL_COMPAT_LEGACY "'.\n")); 8808 return (1); 8809 } 8810 8811 ret = zpool_upgrade(zhp, version); 8812 if (ret != 0) 8813 return (ret); 8814 8815 if (version >= SPA_VERSION_FEATURES) { 8816 (void) printf(gettext("Successfully upgraded " 8817 "'%s' from version %llu to feature flags.\n"), 8818 zpool_get_name(zhp), (u_longlong_t)oldversion); 8819 } else { 8820 (void) printf(gettext("Successfully upgraded " 8821 "'%s' from version %llu to version %llu.\n"), 8822 zpool_get_name(zhp), (u_longlong_t)oldversion, 8823 (u_longlong_t)version); 8824 } 8825 8826 return (0); 8827 } 8828 8829 static int 8830 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 8831 { 8832 int i, ret, count; 8833 boolean_t firstff = B_TRUE; 8834 nvlist_t *enabled = zpool_get_features(zhp); 8835 8836 char compat[ZFS_MAXPROPLEN]; 8837 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat, 8838 ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 8839 compat[0] = '\0'; 8840 8841 boolean_t requested_features[SPA_FEATURES]; 8842 if (zpool_do_load_compat(compat, requested_features) != 8843 ZPOOL_COMPATIBILITY_OK) 8844 return (-1); 8845 8846 count = 0; 8847 for (i = 0; i < SPA_FEATURES; i++) { 8848 const char *fname = spa_feature_table[i].fi_uname; 8849 const char *fguid = spa_feature_table[i].fi_guid; 8850 8851 if (!spa_feature_table[i].fi_zfs_mod_supported) 8852 continue; 8853 8854 if (!nvlist_exists(enabled, fguid) && requested_features[i]) { 8855 char *propname; 8856 verify(-1 != asprintf(&propname, "feature@%s", fname)); 8857 ret = zpool_set_prop(zhp, propname, 8858 ZFS_FEATURE_ENABLED); 8859 if (ret != 0) { 8860 free(propname); 8861 return (ret); 8862 } 8863 count++; 8864 8865 if (firstff) { 8866 (void) printf(gettext("Enabled the " 8867 "following features on '%s':\n"), 8868 zpool_get_name(zhp)); 8869 firstff = B_FALSE; 8870 } 8871 (void) printf(gettext(" %s\n"), fname); 8872 free(propname); 8873 } 8874 } 8875 8876 if (countp != NULL) 8877 *countp = count; 8878 return (0); 8879 } 8880 8881 static int 8882 upgrade_cb(zpool_handle_t *zhp, void *arg) 8883 { 8884 upgrade_cbdata_t *cbp = arg; 8885 nvlist_t *config; 8886 uint64_t version; 8887 boolean_t modified_pool = B_FALSE; 8888 int ret; 8889 8890 config = zpool_get_config(zhp, NULL); 8891 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8892 &version) == 0); 8893 8894 assert(SPA_VERSION_IS_SUPPORTED(version)); 8895 8896 if (version < cbp->cb_version) { 8897 cbp->cb_first = B_FALSE; 8898 ret = upgrade_version(zhp, cbp->cb_version); 8899 if (ret != 0) 8900 return (ret); 8901 modified_pool = B_TRUE; 8902 8903 /* 8904 * If they did "zpool upgrade -a", then we could 8905 * be doing ioctls to different pools. We need 8906 * to log this history once to each pool, and bypass 8907 * the normal history logging that happens in main(). 8908 */ 8909 (void) zpool_log_history(g_zfs, history_str); 8910 log_history = B_FALSE; 8911 } 8912 8913 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 8914 int count; 8915 ret = upgrade_enable_all(zhp, &count); 8916 if (ret != 0) 8917 return (ret); 8918 8919 if (count > 0) { 8920 cbp->cb_first = B_FALSE; 8921 modified_pool = B_TRUE; 8922 } 8923 } 8924 8925 if (modified_pool) { 8926 (void) printf("\n"); 8927 (void) after_zpool_upgrade(zhp); 8928 } 8929 8930 return (0); 8931 } 8932 8933 static int 8934 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 8935 { 8936 upgrade_cbdata_t *cbp = arg; 8937 nvlist_t *config; 8938 uint64_t version; 8939 8940 config = zpool_get_config(zhp, NULL); 8941 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8942 &version) == 0); 8943 8944 assert(SPA_VERSION_IS_SUPPORTED(version)); 8945 8946 if (version < SPA_VERSION_FEATURES) { 8947 if (cbp->cb_first) { 8948 (void) printf(gettext("The following pools are " 8949 "formatted with legacy version numbers and can\n" 8950 "be upgraded to use feature flags. After " 8951 "being upgraded, these pools\nwill no " 8952 "longer be accessible by software that does not " 8953 "support feature\nflags.\n\n" 8954 "Note that setting a pool's 'compatibility' " 8955 "feature to '" ZPOOL_COMPAT_LEGACY "' will\n" 8956 "inhibit upgrades.\n\n")); 8957 (void) printf(gettext("VER POOL\n")); 8958 (void) printf(gettext("--- ------------\n")); 8959 cbp->cb_first = B_FALSE; 8960 } 8961 8962 (void) printf("%2llu %s\n", (u_longlong_t)version, 8963 zpool_get_name(zhp)); 8964 } 8965 8966 return (0); 8967 } 8968 8969 static int 8970 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 8971 { 8972 upgrade_cbdata_t *cbp = arg; 8973 nvlist_t *config; 8974 uint64_t version; 8975 8976 config = zpool_get_config(zhp, NULL); 8977 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 8978 &version) == 0); 8979 8980 if (version >= SPA_VERSION_FEATURES) { 8981 int i; 8982 boolean_t poolfirst = B_TRUE; 8983 nvlist_t *enabled = zpool_get_features(zhp); 8984 8985 for (i = 0; i < SPA_FEATURES; i++) { 8986 const char *fguid = spa_feature_table[i].fi_guid; 8987 const char *fname = spa_feature_table[i].fi_uname; 8988 8989 if (!spa_feature_table[i].fi_zfs_mod_supported) 8990 continue; 8991 8992 if (!nvlist_exists(enabled, fguid)) { 8993 if (cbp->cb_first) { 8994 (void) printf(gettext("\nSome " 8995 "supported features are not " 8996 "enabled on the following pools. " 8997 "Once a\nfeature is enabled the " 8998 "pool may become incompatible with " 8999 "software\nthat does not support " 9000 "the feature. See " 9001 "zpool-features(7) for " 9002 "details.\n\n" 9003 "Note that the pool " 9004 "'compatibility' feature can be " 9005 "used to inhibit\nfeature " 9006 "upgrades.\n\n")); 9007 (void) printf(gettext("POOL " 9008 "FEATURE\n")); 9009 (void) printf(gettext("------" 9010 "---------\n")); 9011 cbp->cb_first = B_FALSE; 9012 } 9013 9014 if (poolfirst) { 9015 (void) printf(gettext("%s\n"), 9016 zpool_get_name(zhp)); 9017 poolfirst = B_FALSE; 9018 } 9019 9020 (void) printf(gettext(" %s\n"), fname); 9021 } 9022 /* 9023 * If they did "zpool upgrade -a", then we could 9024 * be doing ioctls to different pools. We need 9025 * to log this history once to each pool, and bypass 9026 * the normal history logging that happens in main(). 9027 */ 9028 (void) zpool_log_history(g_zfs, history_str); 9029 log_history = B_FALSE; 9030 } 9031 } 9032 9033 return (0); 9034 } 9035 9036 /* ARGSUSED */ 9037 static int 9038 upgrade_one(zpool_handle_t *zhp, void *data) 9039 { 9040 boolean_t modified_pool = B_FALSE; 9041 upgrade_cbdata_t *cbp = data; 9042 uint64_t cur_version; 9043 int ret; 9044 9045 if (strcmp("log", zpool_get_name(zhp)) == 0) { 9046 (void) fprintf(stderr, gettext("'log' is now a reserved word\n" 9047 "Pool 'log' must be renamed using export and import" 9048 " to upgrade.\n")); 9049 return (1); 9050 } 9051 9052 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 9053 if (cur_version > cbp->cb_version) { 9054 (void) printf(gettext("Pool '%s' is already formatted " 9055 "using more current version '%llu'.\n\n"), 9056 zpool_get_name(zhp), (u_longlong_t)cur_version); 9057 return (0); 9058 } 9059 9060 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 9061 (void) printf(gettext("Pool '%s' is already formatted " 9062 "using version %llu.\n\n"), zpool_get_name(zhp), 9063 (u_longlong_t)cbp->cb_version); 9064 return (0); 9065 } 9066 9067 if (cur_version != cbp->cb_version) { 9068 modified_pool = B_TRUE; 9069 ret = upgrade_version(zhp, cbp->cb_version); 9070 if (ret != 0) 9071 return (ret); 9072 } 9073 9074 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 9075 int count = 0; 9076 ret = upgrade_enable_all(zhp, &count); 9077 if (ret != 0) 9078 return (ret); 9079 9080 if (count != 0) { 9081 modified_pool = B_TRUE; 9082 } else if (cur_version == SPA_VERSION) { 9083 (void) printf(gettext("Pool '%s' already has all " 9084 "supported and requested features enabled.\n"), 9085 zpool_get_name(zhp)); 9086 } 9087 } 9088 9089 if (modified_pool) { 9090 (void) printf("\n"); 9091 (void) after_zpool_upgrade(zhp); 9092 } 9093 9094 return (0); 9095 } 9096 9097 /* 9098 * zpool upgrade 9099 * zpool upgrade -v 9100 * zpool upgrade [-V version] <-a | pool ...> 9101 * 9102 * With no arguments, display downrev'd ZFS pool available for upgrade. 9103 * Individual pools can be upgraded by specifying the pool, and '-a' will 9104 * upgrade all pools. 9105 */ 9106 int 9107 zpool_do_upgrade(int argc, char **argv) 9108 { 9109 int c; 9110 upgrade_cbdata_t cb = { 0 }; 9111 int ret = 0; 9112 boolean_t showversions = B_FALSE; 9113 boolean_t upgradeall = B_FALSE; 9114 char *end; 9115 9116 9117 /* check options */ 9118 while ((c = getopt(argc, argv, ":avV:")) != -1) { 9119 switch (c) { 9120 case 'a': 9121 upgradeall = B_TRUE; 9122 break; 9123 case 'v': 9124 showversions = B_TRUE; 9125 break; 9126 case 'V': 9127 cb.cb_version = strtoll(optarg, &end, 10); 9128 if (*end != '\0' || 9129 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 9130 (void) fprintf(stderr, 9131 gettext("invalid version '%s'\n"), optarg); 9132 usage(B_FALSE); 9133 } 9134 break; 9135 case ':': 9136 (void) fprintf(stderr, gettext("missing argument for " 9137 "'%c' option\n"), optopt); 9138 usage(B_FALSE); 9139 break; 9140 case '?': 9141 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9142 optopt); 9143 usage(B_FALSE); 9144 } 9145 } 9146 9147 cb.cb_argc = argc; 9148 cb.cb_argv = argv; 9149 argc -= optind; 9150 argv += optind; 9151 9152 if (cb.cb_version == 0) { 9153 cb.cb_version = SPA_VERSION; 9154 } else if (!upgradeall && argc == 0) { 9155 (void) fprintf(stderr, gettext("-V option is " 9156 "incompatible with other arguments\n")); 9157 usage(B_FALSE); 9158 } 9159 9160 if (showversions) { 9161 if (upgradeall || argc != 0) { 9162 (void) fprintf(stderr, gettext("-v option is " 9163 "incompatible with other arguments\n")); 9164 usage(B_FALSE); 9165 } 9166 } else if (upgradeall) { 9167 if (argc != 0) { 9168 (void) fprintf(stderr, gettext("-a option should not " 9169 "be used along with a pool name\n")); 9170 usage(B_FALSE); 9171 } 9172 } 9173 9174 (void) printf(gettext("This system supports ZFS pool feature " 9175 "flags.\n\n")); 9176 if (showversions) { 9177 int i; 9178 9179 (void) printf(gettext("The following features are " 9180 "supported:\n\n")); 9181 (void) printf(gettext("FEAT DESCRIPTION\n")); 9182 (void) printf("----------------------------------------------" 9183 "---------------\n"); 9184 for (i = 0; i < SPA_FEATURES; i++) { 9185 zfeature_info_t *fi = &spa_feature_table[i]; 9186 if (!fi->fi_zfs_mod_supported) 9187 continue; 9188 const char *ro = 9189 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 9190 " (read-only compatible)" : ""; 9191 9192 (void) printf("%-37s%s\n", fi->fi_uname, ro); 9193 (void) printf(" %s\n", fi->fi_desc); 9194 } 9195 (void) printf("\n"); 9196 9197 (void) printf(gettext("The following legacy versions are also " 9198 "supported:\n\n")); 9199 (void) printf(gettext("VER DESCRIPTION\n")); 9200 (void) printf("--- -----------------------------------------" 9201 "---------------\n"); 9202 (void) printf(gettext(" 1 Initial ZFS version\n")); 9203 (void) printf(gettext(" 2 Ditto blocks " 9204 "(replicated metadata)\n")); 9205 (void) printf(gettext(" 3 Hot spares and double parity " 9206 "RAID-Z\n")); 9207 (void) printf(gettext(" 4 zpool history\n")); 9208 (void) printf(gettext(" 5 Compression using the gzip " 9209 "algorithm\n")); 9210 (void) printf(gettext(" 6 bootfs pool property\n")); 9211 (void) printf(gettext(" 7 Separate intent log devices\n")); 9212 (void) printf(gettext(" 8 Delegated administration\n")); 9213 (void) printf(gettext(" 9 refquota and refreservation " 9214 "properties\n")); 9215 (void) printf(gettext(" 10 Cache devices\n")); 9216 (void) printf(gettext(" 11 Improved scrub performance\n")); 9217 (void) printf(gettext(" 12 Snapshot properties\n")); 9218 (void) printf(gettext(" 13 snapused property\n")); 9219 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 9220 (void) printf(gettext(" 15 user/group space accounting\n")); 9221 (void) printf(gettext(" 16 stmf property support\n")); 9222 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 9223 (void) printf(gettext(" 18 Snapshot user holds\n")); 9224 (void) printf(gettext(" 19 Log device removal\n")); 9225 (void) printf(gettext(" 20 Compression using zle " 9226 "(zero-length encoding)\n")); 9227 (void) printf(gettext(" 21 Deduplication\n")); 9228 (void) printf(gettext(" 22 Received properties\n")); 9229 (void) printf(gettext(" 23 Slim ZIL\n")); 9230 (void) printf(gettext(" 24 System attributes\n")); 9231 (void) printf(gettext(" 25 Improved scrub stats\n")); 9232 (void) printf(gettext(" 26 Improved snapshot deletion " 9233 "performance\n")); 9234 (void) printf(gettext(" 27 Improved snapshot creation " 9235 "performance\n")); 9236 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 9237 (void) printf(gettext("\nFor more information on a particular " 9238 "version, including supported releases,\n")); 9239 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 9240 } else if (argc == 0 && upgradeall) { 9241 cb.cb_first = B_TRUE; 9242 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 9243 if (ret == 0 && cb.cb_first) { 9244 if (cb.cb_version == SPA_VERSION) { 9245 (void) printf(gettext("All pools are already " 9246 "formatted using feature flags.\n\n")); 9247 (void) printf(gettext("Every feature flags " 9248 "pool already has all supported and " 9249 "requested features enabled.\n")); 9250 } else { 9251 (void) printf(gettext("All pools are already " 9252 "formatted with version %llu or higher.\n"), 9253 (u_longlong_t)cb.cb_version); 9254 } 9255 } 9256 } else if (argc == 0) { 9257 cb.cb_first = B_TRUE; 9258 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 9259 assert(ret == 0); 9260 9261 if (cb.cb_first) { 9262 (void) printf(gettext("All pools are formatted " 9263 "using feature flags.\n\n")); 9264 } else { 9265 (void) printf(gettext("\nUse 'zpool upgrade -v' " 9266 "for a list of available legacy versions.\n")); 9267 } 9268 9269 cb.cb_first = B_TRUE; 9270 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 9271 assert(ret == 0); 9272 9273 if (cb.cb_first) { 9274 (void) printf(gettext("Every feature flags pool has " 9275 "all supported and requested features enabled.\n")); 9276 } else { 9277 (void) printf(gettext("\n")); 9278 } 9279 } else { 9280 ret = for_each_pool(argc, argv, B_FALSE, NULL, B_FALSE, 9281 upgrade_one, &cb); 9282 } 9283 9284 return (ret); 9285 } 9286 9287 typedef struct hist_cbdata { 9288 boolean_t first; 9289 boolean_t longfmt; 9290 boolean_t internal; 9291 } hist_cbdata_t; 9292 9293 static void 9294 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb) 9295 { 9296 nvlist_t **records; 9297 uint_t numrecords; 9298 int i; 9299 9300 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 9301 &records, &numrecords) == 0); 9302 for (i = 0; i < numrecords; i++) { 9303 nvlist_t *rec = records[i]; 9304 char tbuf[64] = ""; 9305 9306 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 9307 time_t tsec; 9308 struct tm t; 9309 9310 tsec = fnvlist_lookup_uint64(records[i], 9311 ZPOOL_HIST_TIME); 9312 (void) localtime_r(&tsec, &t); 9313 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 9314 } 9315 9316 if (nvlist_exists(rec, ZPOOL_HIST_ELAPSED_NS)) { 9317 uint64_t elapsed_ns = fnvlist_lookup_int64(records[i], 9318 ZPOOL_HIST_ELAPSED_NS); 9319 (void) snprintf(tbuf + strlen(tbuf), 9320 sizeof (tbuf) - strlen(tbuf), 9321 " (%lldms)", (long long)elapsed_ns / 1000 / 1000); 9322 } 9323 9324 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 9325 (void) printf("%s %s", tbuf, 9326 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 9327 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 9328 int ievent = 9329 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 9330 if (!cb->internal) 9331 continue; 9332 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 9333 (void) printf("%s unrecognized record:\n", 9334 tbuf); 9335 dump_nvlist(rec, 4); 9336 continue; 9337 } 9338 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 9339 zfs_history_event_names[ievent], 9340 (longlong_t)fnvlist_lookup_uint64( 9341 rec, ZPOOL_HIST_TXG), 9342 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 9343 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 9344 if (!cb->internal) 9345 continue; 9346 (void) printf("%s [txg:%lld] %s", tbuf, 9347 (longlong_t)fnvlist_lookup_uint64( 9348 rec, ZPOOL_HIST_TXG), 9349 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 9350 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 9351 (void) printf(" %s (%llu)", 9352 fnvlist_lookup_string(rec, 9353 ZPOOL_HIST_DSNAME), 9354 (u_longlong_t)fnvlist_lookup_uint64(rec, 9355 ZPOOL_HIST_DSID)); 9356 } 9357 (void) printf(" %s", fnvlist_lookup_string(rec, 9358 ZPOOL_HIST_INT_STR)); 9359 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 9360 if (!cb->internal) 9361 continue; 9362 (void) printf("%s ioctl %s\n", tbuf, 9363 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 9364 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 9365 (void) printf(" input:\n"); 9366 dump_nvlist(fnvlist_lookup_nvlist(rec, 9367 ZPOOL_HIST_INPUT_NVL), 8); 9368 } 9369 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 9370 (void) printf(" output:\n"); 9371 dump_nvlist(fnvlist_lookup_nvlist(rec, 9372 ZPOOL_HIST_OUTPUT_NVL), 8); 9373 } 9374 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_SIZE)) { 9375 (void) printf(" output nvlist omitted; " 9376 "original size: %lldKB\n", 9377 (longlong_t)fnvlist_lookup_int64(rec, 9378 ZPOOL_HIST_OUTPUT_SIZE) / 1024); 9379 } 9380 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 9381 (void) printf(" errno: %lld\n", 9382 (longlong_t)fnvlist_lookup_int64(rec, 9383 ZPOOL_HIST_ERRNO)); 9384 } 9385 } else { 9386 if (!cb->internal) 9387 continue; 9388 (void) printf("%s unrecognized record:\n", tbuf); 9389 dump_nvlist(rec, 4); 9390 } 9391 9392 if (!cb->longfmt) { 9393 (void) printf("\n"); 9394 continue; 9395 } 9396 (void) printf(" ["); 9397 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 9398 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 9399 struct passwd *pwd = getpwuid(who); 9400 (void) printf("user %d ", (int)who); 9401 if (pwd != NULL) 9402 (void) printf("(%s) ", pwd->pw_name); 9403 } 9404 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 9405 (void) printf("on %s", 9406 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 9407 } 9408 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 9409 (void) printf(":%s", 9410 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 9411 } 9412 9413 (void) printf("]"); 9414 (void) printf("\n"); 9415 } 9416 } 9417 9418 /* 9419 * Print out the command history for a specific pool. 9420 */ 9421 static int 9422 get_history_one(zpool_handle_t *zhp, void *data) 9423 { 9424 nvlist_t *nvhis; 9425 int ret; 9426 hist_cbdata_t *cb = (hist_cbdata_t *)data; 9427 uint64_t off = 0; 9428 boolean_t eof = B_FALSE; 9429 9430 cb->first = B_FALSE; 9431 9432 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 9433 9434 while (!eof) { 9435 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0) 9436 return (ret); 9437 9438 print_history_records(nvhis, cb); 9439 nvlist_free(nvhis); 9440 } 9441 (void) printf("\n"); 9442 9443 return (ret); 9444 } 9445 9446 /* 9447 * zpool history <pool> 9448 * 9449 * Displays the history of commands that modified pools. 9450 */ 9451 int 9452 zpool_do_history(int argc, char **argv) 9453 { 9454 hist_cbdata_t cbdata = { 0 }; 9455 int ret; 9456 int c; 9457 9458 cbdata.first = B_TRUE; 9459 /* check options */ 9460 while ((c = getopt(argc, argv, "li")) != -1) { 9461 switch (c) { 9462 case 'l': 9463 cbdata.longfmt = B_TRUE; 9464 break; 9465 case 'i': 9466 cbdata.internal = B_TRUE; 9467 break; 9468 case '?': 9469 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9470 optopt); 9471 usage(B_FALSE); 9472 } 9473 } 9474 argc -= optind; 9475 argv += optind; 9476 9477 ret = for_each_pool(argc, argv, B_FALSE, NULL, B_FALSE, get_history_one, 9478 &cbdata); 9479 9480 if (argc == 0 && cbdata.first == B_TRUE) { 9481 (void) fprintf(stderr, gettext("no pools available\n")); 9482 return (0); 9483 } 9484 9485 return (ret); 9486 } 9487 9488 typedef struct ev_opts { 9489 int verbose; 9490 int scripted; 9491 int follow; 9492 int clear; 9493 char poolname[ZFS_MAX_DATASET_NAME_LEN]; 9494 } ev_opts_t; 9495 9496 static void 9497 zpool_do_events_short(nvlist_t *nvl, ev_opts_t *opts) 9498 { 9499 char ctime_str[26], str[32], *ptr; 9500 int64_t *tv; 9501 uint_t n; 9502 9503 verify(nvlist_lookup_int64_array(nvl, FM_EREPORT_TIME, &tv, &n) == 0); 9504 memset(str, ' ', 32); 9505 (void) ctime_r((const time_t *)&tv[0], ctime_str); 9506 (void) memcpy(str, ctime_str+4, 6); /* 'Jun 30' */ 9507 (void) memcpy(str+7, ctime_str+20, 4); /* '1993' */ 9508 (void) memcpy(str+12, ctime_str+11, 8); /* '21:49:08' */ 9509 (void) sprintf(str+20, ".%09lld", (longlong_t)tv[1]); /* '.123456789' */ 9510 if (opts->scripted) 9511 (void) printf(gettext("%s\t"), str); 9512 else 9513 (void) printf(gettext("%s "), str); 9514 9515 verify(nvlist_lookup_string(nvl, FM_CLASS, &ptr) == 0); 9516 (void) printf(gettext("%s\n"), ptr); 9517 } 9518 9519 static void 9520 zpool_do_events_nvprint(nvlist_t *nvl, int depth) 9521 { 9522 nvpair_t *nvp; 9523 9524 for (nvp = nvlist_next_nvpair(nvl, NULL); 9525 nvp != NULL; nvp = nvlist_next_nvpair(nvl, nvp)) { 9526 9527 data_type_t type = nvpair_type(nvp); 9528 const char *name = nvpair_name(nvp); 9529 9530 boolean_t b; 9531 uint8_t i8; 9532 uint16_t i16; 9533 uint32_t i32; 9534 uint64_t i64; 9535 char *str; 9536 nvlist_t *cnv; 9537 9538 printf(gettext("%*s%s = "), depth, "", name); 9539 9540 switch (type) { 9541 case DATA_TYPE_BOOLEAN: 9542 printf(gettext("%s"), "1"); 9543 break; 9544 9545 case DATA_TYPE_BOOLEAN_VALUE: 9546 (void) nvpair_value_boolean_value(nvp, &b); 9547 printf(gettext("%s"), b ? "1" : "0"); 9548 break; 9549 9550 case DATA_TYPE_BYTE: 9551 (void) nvpair_value_byte(nvp, &i8); 9552 printf(gettext("0x%x"), i8); 9553 break; 9554 9555 case DATA_TYPE_INT8: 9556 (void) nvpair_value_int8(nvp, (void *)&i8); 9557 printf(gettext("0x%x"), i8); 9558 break; 9559 9560 case DATA_TYPE_UINT8: 9561 (void) nvpair_value_uint8(nvp, &i8); 9562 printf(gettext("0x%x"), i8); 9563 break; 9564 9565 case DATA_TYPE_INT16: 9566 (void) nvpair_value_int16(nvp, (void *)&i16); 9567 printf(gettext("0x%x"), i16); 9568 break; 9569 9570 case DATA_TYPE_UINT16: 9571 (void) nvpair_value_uint16(nvp, &i16); 9572 printf(gettext("0x%x"), i16); 9573 break; 9574 9575 case DATA_TYPE_INT32: 9576 (void) nvpair_value_int32(nvp, (void *)&i32); 9577 printf(gettext("0x%x"), i32); 9578 break; 9579 9580 case DATA_TYPE_UINT32: 9581 (void) nvpair_value_uint32(nvp, &i32); 9582 printf(gettext("0x%x"), i32); 9583 break; 9584 9585 case DATA_TYPE_INT64: 9586 (void) nvpair_value_int64(nvp, (void *)&i64); 9587 printf(gettext("0x%llx"), (u_longlong_t)i64); 9588 break; 9589 9590 case DATA_TYPE_UINT64: 9591 (void) nvpair_value_uint64(nvp, &i64); 9592 /* 9593 * translate vdev state values to readable 9594 * strings to aide zpool events consumers 9595 */ 9596 if (strcmp(name, 9597 FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 || 9598 strcmp(name, 9599 FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) { 9600 printf(gettext("\"%s\" (0x%llx)"), 9601 zpool_state_to_name(i64, VDEV_AUX_NONE), 9602 (u_longlong_t)i64); 9603 } else { 9604 printf(gettext("0x%llx"), (u_longlong_t)i64); 9605 } 9606 break; 9607 9608 case DATA_TYPE_HRTIME: 9609 (void) nvpair_value_hrtime(nvp, (void *)&i64); 9610 printf(gettext("0x%llx"), (u_longlong_t)i64); 9611 break; 9612 9613 case DATA_TYPE_STRING: 9614 (void) nvpair_value_string(nvp, &str); 9615 printf(gettext("\"%s\""), str ? str : "<NULL>"); 9616 break; 9617 9618 case DATA_TYPE_NVLIST: 9619 printf(gettext("(embedded nvlist)\n")); 9620 (void) nvpair_value_nvlist(nvp, &cnv); 9621 zpool_do_events_nvprint(cnv, depth + 8); 9622 printf(gettext("%*s(end %s)"), depth, "", name); 9623 break; 9624 9625 case DATA_TYPE_NVLIST_ARRAY: { 9626 nvlist_t **val; 9627 uint_t i, nelem; 9628 9629 (void) nvpair_value_nvlist_array(nvp, &val, &nelem); 9630 printf(gettext("(%d embedded nvlists)\n"), nelem); 9631 for (i = 0; i < nelem; i++) { 9632 printf(gettext("%*s%s[%d] = %s\n"), 9633 depth, "", name, i, "(embedded nvlist)"); 9634 zpool_do_events_nvprint(val[i], depth + 8); 9635 printf(gettext("%*s(end %s[%i])\n"), 9636 depth, "", name, i); 9637 } 9638 printf(gettext("%*s(end %s)\n"), depth, "", name); 9639 } 9640 break; 9641 9642 case DATA_TYPE_INT8_ARRAY: { 9643 int8_t *val; 9644 uint_t i, nelem; 9645 9646 (void) nvpair_value_int8_array(nvp, &val, &nelem); 9647 for (i = 0; i < nelem; i++) 9648 printf(gettext("0x%x "), val[i]); 9649 9650 break; 9651 } 9652 9653 case DATA_TYPE_UINT8_ARRAY: { 9654 uint8_t *val; 9655 uint_t i, nelem; 9656 9657 (void) nvpair_value_uint8_array(nvp, &val, &nelem); 9658 for (i = 0; i < nelem; i++) 9659 printf(gettext("0x%x "), val[i]); 9660 9661 break; 9662 } 9663 9664 case DATA_TYPE_INT16_ARRAY: { 9665 int16_t *val; 9666 uint_t i, nelem; 9667 9668 (void) nvpair_value_int16_array(nvp, &val, &nelem); 9669 for (i = 0; i < nelem; i++) 9670 printf(gettext("0x%x "), val[i]); 9671 9672 break; 9673 } 9674 9675 case DATA_TYPE_UINT16_ARRAY: { 9676 uint16_t *val; 9677 uint_t i, nelem; 9678 9679 (void) nvpair_value_uint16_array(nvp, &val, &nelem); 9680 for (i = 0; i < nelem; i++) 9681 printf(gettext("0x%x "), val[i]); 9682 9683 break; 9684 } 9685 9686 case DATA_TYPE_INT32_ARRAY: { 9687 int32_t *val; 9688 uint_t i, nelem; 9689 9690 (void) nvpair_value_int32_array(nvp, &val, &nelem); 9691 for (i = 0; i < nelem; i++) 9692 printf(gettext("0x%x "), val[i]); 9693 9694 break; 9695 } 9696 9697 case DATA_TYPE_UINT32_ARRAY: { 9698 uint32_t *val; 9699 uint_t i, nelem; 9700 9701 (void) nvpair_value_uint32_array(nvp, &val, &nelem); 9702 for (i = 0; i < nelem; i++) 9703 printf(gettext("0x%x "), val[i]); 9704 9705 break; 9706 } 9707 9708 case DATA_TYPE_INT64_ARRAY: { 9709 int64_t *val; 9710 uint_t i, nelem; 9711 9712 (void) nvpair_value_int64_array(nvp, &val, &nelem); 9713 for (i = 0; i < nelem; i++) 9714 printf(gettext("0x%llx "), 9715 (u_longlong_t)val[i]); 9716 9717 break; 9718 } 9719 9720 case DATA_TYPE_UINT64_ARRAY: { 9721 uint64_t *val; 9722 uint_t i, nelem; 9723 9724 (void) nvpair_value_uint64_array(nvp, &val, &nelem); 9725 for (i = 0; i < nelem; i++) 9726 printf(gettext("0x%llx "), 9727 (u_longlong_t)val[i]); 9728 9729 break; 9730 } 9731 9732 case DATA_TYPE_STRING_ARRAY: { 9733 char **str; 9734 uint_t i, nelem; 9735 9736 (void) nvpair_value_string_array(nvp, &str, &nelem); 9737 for (i = 0; i < nelem; i++) 9738 printf(gettext("\"%s\" "), 9739 str[i] ? str[i] : "<NULL>"); 9740 9741 break; 9742 } 9743 9744 case DATA_TYPE_BOOLEAN_ARRAY: 9745 case DATA_TYPE_BYTE_ARRAY: 9746 case DATA_TYPE_DOUBLE: 9747 case DATA_TYPE_DONTCARE: 9748 case DATA_TYPE_UNKNOWN: 9749 printf(gettext("<unknown>")); 9750 break; 9751 } 9752 9753 printf(gettext("\n")); 9754 } 9755 } 9756 9757 static int 9758 zpool_do_events_next(ev_opts_t *opts) 9759 { 9760 nvlist_t *nvl; 9761 int zevent_fd, ret, dropped; 9762 char *pool; 9763 9764 zevent_fd = open(ZFS_DEV, O_RDWR); 9765 VERIFY(zevent_fd >= 0); 9766 9767 if (!opts->scripted) 9768 (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS"); 9769 9770 while (1) { 9771 ret = zpool_events_next(g_zfs, &nvl, &dropped, 9772 (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd); 9773 if (ret || nvl == NULL) 9774 break; 9775 9776 if (dropped > 0) 9777 (void) printf(gettext("dropped %d events\n"), dropped); 9778 9779 if (strlen(opts->poolname) > 0 && 9780 nvlist_lookup_string(nvl, FM_FMRI_ZFS_POOL, &pool) == 0 && 9781 strcmp(opts->poolname, pool) != 0) 9782 continue; 9783 9784 zpool_do_events_short(nvl, opts); 9785 9786 if (opts->verbose) { 9787 zpool_do_events_nvprint(nvl, 8); 9788 printf(gettext("\n")); 9789 } 9790 (void) fflush(stdout); 9791 9792 nvlist_free(nvl); 9793 } 9794 9795 VERIFY(0 == close(zevent_fd)); 9796 9797 return (ret); 9798 } 9799 9800 static int 9801 zpool_do_events_clear(ev_opts_t *opts) 9802 { 9803 int count, ret; 9804 9805 ret = zpool_events_clear(g_zfs, &count); 9806 if (!ret) 9807 (void) printf(gettext("cleared %d events\n"), count); 9808 9809 return (ret); 9810 } 9811 9812 /* 9813 * zpool events [-vHf [pool] | -c] 9814 * 9815 * Displays events logs by ZFS. 9816 */ 9817 int 9818 zpool_do_events(int argc, char **argv) 9819 { 9820 ev_opts_t opts = { 0 }; 9821 int ret; 9822 int c; 9823 9824 /* check options */ 9825 while ((c = getopt(argc, argv, "vHfc")) != -1) { 9826 switch (c) { 9827 case 'v': 9828 opts.verbose = 1; 9829 break; 9830 case 'H': 9831 opts.scripted = 1; 9832 break; 9833 case 'f': 9834 opts.follow = 1; 9835 break; 9836 case 'c': 9837 opts.clear = 1; 9838 break; 9839 case '?': 9840 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 9841 optopt); 9842 usage(B_FALSE); 9843 } 9844 } 9845 argc -= optind; 9846 argv += optind; 9847 9848 if (argc > 1) { 9849 (void) fprintf(stderr, gettext("too many arguments\n")); 9850 usage(B_FALSE); 9851 } else if (argc == 1) { 9852 (void) strlcpy(opts.poolname, argv[0], sizeof (opts.poolname)); 9853 if (!zfs_name_valid(opts.poolname, ZFS_TYPE_POOL)) { 9854 (void) fprintf(stderr, 9855 gettext("invalid pool name '%s'\n"), opts.poolname); 9856 usage(B_FALSE); 9857 } 9858 } 9859 9860 if ((argc == 1 || opts.verbose || opts.scripted || opts.follow) && 9861 opts.clear) { 9862 (void) fprintf(stderr, 9863 gettext("invalid options combined with -c\n")); 9864 usage(B_FALSE); 9865 } 9866 9867 if (opts.clear) 9868 ret = zpool_do_events_clear(&opts); 9869 else 9870 ret = zpool_do_events_next(&opts); 9871 9872 return (ret); 9873 } 9874 9875 static int 9876 get_callback(zpool_handle_t *zhp, void *data) 9877 { 9878 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 9879 char value[MAXNAMELEN]; 9880 zprop_source_t srctype; 9881 zprop_list_t *pl; 9882 9883 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 9884 9885 /* 9886 * Skip the special fake placeholder. This will also skip 9887 * over the name property when 'all' is specified. 9888 */ 9889 if (pl->pl_prop == ZPOOL_PROP_NAME && 9890 pl == cbp->cb_proplist) 9891 continue; 9892 9893 if (pl->pl_prop == ZPROP_INVAL && 9894 (zpool_prop_feature(pl->pl_user_prop) || 9895 zpool_prop_unsupported(pl->pl_user_prop))) { 9896 srctype = ZPROP_SRC_LOCAL; 9897 9898 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 9899 value, sizeof (value)) == 0) { 9900 zprop_print_one_property(zpool_get_name(zhp), 9901 cbp, pl->pl_user_prop, value, srctype, 9902 NULL, NULL); 9903 } 9904 } else { 9905 if (zpool_get_prop(zhp, pl->pl_prop, value, 9906 sizeof (value), &srctype, cbp->cb_literal) != 0) 9907 continue; 9908 9909 zprop_print_one_property(zpool_get_name(zhp), cbp, 9910 zpool_prop_to_name(pl->pl_prop), value, srctype, 9911 NULL, NULL); 9912 } 9913 } 9914 return (0); 9915 } 9916 9917 /* 9918 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 9919 * 9920 * -H Scripted mode. Don't display headers, and separate properties 9921 * by a single tab. 9922 * -o List of columns to display. Defaults to 9923 * "name,property,value,source". 9924 * -p Display values in parsable (exact) format. 9925 * 9926 * Get properties of pools in the system. Output space statistics 9927 * for each one as well as other attributes. 9928 */ 9929 int 9930 zpool_do_get(int argc, char **argv) 9931 { 9932 zprop_get_cbdata_t cb = { 0 }; 9933 zprop_list_t fake_name = { 0 }; 9934 int ret; 9935 int c, i; 9936 char *value; 9937 9938 cb.cb_first = B_TRUE; 9939 9940 /* 9941 * Set up default columns and sources. 9942 */ 9943 cb.cb_sources = ZPROP_SRC_ALL; 9944 cb.cb_columns[0] = GET_COL_NAME; 9945 cb.cb_columns[1] = GET_COL_PROPERTY; 9946 cb.cb_columns[2] = GET_COL_VALUE; 9947 cb.cb_columns[3] = GET_COL_SOURCE; 9948 cb.cb_type = ZFS_TYPE_POOL; 9949 9950 /* check options */ 9951 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 9952 switch (c) { 9953 case 'p': 9954 cb.cb_literal = B_TRUE; 9955 break; 9956 case 'H': 9957 cb.cb_scripted = B_TRUE; 9958 break; 9959 case 'o': 9960 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 9961 i = 0; 9962 while (*optarg != '\0') { 9963 static char *col_subopts[] = 9964 { "name", "property", "value", "source", 9965 "all", NULL }; 9966 9967 if (i == ZFS_GET_NCOLS) { 9968 (void) fprintf(stderr, gettext("too " 9969 "many fields given to -o " 9970 "option\n")); 9971 usage(B_FALSE); 9972 } 9973 9974 switch (getsubopt(&optarg, col_subopts, 9975 &value)) { 9976 case 0: 9977 cb.cb_columns[i++] = GET_COL_NAME; 9978 break; 9979 case 1: 9980 cb.cb_columns[i++] = GET_COL_PROPERTY; 9981 break; 9982 case 2: 9983 cb.cb_columns[i++] = GET_COL_VALUE; 9984 break; 9985 case 3: 9986 cb.cb_columns[i++] = GET_COL_SOURCE; 9987 break; 9988 case 4: 9989 if (i > 0) { 9990 (void) fprintf(stderr, 9991 gettext("\"all\" conflicts " 9992 "with specific fields " 9993 "given to -o option\n")); 9994 usage(B_FALSE); 9995 } 9996 cb.cb_columns[0] = GET_COL_NAME; 9997 cb.cb_columns[1] = GET_COL_PROPERTY; 9998 cb.cb_columns[2] = GET_COL_VALUE; 9999 cb.cb_columns[3] = GET_COL_SOURCE; 10000 i = ZFS_GET_NCOLS; 10001 break; 10002 default: 10003 (void) fprintf(stderr, 10004 gettext("invalid column name " 10005 "'%s'\n"), value); 10006 usage(B_FALSE); 10007 } 10008 } 10009 break; 10010 case '?': 10011 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 10012 optopt); 10013 usage(B_FALSE); 10014 } 10015 } 10016 10017 argc -= optind; 10018 argv += optind; 10019 10020 if (argc < 1) { 10021 (void) fprintf(stderr, gettext("missing property " 10022 "argument\n")); 10023 usage(B_FALSE); 10024 } 10025 10026 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 10027 ZFS_TYPE_POOL) != 0) 10028 usage(B_FALSE); 10029 10030 argc--; 10031 argv++; 10032 10033 if (cb.cb_proplist != NULL) { 10034 fake_name.pl_prop = ZPOOL_PROP_NAME; 10035 fake_name.pl_width = strlen(gettext("NAME")); 10036 fake_name.pl_next = cb.cb_proplist; 10037 cb.cb_proplist = &fake_name; 10038 } 10039 10040 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, cb.cb_literal, 10041 get_callback, &cb); 10042 10043 if (cb.cb_proplist == &fake_name) 10044 zprop_free_list(fake_name.pl_next); 10045 else 10046 zprop_free_list(cb.cb_proplist); 10047 10048 return (ret); 10049 } 10050 10051 typedef struct set_cbdata { 10052 char *cb_propname; 10053 char *cb_value; 10054 boolean_t cb_any_successful; 10055 } set_cbdata_t; 10056 10057 static int 10058 set_callback(zpool_handle_t *zhp, void *data) 10059 { 10060 int error; 10061 set_cbdata_t *cb = (set_cbdata_t *)data; 10062 10063 /* Check if we have out-of-bounds features */ 10064 if (strcmp(cb->cb_propname, ZPOOL_CONFIG_COMPATIBILITY) == 0) { 10065 boolean_t features[SPA_FEATURES]; 10066 if (zpool_do_load_compat(cb->cb_value, features) != 10067 ZPOOL_COMPATIBILITY_OK) 10068 return (-1); 10069 10070 nvlist_t *enabled = zpool_get_features(zhp); 10071 spa_feature_t i; 10072 for (i = 0; i < SPA_FEATURES; i++) { 10073 const char *fguid = spa_feature_table[i].fi_guid; 10074 if (nvlist_exists(enabled, fguid) && !features[i]) 10075 break; 10076 } 10077 if (i < SPA_FEATURES) 10078 (void) fprintf(stderr, gettext("Warning: one or " 10079 "more features already enabled on pool '%s'\n" 10080 "are not present in this compatibility set.\n"), 10081 zpool_get_name(zhp)); 10082 } 10083 10084 /* if we're setting a feature, check it's in compatibility set */ 10085 if (zpool_prop_feature(cb->cb_propname) && 10086 strcmp(cb->cb_value, ZFS_FEATURE_ENABLED) == 0) { 10087 char *fname = strchr(cb->cb_propname, '@') + 1; 10088 spa_feature_t f; 10089 10090 if (zfeature_lookup_name(fname, &f) == 0) { 10091 char compat[ZFS_MAXPROPLEN]; 10092 if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, 10093 compat, ZFS_MAXPROPLEN, NULL, B_FALSE) != 0) 10094 compat[0] = '\0'; 10095 10096 boolean_t features[SPA_FEATURES]; 10097 if (zpool_do_load_compat(compat, features) != 10098 ZPOOL_COMPATIBILITY_OK) { 10099 (void) fprintf(stderr, gettext("Error: " 10100 "cannot enable feature '%s' on pool '%s'\n" 10101 "because the pool's 'compatibility' " 10102 "property cannot be parsed.\n"), 10103 fname, zpool_get_name(zhp)); 10104 return (-1); 10105 } 10106 10107 if (!features[f]) { 10108 (void) fprintf(stderr, gettext("Error: " 10109 "cannot enable feature '%s' on pool '%s'\n" 10110 "as it is not specified in this pool's " 10111 "current compatibility set.\n" 10112 "Consider setting 'compatibility' to a " 10113 "less restrictive set, or to 'off'.\n"), 10114 fname, zpool_get_name(zhp)); 10115 return (-1); 10116 } 10117 } 10118 } 10119 10120 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 10121 10122 if (!error) 10123 cb->cb_any_successful = B_TRUE; 10124 10125 return (error); 10126 } 10127 10128 int 10129 zpool_do_set(int argc, char **argv) 10130 { 10131 set_cbdata_t cb = { 0 }; 10132 int error; 10133 10134 if (argc > 1 && argv[1][0] == '-') { 10135 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 10136 argv[1][1]); 10137 usage(B_FALSE); 10138 } 10139 10140 if (argc < 2) { 10141 (void) fprintf(stderr, gettext("missing property=value " 10142 "argument\n")); 10143 usage(B_FALSE); 10144 } 10145 10146 if (argc < 3) { 10147 (void) fprintf(stderr, gettext("missing pool name\n")); 10148 usage(B_FALSE); 10149 } 10150 10151 if (argc > 3) { 10152 (void) fprintf(stderr, gettext("too many pool names\n")); 10153 usage(B_FALSE); 10154 } 10155 10156 cb.cb_propname = argv[1]; 10157 cb.cb_value = strchr(cb.cb_propname, '='); 10158 if (cb.cb_value == NULL) { 10159 (void) fprintf(stderr, gettext("missing value in " 10160 "property=value argument\n")); 10161 usage(B_FALSE); 10162 } 10163 10164 *(cb.cb_value) = '\0'; 10165 cb.cb_value++; 10166 10167 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, B_FALSE, 10168 set_callback, &cb); 10169 10170 return (error); 10171 } 10172 10173 /* Add up the total number of bytes left to initialize/trim across all vdevs */ 10174 static uint64_t 10175 vdev_activity_remaining(nvlist_t *nv, zpool_wait_activity_t activity) 10176 { 10177 uint64_t bytes_remaining; 10178 nvlist_t **child; 10179 uint_t c, children; 10180 vdev_stat_t *vs; 10181 10182 assert(activity == ZPOOL_WAIT_INITIALIZE || 10183 activity == ZPOOL_WAIT_TRIM); 10184 10185 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 10186 (uint64_t **)&vs, &c) == 0); 10187 10188 if (activity == ZPOOL_WAIT_INITIALIZE && 10189 vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) 10190 bytes_remaining = vs->vs_initialize_bytes_est - 10191 vs->vs_initialize_bytes_done; 10192 else if (activity == ZPOOL_WAIT_TRIM && 10193 vs->vs_trim_state == VDEV_TRIM_ACTIVE) 10194 bytes_remaining = vs->vs_trim_bytes_est - 10195 vs->vs_trim_bytes_done; 10196 else 10197 bytes_remaining = 0; 10198 10199 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10200 &child, &children) != 0) 10201 children = 0; 10202 10203 for (c = 0; c < children; c++) 10204 bytes_remaining += vdev_activity_remaining(child[c], activity); 10205 10206 return (bytes_remaining); 10207 } 10208 10209 /* Add up the total number of bytes left to rebuild across top-level vdevs */ 10210 static uint64_t 10211 vdev_activity_top_remaining(nvlist_t *nv) 10212 { 10213 uint64_t bytes_remaining = 0; 10214 nvlist_t **child; 10215 uint_t children; 10216 int error; 10217 10218 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10219 &child, &children) != 0) 10220 children = 0; 10221 10222 for (uint_t c = 0; c < children; c++) { 10223 vdev_rebuild_stat_t *vrs; 10224 uint_t i; 10225 10226 error = nvlist_lookup_uint64_array(child[c], 10227 ZPOOL_CONFIG_REBUILD_STATS, (uint64_t **)&vrs, &i); 10228 if (error == 0) { 10229 if (vrs->vrs_state == VDEV_REBUILD_ACTIVE) { 10230 bytes_remaining += (vrs->vrs_bytes_est - 10231 vrs->vrs_bytes_rebuilt); 10232 } 10233 } 10234 } 10235 10236 return (bytes_remaining); 10237 } 10238 10239 /* Whether any vdevs are 'spare' or 'replacing' vdevs */ 10240 static boolean_t 10241 vdev_any_spare_replacing(nvlist_t *nv) 10242 { 10243 nvlist_t **child; 10244 uint_t c, children; 10245 char *vdev_type; 10246 10247 (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &vdev_type); 10248 10249 if (strcmp(vdev_type, VDEV_TYPE_REPLACING) == 0 || 10250 strcmp(vdev_type, VDEV_TYPE_SPARE) == 0 || 10251 strcmp(vdev_type, VDEV_TYPE_DRAID_SPARE) == 0) { 10252 return (B_TRUE); 10253 } 10254 10255 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 10256 &child, &children) != 0) 10257 children = 0; 10258 10259 for (c = 0; c < children; c++) { 10260 if (vdev_any_spare_replacing(child[c])) 10261 return (B_TRUE); 10262 } 10263 10264 return (B_FALSE); 10265 } 10266 10267 typedef struct wait_data { 10268 char *wd_poolname; 10269 boolean_t wd_scripted; 10270 boolean_t wd_exact; 10271 boolean_t wd_headers_once; 10272 boolean_t wd_should_exit; 10273 /* Which activities to wait for */ 10274 boolean_t wd_enabled[ZPOOL_WAIT_NUM_ACTIVITIES]; 10275 float wd_interval; 10276 pthread_cond_t wd_cv; 10277 pthread_mutex_t wd_mutex; 10278 } wait_data_t; 10279 10280 /* 10281 * Print to stdout a single line, containing one column for each activity that 10282 * we are waiting for specifying how many bytes of work are left for that 10283 * activity. 10284 */ 10285 static void 10286 print_wait_status_row(wait_data_t *wd, zpool_handle_t *zhp, int row) 10287 { 10288 nvlist_t *config, *nvroot; 10289 uint_t c; 10290 int i; 10291 pool_checkpoint_stat_t *pcs = NULL; 10292 pool_scan_stat_t *pss = NULL; 10293 pool_removal_stat_t *prs = NULL; 10294 char *headers[] = {"DISCARD", "FREE", "INITIALIZE", "REPLACE", 10295 "REMOVE", "RESILVER", "SCRUB", "TRIM"}; 10296 int col_widths[ZPOOL_WAIT_NUM_ACTIVITIES]; 10297 10298 /* Calculate the width of each column */ 10299 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10300 /* 10301 * Make sure we have enough space in the col for pretty-printed 10302 * numbers and for the column header, and then leave a couple 10303 * spaces between cols for readability. 10304 */ 10305 col_widths[i] = MAX(strlen(headers[i]), 6) + 2; 10306 } 10307 10308 /* Print header if appropriate */ 10309 int term_height = terminal_height(); 10310 boolean_t reprint_header = (!wd->wd_headers_once && term_height > 0 && 10311 row % (term_height-1) == 0); 10312 if (!wd->wd_scripted && (row == 0 || reprint_header)) { 10313 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10314 if (wd->wd_enabled[i]) 10315 (void) printf("%*s", col_widths[i], headers[i]); 10316 } 10317 (void) printf("\n"); 10318 } 10319 10320 /* Bytes of work remaining in each activity */ 10321 int64_t bytes_rem[ZPOOL_WAIT_NUM_ACTIVITIES] = {0}; 10322 10323 bytes_rem[ZPOOL_WAIT_FREE] = 10324 zpool_get_prop_int(zhp, ZPOOL_PROP_FREEING, NULL); 10325 10326 config = zpool_get_config(zhp, NULL); 10327 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 10328 10329 (void) nvlist_lookup_uint64_array(nvroot, 10330 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 10331 if (pcs != NULL && pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 10332 bytes_rem[ZPOOL_WAIT_CKPT_DISCARD] = pcs->pcs_space; 10333 10334 (void) nvlist_lookup_uint64_array(nvroot, 10335 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 10336 if (prs != NULL && prs->prs_state == DSS_SCANNING) 10337 bytes_rem[ZPOOL_WAIT_REMOVE] = prs->prs_to_copy - 10338 prs->prs_copied; 10339 10340 (void) nvlist_lookup_uint64_array(nvroot, 10341 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&pss, &c); 10342 if (pss != NULL && pss->pss_state == DSS_SCANNING && 10343 pss->pss_pass_scrub_pause == 0) { 10344 int64_t rem = pss->pss_to_examine - pss->pss_issued; 10345 if (pss->pss_func == POOL_SCAN_SCRUB) 10346 bytes_rem[ZPOOL_WAIT_SCRUB] = rem; 10347 else 10348 bytes_rem[ZPOOL_WAIT_RESILVER] = rem; 10349 } else if (check_rebuilding(nvroot, NULL)) { 10350 bytes_rem[ZPOOL_WAIT_RESILVER] = 10351 vdev_activity_top_remaining(nvroot); 10352 } 10353 10354 bytes_rem[ZPOOL_WAIT_INITIALIZE] = 10355 vdev_activity_remaining(nvroot, ZPOOL_WAIT_INITIALIZE); 10356 bytes_rem[ZPOOL_WAIT_TRIM] = 10357 vdev_activity_remaining(nvroot, ZPOOL_WAIT_TRIM); 10358 10359 /* 10360 * A replace finishes after resilvering finishes, so the amount of work 10361 * left for a replace is the same as for resilvering. 10362 * 10363 * It isn't quite correct to say that if we have any 'spare' or 10364 * 'replacing' vdevs and a resilver is happening, then a replace is in 10365 * progress, like we do here. When a hot spare is used, the faulted vdev 10366 * is not removed after the hot spare is resilvered, so parent 'spare' 10367 * vdev is not removed either. So we could have a 'spare' vdev, but be 10368 * resilvering for a different reason. However, we use it as a heuristic 10369 * because we don't have access to the DTLs, which could tell us whether 10370 * or not we have really finished resilvering a hot spare. 10371 */ 10372 if (vdev_any_spare_replacing(nvroot)) 10373 bytes_rem[ZPOOL_WAIT_REPLACE] = bytes_rem[ZPOOL_WAIT_RESILVER]; 10374 10375 if (timestamp_fmt != NODATE) 10376 print_timestamp(timestamp_fmt); 10377 10378 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10379 char buf[64]; 10380 if (!wd->wd_enabled[i]) 10381 continue; 10382 10383 if (wd->wd_exact) 10384 (void) snprintf(buf, sizeof (buf), "%" PRIi64, 10385 bytes_rem[i]); 10386 else 10387 zfs_nicenum(bytes_rem[i], buf, sizeof (buf)); 10388 10389 if (wd->wd_scripted) 10390 (void) printf(i == 0 ? "%s" : "\t%s", buf); 10391 else 10392 (void) printf(" %*s", col_widths[i] - 1, buf); 10393 } 10394 (void) printf("\n"); 10395 (void) fflush(stdout); 10396 } 10397 10398 static void * 10399 wait_status_thread(void *arg) 10400 { 10401 wait_data_t *wd = (wait_data_t *)arg; 10402 zpool_handle_t *zhp; 10403 10404 if ((zhp = zpool_open(g_zfs, wd->wd_poolname)) == NULL) 10405 return (void *)(1); 10406 10407 for (int row = 0; ; row++) { 10408 boolean_t missing; 10409 struct timespec timeout; 10410 int ret = 0; 10411 (void) clock_gettime(CLOCK_REALTIME, &timeout); 10412 10413 if (zpool_refresh_stats(zhp, &missing) != 0 || missing || 10414 zpool_props_refresh(zhp) != 0) { 10415 zpool_close(zhp); 10416 return (void *)(uintptr_t)(missing ? 0 : 1); 10417 } 10418 10419 print_wait_status_row(wd, zhp, row); 10420 10421 timeout.tv_sec += floor(wd->wd_interval); 10422 long nanos = timeout.tv_nsec + 10423 (wd->wd_interval - floor(wd->wd_interval)) * NANOSEC; 10424 if (nanos >= NANOSEC) { 10425 timeout.tv_sec++; 10426 timeout.tv_nsec = nanos - NANOSEC; 10427 } else { 10428 timeout.tv_nsec = nanos; 10429 } 10430 pthread_mutex_lock(&wd->wd_mutex); 10431 if (!wd->wd_should_exit) 10432 ret = pthread_cond_timedwait(&wd->wd_cv, &wd->wd_mutex, 10433 &timeout); 10434 pthread_mutex_unlock(&wd->wd_mutex); 10435 if (ret == 0) { 10436 break; /* signaled by main thread */ 10437 } else if (ret != ETIMEDOUT) { 10438 (void) fprintf(stderr, gettext("pthread_cond_timedwait " 10439 "failed: %s\n"), strerror(ret)); 10440 zpool_close(zhp); 10441 return (void *)(uintptr_t)(1); 10442 } 10443 } 10444 10445 zpool_close(zhp); 10446 return (void *)(0); 10447 } 10448 10449 int 10450 zpool_do_wait(int argc, char **argv) 10451 { 10452 boolean_t verbose = B_FALSE; 10453 int c; 10454 char *value; 10455 int i; 10456 unsigned long count; 10457 pthread_t status_thr; 10458 int error = 0; 10459 zpool_handle_t *zhp; 10460 10461 wait_data_t wd; 10462 wd.wd_scripted = B_FALSE; 10463 wd.wd_exact = B_FALSE; 10464 wd.wd_headers_once = B_FALSE; 10465 wd.wd_should_exit = B_FALSE; 10466 10467 pthread_mutex_init(&wd.wd_mutex, NULL); 10468 pthread_cond_init(&wd.wd_cv, NULL); 10469 10470 /* By default, wait for all types of activity. */ 10471 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) 10472 wd.wd_enabled[i] = B_TRUE; 10473 10474 while ((c = getopt(argc, argv, "HpT:t:")) != -1) { 10475 switch (c) { 10476 case 'H': 10477 wd.wd_scripted = B_TRUE; 10478 break; 10479 case 'n': 10480 wd.wd_headers_once = B_TRUE; 10481 break; 10482 case 'p': 10483 wd.wd_exact = B_TRUE; 10484 break; 10485 case 'T': 10486 get_timestamp_arg(*optarg); 10487 break; 10488 case 't': 10489 { 10490 static char *col_subopts[] = { "discard", "free", 10491 "initialize", "replace", "remove", "resilver", 10492 "scrub", "trim", NULL }; 10493 10494 /* Reset activities array */ 10495 bzero(&wd.wd_enabled, sizeof (wd.wd_enabled)); 10496 while (*optarg != '\0') { 10497 int activity = getsubopt(&optarg, col_subopts, 10498 &value); 10499 10500 if (activity < 0) { 10501 (void) fprintf(stderr, 10502 gettext("invalid activity '%s'\n"), 10503 value); 10504 usage(B_FALSE); 10505 } 10506 10507 wd.wd_enabled[activity] = B_TRUE; 10508 } 10509 break; 10510 } 10511 case '?': 10512 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 10513 optopt); 10514 usage(B_FALSE); 10515 } 10516 } 10517 10518 argc -= optind; 10519 argv += optind; 10520 10521 get_interval_count(&argc, argv, &wd.wd_interval, &count); 10522 if (count != 0) { 10523 /* This subcmd only accepts an interval, not a count */ 10524 (void) fprintf(stderr, gettext("too many arguments\n")); 10525 usage(B_FALSE); 10526 } 10527 10528 if (wd.wd_interval != 0) 10529 verbose = B_TRUE; 10530 10531 if (argc < 1) { 10532 (void) fprintf(stderr, gettext("missing 'pool' argument\n")); 10533 usage(B_FALSE); 10534 } 10535 if (argc > 1) { 10536 (void) fprintf(stderr, gettext("too many arguments\n")); 10537 usage(B_FALSE); 10538 } 10539 10540 wd.wd_poolname = argv[0]; 10541 10542 if ((zhp = zpool_open(g_zfs, wd.wd_poolname)) == NULL) 10543 return (1); 10544 10545 if (verbose) { 10546 /* 10547 * We use a separate thread for printing status updates because 10548 * the main thread will call lzc_wait(), which blocks as long 10549 * as an activity is in progress, which can be a long time. 10550 */ 10551 if (pthread_create(&status_thr, NULL, wait_status_thread, &wd) 10552 != 0) { 10553 (void) fprintf(stderr, gettext("failed to create status" 10554 "thread: %s\n"), strerror(errno)); 10555 zpool_close(zhp); 10556 return (1); 10557 } 10558 } 10559 10560 /* 10561 * Loop over all activities that we are supposed to wait for until none 10562 * of them are in progress. Note that this means we can end up waiting 10563 * for more activities to complete than just those that were in progress 10564 * when we began waiting; if an activity we are interested in begins 10565 * while we are waiting for another activity, we will wait for both to 10566 * complete before exiting. 10567 */ 10568 for (;;) { 10569 boolean_t missing = B_FALSE; 10570 boolean_t any_waited = B_FALSE; 10571 10572 for (i = 0; i < ZPOOL_WAIT_NUM_ACTIVITIES; i++) { 10573 boolean_t waited; 10574 10575 if (!wd.wd_enabled[i]) 10576 continue; 10577 10578 error = zpool_wait_status(zhp, i, &missing, &waited); 10579 if (error != 0 || missing) 10580 break; 10581 10582 any_waited = (any_waited || waited); 10583 } 10584 10585 if (error != 0 || missing || !any_waited) 10586 break; 10587 } 10588 10589 zpool_close(zhp); 10590 10591 if (verbose) { 10592 uintptr_t status; 10593 pthread_mutex_lock(&wd.wd_mutex); 10594 wd.wd_should_exit = B_TRUE; 10595 pthread_cond_signal(&wd.wd_cv); 10596 pthread_mutex_unlock(&wd.wd_mutex); 10597 (void) pthread_join(status_thr, (void *)&status); 10598 if (status != 0) 10599 error = status; 10600 } 10601 10602 pthread_mutex_destroy(&wd.wd_mutex); 10603 pthread_cond_destroy(&wd.wd_cv); 10604 return (error); 10605 } 10606 10607 static int 10608 find_command_idx(char *command, int *idx) 10609 { 10610 int i; 10611 10612 for (i = 0; i < NCOMMAND; i++) { 10613 if (command_table[i].name == NULL) 10614 continue; 10615 10616 if (strcmp(command, command_table[i].name) == 0) { 10617 *idx = i; 10618 return (0); 10619 } 10620 } 10621 return (1); 10622 } 10623 10624 /* 10625 * Display version message 10626 */ 10627 static int 10628 zpool_do_version(int argc, char **argv) 10629 { 10630 if (zfs_version_print() == -1) 10631 return (1); 10632 10633 return (0); 10634 } 10635 10636 /* 10637 * Do zpool_load_compat() and print error message on failure 10638 */ 10639 static zpool_compat_status_t 10640 zpool_do_load_compat(const char *compat, boolean_t *list) 10641 { 10642 char report[1024]; 10643 10644 zpool_compat_status_t ret; 10645 10646 ret = zpool_load_compat(compat, list, report, 1024); 10647 switch (ret) { 10648 10649 case ZPOOL_COMPATIBILITY_OK: 10650 break; 10651 10652 case ZPOOL_COMPATIBILITY_NOFILES: 10653 case ZPOOL_COMPATIBILITY_BADFILE: 10654 case ZPOOL_COMPATIBILITY_BADTOKEN: 10655 (void) fprintf(stderr, "Error: %s\n", report); 10656 break; 10657 10658 case ZPOOL_COMPATIBILITY_WARNTOKEN: 10659 (void) fprintf(stderr, "Warning: %s\n", report); 10660 ret = ZPOOL_COMPATIBILITY_OK; 10661 break; 10662 } 10663 return (ret); 10664 } 10665 10666 int 10667 main(int argc, char **argv) 10668 { 10669 int ret = 0; 10670 int i = 0; 10671 char *cmdname; 10672 char **newargv; 10673 10674 (void) setlocale(LC_ALL, ""); 10675 (void) setlocale(LC_NUMERIC, "C"); 10676 (void) textdomain(TEXT_DOMAIN); 10677 srand(time(NULL)); 10678 10679 opterr = 0; 10680 10681 /* 10682 * Make sure the user has specified some command. 10683 */ 10684 if (argc < 2) { 10685 (void) fprintf(stderr, gettext("missing command\n")); 10686 usage(B_FALSE); 10687 } 10688 10689 cmdname = argv[1]; 10690 10691 /* 10692 * Special case '-?' 10693 */ 10694 if ((strcmp(cmdname, "-?") == 0) || strcmp(cmdname, "--help") == 0) 10695 usage(B_TRUE); 10696 10697 /* 10698 * Special case '-V|--version' 10699 */ 10700 if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0)) 10701 return (zpool_do_version(argc, argv)); 10702 10703 if ((g_zfs = libzfs_init()) == NULL) { 10704 (void) fprintf(stderr, "%s\n", libzfs_error_init(errno)); 10705 return (1); 10706 } 10707 10708 libzfs_print_on_error(g_zfs, B_TRUE); 10709 10710 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 10711 10712 /* 10713 * Many commands modify input strings for string parsing reasons. 10714 * We create a copy to protect the original argv. 10715 */ 10716 newargv = malloc((argc + 1) * sizeof (newargv[0])); 10717 for (i = 0; i < argc; i++) 10718 newargv[i] = strdup(argv[i]); 10719 newargv[argc] = NULL; 10720 10721 /* 10722 * Run the appropriate command. 10723 */ 10724 if (find_command_idx(cmdname, &i) == 0) { 10725 current_command = &command_table[i]; 10726 ret = command_table[i].func(argc - 1, newargv + 1); 10727 } else if (strchr(cmdname, '=')) { 10728 verify(find_command_idx("set", &i) == 0); 10729 current_command = &command_table[i]; 10730 ret = command_table[i].func(argc, newargv); 10731 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 10732 /* 10733 * 'freeze' is a vile debugging abomination, so we treat 10734 * it as such. 10735 */ 10736 zfs_cmd_t zc = {"\0"}; 10737 10738 (void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name)); 10739 ret = zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc); 10740 if (ret != 0) { 10741 (void) fprintf(stderr, 10742 gettext("failed to freeze pool: %d\n"), errno); 10743 ret = 1; 10744 } 10745 10746 log_history = 0; 10747 } else { 10748 (void) fprintf(stderr, gettext("unrecognized " 10749 "command '%s'\n"), cmdname); 10750 usage(B_FALSE); 10751 ret = 1; 10752 } 10753 10754 for (i = 0; i < argc; i++) 10755 free(newargv[i]); 10756 free(newargv); 10757 10758 if (ret == 0 && log_history) 10759 (void) zpool_log_history(g_zfs, history_str); 10760 10761 libzfs_fini(g_zfs); 10762 10763 /* 10764 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 10765 * for the purposes of running ::findleaks. 10766 */ 10767 if (getenv("ZFS_ABORT") != NULL) { 10768 (void) printf("dumping core by request\n"); 10769 abort(); 10770 } 10771 10772 return (ret); 10773 } 10774