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