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] ..." 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 } 4988 } 4989 4990 /* 4991 * Flush the output so that redirection to a file isn't buffered 4992 * indefinitely. 4993 */ 4994 (void) fflush(stdout); 4995 4996 if (interval == 0) 4997 break; 4998 4999 if (count != 0 && --count == 0) 5000 break; 5001 5002 (void) fsleep(interval); 5003 } 5004 5005 pool_list_free(list); 5006 5007 return (ret); 5008 } 5009 5010 typedef struct list_cbdata { 5011 boolean_t cb_verbose; 5012 int cb_name_flags; 5013 int cb_namewidth; 5014 boolean_t cb_scripted; 5015 zprop_list_t *cb_proplist; 5016 boolean_t cb_literal; 5017 } list_cbdata_t; 5018 5019 5020 /* 5021 * Given a list of columns to display, output appropriate headers for each one. 5022 */ 5023 static void 5024 print_header(list_cbdata_t *cb) 5025 { 5026 zprop_list_t *pl = cb->cb_proplist; 5027 char headerbuf[ZPOOL_MAXPROPLEN]; 5028 const char *header; 5029 boolean_t first = B_TRUE; 5030 boolean_t right_justify; 5031 size_t width = 0; 5032 5033 for (; pl != NULL; pl = pl->pl_next) { 5034 width = pl->pl_width; 5035 if (first && cb->cb_verbose) { 5036 /* 5037 * Reset the width to accommodate the verbose listing 5038 * of devices. 5039 */ 5040 width = cb->cb_namewidth; 5041 } 5042 5043 if (!first) 5044 (void) printf(" "); 5045 else 5046 first = B_FALSE; 5047 5048 right_justify = B_FALSE; 5049 if (pl->pl_prop != ZPROP_INVAL) { 5050 header = zpool_prop_column_name(pl->pl_prop); 5051 right_justify = zpool_prop_align_right(pl->pl_prop); 5052 } else { 5053 int i; 5054 5055 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 5056 headerbuf[i] = toupper(pl->pl_user_prop[i]); 5057 headerbuf[i] = '\0'; 5058 header = headerbuf; 5059 } 5060 5061 if (pl->pl_next == NULL && !right_justify) 5062 (void) printf("%s", header); 5063 else if (right_justify) 5064 (void) printf("%*s", width, header); 5065 else 5066 (void) printf("%-*s", width, header); 5067 5068 } 5069 5070 (void) printf("\n"); 5071 } 5072 5073 /* 5074 * Given a pool and a list of properties, print out all the properties according 5075 * to the described layout. Used by zpool_do_list(). 5076 */ 5077 static void 5078 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 5079 { 5080 zprop_list_t *pl = cb->cb_proplist; 5081 boolean_t first = B_TRUE; 5082 char property[ZPOOL_MAXPROPLEN]; 5083 char *propstr; 5084 boolean_t right_justify; 5085 size_t width; 5086 5087 for (; pl != NULL; pl = pl->pl_next) { 5088 5089 width = pl->pl_width; 5090 if (first && cb->cb_verbose) { 5091 /* 5092 * Reset the width to accommodate the verbose listing 5093 * of devices. 5094 */ 5095 width = cb->cb_namewidth; 5096 } 5097 5098 if (!first) { 5099 if (cb->cb_scripted) 5100 (void) printf("\t"); 5101 else 5102 (void) printf(" "); 5103 } else { 5104 first = B_FALSE; 5105 } 5106 5107 right_justify = B_FALSE; 5108 if (pl->pl_prop != ZPROP_INVAL) { 5109 if (zpool_get_prop(zhp, pl->pl_prop, property, 5110 sizeof (property), NULL, cb->cb_literal) != 0) 5111 propstr = "-"; 5112 else 5113 propstr = property; 5114 5115 right_justify = zpool_prop_align_right(pl->pl_prop); 5116 } else if ((zpool_prop_feature(pl->pl_user_prop) || 5117 zpool_prop_unsupported(pl->pl_user_prop)) && 5118 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 5119 sizeof (property)) == 0) { 5120 propstr = property; 5121 } else { 5122 propstr = "-"; 5123 } 5124 5125 5126 /* 5127 * If this is being called in scripted mode, or if this is the 5128 * last column and it is left-justified, don't include a width 5129 * format specifier. 5130 */ 5131 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 5132 (void) printf("%s", propstr); 5133 else if (right_justify) 5134 (void) printf("%*s", width, propstr); 5135 else 5136 (void) printf("%-*s", width, propstr); 5137 } 5138 5139 (void) printf("\n"); 5140 } 5141 5142 static void 5143 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted, 5144 boolean_t valid) 5145 { 5146 char propval[64]; 5147 boolean_t fixed; 5148 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 5149 5150 switch (prop) { 5151 case ZPOOL_PROP_EXPANDSZ: 5152 case ZPOOL_PROP_CHECKPOINT: 5153 if (value == 0) 5154 (void) strlcpy(propval, "-", sizeof (propval)); 5155 else 5156 zfs_nicenum(value, propval, sizeof (propval)); 5157 break; 5158 case ZPOOL_PROP_FRAGMENTATION: 5159 if (value == ZFS_FRAG_INVALID) { 5160 (void) strlcpy(propval, "-", sizeof (propval)); 5161 } else { 5162 (void) snprintf(propval, sizeof (propval), "%llu%%", 5163 value); 5164 } 5165 break; 5166 case ZPOOL_PROP_CAPACITY: 5167 (void) snprintf(propval, sizeof (propval), 5168 value < 1000 ? "%1.2f%%" : value < 10000 ? 5169 "%2.1f%%" : "%3.0f%%", value / 100.0); 5170 break; 5171 default: 5172 zfs_nicenum(value, propval, sizeof (propval)); 5173 } 5174 5175 if (!valid) 5176 (void) strlcpy(propval, "-", sizeof (propval)); 5177 5178 if (scripted) 5179 (void) printf("\t%s", propval); 5180 else 5181 (void) printf(" %*s", width, propval); 5182 } 5183 5184 /* 5185 * print static default line per vdev 5186 */ 5187 void 5188 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 5189 list_cbdata_t *cb, int depth) 5190 { 5191 nvlist_t **child; 5192 vdev_stat_t *vs; 5193 uint_t c, children; 5194 char *vname; 5195 boolean_t scripted = cb->cb_scripted; 5196 uint64_t islog = B_FALSE; 5197 char *dashes = "%-*s - - - - - -\n"; 5198 5199 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 5200 (uint64_t **)&vs, &c) == 0); 5201 5202 if (name != NULL) { 5203 boolean_t toplevel = (vs->vs_space != 0); 5204 uint64_t cap; 5205 5206 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 5207 return; 5208 5209 if (scripted) 5210 (void) printf("\t%s", name); 5211 else if (strlen(name) + depth > cb->cb_namewidth) 5212 (void) printf("%*s%s", depth, "", name); 5213 else 5214 (void) printf("%*s%s%*s", depth, "", name, 5215 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 5216 5217 /* 5218 * Print the properties for the individual vdevs. Some 5219 * properties are only applicable to toplevel vdevs. The 5220 * 'toplevel' boolean value is passed to the print_one_column() 5221 * to indicate that the value is valid. 5222 */ 5223 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted, 5224 toplevel); 5225 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted, 5226 toplevel); 5227 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 5228 scripted, toplevel); 5229 print_one_column(ZPOOL_PROP_CHECKPOINT, 5230 vs->vs_checkpoint_space, scripted, toplevel); 5231 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted, 5232 B_TRUE); 5233 print_one_column(ZPOOL_PROP_FRAGMENTATION, 5234 vs->vs_fragmentation, scripted, 5235 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel)); 5236 cap = (vs->vs_space == 0) ? 0 : 5237 (vs->vs_alloc * 10000 / vs->vs_space); 5238 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel); 5239 (void) printf("\n"); 5240 } 5241 5242 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 5243 &child, &children) != 0) 5244 return; 5245 5246 /* list the normal vdevs first */ 5247 for (c = 0; c < children; c++) { 5248 uint64_t ishole = B_FALSE; 5249 5250 if (nvlist_lookup_uint64(child[c], 5251 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 5252 continue; 5253 5254 if (nvlist_lookup_uint64(child[c], 5255 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) 5256 continue; 5257 5258 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 5259 continue; 5260 5261 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5262 cb->cb_name_flags); 5263 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5264 free(vname); 5265 } 5266 5267 /* list the classes: 'logs', 'dedup', and 'special' */ 5268 for (uint_t n = 0; n < 3; n++) { 5269 boolean_t printed = B_FALSE; 5270 5271 for (c = 0; c < children; c++) { 5272 char *bias = NULL; 5273 char *type = NULL; 5274 5275 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 5276 &islog) == 0 && islog) { 5277 bias = VDEV_ALLOC_CLASS_LOGS; 5278 } else { 5279 (void) nvlist_lookup_string(child[c], 5280 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 5281 (void) nvlist_lookup_string(child[c], 5282 ZPOOL_CONFIG_TYPE, &type); 5283 } 5284 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 5285 continue; 5286 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 5287 continue; 5288 5289 if (!printed) { 5290 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5291 (void) printf(dashes, cb->cb_namewidth, 5292 class_name[n]); 5293 printed = B_TRUE; 5294 } 5295 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5296 cb->cb_name_flags); 5297 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5298 free(vname); 5299 } 5300 } 5301 5302 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 5303 &child, &children) == 0 && children > 0) { 5304 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5305 (void) printf(dashes, cb->cb_namewidth, "cache"); 5306 for (c = 0; c < children; c++) { 5307 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5308 cb->cb_name_flags); 5309 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5310 free(vname); 5311 } 5312 } 5313 5314 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 5315 &children) == 0 && children > 0) { 5316 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5317 (void) printf(dashes, cb->cb_namewidth, "spare"); 5318 for (c = 0; c < children; c++) { 5319 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5320 cb->cb_name_flags); 5321 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5322 free(vname); 5323 } 5324 } 5325 } 5326 5327 /* 5328 * Generic callback function to list a pool. 5329 */ 5330 int 5331 list_callback(zpool_handle_t *zhp, void *data) 5332 { 5333 list_cbdata_t *cbp = data; 5334 nvlist_t *config; 5335 nvlist_t *nvroot; 5336 5337 config = zpool_get_config(zhp, NULL); 5338 5339 if (cbp->cb_verbose) { 5340 config = zpool_get_config(zhp, NULL); 5341 5342 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 5343 &nvroot) == 0); 5344 } 5345 5346 if (cbp->cb_verbose) 5347 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 5348 cbp->cb_name_flags); 5349 5350 print_pool(zhp, cbp); 5351 5352 if (cbp->cb_verbose) 5353 print_list_stats(zhp, NULL, nvroot, cbp, 0); 5354 5355 return (0); 5356 } 5357 5358 /* 5359 * Set the minimum pool/vdev name column width. The width must be at least 9, 5360 * but may be as large as needed. 5361 */ 5362 static int 5363 get_namewidth_list(zpool_handle_t *zhp, void *data) 5364 { 5365 list_cbdata_t *cb = data; 5366 int width; 5367 5368 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 5369 cb->cb_verbose); 5370 5371 if (width < 9) 5372 width = 9; 5373 5374 cb->cb_namewidth = width; 5375 5376 return (0); 5377 } 5378 5379 /* 5380 * zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 5381 * 5382 * -g Display guid for individual vdev name. 5383 * -H Scripted mode. Don't display headers, and separate properties 5384 * by a single tab. 5385 * -L Follow links when resolving vdev path name. 5386 * -o List of properties to display. Defaults to 5387 * "name,size,allocated,free,expandsize,fragmentation,capacity," 5388 * "dedupratio,health,altroot" 5389 * -p Diplay values in parsable (exact) format. 5390 * -P Display full path for vdev name. 5391 * -T Display a timestamp in date(1) or Unix format 5392 * 5393 * List all pools in the system, whether or not they're healthy. Output space 5394 * statistics for each one, as well as health status summary. 5395 */ 5396 int 5397 zpool_do_list(int argc, char **argv) 5398 { 5399 int c; 5400 int ret; 5401 list_cbdata_t cb = { 0 }; 5402 static char default_props[] = 5403 "name,size,allocated,free,checkpoint,expandsize,fragmentation," 5404 "capacity,dedupratio,health,altroot"; 5405 char *props = default_props; 5406 float interval = 0; 5407 unsigned long count = 0; 5408 zpool_list_t *list; 5409 boolean_t first = B_TRUE; 5410 5411 /* check options */ 5412 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) { 5413 switch (c) { 5414 case 'g': 5415 cb.cb_name_flags |= VDEV_NAME_GUID; 5416 break; 5417 case 'H': 5418 cb.cb_scripted = B_TRUE; 5419 break; 5420 case 'L': 5421 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 5422 break; 5423 case 'o': 5424 props = optarg; 5425 break; 5426 case 'P': 5427 cb.cb_name_flags |= VDEV_NAME_PATH; 5428 break; 5429 case 'p': 5430 cb.cb_literal = B_TRUE; 5431 break; 5432 case 'T': 5433 get_timestamp_arg(*optarg); 5434 break; 5435 case 'v': 5436 cb.cb_verbose = B_TRUE; 5437 cb.cb_namewidth = 8; /* 8 until precalc is avail */ 5438 break; 5439 case ':': 5440 (void) fprintf(stderr, gettext("missing argument for " 5441 "'%c' option\n"), optopt); 5442 usage(B_FALSE); 5443 break; 5444 case '?': 5445 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5446 optopt); 5447 usage(B_FALSE); 5448 } 5449 } 5450 5451 argc -= optind; 5452 argv += optind; 5453 5454 get_interval_count(&argc, argv, &interval, &count); 5455 5456 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 5457 usage(B_FALSE); 5458 5459 for (;;) { 5460 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 5461 &ret)) == NULL) 5462 return (1); 5463 5464 if (pool_list_count(list) == 0) 5465 break; 5466 5467 cb.cb_namewidth = 0; 5468 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb); 5469 5470 if (timestamp_fmt != NODATE) 5471 print_timestamp(timestamp_fmt); 5472 5473 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 5474 print_header(&cb); 5475 first = B_FALSE; 5476 } 5477 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 5478 5479 if (interval == 0) 5480 break; 5481 5482 if (count != 0 && --count == 0) 5483 break; 5484 5485 pool_list_free(list); 5486 (void) fsleep(interval); 5487 } 5488 5489 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 5490 (void) printf(gettext("no pools available\n")); 5491 ret = 0; 5492 } 5493 5494 pool_list_free(list); 5495 zprop_free_list(cb.cb_proplist); 5496 return (ret); 5497 } 5498 5499 static int 5500 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 5501 { 5502 boolean_t force = B_FALSE; 5503 int c; 5504 nvlist_t *nvroot; 5505 char *poolname, *old_disk, *new_disk; 5506 zpool_handle_t *zhp; 5507 zpool_boot_label_t boot_type; 5508 uint64_t boot_size; 5509 nvlist_t *props = NULL; 5510 char *propval; 5511 int ret; 5512 5513 /* check options */ 5514 while ((c = getopt(argc, argv, "fo:")) != -1) { 5515 switch (c) { 5516 case 'f': 5517 force = B_TRUE; 5518 break; 5519 case 'o': 5520 if ((propval = strchr(optarg, '=')) == NULL) { 5521 (void) fprintf(stderr, gettext("missing " 5522 "'=' for -o option\n")); 5523 usage(B_FALSE); 5524 } 5525 *propval = '\0'; 5526 propval++; 5527 5528 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 5529 (add_prop_list(optarg, propval, &props, B_TRUE))) 5530 usage(B_FALSE); 5531 break; 5532 case '?': 5533 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5534 optopt); 5535 usage(B_FALSE); 5536 } 5537 } 5538 5539 argc -= optind; 5540 argv += optind; 5541 5542 /* get pool name and check number of arguments */ 5543 if (argc < 1) { 5544 (void) fprintf(stderr, gettext("missing pool name argument\n")); 5545 usage(B_FALSE); 5546 } 5547 5548 poolname = argv[0]; 5549 5550 if (argc < 2) { 5551 (void) fprintf(stderr, 5552 gettext("missing <device> specification\n")); 5553 usage(B_FALSE); 5554 } 5555 5556 old_disk = argv[1]; 5557 5558 if (argc < 3) { 5559 if (!replacing) { 5560 (void) fprintf(stderr, 5561 gettext("missing <new_device> specification\n")); 5562 usage(B_FALSE); 5563 } 5564 new_disk = old_disk; 5565 argc -= 1; 5566 argv += 1; 5567 } else { 5568 new_disk = argv[2]; 5569 argc -= 2; 5570 argv += 2; 5571 } 5572 5573 if (argc > 1) { 5574 (void) fprintf(stderr, gettext("too many arguments\n")); 5575 usage(B_FALSE); 5576 } 5577 5578 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5579 return (1); 5580 5581 if (zpool_get_config(zhp, NULL) == NULL) { 5582 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 5583 poolname); 5584 zpool_close(zhp); 5585 return (1); 5586 } 5587 5588 if (zpool_is_bootable(zhp)) 5589 boot_type = ZPOOL_COPY_BOOT_LABEL; 5590 else 5591 boot_type = ZPOOL_NO_BOOT_LABEL; 5592 5593 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 5594 5595 /* unless manually specified use "ashift" pool property (if set) */ 5596 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 5597 int intval; 5598 zprop_source_t src; 5599 char strval[ZPOOL_MAXPROPLEN]; 5600 5601 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 5602 if (src != ZPROP_SRC_DEFAULT) { 5603 (void) sprintf(strval, "%" PRId32, intval); 5604 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 5605 &props, B_TRUE) == 0); 5606 } 5607 } 5608 5609 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE, 5610 boot_type, boot_size, argc, argv); 5611 if (nvroot == NULL) { 5612 zpool_close(zhp); 5613 return (1); 5614 } 5615 5616 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 5617 5618 nvlist_free(nvroot); 5619 zpool_close(zhp); 5620 5621 return (ret); 5622 } 5623 5624 /* 5625 * zpool replace [-f] <pool> <device> <new_device> 5626 * 5627 * -f Force attach, even if <new_device> appears to be in use. 5628 * 5629 * Replace <device> with <new_device>. 5630 */ 5631 /* ARGSUSED */ 5632 int 5633 zpool_do_replace(int argc, char **argv) 5634 { 5635 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 5636 } 5637 5638 /* 5639 * zpool attach [-f] [-o property=value] <pool> <device> <new_device> 5640 * 5641 * -f Force attach, even if <new_device> appears to be in use. 5642 * -o Set property=value. 5643 * 5644 * Attach <new_device> to the mirror containing <device>. If <device> is not 5645 * part of a mirror, then <device> will be transformed into a mirror of 5646 * <device> and <new_device>. In either case, <new_device> will begin life 5647 * with a DTL of [0, now], and will immediately begin to resilver itself. 5648 */ 5649 int 5650 zpool_do_attach(int argc, char **argv) 5651 { 5652 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 5653 } 5654 5655 /* 5656 * zpool detach [-f] <pool> <device> 5657 * 5658 * -f Force detach of <device>, even if DTLs argue against it 5659 * (not supported yet) 5660 * 5661 * Detach a device from a mirror. The operation will be refused if <device> 5662 * is the last device in the mirror, or if the DTLs indicate that this device 5663 * has the only valid copy of some data. 5664 */ 5665 /* ARGSUSED */ 5666 int 5667 zpool_do_detach(int argc, char **argv) 5668 { 5669 int c; 5670 char *poolname, *path; 5671 zpool_handle_t *zhp; 5672 int ret; 5673 5674 /* check options */ 5675 while ((c = getopt(argc, argv, "f")) != -1) { 5676 switch (c) { 5677 case 'f': 5678 case '?': 5679 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5680 optopt); 5681 usage(B_FALSE); 5682 } 5683 } 5684 5685 argc -= optind; 5686 argv += optind; 5687 5688 /* get pool name and check number of arguments */ 5689 if (argc < 1) { 5690 (void) fprintf(stderr, gettext("missing pool name argument\n")); 5691 usage(B_FALSE); 5692 } 5693 5694 if (argc < 2) { 5695 (void) fprintf(stderr, 5696 gettext("missing <device> specification\n")); 5697 usage(B_FALSE); 5698 } 5699 5700 poolname = argv[0]; 5701 path = argv[1]; 5702 5703 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5704 return (1); 5705 5706 ret = zpool_vdev_detach(zhp, path); 5707 5708 zpool_close(zhp); 5709 5710 return (ret); 5711 } 5712 5713 /* 5714 * zpool split [-gLnP] [-o prop=val] ... 5715 * [-o mntopt] ... 5716 * [-R altroot] <pool> <newpool> [<device> ...] 5717 * 5718 * -g Display guid for individual vdev name. 5719 * -L Follow links when resolving vdev path name. 5720 * -n Do not split the pool, but display the resulting layout if 5721 * it were to be split. 5722 * -o Set property=value, or set mount options. 5723 * -P Display full path for vdev name. 5724 * -R Mount the split-off pool under an alternate root. 5725 * -l Load encryption keys while importing. 5726 * 5727 * Splits the named pool and gives it the new pool name. Devices to be split 5728 * off may be listed, provided that no more than one device is specified 5729 * per top-level vdev mirror. The newly split pool is left in an exported 5730 * state unless -R is specified. 5731 * 5732 * Restrictions: the top-level of the pool pool must only be made up of 5733 * mirrors; all devices in the pool must be healthy; no device may be 5734 * undergoing a resilvering operation. 5735 */ 5736 int 5737 zpool_do_split(int argc, char **argv) 5738 { 5739 char *srcpool, *newpool, *propval; 5740 char *mntopts = NULL; 5741 splitflags_t flags; 5742 int c, ret = 0; 5743 boolean_t loadkeys = B_FALSE; 5744 zpool_handle_t *zhp; 5745 nvlist_t *config, *props = NULL; 5746 5747 flags.dryrun = B_FALSE; 5748 flags.import = B_FALSE; 5749 flags.name_flags = 0; 5750 5751 /* check options */ 5752 while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) { 5753 switch (c) { 5754 case 'g': 5755 flags.name_flags |= VDEV_NAME_GUID; 5756 break; 5757 case 'L': 5758 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS; 5759 break; 5760 case 'R': 5761 flags.import = B_TRUE; 5762 if (add_prop_list( 5763 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 5764 &props, B_TRUE) != 0) { 5765 nvlist_free(props); 5766 usage(B_FALSE); 5767 } 5768 break; 5769 case 'l': 5770 loadkeys = B_TRUE; 5771 break; 5772 case 'n': 5773 flags.dryrun = B_TRUE; 5774 break; 5775 case 'o': 5776 if ((propval = strchr(optarg, '=')) != NULL) { 5777 *propval = '\0'; 5778 propval++; 5779 if (add_prop_list(optarg, propval, 5780 &props, B_TRUE) != 0) { 5781 nvlist_free(props); 5782 usage(B_FALSE); 5783 } 5784 } else { 5785 mntopts = optarg; 5786 } 5787 break; 5788 case 'P': 5789 flags.name_flags |= VDEV_NAME_PATH; 5790 break; 5791 case ':': 5792 (void) fprintf(stderr, gettext("missing argument for " 5793 "'%c' option\n"), optopt); 5794 usage(B_FALSE); 5795 break; 5796 case '?': 5797 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5798 optopt); 5799 usage(B_FALSE); 5800 break; 5801 } 5802 } 5803 5804 if (!flags.import && mntopts != NULL) { 5805 (void) fprintf(stderr, gettext("setting mntopts is only " 5806 "valid when importing the pool\n")); 5807 usage(B_FALSE); 5808 } 5809 5810 if (!flags.import && loadkeys) { 5811 (void) fprintf(stderr, gettext("loading keys is only " 5812 "valid when importing the pool\n")); 5813 usage(B_FALSE); 5814 } 5815 5816 argc -= optind; 5817 argv += optind; 5818 5819 if (argc < 1) { 5820 (void) fprintf(stderr, gettext("Missing pool name\n")); 5821 usage(B_FALSE); 5822 } 5823 if (argc < 2) { 5824 (void) fprintf(stderr, gettext("Missing new pool name\n")); 5825 usage(B_FALSE); 5826 } 5827 5828 srcpool = argv[0]; 5829 newpool = argv[1]; 5830 5831 argc -= 2; 5832 argv += 2; 5833 5834 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 5835 return (1); 5836 5837 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 5838 if (config == NULL) { 5839 ret = 1; 5840 } else { 5841 if (flags.dryrun) { 5842 (void) printf(gettext("would create '%s' with the " 5843 "following layout:\n\n"), newpool); 5844 print_vdev_tree(NULL, newpool, config, 0, "", 5845 flags.name_flags); 5846 } 5847 nvlist_free(config); 5848 } 5849 5850 zpool_close(zhp); 5851 5852 if (ret != 0 || flags.dryrun || !flags.import) 5853 return (ret); 5854 5855 /* 5856 * The split was successful. Now we need to open the new 5857 * pool and import it. 5858 */ 5859 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 5860 return (1); 5861 5862 if (loadkeys) { 5863 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool); 5864 if (ret != 0) 5865 ret = 1; 5866 } 5867 5868 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 5869 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 5870 ret = 1; 5871 (void) fprintf(stderr, gettext("Split was successful, but " 5872 "the datasets could not all be mounted\n")); 5873 (void) fprintf(stderr, gettext("Try doing '%s' with a " 5874 "different altroot\n"), "zpool import"); 5875 } 5876 zpool_close(zhp); 5877 5878 return (ret); 5879 } 5880 5881 5882 5883 /* 5884 * zpool online <pool> <device> ... 5885 */ 5886 int 5887 zpool_do_online(int argc, char **argv) 5888 { 5889 int c, i; 5890 char *poolname; 5891 zpool_handle_t *zhp; 5892 int ret = 0; 5893 vdev_state_t newstate; 5894 int flags = 0; 5895 5896 /* check options */ 5897 while ((c = getopt(argc, argv, "et")) != -1) { 5898 switch (c) { 5899 case 'e': 5900 flags |= ZFS_ONLINE_EXPAND; 5901 break; 5902 case 't': 5903 case '?': 5904 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5905 optopt); 5906 usage(B_FALSE); 5907 } 5908 } 5909 5910 argc -= optind; 5911 argv += optind; 5912 5913 /* get pool name and check number of arguments */ 5914 if (argc < 1) { 5915 (void) fprintf(stderr, gettext("missing pool name\n")); 5916 usage(B_FALSE); 5917 } 5918 if (argc < 2) { 5919 (void) fprintf(stderr, gettext("missing device name\n")); 5920 usage(B_FALSE); 5921 } 5922 5923 poolname = argv[0]; 5924 5925 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5926 return (1); 5927 5928 for (i = 1; i < argc; i++) { 5929 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 5930 if (newstate != VDEV_STATE_HEALTHY) { 5931 (void) printf(gettext("warning: device '%s' " 5932 "onlined, but remains in faulted state\n"), 5933 argv[i]); 5934 if (newstate == VDEV_STATE_FAULTED) 5935 (void) printf(gettext("use 'zpool " 5936 "clear' to restore a faulted " 5937 "device\n")); 5938 else 5939 (void) printf(gettext("use 'zpool " 5940 "replace' to replace devices " 5941 "that are no longer present\n")); 5942 } 5943 } else { 5944 ret = 1; 5945 } 5946 } 5947 5948 zpool_close(zhp); 5949 5950 return (ret); 5951 } 5952 5953 /* 5954 * zpool offline [-ft] <pool> <device> ... 5955 * 5956 * -f Force the device into the offline state, even if doing 5957 * so would appear to compromise pool availability. 5958 * (not supported yet) 5959 * 5960 * -t Only take the device off-line temporarily. The offline 5961 * state will not be persistent across reboots. 5962 */ 5963 /* ARGSUSED */ 5964 int 5965 zpool_do_offline(int argc, char **argv) 5966 { 5967 int c, i; 5968 char *poolname; 5969 zpool_handle_t *zhp; 5970 int ret = 0; 5971 boolean_t istmp = B_FALSE; 5972 5973 /* check options */ 5974 while ((c = getopt(argc, argv, "ft")) != -1) { 5975 switch (c) { 5976 case 't': 5977 istmp = B_TRUE; 5978 break; 5979 case 'f': 5980 case '?': 5981 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5982 optopt); 5983 usage(B_FALSE); 5984 } 5985 } 5986 5987 argc -= optind; 5988 argv += optind; 5989 5990 /* get pool name and check number of arguments */ 5991 if (argc < 1) { 5992 (void) fprintf(stderr, gettext("missing pool name\n")); 5993 usage(B_FALSE); 5994 } 5995 if (argc < 2) { 5996 (void) fprintf(stderr, gettext("missing device name\n")); 5997 usage(B_FALSE); 5998 } 5999 6000 poolname = argv[0]; 6001 6002 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6003 return (1); 6004 6005 for (i = 1; i < argc; i++) { 6006 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 6007 ret = 1; 6008 } 6009 6010 zpool_close(zhp); 6011 6012 return (ret); 6013 } 6014 6015 /* 6016 * zpool clear <pool> [device] 6017 * 6018 * Clear all errors associated with a pool or a particular device. 6019 */ 6020 int 6021 zpool_do_clear(int argc, char **argv) 6022 { 6023 int c; 6024 int ret = 0; 6025 boolean_t dryrun = B_FALSE; 6026 boolean_t do_rewind = B_FALSE; 6027 boolean_t xtreme_rewind = B_FALSE; 6028 uint32_t rewind_policy = ZPOOL_NO_REWIND; 6029 nvlist_t *policy = NULL; 6030 zpool_handle_t *zhp; 6031 char *pool, *device; 6032 6033 /* check options */ 6034 while ((c = getopt(argc, argv, "FnX")) != -1) { 6035 switch (c) { 6036 case 'F': 6037 do_rewind = B_TRUE; 6038 break; 6039 case 'n': 6040 dryrun = B_TRUE; 6041 break; 6042 case 'X': 6043 xtreme_rewind = B_TRUE; 6044 break; 6045 case '?': 6046 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6047 optopt); 6048 usage(B_FALSE); 6049 } 6050 } 6051 6052 argc -= optind; 6053 argv += optind; 6054 6055 if (argc < 1) { 6056 (void) fprintf(stderr, gettext("missing pool name\n")); 6057 usage(B_FALSE); 6058 } 6059 6060 if (argc > 2) { 6061 (void) fprintf(stderr, gettext("too many arguments\n")); 6062 usage(B_FALSE); 6063 } 6064 6065 if ((dryrun || xtreme_rewind) && !do_rewind) { 6066 (void) fprintf(stderr, 6067 gettext("-n or -X only meaningful with -F\n")); 6068 usage(B_FALSE); 6069 } 6070 if (dryrun) 6071 rewind_policy = ZPOOL_TRY_REWIND; 6072 else if (do_rewind) 6073 rewind_policy = ZPOOL_DO_REWIND; 6074 if (xtreme_rewind) 6075 rewind_policy |= ZPOOL_EXTREME_REWIND; 6076 6077 /* In future, further rewind policy choices can be passed along here */ 6078 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 6079 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 6080 rewind_policy) != 0) { 6081 return (1); 6082 } 6083 6084 pool = argv[0]; 6085 device = argc == 2 ? argv[1] : NULL; 6086 6087 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 6088 nvlist_free(policy); 6089 return (1); 6090 } 6091 6092 if (zpool_clear(zhp, device, policy) != 0) 6093 ret = 1; 6094 6095 zpool_close(zhp); 6096 6097 nvlist_free(policy); 6098 6099 return (ret); 6100 } 6101 6102 /* 6103 * zpool reguid <pool> 6104 */ 6105 int 6106 zpool_do_reguid(int argc, char **argv) 6107 { 6108 int c; 6109 char *poolname; 6110 zpool_handle_t *zhp; 6111 int ret = 0; 6112 6113 /* check options */ 6114 while ((c = getopt(argc, argv, "")) != -1) { 6115 switch (c) { 6116 case '?': 6117 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6118 optopt); 6119 usage(B_FALSE); 6120 } 6121 } 6122 6123 argc -= optind; 6124 argv += optind; 6125 6126 /* get pool name and check number of arguments */ 6127 if (argc < 1) { 6128 (void) fprintf(stderr, gettext("missing pool name\n")); 6129 usage(B_FALSE); 6130 } 6131 6132 if (argc > 1) { 6133 (void) fprintf(stderr, gettext("too many arguments\n")); 6134 usage(B_FALSE); 6135 } 6136 6137 poolname = argv[0]; 6138 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6139 return (1); 6140 6141 ret = zpool_reguid(zhp); 6142 6143 zpool_close(zhp); 6144 return (ret); 6145 } 6146 6147 6148 /* 6149 * zpool reopen <pool> 6150 * 6151 * Reopen the pool so that the kernel can update the sizes of all vdevs. 6152 */ 6153 int 6154 zpool_do_reopen(int argc, char **argv) 6155 { 6156 int c; 6157 int ret = 0; 6158 zpool_handle_t *zhp; 6159 char *pool; 6160 6161 /* check options */ 6162 while ((c = getopt(argc, argv, "")) != -1) { 6163 switch (c) { 6164 case '?': 6165 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6166 optopt); 6167 usage(B_FALSE); 6168 } 6169 } 6170 6171 argc--; 6172 argv++; 6173 6174 if (argc < 1) { 6175 (void) fprintf(stderr, gettext("missing pool name\n")); 6176 usage(B_FALSE); 6177 } 6178 6179 if (argc > 1) { 6180 (void) fprintf(stderr, gettext("too many arguments\n")); 6181 usage(B_FALSE); 6182 } 6183 6184 pool = argv[0]; 6185 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 6186 return (1); 6187 6188 ret = zpool_reopen(zhp); 6189 zpool_close(zhp); 6190 return (ret); 6191 } 6192 6193 typedef struct scrub_cbdata { 6194 int cb_type; 6195 int cb_argc; 6196 char **cb_argv; 6197 pool_scrub_cmd_t cb_scrub_cmd; 6198 } scrub_cbdata_t; 6199 6200 static boolean_t 6201 zpool_has_checkpoint(zpool_handle_t *zhp) 6202 { 6203 nvlist_t *config, *nvroot; 6204 6205 config = zpool_get_config(zhp, NULL); 6206 6207 if (config != NULL) { 6208 pool_checkpoint_stat_t *pcs = NULL; 6209 uint_t c; 6210 6211 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 6212 (void) nvlist_lookup_uint64_array(nvroot, 6213 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 6214 6215 if (pcs == NULL || pcs->pcs_state == CS_NONE) 6216 return (B_FALSE); 6217 6218 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS || 6219 pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 6220 return (B_TRUE); 6221 } 6222 6223 return (B_FALSE); 6224 } 6225 6226 int 6227 scrub_callback(zpool_handle_t *zhp, void *data) 6228 { 6229 scrub_cbdata_t *cb = data; 6230 int err; 6231 6232 /* 6233 * Ignore faulted pools. 6234 */ 6235 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 6236 (void) fprintf(stderr, gettext("cannot scan '%s': pool is " 6237 "currently unavailable\n"), zpool_get_name(zhp)); 6238 return (1); 6239 } 6240 6241 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 6242 6243 if (err == 0 && zpool_has_checkpoint(zhp) && 6244 cb->cb_type == POOL_SCAN_SCRUB) { 6245 (void) printf(gettext("warning: will not scrub state that " 6246 "belongs to the checkpoint of pool '%s'\n"), 6247 zpool_get_name(zhp)); 6248 } 6249 6250 return (err != 0); 6251 } 6252 6253 /* 6254 * zpool scrub [-s | -p] <pool> ... 6255 * 6256 * -s Stop. Stops any in-progress scrub. 6257 * -p Pause. Pause in-progress scrub. 6258 */ 6259 int 6260 zpool_do_scrub(int argc, char **argv) 6261 { 6262 int c; 6263 scrub_cbdata_t cb; 6264 6265 cb.cb_type = POOL_SCAN_SCRUB; 6266 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 6267 6268 /* check options */ 6269 while ((c = getopt(argc, argv, "sp")) != -1) { 6270 switch (c) { 6271 case 's': 6272 cb.cb_type = POOL_SCAN_NONE; 6273 break; 6274 case 'p': 6275 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 6276 break; 6277 case '?': 6278 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6279 optopt); 6280 usage(B_FALSE); 6281 } 6282 } 6283 6284 if (cb.cb_type == POOL_SCAN_NONE && 6285 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 6286 (void) fprintf(stderr, gettext("invalid option combination: " 6287 "-s and -p are mutually exclusive\n")); 6288 usage(B_FALSE); 6289 } 6290 6291 cb.cb_argc = argc; 6292 cb.cb_argv = argv; 6293 argc -= optind; 6294 argv += optind; 6295 6296 if (argc < 1) { 6297 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6298 usage(B_FALSE); 6299 } 6300 6301 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 6302 } 6303 6304 /* 6305 * zpool resilver <pool> ... 6306 * 6307 * Restarts any in-progress resilver 6308 */ 6309 int 6310 zpool_do_resilver(int argc, char **argv) 6311 { 6312 int c; 6313 scrub_cbdata_t cb; 6314 6315 cb.cb_type = POOL_SCAN_RESILVER; 6316 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 6317 cb.cb_argc = argc; 6318 cb.cb_argv = argv; 6319 6320 /* check options */ 6321 while ((c = getopt(argc, argv, "")) != -1) { 6322 switch (c) { 6323 case '?': 6324 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6325 optopt); 6326 usage(B_FALSE); 6327 } 6328 } 6329 6330 argc -= optind; 6331 argv += optind; 6332 6333 if (argc < 1) { 6334 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6335 usage(B_FALSE); 6336 } 6337 6338 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 6339 } 6340 6341 /* 6342 * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...] 6343 * 6344 * -c Cancel. Ends any in-progress trim. 6345 * -d Secure trim. Requires kernel and device support. 6346 * -r <rate> Sets the TRIM rate in bytes (per second). Supports 6347 * adding a multiplier suffix such as 'k' or 'm'. 6348 * -s Suspend. TRIM can then be restarted with no flags. 6349 */ 6350 int 6351 zpool_do_trim(int argc, char **argv) 6352 { 6353 struct option long_options[] = { 6354 {"cancel", no_argument, NULL, 'c'}, 6355 {"secure", no_argument, NULL, 'd'}, 6356 {"rate", required_argument, NULL, 'r'}, 6357 {"suspend", no_argument, NULL, 's'}, 6358 {0, 0, 0, 0} 6359 }; 6360 6361 pool_trim_func_t cmd_type = POOL_TRIM_START; 6362 uint64_t rate = 0; 6363 boolean_t secure = B_FALSE; 6364 6365 int c; 6366 while ((c = getopt_long(argc, argv, "cdr:s", long_options, NULL)) 6367 != -1) { 6368 switch (c) { 6369 case 'c': 6370 if (cmd_type != POOL_TRIM_START && 6371 cmd_type != POOL_TRIM_CANCEL) { 6372 (void) fprintf(stderr, gettext("-c cannot be " 6373 "combined with other options\n")); 6374 usage(B_FALSE); 6375 } 6376 cmd_type = POOL_TRIM_CANCEL; 6377 break; 6378 case 'd': 6379 if (cmd_type != POOL_TRIM_START) { 6380 (void) fprintf(stderr, gettext("-d cannot be " 6381 "combined with the -c or -s options\n")); 6382 usage(B_FALSE); 6383 } 6384 secure = B_TRUE; 6385 break; 6386 case 'r': 6387 if (cmd_type != POOL_TRIM_START) { 6388 (void) fprintf(stderr, gettext("-r cannot be " 6389 "combined with the -c or -s options\n")); 6390 usage(B_FALSE); 6391 } 6392 if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) { 6393 (void) fprintf(stderr, 6394 gettext("invalid value for rate\n")); 6395 usage(B_FALSE); 6396 } 6397 break; 6398 case 's': 6399 if (cmd_type != POOL_TRIM_START && 6400 cmd_type != POOL_TRIM_SUSPEND) { 6401 (void) fprintf(stderr, gettext("-s cannot be " 6402 "combined with other options\n")); 6403 usage(B_FALSE); 6404 } 6405 cmd_type = POOL_TRIM_SUSPEND; 6406 break; 6407 case '?': 6408 if (optopt != 0) { 6409 (void) fprintf(stderr, 6410 gettext("invalid option '%c'\n"), optopt); 6411 } else { 6412 (void) fprintf(stderr, 6413 gettext("invalid option '%s'\n"), 6414 argv[optind - 1]); 6415 } 6416 usage(B_FALSE); 6417 } 6418 } 6419 6420 argc -= optind; 6421 argv += optind; 6422 6423 if (argc < 1) { 6424 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6425 usage(B_FALSE); 6426 return (-1); 6427 } 6428 6429 char *poolname = argv[0]; 6430 zpool_handle_t *zhp = zpool_open(g_zfs, poolname); 6431 if (zhp == NULL) 6432 return (-1); 6433 6434 trimflags_t trim_flags = { 6435 .secure = secure, 6436 .rate = rate, 6437 }; 6438 6439 nvlist_t *vdevs = fnvlist_alloc(); 6440 if (argc == 1) { 6441 /* no individual leaf vdevs specified, so add them all */ 6442 nvlist_t *config = zpool_get_config(zhp, NULL); 6443 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 6444 ZPOOL_CONFIG_VDEV_TREE); 6445 zpool_collect_leaves(zhp, nvroot, vdevs); 6446 trim_flags.fullpool = B_TRUE; 6447 } else { 6448 trim_flags.fullpool = B_FALSE; 6449 for (int i = 1; i < argc; i++) { 6450 fnvlist_add_boolean(vdevs, argv[i]); 6451 } 6452 } 6453 6454 int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags); 6455 6456 fnvlist_free(vdevs); 6457 zpool_close(zhp); 6458 6459 return (error); 6460 } 6461 6462 /* 6463 * zpool initialize [-c | -s] <pool> [<vdev> ...] 6464 * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool 6465 * if none specified. 6466 * 6467 * -c Cancel. Ends active initializing. 6468 * -s Suspend. Initializing can then be restarted with no flags. 6469 */ 6470 int 6471 zpool_do_initialize(int argc, char **argv) 6472 { 6473 int c; 6474 char *poolname; 6475 zpool_handle_t *zhp; 6476 nvlist_t *vdevs; 6477 int err = 0; 6478 6479 struct option long_options[] = { 6480 {"cancel", no_argument, NULL, 'c'}, 6481 {"suspend", no_argument, NULL, 's'}, 6482 {0, 0, 0, 0} 6483 }; 6484 6485 pool_initialize_func_t cmd_type = POOL_INITIALIZE_START; 6486 while ((c = getopt_long(argc, argv, "cs", long_options, NULL)) != -1) { 6487 switch (c) { 6488 case 'c': 6489 if (cmd_type != POOL_INITIALIZE_START && 6490 cmd_type != POOL_INITIALIZE_CANCEL) { 6491 (void) fprintf(stderr, gettext("-c cannot be " 6492 "combined with other options\n")); 6493 usage(B_FALSE); 6494 } 6495 cmd_type = POOL_INITIALIZE_CANCEL; 6496 break; 6497 case 's': 6498 if (cmd_type != POOL_INITIALIZE_START && 6499 cmd_type != POOL_INITIALIZE_SUSPEND) { 6500 (void) fprintf(stderr, gettext("-s cannot be " 6501 "combined with other options\n")); 6502 usage(B_FALSE); 6503 } 6504 cmd_type = POOL_INITIALIZE_SUSPEND; 6505 break; 6506 case '?': 6507 if (optopt != 0) { 6508 (void) fprintf(stderr, 6509 gettext("invalid option '%c'\n"), optopt); 6510 } else { 6511 (void) fprintf(stderr, 6512 gettext("invalid option '%s'\n"), 6513 argv[optind - 1]); 6514 } 6515 usage(B_FALSE); 6516 } 6517 } 6518 6519 argc -= optind; 6520 argv += optind; 6521 6522 if (argc < 1) { 6523 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6524 usage(B_FALSE); 6525 return (-1); 6526 } 6527 6528 poolname = argv[0]; 6529 zhp = zpool_open(g_zfs, poolname); 6530 if (zhp == NULL) 6531 return (-1); 6532 6533 vdevs = fnvlist_alloc(); 6534 if (argc == 1) { 6535 /* no individual leaf vdevs specified, so add them all */ 6536 nvlist_t *config = zpool_get_config(zhp, NULL); 6537 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 6538 ZPOOL_CONFIG_VDEV_TREE); 6539 zpool_collect_leaves(zhp, nvroot, vdevs); 6540 } else { 6541 for (int i = 1; i < argc; i++) { 6542 fnvlist_add_boolean(vdevs, argv[i]); 6543 } 6544 } 6545 6546 err = zpool_initialize(zhp, cmd_type, vdevs); 6547 6548 fnvlist_free(vdevs); 6549 zpool_close(zhp); 6550 6551 return (err); 6552 } 6553 6554 /* 6555 * Print out detailed scrub status. 6556 */ 6557 static void 6558 print_scan_status(pool_scan_stat_t *ps) 6559 { 6560 time_t start, end, pause; 6561 uint64_t total_secs_left; 6562 uint64_t elapsed, secs_left, mins_left, hours_left, days_left; 6563 uint64_t pass_scanned, scanned, pass_issued, issued, total; 6564 uint_t scan_rate, issue_rate; 6565 double fraction_done; 6566 char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7]; 6567 char srate_buf[7], irate_buf[7]; 6568 6569 (void) printf(gettext(" scan: ")); 6570 6571 /* If there's never been a scan, there's not much to say. */ 6572 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 6573 ps->pss_func >= POOL_SCAN_FUNCS) { 6574 (void) printf(gettext("none requested\n")); 6575 return; 6576 } 6577 6578 start = ps->pss_start_time; 6579 end = ps->pss_end_time; 6580 pause = ps->pss_pass_scrub_pause; 6581 6582 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 6583 6584 assert(ps->pss_func == POOL_SCAN_SCRUB || 6585 ps->pss_func == POOL_SCAN_RESILVER); 6586 6587 /* 6588 * Scan is finished or canceled. 6589 */ 6590 if (ps->pss_state == DSS_FINISHED) { 6591 total_secs_left = end - start; 6592 days_left = total_secs_left / 60 / 60 / 24; 6593 hours_left = (total_secs_left / 60 / 60) % 24; 6594 mins_left = (total_secs_left / 60) % 60; 6595 secs_left = (total_secs_left % 60); 6596 6597 if (ps->pss_func == POOL_SCAN_SCRUB) { 6598 (void) printf(gettext("scrub repaired %s " 6599 "in %llu days %02llu:%02llu:%02llu " 6600 "with %llu errors on %s"), processed_buf, 6601 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6602 (u_longlong_t)mins_left, (u_longlong_t)secs_left, 6603 (u_longlong_t)ps->pss_errors, ctime(&end)); 6604 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6605 (void) printf(gettext("resilvered %s " 6606 "in %llu days %02llu:%02llu:%02llu " 6607 "with %llu errors on %s"), processed_buf, 6608 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6609 (u_longlong_t)mins_left, (u_longlong_t)secs_left, 6610 (u_longlong_t)ps->pss_errors, ctime(&end)); 6611 } 6612 return; 6613 } else if (ps->pss_state == DSS_CANCELED) { 6614 if (ps->pss_func == POOL_SCAN_SCRUB) { 6615 (void) printf(gettext("scrub canceled on %s"), 6616 ctime(&end)); 6617 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6618 (void) printf(gettext("resilver canceled on %s"), 6619 ctime(&end)); 6620 } 6621 return; 6622 } 6623 6624 assert(ps->pss_state == DSS_SCANNING); 6625 6626 /* Scan is in progress. Resilvers can't be paused. */ 6627 if (ps->pss_func == POOL_SCAN_SCRUB) { 6628 if (pause == 0) { 6629 (void) printf(gettext("scrub in progress since %s"), 6630 ctime(&start)); 6631 } else { 6632 (void) printf(gettext("scrub paused since %s"), 6633 ctime(&pause)); 6634 (void) printf(gettext("\tscrub started on %s"), 6635 ctime(&start)); 6636 } 6637 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6638 (void) printf(gettext("resilver in progress since %s"), 6639 ctime(&start)); 6640 } 6641 6642 scanned = ps->pss_examined; 6643 pass_scanned = ps->pss_pass_exam; 6644 issued = ps->pss_issued; 6645 pass_issued = ps->pss_pass_issued; 6646 total = ps->pss_to_examine; 6647 6648 /* we are only done with a block once we have issued the IO for it */ 6649 fraction_done = (double)issued / total; 6650 6651 /* elapsed time for this pass, rounding up to 1 if it's 0 */ 6652 elapsed = time(NULL) - ps->pss_pass_start; 6653 elapsed -= ps->pss_pass_scrub_spent_paused; 6654 elapsed = (elapsed != 0) ? elapsed : 1; 6655 6656 scan_rate = pass_scanned / elapsed; 6657 issue_rate = pass_issued / elapsed; 6658 total_secs_left = (issue_rate != 0 && total >= issued) ? 6659 ((total - issued) / issue_rate) : UINT64_MAX; 6660 6661 days_left = total_secs_left / 60 / 60 / 24; 6662 hours_left = (total_secs_left / 60 / 60) % 24; 6663 mins_left = (total_secs_left / 60) % 60; 6664 secs_left = (total_secs_left % 60); 6665 6666 /* format all of the numbers we will be reporting */ 6667 zfs_nicenum(scanned, scanned_buf, sizeof (scanned_buf)); 6668 zfs_nicenum(issued, issued_buf, sizeof (issued_buf)); 6669 zfs_nicenum(total, total_buf, sizeof (total_buf)); 6670 zfs_nicenum(scan_rate, srate_buf, sizeof (srate_buf)); 6671 zfs_nicenum(issue_rate, irate_buf, sizeof (irate_buf)); 6672 6673 /* do not print estimated time if we have a paused scrub */ 6674 if (pause == 0) { 6675 (void) printf(gettext("\t%s scanned at %s/s, " 6676 "%s issued at %s/s, %s total\n"), 6677 scanned_buf, srate_buf, issued_buf, irate_buf, total_buf); 6678 } else { 6679 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"), 6680 scanned_buf, issued_buf, total_buf); 6681 } 6682 6683 if (ps->pss_func == POOL_SCAN_RESILVER) { 6684 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 6685 processed_buf, 100 * fraction_done); 6686 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 6687 (void) printf(gettext("\t%s repaired, %.2f%% done"), 6688 processed_buf, 100 * fraction_done); 6689 } 6690 6691 if (pause == 0) { 6692 if (total_secs_left != UINT64_MAX && 6693 issue_rate >= 10 * 1024 * 1024) { 6694 (void) printf(gettext(", %llu days " 6695 "%02llu:%02llu:%02llu to go\n"), 6696 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6697 (u_longlong_t)mins_left, (u_longlong_t)secs_left); 6698 } else { 6699 (void) printf(gettext(", no estimated " 6700 "completion time\n")); 6701 } 6702 } else { 6703 (void) printf(gettext("\n")); 6704 } 6705 } 6706 6707 /* 6708 * As we don't scrub checkpointed blocks, we want to warn the 6709 * user that we skipped scanning some blocks if a checkpoint exists 6710 * or existed at any time during the scan. 6711 */ 6712 static void 6713 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs) 6714 { 6715 if (ps == NULL || pcs == NULL) 6716 return; 6717 6718 if (pcs->pcs_state == CS_NONE || 6719 pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 6720 return; 6721 6722 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS); 6723 6724 if (ps->pss_state == DSS_NONE) 6725 return; 6726 6727 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) && 6728 ps->pss_end_time < pcs->pcs_start_time) 6729 return; 6730 6731 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) { 6732 (void) printf(gettext(" scan warning: skipped blocks " 6733 "that are only referenced by the checkpoint.\n")); 6734 } else { 6735 assert(ps->pss_state == DSS_SCANNING); 6736 (void) printf(gettext(" scan warning: skipping blocks " 6737 "that are only referenced by the checkpoint.\n")); 6738 } 6739 } 6740 6741 /* 6742 * Print out detailed removal status. 6743 */ 6744 static void 6745 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 6746 { 6747 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 6748 time_t start, end; 6749 nvlist_t *config, *nvroot; 6750 nvlist_t **child; 6751 uint_t children; 6752 char *vdev_name; 6753 6754 if (prs == NULL || prs->prs_state == DSS_NONE) 6755 return; 6756 6757 /* 6758 * Determine name of vdev. 6759 */ 6760 config = zpool_get_config(zhp, NULL); 6761 nvroot = fnvlist_lookup_nvlist(config, 6762 ZPOOL_CONFIG_VDEV_TREE); 6763 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 6764 &child, &children) == 0); 6765 assert(prs->prs_removing_vdev < children); 6766 vdev_name = zpool_vdev_name(g_zfs, zhp, 6767 child[prs->prs_removing_vdev], B_TRUE); 6768 6769 (void) printf(gettext("remove: ")); 6770 6771 start = prs->prs_start_time; 6772 end = prs->prs_end_time; 6773 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 6774 6775 /* 6776 * Removal is finished or canceled. 6777 */ 6778 if (prs->prs_state == DSS_FINISHED) { 6779 uint64_t minutes_taken = (end - start) / 60; 6780 6781 (void) printf(gettext("Removal of vdev %llu copied %s " 6782 "in %lluh%um, completed on %s"), 6783 (longlong_t)prs->prs_removing_vdev, 6784 copied_buf, 6785 (u_longlong_t)(minutes_taken / 60), 6786 (uint_t)(minutes_taken % 60), 6787 ctime((time_t *)&end)); 6788 } else if (prs->prs_state == DSS_CANCELED) { 6789 (void) printf(gettext("Removal of %s canceled on %s"), 6790 vdev_name, ctime(&end)); 6791 } else { 6792 uint64_t copied, total, elapsed, mins_left, hours_left; 6793 double fraction_done; 6794 uint_t rate; 6795 6796 assert(prs->prs_state == DSS_SCANNING); 6797 6798 /* 6799 * Removal is in progress. 6800 */ 6801 (void) printf(gettext( 6802 "Evacuation of %s in progress since %s"), 6803 vdev_name, ctime(&start)); 6804 6805 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 6806 total = prs->prs_to_copy; 6807 fraction_done = (double)copied / total; 6808 6809 /* elapsed time for this pass */ 6810 elapsed = time(NULL) - prs->prs_start_time; 6811 elapsed = elapsed > 0 ? elapsed : 1; 6812 rate = copied / elapsed; 6813 rate = rate > 0 ? rate : 1; 6814 mins_left = ((total - copied) / rate) / 60; 6815 hours_left = mins_left / 60; 6816 6817 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 6818 zfs_nicenum(total, total_buf, sizeof (total_buf)); 6819 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 6820 6821 /* 6822 * do not print estimated time if hours_left is more than 6823 * 30 days 6824 */ 6825 (void) printf(gettext(" %s copied out of %s at %s/s, " 6826 "%.2f%% done"), 6827 examined_buf, total_buf, rate_buf, 100 * fraction_done); 6828 if (hours_left < (30 * 24)) { 6829 (void) printf(gettext(", %lluh%um to go\n"), 6830 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 6831 } else { 6832 (void) printf(gettext( 6833 ", (copy is slow, no estimated time)\n")); 6834 } 6835 } 6836 6837 if (prs->prs_mapping_memory > 0) { 6838 char mem_buf[7]; 6839 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 6840 (void) printf(gettext(" %s memory used for " 6841 "removed device mappings\n"), 6842 mem_buf); 6843 } 6844 } 6845 6846 static void 6847 print_checkpoint_status(pool_checkpoint_stat_t *pcs) 6848 { 6849 time_t start; 6850 char space_buf[7]; 6851 6852 if (pcs == NULL || pcs->pcs_state == CS_NONE) 6853 return; 6854 6855 (void) printf(gettext("checkpoint: ")); 6856 6857 start = pcs->pcs_start_time; 6858 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf)); 6859 6860 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) { 6861 char *date = ctime(&start); 6862 6863 /* 6864 * ctime() adds a newline at the end of the generated 6865 * string, thus the weird format specifier and the 6866 * strlen() call used to chop it off from the output. 6867 */ 6868 (void) printf(gettext("created %.*s, consumes %s\n"), 6869 strlen(date) - 1, date, space_buf); 6870 return; 6871 } 6872 6873 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 6874 6875 (void) printf(gettext("discarding, %s remaining.\n"), 6876 space_buf); 6877 } 6878 6879 static void 6880 print_error_log(zpool_handle_t *zhp) 6881 { 6882 nvlist_t *nverrlist = NULL; 6883 nvpair_t *elem; 6884 char *pathname; 6885 size_t len = MAXPATHLEN * 2; 6886 6887 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 6888 (void) printf("errors: List of errors unavailable " 6889 "(insufficient privileges)\n"); 6890 return; 6891 } 6892 6893 (void) printf("errors: Permanent errors have been " 6894 "detected in the following files:\n\n"); 6895 6896 pathname = safe_malloc(len); 6897 elem = NULL; 6898 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 6899 nvlist_t *nv; 6900 uint64_t dsobj, obj; 6901 6902 verify(nvpair_value_nvlist(elem, &nv) == 0); 6903 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 6904 &dsobj) == 0); 6905 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 6906 &obj) == 0); 6907 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 6908 (void) printf("%7s %s\n", "", pathname); 6909 } 6910 free(pathname); 6911 nvlist_free(nverrlist); 6912 } 6913 6914 static void 6915 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares, 6916 uint_t nspares) 6917 { 6918 uint_t i; 6919 char *name; 6920 6921 if (nspares == 0) 6922 return; 6923 6924 (void) printf(gettext("\tspares\n")); 6925 6926 for (i = 0; i < nspares; i++) { 6927 name = zpool_vdev_name(g_zfs, zhp, spares[i], 6928 cb->cb_name_flags); 6929 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE); 6930 free(name); 6931 } 6932 } 6933 6934 static void 6935 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache, 6936 uint_t nl2cache) 6937 { 6938 uint_t i; 6939 char *name; 6940 6941 if (nl2cache == 0) 6942 return; 6943 6944 (void) printf(gettext("\tcache\n")); 6945 6946 for (i = 0; i < nl2cache; i++) { 6947 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], 6948 cb->cb_name_flags); 6949 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE); 6950 free(name); 6951 } 6952 } 6953 6954 static void 6955 print_dedup_stats(nvlist_t *config) 6956 { 6957 ddt_histogram_t *ddh; 6958 ddt_stat_t *dds; 6959 ddt_object_t *ddo; 6960 uint_t c; 6961 6962 /* 6963 * If the pool was faulted then we may not have been able to 6964 * obtain the config. Otherwise, if we have anything in the dedup 6965 * table continue processing the stats. 6966 */ 6967 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 6968 (uint64_t **)&ddo, &c) != 0) 6969 return; 6970 6971 (void) printf("\n"); 6972 (void) printf(gettext(" dedup: ")); 6973 if (ddo->ddo_count == 0) { 6974 (void) printf(gettext("no DDT entries\n")); 6975 return; 6976 } 6977 6978 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 6979 (u_longlong_t)ddo->ddo_count, 6980 (u_longlong_t)ddo->ddo_dspace, 6981 (u_longlong_t)ddo->ddo_mspace); 6982 6983 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 6984 (uint64_t **)&dds, &c) == 0); 6985 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 6986 (uint64_t **)&ddh, &c) == 0); 6987 zpool_dump_ddt(dds, ddh); 6988 } 6989 6990 /* 6991 * Display a summary of pool status. Displays a summary such as: 6992 * 6993 * pool: tank 6994 * status: DEGRADED 6995 * reason: One or more devices ... 6996 * see: http://illumos.org/msg/ZFS-xxxx-01 6997 * config: 6998 * mirror DEGRADED 6999 * c1t0d0 OK 7000 * c2t0d0 UNAVAIL 7001 * 7002 * When given the '-v' option, we print out the complete config. If the '-e' 7003 * option is specified, then we print out error rate information as well. 7004 */ 7005 int 7006 status_callback(zpool_handle_t *zhp, void *data) 7007 { 7008 status_cbdata_t *cbp = data; 7009 nvlist_t *config, *nvroot; 7010 char *msgid; 7011 int reason; 7012 zpool_errata_t errata; 7013 const char *health; 7014 uint_t c; 7015 vdev_stat_t *vs; 7016 7017 config = zpool_get_config(zhp, NULL); 7018 reason = zpool_get_status(zhp, &msgid, &errata); 7019 7020 cbp->cb_count++; 7021 7022 /* 7023 * If we were given 'zpool status -x', only report those pools with 7024 * problems. 7025 */ 7026 if (cbp->cb_explain && 7027 (reason == ZPOOL_STATUS_OK || 7028 reason == ZPOOL_STATUS_VERSION_OLDER || 7029 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 7030 if (!cbp->cb_allpools) { 7031 (void) printf(gettext("pool '%s' is healthy\n"), 7032 zpool_get_name(zhp)); 7033 if (cbp->cb_first) 7034 cbp->cb_first = B_FALSE; 7035 } 7036 return (0); 7037 } 7038 7039 if (cbp->cb_first) 7040 cbp->cb_first = B_FALSE; 7041 else 7042 (void) printf("\n"); 7043 7044 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 7045 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 7046 (uint64_t **)&vs, &c) == 0); 7047 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 7048 7049 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 7050 (void) printf(gettext(" state: %s\n"), health); 7051 7052 switch (reason) { 7053 case ZPOOL_STATUS_MISSING_DEV_R: 7054 (void) printf(gettext("status: One or more devices could not " 7055 "be opened. Sufficient replicas exist for\n\tthe pool to " 7056 "continue functioning in a degraded state.\n")); 7057 (void) printf(gettext("action: Attach the missing device and " 7058 "online it using 'zpool online'.\n")); 7059 break; 7060 7061 case ZPOOL_STATUS_MISSING_DEV_NR: 7062 (void) printf(gettext("status: One or more devices could not " 7063 "be opened. There are insufficient\n\treplicas for the " 7064 "pool to continue functioning.\n")); 7065 (void) printf(gettext("action: Attach the missing device and " 7066 "online it using 'zpool online'.\n")); 7067 break; 7068 7069 case ZPOOL_STATUS_CORRUPT_LABEL_R: 7070 (void) printf(gettext("status: One or more devices could not " 7071 "be used because the label is missing or\n\tinvalid. " 7072 "Sufficient replicas exist for the pool to continue\n\t" 7073 "functioning in a degraded state.\n")); 7074 (void) printf(gettext("action: Replace the device using " 7075 "'zpool replace'.\n")); 7076 break; 7077 7078 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 7079 (void) printf(gettext("status: One or more devices could not " 7080 "be used because the label is missing \n\tor invalid. " 7081 "There are insufficient replicas for the pool to " 7082 "continue\n\tfunctioning.\n")); 7083 zpool_explain_recover(zpool_get_handle(zhp), 7084 zpool_get_name(zhp), reason, config); 7085 break; 7086 7087 case ZPOOL_STATUS_FAILING_DEV: 7088 (void) printf(gettext("status: One or more devices has " 7089 "experienced an unrecoverable error. An\n\tattempt was " 7090 "made to correct the error. Applications are " 7091 "unaffected.\n")); 7092 (void) printf(gettext("action: Determine if the device needs " 7093 "to be replaced, and clear the errors\n\tusing " 7094 "'zpool clear' or replace the device with 'zpool " 7095 "replace'.\n")); 7096 break; 7097 7098 case ZPOOL_STATUS_OFFLINE_DEV: 7099 (void) printf(gettext("status: One or more devices has " 7100 "been taken offline by the administrator.\n\tSufficient " 7101 "replicas exist for the pool to continue functioning in " 7102 "a\n\tdegraded state.\n")); 7103 (void) printf(gettext("action: Online the device using " 7104 "'zpool online' or replace the device with\n\t'zpool " 7105 "replace'.\n")); 7106 break; 7107 7108 case ZPOOL_STATUS_REMOVED_DEV: 7109 (void) printf(gettext("status: One or more devices has " 7110 "been removed by the administrator.\n\tSufficient " 7111 "replicas exist for the pool to continue functioning in " 7112 "a\n\tdegraded state.\n")); 7113 (void) printf(gettext("action: Online the device using " 7114 "'zpool online' or replace the device with\n\t'zpool " 7115 "replace'.\n")); 7116 break; 7117 7118 case ZPOOL_STATUS_RESILVERING: 7119 (void) printf(gettext("status: One or more devices is " 7120 "currently being resilvered. The pool will\n\tcontinue " 7121 "to function, possibly in a degraded state.\n")); 7122 (void) printf(gettext("action: Wait for the resilver to " 7123 "complete.\n")); 7124 break; 7125 7126 case ZPOOL_STATUS_CORRUPT_DATA: 7127 (void) printf(gettext("status: One or more devices has " 7128 "experienced an error resulting in data\n\tcorruption. " 7129 "Applications may be affected.\n")); 7130 (void) printf(gettext("action: Restore the file in question " 7131 "if possible. Otherwise restore the\n\tentire pool from " 7132 "backup.\n")); 7133 break; 7134 7135 case ZPOOL_STATUS_CORRUPT_POOL: 7136 (void) printf(gettext("status: The pool metadata is corrupted " 7137 "and the pool cannot be opened.\n")); 7138 zpool_explain_recover(zpool_get_handle(zhp), 7139 zpool_get_name(zhp), reason, config); 7140 break; 7141 7142 case ZPOOL_STATUS_VERSION_OLDER: 7143 (void) printf(gettext("status: The pool is formatted using a " 7144 "legacy on-disk format. The pool can\n\tstill be used, " 7145 "but some features are unavailable.\n")); 7146 (void) printf(gettext("action: Upgrade the pool using 'zpool " 7147 "upgrade'. Once this is done, the\n\tpool will no longer " 7148 "be accessible on software that does not support feature\n" 7149 "\tflags.\n")); 7150 break; 7151 7152 case ZPOOL_STATUS_VERSION_NEWER: 7153 (void) printf(gettext("status: The pool has been upgraded to a " 7154 "newer, incompatible on-disk version.\n\tThe pool cannot " 7155 "be accessed on this system.\n")); 7156 (void) printf(gettext("action: Access the pool from a system " 7157 "running more recent software, or\n\trestore the pool from " 7158 "backup.\n")); 7159 break; 7160 7161 case ZPOOL_STATUS_FEAT_DISABLED: 7162 (void) printf(gettext("status: Some supported features are not " 7163 "enabled on the pool. The pool can\n\tstill be used, but " 7164 "some features are unavailable.\n")); 7165 (void) printf(gettext("action: Enable all features using " 7166 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 7167 "longer be accessible by software that does not support\n\t" 7168 "the features. See zpool-features(5) for details.\n")); 7169 break; 7170 7171 case ZPOOL_STATUS_UNSUP_FEAT_READ: 7172 (void) printf(gettext("status: The pool cannot be accessed on " 7173 "this system because it uses the\n\tfollowing feature(s) " 7174 "not supported on this system:\n")); 7175 zpool_print_unsup_feat(config); 7176 (void) printf("\n"); 7177 (void) printf(gettext("action: Access the pool from a system " 7178 "that supports the required feature(s),\n\tor restore the " 7179 "pool from backup.\n")); 7180 break; 7181 7182 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 7183 (void) printf(gettext("status: The pool can only be accessed " 7184 "in read-only mode on this system. It\n\tcannot be " 7185 "accessed in read-write mode because it uses the " 7186 "following\n\tfeature(s) not supported on this system:\n")); 7187 zpool_print_unsup_feat(config); 7188 (void) printf("\n"); 7189 (void) printf(gettext("action: The pool cannot be accessed in " 7190 "read-write mode. Import the pool with\n" 7191 "\t\"-o readonly=on\", access the pool from a system that " 7192 "supports the\n\trequired feature(s), or restore the " 7193 "pool from backup.\n")); 7194 break; 7195 7196 case ZPOOL_STATUS_FAULTED_DEV_R: 7197 (void) printf(gettext("status: One or more devices are " 7198 "faulted in response to persistent errors.\n\tSufficient " 7199 "replicas exist for the pool to continue functioning " 7200 "in a\n\tdegraded state.\n")); 7201 (void) printf(gettext("action: Replace the faulted device, " 7202 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 7203 break; 7204 7205 case ZPOOL_STATUS_FAULTED_DEV_NR: 7206 (void) printf(gettext("status: One or more devices are " 7207 "faulted in response to persistent errors. There are " 7208 "insufficient replicas for the pool to\n\tcontinue " 7209 "functioning.\n")); 7210 (void) printf(gettext("action: Destroy and re-create the pool " 7211 "from a backup source. Manually marking the device\n" 7212 "\trepaired using 'zpool clear' may allow some data " 7213 "to be recovered.\n")); 7214 break; 7215 7216 case ZPOOL_STATUS_IO_FAILURE_MMP: 7217 (void) printf(gettext("status: The pool is suspended because " 7218 "multihost writes failed or were delayed;\n\tanother " 7219 "system could import the pool undetected.\n")); 7220 (void) printf(gettext("action: Make sure the pool's devices " 7221 "are connected, then reboot your system and\n\timport the " 7222 "pool.\n")); 7223 break; 7224 7225 case ZPOOL_STATUS_IO_FAILURE_WAIT: 7226 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 7227 (void) printf(gettext("status: One or more devices are " 7228 "faulted in response to IO failures.\n")); 7229 (void) printf(gettext("action: Make sure the affected devices " 7230 "are connected, then run 'zpool clear'.\n")); 7231 break; 7232 7233 case ZPOOL_STATUS_BAD_LOG: 7234 (void) printf(gettext("status: An intent log record " 7235 "could not be read.\n" 7236 "\tWaiting for adminstrator intervention to fix the " 7237 "faulted pool.\n")); 7238 (void) printf(gettext("action: Either restore the affected " 7239 "device(s) and run 'zpool online',\n" 7240 "\tor ignore the intent log records by running " 7241 "'zpool clear'.\n")); 7242 break; 7243 7244 case ZPOOL_STATUS_ERRATA: 7245 (void) printf(gettext("status: Errata #%d detected.\n"), 7246 errata); 7247 7248 switch (errata) { 7249 case ZPOOL_ERRATA_NONE: 7250 break; 7251 7252 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 7253 (void) printf(gettext("action: To correct the issue " 7254 "run 'zpool scrub'.\n")); 7255 break; 7256 7257 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 7258 (void) printf(gettext("\tExisting encrypted datasets " 7259 "contain an on-disk incompatibility\n\twhich " 7260 "needs to be corrected.\n")); 7261 (void) printf(gettext("action: To correct the issue " 7262 "backup existing encrypted datasets to new\n\t" 7263 "encrypted datasets and destroy the old ones. " 7264 "'zfs mount -o ro' can\n\tbe used to temporarily " 7265 "mount existing encrypted datasets readonly.\n")); 7266 break; 7267 7268 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 7269 (void) printf(gettext("\tExisting encrypted datasets " 7270 "contain an on-disk incompatibility\n\twhich " 7271 "needs to be corrected.\n")); 7272 (void) printf(gettext("action: To correct the issue " 7273 "enable the bookmark_v2 feature and " 7274 "backup\n\tany existing encrypted datasets to " 7275 "new encrypted datasets and\n\tdestroy the old " 7276 "ones. If this pool does not contain any\n\t" 7277 "encrypted datasets, simply enable the " 7278 "bookmark_v2 feature\n")); 7279 break; 7280 7281 default: 7282 /* 7283 * All errata which allow the pool to be imported 7284 * must contain an action message. 7285 */ 7286 assert(0); 7287 } 7288 break; 7289 7290 default: 7291 /* 7292 * The remaining errors can't actually be generated, yet. 7293 */ 7294 assert(reason == ZPOOL_STATUS_OK); 7295 } 7296 7297 if (msgid != NULL) 7298 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 7299 msgid); 7300 7301 if (config != NULL) { 7302 uint64_t nerr; 7303 nvlist_t **spares, **l2cache; 7304 uint_t nspares, nl2cache; 7305 pool_checkpoint_stat_t *pcs = NULL; 7306 pool_scan_stat_t *ps = NULL; 7307 pool_removal_stat_t *prs = NULL; 7308 7309 (void) nvlist_lookup_uint64_array(nvroot, 7310 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7311 (void) nvlist_lookup_uint64_array(nvroot, 7312 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 7313 (void) nvlist_lookup_uint64_array(nvroot, 7314 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 7315 7316 print_scan_status(ps); 7317 print_checkpoint_scan_warning(ps, pcs); 7318 print_removal_status(zhp, prs); 7319 print_checkpoint_status(pcs); 7320 7321 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 7322 cbp->cb_name_flags); 7323 if (cbp->cb_namewidth < 10) 7324 cbp->cb_namewidth = 10; 7325 7326 (void) printf(gettext("config:\n\n")); 7327 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), 7328 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE", 7329 "CKSUM"); 7330 7331 if (cbp->cb_print_slow_ios) 7332 (void) printf(" %5s", gettext("SLOW")); 7333 7334 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0, 7335 B_FALSE); 7336 7337 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP); 7338 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 7339 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS); 7340 7341 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 7342 &l2cache, &nl2cache) == 0) 7343 print_l2cache(zhp, cbp, l2cache, nl2cache); 7344 7345 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 7346 &spares, &nspares) == 0) 7347 print_spares(zhp, cbp, spares, nspares); 7348 7349 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 7350 &nerr) == 0) { 7351 nvlist_t *nverrlist = NULL; 7352 7353 /* 7354 * If the approximate error count is small, get a 7355 * precise count by fetching the entire log and 7356 * uniquifying the results. 7357 */ 7358 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 7359 zpool_get_errlog(zhp, &nverrlist) == 0) { 7360 nvpair_t *elem; 7361 7362 elem = NULL; 7363 nerr = 0; 7364 while ((elem = nvlist_next_nvpair(nverrlist, 7365 elem)) != NULL) { 7366 nerr++; 7367 } 7368 } 7369 nvlist_free(nverrlist); 7370 7371 (void) printf("\n"); 7372 7373 if (nerr == 0) 7374 (void) printf(gettext("errors: No known data " 7375 "errors\n")); 7376 else if (!cbp->cb_verbose) 7377 (void) printf(gettext("errors: %llu data " 7378 "errors, use '-v' for a list\n"), 7379 (u_longlong_t)nerr); 7380 else 7381 print_error_log(zhp); 7382 } 7383 7384 if (cbp->cb_dedup_stats) 7385 print_dedup_stats(config); 7386 } else { 7387 (void) printf(gettext("config: The configuration cannot be " 7388 "determined.\n")); 7389 } 7390 7391 return (0); 7392 } 7393 7394 /* 7395 * zpool status [-igLpPstvx] [-T d|u] [pool] ... [interval [count]] 7396 * 7397 * -i Display vdev initialization status. 7398 * -g Display guid for individual vdev name. 7399 * -L Follow links when resolving vdev path name. 7400 * -p Display values in parsable (exact) format. 7401 * -P Display full path for vdev name. 7402 * -s Display slow IOs column. 7403 * -v Display complete error logs 7404 * -x Display only pools with potential problems 7405 * -D Display dedup status (undocumented) 7406 * -t Display vdev TRIM status. 7407 * -T Display a timestamp in date(1) or Unix format 7408 * 7409 * Describes the health status of all pools or some subset. 7410 */ 7411 int 7412 zpool_do_status(int argc, char **argv) 7413 { 7414 int c; 7415 int ret; 7416 float interval = 0; 7417 unsigned long count = 0; 7418 status_cbdata_t cb = { 0 }; 7419 7420 /* check options */ 7421 while ((c = getopt(argc, argv, "igLpPsvxDtT:")) != -1) { 7422 switch (c) { 7423 case 'i': 7424 cb.cb_print_vdev_init = B_TRUE; 7425 break; 7426 case 'g': 7427 cb.cb_name_flags |= VDEV_NAME_GUID; 7428 break; 7429 case 'L': 7430 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 7431 break; 7432 case 'p': 7433 cb.cb_literal = B_TRUE; 7434 break; 7435 case 'P': 7436 cb.cb_name_flags |= VDEV_NAME_PATH; 7437 break; 7438 case 's': 7439 cb.cb_print_slow_ios = B_TRUE; 7440 break; 7441 case 'v': 7442 cb.cb_verbose = B_TRUE; 7443 break; 7444 case 'x': 7445 cb.cb_explain = B_TRUE; 7446 break; 7447 case 'D': 7448 cb.cb_dedup_stats = B_TRUE; 7449 break; 7450 case 't': 7451 cb.cb_print_vdev_trim = B_TRUE; 7452 break; 7453 case 'T': 7454 get_timestamp_arg(*optarg); 7455 break; 7456 case '?': 7457 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7458 optopt); 7459 usage(B_FALSE); 7460 } 7461 } 7462 7463 argc -= optind; 7464 argv += optind; 7465 7466 get_interval_count(&argc, argv, &interval, &count); 7467 7468 if (argc == 0) 7469 cb.cb_allpools = B_TRUE; 7470 7471 cb.cb_first = B_TRUE; 7472 cb.cb_print_status = B_TRUE; 7473 7474 for (;;) { 7475 if (timestamp_fmt != NODATE) 7476 print_timestamp(timestamp_fmt); 7477 7478 ret = for_each_pool(argc, argv, B_TRUE, NULL, 7479 status_callback, &cb); 7480 7481 if (argc == 0 && cb.cb_count == 0) 7482 (void) printf(gettext("no pools available\n")); 7483 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 7484 (void) printf(gettext("all pools are healthy\n")); 7485 7486 if (ret != 0) 7487 return (ret); 7488 7489 if (interval == 0) 7490 break; 7491 7492 if (count != 0 && --count == 0) 7493 break; 7494 7495 (void) fsleep(interval); 7496 } 7497 7498 return (0); 7499 } 7500 7501 typedef struct upgrade_cbdata { 7502 int cb_first; 7503 int cb_argc; 7504 uint64_t cb_version; 7505 char **cb_argv; 7506 } upgrade_cbdata_t; 7507 7508 static int 7509 upgrade_version(zpool_handle_t *zhp, uint64_t version) 7510 { 7511 int ret; 7512 nvlist_t *config; 7513 uint64_t oldversion; 7514 7515 config = zpool_get_config(zhp, NULL); 7516 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7517 &oldversion) == 0); 7518 7519 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 7520 assert(oldversion < version); 7521 7522 ret = zpool_upgrade(zhp, version); 7523 if (ret != 0) 7524 return (ret); 7525 7526 if (version >= SPA_VERSION_FEATURES) { 7527 (void) printf(gettext("Successfully upgraded " 7528 "'%s' from version %llu to feature flags.\n"), 7529 zpool_get_name(zhp), oldversion); 7530 } else { 7531 (void) printf(gettext("Successfully upgraded " 7532 "'%s' from version %llu to version %llu.\n"), 7533 zpool_get_name(zhp), oldversion, version); 7534 } 7535 7536 return (0); 7537 } 7538 7539 static int 7540 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 7541 { 7542 int i, ret, count; 7543 boolean_t firstff = B_TRUE; 7544 nvlist_t *enabled = zpool_get_features(zhp); 7545 7546 count = 0; 7547 for (i = 0; i < SPA_FEATURES; i++) { 7548 const char *fname = spa_feature_table[i].fi_uname; 7549 const char *fguid = spa_feature_table[i].fi_guid; 7550 if (!nvlist_exists(enabled, fguid)) { 7551 char *propname; 7552 verify(-1 != asprintf(&propname, "feature@%s", fname)); 7553 ret = zpool_set_prop(zhp, propname, 7554 ZFS_FEATURE_ENABLED); 7555 if (ret != 0) { 7556 free(propname); 7557 return (ret); 7558 } 7559 count++; 7560 7561 if (firstff) { 7562 (void) printf(gettext("Enabled the " 7563 "following features on '%s':\n"), 7564 zpool_get_name(zhp)); 7565 firstff = B_FALSE; 7566 } 7567 (void) printf(gettext(" %s\n"), fname); 7568 free(propname); 7569 } 7570 } 7571 7572 if (countp != NULL) 7573 *countp = count; 7574 return (0); 7575 } 7576 7577 static int 7578 upgrade_cb(zpool_handle_t *zhp, void *arg) 7579 { 7580 upgrade_cbdata_t *cbp = arg; 7581 nvlist_t *config; 7582 uint64_t version; 7583 boolean_t printnl = B_FALSE; 7584 int ret; 7585 7586 config = zpool_get_config(zhp, NULL); 7587 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7588 &version) == 0); 7589 7590 assert(SPA_VERSION_IS_SUPPORTED(version)); 7591 7592 if (version < cbp->cb_version) { 7593 cbp->cb_first = B_FALSE; 7594 ret = upgrade_version(zhp, cbp->cb_version); 7595 if (ret != 0) 7596 return (ret); 7597 printnl = B_TRUE; 7598 7599 /* 7600 * If they did "zpool upgrade -a", then we could 7601 * be doing ioctls to different pools. We need 7602 * to log this history once to each pool, and bypass 7603 * the normal history logging that happens in main(). 7604 */ 7605 (void) zpool_log_history(g_zfs, history_str); 7606 log_history = B_FALSE; 7607 } 7608 7609 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 7610 int count; 7611 ret = upgrade_enable_all(zhp, &count); 7612 if (ret != 0) 7613 return (ret); 7614 7615 if (count > 0) { 7616 cbp->cb_first = B_FALSE; 7617 printnl = B_TRUE; 7618 } 7619 } 7620 7621 if (printnl) { 7622 (void) printf(gettext("\n")); 7623 } 7624 7625 return (0); 7626 } 7627 7628 static int 7629 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 7630 { 7631 upgrade_cbdata_t *cbp = arg; 7632 nvlist_t *config; 7633 uint64_t version; 7634 7635 config = zpool_get_config(zhp, NULL); 7636 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7637 &version) == 0); 7638 7639 assert(SPA_VERSION_IS_SUPPORTED(version)); 7640 7641 if (version < SPA_VERSION_FEATURES) { 7642 if (cbp->cb_first) { 7643 (void) printf(gettext("The following pools are " 7644 "formatted with legacy version numbers and can\n" 7645 "be upgraded to use feature flags. After " 7646 "being upgraded, these pools\nwill no " 7647 "longer be accessible by software that does not " 7648 "support feature\nflags.\n\n")); 7649 (void) printf(gettext("VER POOL\n")); 7650 (void) printf(gettext("--- ------------\n")); 7651 cbp->cb_first = B_FALSE; 7652 } 7653 7654 (void) printf("%2llu %s\n", (u_longlong_t)version, 7655 zpool_get_name(zhp)); 7656 } 7657 7658 return (0); 7659 } 7660 7661 static int 7662 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 7663 { 7664 upgrade_cbdata_t *cbp = arg; 7665 nvlist_t *config; 7666 uint64_t version; 7667 7668 config = zpool_get_config(zhp, NULL); 7669 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7670 &version) == 0); 7671 7672 if (version >= SPA_VERSION_FEATURES) { 7673 int i; 7674 boolean_t poolfirst = B_TRUE; 7675 nvlist_t *enabled = zpool_get_features(zhp); 7676 7677 for (i = 0; i < SPA_FEATURES; i++) { 7678 const char *fguid = spa_feature_table[i].fi_guid; 7679 const char *fname = spa_feature_table[i].fi_uname; 7680 if (!nvlist_exists(enabled, fguid)) { 7681 if (cbp->cb_first) { 7682 (void) printf(gettext("\nSome " 7683 "supported features are not " 7684 "enabled on the following pools. " 7685 "Once a\nfeature is enabled the " 7686 "pool may become incompatible with " 7687 "software\nthat does not support " 7688 "the feature. See " 7689 "zpool-features(5) for " 7690 "details.\n\n")); 7691 (void) printf(gettext("POOL " 7692 "FEATURE\n")); 7693 (void) printf(gettext("------" 7694 "---------\n")); 7695 cbp->cb_first = B_FALSE; 7696 } 7697 7698 if (poolfirst) { 7699 (void) printf(gettext("%s\n"), 7700 zpool_get_name(zhp)); 7701 poolfirst = B_FALSE; 7702 } 7703 7704 (void) printf(gettext(" %s\n"), fname); 7705 } 7706 } 7707 } 7708 7709 return (0); 7710 } 7711 7712 /* ARGSUSED */ 7713 static int 7714 upgrade_one(zpool_handle_t *zhp, void *data) 7715 { 7716 boolean_t printnl = B_FALSE; 7717 upgrade_cbdata_t *cbp = data; 7718 uint64_t cur_version; 7719 int ret; 7720 7721 if (strcmp("log", zpool_get_name(zhp)) == 0) { 7722 (void) printf(gettext("'log' is now a reserved word\n" 7723 "Pool 'log' must be renamed using export and import" 7724 " to upgrade.\n")); 7725 return (1); 7726 } 7727 7728 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 7729 if (cur_version > cbp->cb_version) { 7730 (void) printf(gettext("Pool '%s' is already formatted " 7731 "using more current version '%llu'.\n\n"), 7732 zpool_get_name(zhp), cur_version); 7733 return (0); 7734 } 7735 7736 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 7737 (void) printf(gettext("Pool '%s' is already formatted " 7738 "using version %llu.\n\n"), zpool_get_name(zhp), 7739 cbp->cb_version); 7740 return (0); 7741 } 7742 7743 if (cur_version != cbp->cb_version) { 7744 printnl = B_TRUE; 7745 ret = upgrade_version(zhp, cbp->cb_version); 7746 if (ret != 0) 7747 return (ret); 7748 } 7749 7750 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 7751 int count = 0; 7752 ret = upgrade_enable_all(zhp, &count); 7753 if (ret != 0) 7754 return (ret); 7755 7756 if (count != 0) { 7757 printnl = B_TRUE; 7758 } else if (cur_version == SPA_VERSION) { 7759 (void) printf(gettext("Pool '%s' already has all " 7760 "supported features enabled.\n"), 7761 zpool_get_name(zhp)); 7762 } 7763 } 7764 7765 if (printnl) { 7766 (void) printf(gettext("\n")); 7767 } 7768 7769 return (0); 7770 } 7771 7772 /* 7773 * zpool upgrade 7774 * zpool upgrade -v 7775 * zpool upgrade [-V version] <-a | pool ...> 7776 * 7777 * With no arguments, display downrev'd ZFS pool available for upgrade. 7778 * Individual pools can be upgraded by specifying the pool, and '-a' will 7779 * upgrade all pools. 7780 */ 7781 int 7782 zpool_do_upgrade(int argc, char **argv) 7783 { 7784 int c; 7785 upgrade_cbdata_t cb = { 0 }; 7786 int ret = 0; 7787 boolean_t showversions = B_FALSE; 7788 boolean_t upgradeall = B_FALSE; 7789 char *end; 7790 7791 7792 /* check options */ 7793 while ((c = getopt(argc, argv, ":avV:")) != -1) { 7794 switch (c) { 7795 case 'a': 7796 upgradeall = B_TRUE; 7797 break; 7798 case 'v': 7799 showversions = B_TRUE; 7800 break; 7801 case 'V': 7802 cb.cb_version = strtoll(optarg, &end, 10); 7803 if (*end != '\0' || 7804 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 7805 (void) fprintf(stderr, 7806 gettext("invalid version '%s'\n"), optarg); 7807 usage(B_FALSE); 7808 } 7809 break; 7810 case ':': 7811 (void) fprintf(stderr, gettext("missing argument for " 7812 "'%c' option\n"), optopt); 7813 usage(B_FALSE); 7814 break; 7815 case '?': 7816 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7817 optopt); 7818 usage(B_FALSE); 7819 } 7820 } 7821 7822 cb.cb_argc = argc; 7823 cb.cb_argv = argv; 7824 argc -= optind; 7825 argv += optind; 7826 7827 if (cb.cb_version == 0) { 7828 cb.cb_version = SPA_VERSION; 7829 } else if (!upgradeall && argc == 0) { 7830 (void) fprintf(stderr, gettext("-V option is " 7831 "incompatible with other arguments\n")); 7832 usage(B_FALSE); 7833 } 7834 7835 if (showversions) { 7836 if (upgradeall || argc != 0) { 7837 (void) fprintf(stderr, gettext("-v option is " 7838 "incompatible with other arguments\n")); 7839 usage(B_FALSE); 7840 } 7841 } else if (upgradeall) { 7842 if (argc != 0) { 7843 (void) fprintf(stderr, gettext("-a option should not " 7844 "be used along with a pool name\n")); 7845 usage(B_FALSE); 7846 } 7847 } 7848 7849 (void) printf(gettext("This system supports ZFS pool feature " 7850 "flags.\n\n")); 7851 if (showversions) { 7852 int i; 7853 7854 (void) printf(gettext("The following features are " 7855 "supported:\n\n")); 7856 (void) printf(gettext("FEAT DESCRIPTION\n")); 7857 (void) printf("----------------------------------------------" 7858 "---------------\n"); 7859 for (i = 0; i < SPA_FEATURES; i++) { 7860 zfeature_info_t *fi = &spa_feature_table[i]; 7861 const char *ro = 7862 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 7863 " (read-only compatible)" : ""; 7864 7865 (void) printf("%-37s%s\n", fi->fi_uname, ro); 7866 (void) printf(" %s\n", fi->fi_desc); 7867 } 7868 (void) printf("\n"); 7869 7870 (void) printf(gettext("The following legacy versions are also " 7871 "supported:\n\n")); 7872 (void) printf(gettext("VER DESCRIPTION\n")); 7873 (void) printf("--- -----------------------------------------" 7874 "---------------\n"); 7875 (void) printf(gettext(" 1 Initial ZFS version\n")); 7876 (void) printf(gettext(" 2 Ditto blocks " 7877 "(replicated metadata)\n")); 7878 (void) printf(gettext(" 3 Hot spares and double parity " 7879 "RAID-Z\n")); 7880 (void) printf(gettext(" 4 zpool history\n")); 7881 (void) printf(gettext(" 5 Compression using the gzip " 7882 "algorithm\n")); 7883 (void) printf(gettext(" 6 bootfs pool property\n")); 7884 (void) printf(gettext(" 7 Separate intent log devices\n")); 7885 (void) printf(gettext(" 8 Delegated administration\n")); 7886 (void) printf(gettext(" 9 refquota and refreservation " 7887 "properties\n")); 7888 (void) printf(gettext(" 10 Cache devices\n")); 7889 (void) printf(gettext(" 11 Improved scrub performance\n")); 7890 (void) printf(gettext(" 12 Snapshot properties\n")); 7891 (void) printf(gettext(" 13 snapused property\n")); 7892 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 7893 (void) printf(gettext(" 15 user/group space accounting\n")); 7894 (void) printf(gettext(" 16 stmf property support\n")); 7895 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 7896 (void) printf(gettext(" 18 Snapshot user holds\n")); 7897 (void) printf(gettext(" 19 Log device removal\n")); 7898 (void) printf(gettext(" 20 Compression using zle " 7899 "(zero-length encoding)\n")); 7900 (void) printf(gettext(" 21 Deduplication\n")); 7901 (void) printf(gettext(" 22 Received properties\n")); 7902 (void) printf(gettext(" 23 Slim ZIL\n")); 7903 (void) printf(gettext(" 24 System attributes\n")); 7904 (void) printf(gettext(" 25 Improved scrub stats\n")); 7905 (void) printf(gettext(" 26 Improved snapshot deletion " 7906 "performance\n")); 7907 (void) printf(gettext(" 27 Improved snapshot creation " 7908 "performance\n")); 7909 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 7910 (void) printf(gettext("\nFor more information on a particular " 7911 "version, including supported releases,\n")); 7912 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 7913 } else if (argc == 0 && upgradeall) { 7914 cb.cb_first = B_TRUE; 7915 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 7916 if (ret == 0 && cb.cb_first) { 7917 if (cb.cb_version == SPA_VERSION) { 7918 (void) printf(gettext("All pools are already " 7919 "formatted using feature flags.\n\n")); 7920 (void) printf(gettext("Every feature flags " 7921 "pool already has all supported features " 7922 "enabled.\n")); 7923 } else { 7924 (void) printf(gettext("All pools are already " 7925 "formatted with version %llu or higher.\n"), 7926 cb.cb_version); 7927 } 7928 } 7929 } else if (argc == 0) { 7930 cb.cb_first = B_TRUE; 7931 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 7932 assert(ret == 0); 7933 7934 if (cb.cb_first) { 7935 (void) printf(gettext("All pools are formatted " 7936 "using feature flags.\n\n")); 7937 } else { 7938 (void) printf(gettext("\nUse 'zpool upgrade -v' " 7939 "for a list of available legacy versions.\n")); 7940 } 7941 7942 cb.cb_first = B_TRUE; 7943 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 7944 assert(ret == 0); 7945 7946 if (cb.cb_first) { 7947 (void) printf(gettext("Every feature flags pool has " 7948 "all supported features enabled.\n")); 7949 } else { 7950 (void) printf(gettext("\n")); 7951 } 7952 } else { 7953 ret = for_each_pool(argc, argv, B_FALSE, NULL, 7954 upgrade_one, &cb); 7955 } 7956 7957 return (ret); 7958 } 7959 7960 typedef struct hist_cbdata { 7961 boolean_t first; 7962 boolean_t longfmt; 7963 boolean_t internal; 7964 } hist_cbdata_t; 7965 7966 static void 7967 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb) 7968 { 7969 nvlist_t **records; 7970 uint_t numrecords; 7971 int i; 7972 7973 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 7974 &records, &numrecords) == 0); 7975 for (i = 0; i < numrecords; i++) { 7976 nvlist_t *rec = records[i]; 7977 char tbuf[30] = ""; 7978 7979 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 7980 time_t tsec; 7981 struct tm t; 7982 7983 tsec = fnvlist_lookup_uint64(records[i], 7984 ZPOOL_HIST_TIME); 7985 (void) localtime_r(&tsec, &t); 7986 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 7987 } 7988 7989 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 7990 (void) printf("%s %s", tbuf, 7991 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 7992 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 7993 int ievent = 7994 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 7995 if (!cb->internal) 7996 continue; 7997 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 7998 (void) printf("%s unrecognized record:\n", 7999 tbuf); 8000 dump_nvlist(rec, 4); 8001 continue; 8002 } 8003 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 8004 zfs_history_event_names[ievent], 8005 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 8006 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 8007 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 8008 if (!cb->internal) 8009 continue; 8010 (void) printf("%s [txg:%lld] %s", tbuf, 8011 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 8012 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 8013 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 8014 (void) printf(" %s (%llu)", 8015 fnvlist_lookup_string(rec, 8016 ZPOOL_HIST_DSNAME), 8017 fnvlist_lookup_uint64(rec, 8018 ZPOOL_HIST_DSID)); 8019 } 8020 (void) printf(" %s", fnvlist_lookup_string(rec, 8021 ZPOOL_HIST_INT_STR)); 8022 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 8023 if (!cb->internal) 8024 continue; 8025 (void) printf("%s ioctl %s\n", tbuf, 8026 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 8027 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 8028 (void) printf(" input:\n"); 8029 dump_nvlist(fnvlist_lookup_nvlist(rec, 8030 ZPOOL_HIST_INPUT_NVL), 8); 8031 } 8032 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 8033 (void) printf(" output:\n"); 8034 dump_nvlist(fnvlist_lookup_nvlist(rec, 8035 ZPOOL_HIST_OUTPUT_NVL), 8); 8036 } 8037 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 8038 (void) printf(" errno: %lld\n", 8039 fnvlist_lookup_int64(rec, 8040 ZPOOL_HIST_ERRNO)); 8041 } 8042 } else { 8043 if (!cb->internal) 8044 continue; 8045 (void) printf("%s unrecognized record:\n", tbuf); 8046 dump_nvlist(rec, 4); 8047 } 8048 8049 if (!cb->longfmt) { 8050 (void) printf("\n"); 8051 continue; 8052 } 8053 (void) printf(" ["); 8054 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 8055 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 8056 struct passwd *pwd = getpwuid(who); 8057 (void) printf("user %d ", (int)who); 8058 if (pwd != NULL) 8059 (void) printf("(%s) ", pwd->pw_name); 8060 } 8061 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 8062 (void) printf("on %s", 8063 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 8064 } 8065 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 8066 (void) printf(":%s", 8067 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 8068 } 8069 (void) printf("]"); 8070 (void) printf("\n"); 8071 } 8072 } 8073 8074 /* 8075 * Print out the command history for a specific pool. 8076 */ 8077 static int 8078 get_history_one(zpool_handle_t *zhp, void *data) 8079 { 8080 nvlist_t *nvhis; 8081 int ret; 8082 hist_cbdata_t *cb = (hist_cbdata_t *)data; 8083 uint64_t off = 0; 8084 boolean_t eof = B_FALSE; 8085 8086 cb->first = B_FALSE; 8087 8088 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 8089 8090 while (!eof) { 8091 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0) 8092 return (ret); 8093 8094 print_history_records(nvhis, cb); 8095 nvlist_free(nvhis); 8096 } 8097 (void) printf("\n"); 8098 8099 return (ret); 8100 } 8101 8102 /* 8103 * zpool history <pool> 8104 * 8105 * Displays the history of commands that modified pools. 8106 */ 8107 int 8108 zpool_do_history(int argc, char **argv) 8109 { 8110 hist_cbdata_t cbdata = { 0 }; 8111 int ret; 8112 int c; 8113 8114 cbdata.first = B_TRUE; 8115 /* check options */ 8116 while ((c = getopt(argc, argv, "li")) != -1) { 8117 switch (c) { 8118 case 'l': 8119 cbdata.longfmt = B_TRUE; 8120 break; 8121 case 'i': 8122 cbdata.internal = B_TRUE; 8123 break; 8124 case '?': 8125 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8126 optopt); 8127 usage(B_FALSE); 8128 } 8129 } 8130 argc -= optind; 8131 argv += optind; 8132 8133 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 8134 &cbdata); 8135 8136 if (argc == 0 && cbdata.first == B_TRUE) { 8137 (void) printf(gettext("no pools available\n")); 8138 return (0); 8139 } 8140 8141 return (ret); 8142 } 8143 8144 static int 8145 get_callback(zpool_handle_t *zhp, void *data) 8146 { 8147 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 8148 char value[MAXNAMELEN]; 8149 zprop_source_t srctype; 8150 zprop_list_t *pl; 8151 8152 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 8153 8154 /* 8155 * Skip the special fake placeholder. This will also skip 8156 * over the name property when 'all' is specified. 8157 */ 8158 if (pl->pl_prop == ZPOOL_PROP_NAME && 8159 pl == cbp->cb_proplist) 8160 continue; 8161 8162 if (pl->pl_prop == ZPROP_INVAL && 8163 (zpool_prop_feature(pl->pl_user_prop) || 8164 zpool_prop_unsupported(pl->pl_user_prop))) { 8165 srctype = ZPROP_SRC_LOCAL; 8166 8167 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 8168 value, sizeof (value)) == 0) { 8169 zprop_print_one_property(zpool_get_name(zhp), 8170 cbp, pl->pl_user_prop, value, srctype, 8171 NULL, NULL); 8172 } 8173 } else { 8174 if (zpool_get_prop(zhp, pl->pl_prop, value, 8175 sizeof (value), &srctype, cbp->cb_literal) != 0) 8176 continue; 8177 8178 zprop_print_one_property(zpool_get_name(zhp), cbp, 8179 zpool_prop_to_name(pl->pl_prop), value, srctype, 8180 NULL, NULL); 8181 } 8182 } 8183 return (0); 8184 } 8185 8186 /* 8187 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 8188 * 8189 * -H Scripted mode. Don't display headers, and separate properties 8190 * by a single tab. 8191 * -o List of columns to display. Defaults to 8192 * "name,property,value,source". 8193 * -p Diplay values in parsable (exact) format. 8194 * 8195 * Get properties of pools in the system. Output space statistics 8196 * for each one as well as other attributes. 8197 */ 8198 int 8199 zpool_do_get(int argc, char **argv) 8200 { 8201 zprop_get_cbdata_t cb = { 0 }; 8202 zprop_list_t fake_name = { 0 }; 8203 int ret; 8204 int c, i; 8205 char *value; 8206 8207 cb.cb_first = B_TRUE; 8208 8209 /* 8210 * Set up default columns and sources. 8211 */ 8212 cb.cb_sources = ZPROP_SRC_ALL; 8213 cb.cb_columns[0] = GET_COL_NAME; 8214 cb.cb_columns[1] = GET_COL_PROPERTY; 8215 cb.cb_columns[2] = GET_COL_VALUE; 8216 cb.cb_columns[3] = GET_COL_SOURCE; 8217 cb.cb_type = ZFS_TYPE_POOL; 8218 8219 /* check options */ 8220 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 8221 switch (c) { 8222 case 'p': 8223 cb.cb_literal = B_TRUE; 8224 break; 8225 case 'H': 8226 cb.cb_scripted = B_TRUE; 8227 break; 8228 case 'o': 8229 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 8230 i = 0; 8231 while (*optarg != '\0') { 8232 static char *col_subopts[] = 8233 { "name", "property", "value", "source", 8234 "all", NULL }; 8235 8236 if (i == ZFS_GET_NCOLS) { 8237 (void) fprintf(stderr, gettext("too " 8238 "many fields given to -o " 8239 "option\n")); 8240 usage(B_FALSE); 8241 } 8242 8243 switch (getsubopt(&optarg, col_subopts, 8244 &value)) { 8245 case 0: 8246 cb.cb_columns[i++] = GET_COL_NAME; 8247 break; 8248 case 1: 8249 cb.cb_columns[i++] = GET_COL_PROPERTY; 8250 break; 8251 case 2: 8252 cb.cb_columns[i++] = GET_COL_VALUE; 8253 break; 8254 case 3: 8255 cb.cb_columns[i++] = GET_COL_SOURCE; 8256 break; 8257 case 4: 8258 if (i > 0) { 8259 (void) fprintf(stderr, 8260 gettext("\"all\" conflicts " 8261 "with specific fields " 8262 "given to -o option\n")); 8263 usage(B_FALSE); 8264 } 8265 cb.cb_columns[0] = GET_COL_NAME; 8266 cb.cb_columns[1] = GET_COL_PROPERTY; 8267 cb.cb_columns[2] = GET_COL_VALUE; 8268 cb.cb_columns[3] = GET_COL_SOURCE; 8269 i = ZFS_GET_NCOLS; 8270 break; 8271 default: 8272 (void) fprintf(stderr, 8273 gettext("invalid column name " 8274 "'%s'\n"), value); 8275 usage(B_FALSE); 8276 } 8277 } 8278 break; 8279 case '?': 8280 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8281 optopt); 8282 usage(B_FALSE); 8283 } 8284 } 8285 8286 argc -= optind; 8287 argv += optind; 8288 8289 if (argc < 1) { 8290 (void) fprintf(stderr, gettext("missing property " 8291 "argument\n")); 8292 usage(B_FALSE); 8293 } 8294 8295 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 8296 ZFS_TYPE_POOL) != 0) 8297 usage(B_FALSE); 8298 8299 argc--; 8300 argv++; 8301 8302 if (cb.cb_proplist != NULL) { 8303 fake_name.pl_prop = ZPOOL_PROP_NAME; 8304 fake_name.pl_width = strlen(gettext("NAME")); 8305 fake_name.pl_next = cb.cb_proplist; 8306 cb.cb_proplist = &fake_name; 8307 } 8308 8309 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 8310 get_callback, &cb); 8311 8312 if (cb.cb_proplist == &fake_name) 8313 zprop_free_list(fake_name.pl_next); 8314 else 8315 zprop_free_list(cb.cb_proplist); 8316 8317 return (ret); 8318 } 8319 8320 typedef struct set_cbdata { 8321 char *cb_propname; 8322 char *cb_value; 8323 boolean_t cb_any_successful; 8324 } set_cbdata_t; 8325 8326 int 8327 set_callback(zpool_handle_t *zhp, void *data) 8328 { 8329 int error; 8330 set_cbdata_t *cb = (set_cbdata_t *)data; 8331 8332 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 8333 8334 if (!error) 8335 cb->cb_any_successful = B_TRUE; 8336 8337 return (error); 8338 } 8339 8340 int 8341 zpool_do_set(int argc, char **argv) 8342 { 8343 set_cbdata_t cb = { 0 }; 8344 int error; 8345 8346 if (argc > 1 && argv[1][0] == '-') { 8347 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8348 argv[1][1]); 8349 usage(B_FALSE); 8350 } 8351 8352 if (argc < 2) { 8353 (void) fprintf(stderr, gettext("missing property=value " 8354 "argument\n")); 8355 usage(B_FALSE); 8356 } 8357 8358 if (argc < 3) { 8359 (void) fprintf(stderr, gettext("missing pool name\n")); 8360 usage(B_FALSE); 8361 } 8362 8363 if (argc > 3) { 8364 (void) fprintf(stderr, gettext("too many pool names\n")); 8365 usage(B_FALSE); 8366 } 8367 8368 cb.cb_propname = argv[1]; 8369 cb.cb_value = strchr(cb.cb_propname, '='); 8370 if (cb.cb_value == NULL) { 8371 (void) fprintf(stderr, gettext("missing value in " 8372 "property=value argument\n")); 8373 usage(B_FALSE); 8374 } 8375 8376 *(cb.cb_value) = '\0'; 8377 cb.cb_value++; 8378 8379 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 8380 set_callback, &cb); 8381 8382 return (error); 8383 } 8384 8385 static int 8386 find_command_idx(char *command, int *idx) 8387 { 8388 int i; 8389 8390 for (i = 0; i < NCOMMAND; i++) { 8391 if (command_table[i].name == NULL) 8392 continue; 8393 8394 if (strcmp(command, command_table[i].name) == 0) { 8395 *idx = i; 8396 return (0); 8397 } 8398 } 8399 return (1); 8400 } 8401 8402 int 8403 main(int argc, char **argv) 8404 { 8405 int ret = 0; 8406 int i; 8407 char *cmdname; 8408 8409 (void) setlocale(LC_ALL, ""); 8410 (void) textdomain(TEXT_DOMAIN); 8411 8412 if ((g_zfs = libzfs_init()) == NULL) { 8413 (void) fprintf(stderr, gettext("internal error: failed to " 8414 "initialize ZFS library\n")); 8415 return (1); 8416 } 8417 8418 libzfs_print_on_error(g_zfs, B_TRUE); 8419 8420 opterr = 0; 8421 8422 /* 8423 * Make sure the user has specified some command. 8424 */ 8425 if (argc < 2) { 8426 (void) fprintf(stderr, gettext("missing command\n")); 8427 usage(B_FALSE); 8428 } 8429 8430 cmdname = argv[1]; 8431 8432 /* 8433 * Special case '-?' 8434 */ 8435 if (strcmp(cmdname, "-?") == 0) 8436 usage(B_TRUE); 8437 8438 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 8439 8440 /* 8441 * Run the appropriate command. 8442 */ 8443 if (find_command_idx(cmdname, &i) == 0) { 8444 current_command = &command_table[i]; 8445 ret = command_table[i].func(argc - 1, argv + 1); 8446 } else if (strchr(cmdname, '=')) { 8447 verify(find_command_idx("set", &i) == 0); 8448 current_command = &command_table[i]; 8449 ret = command_table[i].func(argc, argv); 8450 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 8451 /* 8452 * 'freeze' is a vile debugging abomination, so we treat 8453 * it as such. 8454 */ 8455 char buf[16384]; 8456 int fd = open(ZFS_DEV, O_RDWR); 8457 (void) strcpy((void *)buf, argv[2]); 8458 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 8459 } else { 8460 (void) fprintf(stderr, gettext("unrecognized " 8461 "command '%s'\n"), cmdname); 8462 usage(B_FALSE); 8463 } 8464 8465 if (ret == 0 && log_history) 8466 (void) zpool_log_history(g_zfs, history_str); 8467 8468 libzfs_fini(g_zfs); 8469 8470 /* 8471 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 8472 * for the purposes of running ::findleaks. 8473 */ 8474 if (getenv("ZFS_ABORT") != NULL) { 8475 (void) printf("dumping core by request\n"); 8476 abort(); 8477 } 8478 8479 return (ret); 8480 } 8481