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