1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 26 * Copyright (c) 2011, 2024 by Delphix. All rights reserved. 27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> 28 * Copyright (c) 2018 Datto Inc. 29 * Copyright (c) 2017 Open-E, Inc. All Rights Reserved. 30 * Copyright (c) 2017, Intel Corporation. 31 * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com> 32 * Copyright (c) 2021, Colm Buckley <colm@tuatha.org> 33 * Copyright (c) 2021, 2023, Klara Inc. 34 */ 35 36 #include <errno.h> 37 #include <libintl.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <strings.h> 41 #include <unistd.h> 42 #include <libgen.h> 43 #include <zone.h> 44 #include <sys/stat.h> 45 #include <sys/efi_partition.h> 46 #include <sys/systeminfo.h> 47 #include <sys/zfs_ioctl.h> 48 #include <sys/zfs_sysfs.h> 49 #include <sys/vdev_disk.h> 50 #include <sys/types.h> 51 #include <dlfcn.h> 52 #include <libzutil.h> 53 #include <fcntl.h> 54 55 #include "zfs_namecheck.h" 56 #include "zfs_prop.h" 57 #include "libzfs_impl.h" 58 #include "zfs_comutil.h" 59 #include "zfeature_common.h" 60 61 static boolean_t zpool_vdev_is_interior(const char *name); 62 63 typedef struct prop_flags { 64 unsigned int create:1; /* Validate property on creation */ 65 unsigned int import:1; /* Validate property on import */ 66 unsigned int vdevprop:1; /* Validate property as a VDEV property */ 67 } prop_flags_t; 68 69 /* 70 * ==================================================================== 71 * zpool property functions 72 * ==================================================================== 73 */ 74 75 static int 76 zpool_get_all_props(zpool_handle_t *zhp) 77 { 78 zfs_cmd_t zc = {"\0"}; 79 libzfs_handle_t *hdl = zhp->zpool_hdl; 80 81 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 82 83 if (zhp->zpool_n_propnames > 0) { 84 nvlist_t *innvl = fnvlist_alloc(); 85 fnvlist_add_string_array(innvl, ZPOOL_GET_PROPS_NAMES, 86 zhp->zpool_propnames, zhp->zpool_n_propnames); 87 zcmd_write_src_nvlist(hdl, &zc, innvl); 88 fnvlist_free(innvl); 89 } 90 91 zcmd_alloc_dst_nvlist(hdl, &zc, 0); 92 93 while (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) { 94 if (errno == ENOMEM) 95 zcmd_expand_dst_nvlist(hdl, &zc); 96 else { 97 zcmd_free_nvlists(&zc); 98 return (-1); 99 } 100 } 101 102 if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) { 103 zcmd_free_nvlists(&zc); 104 return (-1); 105 } 106 107 zcmd_free_nvlists(&zc); 108 109 return (0); 110 } 111 112 int 113 zpool_props_refresh(zpool_handle_t *zhp) 114 { 115 nvlist_t *old_props; 116 117 old_props = zhp->zpool_props; 118 119 if (zpool_get_all_props(zhp) != 0) 120 return (-1); 121 122 nvlist_free(old_props); 123 return (0); 124 } 125 126 static const char * 127 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop, 128 zprop_source_t *src) 129 { 130 nvlist_t *nv, *nvl; 131 const char *value; 132 zprop_source_t source; 133 134 nvl = zhp->zpool_props; 135 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) { 136 source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 137 value = fnvlist_lookup_string(nv, ZPROP_VALUE); 138 } else { 139 source = ZPROP_SRC_DEFAULT; 140 if ((value = zpool_prop_default_string(prop)) == NULL) 141 value = "-"; 142 } 143 144 if (src) 145 *src = source; 146 147 return (value); 148 } 149 150 uint64_t 151 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src) 152 { 153 nvlist_t *nv, *nvl; 154 uint64_t value; 155 zprop_source_t source; 156 157 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) { 158 /* 159 * zpool_get_all_props() has most likely failed because 160 * the pool is faulted, but if all we need is the top level 161 * vdev's guid then get it from the zhp config nvlist. 162 */ 163 if ((prop == ZPOOL_PROP_GUID) && 164 (nvlist_lookup_nvlist(zhp->zpool_config, 165 ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) && 166 (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value) 167 == 0)) { 168 return (value); 169 } 170 return (zpool_prop_default_numeric(prop)); 171 } 172 173 nvl = zhp->zpool_props; 174 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) { 175 source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 176 value = fnvlist_lookup_uint64(nv, ZPROP_VALUE); 177 } else { 178 source = ZPROP_SRC_DEFAULT; 179 value = zpool_prop_default_numeric(prop); 180 } 181 182 if (src) 183 *src = source; 184 185 return (value); 186 } 187 188 /* 189 * Map VDEV STATE to printed strings. 190 */ 191 const char * 192 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux) 193 { 194 switch (state) { 195 case VDEV_STATE_CLOSED: 196 case VDEV_STATE_OFFLINE: 197 return (gettext("OFFLINE")); 198 case VDEV_STATE_REMOVED: 199 return (gettext("REMOVED")); 200 case VDEV_STATE_CANT_OPEN: 201 if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG) 202 return (gettext("FAULTED")); 203 else if (aux == VDEV_AUX_SPLIT_POOL) 204 return (gettext("SPLIT")); 205 else 206 return (gettext("UNAVAIL")); 207 case VDEV_STATE_FAULTED: 208 return (gettext("FAULTED")); 209 case VDEV_STATE_DEGRADED: 210 return (gettext("DEGRADED")); 211 case VDEV_STATE_HEALTHY: 212 return (gettext("ONLINE")); 213 214 default: 215 break; 216 } 217 218 return (gettext("UNKNOWN")); 219 } 220 221 /* 222 * Map POOL STATE to printed strings. 223 */ 224 const char * 225 zpool_pool_state_to_name(pool_state_t state) 226 { 227 switch (state) { 228 default: 229 break; 230 case POOL_STATE_ACTIVE: 231 return (gettext("ACTIVE")); 232 case POOL_STATE_EXPORTED: 233 return (gettext("EXPORTED")); 234 case POOL_STATE_DESTROYED: 235 return (gettext("DESTROYED")); 236 case POOL_STATE_SPARE: 237 return (gettext("SPARE")); 238 case POOL_STATE_L2CACHE: 239 return (gettext("L2CACHE")); 240 case POOL_STATE_UNINITIALIZED: 241 return (gettext("UNINITIALIZED")); 242 case POOL_STATE_UNAVAIL: 243 return (gettext("UNAVAIL")); 244 case POOL_STATE_POTENTIALLY_ACTIVE: 245 return (gettext("POTENTIALLY_ACTIVE")); 246 } 247 248 return (gettext("UNKNOWN")); 249 } 250 251 /* 252 * Given a pool handle, return the pool health string ("ONLINE", "DEGRADED", 253 * "SUSPENDED", etc). 254 */ 255 const char * 256 zpool_get_state_str(zpool_handle_t *zhp) 257 { 258 zpool_errata_t errata; 259 zpool_status_t status; 260 const char *str; 261 262 status = zpool_get_status(zhp, NULL, &errata); 263 264 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 265 str = gettext("FAULTED"); 266 } else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT || 267 status == ZPOOL_STATUS_IO_FAILURE_CONTINUE || 268 status == ZPOOL_STATUS_IO_FAILURE_MMP) { 269 str = gettext("SUSPENDED"); 270 } else { 271 nvlist_t *nvroot = fnvlist_lookup_nvlist( 272 zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE); 273 uint_t vsc; 274 vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array( 275 nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc); 276 str = zpool_state_to_name(vs->vs_state, vs->vs_aux); 277 } 278 return (str); 279 } 280 281 /* 282 * Get a zpool property value for 'prop' and return the value in 283 * a pre-allocated buffer. 284 */ 285 int 286 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, 287 size_t len, zprop_source_t *srctype, boolean_t literal) 288 { 289 uint64_t intval; 290 const char *strval; 291 zprop_source_t src = ZPROP_SRC_NONE; 292 293 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 294 switch (prop) { 295 case ZPOOL_PROP_NAME: 296 (void) strlcpy(buf, zpool_get_name(zhp), len); 297 break; 298 299 case ZPOOL_PROP_HEALTH: 300 (void) strlcpy(buf, zpool_get_state_str(zhp), len); 301 break; 302 303 case ZPOOL_PROP_GUID: 304 intval = zpool_get_prop_int(zhp, prop, &src); 305 (void) snprintf(buf, len, "%llu", (u_longlong_t)intval); 306 break; 307 308 case ZPOOL_PROP_ALTROOT: 309 case ZPOOL_PROP_CACHEFILE: 310 case ZPOOL_PROP_COMMENT: 311 case ZPOOL_PROP_COMPATIBILITY: 312 if (zhp->zpool_props != NULL || 313 zpool_get_all_props(zhp) == 0) { 314 (void) strlcpy(buf, 315 zpool_get_prop_string(zhp, prop, &src), 316 len); 317 break; 318 } 319 zfs_fallthrough; 320 default: 321 (void) strlcpy(buf, "-", len); 322 break; 323 } 324 325 if (srctype != NULL) 326 *srctype = src; 327 return (0); 328 } 329 330 /* 331 * ZPOOL_PROP_DEDUPCACHED can be fetched by name only using 332 * the ZPOOL_GET_PROPS_NAMES mechanism 333 */ 334 if (prop == ZPOOL_PROP_DEDUPCACHED) { 335 zpool_add_propname(zhp, ZPOOL_DEDUPCACHED_PROP_NAME); 336 (void) zpool_props_refresh(zhp); 337 } 338 339 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) && 340 prop != ZPOOL_PROP_NAME) 341 return (-1); 342 343 switch (zpool_prop_get_type(prop)) { 344 case PROP_TYPE_STRING: 345 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src), 346 len); 347 break; 348 349 case PROP_TYPE_NUMBER: 350 intval = zpool_get_prop_int(zhp, prop, &src); 351 352 switch (prop) { 353 case ZPOOL_PROP_DEDUP_TABLE_QUOTA: 354 /* 355 * If dedup quota is 0, we translate this into 'none' 356 * (unless literal is set). And if it is UINT64_MAX 357 * we translate that as 'automatic' (limit to size of 358 * the dedicated dedup VDEV. Otherwise, fall throught 359 * into the regular number formating. 360 */ 361 if (intval == 0) { 362 (void) strlcpy(buf, literal ? "0" : "none", 363 len); 364 break; 365 } else if (intval == UINT64_MAX) { 366 (void) strlcpy(buf, "auto", len); 367 break; 368 } 369 zfs_fallthrough; 370 371 case ZPOOL_PROP_SIZE: 372 case ZPOOL_PROP_ALLOCATED: 373 case ZPOOL_PROP_FREE: 374 case ZPOOL_PROP_FREEING: 375 case ZPOOL_PROP_LEAKED: 376 case ZPOOL_PROP_ASHIFT: 377 case ZPOOL_PROP_MAXBLOCKSIZE: 378 case ZPOOL_PROP_MAXDNODESIZE: 379 case ZPOOL_PROP_BCLONESAVED: 380 case ZPOOL_PROP_BCLONEUSED: 381 case ZPOOL_PROP_DEDUP_TABLE_SIZE: 382 case ZPOOL_PROP_DEDUPCACHED: 383 if (literal) 384 (void) snprintf(buf, len, "%llu", 385 (u_longlong_t)intval); 386 else 387 (void) zfs_nicenum(intval, buf, len); 388 break; 389 390 case ZPOOL_PROP_EXPANDSZ: 391 case ZPOOL_PROP_CHECKPOINT: 392 if (intval == 0) { 393 (void) strlcpy(buf, "-", len); 394 } else if (literal) { 395 (void) snprintf(buf, len, "%llu", 396 (u_longlong_t)intval); 397 } else { 398 (void) zfs_nicebytes(intval, buf, len); 399 } 400 break; 401 402 case ZPOOL_PROP_CAPACITY: 403 if (literal) { 404 (void) snprintf(buf, len, "%llu", 405 (u_longlong_t)intval); 406 } else { 407 (void) snprintf(buf, len, "%llu%%", 408 (u_longlong_t)intval); 409 } 410 break; 411 412 case ZPOOL_PROP_FRAGMENTATION: 413 if (intval == UINT64_MAX) { 414 (void) strlcpy(buf, "-", len); 415 } else if (literal) { 416 (void) snprintf(buf, len, "%llu", 417 (u_longlong_t)intval); 418 } else { 419 (void) snprintf(buf, len, "%llu%%", 420 (u_longlong_t)intval); 421 } 422 break; 423 424 case ZPOOL_PROP_BCLONERATIO: 425 case ZPOOL_PROP_DEDUPRATIO: 426 if (literal) 427 (void) snprintf(buf, len, "%llu.%02llu", 428 (u_longlong_t)(intval / 100), 429 (u_longlong_t)(intval % 100)); 430 else 431 (void) snprintf(buf, len, "%llu.%02llux", 432 (u_longlong_t)(intval / 100), 433 (u_longlong_t)(intval % 100)); 434 break; 435 436 case ZPOOL_PROP_HEALTH: 437 (void) strlcpy(buf, zpool_get_state_str(zhp), len); 438 break; 439 case ZPOOL_PROP_VERSION: 440 if (intval >= SPA_VERSION_FEATURES) { 441 (void) snprintf(buf, len, "-"); 442 break; 443 } 444 zfs_fallthrough; 445 default: 446 (void) snprintf(buf, len, "%llu", (u_longlong_t)intval); 447 } 448 break; 449 450 case PROP_TYPE_INDEX: 451 intval = zpool_get_prop_int(zhp, prop, &src); 452 if (zpool_prop_index_to_string(prop, intval, &strval) 453 != 0) 454 return (-1); 455 (void) strlcpy(buf, strval, len); 456 break; 457 458 default: 459 abort(); 460 } 461 462 if (srctype) 463 *srctype = src; 464 465 return (0); 466 } 467 468 /* 469 * Get a zpool property value for 'propname' and return the value in 470 * a pre-allocated buffer. 471 */ 472 int 473 zpool_get_userprop(zpool_handle_t *zhp, const char *propname, char *buf, 474 size_t len, zprop_source_t *srctype) 475 { 476 nvlist_t *nv; 477 uint64_t ival; 478 const char *value; 479 zprop_source_t source = ZPROP_SRC_LOCAL; 480 481 if (zhp->zpool_props == NULL) 482 zpool_get_all_props(zhp); 483 484 if (nvlist_lookup_nvlist(zhp->zpool_props, propname, &nv) == 0) { 485 if (nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0) 486 source = ival; 487 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0); 488 } else { 489 source = ZPROP_SRC_DEFAULT; 490 value = "-"; 491 } 492 493 if (srctype) 494 *srctype = source; 495 496 (void) strlcpy(buf, value, len); 497 498 return (0); 499 } 500 501 /* 502 * Check if the bootfs name has the same pool name as it is set to. 503 * Assuming bootfs is a valid dataset name. 504 */ 505 static boolean_t 506 bootfs_name_valid(const char *pool, const char *bootfs) 507 { 508 int len = strlen(pool); 509 if (bootfs[0] == '\0') 510 return (B_TRUE); 511 512 if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT)) 513 return (B_FALSE); 514 515 if (strncmp(pool, bootfs, len) == 0 && 516 (bootfs[len] == '/' || bootfs[len] == '\0')) 517 return (B_TRUE); 518 519 return (B_FALSE); 520 } 521 522 /* 523 * Given an nvlist of zpool properties to be set, validate that they are 524 * correct, and parse any numeric properties (index, boolean, etc) if they are 525 * specified as strings. 526 */ 527 static nvlist_t * 528 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, 529 nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf) 530 { 531 nvpair_t *elem; 532 nvlist_t *retprops; 533 zpool_prop_t prop; 534 const char *strval; 535 uint64_t intval; 536 const char *check; 537 struct stat64 statbuf; 538 zpool_handle_t *zhp; 539 char *parent, *slash; 540 char report[1024]; 541 542 if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) { 543 (void) no_memory(hdl); 544 return (NULL); 545 } 546 547 elem = NULL; 548 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 549 const char *propname = nvpair_name(elem); 550 551 if (flags.vdevprop && zpool_prop_vdev(propname)) { 552 vdev_prop_t vprop = vdev_name_to_prop(propname); 553 554 if (vdev_prop_readonly(vprop)) { 555 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' " 556 "is readonly"), propname); 557 (void) zfs_error(hdl, EZFS_PROPREADONLY, 558 errbuf); 559 goto error; 560 } 561 562 if (zprop_parse_value(hdl, elem, vprop, ZFS_TYPE_VDEV, 563 retprops, &strval, &intval, errbuf) != 0) 564 goto error; 565 566 continue; 567 } else if (flags.vdevprop && vdev_prop_user(propname)) { 568 if (nvlist_add_nvpair(retprops, elem) != 0) { 569 (void) no_memory(hdl); 570 goto error; 571 } 572 continue; 573 } else if (flags.vdevprop) { 574 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 575 "invalid property: '%s'"), propname); 576 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 577 goto error; 578 } 579 580 prop = zpool_name_to_prop(propname); 581 if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) { 582 int err; 583 char *fname = strchr(propname, '@') + 1; 584 585 err = zfeature_lookup_name(fname, NULL); 586 if (err != 0) { 587 ASSERT3U(err, ==, ENOENT); 588 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 589 "feature '%s' unsupported by kernel"), 590 fname); 591 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 592 goto error; 593 } 594 595 if (nvpair_type(elem) != DATA_TYPE_STRING) { 596 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 597 "'%s' must be a string"), propname); 598 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 599 goto error; 600 } 601 602 (void) nvpair_value_string(elem, &strval); 603 if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0 && 604 strcmp(strval, ZFS_FEATURE_DISABLED) != 0) { 605 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 606 "property '%s' can only be set to " 607 "'enabled' or 'disabled'"), propname); 608 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 609 goto error; 610 } 611 612 if (!flags.create && 613 strcmp(strval, ZFS_FEATURE_DISABLED) == 0) { 614 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 615 "property '%s' can only be set to " 616 "'disabled' at creation time"), propname); 617 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 618 goto error; 619 } 620 621 if (nvlist_add_uint64(retprops, propname, 0) != 0) { 622 (void) no_memory(hdl); 623 goto error; 624 } 625 continue; 626 } else if (prop == ZPOOL_PROP_INVAL && 627 zfs_prop_user(propname)) { 628 /* 629 * This is a user property: make sure it's a 630 * string, and that it's less than ZAP_MAXNAMELEN. 631 */ 632 if (nvpair_type(elem) != DATA_TYPE_STRING) { 633 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 634 "'%s' must be a string"), propname); 635 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 636 goto error; 637 } 638 639 if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) { 640 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 641 "property name '%s' is too long"), 642 propname); 643 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 644 goto error; 645 } 646 647 (void) nvpair_value_string(elem, &strval); 648 649 if (strlen(strval) >= ZFS_MAXPROPLEN) { 650 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 651 "property value '%s' is too long"), 652 strval); 653 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 654 goto error; 655 } 656 657 if (nvlist_add_string(retprops, propname, 658 strval) != 0) { 659 (void) no_memory(hdl); 660 goto error; 661 } 662 663 continue; 664 } 665 666 /* 667 * Make sure this property is valid and applies to this type. 668 */ 669 if (prop == ZPOOL_PROP_INVAL) { 670 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 671 "invalid property '%s'"), propname); 672 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 673 goto error; 674 } 675 676 if (zpool_prop_readonly(prop)) { 677 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' " 678 "is readonly"), propname); 679 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 680 goto error; 681 } 682 683 if (!flags.create && zpool_prop_setonce(prop)) { 684 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 685 "property '%s' can only be set at " 686 "creation time"), propname); 687 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 688 goto error; 689 } 690 691 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops, 692 &strval, &intval, errbuf) != 0) 693 goto error; 694 695 /* 696 * Perform additional checking for specific properties. 697 */ 698 switch (prop) { 699 case ZPOOL_PROP_VERSION: 700 if (intval < version || 701 !SPA_VERSION_IS_SUPPORTED(intval)) { 702 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 703 "property '%s' number %llu is invalid."), 704 propname, (unsigned long long)intval); 705 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 706 goto error; 707 } 708 break; 709 710 case ZPOOL_PROP_ASHIFT: 711 if (intval != 0 && 712 (intval < ASHIFT_MIN || intval > ASHIFT_MAX)) { 713 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 714 "property '%s' number %llu is invalid, " 715 "only values between %" PRId32 " and %" 716 PRId32 " are allowed."), 717 propname, (unsigned long long)intval, 718 ASHIFT_MIN, ASHIFT_MAX); 719 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 720 goto error; 721 } 722 break; 723 724 case ZPOOL_PROP_BOOTFS: 725 if (flags.create || flags.import) { 726 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 727 "property '%s' cannot be set at creation " 728 "or import time"), propname); 729 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 730 goto error; 731 } 732 733 if (version < SPA_VERSION_BOOTFS) { 734 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 735 "pool must be upgraded to support " 736 "'%s' property"), propname); 737 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 738 goto error; 739 } 740 741 /* 742 * bootfs property value has to be a dataset name and 743 * the dataset has to be in the same pool as it sets to. 744 */ 745 if (!bootfs_name_valid(poolname, strval)) { 746 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' " 747 "is an invalid name"), strval); 748 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 749 goto error; 750 } 751 752 if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) { 753 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 754 "could not open pool '%s'"), poolname); 755 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf); 756 goto error; 757 } 758 zpool_close(zhp); 759 break; 760 761 case ZPOOL_PROP_ALTROOT: 762 if (!flags.create && !flags.import) { 763 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 764 "property '%s' can only be set during pool " 765 "creation or import"), propname); 766 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 767 goto error; 768 } 769 770 if (strval[0] != '/') { 771 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 772 "bad alternate root '%s'"), strval); 773 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 774 goto error; 775 } 776 break; 777 778 case ZPOOL_PROP_CACHEFILE: 779 if (strval[0] == '\0') 780 break; 781 782 if (strcmp(strval, "none") == 0) 783 break; 784 785 if (strval[0] != '/') { 786 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 787 "property '%s' must be empty, an " 788 "absolute path, or 'none'"), propname); 789 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 790 goto error; 791 } 792 793 parent = strdup(strval); 794 if (parent == NULL) { 795 (void) zfs_error(hdl, EZFS_NOMEM, errbuf); 796 goto error; 797 } 798 slash = strrchr(parent, '/'); 799 800 if (slash[1] == '\0' || strcmp(slash, "/.") == 0 || 801 strcmp(slash, "/..") == 0) { 802 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 803 "'%s' is not a valid file"), parent); 804 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 805 free(parent); 806 goto error; 807 } 808 809 *slash = '\0'; 810 811 if (parent[0] != '\0' && 812 (stat64(parent, &statbuf) != 0 || 813 !S_ISDIR(statbuf.st_mode))) { 814 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 815 "'%s' is not a valid directory"), 816 parent); 817 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 818 free(parent); 819 goto error; 820 } 821 free(parent); 822 823 break; 824 825 case ZPOOL_PROP_COMPATIBILITY: 826 switch (zpool_load_compat(strval, NULL, report, 1024)) { 827 case ZPOOL_COMPATIBILITY_OK: 828 case ZPOOL_COMPATIBILITY_WARNTOKEN: 829 break; 830 case ZPOOL_COMPATIBILITY_BADFILE: 831 case ZPOOL_COMPATIBILITY_BADTOKEN: 832 case ZPOOL_COMPATIBILITY_NOFILES: 833 zfs_error_aux(hdl, "%s", report); 834 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 835 goto error; 836 } 837 break; 838 839 case ZPOOL_PROP_COMMENT: 840 for (check = strval; *check != '\0'; check++) { 841 if (!isprint(*check)) { 842 zfs_error_aux(hdl, 843 dgettext(TEXT_DOMAIN, 844 "comment may only have printable " 845 "characters")); 846 (void) zfs_error(hdl, EZFS_BADPROP, 847 errbuf); 848 goto error; 849 } 850 } 851 if (strlen(strval) > ZPROP_MAX_COMMENT) { 852 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 853 "comment must not exceed %d characters"), 854 ZPROP_MAX_COMMENT); 855 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 856 goto error; 857 } 858 break; 859 case ZPOOL_PROP_READONLY: 860 if (!flags.import) { 861 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 862 "property '%s' can only be set at " 863 "import time"), propname); 864 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 865 goto error; 866 } 867 break; 868 case ZPOOL_PROP_MULTIHOST: 869 if (get_system_hostid() == 0) { 870 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 871 "requires a non-zero system hostid")); 872 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 873 goto error; 874 } 875 break; 876 case ZPOOL_PROP_DEDUPDITTO: 877 printf("Note: property '%s' no longer has " 878 "any effect\n", propname); 879 break; 880 881 default: 882 break; 883 } 884 } 885 886 return (retprops); 887 error: 888 nvlist_free(retprops); 889 return (NULL); 890 } 891 892 /* 893 * Set zpool property : propname=propval. 894 */ 895 int 896 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval) 897 { 898 zfs_cmd_t zc = {"\0"}; 899 int ret = -1; 900 char errbuf[ERRBUFLEN]; 901 nvlist_t *nvl = NULL; 902 nvlist_t *realprops; 903 uint64_t version; 904 prop_flags_t flags = { 0 }; 905 906 (void) snprintf(errbuf, sizeof (errbuf), 907 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), 908 zhp->zpool_name); 909 910 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 911 return (no_memory(zhp->zpool_hdl)); 912 913 if (nvlist_add_string(nvl, propname, propval) != 0) { 914 nvlist_free(nvl); 915 return (no_memory(zhp->zpool_hdl)); 916 } 917 918 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 919 if ((realprops = zpool_valid_proplist(zhp->zpool_hdl, 920 zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) { 921 nvlist_free(nvl); 922 return (-1); 923 } 924 925 nvlist_free(nvl); 926 nvl = realprops; 927 928 /* 929 * Execute the corresponding ioctl() to set this property. 930 */ 931 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 932 933 zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl); 934 935 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc); 936 937 zcmd_free_nvlists(&zc); 938 nvlist_free(nvl); 939 940 if (ret) 941 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf); 942 else 943 (void) zpool_props_refresh(zhp); 944 945 return (ret); 946 } 947 948 int 949 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp, 950 zfs_type_t type, boolean_t literal) 951 { 952 libzfs_handle_t *hdl = zhp->zpool_hdl; 953 zprop_list_t *entry; 954 char buf[ZFS_MAXPROPLEN]; 955 nvlist_t *features = NULL; 956 nvpair_t *nvp; 957 zprop_list_t **last; 958 boolean_t firstexpand = (NULL == *plp); 959 int i; 960 961 if (zprop_expand_list(hdl, plp, type) != 0) 962 return (-1); 963 964 if (type == ZFS_TYPE_VDEV) 965 return (0); 966 967 last = plp; 968 while (*last != NULL) 969 last = &(*last)->pl_next; 970 971 if ((*plp)->pl_all) 972 features = zpool_get_features(zhp); 973 974 if ((*plp)->pl_all && firstexpand) { 975 /* Handle userprops in the all properties case */ 976 if (zhp->zpool_props == NULL && zpool_props_refresh(zhp)) 977 return (-1); 978 979 nvp = NULL; 980 while ((nvp = nvlist_next_nvpair(zhp->zpool_props, nvp)) != 981 NULL) { 982 const char *propname = nvpair_name(nvp); 983 984 if (!zfs_prop_user(propname)) 985 continue; 986 987 entry = zfs_alloc(hdl, sizeof (zprop_list_t)); 988 entry->pl_prop = ZPROP_USERPROP; 989 entry->pl_user_prop = zfs_strdup(hdl, propname); 990 entry->pl_width = strlen(entry->pl_user_prop); 991 entry->pl_all = B_TRUE; 992 993 *last = entry; 994 last = &entry->pl_next; 995 } 996 997 for (i = 0; i < SPA_FEATURES; i++) { 998 entry = zfs_alloc(hdl, sizeof (zprop_list_t)); 999 entry->pl_prop = ZPROP_USERPROP; 1000 entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s", 1001 spa_feature_table[i].fi_uname); 1002 entry->pl_width = strlen(entry->pl_user_prop); 1003 entry->pl_all = B_TRUE; 1004 1005 *last = entry; 1006 last = &entry->pl_next; 1007 } 1008 } 1009 1010 /* add any unsupported features */ 1011 for (nvp = nvlist_next_nvpair(features, NULL); 1012 nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) { 1013 char *propname; 1014 boolean_t found; 1015 1016 if (zfeature_is_supported(nvpair_name(nvp))) 1017 continue; 1018 1019 propname = zfs_asprintf(hdl, "unsupported@%s", 1020 nvpair_name(nvp)); 1021 1022 /* 1023 * Before adding the property to the list make sure that no 1024 * other pool already added the same property. 1025 */ 1026 found = B_FALSE; 1027 entry = *plp; 1028 while (entry != NULL) { 1029 if (entry->pl_user_prop != NULL && 1030 strcmp(propname, entry->pl_user_prop) == 0) { 1031 found = B_TRUE; 1032 break; 1033 } 1034 entry = entry->pl_next; 1035 } 1036 if (found) { 1037 free(propname); 1038 continue; 1039 } 1040 1041 entry = zfs_alloc(hdl, sizeof (zprop_list_t)); 1042 entry->pl_prop = ZPROP_USERPROP; 1043 entry->pl_user_prop = propname; 1044 entry->pl_width = strlen(entry->pl_user_prop); 1045 entry->pl_all = B_TRUE; 1046 1047 *last = entry; 1048 last = &entry->pl_next; 1049 } 1050 1051 for (entry = *plp; entry != NULL; entry = entry->pl_next) { 1052 if (entry->pl_fixed && !literal) 1053 continue; 1054 1055 if (entry->pl_prop != ZPROP_USERPROP && 1056 zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf), 1057 NULL, literal) == 0) { 1058 if (strlen(buf) > entry->pl_width) 1059 entry->pl_width = strlen(buf); 1060 } else if (entry->pl_prop == ZPROP_INVAL && 1061 zfs_prop_user(entry->pl_user_prop) && 1062 zpool_get_userprop(zhp, entry->pl_user_prop, buf, 1063 sizeof (buf), NULL) == 0) { 1064 if (strlen(buf) > entry->pl_width) 1065 entry->pl_width = strlen(buf); 1066 } 1067 } 1068 1069 return (0); 1070 } 1071 1072 int 1073 vdev_expand_proplist(zpool_handle_t *zhp, const char *vdevname, 1074 zprop_list_t **plp) 1075 { 1076 zprop_list_t *entry; 1077 char buf[ZFS_MAXPROPLEN]; 1078 const char *strval = NULL; 1079 int err = 0; 1080 nvpair_t *elem = NULL; 1081 nvlist_t *vprops = NULL; 1082 nvlist_t *propval = NULL; 1083 const char *propname; 1084 vdev_prop_t prop; 1085 zprop_list_t **last; 1086 1087 for (entry = *plp; entry != NULL; entry = entry->pl_next) { 1088 if (entry->pl_fixed) 1089 continue; 1090 1091 if (zpool_get_vdev_prop(zhp, vdevname, entry->pl_prop, 1092 entry->pl_user_prop, buf, sizeof (buf), NULL, 1093 B_FALSE) == 0) { 1094 if (strlen(buf) > entry->pl_width) 1095 entry->pl_width = strlen(buf); 1096 } 1097 if (entry->pl_prop == VDEV_PROP_NAME && 1098 strlen(vdevname) > entry->pl_width) 1099 entry->pl_width = strlen(vdevname); 1100 } 1101 1102 /* Handle the all properties case */ 1103 last = plp; 1104 if (*last != NULL && (*last)->pl_all == B_TRUE) { 1105 while (*last != NULL) 1106 last = &(*last)->pl_next; 1107 1108 err = zpool_get_all_vdev_props(zhp, vdevname, &vprops); 1109 if (err != 0) 1110 return (err); 1111 1112 while ((elem = nvlist_next_nvpair(vprops, elem)) != NULL) { 1113 propname = nvpair_name(elem); 1114 1115 /* Skip properties that are not user defined */ 1116 if ((prop = vdev_name_to_prop(propname)) != 1117 VDEV_PROP_USERPROP) 1118 continue; 1119 1120 if (nvpair_value_nvlist(elem, &propval) != 0) 1121 continue; 1122 1123 strval = fnvlist_lookup_string(propval, ZPROP_VALUE); 1124 1125 entry = zfs_alloc(zhp->zpool_hdl, 1126 sizeof (zprop_list_t)); 1127 entry->pl_prop = prop; 1128 entry->pl_user_prop = zfs_strdup(zhp->zpool_hdl, 1129 propname); 1130 entry->pl_width = strlen(strval); 1131 entry->pl_all = B_TRUE; 1132 *last = entry; 1133 last = &entry->pl_next; 1134 } 1135 } 1136 1137 return (0); 1138 } 1139 1140 /* 1141 * Get the state for the given feature on the given ZFS pool. 1142 */ 1143 int 1144 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf, 1145 size_t len) 1146 { 1147 uint64_t refcount; 1148 boolean_t found = B_FALSE; 1149 nvlist_t *features = zpool_get_features(zhp); 1150 boolean_t supported; 1151 const char *feature = strchr(propname, '@') + 1; 1152 1153 supported = zpool_prop_feature(propname); 1154 ASSERT(supported || zpool_prop_unsupported(propname)); 1155 1156 /* 1157 * Convert from feature name to feature guid. This conversion is 1158 * unnecessary for unsupported@... properties because they already 1159 * use guids. 1160 */ 1161 if (supported) { 1162 int ret; 1163 spa_feature_t fid; 1164 1165 ret = zfeature_lookup_name(feature, &fid); 1166 if (ret != 0) { 1167 (void) strlcpy(buf, "-", len); 1168 return (ENOTSUP); 1169 } 1170 feature = spa_feature_table[fid].fi_guid; 1171 } 1172 1173 if (nvlist_lookup_uint64(features, feature, &refcount) == 0) 1174 found = B_TRUE; 1175 1176 if (supported) { 1177 if (!found) { 1178 (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len); 1179 } else { 1180 if (refcount == 0) 1181 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len); 1182 else 1183 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len); 1184 } 1185 } else { 1186 if (found) { 1187 if (refcount == 0) { 1188 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE); 1189 } else { 1190 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY); 1191 } 1192 } else { 1193 (void) strlcpy(buf, "-", len); 1194 return (ENOTSUP); 1195 } 1196 } 1197 1198 return (0); 1199 } 1200 1201 /* 1202 * Validate the given pool name, optionally putting an extended error message in 1203 * 'buf'. 1204 */ 1205 boolean_t 1206 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool) 1207 { 1208 namecheck_err_t why; 1209 char what; 1210 int ret; 1211 1212 ret = pool_namecheck(pool, &why, &what); 1213 1214 /* 1215 * The rules for reserved pool names were extended at a later point. 1216 * But we need to support users with existing pools that may now be 1217 * invalid. So we only check for this expanded set of names during a 1218 * create (or import), and only in userland. 1219 */ 1220 if (ret == 0 && !isopen && 1221 (strncmp(pool, "mirror", 6) == 0 || 1222 strncmp(pool, "raidz", 5) == 0 || 1223 strncmp(pool, "draid", 5) == 0 || 1224 strncmp(pool, "spare", 5) == 0 || 1225 strcmp(pool, "log") == 0)) { 1226 if (hdl != NULL) 1227 zfs_error_aux(hdl, 1228 dgettext(TEXT_DOMAIN, "name is reserved")); 1229 return (B_FALSE); 1230 } 1231 1232 1233 if (ret != 0) { 1234 if (hdl != NULL) { 1235 switch (why) { 1236 case NAME_ERR_TOOLONG: 1237 zfs_error_aux(hdl, 1238 dgettext(TEXT_DOMAIN, "name is too long")); 1239 break; 1240 1241 case NAME_ERR_INVALCHAR: 1242 zfs_error_aux(hdl, 1243 dgettext(TEXT_DOMAIN, "invalid character " 1244 "'%c' in pool name"), what); 1245 break; 1246 1247 case NAME_ERR_NOLETTER: 1248 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1249 "name must begin with a letter")); 1250 break; 1251 1252 case NAME_ERR_RESERVED: 1253 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1254 "name is reserved")); 1255 break; 1256 1257 case NAME_ERR_DISKLIKE: 1258 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1259 "pool name is reserved")); 1260 break; 1261 1262 case NAME_ERR_LEADING_SLASH: 1263 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1264 "leading slash in name")); 1265 break; 1266 1267 case NAME_ERR_EMPTY_COMPONENT: 1268 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1269 "empty component in name")); 1270 break; 1271 1272 case NAME_ERR_TRAILING_SLASH: 1273 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1274 "trailing slash in name")); 1275 break; 1276 1277 case NAME_ERR_MULTIPLE_DELIMITERS: 1278 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1279 "multiple '@' and/or '#' delimiters in " 1280 "name")); 1281 break; 1282 1283 case NAME_ERR_NO_AT: 1284 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1285 "permission set is missing '@'")); 1286 break; 1287 1288 default: 1289 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1290 "(%d) not defined"), why); 1291 break; 1292 } 1293 } 1294 return (B_FALSE); 1295 } 1296 1297 return (B_TRUE); 1298 } 1299 1300 /* 1301 * Open a handle to the given pool, even if the pool is currently in the FAULTED 1302 * state. 1303 */ 1304 zpool_handle_t * 1305 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool) 1306 { 1307 zpool_handle_t *zhp; 1308 boolean_t missing; 1309 1310 /* 1311 * Make sure the pool name is valid. 1312 */ 1313 if (!zpool_name_valid(hdl, B_TRUE, pool)) { 1314 (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME, 1315 dgettext(TEXT_DOMAIN, "cannot open '%s'"), 1316 pool); 1317 return (NULL); 1318 } 1319 1320 zhp = zfs_alloc(hdl, sizeof (zpool_handle_t)); 1321 1322 zhp->zpool_hdl = hdl; 1323 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 1324 1325 if (zpool_refresh_stats(zhp, &missing) != 0) { 1326 zpool_close(zhp); 1327 return (NULL); 1328 } 1329 1330 if (missing) { 1331 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool")); 1332 (void) zfs_error_fmt(hdl, EZFS_NOENT, 1333 dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool); 1334 zpool_close(zhp); 1335 return (NULL); 1336 } 1337 1338 return (zhp); 1339 } 1340 1341 /* 1342 * Like the above, but silent on error. Used when iterating over pools (because 1343 * the configuration cache may be out of date). 1344 */ 1345 int 1346 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret) 1347 { 1348 zpool_handle_t *zhp; 1349 boolean_t missing; 1350 1351 zhp = zfs_alloc(hdl, sizeof (zpool_handle_t)); 1352 1353 zhp->zpool_hdl = hdl; 1354 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 1355 1356 if (zpool_refresh_stats(zhp, &missing) != 0) { 1357 zpool_close(zhp); 1358 return (-1); 1359 } 1360 1361 if (missing) { 1362 zpool_close(zhp); 1363 *ret = NULL; 1364 return (0); 1365 } 1366 1367 *ret = zhp; 1368 return (0); 1369 } 1370 1371 /* 1372 * Similar to zpool_open_canfail(), but refuses to open pools in the faulted 1373 * state. 1374 */ 1375 zpool_handle_t * 1376 zpool_open(libzfs_handle_t *hdl, const char *pool) 1377 { 1378 zpool_handle_t *zhp; 1379 1380 if ((zhp = zpool_open_canfail(hdl, pool)) == NULL) 1381 return (NULL); 1382 1383 if (zhp->zpool_state == POOL_STATE_UNAVAIL) { 1384 (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL, 1385 dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name); 1386 zpool_close(zhp); 1387 return (NULL); 1388 } 1389 1390 return (zhp); 1391 } 1392 1393 /* 1394 * Close the handle. Simply frees the memory associated with the handle. 1395 */ 1396 void 1397 zpool_close(zpool_handle_t *zhp) 1398 { 1399 nvlist_free(zhp->zpool_config); 1400 nvlist_free(zhp->zpool_old_config); 1401 nvlist_free(zhp->zpool_props); 1402 free(zhp); 1403 } 1404 1405 /* 1406 * Return the name of the pool. 1407 */ 1408 const char * 1409 zpool_get_name(zpool_handle_t *zhp) 1410 { 1411 return (zhp->zpool_name); 1412 } 1413 1414 1415 /* 1416 * Return the state of the pool (ACTIVE or UNAVAILABLE) 1417 */ 1418 int 1419 zpool_get_state(zpool_handle_t *zhp) 1420 { 1421 return (zhp->zpool_state); 1422 } 1423 1424 /* 1425 * Check if vdev list contains a special vdev 1426 */ 1427 static boolean_t 1428 zpool_has_special_vdev(nvlist_t *nvroot) 1429 { 1430 nvlist_t **child; 1431 uint_t children; 1432 1433 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child, 1434 &children) == 0) { 1435 for (uint_t c = 0; c < children; c++) { 1436 const char *bias; 1437 1438 if (nvlist_lookup_string(child[c], 1439 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 && 1440 strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) { 1441 return (B_TRUE); 1442 } 1443 } 1444 } 1445 return (B_FALSE); 1446 } 1447 1448 /* 1449 * Check if vdev list contains a dRAID vdev 1450 */ 1451 static boolean_t 1452 zpool_has_draid_vdev(nvlist_t *nvroot) 1453 { 1454 nvlist_t **child; 1455 uint_t children; 1456 1457 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 1458 &child, &children) == 0) { 1459 for (uint_t c = 0; c < children; c++) { 1460 const char *type; 1461 1462 if (nvlist_lookup_string(child[c], 1463 ZPOOL_CONFIG_TYPE, &type) == 0 && 1464 strcmp(type, VDEV_TYPE_DRAID) == 0) { 1465 return (B_TRUE); 1466 } 1467 } 1468 } 1469 return (B_FALSE); 1470 } 1471 1472 /* 1473 * Output a dRAID top-level vdev name in to the provided buffer. 1474 */ 1475 static char * 1476 zpool_draid_name(char *name, int len, uint64_t data, uint64_t parity, 1477 uint64_t spares, uint64_t children) 1478 { 1479 snprintf(name, len, "%s%llu:%llud:%lluc:%llus", 1480 VDEV_TYPE_DRAID, (u_longlong_t)parity, (u_longlong_t)data, 1481 (u_longlong_t)children, (u_longlong_t)spares); 1482 1483 return (name); 1484 } 1485 1486 /* 1487 * Return B_TRUE if the provided name is a dRAID spare name. 1488 */ 1489 boolean_t 1490 zpool_is_draid_spare(const char *name) 1491 { 1492 uint64_t spare_id, parity, vdev_id; 1493 1494 if (sscanf(name, VDEV_TYPE_DRAID "%llu-%llu-%llu", 1495 (u_longlong_t *)&parity, (u_longlong_t *)&vdev_id, 1496 (u_longlong_t *)&spare_id) == 3) { 1497 return (B_TRUE); 1498 } 1499 1500 return (B_FALSE); 1501 } 1502 1503 /* 1504 * Create the named pool, using the provided vdev list. It is assumed 1505 * that the consumer has already validated the contents of the nvlist, so we 1506 * don't have to worry about error semantics. 1507 */ 1508 int 1509 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, 1510 nvlist_t *props, nvlist_t *fsprops) 1511 { 1512 zfs_cmd_t zc = {"\0"}; 1513 nvlist_t *zc_fsprops = NULL; 1514 nvlist_t *zc_props = NULL; 1515 nvlist_t *hidden_args = NULL; 1516 uint8_t *wkeydata = NULL; 1517 uint_t wkeylen = 0; 1518 char errbuf[ERRBUFLEN]; 1519 int ret = -1; 1520 1521 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1522 "cannot create '%s'"), pool); 1523 1524 if (!zpool_name_valid(hdl, B_FALSE, pool)) 1525 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 1526 1527 zcmd_write_conf_nvlist(hdl, &zc, nvroot); 1528 1529 if (props) { 1530 prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE }; 1531 1532 if ((zc_props = zpool_valid_proplist(hdl, pool, props, 1533 SPA_VERSION_1, flags, errbuf)) == NULL) { 1534 goto create_failed; 1535 } 1536 } 1537 1538 if (fsprops) { 1539 uint64_t zoned; 1540 const char *zonestr; 1541 1542 zoned = ((nvlist_lookup_string(fsprops, 1543 zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) && 1544 strcmp(zonestr, "on") == 0); 1545 1546 if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM, 1547 fsprops, zoned, NULL, NULL, B_TRUE, errbuf)) == NULL) { 1548 goto create_failed; 1549 } 1550 1551 if (nvlist_exists(zc_fsprops, 1552 zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) && 1553 !zpool_has_special_vdev(nvroot)) { 1554 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1555 "%s property requires a special vdev"), 1556 zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)); 1557 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1558 goto create_failed; 1559 } 1560 1561 if (!zc_props && 1562 (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) { 1563 goto create_failed; 1564 } 1565 if (zfs_crypto_create(hdl, NULL, zc_fsprops, props, B_TRUE, 1566 &wkeydata, &wkeylen) != 0) { 1567 zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf); 1568 goto create_failed; 1569 } 1570 if (nvlist_add_nvlist(zc_props, 1571 ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) { 1572 goto create_failed; 1573 } 1574 if (wkeydata != NULL) { 1575 if (nvlist_alloc(&hidden_args, NV_UNIQUE_NAME, 0) != 0) 1576 goto create_failed; 1577 1578 if (nvlist_add_uint8_array(hidden_args, "wkeydata", 1579 wkeydata, wkeylen) != 0) 1580 goto create_failed; 1581 1582 if (nvlist_add_nvlist(zc_props, ZPOOL_HIDDEN_ARGS, 1583 hidden_args) != 0) 1584 goto create_failed; 1585 } 1586 } 1587 1588 if (zc_props) 1589 zcmd_write_src_nvlist(hdl, &zc, zc_props); 1590 1591 (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); 1592 1593 if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) { 1594 1595 zcmd_free_nvlists(&zc); 1596 nvlist_free(zc_props); 1597 nvlist_free(zc_fsprops); 1598 nvlist_free(hidden_args); 1599 if (wkeydata != NULL) 1600 free(wkeydata); 1601 1602 switch (errno) { 1603 case EBUSY: 1604 /* 1605 * This can happen if the user has specified the same 1606 * device multiple times. We can't reliably detect this 1607 * until we try to add it and see we already have a 1608 * label. This can also happen under if the device is 1609 * part of an active md or lvm device. 1610 */ 1611 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1612 "one or more vdevs refer to the same device, or " 1613 "one of\nthe devices is part of an active md or " 1614 "lvm device")); 1615 return (zfs_error(hdl, EZFS_BADDEV, errbuf)); 1616 1617 case ERANGE: 1618 /* 1619 * This happens if the record size is smaller or larger 1620 * than the allowed size range, or not a power of 2. 1621 * 1622 * NOTE: although zfs_valid_proplist is called earlier, 1623 * this case may have slipped through since the 1624 * pool does not exist yet and it is therefore 1625 * impossible to read properties e.g. max blocksize 1626 * from the pool. 1627 */ 1628 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1629 "record size invalid")); 1630 return (zfs_error(hdl, EZFS_BADPROP, errbuf)); 1631 1632 case EOVERFLOW: 1633 /* 1634 * This occurs when one of the devices is below 1635 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 1636 * device was the problem device since there's no 1637 * reliable way to determine device size from userland. 1638 */ 1639 { 1640 char buf[64]; 1641 1642 zfs_nicebytes(SPA_MINDEVSIZE, buf, 1643 sizeof (buf)); 1644 1645 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1646 "one or more devices is less than the " 1647 "minimum size (%s)"), buf); 1648 } 1649 return (zfs_error(hdl, EZFS_BADDEV, errbuf)); 1650 1651 case ENOSPC: 1652 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1653 "one or more devices is out of space")); 1654 return (zfs_error(hdl, EZFS_BADDEV, errbuf)); 1655 1656 case EINVAL: 1657 if (zpool_has_draid_vdev(nvroot) && 1658 zfeature_lookup_name("draid", NULL) != 0) { 1659 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1660 "dRAID vdevs are unsupported by the " 1661 "kernel")); 1662 return (zfs_error(hdl, EZFS_BADDEV, errbuf)); 1663 } else { 1664 return (zpool_standard_error(hdl, errno, 1665 errbuf)); 1666 } 1667 1668 default: 1669 return (zpool_standard_error(hdl, errno, errbuf)); 1670 } 1671 } 1672 1673 create_failed: 1674 zcmd_free_nvlists(&zc); 1675 nvlist_free(zc_props); 1676 nvlist_free(zc_fsprops); 1677 nvlist_free(hidden_args); 1678 if (wkeydata != NULL) 1679 free(wkeydata); 1680 return (ret); 1681 } 1682 1683 /* 1684 * Destroy the given pool. It is up to the caller to ensure that there are no 1685 * datasets left in the pool. 1686 */ 1687 int 1688 zpool_destroy(zpool_handle_t *zhp, const char *log_str) 1689 { 1690 zfs_cmd_t zc = {"\0"}; 1691 zfs_handle_t *zfp = NULL; 1692 libzfs_handle_t *hdl = zhp->zpool_hdl; 1693 char errbuf[ERRBUFLEN]; 1694 1695 if (zhp->zpool_state == POOL_STATE_ACTIVE && 1696 (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL) 1697 return (-1); 1698 1699 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1700 zc.zc_history = (uint64_t)(uintptr_t)log_str; 1701 1702 if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) { 1703 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1704 "cannot destroy '%s'"), zhp->zpool_name); 1705 1706 if (errno == EROFS) { 1707 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1708 "one or more devices is read only")); 1709 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 1710 } else { 1711 (void) zpool_standard_error(hdl, errno, errbuf); 1712 } 1713 1714 if (zfp) 1715 zfs_close(zfp); 1716 return (-1); 1717 } 1718 1719 if (zfp) { 1720 remove_mountpoint(zfp); 1721 zfs_close(zfp); 1722 } 1723 1724 return (0); 1725 } 1726 1727 /* 1728 * Create a checkpoint in the given pool. 1729 */ 1730 int 1731 zpool_checkpoint(zpool_handle_t *zhp) 1732 { 1733 libzfs_handle_t *hdl = zhp->zpool_hdl; 1734 char errbuf[ERRBUFLEN]; 1735 int error; 1736 1737 error = lzc_pool_checkpoint(zhp->zpool_name); 1738 if (error != 0) { 1739 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1740 "cannot checkpoint '%s'"), zhp->zpool_name); 1741 (void) zpool_standard_error(hdl, error, errbuf); 1742 return (-1); 1743 } 1744 1745 return (0); 1746 } 1747 1748 /* 1749 * Discard the checkpoint from the given pool. 1750 */ 1751 int 1752 zpool_discard_checkpoint(zpool_handle_t *zhp) 1753 { 1754 libzfs_handle_t *hdl = zhp->zpool_hdl; 1755 char errbuf[ERRBUFLEN]; 1756 int error; 1757 1758 error = lzc_pool_checkpoint_discard(zhp->zpool_name); 1759 if (error != 0) { 1760 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1761 "cannot discard checkpoint in '%s'"), zhp->zpool_name); 1762 (void) zpool_standard_error(hdl, error, errbuf); 1763 return (-1); 1764 } 1765 1766 return (0); 1767 } 1768 1769 /* 1770 * Load data type for the given pool. 1771 */ 1772 int 1773 zpool_prefetch(zpool_handle_t *zhp, zpool_prefetch_type_t type) 1774 { 1775 libzfs_handle_t *hdl = zhp->zpool_hdl; 1776 char msg[1024]; 1777 int error; 1778 1779 error = lzc_pool_prefetch(zhp->zpool_name, type); 1780 if (error != 0) { 1781 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1782 "cannot prefetch %s in '%s'"), 1783 type == ZPOOL_PREFETCH_DDT ? "ddt" : "", zhp->zpool_name); 1784 (void) zpool_standard_error(hdl, error, msg); 1785 return (-1); 1786 } 1787 1788 return (0); 1789 } 1790 1791 /* 1792 * Add the given vdevs to the pool. The caller must have already performed the 1793 * necessary verification to ensure that the vdev specification is well-formed. 1794 */ 1795 int 1796 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot, boolean_t check_ashift) 1797 { 1798 zfs_cmd_t zc = {"\0"}; 1799 int ret; 1800 libzfs_handle_t *hdl = zhp->zpool_hdl; 1801 char errbuf[ERRBUFLEN]; 1802 nvlist_t **spares, **l2cache; 1803 uint_t nspares, nl2cache; 1804 1805 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1806 "cannot add to '%s'"), zhp->zpool_name); 1807 1808 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) < 1809 SPA_VERSION_SPARES && 1810 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 1811 &spares, &nspares) == 0) { 1812 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be " 1813 "upgraded to add hot spares")); 1814 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 1815 } 1816 1817 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) < 1818 SPA_VERSION_L2CACHE && 1819 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 1820 &l2cache, &nl2cache) == 0) { 1821 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be " 1822 "upgraded to add cache devices")); 1823 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 1824 } 1825 1826 zcmd_write_conf_nvlist(hdl, &zc, nvroot); 1827 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1828 zc.zc_flags = check_ashift; 1829 1830 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) { 1831 switch (errno) { 1832 case EBUSY: 1833 /* 1834 * This can happen if the user has specified the same 1835 * device multiple times. We can't reliably detect this 1836 * until we try to add it and see we already have a 1837 * label. 1838 */ 1839 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1840 "one or more vdevs refer to the same device")); 1841 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 1842 break; 1843 1844 case EINVAL: 1845 1846 if (zpool_has_draid_vdev(nvroot) && 1847 zfeature_lookup_name("draid", NULL) != 0) { 1848 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1849 "dRAID vdevs are unsupported by the " 1850 "kernel")); 1851 } else { 1852 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1853 "invalid config; a pool with removing/" 1854 "removed vdevs does not support adding " 1855 "raidz or dRAID vdevs")); 1856 } 1857 1858 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 1859 break; 1860 1861 case EOVERFLOW: 1862 /* 1863 * This occurs when one of the devices is below 1864 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 1865 * device was the problem device since there's no 1866 * reliable way to determine device size from userland. 1867 */ 1868 { 1869 char buf[64]; 1870 1871 zfs_nicebytes(SPA_MINDEVSIZE, buf, 1872 sizeof (buf)); 1873 1874 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1875 "device is less than the minimum " 1876 "size (%s)"), buf); 1877 } 1878 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 1879 break; 1880 1881 case ENOTSUP: 1882 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1883 "pool must be upgraded to add these vdevs")); 1884 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 1885 break; 1886 1887 default: 1888 (void) zpool_standard_error(hdl, errno, errbuf); 1889 } 1890 1891 ret = -1; 1892 } else { 1893 ret = 0; 1894 } 1895 1896 zcmd_free_nvlists(&zc); 1897 1898 return (ret); 1899 } 1900 1901 /* 1902 * Exports the pool from the system. The caller must ensure that there are no 1903 * mounted datasets in the pool. 1904 */ 1905 static int 1906 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce, 1907 const char *log_str) 1908 { 1909 zfs_cmd_t zc = {"\0"}; 1910 1911 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1912 zc.zc_cookie = force; 1913 zc.zc_guid = hardforce; 1914 zc.zc_history = (uint64_t)(uintptr_t)log_str; 1915 1916 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) { 1917 switch (errno) { 1918 case EXDEV: 1919 zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, 1920 "use '-f' to override the following errors:\n" 1921 "'%s' has an active shared spare which could be" 1922 " used by other pools once '%s' is exported."), 1923 zhp->zpool_name, zhp->zpool_name); 1924 return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE, 1925 dgettext(TEXT_DOMAIN, "cannot export '%s'"), 1926 zhp->zpool_name)); 1927 default: 1928 return (zpool_standard_error_fmt(zhp->zpool_hdl, errno, 1929 dgettext(TEXT_DOMAIN, "cannot export '%s'"), 1930 zhp->zpool_name)); 1931 } 1932 } 1933 1934 return (0); 1935 } 1936 1937 int 1938 zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str) 1939 { 1940 return (zpool_export_common(zhp, force, B_FALSE, log_str)); 1941 } 1942 1943 int 1944 zpool_export_force(zpool_handle_t *zhp, const char *log_str) 1945 { 1946 return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str)); 1947 } 1948 1949 static void 1950 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun, 1951 nvlist_t *config) 1952 { 1953 nvlist_t *nv = NULL; 1954 uint64_t rewindto; 1955 int64_t loss = -1; 1956 struct tm t; 1957 char timestr[128]; 1958 1959 if (!hdl->libzfs_printerr || config == NULL) 1960 return; 1961 1962 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 || 1963 nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) { 1964 return; 1965 } 1966 1967 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0) 1968 return; 1969 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss); 1970 1971 if (localtime_r((time_t *)&rewindto, &t) != NULL && 1972 ctime_r((time_t *)&rewindto, timestr) != NULL) { 1973 timestr[24] = 0; 1974 if (dryrun) { 1975 (void) printf(dgettext(TEXT_DOMAIN, 1976 "Would be able to return %s " 1977 "to its state as of %s.\n"), 1978 name, timestr); 1979 } else { 1980 (void) printf(dgettext(TEXT_DOMAIN, 1981 "Pool %s returned to its state as of %s.\n"), 1982 name, timestr); 1983 } 1984 if (loss > 120) { 1985 (void) printf(dgettext(TEXT_DOMAIN, 1986 "%s approximately %lld "), 1987 dryrun ? "Would discard" : "Discarded", 1988 ((longlong_t)loss + 30) / 60); 1989 (void) printf(dgettext(TEXT_DOMAIN, 1990 "minutes of transactions.\n")); 1991 } else if (loss > 0) { 1992 (void) printf(dgettext(TEXT_DOMAIN, 1993 "%s approximately %lld "), 1994 dryrun ? "Would discard" : "Discarded", 1995 (longlong_t)loss); 1996 (void) printf(dgettext(TEXT_DOMAIN, 1997 "seconds of transactions.\n")); 1998 } 1999 } 2000 } 2001 2002 void 2003 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason, 2004 nvlist_t *config, char *buf, size_t size) 2005 { 2006 nvlist_t *nv = NULL; 2007 int64_t loss = -1; 2008 uint64_t edata = UINT64_MAX; 2009 uint64_t rewindto; 2010 struct tm t; 2011 char timestr[128], temp[1024]; 2012 2013 if (!hdl->libzfs_printerr) 2014 return; 2015 2016 /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */ 2017 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 || 2018 nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 || 2019 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0) 2020 goto no_info; 2021 2022 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss); 2023 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS, 2024 &edata); 2025 2026 (void) snprintf(buf, size, dgettext(TEXT_DOMAIN, 2027 "Recovery is possible, but will result in some data loss.\n")); 2028 2029 if (localtime_r((time_t *)&rewindto, &t) != NULL && 2030 ctime_r((time_t *)&rewindto, timestr) != NULL) { 2031 timestr[24] = 0; 2032 (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN, 2033 "\tReturning the pool to its state as of %s\n" 2034 "\tshould correct the problem. "), timestr); 2035 (void) strlcat(buf, temp, size); 2036 } else { 2037 (void) strlcat(buf, dgettext(TEXT_DOMAIN, 2038 "\tReverting the pool to an earlier state " 2039 "should correct the problem.\n\t"), size); 2040 } 2041 2042 if (loss > 120) { 2043 (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN, 2044 "Approximately %lld minutes of data\n" 2045 "\tmust be discarded, irreversibly. "), 2046 ((longlong_t)loss + 30) / 60); 2047 (void) strlcat(buf, temp, size); 2048 } else if (loss > 0) { 2049 (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN, 2050 "Approximately %lld seconds of data\n" 2051 "\tmust be discarded, irreversibly. "), 2052 (longlong_t)loss); 2053 (void) strlcat(buf, temp, size); 2054 } 2055 if (edata != 0 && edata != UINT64_MAX) { 2056 if (edata == 1) { 2057 (void) strlcat(buf, dgettext(TEXT_DOMAIN, 2058 "After rewind, at least\n" 2059 "\tone persistent user-data error will remain. "), 2060 size); 2061 } else { 2062 (void) strlcat(buf, dgettext(TEXT_DOMAIN, 2063 "After rewind, several\n" 2064 "\tpersistent user-data errors will remain. "), 2065 size); 2066 } 2067 } 2068 (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN, 2069 "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "), 2070 reason >= 0 ? "clear" : "import", name); 2071 (void) strlcat(buf, temp, size); 2072 2073 (void) strlcat(buf, dgettext(TEXT_DOMAIN, 2074 "A scrub of the pool\n" 2075 "\tis strongly recommended after recovery.\n"), size); 2076 return; 2077 2078 no_info: 2079 (void) strlcat(buf, dgettext(TEXT_DOMAIN, 2080 "Destroy and re-create the pool from\n\ta backup source.\n"), size); 2081 } 2082 2083 /* 2084 * zpool_import() is a contracted interface. Should be kept the same 2085 * if possible. 2086 * 2087 * Applications should use zpool_import_props() to import a pool with 2088 * new properties value to be set. 2089 */ 2090 int 2091 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, 2092 char *altroot) 2093 { 2094 nvlist_t *props = NULL; 2095 int ret; 2096 2097 if (altroot != NULL) { 2098 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { 2099 return (zfs_error_fmt(hdl, EZFS_NOMEM, 2100 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 2101 newname)); 2102 } 2103 2104 if (nvlist_add_string(props, 2105 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 || 2106 nvlist_add_string(props, 2107 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) { 2108 nvlist_free(props); 2109 return (zfs_error_fmt(hdl, EZFS_NOMEM, 2110 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 2111 newname)); 2112 } 2113 } 2114 2115 ret = zpool_import_props(hdl, config, newname, props, 2116 ZFS_IMPORT_NORMAL); 2117 nvlist_free(props); 2118 return (ret); 2119 } 2120 2121 static void 2122 print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv, 2123 int indent) 2124 { 2125 nvlist_t **child; 2126 uint_t c, children; 2127 char *vname; 2128 uint64_t is_log = 0; 2129 2130 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, 2131 &is_log); 2132 2133 if (name != NULL) 2134 (void) printf("\t%*s%s%s\n", indent, "", name, 2135 is_log ? " [log]" : ""); 2136 2137 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2138 &child, &children) != 0) 2139 return; 2140 2141 for (c = 0; c < children; c++) { 2142 vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID); 2143 print_vdev_tree(hdl, vname, child[c], indent + 2); 2144 free(vname); 2145 } 2146 } 2147 2148 void 2149 zpool_collect_unsup_feat(nvlist_t *config, char *buf, size_t size) 2150 { 2151 nvlist_t *nvinfo, *unsup_feat; 2152 char temp[512]; 2153 2154 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 2155 unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT); 2156 2157 for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); 2158 nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) { 2159 const char *desc = fnvpair_value_string(nvp); 2160 if (strlen(desc) > 0) { 2161 (void) snprintf(temp, 512, "\t%s (%s)\n", 2162 nvpair_name(nvp), desc); 2163 (void) strlcat(buf, temp, size); 2164 } else { 2165 (void) snprintf(temp, 512, "\t%s\n", nvpair_name(nvp)); 2166 (void) strlcat(buf, temp, size); 2167 } 2168 } 2169 } 2170 2171 /* 2172 * Import the given pool using the known configuration and a list of 2173 * properties to be set. The configuration should have come from 2174 * zpool_find_import(). The 'newname' parameters control whether the pool 2175 * is imported with a different name. 2176 */ 2177 int 2178 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, 2179 nvlist_t *props, int flags) 2180 { 2181 zfs_cmd_t zc = {"\0"}; 2182 zpool_load_policy_t policy; 2183 nvlist_t *nv = NULL; 2184 nvlist_t *nvinfo = NULL; 2185 nvlist_t *missing = NULL; 2186 const char *thename; 2187 const char *origname; 2188 int ret; 2189 int error = 0; 2190 char buf[2048]; 2191 char errbuf[ERRBUFLEN]; 2192 2193 origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); 2194 2195 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2196 "cannot import pool '%s'"), origname); 2197 2198 if (newname != NULL) { 2199 if (!zpool_name_valid(hdl, B_FALSE, newname)) 2200 return (zfs_error_fmt(hdl, EZFS_INVALIDNAME, 2201 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 2202 newname)); 2203 thename = newname; 2204 } else { 2205 thename = origname; 2206 } 2207 2208 if (props != NULL) { 2209 uint64_t version; 2210 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE }; 2211 2212 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION); 2213 2214 if ((props = zpool_valid_proplist(hdl, origname, 2215 props, version, flags, errbuf)) == NULL) 2216 return (-1); 2217 zcmd_write_src_nvlist(hdl, &zc, props); 2218 nvlist_free(props); 2219 } 2220 2221 (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); 2222 2223 zc.zc_guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID); 2224 2225 zcmd_write_conf_nvlist(hdl, &zc, config); 2226 zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2); 2227 2228 zc.zc_cookie = flags; 2229 while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 && 2230 errno == ENOMEM) 2231 zcmd_expand_dst_nvlist(hdl, &zc); 2232 if (ret != 0) 2233 error = errno; 2234 2235 (void) zcmd_read_dst_nvlist(hdl, &zc, &nv); 2236 2237 zcmd_free_nvlists(&zc); 2238 2239 zpool_get_load_policy(config, &policy); 2240 2241 if (error) { 2242 char desc[1024]; 2243 char aux[256]; 2244 2245 /* 2246 * Dry-run failed, but we print out what success 2247 * looks like if we found a best txg 2248 */ 2249 if (policy.zlp_rewind & ZPOOL_TRY_REWIND) { 2250 zpool_rewind_exclaim(hdl, newname ? origname : thename, 2251 B_TRUE, nv); 2252 nvlist_free(nv); 2253 return (-1); 2254 } 2255 2256 if (newname == NULL) 2257 (void) snprintf(desc, sizeof (desc), 2258 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 2259 thename); 2260 else 2261 (void) snprintf(desc, sizeof (desc), 2262 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), 2263 origname, thename); 2264 2265 switch (error) { 2266 case ENOTSUP: 2267 if (nv != NULL && nvlist_lookup_nvlist(nv, 2268 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 && 2269 nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) { 2270 (void) printf(dgettext(TEXT_DOMAIN, "This " 2271 "pool uses the following feature(s) not " 2272 "supported by this system:\n")); 2273 memset(buf, 0, 2048); 2274 zpool_collect_unsup_feat(nv, buf, 2048); 2275 (void) printf("%s", buf); 2276 if (nvlist_exists(nvinfo, 2277 ZPOOL_CONFIG_CAN_RDONLY)) { 2278 (void) printf(dgettext(TEXT_DOMAIN, 2279 "All unsupported features are only " 2280 "required for writing to the pool." 2281 "\nThe pool can be imported using " 2282 "'-o readonly=on'.\n")); 2283 } 2284 } 2285 /* 2286 * Unsupported version. 2287 */ 2288 (void) zfs_error(hdl, EZFS_BADVERSION, desc); 2289 break; 2290 2291 case EREMOTEIO: 2292 if (nv != NULL && nvlist_lookup_nvlist(nv, 2293 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0) { 2294 const char *hostname = "<unknown>"; 2295 uint64_t hostid = 0; 2296 mmp_state_t mmp_state; 2297 2298 mmp_state = fnvlist_lookup_uint64(nvinfo, 2299 ZPOOL_CONFIG_MMP_STATE); 2300 2301 if (nvlist_exists(nvinfo, 2302 ZPOOL_CONFIG_MMP_HOSTNAME)) 2303 hostname = fnvlist_lookup_string(nvinfo, 2304 ZPOOL_CONFIG_MMP_HOSTNAME); 2305 2306 if (nvlist_exists(nvinfo, 2307 ZPOOL_CONFIG_MMP_HOSTID)) 2308 hostid = fnvlist_lookup_uint64(nvinfo, 2309 ZPOOL_CONFIG_MMP_HOSTID); 2310 2311 if (mmp_state == MMP_STATE_ACTIVE) { 2312 (void) snprintf(aux, sizeof (aux), 2313 dgettext(TEXT_DOMAIN, "pool is imp" 2314 "orted on host '%s' (hostid=%lx).\n" 2315 "Export the pool on the other " 2316 "system, then run 'zpool import'."), 2317 hostname, (unsigned long) hostid); 2318 } else if (mmp_state == MMP_STATE_NO_HOSTID) { 2319 (void) snprintf(aux, sizeof (aux), 2320 dgettext(TEXT_DOMAIN, "pool has " 2321 "the multihost property on and " 2322 "the\nsystem's hostid is not set. " 2323 "Set a unique system hostid with " 2324 "the zgenhostid(8) command.\n")); 2325 } 2326 2327 (void) zfs_error_aux(hdl, "%s", aux); 2328 } 2329 (void) zfs_error(hdl, EZFS_ACTIVE_POOL, desc); 2330 break; 2331 2332 case EINVAL: 2333 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc); 2334 break; 2335 2336 case EROFS: 2337 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2338 "one or more devices is read only")); 2339 (void) zfs_error(hdl, EZFS_BADDEV, desc); 2340 break; 2341 2342 case ENXIO: 2343 if (nv && nvlist_lookup_nvlist(nv, 2344 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 && 2345 nvlist_lookup_nvlist(nvinfo, 2346 ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) { 2347 (void) printf(dgettext(TEXT_DOMAIN, 2348 "The devices below are missing or " 2349 "corrupted, use '-m' to import the pool " 2350 "anyway:\n")); 2351 print_vdev_tree(hdl, NULL, missing, 2); 2352 (void) printf("\n"); 2353 } 2354 (void) zpool_standard_error(hdl, error, desc); 2355 break; 2356 2357 case EEXIST: 2358 (void) zpool_standard_error(hdl, error, desc); 2359 break; 2360 2361 case EBUSY: 2362 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2363 "one or more devices are already in use\n")); 2364 (void) zfs_error(hdl, EZFS_BADDEV, desc); 2365 break; 2366 case ENAMETOOLONG: 2367 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2368 "new name of at least one dataset is longer than " 2369 "the maximum allowable length")); 2370 (void) zfs_error(hdl, EZFS_NAMETOOLONG, desc); 2371 break; 2372 default: 2373 (void) zpool_standard_error(hdl, error, desc); 2374 memset(buf, 0, 2048); 2375 zpool_explain_recover(hdl, 2376 newname ? origname : thename, -error, nv, 2377 buf, 2048); 2378 (void) printf("\t%s", buf); 2379 break; 2380 } 2381 2382 nvlist_free(nv); 2383 ret = -1; 2384 } else { 2385 zpool_handle_t *zhp; 2386 2387 /* 2388 * This should never fail, but play it safe anyway. 2389 */ 2390 if (zpool_open_silent(hdl, thename, &zhp) != 0) 2391 ret = -1; 2392 else if (zhp != NULL) 2393 zpool_close(zhp); 2394 if (policy.zlp_rewind & 2395 (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) { 2396 zpool_rewind_exclaim(hdl, newname ? origname : thename, 2397 ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv); 2398 } 2399 nvlist_free(nv); 2400 } 2401 2402 return (ret); 2403 } 2404 2405 /* 2406 * Translate vdev names to guids. If a vdev_path is determined to be 2407 * unsuitable then a vd_errlist is allocated and the vdev path and errno 2408 * are added to it. 2409 */ 2410 static int 2411 zpool_translate_vdev_guids(zpool_handle_t *zhp, nvlist_t *vds, 2412 nvlist_t *vdev_guids, nvlist_t *guids_to_paths, nvlist_t **vd_errlist) 2413 { 2414 nvlist_t *errlist = NULL; 2415 int error = 0; 2416 2417 for (nvpair_t *elem = nvlist_next_nvpair(vds, NULL); elem != NULL; 2418 elem = nvlist_next_nvpair(vds, elem)) { 2419 boolean_t spare, cache; 2420 2421 const char *vd_path = nvpair_name(elem); 2422 nvlist_t *tgt = zpool_find_vdev(zhp, vd_path, &spare, &cache, 2423 NULL); 2424 2425 if ((tgt == NULL) || cache || spare) { 2426 if (errlist == NULL) { 2427 errlist = fnvlist_alloc(); 2428 error = EINVAL; 2429 } 2430 2431 uint64_t err = (tgt == NULL) ? EZFS_NODEVICE : 2432 (spare ? EZFS_ISSPARE : EZFS_ISL2CACHE); 2433 fnvlist_add_int64(errlist, vd_path, err); 2434 continue; 2435 } 2436 2437 uint64_t guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 2438 fnvlist_add_uint64(vdev_guids, vd_path, guid); 2439 2440 char msg[MAXNAMELEN]; 2441 (void) snprintf(msg, sizeof (msg), "%llu", (u_longlong_t)guid); 2442 fnvlist_add_string(guids_to_paths, msg, vd_path); 2443 } 2444 2445 if (error != 0) { 2446 verify(errlist != NULL); 2447 if (vd_errlist != NULL) 2448 *vd_errlist = errlist; 2449 else 2450 fnvlist_free(errlist); 2451 } 2452 2453 return (error); 2454 } 2455 2456 static int 2457 xlate_init_err(int err) 2458 { 2459 switch (err) { 2460 case ENODEV: 2461 return (EZFS_NODEVICE); 2462 case EINVAL: 2463 case EROFS: 2464 return (EZFS_BADDEV); 2465 case EBUSY: 2466 return (EZFS_INITIALIZING); 2467 case ESRCH: 2468 return (EZFS_NO_INITIALIZE); 2469 } 2470 return (err); 2471 } 2472 2473 /* 2474 * Begin, suspend, cancel, or uninit (clear) the initialization (initializing 2475 * of all free blocks) for the given vdevs in the given pool. 2476 */ 2477 static int 2478 zpool_initialize_impl(zpool_handle_t *zhp, pool_initialize_func_t cmd_type, 2479 nvlist_t *vds, boolean_t wait) 2480 { 2481 int err; 2482 2483 nvlist_t *vdev_guids = fnvlist_alloc(); 2484 nvlist_t *guids_to_paths = fnvlist_alloc(); 2485 nvlist_t *vd_errlist = NULL; 2486 nvlist_t *errlist; 2487 nvpair_t *elem; 2488 2489 err = zpool_translate_vdev_guids(zhp, vds, vdev_guids, 2490 guids_to_paths, &vd_errlist); 2491 2492 if (err != 0) { 2493 verify(vd_errlist != NULL); 2494 goto list_errors; 2495 } 2496 2497 err = lzc_initialize(zhp->zpool_name, cmd_type, 2498 vdev_guids, &errlist); 2499 2500 if (err != 0) { 2501 if (errlist != NULL && nvlist_lookup_nvlist(errlist, 2502 ZPOOL_INITIALIZE_VDEVS, &vd_errlist) == 0) { 2503 goto list_errors; 2504 } 2505 2506 if (err == EINVAL && cmd_type == POOL_INITIALIZE_UNINIT) { 2507 zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, 2508 "uninitialize is not supported by kernel")); 2509 } 2510 2511 (void) zpool_standard_error(zhp->zpool_hdl, err, 2512 dgettext(TEXT_DOMAIN, "operation failed")); 2513 goto out; 2514 } 2515 2516 if (wait) { 2517 for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL; 2518 elem = nvlist_next_nvpair(vdev_guids, elem)) { 2519 2520 uint64_t guid = fnvpair_value_uint64(elem); 2521 2522 err = lzc_wait_tag(zhp->zpool_name, 2523 ZPOOL_WAIT_INITIALIZE, guid, NULL); 2524 if (err != 0) { 2525 (void) zpool_standard_error_fmt(zhp->zpool_hdl, 2526 err, dgettext(TEXT_DOMAIN, "error " 2527 "waiting for '%s' to initialize"), 2528 nvpair_name(elem)); 2529 2530 goto out; 2531 } 2532 } 2533 } 2534 goto out; 2535 2536 list_errors: 2537 for (elem = nvlist_next_nvpair(vd_errlist, NULL); elem != NULL; 2538 elem = nvlist_next_nvpair(vd_errlist, elem)) { 2539 int64_t vd_error = xlate_init_err(fnvpair_value_int64(elem)); 2540 const char *path; 2541 2542 if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem), 2543 &path) != 0) 2544 path = nvpair_name(elem); 2545 2546 (void) zfs_error_fmt(zhp->zpool_hdl, vd_error, 2547 "cannot initialize '%s'", path); 2548 } 2549 2550 out: 2551 fnvlist_free(vdev_guids); 2552 fnvlist_free(guids_to_paths); 2553 2554 if (vd_errlist != NULL) 2555 fnvlist_free(vd_errlist); 2556 2557 return (err == 0 ? 0 : -1); 2558 } 2559 2560 int 2561 zpool_initialize(zpool_handle_t *zhp, pool_initialize_func_t cmd_type, 2562 nvlist_t *vds) 2563 { 2564 return (zpool_initialize_impl(zhp, cmd_type, vds, B_FALSE)); 2565 } 2566 2567 int 2568 zpool_initialize_wait(zpool_handle_t *zhp, pool_initialize_func_t cmd_type, 2569 nvlist_t *vds) 2570 { 2571 return (zpool_initialize_impl(zhp, cmd_type, vds, B_TRUE)); 2572 } 2573 2574 static int 2575 xlate_trim_err(int err) 2576 { 2577 switch (err) { 2578 case ENODEV: 2579 return (EZFS_NODEVICE); 2580 case EINVAL: 2581 case EROFS: 2582 return (EZFS_BADDEV); 2583 case EBUSY: 2584 return (EZFS_TRIMMING); 2585 case ESRCH: 2586 return (EZFS_NO_TRIM); 2587 case EOPNOTSUPP: 2588 return (EZFS_TRIM_NOTSUP); 2589 } 2590 return (err); 2591 } 2592 2593 static int 2594 zpool_trim_wait(zpool_handle_t *zhp, nvlist_t *vdev_guids) 2595 { 2596 int err; 2597 nvpair_t *elem; 2598 2599 for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL; 2600 elem = nvlist_next_nvpair(vdev_guids, elem)) { 2601 2602 uint64_t guid = fnvpair_value_uint64(elem); 2603 2604 err = lzc_wait_tag(zhp->zpool_name, 2605 ZPOOL_WAIT_TRIM, guid, NULL); 2606 if (err != 0) { 2607 (void) zpool_standard_error_fmt(zhp->zpool_hdl, 2608 err, dgettext(TEXT_DOMAIN, "error " 2609 "waiting to trim '%s'"), nvpair_name(elem)); 2610 2611 return (err); 2612 } 2613 } 2614 return (0); 2615 } 2616 2617 /* 2618 * Check errlist and report any errors, omitting ones which should be 2619 * suppressed. Returns B_TRUE if any errors were reported. 2620 */ 2621 static boolean_t 2622 check_trim_errs(zpool_handle_t *zhp, trimflags_t *trim_flags, 2623 nvlist_t *guids_to_paths, nvlist_t *vds, nvlist_t *errlist) 2624 { 2625 nvpair_t *elem; 2626 boolean_t reported_errs = B_FALSE; 2627 int num_vds = 0; 2628 int num_suppressed_errs = 0; 2629 2630 for (elem = nvlist_next_nvpair(vds, NULL); 2631 elem != NULL; elem = nvlist_next_nvpair(vds, elem)) { 2632 num_vds++; 2633 } 2634 2635 for (elem = nvlist_next_nvpair(errlist, NULL); 2636 elem != NULL; elem = nvlist_next_nvpair(errlist, elem)) { 2637 int64_t vd_error = xlate_trim_err(fnvpair_value_int64(elem)); 2638 const char *path; 2639 2640 /* 2641 * If only the pool was specified, and it was not a secure 2642 * trim then suppress warnings for individual vdevs which 2643 * do not support trimming. 2644 */ 2645 if (vd_error == EZFS_TRIM_NOTSUP && 2646 trim_flags->fullpool && 2647 !trim_flags->secure) { 2648 num_suppressed_errs++; 2649 continue; 2650 } 2651 2652 reported_errs = B_TRUE; 2653 if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem), 2654 &path) != 0) 2655 path = nvpair_name(elem); 2656 2657 (void) zfs_error_fmt(zhp->zpool_hdl, vd_error, 2658 "cannot trim '%s'", path); 2659 } 2660 2661 if (num_suppressed_errs == num_vds) { 2662 (void) zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, 2663 "no devices in pool support trim operations")); 2664 (void) (zfs_error(zhp->zpool_hdl, EZFS_TRIM_NOTSUP, 2665 dgettext(TEXT_DOMAIN, "cannot trim"))); 2666 reported_errs = B_TRUE; 2667 } 2668 2669 return (reported_errs); 2670 } 2671 2672 /* 2673 * Begin, suspend, or cancel the TRIM (discarding of all free blocks) for 2674 * the given vdevs in the given pool. 2675 */ 2676 int 2677 zpool_trim(zpool_handle_t *zhp, pool_trim_func_t cmd_type, nvlist_t *vds, 2678 trimflags_t *trim_flags) 2679 { 2680 int err; 2681 int retval = 0; 2682 2683 nvlist_t *vdev_guids = fnvlist_alloc(); 2684 nvlist_t *guids_to_paths = fnvlist_alloc(); 2685 nvlist_t *errlist = NULL; 2686 2687 err = zpool_translate_vdev_guids(zhp, vds, vdev_guids, 2688 guids_to_paths, &errlist); 2689 if (err != 0) { 2690 check_trim_errs(zhp, trim_flags, guids_to_paths, vds, errlist); 2691 retval = -1; 2692 goto out; 2693 } 2694 2695 err = lzc_trim(zhp->zpool_name, cmd_type, trim_flags->rate, 2696 trim_flags->secure, vdev_guids, &errlist); 2697 if (err != 0) { 2698 nvlist_t *vd_errlist; 2699 if (errlist != NULL && nvlist_lookup_nvlist(errlist, 2700 ZPOOL_TRIM_VDEVS, &vd_errlist) == 0) { 2701 if (check_trim_errs(zhp, trim_flags, guids_to_paths, 2702 vds, vd_errlist)) { 2703 retval = -1; 2704 goto out; 2705 } 2706 } else { 2707 char errbuf[ERRBUFLEN]; 2708 2709 (void) snprintf(errbuf, sizeof (errbuf), 2710 dgettext(TEXT_DOMAIN, "operation failed")); 2711 zpool_standard_error(zhp->zpool_hdl, err, errbuf); 2712 retval = -1; 2713 goto out; 2714 } 2715 } 2716 2717 2718 if (trim_flags->wait) 2719 retval = zpool_trim_wait(zhp, vdev_guids); 2720 2721 out: 2722 if (errlist != NULL) 2723 fnvlist_free(errlist); 2724 fnvlist_free(vdev_guids); 2725 fnvlist_free(guids_to_paths); 2726 return (retval); 2727 } 2728 2729 /* 2730 * Scan the pool. 2731 */ 2732 int 2733 zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd) 2734 { 2735 char errbuf[ERRBUFLEN]; 2736 int err; 2737 libzfs_handle_t *hdl = zhp->zpool_hdl; 2738 2739 nvlist_t *args = fnvlist_alloc(); 2740 fnvlist_add_uint64(args, "scan_type", (uint64_t)func); 2741 fnvlist_add_uint64(args, "scan_command", (uint64_t)cmd); 2742 2743 err = lzc_scrub(ZFS_IOC_POOL_SCRUB, zhp->zpool_name, args, NULL); 2744 fnvlist_free(args); 2745 2746 if (err == 0) { 2747 return (0); 2748 } else if (err == ZFS_ERR_IOC_CMD_UNAVAIL) { 2749 zfs_cmd_t zc = {"\0"}; 2750 (void) strlcpy(zc.zc_name, zhp->zpool_name, 2751 sizeof (zc.zc_name)); 2752 zc.zc_cookie = func; 2753 zc.zc_flags = cmd; 2754 2755 if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0) 2756 return (0); 2757 } 2758 2759 /* 2760 * An ECANCELED on a scrub means one of the following: 2761 * 1. we resumed a paused scrub. 2762 * 2. we resumed a paused error scrub. 2763 * 3. Error scrub is not run because of no error log. 2764 * 2765 * Note that we no longer return ECANCELED in case 1 or 2. However, in 2766 * order to prevent problems where we have a newer userland than 2767 * kernel, we keep this check in place. That prevents erroneous 2768 * failures when an older kernel returns ECANCELED in those cases. 2769 */ 2770 if (err == ECANCELED && (func == POOL_SCAN_SCRUB || 2771 func == POOL_SCAN_ERRORSCRUB) && cmd == POOL_SCRUB_NORMAL) 2772 return (0); 2773 /* 2774 * The following cases have been handled here: 2775 * 1. Paused a scrub/error scrub if there is none in progress. 2776 */ 2777 if (err == ENOENT && func != POOL_SCAN_NONE && cmd == 2778 POOL_SCRUB_PAUSE) { 2779 return (0); 2780 } 2781 2782 ASSERT3U(func, >=, POOL_SCAN_NONE); 2783 ASSERT3U(func, <, POOL_SCAN_FUNCS); 2784 2785 if (func == POOL_SCAN_SCRUB || func == POOL_SCAN_ERRORSCRUB) { 2786 if (cmd == POOL_SCRUB_PAUSE) { 2787 (void) snprintf(errbuf, sizeof (errbuf), 2788 dgettext(TEXT_DOMAIN, "cannot pause scrubbing %s"), 2789 zhp->zpool_name); 2790 } else { 2791 assert(cmd == POOL_SCRUB_NORMAL); 2792 (void) snprintf(errbuf, sizeof (errbuf), 2793 dgettext(TEXT_DOMAIN, "cannot scrub %s"), 2794 zhp->zpool_name); 2795 } 2796 } else if (func == POOL_SCAN_RESILVER) { 2797 assert(cmd == POOL_SCRUB_NORMAL); 2798 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2799 "cannot restart resilver on %s"), zhp->zpool_name); 2800 } else if (func == POOL_SCAN_NONE) { 2801 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2802 "cannot cancel scrubbing %s"), zhp->zpool_name); 2803 } else { 2804 assert(!"unexpected result"); 2805 } 2806 2807 /* 2808 * With EBUSY, six cases are possible: 2809 * 2810 * Current state Requested 2811 * 1. Normal Scrub Running Normal Scrub or Error Scrub 2812 * 2. Normal Scrub Paused Error Scrub 2813 * 3. Normal Scrub Paused Pause Normal Scrub 2814 * 4. Error Scrub Running Normal Scrub or Error Scrub 2815 * 5. Error Scrub Paused Pause Error Scrub 2816 * 6. Resilvering Anything else 2817 */ 2818 if (err == EBUSY) { 2819 nvlist_t *nvroot; 2820 pool_scan_stat_t *ps = NULL; 2821 uint_t psc; 2822 2823 nvroot = fnvlist_lookup_nvlist(zhp->zpool_config, 2824 ZPOOL_CONFIG_VDEV_TREE); 2825 (void) nvlist_lookup_uint64_array(nvroot, 2826 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc); 2827 if (ps && ps->pss_func == POOL_SCAN_SCRUB && 2828 ps->pss_state == DSS_SCANNING) { 2829 if (ps->pss_pass_scrub_pause == 0) { 2830 /* handles case 1 */ 2831 assert(cmd == POOL_SCRUB_NORMAL); 2832 return (zfs_error(hdl, EZFS_SCRUBBING, 2833 errbuf)); 2834 } else { 2835 if (func == POOL_SCAN_ERRORSCRUB) { 2836 /* handles case 2 */ 2837 ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL); 2838 return (zfs_error(hdl, 2839 EZFS_SCRUB_PAUSED_TO_CANCEL, 2840 errbuf)); 2841 } else { 2842 /* handles case 3 */ 2843 ASSERT3U(func, ==, POOL_SCAN_SCRUB); 2844 ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE); 2845 return (zfs_error(hdl, 2846 EZFS_SCRUB_PAUSED, errbuf)); 2847 } 2848 } 2849 } else if (ps && 2850 ps->pss_error_scrub_func == POOL_SCAN_ERRORSCRUB && 2851 ps->pss_error_scrub_state == DSS_ERRORSCRUBBING) { 2852 if (ps->pss_pass_error_scrub_pause == 0) { 2853 /* handles case 4 */ 2854 ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL); 2855 return (zfs_error(hdl, EZFS_ERRORSCRUBBING, 2856 errbuf)); 2857 } else { 2858 /* handles case 5 */ 2859 ASSERT3U(func, ==, POOL_SCAN_ERRORSCRUB); 2860 ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE); 2861 return (zfs_error(hdl, EZFS_ERRORSCRUB_PAUSED, 2862 errbuf)); 2863 } 2864 } else { 2865 /* handles case 6 */ 2866 return (zfs_error(hdl, EZFS_RESILVERING, errbuf)); 2867 } 2868 } else if (err == ENOENT) { 2869 return (zfs_error(hdl, EZFS_NO_SCRUB, errbuf)); 2870 } else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) { 2871 return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, errbuf)); 2872 } else { 2873 return (zpool_standard_error(hdl, err, errbuf)); 2874 } 2875 } 2876 2877 /* 2878 * Find a vdev that matches the search criteria specified. We use the 2879 * the nvpair name to determine how we should look for the device. 2880 * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL 2881 * spare; but FALSE if its an INUSE spare. 2882 * 2883 * If 'return_parent' is set, then return the *parent* of the vdev you're 2884 * searching for rather than the vdev itself. 2885 */ 2886 static nvlist_t * 2887 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, 2888 boolean_t *l2cache, boolean_t *log, boolean_t return_parent) 2889 { 2890 uint_t c, children; 2891 nvlist_t **child; 2892 nvlist_t *ret; 2893 uint64_t is_log; 2894 const char *srchkey; 2895 nvpair_t *pair = nvlist_next_nvpair(search, NULL); 2896 const char *tmp = NULL; 2897 boolean_t is_root; 2898 2899 /* Nothing to look for */ 2900 if (search == NULL || pair == NULL) 2901 return (NULL); 2902 2903 /* Obtain the key we will use to search */ 2904 srchkey = nvpair_name(pair); 2905 2906 nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &tmp); 2907 if (strcmp(tmp, "root") == 0) 2908 is_root = B_TRUE; 2909 else 2910 is_root = B_FALSE; 2911 2912 switch (nvpair_type(pair)) { 2913 case DATA_TYPE_UINT64: 2914 if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) { 2915 uint64_t srchval = fnvpair_value_uint64(pair); 2916 uint64_t theguid = fnvlist_lookup_uint64(nv, 2917 ZPOOL_CONFIG_GUID); 2918 if (theguid == srchval) 2919 return (nv); 2920 } 2921 break; 2922 2923 case DATA_TYPE_STRING: { 2924 const char *srchval, *val; 2925 2926 srchval = fnvpair_value_string(pair); 2927 if (nvlist_lookup_string(nv, srchkey, &val) != 0) 2928 break; 2929 2930 /* 2931 * Search for the requested value. Special cases: 2932 * 2933 * - ZPOOL_CONFIG_PATH for whole disk entries. These end in 2934 * "-part1", or "p1". The suffix is hidden from the user, 2935 * but included in the string, so this matches around it. 2936 * - ZPOOL_CONFIG_PATH for short names zfs_strcmp_shortname() 2937 * is used to check all possible expanded paths. 2938 * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE). 2939 * 2940 * Otherwise, all other searches are simple string compares. 2941 */ 2942 if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0) { 2943 uint64_t wholedisk = 0; 2944 2945 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 2946 &wholedisk); 2947 if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0) 2948 return (nv); 2949 2950 } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0) { 2951 char *type, *idx, *end, *p; 2952 uint64_t id, vdev_id; 2953 2954 /* 2955 * Determine our vdev type, keeping in mind 2956 * that the srchval is composed of a type and 2957 * vdev id pair (i.e. mirror-4). 2958 */ 2959 if ((type = strdup(srchval)) == NULL) 2960 return (NULL); 2961 2962 if ((p = strrchr(type, '-')) == NULL) { 2963 free(type); 2964 break; 2965 } 2966 idx = p + 1; 2967 *p = '\0'; 2968 2969 /* 2970 * draid names are presented like: draid2:4d:6c:0s 2971 * We match them up to the first ':' so we can still 2972 * do the parity check below, but the other params 2973 * are ignored. 2974 */ 2975 if ((p = strchr(type, ':')) != NULL) { 2976 if (strncmp(type, VDEV_TYPE_DRAID, 2977 strlen(VDEV_TYPE_DRAID)) == 0) 2978 *p = '\0'; 2979 } 2980 2981 /* 2982 * If the types don't match then keep looking. 2983 */ 2984 if (strncmp(val, type, strlen(val)) != 0) { 2985 free(type); 2986 break; 2987 } 2988 2989 verify(zpool_vdev_is_interior(type)); 2990 2991 id = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID); 2992 errno = 0; 2993 vdev_id = strtoull(idx, &end, 10); 2994 2995 /* 2996 * If we are looking for a raidz and a parity is 2997 * specified, make sure it matches. 2998 */ 2999 int rzlen = strlen(VDEV_TYPE_RAIDZ); 3000 assert(rzlen == strlen(VDEV_TYPE_DRAID)); 3001 int typlen = strlen(type); 3002 if ((strncmp(type, VDEV_TYPE_RAIDZ, rzlen) == 0 || 3003 strncmp(type, VDEV_TYPE_DRAID, rzlen) == 0) && 3004 typlen != rzlen) { 3005 uint64_t vdev_parity; 3006 int parity = *(type + rzlen) - '0'; 3007 3008 if (parity <= 0 || parity > 3 || 3009 (typlen - rzlen) != 1) { 3010 /* 3011 * Nonsense parity specified, can 3012 * never match 3013 */ 3014 free(type); 3015 return (NULL); 3016 } 3017 vdev_parity = fnvlist_lookup_uint64(nv, 3018 ZPOOL_CONFIG_NPARITY); 3019 if ((int)vdev_parity != parity) { 3020 free(type); 3021 break; 3022 } 3023 } 3024 3025 free(type); 3026 if (errno != 0) 3027 return (NULL); 3028 3029 /* 3030 * Now verify that we have the correct vdev id. 3031 */ 3032 if (vdev_id == id) 3033 return (nv); 3034 } 3035 3036 /* 3037 * Common case 3038 */ 3039 if (strcmp(srchval, val) == 0) 3040 return (nv); 3041 break; 3042 } 3043 3044 default: 3045 break; 3046 } 3047 3048 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 3049 &child, &children) != 0) 3050 return (NULL); 3051 3052 for (c = 0; c < children; c++) { 3053 if ((ret = vdev_to_nvlist_iter(child[c], search, 3054 avail_spare, l2cache, NULL, return_parent)) != NULL) { 3055 /* 3056 * The 'is_log' value is only set for the toplevel 3057 * vdev, not the leaf vdevs. So we always lookup the 3058 * log device from the root of the vdev tree (where 3059 * 'log' is non-NULL). 3060 */ 3061 if (log != NULL && 3062 nvlist_lookup_uint64(child[c], 3063 ZPOOL_CONFIG_IS_LOG, &is_log) == 0 && 3064 is_log) { 3065 *log = B_TRUE; 3066 } 3067 return (ret && return_parent && !is_root ? nv : ret); 3068 } 3069 } 3070 3071 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 3072 &child, &children) == 0) { 3073 for (c = 0; c < children; c++) { 3074 if ((ret = vdev_to_nvlist_iter(child[c], search, 3075 avail_spare, l2cache, NULL, return_parent)) 3076 != NULL) { 3077 *avail_spare = B_TRUE; 3078 return (ret && return_parent && 3079 !is_root ? nv : ret); 3080 } 3081 } 3082 } 3083 3084 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 3085 &child, &children) == 0) { 3086 for (c = 0; c < children; c++) { 3087 if ((ret = vdev_to_nvlist_iter(child[c], search, 3088 avail_spare, l2cache, NULL, return_parent)) 3089 != NULL) { 3090 *l2cache = B_TRUE; 3091 return (ret && return_parent && 3092 !is_root ? nv : ret); 3093 } 3094 } 3095 } 3096 3097 return (NULL); 3098 } 3099 3100 /* 3101 * Given a physical path or guid, find the associated vdev. 3102 */ 3103 nvlist_t * 3104 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath, 3105 boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log) 3106 { 3107 nvlist_t *search, *nvroot, *ret; 3108 uint64_t guid; 3109 char *end; 3110 3111 search = fnvlist_alloc(); 3112 3113 guid = strtoull(ppath, &end, 0); 3114 if (guid != 0 && *end == '\0') { 3115 fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid); 3116 } else { 3117 fnvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath); 3118 } 3119 3120 nvroot = fnvlist_lookup_nvlist(zhp->zpool_config, 3121 ZPOOL_CONFIG_VDEV_TREE); 3122 3123 *avail_spare = B_FALSE; 3124 *l2cache = B_FALSE; 3125 if (log != NULL) 3126 *log = B_FALSE; 3127 ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log, 3128 B_FALSE); 3129 fnvlist_free(search); 3130 3131 return (ret); 3132 } 3133 3134 /* 3135 * Determine if we have an "interior" top-level vdev (i.e mirror/raidz). 3136 */ 3137 static boolean_t 3138 zpool_vdev_is_interior(const char *name) 3139 { 3140 if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 || 3141 strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 || 3142 strncmp(name, 3143 VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 || 3144 strncmp(name, VDEV_TYPE_ROOT, strlen(VDEV_TYPE_ROOT)) == 0 || 3145 strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0) 3146 return (B_TRUE); 3147 3148 if (strncmp(name, VDEV_TYPE_DRAID, strlen(VDEV_TYPE_DRAID)) == 0 && 3149 !zpool_is_draid_spare(name)) 3150 return (B_TRUE); 3151 3152 return (B_FALSE); 3153 } 3154 3155 /* 3156 * Lookup the nvlist for a given vdev or vdev's parent (depending on 3157 * if 'return_parent' is set). 3158 */ 3159 static nvlist_t * 3160 __zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, 3161 boolean_t *l2cache, boolean_t *log, boolean_t return_parent) 3162 { 3163 char *end; 3164 nvlist_t *nvroot, *search, *ret; 3165 uint64_t guid; 3166 boolean_t __avail_spare, __l2cache, __log; 3167 3168 search = fnvlist_alloc(); 3169 3170 guid = strtoull(path, &end, 0); 3171 if (guid != 0 && *end == '\0') { 3172 fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid); 3173 } else if (zpool_vdev_is_interior(path)) { 3174 fnvlist_add_string(search, ZPOOL_CONFIG_TYPE, path); 3175 } else { 3176 fnvlist_add_string(search, ZPOOL_CONFIG_PATH, path); 3177 } 3178 3179 nvroot = fnvlist_lookup_nvlist(zhp->zpool_config, 3180 ZPOOL_CONFIG_VDEV_TREE); 3181 3182 /* 3183 * User can pass NULL for avail_spare, l2cache, and log, but 3184 * we still need to provide variables to vdev_to_nvlist_iter(), so 3185 * just point them to junk variables here. 3186 */ 3187 if (!avail_spare) 3188 avail_spare = &__avail_spare; 3189 if (!l2cache) 3190 l2cache = &__l2cache; 3191 if (!log) 3192 log = &__log; 3193 3194 *avail_spare = B_FALSE; 3195 *l2cache = B_FALSE; 3196 if (log != NULL) 3197 *log = B_FALSE; 3198 ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log, 3199 return_parent); 3200 fnvlist_free(search); 3201 3202 return (ret); 3203 } 3204 3205 nvlist_t * 3206 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, 3207 boolean_t *l2cache, boolean_t *log) 3208 { 3209 return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log, 3210 B_FALSE)); 3211 } 3212 3213 /* Given a vdev path, return its parent's nvlist */ 3214 nvlist_t * 3215 zpool_find_parent_vdev(zpool_handle_t *zhp, const char *path, 3216 boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log) 3217 { 3218 return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log, 3219 B_TRUE)); 3220 } 3221 3222 /* 3223 * Convert a vdev path to a GUID. Returns GUID or 0 on error. 3224 * 3225 * If is_spare, is_l2cache, or is_log is non-NULL, then store within it 3226 * if the VDEV is a spare, l2cache, or log device. If they're NULL then 3227 * ignore them. 3228 */ 3229 static uint64_t 3230 zpool_vdev_path_to_guid_impl(zpool_handle_t *zhp, const char *path, 3231 boolean_t *is_spare, boolean_t *is_l2cache, boolean_t *is_log) 3232 { 3233 boolean_t spare = B_FALSE, l2cache = B_FALSE, log = B_FALSE; 3234 nvlist_t *tgt; 3235 3236 if ((tgt = zpool_find_vdev(zhp, path, &spare, &l2cache, 3237 &log)) == NULL) 3238 return (0); 3239 3240 if (is_spare != NULL) 3241 *is_spare = spare; 3242 if (is_l2cache != NULL) 3243 *is_l2cache = l2cache; 3244 if (is_log != NULL) 3245 *is_log = log; 3246 3247 return (fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID)); 3248 } 3249 3250 /* Convert a vdev path to a GUID. Returns GUID or 0 on error. */ 3251 uint64_t 3252 zpool_vdev_path_to_guid(zpool_handle_t *zhp, const char *path) 3253 { 3254 return (zpool_vdev_path_to_guid_impl(zhp, path, NULL, NULL, NULL)); 3255 } 3256 3257 /* 3258 * Bring the specified vdev online. The 'flags' parameter is a set of the 3259 * ZFS_ONLINE_* flags. 3260 */ 3261 int 3262 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, 3263 vdev_state_t *newstate) 3264 { 3265 zfs_cmd_t zc = {"\0"}; 3266 char errbuf[ERRBUFLEN]; 3267 nvlist_t *tgt; 3268 boolean_t avail_spare, l2cache, islog; 3269 libzfs_handle_t *hdl = zhp->zpool_hdl; 3270 3271 if (flags & ZFS_ONLINE_EXPAND) { 3272 (void) snprintf(errbuf, sizeof (errbuf), 3273 dgettext(TEXT_DOMAIN, "cannot expand %s"), path); 3274 } else { 3275 (void) snprintf(errbuf, sizeof (errbuf), 3276 dgettext(TEXT_DOMAIN, "cannot online %s"), path); 3277 } 3278 3279 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3280 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 3281 &islog)) == NULL) 3282 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 3283 3284 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 3285 3286 if (!(flags & ZFS_ONLINE_SPARE) && avail_spare) 3287 return (zfs_error(hdl, EZFS_ISSPARE, errbuf)); 3288 3289 #ifndef __FreeBSD__ 3290 const char *pathname; 3291 if ((flags & ZFS_ONLINE_EXPAND || 3292 zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) && 3293 nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &pathname) == 0) { 3294 uint64_t wholedisk = 0; 3295 3296 (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, 3297 &wholedisk); 3298 3299 /* 3300 * XXX - L2ARC 1.0 devices can't support expansion. 3301 */ 3302 if (l2cache) { 3303 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3304 "cannot expand cache devices")); 3305 return (zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf)); 3306 } 3307 3308 if (wholedisk) { 3309 const char *fullpath = path; 3310 char buf[MAXPATHLEN]; 3311 int error; 3312 3313 if (path[0] != '/') { 3314 error = zfs_resolve_shortname(path, buf, 3315 sizeof (buf)); 3316 if (error != 0) 3317 return (zfs_error(hdl, EZFS_NODEVICE, 3318 errbuf)); 3319 3320 fullpath = buf; 3321 } 3322 3323 error = zpool_relabel_disk(hdl, fullpath, errbuf); 3324 if (error != 0) 3325 return (error); 3326 } 3327 } 3328 #endif 3329 3330 zc.zc_cookie = VDEV_STATE_ONLINE; 3331 zc.zc_obj = flags; 3332 3333 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) { 3334 if (errno == EINVAL) { 3335 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split " 3336 "from this pool into a new one. Use '%s' " 3337 "instead"), "zpool detach"); 3338 return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, errbuf)); 3339 } 3340 return (zpool_standard_error(hdl, errno, errbuf)); 3341 } 3342 3343 *newstate = zc.zc_cookie; 3344 return (0); 3345 } 3346 3347 /* 3348 * Take the specified vdev offline 3349 */ 3350 int 3351 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp) 3352 { 3353 zfs_cmd_t zc = {"\0"}; 3354 char errbuf[ERRBUFLEN]; 3355 nvlist_t *tgt; 3356 boolean_t avail_spare, l2cache; 3357 libzfs_handle_t *hdl = zhp->zpool_hdl; 3358 3359 (void) snprintf(errbuf, sizeof (errbuf), 3360 dgettext(TEXT_DOMAIN, "cannot offline %s"), path); 3361 3362 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3363 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 3364 NULL)) == NULL) 3365 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 3366 3367 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 3368 3369 if (avail_spare) 3370 return (zfs_error(hdl, EZFS_ISSPARE, errbuf)); 3371 3372 zc.zc_cookie = VDEV_STATE_OFFLINE; 3373 zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0; 3374 3375 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 3376 return (0); 3377 3378 switch (errno) { 3379 case EBUSY: 3380 3381 /* 3382 * There are no other replicas of this device. 3383 */ 3384 return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf)); 3385 3386 case EEXIST: 3387 /* 3388 * The log device has unplayed logs 3389 */ 3390 return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, errbuf)); 3391 3392 default: 3393 return (zpool_standard_error(hdl, errno, errbuf)); 3394 } 3395 } 3396 3397 /* 3398 * Remove the specified vdev asynchronously from the configuration, so 3399 * that it may come ONLINE if reinserted. This is called from zed on 3400 * Udev remove event. 3401 * Note: We also have a similar function zpool_vdev_remove() that 3402 * removes the vdev from the pool. 3403 */ 3404 int 3405 zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path) 3406 { 3407 zfs_cmd_t zc = {"\0"}; 3408 char errbuf[ERRBUFLEN]; 3409 nvlist_t *tgt; 3410 boolean_t avail_spare, l2cache; 3411 libzfs_handle_t *hdl = zhp->zpool_hdl; 3412 3413 (void) snprintf(errbuf, sizeof (errbuf), 3414 dgettext(TEXT_DOMAIN, "cannot remove %s"), path); 3415 3416 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3417 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 3418 NULL)) == NULL) 3419 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 3420 3421 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 3422 3423 zc.zc_cookie = VDEV_STATE_REMOVED; 3424 3425 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 3426 return (0); 3427 3428 return (zpool_standard_error(hdl, errno, errbuf)); 3429 } 3430 3431 /* 3432 * Mark the given vdev faulted. 3433 */ 3434 int 3435 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux) 3436 { 3437 zfs_cmd_t zc = {"\0"}; 3438 char errbuf[ERRBUFLEN]; 3439 libzfs_handle_t *hdl = zhp->zpool_hdl; 3440 3441 (void) snprintf(errbuf, sizeof (errbuf), 3442 dgettext(TEXT_DOMAIN, "cannot fault %llu"), (u_longlong_t)guid); 3443 3444 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3445 zc.zc_guid = guid; 3446 zc.zc_cookie = VDEV_STATE_FAULTED; 3447 zc.zc_obj = aux; 3448 3449 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 3450 return (0); 3451 3452 switch (errno) { 3453 case EBUSY: 3454 3455 /* 3456 * There are no other replicas of this device. 3457 */ 3458 return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf)); 3459 3460 default: 3461 return (zpool_standard_error(hdl, errno, errbuf)); 3462 } 3463 3464 } 3465 3466 /* 3467 * Generic set vdev state function 3468 */ 3469 static int 3470 zpool_vdev_set_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux, 3471 vdev_state_t state) 3472 { 3473 zfs_cmd_t zc = {"\0"}; 3474 char errbuf[ERRBUFLEN]; 3475 libzfs_handle_t *hdl = zhp->zpool_hdl; 3476 3477 (void) snprintf(errbuf, sizeof (errbuf), 3478 dgettext(TEXT_DOMAIN, "cannot set %s %llu"), 3479 zpool_state_to_name(state, aux), (u_longlong_t)guid); 3480 3481 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3482 zc.zc_guid = guid; 3483 zc.zc_cookie = state; 3484 zc.zc_obj = aux; 3485 3486 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 3487 return (0); 3488 3489 return (zpool_standard_error(hdl, errno, errbuf)); 3490 } 3491 3492 /* 3493 * Mark the given vdev degraded. 3494 */ 3495 int 3496 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux) 3497 { 3498 return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_DEGRADED)); 3499 } 3500 3501 /* 3502 * Mark the given vdev as in a removed state (as if the device does not exist). 3503 * 3504 * This is different than zpool_vdev_remove() which does a removal of a device 3505 * from the pool (but the device does exist). 3506 */ 3507 int 3508 zpool_vdev_set_removed_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux) 3509 { 3510 return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_REMOVED)); 3511 } 3512 3513 /* 3514 * Returns TRUE if the given nvlist is a vdev that was originally swapped in as 3515 * a hot spare. 3516 */ 3517 static boolean_t 3518 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which) 3519 { 3520 nvlist_t **child; 3521 uint_t c, children; 3522 3523 if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child, 3524 &children) == 0) { 3525 const char *type = fnvlist_lookup_string(search, 3526 ZPOOL_CONFIG_TYPE); 3527 if ((strcmp(type, VDEV_TYPE_SPARE) == 0 || 3528 strcmp(type, VDEV_TYPE_DRAID_SPARE) == 0) && 3529 children == 2 && child[which] == tgt) 3530 return (B_TRUE); 3531 3532 for (c = 0; c < children; c++) 3533 if (is_replacing_spare(child[c], tgt, which)) 3534 return (B_TRUE); 3535 } 3536 3537 return (B_FALSE); 3538 } 3539 3540 /* 3541 * Attach new_disk (fully described by nvroot) to old_disk. 3542 * If 'replacing' is specified, the new disk will replace the old one. 3543 */ 3544 int 3545 zpool_vdev_attach(zpool_handle_t *zhp, const char *old_disk, 3546 const char *new_disk, nvlist_t *nvroot, int replacing, boolean_t rebuild) 3547 { 3548 zfs_cmd_t zc = {"\0"}; 3549 char errbuf[ERRBUFLEN]; 3550 int ret; 3551 nvlist_t *tgt; 3552 boolean_t avail_spare, l2cache, islog; 3553 uint64_t val; 3554 char *newname; 3555 const char *type; 3556 nvlist_t **child; 3557 uint_t children; 3558 nvlist_t *config_root; 3559 libzfs_handle_t *hdl = zhp->zpool_hdl; 3560 3561 if (replacing) 3562 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3563 "cannot replace %s with %s"), old_disk, new_disk); 3564 else 3565 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 3566 "cannot attach %s to %s"), new_disk, old_disk); 3567 3568 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3569 if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache, 3570 &islog)) == NULL) 3571 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 3572 3573 if (avail_spare) 3574 return (zfs_error(hdl, EZFS_ISSPARE, errbuf)); 3575 3576 if (l2cache) 3577 return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf)); 3578 3579 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 3580 zc.zc_cookie = replacing; 3581 zc.zc_simple = rebuild; 3582 3583 if (rebuild && 3584 zfeature_lookup_guid("org.openzfs:device_rebuild", NULL) != 0) { 3585 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3586 "the loaded zfs module doesn't support device rebuilds")); 3587 return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf)); 3588 } 3589 3590 type = fnvlist_lookup_string(tgt, ZPOOL_CONFIG_TYPE); 3591 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 && 3592 zfeature_lookup_guid("org.openzfs:raidz_expansion", NULL) != 0) { 3593 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3594 "the loaded zfs module doesn't support raidz expansion")); 3595 return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf)); 3596 } 3597 3598 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 3599 &child, &children) != 0 || children != 1) { 3600 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3601 "new device must be a single disk")); 3602 return (zfs_error(hdl, EZFS_INVALCONFIG, errbuf)); 3603 } 3604 3605 config_root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 3606 ZPOOL_CONFIG_VDEV_TREE); 3607 3608 if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL) 3609 return (-1); 3610 3611 /* 3612 * If the target is a hot spare that has been swapped in, we can only 3613 * replace it with another hot spare. 3614 */ 3615 if (replacing && 3616 nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && 3617 (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache, 3618 NULL) == NULL || !avail_spare) && 3619 is_replacing_spare(config_root, tgt, 1)) { 3620 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3621 "can only be replaced by another hot spare")); 3622 free(newname); 3623 return (zfs_error(hdl, EZFS_BADTARGET, errbuf)); 3624 } 3625 3626 free(newname); 3627 3628 zcmd_write_conf_nvlist(hdl, &zc, nvroot); 3629 3630 ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc); 3631 3632 zcmd_free_nvlists(&zc); 3633 3634 if (ret == 0) 3635 return (0); 3636 3637 switch (errno) { 3638 case ENOTSUP: 3639 /* 3640 * Can't attach to or replace this type of vdev. 3641 */ 3642 if (replacing) { 3643 uint64_t version = zpool_get_prop_int(zhp, 3644 ZPOOL_PROP_VERSION, NULL); 3645 3646 if (islog) { 3647 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3648 "cannot replace a log with a spare")); 3649 } else if (rebuild) { 3650 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3651 "only mirror and dRAID vdevs support " 3652 "sequential reconstruction")); 3653 } else if (zpool_is_draid_spare(new_disk)) { 3654 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3655 "dRAID spares can only replace child " 3656 "devices in their parent's dRAID vdev")); 3657 } else if (version >= SPA_VERSION_MULTI_REPLACE) { 3658 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3659 "already in replacing/spare config; wait " 3660 "for completion or use 'zpool detach'")); 3661 } else { 3662 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3663 "cannot replace a replacing device")); 3664 } 3665 } else if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) { 3666 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3667 "raidz_expansion feature must be enabled " 3668 "in order to attach a device to raidz")); 3669 } else { 3670 char status[64] = {0}; 3671 zpool_prop_get_feature(zhp, 3672 "feature@device_rebuild", status, 63); 3673 if (rebuild && 3674 strncmp(status, ZFS_FEATURE_DISABLED, 64) == 0) { 3675 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3676 "device_rebuild feature must be enabled " 3677 "in order to use sequential " 3678 "reconstruction")); 3679 } else { 3680 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3681 "can only attach to mirrors and top-level " 3682 "disks")); 3683 } 3684 } 3685 (void) zfs_error(hdl, EZFS_BADTARGET, errbuf); 3686 break; 3687 3688 case EINVAL: 3689 /* 3690 * The new device must be a single disk. 3691 */ 3692 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3693 "new device must be a single disk")); 3694 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf); 3695 break; 3696 3697 case EBUSY: 3698 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"), 3699 new_disk); 3700 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 3701 break; 3702 3703 case EOVERFLOW: 3704 /* 3705 * The new device is too small. 3706 */ 3707 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3708 "device is too small")); 3709 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 3710 break; 3711 3712 case EDOM: 3713 /* 3714 * The new device has a different optimal sector size. 3715 */ 3716 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3717 "new device has a different optimal sector size; use the " 3718 "option '-o ashift=N' to override the optimal size")); 3719 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 3720 break; 3721 3722 case ENAMETOOLONG: 3723 /* 3724 * The resulting top-level vdev spec won't fit in the label. 3725 */ 3726 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf); 3727 break; 3728 3729 case ENXIO: 3730 /* 3731 * The existing raidz vdev has offline children 3732 */ 3733 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) { 3734 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3735 "raidz vdev has devices that are are offline or " 3736 "being replaced")); 3737 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 3738 break; 3739 } else { 3740 (void) zpool_standard_error(hdl, errno, errbuf); 3741 } 3742 break; 3743 3744 case EADDRINUSE: 3745 /* 3746 * The boot reserved area is already being used (FreeBSD) 3747 */ 3748 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) { 3749 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3750 "the reserved boot area needed for the expansion " 3751 "is already being used by a boot loader")); 3752 (void) zfs_error(hdl, EZFS_BADDEV, errbuf); 3753 } else { 3754 (void) zpool_standard_error(hdl, errno, errbuf); 3755 } 3756 break; 3757 3758 case ZFS_ERR_ASHIFT_MISMATCH: 3759 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3760 "The new device cannot have a higher alignment requirement " 3761 "than the top-level vdev.")); 3762 (void) zfs_error(hdl, EZFS_BADTARGET, errbuf); 3763 break; 3764 default: 3765 (void) zpool_standard_error(hdl, errno, errbuf); 3766 } 3767 3768 return (-1); 3769 } 3770 3771 /* 3772 * Detach the specified device. 3773 */ 3774 int 3775 zpool_vdev_detach(zpool_handle_t *zhp, const char *path) 3776 { 3777 zfs_cmd_t zc = {"\0"}; 3778 char errbuf[ERRBUFLEN]; 3779 nvlist_t *tgt; 3780 boolean_t avail_spare, l2cache; 3781 libzfs_handle_t *hdl = zhp->zpool_hdl; 3782 3783 (void) snprintf(errbuf, sizeof (errbuf), 3784 dgettext(TEXT_DOMAIN, "cannot detach %s"), path); 3785 3786 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3787 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 3788 NULL)) == NULL) 3789 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 3790 3791 if (avail_spare) 3792 return (zfs_error(hdl, EZFS_ISSPARE, errbuf)); 3793 3794 if (l2cache) 3795 return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf)); 3796 3797 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 3798 3799 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0) 3800 return (0); 3801 3802 switch (errno) { 3803 3804 case ENOTSUP: 3805 /* 3806 * Can't detach from this type of vdev. 3807 */ 3808 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only " 3809 "applicable to mirror and replacing vdevs")); 3810 (void) zfs_error(hdl, EZFS_BADTARGET, errbuf); 3811 break; 3812 3813 case EBUSY: 3814 /* 3815 * There are no other replicas of this device. 3816 */ 3817 (void) zfs_error(hdl, EZFS_NOREPLICAS, errbuf); 3818 break; 3819 3820 default: 3821 (void) zpool_standard_error(hdl, errno, errbuf); 3822 } 3823 3824 return (-1); 3825 } 3826 3827 /* 3828 * Find a mirror vdev in the source nvlist. 3829 * 3830 * The mchild array contains a list of disks in one of the top-level mirrors 3831 * of the source pool. The schild array contains a list of disks that the 3832 * user specified on the command line. We loop over the mchild array to 3833 * see if any entry in the schild array matches. 3834 * 3835 * If a disk in the mchild array is found in the schild array, we return 3836 * the index of that entry. Otherwise we return -1. 3837 */ 3838 static int 3839 find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren, 3840 nvlist_t **schild, uint_t schildren) 3841 { 3842 uint_t mc; 3843 3844 for (mc = 0; mc < mchildren; mc++) { 3845 uint_t sc; 3846 char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp, 3847 mchild[mc], 0); 3848 3849 for (sc = 0; sc < schildren; sc++) { 3850 char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp, 3851 schild[sc], 0); 3852 boolean_t result = (strcmp(mpath, spath) == 0); 3853 3854 free(spath); 3855 if (result) { 3856 free(mpath); 3857 return (mc); 3858 } 3859 } 3860 3861 free(mpath); 3862 } 3863 3864 return (-1); 3865 } 3866 3867 /* 3868 * Split a mirror pool. If newroot points to null, then a new nvlist 3869 * is generated and it is the responsibility of the caller to free it. 3870 */ 3871 int 3872 zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot, 3873 nvlist_t *props, splitflags_t flags) 3874 { 3875 zfs_cmd_t zc = {"\0"}; 3876 char errbuf[ERRBUFLEN]; 3877 const char *bias; 3878 nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL; 3879 nvlist_t **varray = NULL, *zc_props = NULL; 3880 uint_t c, children, newchildren, lastlog = 0, vcount, found = 0; 3881 libzfs_handle_t *hdl = zhp->zpool_hdl; 3882 uint64_t vers, readonly = B_FALSE; 3883 boolean_t freelist = B_FALSE, memory_err = B_TRUE; 3884 int retval = 0; 3885 3886 (void) snprintf(errbuf, sizeof (errbuf), 3887 dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name); 3888 3889 if (!zpool_name_valid(hdl, B_FALSE, newname)) 3890 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf)); 3891 3892 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 3893 (void) fprintf(stderr, gettext("Internal error: unable to " 3894 "retrieve pool configuration\n")); 3895 return (-1); 3896 } 3897 3898 tree = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 3899 vers = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION); 3900 3901 if (props) { 3902 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE }; 3903 if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name, 3904 props, vers, flags, errbuf)) == NULL) 3905 return (-1); 3906 (void) nvlist_lookup_uint64(zc_props, 3907 zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly); 3908 if (readonly) { 3909 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3910 "property %s can only be set at import time"), 3911 zpool_prop_to_name(ZPOOL_PROP_READONLY)); 3912 return (-1); 3913 } 3914 } 3915 3916 if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child, 3917 &children) != 0) { 3918 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3919 "Source pool is missing vdev tree")); 3920 nvlist_free(zc_props); 3921 return (-1); 3922 } 3923 3924 varray = zfs_alloc(hdl, children * sizeof (nvlist_t *)); 3925 vcount = 0; 3926 3927 if (*newroot == NULL || 3928 nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, 3929 &newchild, &newchildren) != 0) 3930 newchildren = 0; 3931 3932 for (c = 0; c < children; c++) { 3933 uint64_t is_log = B_FALSE, is_hole = B_FALSE; 3934 boolean_t is_special = B_FALSE, is_dedup = B_FALSE; 3935 const char *type; 3936 nvlist_t **mchild, *vdev; 3937 uint_t mchildren; 3938 int entry; 3939 3940 /* 3941 * Unlike cache & spares, slogs are stored in the 3942 * ZPOOL_CONFIG_CHILDREN array. We filter them out here. 3943 */ 3944 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 3945 &is_log); 3946 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 3947 &is_hole); 3948 if (is_log || is_hole) { 3949 /* 3950 * Create a hole vdev and put it in the config. 3951 */ 3952 if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0) 3953 goto out; 3954 if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, 3955 VDEV_TYPE_HOLE) != 0) 3956 goto out; 3957 if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE, 3958 1) != 0) 3959 goto out; 3960 if (lastlog == 0) 3961 lastlog = vcount; 3962 varray[vcount++] = vdev; 3963 continue; 3964 } 3965 lastlog = 0; 3966 type = fnvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE); 3967 3968 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) { 3969 vdev = child[c]; 3970 if (nvlist_dup(vdev, &varray[vcount++], 0) != 0) 3971 goto out; 3972 continue; 3973 } else if (strcmp(type, VDEV_TYPE_MIRROR) != 0) { 3974 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3975 "Source pool must be composed only of mirrors\n")); 3976 retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf); 3977 goto out; 3978 } 3979 3980 if (nvlist_lookup_string(child[c], 3981 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0) { 3982 if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) 3983 is_special = B_TRUE; 3984 else if (strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0) 3985 is_dedup = B_TRUE; 3986 } 3987 verify(nvlist_lookup_nvlist_array(child[c], 3988 ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0); 3989 3990 /* find or add an entry for this top-level vdev */ 3991 if (newchildren > 0 && 3992 (entry = find_vdev_entry(zhp, mchild, mchildren, 3993 newchild, newchildren)) >= 0) { 3994 /* We found a disk that the user specified. */ 3995 vdev = mchild[entry]; 3996 ++found; 3997 } else { 3998 /* User didn't specify a disk for this vdev. */ 3999 vdev = mchild[mchildren - 1]; 4000 } 4001 4002 if (nvlist_dup(vdev, &varray[vcount++], 0) != 0) 4003 goto out; 4004 4005 if (flags.dryrun != 0) { 4006 if (is_dedup == B_TRUE) { 4007 if (nvlist_add_string(varray[vcount - 1], 4008 ZPOOL_CONFIG_ALLOCATION_BIAS, 4009 VDEV_ALLOC_BIAS_DEDUP) != 0) 4010 goto out; 4011 } else if (is_special == B_TRUE) { 4012 if (nvlist_add_string(varray[vcount - 1], 4013 ZPOOL_CONFIG_ALLOCATION_BIAS, 4014 VDEV_ALLOC_BIAS_SPECIAL) != 0) 4015 goto out; 4016 } 4017 } 4018 } 4019 4020 /* did we find every disk the user specified? */ 4021 if (found != newchildren) { 4022 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must " 4023 "include at most one disk from each mirror")); 4024 retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf); 4025 goto out; 4026 } 4027 4028 /* Prepare the nvlist for populating. */ 4029 if (*newroot == NULL) { 4030 if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0) 4031 goto out; 4032 freelist = B_TRUE; 4033 if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE, 4034 VDEV_TYPE_ROOT) != 0) 4035 goto out; 4036 } else { 4037 verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0); 4038 } 4039 4040 /* Add all the children we found */ 4041 if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, 4042 (const nvlist_t **)varray, lastlog == 0 ? vcount : lastlog) != 0) 4043 goto out; 4044 4045 /* 4046 * If we're just doing a dry run, exit now with success. 4047 */ 4048 if (flags.dryrun) { 4049 memory_err = B_FALSE; 4050 freelist = B_FALSE; 4051 goto out; 4052 } 4053 4054 /* now build up the config list & call the ioctl */ 4055 if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0) 4056 goto out; 4057 4058 if (nvlist_add_nvlist(newconfig, 4059 ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 || 4060 nvlist_add_string(newconfig, 4061 ZPOOL_CONFIG_POOL_NAME, newname) != 0 || 4062 nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0) 4063 goto out; 4064 4065 /* 4066 * The new pool is automatically part of the namespace unless we 4067 * explicitly export it. 4068 */ 4069 if (!flags.import) 4070 zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT; 4071 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4072 (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string)); 4073 zcmd_write_conf_nvlist(hdl, &zc, newconfig); 4074 if (zc_props != NULL) 4075 zcmd_write_src_nvlist(hdl, &zc, zc_props); 4076 4077 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) { 4078 retval = zpool_standard_error(hdl, errno, errbuf); 4079 goto out; 4080 } 4081 4082 freelist = B_FALSE; 4083 memory_err = B_FALSE; 4084 4085 out: 4086 if (varray != NULL) { 4087 int v; 4088 4089 for (v = 0; v < vcount; v++) 4090 nvlist_free(varray[v]); 4091 free(varray); 4092 } 4093 zcmd_free_nvlists(&zc); 4094 nvlist_free(zc_props); 4095 nvlist_free(newconfig); 4096 if (freelist) { 4097 nvlist_free(*newroot); 4098 *newroot = NULL; 4099 } 4100 4101 if (retval != 0) 4102 return (retval); 4103 4104 if (memory_err) 4105 return (no_memory(hdl)); 4106 4107 return (0); 4108 } 4109 4110 /* 4111 * Remove the given device. 4112 */ 4113 int 4114 zpool_vdev_remove(zpool_handle_t *zhp, const char *path) 4115 { 4116 zfs_cmd_t zc = {"\0"}; 4117 char errbuf[ERRBUFLEN]; 4118 nvlist_t *tgt; 4119 boolean_t avail_spare, l2cache, islog; 4120 libzfs_handle_t *hdl = zhp->zpool_hdl; 4121 uint64_t version; 4122 4123 (void) snprintf(errbuf, sizeof (errbuf), 4124 dgettext(TEXT_DOMAIN, "cannot remove %s"), path); 4125 4126 if (zpool_is_draid_spare(path)) { 4127 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4128 "dRAID spares cannot be removed")); 4129 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 4130 } 4131 4132 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4133 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 4134 &islog)) == NULL) 4135 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 4136 4137 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 4138 if (islog && version < SPA_VERSION_HOLES) { 4139 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4140 "pool must be upgraded to support log removal")); 4141 return (zfs_error(hdl, EZFS_BADVERSION, errbuf)); 4142 } 4143 4144 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 4145 4146 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0) 4147 return (0); 4148 4149 switch (errno) { 4150 4151 case EALREADY: 4152 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4153 "removal for this vdev is already in progress.")); 4154 (void) zfs_error(hdl, EZFS_BUSY, errbuf); 4155 break; 4156 4157 case EINVAL: 4158 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4159 "invalid config; all top-level vdevs must " 4160 "have the same sector size and not be raidz.")); 4161 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf); 4162 break; 4163 4164 case EBUSY: 4165 if (islog) { 4166 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4167 "Mount encrypted datasets to replay logs.")); 4168 } else { 4169 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4170 "Pool busy; removal may already be in progress")); 4171 } 4172 (void) zfs_error(hdl, EZFS_BUSY, errbuf); 4173 break; 4174 4175 case EACCES: 4176 if (islog) { 4177 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4178 "Mount encrypted datasets to replay logs.")); 4179 (void) zfs_error(hdl, EZFS_BUSY, errbuf); 4180 } else { 4181 (void) zpool_standard_error(hdl, errno, errbuf); 4182 } 4183 break; 4184 4185 default: 4186 (void) zpool_standard_error(hdl, errno, errbuf); 4187 } 4188 return (-1); 4189 } 4190 4191 int 4192 zpool_vdev_remove_cancel(zpool_handle_t *zhp) 4193 { 4194 zfs_cmd_t zc = {{0}}; 4195 char errbuf[ERRBUFLEN]; 4196 libzfs_handle_t *hdl = zhp->zpool_hdl; 4197 4198 (void) snprintf(errbuf, sizeof (errbuf), 4199 dgettext(TEXT_DOMAIN, "cannot cancel removal")); 4200 4201 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4202 zc.zc_cookie = 1; 4203 4204 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0) 4205 return (0); 4206 4207 return (zpool_standard_error(hdl, errno, errbuf)); 4208 } 4209 4210 int 4211 zpool_vdev_indirect_size(zpool_handle_t *zhp, const char *path, 4212 uint64_t *sizep) 4213 { 4214 char errbuf[ERRBUFLEN]; 4215 nvlist_t *tgt; 4216 boolean_t avail_spare, l2cache, islog; 4217 libzfs_handle_t *hdl = zhp->zpool_hdl; 4218 4219 (void) snprintf(errbuf, sizeof (errbuf), 4220 dgettext(TEXT_DOMAIN, "cannot determine indirect size of %s"), 4221 path); 4222 4223 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 4224 &islog)) == NULL) 4225 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 4226 4227 if (avail_spare || l2cache || islog) { 4228 *sizep = 0; 4229 return (0); 4230 } 4231 4232 if (nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_INDIRECT_SIZE, sizep) != 0) { 4233 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 4234 "indirect size not available")); 4235 return (zfs_error(hdl, EINVAL, errbuf)); 4236 } 4237 return (0); 4238 } 4239 4240 /* 4241 * Clear the errors for the pool, or the particular device if specified. 4242 */ 4243 int 4244 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl) 4245 { 4246 zfs_cmd_t zc = {"\0"}; 4247 char errbuf[ERRBUFLEN]; 4248 nvlist_t *tgt; 4249 zpool_load_policy_t policy; 4250 boolean_t avail_spare, l2cache; 4251 libzfs_handle_t *hdl = zhp->zpool_hdl; 4252 nvlist_t *nvi = NULL; 4253 int error; 4254 4255 if (path) 4256 (void) snprintf(errbuf, sizeof (errbuf), 4257 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 4258 path); 4259 else 4260 (void) snprintf(errbuf, sizeof (errbuf), 4261 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 4262 zhp->zpool_name); 4263 4264 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4265 if (path) { 4266 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, 4267 &l2cache, NULL)) == NULL) 4268 return (zfs_error(hdl, EZFS_NODEVICE, errbuf)); 4269 4270 /* 4271 * Don't allow error clearing for hot spares. Do allow 4272 * error clearing for l2cache devices. 4273 */ 4274 if (avail_spare) 4275 return (zfs_error(hdl, EZFS_ISSPARE, errbuf)); 4276 4277 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 4278 } 4279 4280 zpool_get_load_policy(rewindnvl, &policy); 4281 zc.zc_cookie = policy.zlp_rewind; 4282 4283 zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2); 4284 zcmd_write_src_nvlist(hdl, &zc, rewindnvl); 4285 4286 while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 && 4287 errno == ENOMEM) 4288 zcmd_expand_dst_nvlist(hdl, &zc); 4289 4290 if (!error || ((policy.zlp_rewind & ZPOOL_TRY_REWIND) && 4291 errno != EPERM && errno != EACCES)) { 4292 if (policy.zlp_rewind & 4293 (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) { 4294 (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi); 4295 zpool_rewind_exclaim(hdl, zc.zc_name, 4296 ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), 4297 nvi); 4298 nvlist_free(nvi); 4299 } 4300 zcmd_free_nvlists(&zc); 4301 return (0); 4302 } 4303 4304 zcmd_free_nvlists(&zc); 4305 return (zpool_standard_error(hdl, errno, errbuf)); 4306 } 4307 4308 /* 4309 * Similar to zpool_clear(), but takes a GUID (used by fmd). 4310 */ 4311 int 4312 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid) 4313 { 4314 zfs_cmd_t zc = {"\0"}; 4315 char errbuf[ERRBUFLEN]; 4316 libzfs_handle_t *hdl = zhp->zpool_hdl; 4317 4318 (void) snprintf(errbuf, sizeof (errbuf), 4319 dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"), 4320 (u_longlong_t)guid); 4321 4322 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4323 zc.zc_guid = guid; 4324 zc.zc_cookie = ZPOOL_NO_REWIND; 4325 4326 if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0) 4327 return (0); 4328 4329 return (zpool_standard_error(hdl, errno, errbuf)); 4330 } 4331 4332 /* 4333 * Change the GUID for a pool. 4334 * 4335 * Similar to zpool_reguid(), but may take a GUID. 4336 * 4337 * If the guid argument is NULL, then no GUID is passed in the nvlist to the 4338 * ioctl(). 4339 */ 4340 int 4341 zpool_set_guid(zpool_handle_t *zhp, const uint64_t *guid) 4342 { 4343 char errbuf[ERRBUFLEN]; 4344 libzfs_handle_t *hdl = zhp->zpool_hdl; 4345 nvlist_t *nvl = NULL; 4346 zfs_cmd_t zc = {"\0"}; 4347 int error = -1; 4348 4349 if (guid != NULL) { 4350 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 4351 return (no_memory(hdl)); 4352 4353 if (nvlist_add_uint64(nvl, ZPOOL_REGUID_GUID, *guid) != 0) { 4354 nvlist_free(nvl); 4355 return (no_memory(hdl)); 4356 } 4357 4358 zcmd_write_src_nvlist(hdl, &zc, nvl); 4359 } 4360 4361 (void) snprintf(errbuf, sizeof (errbuf), 4362 dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name); 4363 4364 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4365 error = zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc); 4366 if (error) { 4367 return (zpool_standard_error(hdl, errno, errbuf)); 4368 } 4369 if (guid != NULL) { 4370 zcmd_free_nvlists(&zc); 4371 nvlist_free(nvl); 4372 } 4373 return (0); 4374 } 4375 4376 /* 4377 * Change the GUID for a pool. 4378 */ 4379 int 4380 zpool_reguid(zpool_handle_t *zhp) 4381 { 4382 return (zpool_set_guid(zhp, NULL)); 4383 } 4384 4385 /* 4386 * Reopen the pool. 4387 */ 4388 int 4389 zpool_reopen_one(zpool_handle_t *zhp, void *data) 4390 { 4391 libzfs_handle_t *hdl = zpool_get_handle(zhp); 4392 const char *pool_name = zpool_get_name(zhp); 4393 boolean_t *scrub_restart = data; 4394 int error; 4395 4396 error = lzc_reopen(pool_name, *scrub_restart); 4397 if (error) { 4398 return (zpool_standard_error_fmt(hdl, error, 4399 dgettext(TEXT_DOMAIN, "cannot reopen '%s'"), pool_name)); 4400 } 4401 4402 return (0); 4403 } 4404 4405 /* call into libzfs_core to execute the sync IOCTL per pool */ 4406 int 4407 zpool_sync_one(zpool_handle_t *zhp, void *data) 4408 { 4409 int ret; 4410 libzfs_handle_t *hdl = zpool_get_handle(zhp); 4411 const char *pool_name = zpool_get_name(zhp); 4412 boolean_t *force = data; 4413 nvlist_t *innvl = fnvlist_alloc(); 4414 4415 fnvlist_add_boolean_value(innvl, "force", *force); 4416 if ((ret = lzc_sync(pool_name, innvl, NULL)) != 0) { 4417 nvlist_free(innvl); 4418 return (zpool_standard_error_fmt(hdl, ret, 4419 dgettext(TEXT_DOMAIN, "sync '%s' failed"), pool_name)); 4420 } 4421 nvlist_free(innvl); 4422 4423 return (0); 4424 } 4425 4426 #define PATH_BUF_LEN 64 4427 4428 /* 4429 * Given a vdev, return the name to display in iostat. If the vdev has a path, 4430 * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. 4431 * We also check if this is a whole disk, in which case we strip off the 4432 * trailing 's0' slice name. 4433 * 4434 * This routine is also responsible for identifying when disks have been 4435 * reconfigured in a new location. The kernel will have opened the device by 4436 * devid, but the path will still refer to the old location. To catch this, we 4437 * first do a path -> devid translation (which is fast for the common case). If 4438 * the devid matches, we're done. If not, we do a reverse devid -> path 4439 * translation and issue the appropriate ioctl() to update the path of the vdev. 4440 * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any 4441 * of these checks. 4442 */ 4443 char * 4444 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, 4445 int name_flags) 4446 { 4447 const char *type, *tpath; 4448 const char *path; 4449 uint64_t value; 4450 char buf[PATH_BUF_LEN]; 4451 char tmpbuf[PATH_BUF_LEN * 2]; 4452 4453 /* 4454 * vdev_name will be "root"/"root-0" for the root vdev, but it is the 4455 * zpool name that will be displayed to the user. 4456 */ 4457 type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE); 4458 if (zhp != NULL && strcmp(type, "root") == 0) 4459 return (zfs_strdup(hdl, zpool_get_name(zhp))); 4460 4461 if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_PATH")) 4462 name_flags |= VDEV_NAME_PATH; 4463 if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_GUID")) 4464 name_flags |= VDEV_NAME_GUID; 4465 if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_FOLLOW_LINKS")) 4466 name_flags |= VDEV_NAME_FOLLOW_LINKS; 4467 4468 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 || 4469 name_flags & VDEV_NAME_GUID) { 4470 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value); 4471 (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value); 4472 path = buf; 4473 } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &tpath) == 0) { 4474 path = tpath; 4475 4476 if (name_flags & VDEV_NAME_FOLLOW_LINKS) { 4477 char *rp = realpath(path, NULL); 4478 if (rp) { 4479 strlcpy(buf, rp, sizeof (buf)); 4480 path = buf; 4481 free(rp); 4482 } 4483 } 4484 4485 /* 4486 * For a block device only use the name. 4487 */ 4488 if ((strcmp(type, VDEV_TYPE_DISK) == 0) && 4489 !(name_flags & VDEV_NAME_PATH)) { 4490 path = zfs_strip_path(path); 4491 } 4492 4493 /* 4494 * Remove the partition from the path if this is a whole disk. 4495 */ 4496 if (strcmp(type, VDEV_TYPE_DRAID_SPARE) != 0 && 4497 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value) 4498 == 0 && value && !(name_flags & VDEV_NAME_PATH)) { 4499 return (zfs_strip_partition(path)); 4500 } 4501 } else { 4502 path = type; 4503 4504 /* 4505 * If it's a raidz device, we need to stick in the parity level. 4506 */ 4507 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) { 4508 value = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY); 4509 (void) snprintf(buf, sizeof (buf), "%s%llu", path, 4510 (u_longlong_t)value); 4511 path = buf; 4512 } 4513 4514 /* 4515 * If it's a dRAID device, we add parity, groups, and spares. 4516 */ 4517 if (strcmp(path, VDEV_TYPE_DRAID) == 0) { 4518 uint64_t ndata, nparity, nspares; 4519 nvlist_t **child; 4520 uint_t children; 4521 4522 verify(nvlist_lookup_nvlist_array(nv, 4523 ZPOOL_CONFIG_CHILDREN, &child, &children) == 0); 4524 nparity = fnvlist_lookup_uint64(nv, 4525 ZPOOL_CONFIG_NPARITY); 4526 ndata = fnvlist_lookup_uint64(nv, 4527 ZPOOL_CONFIG_DRAID_NDATA); 4528 nspares = fnvlist_lookup_uint64(nv, 4529 ZPOOL_CONFIG_DRAID_NSPARES); 4530 4531 path = zpool_draid_name(buf, sizeof (buf), ndata, 4532 nparity, nspares, children); 4533 } 4534 4535 /* 4536 * We identify each top-level vdev by using a <type-id> 4537 * naming convention. 4538 */ 4539 if (name_flags & VDEV_NAME_TYPE_ID) { 4540 uint64_t id = fnvlist_lookup_uint64(nv, 4541 ZPOOL_CONFIG_ID); 4542 (void) snprintf(tmpbuf, sizeof (tmpbuf), "%s-%llu", 4543 path, (u_longlong_t)id); 4544 path = tmpbuf; 4545 } 4546 } 4547 4548 return (zfs_strdup(hdl, path)); 4549 } 4550 4551 static int 4552 zbookmark_mem_compare(const void *a, const void *b) 4553 { 4554 return (memcmp(a, b, sizeof (zbookmark_phys_t))); 4555 } 4556 4557 void 4558 zpool_add_propname(zpool_handle_t *zhp, const char *propname) 4559 { 4560 assert(zhp->zpool_n_propnames < ZHP_MAX_PROPNAMES); 4561 zhp->zpool_propnames[zhp->zpool_n_propnames] = propname; 4562 zhp->zpool_n_propnames++; 4563 } 4564 4565 /* 4566 * Retrieve the persistent error log, uniquify the members, and return to the 4567 * caller. 4568 */ 4569 int 4570 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp) 4571 { 4572 zfs_cmd_t zc = {"\0"}; 4573 libzfs_handle_t *hdl = zhp->zpool_hdl; 4574 zbookmark_phys_t *buf; 4575 uint64_t buflen = 10000; /* approx. 1MB of RAM */ 4576 4577 if (fnvlist_lookup_uint64(zhp->zpool_config, 4578 ZPOOL_CONFIG_ERRCOUNT) == 0) 4579 return (0); 4580 4581 /* 4582 * Retrieve the raw error list from the kernel. If it doesn't fit, 4583 * allocate a larger buffer and retry. 4584 */ 4585 (void) strcpy(zc.zc_name, zhp->zpool_name); 4586 for (;;) { 4587 buf = zfs_alloc(zhp->zpool_hdl, 4588 buflen * sizeof (zbookmark_phys_t)); 4589 zc.zc_nvlist_dst = (uintptr_t)buf; 4590 zc.zc_nvlist_dst_size = buflen; 4591 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_ERROR_LOG, 4592 &zc) != 0) { 4593 free(buf); 4594 if (errno == ENOMEM) { 4595 buflen *= 2; 4596 } else { 4597 return (zpool_standard_error_fmt(hdl, errno, 4598 dgettext(TEXT_DOMAIN, "errors: List of " 4599 "errors unavailable"))); 4600 } 4601 } else { 4602 break; 4603 } 4604 } 4605 4606 /* 4607 * Sort the resulting bookmarks. This is a little confusing due to the 4608 * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last 4609 * to first, and 'zc_nvlist_dst_size' indicates the number of bookmarks 4610 * _not_ copied as part of the process. So we point the start of our 4611 * array appropriate and decrement the total number of elements. 4612 */ 4613 zbookmark_phys_t *zb = buf + zc.zc_nvlist_dst_size; 4614 uint64_t zblen = buflen - zc.zc_nvlist_dst_size; 4615 4616 qsort(zb, zblen, sizeof (zbookmark_phys_t), zbookmark_mem_compare); 4617 4618 verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0); 4619 4620 /* 4621 * Fill in the nverrlistp with nvlist's of dataset and object numbers. 4622 */ 4623 for (uint64_t i = 0; i < zblen; i++) { 4624 nvlist_t *nv; 4625 4626 /* ignoring zb_blkid and zb_level for now */ 4627 if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset && 4628 zb[i-1].zb_object == zb[i].zb_object) 4629 continue; 4630 4631 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0) 4632 goto nomem; 4633 if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET, 4634 zb[i].zb_objset) != 0) { 4635 nvlist_free(nv); 4636 goto nomem; 4637 } 4638 if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT, 4639 zb[i].zb_object) != 0) { 4640 nvlist_free(nv); 4641 goto nomem; 4642 } 4643 if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) { 4644 nvlist_free(nv); 4645 goto nomem; 4646 } 4647 nvlist_free(nv); 4648 } 4649 4650 free(buf); 4651 return (0); 4652 4653 nomem: 4654 free(buf); 4655 return (no_memory(zhp->zpool_hdl)); 4656 } 4657 4658 /* 4659 * Upgrade a ZFS pool to the latest on-disk version. 4660 */ 4661 int 4662 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version) 4663 { 4664 zfs_cmd_t zc = {"\0"}; 4665 libzfs_handle_t *hdl = zhp->zpool_hdl; 4666 4667 (void) strcpy(zc.zc_name, zhp->zpool_name); 4668 zc.zc_cookie = new_version; 4669 4670 if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0) 4671 return (zpool_standard_error_fmt(hdl, errno, 4672 dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"), 4673 zhp->zpool_name)); 4674 return (0); 4675 } 4676 4677 void 4678 zfs_save_arguments(int argc, char **argv, char *string, int len) 4679 { 4680 int i; 4681 4682 (void) strlcpy(string, zfs_basename(argv[0]), len); 4683 for (i = 1; i < argc; i++) { 4684 (void) strlcat(string, " ", len); 4685 (void) strlcat(string, argv[i], len); 4686 } 4687 } 4688 4689 int 4690 zpool_log_history(libzfs_handle_t *hdl, const char *message) 4691 { 4692 zfs_cmd_t zc = {"\0"}; 4693 nvlist_t *args; 4694 4695 args = fnvlist_alloc(); 4696 fnvlist_add_string(args, "message", message); 4697 zcmd_write_src_nvlist(hdl, &zc, args); 4698 int err = zfs_ioctl(hdl, ZFS_IOC_LOG_HISTORY, &zc); 4699 nvlist_free(args); 4700 zcmd_free_nvlists(&zc); 4701 return (err); 4702 } 4703 4704 /* 4705 * Perform ioctl to get some command history of a pool. 4706 * 4707 * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the 4708 * logical offset of the history buffer to start reading from. 4709 * 4710 * Upon return, 'off' is the next logical offset to read from and 4711 * 'len' is the actual amount of bytes read into 'buf'. 4712 */ 4713 static int 4714 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len) 4715 { 4716 zfs_cmd_t zc = {"\0"}; 4717 libzfs_handle_t *hdl = zhp->zpool_hdl; 4718 4719 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4720 4721 zc.zc_history = (uint64_t)(uintptr_t)buf; 4722 zc.zc_history_len = *len; 4723 zc.zc_history_offset = *off; 4724 4725 if (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) { 4726 switch (errno) { 4727 case EPERM: 4728 return (zfs_error_fmt(hdl, EZFS_PERM, 4729 dgettext(TEXT_DOMAIN, 4730 "cannot show history for pool '%s'"), 4731 zhp->zpool_name)); 4732 case ENOENT: 4733 return (zfs_error_fmt(hdl, EZFS_NOHISTORY, 4734 dgettext(TEXT_DOMAIN, "cannot get history for pool " 4735 "'%s'"), zhp->zpool_name)); 4736 case ENOTSUP: 4737 return (zfs_error_fmt(hdl, EZFS_BADVERSION, 4738 dgettext(TEXT_DOMAIN, "cannot get history for pool " 4739 "'%s', pool must be upgraded"), zhp->zpool_name)); 4740 default: 4741 return (zpool_standard_error_fmt(hdl, errno, 4742 dgettext(TEXT_DOMAIN, 4743 "cannot get history for '%s'"), zhp->zpool_name)); 4744 } 4745 } 4746 4747 *len = zc.zc_history_len; 4748 *off = zc.zc_history_offset; 4749 4750 return (0); 4751 } 4752 4753 /* 4754 * Retrieve the command history of a pool. 4755 */ 4756 int 4757 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off, 4758 boolean_t *eof) 4759 { 4760 libzfs_handle_t *hdl = zhp->zpool_hdl; 4761 char *buf; 4762 int buflen = 128 * 1024; 4763 nvlist_t **records = NULL; 4764 uint_t numrecords = 0; 4765 int err = 0, i; 4766 uint64_t start = *off; 4767 4768 buf = zfs_alloc(hdl, buflen); 4769 4770 /* process about 1MiB a time */ 4771 while (*off - start < 1024 * 1024) { 4772 uint64_t bytes_read = buflen; 4773 uint64_t leftover; 4774 4775 if ((err = get_history(zhp, buf, off, &bytes_read)) != 0) 4776 break; 4777 4778 /* if nothing else was read in, we're at EOF, just return */ 4779 if (!bytes_read) { 4780 *eof = B_TRUE; 4781 break; 4782 } 4783 4784 if ((err = zpool_history_unpack(buf, bytes_read, 4785 &leftover, &records, &numrecords)) != 0) { 4786 zpool_standard_error_fmt(hdl, err, 4787 dgettext(TEXT_DOMAIN, 4788 "cannot get history for '%s'"), zhp->zpool_name); 4789 break; 4790 } 4791 *off -= leftover; 4792 if (leftover == bytes_read) { 4793 /* 4794 * no progress made, because buffer is not big enough 4795 * to hold this record; resize and retry. 4796 */ 4797 buflen *= 2; 4798 free(buf); 4799 buf = zfs_alloc(hdl, buflen); 4800 } 4801 } 4802 4803 free(buf); 4804 4805 if (!err) { 4806 *nvhisp = fnvlist_alloc(); 4807 fnvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD, 4808 (const nvlist_t **)records, numrecords); 4809 } 4810 for (i = 0; i < numrecords; i++) 4811 nvlist_free(records[i]); 4812 free(records); 4813 4814 return (err); 4815 } 4816 4817 /* 4818 * Retrieve the next event given the passed 'zevent_fd' file descriptor. 4819 * If there is a new event available 'nvp' will contain a newly allocated 4820 * nvlist and 'dropped' will be set to the number of missed events since 4821 * the last call to this function. When 'nvp' is set to NULL it indicates 4822 * no new events are available. In either case the function returns 0 and 4823 * it is up to the caller to free 'nvp'. In the case of a fatal error the 4824 * function will return a non-zero value. When the function is called in 4825 * blocking mode (the default, unless the ZEVENT_NONBLOCK flag is passed), 4826 * it will not return until a new event is available. 4827 */ 4828 int 4829 zpool_events_next(libzfs_handle_t *hdl, nvlist_t **nvp, 4830 int *dropped, unsigned flags, int zevent_fd) 4831 { 4832 zfs_cmd_t zc = {"\0"}; 4833 int error = 0; 4834 4835 *nvp = NULL; 4836 *dropped = 0; 4837 zc.zc_cleanup_fd = zevent_fd; 4838 4839 if (flags & ZEVENT_NONBLOCK) 4840 zc.zc_guid = ZEVENT_NONBLOCK; 4841 4842 zcmd_alloc_dst_nvlist(hdl, &zc, ZEVENT_SIZE); 4843 4844 retry: 4845 if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_NEXT, &zc) != 0) { 4846 switch (errno) { 4847 case ESHUTDOWN: 4848 error = zfs_error_fmt(hdl, EZFS_POOLUNAVAIL, 4849 dgettext(TEXT_DOMAIN, "zfs shutdown")); 4850 goto out; 4851 case ENOENT: 4852 /* Blocking error case should not occur */ 4853 if (!(flags & ZEVENT_NONBLOCK)) 4854 error = zpool_standard_error_fmt(hdl, errno, 4855 dgettext(TEXT_DOMAIN, "cannot get event")); 4856 4857 goto out; 4858 case ENOMEM: 4859 zcmd_expand_dst_nvlist(hdl, &zc); 4860 goto retry; 4861 default: 4862 error = zpool_standard_error_fmt(hdl, errno, 4863 dgettext(TEXT_DOMAIN, "cannot get event")); 4864 goto out; 4865 } 4866 } 4867 4868 error = zcmd_read_dst_nvlist(hdl, &zc, nvp); 4869 if (error != 0) 4870 goto out; 4871 4872 *dropped = (int)zc.zc_cookie; 4873 out: 4874 zcmd_free_nvlists(&zc); 4875 4876 return (error); 4877 } 4878 4879 /* 4880 * Clear all events. 4881 */ 4882 int 4883 zpool_events_clear(libzfs_handle_t *hdl, int *count) 4884 { 4885 zfs_cmd_t zc = {"\0"}; 4886 4887 if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0) 4888 return (zpool_standard_error(hdl, errno, 4889 dgettext(TEXT_DOMAIN, "cannot clear events"))); 4890 4891 if (count != NULL) 4892 *count = (int)zc.zc_cookie; /* # of events cleared */ 4893 4894 return (0); 4895 } 4896 4897 /* 4898 * Seek to a specific EID, ZEVENT_SEEK_START, or ZEVENT_SEEK_END for 4899 * the passed zevent_fd file handle. On success zero is returned, 4900 * otherwise -1 is returned and hdl->libzfs_error is set to the errno. 4901 */ 4902 int 4903 zpool_events_seek(libzfs_handle_t *hdl, uint64_t eid, int zevent_fd) 4904 { 4905 zfs_cmd_t zc = {"\0"}; 4906 int error = 0; 4907 4908 zc.zc_guid = eid; 4909 zc.zc_cleanup_fd = zevent_fd; 4910 4911 if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_SEEK, &zc) != 0) { 4912 switch (errno) { 4913 case ENOENT: 4914 error = zfs_error_fmt(hdl, EZFS_NOENT, 4915 dgettext(TEXT_DOMAIN, "cannot get event")); 4916 break; 4917 4918 case ENOMEM: 4919 error = zfs_error_fmt(hdl, EZFS_NOMEM, 4920 dgettext(TEXT_DOMAIN, "cannot get event")); 4921 break; 4922 4923 default: 4924 error = zpool_standard_error_fmt(hdl, errno, 4925 dgettext(TEXT_DOMAIN, "cannot get event")); 4926 break; 4927 } 4928 } 4929 4930 return (error); 4931 } 4932 4933 static void 4934 zpool_obj_to_path_impl(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, 4935 char *pathname, size_t len, boolean_t always_unmounted) 4936 { 4937 zfs_cmd_t zc = {"\0"}; 4938 boolean_t mounted = B_FALSE; 4939 char *mntpnt = NULL; 4940 char dsname[ZFS_MAX_DATASET_NAME_LEN]; 4941 4942 if (dsobj == 0) { 4943 /* special case for the MOS */ 4944 (void) snprintf(pathname, len, "<metadata>:<0x%llx>", 4945 (longlong_t)obj); 4946 return; 4947 } 4948 4949 /* get the dataset's name */ 4950 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 4951 zc.zc_obj = dsobj; 4952 if (zfs_ioctl(zhp->zpool_hdl, 4953 ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) { 4954 /* just write out a path of two object numbers */ 4955 (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>", 4956 (longlong_t)dsobj, (longlong_t)obj); 4957 return; 4958 } 4959 (void) strlcpy(dsname, zc.zc_value, sizeof (dsname)); 4960 4961 /* find out if the dataset is mounted */ 4962 mounted = !always_unmounted && is_mounted(zhp->zpool_hdl, dsname, 4963 &mntpnt); 4964 4965 /* get the corrupted object's path */ 4966 (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name)); 4967 zc.zc_obj = obj; 4968 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_OBJ_TO_PATH, 4969 &zc) == 0) { 4970 if (mounted) { 4971 (void) snprintf(pathname, len, "%s%s", mntpnt, 4972 zc.zc_value); 4973 } else { 4974 (void) snprintf(pathname, len, "%s:%s", 4975 dsname, zc.zc_value); 4976 } 4977 } else { 4978 (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, 4979 (longlong_t)obj); 4980 } 4981 free(mntpnt); 4982 } 4983 4984 void 4985 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, 4986 char *pathname, size_t len) 4987 { 4988 zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_FALSE); 4989 } 4990 4991 void 4992 zpool_obj_to_path_ds(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, 4993 char *pathname, size_t len) 4994 { 4995 zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_TRUE); 4996 } 4997 /* 4998 * Wait while the specified activity is in progress in the pool. 4999 */ 5000 int 5001 zpool_wait(zpool_handle_t *zhp, zpool_wait_activity_t activity) 5002 { 5003 boolean_t missing; 5004 5005 int error = zpool_wait_status(zhp, activity, &missing, NULL); 5006 5007 if (missing) { 5008 (void) zpool_standard_error_fmt(zhp->zpool_hdl, ENOENT, 5009 dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"), 5010 zhp->zpool_name); 5011 return (ENOENT); 5012 } else { 5013 return (error); 5014 } 5015 } 5016 5017 /* 5018 * Wait for the given activity and return the status of the wait (whether or not 5019 * any waiting was done) in the 'waited' parameter. Non-existent pools are 5020 * reported via the 'missing' parameter, rather than by printing an error 5021 * message. This is convenient when this function is called in a loop over a 5022 * long period of time (as it is, for example, by zpool's wait cmd). In that 5023 * scenario, a pool being exported or destroyed should be considered a normal 5024 * event, so we don't want to print an error when we find that the pool doesn't 5025 * exist. 5026 */ 5027 int 5028 zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity, 5029 boolean_t *missing, boolean_t *waited) 5030 { 5031 int error = lzc_wait(zhp->zpool_name, activity, waited); 5032 *missing = (error == ENOENT); 5033 if (*missing) 5034 return (0); 5035 5036 if (error != 0) { 5037 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error, 5038 dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"), 5039 zhp->zpool_name); 5040 } 5041 5042 return (error); 5043 } 5044 5045 int 5046 zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap) 5047 { 5048 int error = lzc_set_bootenv(zhp->zpool_name, envmap); 5049 if (error != 0) { 5050 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error, 5051 dgettext(TEXT_DOMAIN, 5052 "error setting bootenv in pool '%s'"), zhp->zpool_name); 5053 } 5054 5055 return (error); 5056 } 5057 5058 int 5059 zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp) 5060 { 5061 nvlist_t *nvl; 5062 int error; 5063 5064 nvl = NULL; 5065 error = lzc_get_bootenv(zhp->zpool_name, &nvl); 5066 if (error != 0) { 5067 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error, 5068 dgettext(TEXT_DOMAIN, 5069 "error getting bootenv in pool '%s'"), zhp->zpool_name); 5070 } else { 5071 *nvlp = nvl; 5072 } 5073 5074 return (error); 5075 } 5076 5077 /* 5078 * Attempt to read and parse feature file(s) (from "compatibility" property). 5079 * Files contain zpool feature names, comma or whitespace-separated. 5080 * Comments (# character to next newline) are discarded. 5081 * 5082 * Arguments: 5083 * compatibility : string containing feature filenames 5084 * features : either NULL or pointer to array of boolean 5085 * report : either NULL or pointer to string buffer 5086 * rlen : length of "report" buffer 5087 * 5088 * compatibility is NULL (unset), "", "off", "legacy", or list of 5089 * comma-separated filenames. filenames should either be absolute, 5090 * or relative to: 5091 * 1) ZPOOL_SYSCONF_COMPAT_D (eg: /etc/zfs/compatibility.d) or 5092 * 2) ZPOOL_DATA_COMPAT_D (eg: /usr/share/zfs/compatibility.d). 5093 * (Unset), "" or "off" => enable all features 5094 * "legacy" => disable all features 5095 * 5096 * Any feature names read from files which match unames in spa_feature_table 5097 * will have the corresponding boolean set in the features array (if non-NULL). 5098 * If more than one feature set specified, only features present in *all* of 5099 * them will be set. 5100 * 5101 * "report" if not NULL will be populated with a suitable status message. 5102 * 5103 * Return values: 5104 * ZPOOL_COMPATIBILITY_OK : files read and parsed ok 5105 * ZPOOL_COMPATIBILITY_BADFILE : file too big or not a text file 5106 * ZPOOL_COMPATIBILITY_BADTOKEN : SYSCONF file contains invalid feature name 5107 * ZPOOL_COMPATIBILITY_WARNTOKEN : DATA file contains invalid feature name 5108 * ZPOOL_COMPATIBILITY_NOFILES : no feature files found 5109 */ 5110 zpool_compat_status_t 5111 zpool_load_compat(const char *compat, boolean_t *features, char *report, 5112 size_t rlen) 5113 { 5114 int sdirfd, ddirfd, featfd; 5115 struct stat fs; 5116 char *fc; 5117 char *ps, *ls, *ws; 5118 char *file, *line, *word; 5119 5120 char l_compat[ZFS_MAXPROPLEN]; 5121 5122 boolean_t ret_nofiles = B_TRUE; 5123 boolean_t ret_badfile = B_FALSE; 5124 boolean_t ret_badtoken = B_FALSE; 5125 boolean_t ret_warntoken = B_FALSE; 5126 5127 /* special cases (unset), "" and "off" => enable all features */ 5128 if (compat == NULL || compat[0] == '\0' || 5129 strcmp(compat, ZPOOL_COMPAT_OFF) == 0) { 5130 if (features != NULL) 5131 for (uint_t i = 0; i < SPA_FEATURES; i++) 5132 features[i] = B_TRUE; 5133 if (report != NULL) 5134 strlcpy(report, gettext("all features enabled"), rlen); 5135 return (ZPOOL_COMPATIBILITY_OK); 5136 } 5137 5138 /* Final special case "legacy" => disable all features */ 5139 if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) { 5140 if (features != NULL) 5141 for (uint_t i = 0; i < SPA_FEATURES; i++) 5142 features[i] = B_FALSE; 5143 if (report != NULL) 5144 strlcpy(report, gettext("all features disabled"), rlen); 5145 return (ZPOOL_COMPATIBILITY_OK); 5146 } 5147 5148 /* 5149 * Start with all true; will be ANDed with results from each file 5150 */ 5151 if (features != NULL) 5152 for (uint_t i = 0; i < SPA_FEATURES; i++) 5153 features[i] = B_TRUE; 5154 5155 char err_badfile[ZFS_MAXPROPLEN] = ""; 5156 char err_badtoken[ZFS_MAXPROPLEN] = ""; 5157 5158 /* 5159 * We ignore errors from the directory open() 5160 * as they're only needed if the filename is relative 5161 * which will be checked during the openat(). 5162 */ 5163 5164 /* O_PATH safer than O_RDONLY if system allows it */ 5165 #if defined(O_PATH) 5166 #define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_PATH) 5167 #else 5168 #define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_RDONLY) 5169 #endif 5170 5171 sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, ZC_DIR_FLAGS); 5172 ddirfd = open(ZPOOL_DATA_COMPAT_D, ZC_DIR_FLAGS); 5173 5174 (void) strlcpy(l_compat, compat, ZFS_MAXPROPLEN); 5175 5176 for (file = strtok_r(l_compat, ",", &ps); 5177 file != NULL; 5178 file = strtok_r(NULL, ",", &ps)) { 5179 5180 boolean_t l_features[SPA_FEATURES]; 5181 5182 enum { Z_SYSCONF, Z_DATA } source; 5183 5184 /* try sysconfdir first, then datadir */ 5185 source = Z_SYSCONF; 5186 if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) { 5187 featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC); 5188 source = Z_DATA; 5189 } 5190 5191 /* File readable and correct size? */ 5192 if (featfd < 0 || 5193 fstat(featfd, &fs) < 0 || 5194 fs.st_size < 1 || 5195 fs.st_size > ZPOOL_COMPAT_MAXSIZE) { 5196 (void) close(featfd); 5197 strlcat(err_badfile, file, ZFS_MAXPROPLEN); 5198 strlcat(err_badfile, " ", ZFS_MAXPROPLEN); 5199 ret_badfile = B_TRUE; 5200 continue; 5201 } 5202 5203 /* Prefault the file if system allows */ 5204 #if defined(MAP_POPULATE) 5205 #define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE) 5206 #elif defined(MAP_PREFAULT_READ) 5207 #define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_PREFAULT_READ) 5208 #else 5209 #define ZC_MMAP_FLAGS (MAP_PRIVATE) 5210 #endif 5211 5212 /* private mmap() so we can strtok safely */ 5213 fc = (char *)mmap(NULL, fs.st_size, PROT_READ | PROT_WRITE, 5214 ZC_MMAP_FLAGS, featfd, 0); 5215 (void) close(featfd); 5216 5217 /* map ok, and last character == newline? */ 5218 if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') { 5219 (void) munmap((void *) fc, fs.st_size); 5220 strlcat(err_badfile, file, ZFS_MAXPROPLEN); 5221 strlcat(err_badfile, " ", ZFS_MAXPROPLEN); 5222 ret_badfile = B_TRUE; 5223 continue; 5224 } 5225 5226 ret_nofiles = B_FALSE; 5227 5228 for (uint_t i = 0; i < SPA_FEATURES; i++) 5229 l_features[i] = B_FALSE; 5230 5231 /* replace final newline with NULL to ensure string ends */ 5232 fc[fs.st_size - 1] = '\0'; 5233 5234 for (line = strtok_r(fc, "\n", &ls); 5235 line != NULL; 5236 line = strtok_r(NULL, "\n", &ls)) { 5237 /* discard comments */ 5238 char *r = strchr(line, '#'); 5239 if (r != NULL) 5240 *r = '\0'; 5241 5242 for (word = strtok_r(line, ", \t", &ws); 5243 word != NULL; 5244 word = strtok_r(NULL, ", \t", &ws)) { 5245 /* Find matching feature name */ 5246 uint_t f; 5247 for (f = 0; f < SPA_FEATURES; f++) { 5248 zfeature_info_t *fi = 5249 &spa_feature_table[f]; 5250 if (strcmp(word, fi->fi_uname) == 0) { 5251 l_features[f] = B_TRUE; 5252 break; 5253 } 5254 } 5255 if (f < SPA_FEATURES) 5256 continue; 5257 5258 /* found an unrecognized word */ 5259 /* lightly sanitize it */ 5260 if (strlen(word) > 32) 5261 word[32] = '\0'; 5262 for (char *c = word; *c != '\0'; c++) 5263 if (!isprint(*c)) 5264 *c = '?'; 5265 5266 strlcat(err_badtoken, word, ZFS_MAXPROPLEN); 5267 strlcat(err_badtoken, " ", ZFS_MAXPROPLEN); 5268 if (source == Z_SYSCONF) 5269 ret_badtoken = B_TRUE; 5270 else 5271 ret_warntoken = B_TRUE; 5272 } 5273 } 5274 (void) munmap((void *) fc, fs.st_size); 5275 5276 if (features != NULL) 5277 for (uint_t i = 0; i < SPA_FEATURES; i++) 5278 features[i] &= l_features[i]; 5279 } 5280 (void) close(sdirfd); 5281 (void) close(ddirfd); 5282 5283 /* Return the most serious error */ 5284 if (ret_badfile) { 5285 if (report != NULL) 5286 snprintf(report, rlen, gettext("could not read/" 5287 "parse feature file(s): %s"), err_badfile); 5288 return (ZPOOL_COMPATIBILITY_BADFILE); 5289 } 5290 if (ret_nofiles) { 5291 if (report != NULL) 5292 strlcpy(report, 5293 gettext("no valid compatibility files specified"), 5294 rlen); 5295 return (ZPOOL_COMPATIBILITY_NOFILES); 5296 } 5297 if (ret_badtoken) { 5298 if (report != NULL) 5299 snprintf(report, rlen, gettext("invalid feature " 5300 "name(s) in local compatibility files: %s"), 5301 err_badtoken); 5302 return (ZPOOL_COMPATIBILITY_BADTOKEN); 5303 } 5304 if (ret_warntoken) { 5305 if (report != NULL) 5306 snprintf(report, rlen, gettext("unrecognized feature " 5307 "name(s) in distribution compatibility files: %s"), 5308 err_badtoken); 5309 return (ZPOOL_COMPATIBILITY_WARNTOKEN); 5310 } 5311 if (report != NULL) 5312 strlcpy(report, gettext("compatibility set ok"), rlen); 5313 return (ZPOOL_COMPATIBILITY_OK); 5314 } 5315 5316 static int 5317 zpool_vdev_guid(zpool_handle_t *zhp, const char *vdevname, uint64_t *vdev_guid) 5318 { 5319 nvlist_t *tgt; 5320 boolean_t avail_spare, l2cache; 5321 5322 verify(zhp != NULL); 5323 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 5324 char errbuf[ERRBUFLEN]; 5325 (void) snprintf(errbuf, sizeof (errbuf), 5326 dgettext(TEXT_DOMAIN, "pool is in an unavailable state")); 5327 return (zfs_error(zhp->zpool_hdl, EZFS_POOLUNAVAIL, errbuf)); 5328 } 5329 5330 if ((tgt = zpool_find_vdev(zhp, vdevname, &avail_spare, &l2cache, 5331 NULL)) == NULL) { 5332 char errbuf[ERRBUFLEN]; 5333 (void) snprintf(errbuf, sizeof (errbuf), 5334 dgettext(TEXT_DOMAIN, "can not find %s in %s"), 5335 vdevname, zhp->zpool_name); 5336 return (zfs_error(zhp->zpool_hdl, EZFS_NODEVICE, errbuf)); 5337 } 5338 5339 *vdev_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID); 5340 return (0); 5341 } 5342 5343 /* 5344 * Get a vdev property value for 'prop' and return the value in 5345 * a pre-allocated buffer. 5346 */ 5347 int 5348 zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name, 5349 char *buf, size_t len, zprop_source_t *srctype, boolean_t literal) 5350 { 5351 nvlist_t *nv; 5352 const char *strval; 5353 uint64_t intval; 5354 zprop_source_t src = ZPROP_SRC_NONE; 5355 5356 if (prop == VDEV_PROP_USERPROP) { 5357 /* user property, prop_name must contain the property name */ 5358 assert(prop_name != NULL); 5359 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) { 5360 src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 5361 strval = fnvlist_lookup_string(nv, ZPROP_VALUE); 5362 } else { 5363 /* user prop not found */ 5364 src = ZPROP_SRC_DEFAULT; 5365 strval = "-"; 5366 } 5367 (void) strlcpy(buf, strval, len); 5368 if (srctype) 5369 *srctype = src; 5370 return (0); 5371 } 5372 5373 if (prop_name == NULL) 5374 prop_name = (char *)vdev_prop_to_name(prop); 5375 5376 switch (vdev_prop_get_type(prop)) { 5377 case PROP_TYPE_STRING: 5378 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) { 5379 src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 5380 strval = fnvlist_lookup_string(nv, ZPROP_VALUE); 5381 } else { 5382 src = ZPROP_SRC_DEFAULT; 5383 if ((strval = vdev_prop_default_string(prop)) == NULL) 5384 strval = "-"; 5385 } 5386 (void) strlcpy(buf, strval, len); 5387 break; 5388 5389 case PROP_TYPE_NUMBER: 5390 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) { 5391 src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 5392 intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE); 5393 } else { 5394 src = ZPROP_SRC_DEFAULT; 5395 intval = vdev_prop_default_numeric(prop); 5396 } 5397 5398 switch (prop) { 5399 case VDEV_PROP_ASIZE: 5400 case VDEV_PROP_PSIZE: 5401 case VDEV_PROP_SIZE: 5402 case VDEV_PROP_BOOTSIZE: 5403 case VDEV_PROP_ALLOCATED: 5404 case VDEV_PROP_FREE: 5405 case VDEV_PROP_READ_ERRORS: 5406 case VDEV_PROP_WRITE_ERRORS: 5407 case VDEV_PROP_CHECKSUM_ERRORS: 5408 case VDEV_PROP_INITIALIZE_ERRORS: 5409 case VDEV_PROP_TRIM_ERRORS: 5410 case VDEV_PROP_SLOW_IOS: 5411 case VDEV_PROP_OPS_NULL: 5412 case VDEV_PROP_OPS_READ: 5413 case VDEV_PROP_OPS_WRITE: 5414 case VDEV_PROP_OPS_FREE: 5415 case VDEV_PROP_OPS_CLAIM: 5416 case VDEV_PROP_OPS_TRIM: 5417 case VDEV_PROP_BYTES_NULL: 5418 case VDEV_PROP_BYTES_READ: 5419 case VDEV_PROP_BYTES_WRITE: 5420 case VDEV_PROP_BYTES_FREE: 5421 case VDEV_PROP_BYTES_CLAIM: 5422 case VDEV_PROP_BYTES_TRIM: 5423 if (literal) { 5424 (void) snprintf(buf, len, "%llu", 5425 (u_longlong_t)intval); 5426 } else { 5427 (void) zfs_nicenum(intval, buf, len); 5428 } 5429 break; 5430 case VDEV_PROP_EXPANDSZ: 5431 if (intval == 0) { 5432 (void) strlcpy(buf, "-", len); 5433 } else if (literal) { 5434 (void) snprintf(buf, len, "%llu", 5435 (u_longlong_t)intval); 5436 } else { 5437 (void) zfs_nicenum(intval, buf, len); 5438 } 5439 break; 5440 case VDEV_PROP_CAPACITY: 5441 if (literal) { 5442 (void) snprintf(buf, len, "%llu", 5443 (u_longlong_t)intval); 5444 } else { 5445 (void) snprintf(buf, len, "%llu%%", 5446 (u_longlong_t)intval); 5447 } 5448 break; 5449 case VDEV_PROP_CHECKSUM_N: 5450 case VDEV_PROP_CHECKSUM_T: 5451 case VDEV_PROP_IO_N: 5452 case VDEV_PROP_IO_T: 5453 case VDEV_PROP_SLOW_IO_N: 5454 case VDEV_PROP_SLOW_IO_T: 5455 if (intval == UINT64_MAX) { 5456 (void) strlcpy(buf, "-", len); 5457 } else { 5458 (void) snprintf(buf, len, "%llu", 5459 (u_longlong_t)intval); 5460 } 5461 break; 5462 case VDEV_PROP_FRAGMENTATION: 5463 if (intval == UINT64_MAX) { 5464 (void) strlcpy(buf, "-", len); 5465 } else { 5466 (void) snprintf(buf, len, "%llu%%", 5467 (u_longlong_t)intval); 5468 } 5469 break; 5470 case VDEV_PROP_STATE: 5471 if (literal) { 5472 (void) snprintf(buf, len, "%llu", 5473 (u_longlong_t)intval); 5474 } else { 5475 (void) strlcpy(buf, zpool_state_to_name(intval, 5476 VDEV_AUX_NONE), len); 5477 } 5478 break; 5479 default: 5480 (void) snprintf(buf, len, "%llu", 5481 (u_longlong_t)intval); 5482 } 5483 break; 5484 5485 case PROP_TYPE_INDEX: 5486 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) { 5487 src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE); 5488 intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE); 5489 } else { 5490 /* 'trim_support' only valid for leaf vdevs */ 5491 if (prop == VDEV_PROP_TRIM_SUPPORT) { 5492 (void) strlcpy(buf, "-", len); 5493 break; 5494 } 5495 src = ZPROP_SRC_DEFAULT; 5496 intval = vdev_prop_default_numeric(prop); 5497 /* Only use if provided by the RAIDZ VDEV above */ 5498 if (prop == VDEV_PROP_RAIDZ_EXPANDING) 5499 return (ENOENT); 5500 } 5501 if (vdev_prop_index_to_string(prop, intval, 5502 (const char **)&strval) != 0) 5503 return (-1); 5504 (void) strlcpy(buf, strval, len); 5505 break; 5506 5507 default: 5508 abort(); 5509 } 5510 5511 if (srctype) 5512 *srctype = src; 5513 5514 return (0); 5515 } 5516 5517 /* 5518 * Get a vdev property value for 'prop_name' and return the value in 5519 * a pre-allocated buffer. 5520 */ 5521 int 5522 zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop, 5523 char *prop_name, char *buf, size_t len, zprop_source_t *srctype, 5524 boolean_t literal) 5525 { 5526 nvlist_t *reqnvl, *reqprops; 5527 nvlist_t *retprops = NULL; 5528 uint64_t vdev_guid = 0; 5529 int ret; 5530 5531 if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0) 5532 return (ret); 5533 5534 if (nvlist_alloc(&reqnvl, NV_UNIQUE_NAME, 0) != 0) 5535 return (no_memory(zhp->zpool_hdl)); 5536 if (nvlist_alloc(&reqprops, NV_UNIQUE_NAME, 0) != 0) 5537 return (no_memory(zhp->zpool_hdl)); 5538 5539 fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid); 5540 5541 if (prop != VDEV_PROP_USERPROP) { 5542 /* prop_name overrides prop value */ 5543 if (prop_name != NULL) 5544 prop = vdev_name_to_prop(prop_name); 5545 else 5546 prop_name = (char *)vdev_prop_to_name(prop); 5547 assert(prop < VDEV_NUM_PROPS); 5548 } 5549 5550 assert(prop_name != NULL); 5551 if (nvlist_add_uint64(reqprops, prop_name, prop) != 0) { 5552 nvlist_free(reqnvl); 5553 nvlist_free(reqprops); 5554 return (no_memory(zhp->zpool_hdl)); 5555 } 5556 5557 fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_PROPS_GET_PROPS, reqprops); 5558 5559 ret = lzc_get_vdev_prop(zhp->zpool_name, reqnvl, &retprops); 5560 5561 if (ret == 0) { 5562 ret = zpool_get_vdev_prop_value(retprops, prop, prop_name, buf, 5563 len, srctype, literal); 5564 } else { 5565 char errbuf[ERRBUFLEN]; 5566 (void) snprintf(errbuf, sizeof (errbuf), 5567 dgettext(TEXT_DOMAIN, "cannot get vdev property %s from" 5568 " %s in %s"), prop_name, vdevname, zhp->zpool_name); 5569 (void) zpool_standard_error(zhp->zpool_hdl, ret, errbuf); 5570 } 5571 5572 nvlist_free(reqnvl); 5573 nvlist_free(reqprops); 5574 nvlist_free(retprops); 5575 5576 return (ret); 5577 } 5578 5579 /* 5580 * Get all vdev properties 5581 */ 5582 int 5583 zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname, 5584 nvlist_t **outnvl) 5585 { 5586 nvlist_t *nvl = NULL; 5587 uint64_t vdev_guid = 0; 5588 int ret; 5589 5590 if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0) 5591 return (ret); 5592 5593 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 5594 return (no_memory(zhp->zpool_hdl)); 5595 5596 fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid); 5597 5598 ret = lzc_get_vdev_prop(zhp->zpool_name, nvl, outnvl); 5599 5600 nvlist_free(nvl); 5601 5602 if (ret) { 5603 char errbuf[ERRBUFLEN]; 5604 (void) snprintf(errbuf, sizeof (errbuf), 5605 dgettext(TEXT_DOMAIN, "cannot get vdev properties for" 5606 " %s in %s"), vdevname, zhp->zpool_name); 5607 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf); 5608 } 5609 5610 return (ret); 5611 } 5612 5613 /* 5614 * Set vdev property 5615 */ 5616 int 5617 zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname, 5618 const char *propname, const char *propval) 5619 { 5620 int ret; 5621 nvlist_t *nvl = NULL; 5622 nvlist_t *outnvl = NULL; 5623 nvlist_t *props; 5624 nvlist_t *realprops; 5625 prop_flags_t flags = { 0 }; 5626 uint64_t version; 5627 uint64_t vdev_guid; 5628 5629 if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0) 5630 return (ret); 5631 5632 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 5633 return (no_memory(zhp->zpool_hdl)); 5634 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) 5635 return (no_memory(zhp->zpool_hdl)); 5636 5637 fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_SET_VDEV, vdev_guid); 5638 5639 if (nvlist_add_string(props, propname, propval) != 0) { 5640 nvlist_free(props); 5641 return (no_memory(zhp->zpool_hdl)); 5642 } 5643 5644 char errbuf[ERRBUFLEN]; 5645 (void) snprintf(errbuf, sizeof (errbuf), 5646 dgettext(TEXT_DOMAIN, "cannot set property %s for %s on %s"), 5647 propname, vdevname, zhp->zpool_name); 5648 5649 flags.vdevprop = 1; 5650 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 5651 if ((realprops = zpool_valid_proplist(zhp->zpool_hdl, 5652 zhp->zpool_name, props, version, flags, errbuf)) == NULL) { 5653 nvlist_free(props); 5654 nvlist_free(nvl); 5655 return (-1); 5656 } 5657 5658 nvlist_free(props); 5659 props = realprops; 5660 5661 fnvlist_add_nvlist(nvl, ZPOOL_VDEV_PROPS_SET_PROPS, props); 5662 5663 ret = lzc_set_vdev_prop(zhp->zpool_name, nvl, &outnvl); 5664 5665 nvlist_free(props); 5666 nvlist_free(nvl); 5667 nvlist_free(outnvl); 5668 5669 if (ret) 5670 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf); 5671 5672 return (ret); 5673 } 5674 5675 /* 5676 * Prune older entries from the DDT to reclaim space under the quota 5677 */ 5678 int 5679 zpool_ddt_prune(zpool_handle_t *zhp, zpool_ddt_prune_unit_t unit, 5680 uint64_t amount) 5681 { 5682 int error = lzc_ddt_prune(zhp->zpool_name, unit, amount); 5683 if (error != 0) { 5684 libzfs_handle_t *hdl = zhp->zpool_hdl; 5685 char errbuf[ERRBUFLEN]; 5686 5687 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 5688 "cannot prune dedup table on '%s'"), zhp->zpool_name); 5689 5690 if (error == EALREADY) { 5691 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 5692 "a prune operation is already in progress")); 5693 (void) zfs_error(hdl, EZFS_BUSY, errbuf); 5694 } else { 5695 (void) zpool_standard_error(hdl, errno, errbuf); 5696 } 5697 return (-1); 5698 } 5699 5700 return (0); 5701 } 5702