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