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