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