libzfs_pool.c revision 207670
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#include <sys/types.h> 28#include <sys/stat.h> 29#include <assert.h> 30#include <ctype.h> 31#include <errno.h> 32#include <devid.h> 33#include <dirent.h> 34#include <fcntl.h> 35#include <libintl.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <strings.h> 39#include <unistd.h> 40#include <zone.h> 41#include <sys/zfs_ioctl.h> 42#include <sys/zio.h> 43#include <strings.h> 44#include <umem.h> 45 46#include "zfs_namecheck.h" 47#include "zfs_prop.h" 48#include "libzfs_impl.h" 49 50static int read_efi_label(nvlist_t *config, diskaddr_t *sb); 51 52/* 53 * ==================================================================== 54 * zpool property functions 55 * ==================================================================== 56 */ 57 58static int 59zpool_get_all_props(zpool_handle_t *zhp) 60{ 61 zfs_cmd_t zc = { 0 }; 62 libzfs_handle_t *hdl = zhp->zpool_hdl; 63 64 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 65 66 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) 67 return (-1); 68 69 while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) { 70 if (errno == ENOMEM) { 71 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) { 72 zcmd_free_nvlists(&zc); 73 return (-1); 74 } 75 } else { 76 zcmd_free_nvlists(&zc); 77 return (-1); 78 } 79 } 80 81 if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) { 82 zcmd_free_nvlists(&zc); 83 return (-1); 84 } 85 86 zcmd_free_nvlists(&zc); 87 88 return (0); 89} 90 91static int 92zpool_props_refresh(zpool_handle_t *zhp) 93{ 94 nvlist_t *old_props; 95 96 old_props = zhp->zpool_props; 97 98 if (zpool_get_all_props(zhp) != 0) 99 return (-1); 100 101 nvlist_free(old_props); 102 return (0); 103} 104 105static char * 106zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop, 107 zprop_source_t *src) 108{ 109 nvlist_t *nv, *nvl; 110 uint64_t ival; 111 char *value; 112 zprop_source_t source; 113 114 nvl = zhp->zpool_props; 115 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) { 116 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0); 117 source = ival; 118 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0); 119 } else { 120 source = ZPROP_SRC_DEFAULT; 121 if ((value = (char *)zpool_prop_default_string(prop)) == NULL) 122 value = "-"; 123 } 124 125 if (src) 126 *src = source; 127 128 return (value); 129} 130 131uint64_t 132zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src) 133{ 134 nvlist_t *nv, *nvl; 135 uint64_t value; 136 zprop_source_t source; 137 138 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) { 139 /* 140 * zpool_get_all_props() has most likely failed because 141 * the pool is faulted, but if all we need is the top level 142 * vdev's guid then get it from the zhp config nvlist. 143 */ 144 if ((prop == ZPOOL_PROP_GUID) && 145 (nvlist_lookup_nvlist(zhp->zpool_config, 146 ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) && 147 (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value) 148 == 0)) { 149 return (value); 150 } 151 return (zpool_prop_default_numeric(prop)); 152 } 153 154 nvl = zhp->zpool_props; 155 if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) { 156 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0); 157 source = value; 158 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0); 159 } else { 160 source = ZPROP_SRC_DEFAULT; 161 value = zpool_prop_default_numeric(prop); 162 } 163 164 if (src) 165 *src = source; 166 167 return (value); 168} 169 170/* 171 * Map VDEV STATE to printed strings. 172 */ 173char * 174zpool_state_to_name(vdev_state_t state, vdev_aux_t aux) 175{ 176 switch (state) { 177 case VDEV_STATE_CLOSED: 178 case VDEV_STATE_OFFLINE: 179 return (gettext("OFFLINE")); 180 case VDEV_STATE_REMOVED: 181 return (gettext("REMOVED")); 182 case VDEV_STATE_CANT_OPEN: 183 if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG) 184 return (gettext("FAULTED")); 185 else 186 return (gettext("UNAVAIL")); 187 case VDEV_STATE_FAULTED: 188 return (gettext("FAULTED")); 189 case VDEV_STATE_DEGRADED: 190 return (gettext("DEGRADED")); 191 case VDEV_STATE_HEALTHY: 192 return (gettext("ONLINE")); 193 } 194 195 return (gettext("UNKNOWN")); 196} 197 198/* 199 * Get a zpool property value for 'prop' and return the value in 200 * a pre-allocated buffer. 201 */ 202int 203zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, 204 zprop_source_t *srctype) 205{ 206 uint64_t intval; 207 const char *strval; 208 zprop_source_t src = ZPROP_SRC_NONE; 209 nvlist_t *nvroot; 210 vdev_stat_t *vs; 211 uint_t vsc; 212 213 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 214 if (prop == ZPOOL_PROP_NAME) 215 (void) strlcpy(buf, zpool_get_name(zhp), len); 216 else if (prop == ZPOOL_PROP_HEALTH) 217 (void) strlcpy(buf, "FAULTED", len); 218 else 219 (void) strlcpy(buf, "-", len); 220 return (0); 221 } 222 223 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) && 224 prop != ZPOOL_PROP_NAME) 225 return (-1); 226 227 switch (zpool_prop_get_type(prop)) { 228 case PROP_TYPE_STRING: 229 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src), 230 len); 231 break; 232 233 case PROP_TYPE_NUMBER: 234 intval = zpool_get_prop_int(zhp, prop, &src); 235 236 switch (prop) { 237 case ZPOOL_PROP_SIZE: 238 case ZPOOL_PROP_USED: 239 case ZPOOL_PROP_AVAILABLE: 240 (void) zfs_nicenum(intval, buf, len); 241 break; 242 243 case ZPOOL_PROP_CAPACITY: 244 (void) snprintf(buf, len, "%llu%%", 245 (u_longlong_t)intval); 246 break; 247 248 case ZPOOL_PROP_HEALTH: 249 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 250 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); 251 verify(nvlist_lookup_uint64_array(nvroot, 252 ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0); 253 254 (void) strlcpy(buf, zpool_state_to_name(intval, 255 vs->vs_aux), len); 256 break; 257 default: 258 (void) snprintf(buf, len, "%llu", intval); 259 } 260 break; 261 262 case PROP_TYPE_INDEX: 263 intval = zpool_get_prop_int(zhp, prop, &src); 264 if (zpool_prop_index_to_string(prop, intval, &strval) 265 != 0) 266 return (-1); 267 (void) strlcpy(buf, strval, len); 268 break; 269 270 default: 271 abort(); 272 } 273 274 if (srctype) 275 *srctype = src; 276 277 return (0); 278} 279 280/* 281 * Check if the bootfs name has the same pool name as it is set to. 282 * Assuming bootfs is a valid dataset name. 283 */ 284static boolean_t 285bootfs_name_valid(const char *pool, char *bootfs) 286{ 287 int len = strlen(pool); 288 289 if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT)) 290 return (B_FALSE); 291 292 if (strncmp(pool, bootfs, len) == 0 && 293 (bootfs[len] == '/' || bootfs[len] == '\0')) 294 return (B_TRUE); 295 296 return (B_FALSE); 297} 298 299#if defined(sun) 300/* 301 * Inspect the configuration to determine if any of the devices contain 302 * an EFI label. 303 */ 304static boolean_t 305pool_uses_efi(nvlist_t *config) 306{ 307 nvlist_t **child; 308 uint_t c, children; 309 310 if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, 311 &child, &children) != 0) 312 return (read_efi_label(config, NULL) >= 0); 313 314 for (c = 0; c < children; c++) { 315 if (pool_uses_efi(child[c])) 316 return (B_TRUE); 317 } 318 return (B_FALSE); 319} 320#endif 321 322/* 323 * Given an nvlist of zpool properties to be set, validate that they are 324 * correct, and parse any numeric properties (index, boolean, etc) if they are 325 * specified as strings. 326 */ 327static nvlist_t * 328zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, 329 nvlist_t *props, uint64_t version, boolean_t create_or_import, char *errbuf) 330{ 331 nvpair_t *elem; 332 nvlist_t *retprops; 333 zpool_prop_t prop; 334 char *strval; 335 uint64_t intval; 336 char *slash; 337 struct stat64 statbuf; 338 zpool_handle_t *zhp; 339 nvlist_t *nvroot; 340 341 if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) { 342 (void) no_memory(hdl); 343 return (NULL); 344 } 345 346 elem = NULL; 347 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 348 const char *propname = nvpair_name(elem); 349 350 /* 351 * Make sure this property is valid and applies to this type. 352 */ 353 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { 354 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 355 "invalid property '%s'"), propname); 356 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 357 goto error; 358 } 359 360 if (zpool_prop_readonly(prop)) { 361 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' " 362 "is readonly"), propname); 363 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf); 364 goto error; 365 } 366 367 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops, 368 &strval, &intval, errbuf) != 0) 369 goto error; 370 371 /* 372 * Perform additional checking for specific properties. 373 */ 374 switch (prop) { 375 case ZPOOL_PROP_VERSION: 376 if (intval < version || intval > SPA_VERSION) { 377 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 378 "property '%s' number %d is invalid."), 379 propname, intval); 380 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 381 goto error; 382 } 383 break; 384 385 case ZPOOL_PROP_BOOTFS: 386 if (create_or_import) { 387 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 388 "property '%s' cannot be set at creation " 389 "or import time"), propname); 390 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 391 goto error; 392 } 393 394 if (version < SPA_VERSION_BOOTFS) { 395 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 396 "pool must be upgraded to support " 397 "'%s' property"), propname); 398 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); 399 goto error; 400 } 401 402 /* 403 * bootfs property value has to be a dataset name and 404 * the dataset has to be in the same pool as it sets to. 405 */ 406 if (strval[0] != '\0' && !bootfs_name_valid(poolname, 407 strval)) { 408 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' " 409 "is an invalid name"), strval); 410 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 411 goto error; 412 } 413 414 if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) { 415 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 416 "could not open pool '%s'"), poolname); 417 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf); 418 goto error; 419 } 420 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 421 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); 422 423#if defined(sun) 424 /* 425 * bootfs property cannot be set on a disk which has 426 * been EFI labeled. 427 */ 428 if (pool_uses_efi(nvroot)) { 429 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 430 "property '%s' not supported on " 431 "EFI labeled devices"), propname); 432 (void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf); 433 zpool_close(zhp); 434 goto error; 435 } 436#endif 437 zpool_close(zhp); 438 break; 439 440 case ZPOOL_PROP_ALTROOT: 441 if (!create_or_import) { 442 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 443 "property '%s' can only be set during pool " 444 "creation or import"), propname); 445 (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 446 goto error; 447 } 448 449 if (strval[0] != '/') { 450 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 451 "bad alternate root '%s'"), strval); 452 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 453 goto error; 454 } 455 break; 456 457 case ZPOOL_PROP_CACHEFILE: 458 if (strval[0] == '\0') 459 break; 460 461 if (strcmp(strval, "none") == 0) 462 break; 463 464 if (strval[0] != '/') { 465 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 466 "property '%s' must be empty, an " 467 "absolute path, or 'none'"), propname); 468 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 469 goto error; 470 } 471 472 slash = strrchr(strval, '/'); 473 474 if (slash[1] == '\0' || strcmp(slash, "/.") == 0 || 475 strcmp(slash, "/..") == 0) { 476 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 477 "'%s' is not a valid file"), strval); 478 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 479 goto error; 480 } 481 482 *slash = '\0'; 483 484 if (strval[0] != '\0' && 485 (stat64(strval, &statbuf) != 0 || 486 !S_ISDIR(statbuf.st_mode))) { 487 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 488 "'%s' is not a valid directory"), 489 strval); 490 (void) zfs_error(hdl, EZFS_BADPATH, errbuf); 491 goto error; 492 } 493 494 *slash = '/'; 495 break; 496 } 497 } 498 499 return (retprops); 500error: 501 nvlist_free(retprops); 502 return (NULL); 503} 504 505/* 506 * Set zpool property : propname=propval. 507 */ 508int 509zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval) 510{ 511 zfs_cmd_t zc = { 0 }; 512 int ret = -1; 513 char errbuf[1024]; 514 nvlist_t *nvl = NULL; 515 nvlist_t *realprops; 516 uint64_t version; 517 518 (void) snprintf(errbuf, sizeof (errbuf), 519 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"), 520 zhp->zpool_name); 521 522 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) 523 return (zfs_error(zhp->zpool_hdl, EZFS_POOLPROPS, errbuf)); 524 525 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) 526 return (no_memory(zhp->zpool_hdl)); 527 528 if (nvlist_add_string(nvl, propname, propval) != 0) { 529 nvlist_free(nvl); 530 return (no_memory(zhp->zpool_hdl)); 531 } 532 533 version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 534 if ((realprops = zpool_valid_proplist(zhp->zpool_hdl, 535 zhp->zpool_name, nvl, version, B_FALSE, errbuf)) == NULL) { 536 nvlist_free(nvl); 537 return (-1); 538 } 539 540 nvlist_free(nvl); 541 nvl = realprops; 542 543 /* 544 * Execute the corresponding ioctl() to set this property. 545 */ 546 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 547 548 if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) { 549 nvlist_free(nvl); 550 return (-1); 551 } 552 553 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc); 554 555 zcmd_free_nvlists(&zc); 556 nvlist_free(nvl); 557 558 if (ret) 559 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf); 560 else 561 (void) zpool_props_refresh(zhp); 562 563 return (ret); 564} 565 566int 567zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp) 568{ 569 libzfs_handle_t *hdl = zhp->zpool_hdl; 570 zprop_list_t *entry; 571 char buf[ZFS_MAXPROPLEN]; 572 573 if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0) 574 return (-1); 575 576 for (entry = *plp; entry != NULL; entry = entry->pl_next) { 577 578 if (entry->pl_fixed) 579 continue; 580 581 if (entry->pl_prop != ZPROP_INVAL && 582 zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf), 583 NULL) == 0) { 584 if (strlen(buf) > entry->pl_width) 585 entry->pl_width = strlen(buf); 586 } 587 } 588 589 return (0); 590} 591 592 593/* 594 * Validate the given pool name, optionally putting an extended error message in 595 * 'buf'. 596 */ 597boolean_t 598zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool) 599{ 600 namecheck_err_t why; 601 char what; 602 int ret; 603 604 ret = pool_namecheck(pool, &why, &what); 605 606 /* 607 * The rules for reserved pool names were extended at a later point. 608 * But we need to support users with existing pools that may now be 609 * invalid. So we only check for this expanded set of names during a 610 * create (or import), and only in userland. 611 */ 612 if (ret == 0 && !isopen && 613 (strncmp(pool, "mirror", 6) == 0 || 614 strncmp(pool, "raidz", 5) == 0 || 615 strncmp(pool, "spare", 5) == 0 || 616 strcmp(pool, "log") == 0)) { 617 if (hdl != NULL) 618 zfs_error_aux(hdl, 619 dgettext(TEXT_DOMAIN, "name is reserved")); 620 return (B_FALSE); 621 } 622 623 624 if (ret != 0) { 625 if (hdl != NULL) { 626 switch (why) { 627 case NAME_ERR_TOOLONG: 628 zfs_error_aux(hdl, 629 dgettext(TEXT_DOMAIN, "name is too long")); 630 break; 631 632 case NAME_ERR_INVALCHAR: 633 zfs_error_aux(hdl, 634 dgettext(TEXT_DOMAIN, "invalid character " 635 "'%c' in pool name"), what); 636 break; 637 638 case NAME_ERR_NOLETTER: 639 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 640 "name must begin with a letter")); 641 break; 642 643 case NAME_ERR_RESERVED: 644 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 645 "name is reserved")); 646 break; 647 648 case NAME_ERR_DISKLIKE: 649 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 650 "pool name is reserved")); 651 break; 652 653 case NAME_ERR_LEADING_SLASH: 654 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 655 "leading slash in name")); 656 break; 657 658 case NAME_ERR_EMPTY_COMPONENT: 659 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 660 "empty component in name")); 661 break; 662 663 case NAME_ERR_TRAILING_SLASH: 664 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 665 "trailing slash in name")); 666 break; 667 668 case NAME_ERR_MULTIPLE_AT: 669 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 670 "multiple '@' delimiters in name")); 671 break; 672 673 } 674 } 675 return (B_FALSE); 676 } 677 678 return (B_TRUE); 679} 680 681/* 682 * Open a handle to the given pool, even if the pool is currently in the FAULTED 683 * state. 684 */ 685zpool_handle_t * 686zpool_open_canfail(libzfs_handle_t *hdl, const char *pool) 687{ 688 zpool_handle_t *zhp; 689 boolean_t missing; 690 691 /* 692 * Make sure the pool name is valid. 693 */ 694 if (!zpool_name_valid(hdl, B_TRUE, pool)) { 695 (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME, 696 dgettext(TEXT_DOMAIN, "cannot open '%s'"), 697 pool); 698 return (NULL); 699 } 700 701 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL) 702 return (NULL); 703 704 zhp->zpool_hdl = hdl; 705 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 706 707 if (zpool_refresh_stats(zhp, &missing) != 0) { 708 zpool_close(zhp); 709 return (NULL); 710 } 711 712 if (missing) { 713 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool")); 714 (void) zfs_error_fmt(hdl, EZFS_NOENT, 715 dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool); 716 zpool_close(zhp); 717 return (NULL); 718 } 719 720 return (zhp); 721} 722 723/* 724 * Like the above, but silent on error. Used when iterating over pools (because 725 * the configuration cache may be out of date). 726 */ 727int 728zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret) 729{ 730 zpool_handle_t *zhp; 731 boolean_t missing; 732 733 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL) 734 return (-1); 735 736 zhp->zpool_hdl = hdl; 737 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 738 739 if (zpool_refresh_stats(zhp, &missing) != 0) { 740 zpool_close(zhp); 741 return (-1); 742 } 743 744 if (missing) { 745 zpool_close(zhp); 746 *ret = NULL; 747 return (0); 748 } 749 750 *ret = zhp; 751 return (0); 752} 753 754/* 755 * Similar to zpool_open_canfail(), but refuses to open pools in the faulted 756 * state. 757 */ 758zpool_handle_t * 759zpool_open(libzfs_handle_t *hdl, const char *pool) 760{ 761 zpool_handle_t *zhp; 762 763 if ((zhp = zpool_open_canfail(hdl, pool)) == NULL) 764 return (NULL); 765 766 if (zhp->zpool_state == POOL_STATE_UNAVAIL) { 767 (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL, 768 dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name); 769 zpool_close(zhp); 770 return (NULL); 771 } 772 773 return (zhp); 774} 775 776/* 777 * Close the handle. Simply frees the memory associated with the handle. 778 */ 779void 780zpool_close(zpool_handle_t *zhp) 781{ 782 if (zhp->zpool_config) 783 nvlist_free(zhp->zpool_config); 784 if (zhp->zpool_old_config) 785 nvlist_free(zhp->zpool_old_config); 786 if (zhp->zpool_props) 787 nvlist_free(zhp->zpool_props); 788 free(zhp); 789} 790 791/* 792 * Return the name of the pool. 793 */ 794const char * 795zpool_get_name(zpool_handle_t *zhp) 796{ 797 return (zhp->zpool_name); 798} 799 800 801/* 802 * Return the state of the pool (ACTIVE or UNAVAILABLE) 803 */ 804int 805zpool_get_state(zpool_handle_t *zhp) 806{ 807 return (zhp->zpool_state); 808} 809 810/* 811 * Create the named pool, using the provided vdev list. It is assumed 812 * that the consumer has already validated the contents of the nvlist, so we 813 * don't have to worry about error semantics. 814 */ 815int 816zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, 817 nvlist_t *props, nvlist_t *fsprops) 818{ 819 zfs_cmd_t zc = { 0 }; 820 nvlist_t *zc_fsprops = NULL; 821 nvlist_t *zc_props = NULL; 822 char msg[1024]; 823 char *altroot; 824 int ret = -1; 825 826 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 827 "cannot create '%s'"), pool); 828 829 if (!zpool_name_valid(hdl, B_FALSE, pool)) 830 return (zfs_error(hdl, EZFS_INVALIDNAME, msg)); 831 832 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) 833 return (-1); 834 835 if (props) { 836 if ((zc_props = zpool_valid_proplist(hdl, pool, props, 837 SPA_VERSION_1, B_TRUE, msg)) == NULL) { 838 goto create_failed; 839 } 840 } 841 842 if (fsprops) { 843 uint64_t zoned; 844 char *zonestr; 845 846 zoned = ((nvlist_lookup_string(fsprops, 847 zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) && 848 strcmp(zonestr, "on") == 0); 849 850 if ((zc_fsprops = zfs_valid_proplist(hdl, 851 ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) { 852 goto create_failed; 853 } 854 if (!zc_props && 855 (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) { 856 goto create_failed; 857 } 858 if (nvlist_add_nvlist(zc_props, 859 ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) { 860 goto create_failed; 861 } 862 } 863 864 if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0) 865 goto create_failed; 866 867 (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); 868 869 if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) { 870 871 zcmd_free_nvlists(&zc); 872 nvlist_free(zc_props); 873 nvlist_free(zc_fsprops); 874 875 switch (errno) { 876 case EBUSY: 877 /* 878 * This can happen if the user has specified the same 879 * device multiple times. We can't reliably detect this 880 * until we try to add it and see we already have a 881 * label. 882 */ 883 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 884 "one or more vdevs refer to the same device")); 885 return (zfs_error(hdl, EZFS_BADDEV, msg)); 886 887 case EOVERFLOW: 888 /* 889 * This occurs when one of the devices is below 890 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 891 * device was the problem device since there's no 892 * reliable way to determine device size from userland. 893 */ 894 { 895 char buf[64]; 896 897 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 898 899 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 900 "one or more devices is less than the " 901 "minimum size (%s)"), buf); 902 } 903 return (zfs_error(hdl, EZFS_BADDEV, msg)); 904 905 case ENOSPC: 906 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 907 "one or more devices is out of space")); 908 return (zfs_error(hdl, EZFS_BADDEV, msg)); 909 910 case ENOTBLK: 911 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 912 "cache device must be a disk or disk slice")); 913 return (zfs_error(hdl, EZFS_BADDEV, msg)); 914 915 default: 916 return (zpool_standard_error(hdl, errno, msg)); 917 } 918 } 919 920 /* 921 * If this is an alternate root pool, then we automatically set the 922 * mountpoint of the root dataset to be '/'. 923 */ 924 if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT), 925 &altroot) == 0) { 926 zfs_handle_t *zhp; 927 928 verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL); 929 verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 930 "/") == 0); 931 932 zfs_close(zhp); 933 } 934 935create_failed: 936 zcmd_free_nvlists(&zc); 937 nvlist_free(zc_props); 938 nvlist_free(zc_fsprops); 939 return (ret); 940} 941 942/* 943 * Destroy the given pool. It is up to the caller to ensure that there are no 944 * datasets left in the pool. 945 */ 946int 947zpool_destroy(zpool_handle_t *zhp) 948{ 949 zfs_cmd_t zc = { 0 }; 950 zfs_handle_t *zfp = NULL; 951 libzfs_handle_t *hdl = zhp->zpool_hdl; 952 char msg[1024]; 953 954 if (zhp->zpool_state == POOL_STATE_ACTIVE && 955 (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name, 956 ZFS_TYPE_FILESYSTEM)) == NULL) 957 return (-1); 958 959 if (zpool_remove_zvol_links(zhp) != 0) 960 return (-1); 961 962 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 963 964 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) { 965 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 966 "cannot destroy '%s'"), zhp->zpool_name); 967 968 if (errno == EROFS) { 969 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 970 "one or more devices is read only")); 971 (void) zfs_error(hdl, EZFS_BADDEV, msg); 972 } else { 973 (void) zpool_standard_error(hdl, errno, msg); 974 } 975 976 if (zfp) 977 zfs_close(zfp); 978 return (-1); 979 } 980 981 if (zfp) { 982 remove_mountpoint(zfp); 983 zfs_close(zfp); 984 } 985 986 return (0); 987} 988 989/* 990 * Add the given vdevs to the pool. The caller must have already performed the 991 * necessary verification to ensure that the vdev specification is well-formed. 992 */ 993int 994zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) 995{ 996 zfs_cmd_t zc = { 0 }; 997 int ret; 998 libzfs_handle_t *hdl = zhp->zpool_hdl; 999 char msg[1024]; 1000 nvlist_t **spares, **l2cache; 1001 uint_t nspares, nl2cache; 1002 1003 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1004 "cannot add to '%s'"), zhp->zpool_name); 1005 1006 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) < 1007 SPA_VERSION_SPARES && 1008 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 1009 &spares, &nspares) == 0) { 1010 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be " 1011 "upgraded to add hot spares")); 1012 return (zfs_error(hdl, EZFS_BADVERSION, msg)); 1013 } 1014 1015 if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) < 1016 SPA_VERSION_L2CACHE && 1017 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 1018 &l2cache, &nl2cache) == 0) { 1019 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be " 1020 "upgraded to add cache devices")); 1021 return (zfs_error(hdl, EZFS_BADVERSION, msg)); 1022 } 1023 1024 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) 1025 return (-1); 1026 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1027 1028 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) { 1029 switch (errno) { 1030 case EBUSY: 1031 /* 1032 * This can happen if the user has specified the same 1033 * device multiple times. We can't reliably detect this 1034 * until we try to add it and see we already have a 1035 * label. 1036 */ 1037 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1038 "one or more vdevs refer to the same device")); 1039 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1040 break; 1041 1042 case EOVERFLOW: 1043 /* 1044 * This occurrs when one of the devices is below 1045 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 1046 * device was the problem device since there's no 1047 * reliable way to determine device size from userland. 1048 */ 1049 { 1050 char buf[64]; 1051 1052 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 1053 1054 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1055 "device is less than the minimum " 1056 "size (%s)"), buf); 1057 } 1058 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1059 break; 1060 1061 case ENOTSUP: 1062 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1063 "pool must be upgraded to add these vdevs")); 1064 (void) zfs_error(hdl, EZFS_BADVERSION, msg); 1065 break; 1066 1067 case EDOM: 1068 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1069 "root pool can not have multiple vdevs" 1070 " or separate logs")); 1071 (void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg); 1072 break; 1073 1074 case ENOTBLK: 1075 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1076 "cache device must be a disk or disk slice")); 1077 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1078 break; 1079 1080 default: 1081 (void) zpool_standard_error(hdl, errno, msg); 1082 } 1083 1084 ret = -1; 1085 } else { 1086 ret = 0; 1087 } 1088 1089 zcmd_free_nvlists(&zc); 1090 1091 return (ret); 1092} 1093 1094/* 1095 * Exports the pool from the system. The caller must ensure that there are no 1096 * mounted datasets in the pool. 1097 */ 1098int 1099zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce) 1100{ 1101 zfs_cmd_t zc = { 0 }; 1102 char msg[1024]; 1103 1104 if (zpool_remove_zvol_links(zhp) != 0) 1105 return (-1); 1106 1107 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1108 "cannot export '%s'"), zhp->zpool_name); 1109 1110 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1111 zc.zc_cookie = force; 1112 zc.zc_guid = hardforce; 1113 1114 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) { 1115 switch (errno) { 1116 case EXDEV: 1117 zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN, 1118 "use '-f' to override the following errors:\n" 1119 "'%s' has an active shared spare which could be" 1120 " used by other pools once '%s' is exported."), 1121 zhp->zpool_name, zhp->zpool_name); 1122 return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE, 1123 msg)); 1124 default: 1125 return (zpool_standard_error_fmt(zhp->zpool_hdl, errno, 1126 msg)); 1127 } 1128 } 1129 1130 return (0); 1131} 1132 1133int 1134zpool_export(zpool_handle_t *zhp, boolean_t force) 1135{ 1136 return (zpool_export_common(zhp, force, B_FALSE)); 1137} 1138 1139int 1140zpool_export_force(zpool_handle_t *zhp) 1141{ 1142 return (zpool_export_common(zhp, B_TRUE, B_TRUE)); 1143} 1144 1145/* 1146 * zpool_import() is a contracted interface. Should be kept the same 1147 * if possible. 1148 * 1149 * Applications should use zpool_import_props() to import a pool with 1150 * new properties value to be set. 1151 */ 1152int 1153zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, 1154 char *altroot) 1155{ 1156 nvlist_t *props = NULL; 1157 int ret; 1158 1159 if (altroot != NULL) { 1160 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { 1161 return (zfs_error_fmt(hdl, EZFS_NOMEM, 1162 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 1163 newname)); 1164 } 1165 1166 if (nvlist_add_string(props, 1167 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0) { 1168 nvlist_free(props); 1169 return (zfs_error_fmt(hdl, EZFS_NOMEM, 1170 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 1171 newname)); 1172 } 1173 } 1174 1175 ret = zpool_import_props(hdl, config, newname, props, B_FALSE); 1176 if (props) 1177 nvlist_free(props); 1178 return (ret); 1179} 1180 1181/* 1182 * Import the given pool using the known configuration and a list of 1183 * properties to be set. The configuration should have come from 1184 * zpool_find_import(). The 'newname' parameters control whether the pool 1185 * is imported with a different name. 1186 */ 1187int 1188zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, 1189 nvlist_t *props, boolean_t importfaulted) 1190{ 1191 zfs_cmd_t zc = { 0 }; 1192 char *thename; 1193 char *origname; 1194 int ret; 1195 char errbuf[1024]; 1196 1197 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1198 &origname) == 0); 1199 1200 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 1201 "cannot import pool '%s'"), origname); 1202 1203 if (newname != NULL) { 1204 if (!zpool_name_valid(hdl, B_FALSE, newname)) 1205 return (zfs_error_fmt(hdl, EZFS_INVALIDNAME, 1206 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 1207 newname)); 1208 thename = (char *)newname; 1209 } else { 1210 thename = origname; 1211 } 1212 1213 if (props) { 1214 uint64_t version; 1215 1216 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 1217 &version) == 0); 1218 1219 if ((props = zpool_valid_proplist(hdl, origname, 1220 props, version, B_TRUE, errbuf)) == NULL) { 1221 return (-1); 1222 } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) { 1223 nvlist_free(props); 1224 return (-1); 1225 } 1226 } 1227 1228 (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); 1229 1230 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 1231 &zc.zc_guid) == 0); 1232 1233 if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) { 1234 nvlist_free(props); 1235 return (-1); 1236 } 1237 1238 zc.zc_cookie = (uint64_t)importfaulted; 1239 ret = 0; 1240 if (zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc) != 0) { 1241 char desc[1024]; 1242 if (newname == NULL) 1243 (void) snprintf(desc, sizeof (desc), 1244 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 1245 thename); 1246 else 1247 (void) snprintf(desc, sizeof (desc), 1248 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), 1249 origname, thename); 1250 1251 switch (errno) { 1252 case ENOTSUP: 1253 /* 1254 * Unsupported version. 1255 */ 1256 (void) zfs_error(hdl, EZFS_BADVERSION, desc); 1257 break; 1258 1259 case EINVAL: 1260 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc); 1261 break; 1262 1263 default: 1264 (void) zpool_standard_error(hdl, errno, desc); 1265 } 1266 1267 ret = -1; 1268 } else { 1269 zpool_handle_t *zhp; 1270 1271 /* 1272 * This should never fail, but play it safe anyway. 1273 */ 1274 if (zpool_open_silent(hdl, thename, &zhp) != 0) { 1275 ret = -1; 1276 } else if (zhp != NULL) { 1277 ret = zpool_create_zvol_links(zhp); 1278 zpool_close(zhp); 1279 } 1280 1281 } 1282 1283 zcmd_free_nvlists(&zc); 1284 nvlist_free(props); 1285 1286 return (ret); 1287} 1288 1289/* 1290 * Scrub the pool. 1291 */ 1292int 1293zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type) 1294{ 1295 zfs_cmd_t zc = { 0 }; 1296 char msg[1024]; 1297 libzfs_handle_t *hdl = zhp->zpool_hdl; 1298 1299 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1300 zc.zc_cookie = type; 1301 1302 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCRUB, &zc) == 0) 1303 return (0); 1304 1305 (void) snprintf(msg, sizeof (msg), 1306 dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name); 1307 1308 if (errno == EBUSY) 1309 return (zfs_error(hdl, EZFS_RESILVERING, msg)); 1310 else 1311 return (zpool_standard_error(hdl, errno, msg)); 1312} 1313 1314/* 1315 * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL 1316 * spare; but FALSE if its an INUSE spare. 1317 */ 1318static nvlist_t * 1319vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, 1320 boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log) 1321{ 1322 uint_t c, children; 1323 nvlist_t **child; 1324 uint64_t theguid, present; 1325 char *path; 1326 uint64_t wholedisk = 0; 1327 nvlist_t *ret; 1328 uint64_t is_log; 1329 1330 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &theguid) == 0); 1331 1332 if (search == NULL && 1333 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) { 1334 /* 1335 * If the device has never been present since import, the only 1336 * reliable way to match the vdev is by GUID. 1337 */ 1338 if (theguid == guid) 1339 return (nv); 1340 } else if (search != NULL && 1341 nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 1342 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 1343 &wholedisk); 1344 if (wholedisk) { 1345 /* 1346 * For whole disks, the internal path has 's0', but the 1347 * path passed in by the user doesn't. 1348 */ 1349 if (strlen(search) == strlen(path) - 2 && 1350 strncmp(search, path, strlen(search)) == 0) 1351 return (nv); 1352 } else if (strcmp(search, path) == 0) { 1353 return (nv); 1354 } 1355 } 1356 1357 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1358 &child, &children) != 0) 1359 return (NULL); 1360 1361 for (c = 0; c < children; c++) { 1362 if ((ret = vdev_to_nvlist_iter(child[c], search, guid, 1363 avail_spare, l2cache, NULL)) != NULL) { 1364 /* 1365 * The 'is_log' value is only set for the toplevel 1366 * vdev, not the leaf vdevs. So we always lookup the 1367 * log device from the root of the vdev tree (where 1368 * 'log' is non-NULL). 1369 */ 1370 if (log != NULL && 1371 nvlist_lookup_uint64(child[c], 1372 ZPOOL_CONFIG_IS_LOG, &is_log) == 0 && 1373 is_log) { 1374 *log = B_TRUE; 1375 } 1376 return (ret); 1377 } 1378 } 1379 1380 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1381 &child, &children) == 0) { 1382 for (c = 0; c < children; c++) { 1383 if ((ret = vdev_to_nvlist_iter(child[c], search, guid, 1384 avail_spare, l2cache, NULL)) != NULL) { 1385 *avail_spare = B_TRUE; 1386 return (ret); 1387 } 1388 } 1389 } 1390 1391 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1392 &child, &children) == 0) { 1393 for (c = 0; c < children; c++) { 1394 if ((ret = vdev_to_nvlist_iter(child[c], search, guid, 1395 avail_spare, l2cache, NULL)) != NULL) { 1396 *l2cache = B_TRUE; 1397 return (ret); 1398 } 1399 } 1400 } 1401 1402 return (NULL); 1403} 1404 1405nvlist_t * 1406zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, 1407 boolean_t *l2cache, boolean_t *log) 1408{ 1409 char buf[MAXPATHLEN]; 1410 const char *search; 1411 char *end; 1412 nvlist_t *nvroot; 1413 uint64_t guid; 1414 1415 guid = strtoull(path, &end, 10); 1416 if (guid != 0 && *end == '\0') { 1417 search = NULL; 1418 } else if (path[0] != '/') { 1419 (void) snprintf(buf, sizeof (buf), "%s%s", _PATH_DEV, path); 1420 search = buf; 1421 } else { 1422 search = path; 1423 } 1424 1425 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 1426 &nvroot) == 0); 1427 1428 *avail_spare = B_FALSE; 1429 *l2cache = B_FALSE; 1430 if (log != NULL) 1431 *log = B_FALSE; 1432 return (vdev_to_nvlist_iter(nvroot, search, guid, avail_spare, 1433 l2cache, log)); 1434} 1435 1436static int 1437vdev_online(nvlist_t *nv) 1438{ 1439 uint64_t ival; 1440 1441 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 || 1442 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 || 1443 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0) 1444 return (0); 1445 1446 return (1); 1447} 1448 1449/* 1450 * Get phys_path for a root pool 1451 * Return 0 on success; non-zeron on failure. 1452 */ 1453int 1454zpool_get_physpath(zpool_handle_t *zhp, char *physpath) 1455{ 1456 char bootfs[ZPOOL_MAXNAMELEN]; 1457 nvlist_t *vdev_root; 1458 nvlist_t **child; 1459 uint_t count; 1460 int i; 1461 1462 /* 1463 * Make sure this is a root pool, as phys_path doesn't mean 1464 * anything to a non-root pool. 1465 */ 1466 if (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, 1467 sizeof (bootfs), NULL) != 0) 1468 return (-1); 1469 1470 verify(nvlist_lookup_nvlist(zhp->zpool_config, 1471 ZPOOL_CONFIG_VDEV_TREE, &vdev_root) == 0); 1472 1473 if (nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN, 1474 &child, &count) != 0) 1475 return (-2); 1476 1477 for (i = 0; i < count; i++) { 1478 nvlist_t **child2; 1479 uint_t count2; 1480 char *type; 1481 char *tmppath; 1482 int j; 1483 1484 if (nvlist_lookup_string(child[i], ZPOOL_CONFIG_TYPE, &type) 1485 != 0) 1486 return (-3); 1487 1488 if (strcmp(type, VDEV_TYPE_DISK) == 0) { 1489 if (!vdev_online(child[i])) 1490 return (-8); 1491 verify(nvlist_lookup_string(child[i], 1492 ZPOOL_CONFIG_PHYS_PATH, &tmppath) == 0); 1493 (void) strncpy(physpath, tmppath, strlen(tmppath)); 1494 } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) { 1495 if (nvlist_lookup_nvlist_array(child[i], 1496 ZPOOL_CONFIG_CHILDREN, &child2, &count2) != 0) 1497 return (-4); 1498 1499 for (j = 0; j < count2; j++) { 1500 if (!vdev_online(child2[j])) 1501 return (-8); 1502 if (nvlist_lookup_string(child2[j], 1503 ZPOOL_CONFIG_PHYS_PATH, &tmppath) != 0) 1504 return (-5); 1505 1506 if ((strlen(physpath) + strlen(tmppath)) > 1507 MAXNAMELEN) 1508 return (-6); 1509 1510 if (strlen(physpath) == 0) { 1511 (void) strncpy(physpath, tmppath, 1512 strlen(tmppath)); 1513 } else { 1514 (void) strcat(physpath, " "); 1515 (void) strcat(physpath, tmppath); 1516 } 1517 } 1518 } else { 1519 return (-7); 1520 } 1521 } 1522 1523 return (0); 1524} 1525 1526/* 1527 * Returns TRUE if the given guid corresponds to the given type. 1528 * This is used to check for hot spares (INUSE or not), and level 2 cache 1529 * devices. 1530 */ 1531static boolean_t 1532is_guid_type(zpool_handle_t *zhp, uint64_t guid, const char *type) 1533{ 1534 uint64_t target_guid; 1535 nvlist_t *nvroot; 1536 nvlist_t **list; 1537 uint_t count; 1538 int i; 1539 1540 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 1541 &nvroot) == 0); 1542 if (nvlist_lookup_nvlist_array(nvroot, type, &list, &count) == 0) { 1543 for (i = 0; i < count; i++) { 1544 verify(nvlist_lookup_uint64(list[i], ZPOOL_CONFIG_GUID, 1545 &target_guid) == 0); 1546 if (guid == target_guid) 1547 return (B_TRUE); 1548 } 1549 } 1550 1551 return (B_FALSE); 1552} 1553 1554/* 1555 * Bring the specified vdev online. The 'flags' parameter is a set of the 1556 * ZFS_ONLINE_* flags. 1557 */ 1558int 1559zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, 1560 vdev_state_t *newstate) 1561{ 1562 zfs_cmd_t zc = { 0 }; 1563 char msg[1024]; 1564 nvlist_t *tgt; 1565 boolean_t avail_spare, l2cache; 1566 libzfs_handle_t *hdl = zhp->zpool_hdl; 1567 1568 (void) snprintf(msg, sizeof (msg), 1569 dgettext(TEXT_DOMAIN, "cannot online %s"), path); 1570 1571 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1572 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 1573 NULL)) == NULL) 1574 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1575 1576 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1577 1578 if (avail_spare || 1579 is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_SPARES) == B_TRUE) 1580 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1581 1582 zc.zc_cookie = VDEV_STATE_ONLINE; 1583 zc.zc_obj = flags; 1584 1585 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) 1586 return (zpool_standard_error(hdl, errno, msg)); 1587 1588 *newstate = zc.zc_cookie; 1589 return (0); 1590} 1591 1592/* 1593 * Take the specified vdev offline 1594 */ 1595int 1596zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp) 1597{ 1598 zfs_cmd_t zc = { 0 }; 1599 char msg[1024]; 1600 nvlist_t *tgt; 1601 boolean_t avail_spare, l2cache; 1602 libzfs_handle_t *hdl = zhp->zpool_hdl; 1603 1604 (void) snprintf(msg, sizeof (msg), 1605 dgettext(TEXT_DOMAIN, "cannot offline %s"), path); 1606 1607 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1608 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 1609 NULL)) == NULL) 1610 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1611 1612 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1613 1614 if (avail_spare || 1615 is_guid_type(zhp, zc.zc_guid, ZPOOL_CONFIG_SPARES) == B_TRUE) 1616 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1617 1618 zc.zc_cookie = VDEV_STATE_OFFLINE; 1619 zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0; 1620 1621 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 1622 return (0); 1623 1624 switch (errno) { 1625 case EBUSY: 1626 1627 /* 1628 * There are no other replicas of this device. 1629 */ 1630 return (zfs_error(hdl, EZFS_NOREPLICAS, msg)); 1631 1632 default: 1633 return (zpool_standard_error(hdl, errno, msg)); 1634 } 1635} 1636 1637/* 1638 * Mark the given vdev faulted. 1639 */ 1640int 1641zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid) 1642{ 1643 zfs_cmd_t zc = { 0 }; 1644 char msg[1024]; 1645 libzfs_handle_t *hdl = zhp->zpool_hdl; 1646 1647 (void) snprintf(msg, sizeof (msg), 1648 dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid); 1649 1650 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1651 zc.zc_guid = guid; 1652 zc.zc_cookie = VDEV_STATE_FAULTED; 1653 1654 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 1655 return (0); 1656 1657 switch (errno) { 1658 case EBUSY: 1659 1660 /* 1661 * There are no other replicas of this device. 1662 */ 1663 return (zfs_error(hdl, EZFS_NOREPLICAS, msg)); 1664 1665 default: 1666 return (zpool_standard_error(hdl, errno, msg)); 1667 } 1668 1669} 1670 1671/* 1672 * Mark the given vdev degraded. 1673 */ 1674int 1675zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid) 1676{ 1677 zfs_cmd_t zc = { 0 }; 1678 char msg[1024]; 1679 libzfs_handle_t *hdl = zhp->zpool_hdl; 1680 1681 (void) snprintf(msg, sizeof (msg), 1682 dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid); 1683 1684 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1685 zc.zc_guid = guid; 1686 zc.zc_cookie = VDEV_STATE_DEGRADED; 1687 1688 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0) 1689 return (0); 1690 1691 return (zpool_standard_error(hdl, errno, msg)); 1692} 1693 1694/* 1695 * Returns TRUE if the given nvlist is a vdev that was originally swapped in as 1696 * a hot spare. 1697 */ 1698static boolean_t 1699is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which) 1700{ 1701 nvlist_t **child; 1702 uint_t c, children; 1703 char *type; 1704 1705 if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child, 1706 &children) == 0) { 1707 verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE, 1708 &type) == 0); 1709 1710 if (strcmp(type, VDEV_TYPE_SPARE) == 0 && 1711 children == 2 && child[which] == tgt) 1712 return (B_TRUE); 1713 1714 for (c = 0; c < children; c++) 1715 if (is_replacing_spare(child[c], tgt, which)) 1716 return (B_TRUE); 1717 } 1718 1719 return (B_FALSE); 1720} 1721 1722/* 1723 * Attach new_disk (fully described by nvroot) to old_disk. 1724 * If 'replacing' is specified, the new disk will replace the old one. 1725 */ 1726int 1727zpool_vdev_attach(zpool_handle_t *zhp, 1728 const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing) 1729{ 1730 zfs_cmd_t zc = { 0 }; 1731 char msg[1024]; 1732 int ret; 1733 nvlist_t *tgt; 1734 boolean_t avail_spare, l2cache, islog; 1735 uint64_t val; 1736 char *path, *newname; 1737 nvlist_t **child; 1738 uint_t children; 1739 nvlist_t *config_root; 1740 libzfs_handle_t *hdl = zhp->zpool_hdl; 1741 1742 if (replacing) 1743 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1744 "cannot replace %s with %s"), old_disk, new_disk); 1745 else 1746 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1747 "cannot attach %s to %s"), new_disk, old_disk); 1748 1749 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1750 if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache, 1751 &islog)) == 0) 1752 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1753 1754 if (avail_spare) 1755 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1756 1757 if (l2cache) 1758 return (zfs_error(hdl, EZFS_ISL2CACHE, msg)); 1759 1760 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1761 zc.zc_cookie = replacing; 1762 1763 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 1764 &child, &children) != 0 || children != 1) { 1765 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1766 "new device must be a single disk")); 1767 return (zfs_error(hdl, EZFS_INVALCONFIG, msg)); 1768 } 1769 1770 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 1771 ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0); 1772 1773 if ((newname = zpool_vdev_name(NULL, NULL, child[0])) == NULL) 1774 return (-1); 1775 1776 /* 1777 * If the target is a hot spare that has been swapped in, we can only 1778 * replace it with another hot spare. 1779 */ 1780 if (replacing && 1781 nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && 1782 (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache, 1783 NULL) == NULL || !avail_spare) && 1784 is_replacing_spare(config_root, tgt, 1)) { 1785 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1786 "can only be replaced by another hot spare")); 1787 free(newname); 1788 return (zfs_error(hdl, EZFS_BADTARGET, msg)); 1789 } 1790 1791 /* 1792 * If we are attempting to replace a spare, it canot be applied to an 1793 * already spared device. 1794 */ 1795 if (replacing && 1796 nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && 1797 zpool_find_vdev(zhp, newname, &avail_spare, 1798 &l2cache, NULL) != NULL && avail_spare && 1799 is_replacing_spare(config_root, tgt, 0)) { 1800 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1801 "device has already been replaced with a spare")); 1802 free(newname); 1803 return (zfs_error(hdl, EZFS_BADTARGET, msg)); 1804 } 1805 1806 free(newname); 1807 1808 if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0) 1809 return (-1); 1810 1811 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ATTACH, &zc); 1812 1813 zcmd_free_nvlists(&zc); 1814 1815 if (ret == 0) 1816 return (0); 1817 1818 switch (errno) { 1819 case ENOTSUP: 1820 /* 1821 * Can't attach to or replace this type of vdev. 1822 */ 1823 if (replacing) { 1824 if (islog) 1825 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1826 "cannot replace a log with a spare")); 1827 else 1828 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1829 "cannot replace a replacing device")); 1830 } else { 1831 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1832 "can only attach to mirrors and top-level " 1833 "disks")); 1834 } 1835 (void) zfs_error(hdl, EZFS_BADTARGET, msg); 1836 break; 1837 1838 case EINVAL: 1839 /* 1840 * The new device must be a single disk. 1841 */ 1842 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1843 "new device must be a single disk")); 1844 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg); 1845 break; 1846 1847 case EBUSY: 1848 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"), 1849 new_disk); 1850 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1851 break; 1852 1853 case EOVERFLOW: 1854 /* 1855 * The new device is too small. 1856 */ 1857 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1858 "device is too small")); 1859 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1860 break; 1861 1862 case EDOM: 1863 /* 1864 * The new device has a different alignment requirement. 1865 */ 1866 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1867 "devices have different sector alignment")); 1868 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1869 break; 1870 1871 case ENAMETOOLONG: 1872 /* 1873 * The resulting top-level vdev spec won't fit in the label. 1874 */ 1875 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg); 1876 break; 1877 1878 default: 1879 (void) zpool_standard_error(hdl, errno, msg); 1880 } 1881 1882 return (-1); 1883} 1884 1885/* 1886 * Detach the specified device. 1887 */ 1888int 1889zpool_vdev_detach(zpool_handle_t *zhp, const char *path) 1890{ 1891 zfs_cmd_t zc = { 0 }; 1892 char msg[1024]; 1893 nvlist_t *tgt; 1894 boolean_t avail_spare, l2cache; 1895 libzfs_handle_t *hdl = zhp->zpool_hdl; 1896 1897 (void) snprintf(msg, sizeof (msg), 1898 dgettext(TEXT_DOMAIN, "cannot detach %s"), path); 1899 1900 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1901 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 1902 NULL)) == 0) 1903 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1904 1905 if (avail_spare) 1906 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1907 1908 if (l2cache) 1909 return (zfs_error(hdl, EZFS_ISL2CACHE, msg)); 1910 1911 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1912 1913 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0) 1914 return (0); 1915 1916 switch (errno) { 1917 1918 case ENOTSUP: 1919 /* 1920 * Can't detach from this type of vdev. 1921 */ 1922 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only " 1923 "applicable to mirror and replacing vdevs")); 1924 (void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg); 1925 break; 1926 1927 case EBUSY: 1928 /* 1929 * There are no other replicas of this device. 1930 */ 1931 (void) zfs_error(hdl, EZFS_NOREPLICAS, msg); 1932 break; 1933 1934 default: 1935 (void) zpool_standard_error(hdl, errno, msg); 1936 } 1937 1938 return (-1); 1939} 1940 1941/* 1942 * Remove the given device. Currently, this is supported only for hot spares 1943 * and level 2 cache devices. 1944 */ 1945int 1946zpool_vdev_remove(zpool_handle_t *zhp, const char *path) 1947{ 1948 zfs_cmd_t zc = { 0 }; 1949 char msg[1024]; 1950 nvlist_t *tgt; 1951 boolean_t avail_spare, l2cache; 1952 libzfs_handle_t *hdl = zhp->zpool_hdl; 1953 1954 (void) snprintf(msg, sizeof (msg), 1955 dgettext(TEXT_DOMAIN, "cannot remove %s"), path); 1956 1957 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1958 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache, 1959 NULL)) == 0) 1960 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1961 1962 if (!avail_spare && !l2cache) { 1963 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1964 "only inactive hot spares or cache devices " 1965 "can be removed")); 1966 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1967 } 1968 1969 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1970 1971 if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0) 1972 return (0); 1973 1974 return (zpool_standard_error(hdl, errno, msg)); 1975} 1976 1977/* 1978 * Clear the errors for the pool, or the particular device if specified. 1979 */ 1980int 1981zpool_clear(zpool_handle_t *zhp, const char *path) 1982{ 1983 zfs_cmd_t zc = { 0 }; 1984 char msg[1024]; 1985 nvlist_t *tgt; 1986 boolean_t avail_spare, l2cache; 1987 libzfs_handle_t *hdl = zhp->zpool_hdl; 1988 1989 if (path) 1990 (void) snprintf(msg, sizeof (msg), 1991 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1992 path); 1993 else 1994 (void) snprintf(msg, sizeof (msg), 1995 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1996 zhp->zpool_name); 1997 1998 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1999 if (path) { 2000 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, 2001 &l2cache, NULL)) == 0) 2002 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 2003 2004 /* 2005 * Don't allow error clearing for hot spares. Do allow 2006 * error clearing for l2cache devices. 2007 */ 2008 if (avail_spare) 2009 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 2010 2011 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, 2012 &zc.zc_guid) == 0); 2013 } 2014 2015 if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0) 2016 return (0); 2017 2018 return (zpool_standard_error(hdl, errno, msg)); 2019} 2020 2021/* 2022 * Similar to zpool_clear(), but takes a GUID (used by fmd). 2023 */ 2024int 2025zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid) 2026{ 2027 zfs_cmd_t zc = { 0 }; 2028 char msg[1024]; 2029 libzfs_handle_t *hdl = zhp->zpool_hdl; 2030 2031 (void) snprintf(msg, sizeof (msg), 2032 dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"), 2033 guid); 2034 2035 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 2036 zc.zc_guid = guid; 2037 2038 if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0) 2039 return (0); 2040 2041 return (zpool_standard_error(hdl, errno, msg)); 2042} 2043 2044/* 2045 * Iterate over all zvols in a given pool by walking the /dev/zvol/dsk/<pool> 2046 * hierarchy. 2047 */ 2048int 2049zpool_iter_zvol(zpool_handle_t *zhp, int (*cb)(const char *, void *), 2050 void *data) 2051{ 2052 libzfs_handle_t *hdl = zhp->zpool_hdl; 2053 char (*paths)[MAXPATHLEN]; 2054 char path[MAXPATHLEN]; 2055 size_t size = 4; 2056 int curr, fd, base, ret = 0; 2057 DIR *dirp; 2058 struct dirent *dp; 2059 struct stat st; 2060 2061 if ((base = open(ZVOL_FULL_DEV_DIR, O_RDONLY)) < 0) 2062 return (errno == ENOENT ? 0 : -1); 2063 2064 snprintf(path, sizeof(path), "%s/%s", ZVOL_FULL_DEV_DIR, 2065 zhp->zpool_name); 2066 if (stat(path, &st) != 0) { 2067 int err = errno; 2068 (void) close(base); 2069 return (err == ENOENT ? 0 : -1); 2070 } 2071 2072 /* 2073 * Oddly this wasn't a directory -- ignore that failure since we 2074 * know there are no links lower in the (non-existant) hierarchy. 2075 */ 2076 if (!S_ISDIR(st.st_mode)) { 2077 (void) close(base); 2078 return (0); 2079 } 2080 2081 if ((paths = zfs_alloc(hdl, size * sizeof (paths[0]))) == NULL) { 2082 (void) close(base); 2083 return (-1); 2084 } 2085 2086 (void) strlcpy(paths[0], zhp->zpool_name, sizeof (paths[0])); 2087 curr = 0; 2088 2089 while (curr >= 0) { 2090 snprintf(path, sizeof(path), "%s/%s", ZVOL_FULL_DEV_DIR, 2091 paths[curr]); 2092 if (lstat(path, &st) != 0) 2093 goto err; 2094 2095 if (S_ISDIR(st.st_mode)) { 2096 if ((dirp = opendir(path)) == NULL) { 2097 goto err; 2098 } 2099 2100 while ((dp = readdir(dirp)) != NULL) { 2101 if (dp->d_name[0] == '.') 2102 continue; 2103 2104 if (curr + 1 == size) { 2105 paths = zfs_realloc(hdl, paths, 2106 size * sizeof (paths[0]), 2107 size * 2 * sizeof (paths[0])); 2108 if (paths == NULL) { 2109 (void) closedir(dirp); 2110 goto err; 2111 } 2112 2113 size *= 2; 2114 } 2115 2116 (void) strlcpy(paths[curr + 1], paths[curr], 2117 sizeof (paths[curr + 1])); 2118 (void) strlcat(paths[curr], "/", 2119 sizeof (paths[curr])); 2120 (void) strlcat(paths[curr], dp->d_name, 2121 sizeof (paths[curr])); 2122 curr++; 2123 } 2124 2125 (void) closedir(dirp); 2126 2127 } else { 2128 if ((ret = cb(paths[curr], data)) != 0) 2129 break; 2130 } 2131 2132 curr--; 2133 } 2134 2135 free(paths); 2136 (void) close(base); 2137 2138 return (ret); 2139 2140err: 2141 free(paths); 2142 (void) close(base); 2143 return (-1); 2144} 2145 2146typedef struct zvol_cb { 2147 zpool_handle_t *zcb_pool; 2148 boolean_t zcb_create; 2149} zvol_cb_t; 2150 2151/*ARGSUSED*/ 2152static int 2153do_zvol_create(zfs_handle_t *zhp, void *data) 2154{ 2155 int ret = 0; 2156 2157 if (ZFS_IS_VOLUME(zhp)) { 2158 (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name); 2159 ret = zfs_iter_snapshots(zhp, do_zvol_create, NULL); 2160 } 2161 2162 if (ret == 0) 2163 ret = zfs_iter_filesystems(zhp, do_zvol_create, NULL); 2164 2165 zfs_close(zhp); 2166 2167 return (ret); 2168} 2169 2170/* 2171 * Iterate over all zvols in the pool and make any necessary minor nodes. 2172 */ 2173int 2174zpool_create_zvol_links(zpool_handle_t *zhp) 2175{ 2176 zfs_handle_t *zfp; 2177 int ret; 2178 2179 /* 2180 * If the pool is unavailable, just return success. 2181 */ 2182 if ((zfp = make_dataset_handle(zhp->zpool_hdl, 2183 zhp->zpool_name)) == NULL) 2184 return (0); 2185 2186 ret = zfs_iter_filesystems(zfp, do_zvol_create, NULL); 2187 2188 zfs_close(zfp); 2189 return (ret); 2190} 2191 2192static int 2193do_zvol_remove(const char *dataset, void *data) 2194{ 2195 zpool_handle_t *zhp = data; 2196 2197 return (zvol_remove_link(zhp->zpool_hdl, dataset)); 2198} 2199 2200/* 2201 * Iterate over all zvols in the pool and remove any minor nodes. We iterate 2202 * by examining the /dev links so that a corrupted pool doesn't impede this 2203 * operation. 2204 */ 2205int 2206zpool_remove_zvol_links(zpool_handle_t *zhp) 2207{ 2208 return (zpool_iter_zvol(zhp, do_zvol_remove, zhp)); 2209} 2210 2211/* 2212 * Convert from a devid string to a path. 2213 */ 2214static char * 2215devid_to_path(char *devid_str) 2216{ 2217 ddi_devid_t devid; 2218 char *minor; 2219 char *path; 2220 devid_nmlist_t *list = NULL; 2221 int ret; 2222 2223 if (devid_str_decode(devid_str, &devid, &minor) != 0) 2224 return (NULL); 2225 2226 ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list); 2227 2228 devid_str_free(minor); 2229 devid_free(devid); 2230 2231 if (ret != 0) 2232 return (NULL); 2233 2234 if ((path = strdup(list[0].devname)) == NULL) 2235 return (NULL); 2236 2237 devid_free_nmlist(list); 2238 2239 return (path); 2240} 2241 2242/* 2243 * Convert from a path to a devid string. 2244 */ 2245static char * 2246path_to_devid(const char *path) 2247{ 2248 int fd; 2249 ddi_devid_t devid; 2250 char *minor, *ret; 2251 2252 if ((fd = open(path, O_RDONLY)) < 0) 2253 return (NULL); 2254 2255 minor = NULL; 2256 ret = NULL; 2257 if (devid_get(fd, &devid) == 0) { 2258 if (devid_get_minor_name(fd, &minor) == 0) 2259 ret = devid_str_encode(devid, minor); 2260 if (minor != NULL) 2261 devid_str_free(minor); 2262 devid_free(devid); 2263 } 2264 (void) close(fd); 2265 2266 return (ret); 2267} 2268 2269/* 2270 * Issue the necessary ioctl() to update the stored path value for the vdev. We 2271 * ignore any failure here, since a common case is for an unprivileged user to 2272 * type 'zpool status', and we'll display the correct information anyway. 2273 */ 2274static void 2275set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) 2276{ 2277 zfs_cmd_t zc = { 0 }; 2278 2279 (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 2280 (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value)); 2281 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2282 &zc.zc_guid) == 0); 2283 2284 (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc); 2285} 2286 2287/* 2288 * Given a vdev, return the name to display in iostat. If the vdev has a path, 2289 * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. 2290 * We also check if this is a whole disk, in which case we strip off the 2291 * trailing 's0' slice name. 2292 * 2293 * This routine is also responsible for identifying when disks have been 2294 * reconfigured in a new location. The kernel will have opened the device by 2295 * devid, but the path will still refer to the old location. To catch this, we 2296 * first do a path -> devid translation (which is fast for the common case). If 2297 * the devid matches, we're done. If not, we do a reverse devid -> path 2298 * translation and issue the appropriate ioctl() to update the path of the vdev. 2299 * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any 2300 * of these checks. 2301 */ 2302char * 2303zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv) 2304{ 2305 char *path, *devid; 2306 uint64_t value; 2307 char buf[64]; 2308 vdev_stat_t *vs; 2309 uint_t vsc; 2310 2311 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2312 &value) == 0) { 2313 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2314 &value) == 0); 2315 (void) snprintf(buf, sizeof (buf), "%llu", 2316 (u_longlong_t)value); 2317 path = buf; 2318 } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 2319 2320 /* 2321 * If the device is dead (faulted, offline, etc) then don't 2322 * bother opening it. Otherwise we may be forcing the user to 2323 * open a misbehaving device, which can have undesirable 2324 * effects. 2325 */ 2326 if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2327 (uint64_t **)&vs, &vsc) != 0 || 2328 vs->vs_state >= VDEV_STATE_DEGRADED) && 2329 zhp != NULL && 2330 nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { 2331 /* 2332 * Determine if the current path is correct. 2333 */ 2334 char *newdevid = path_to_devid(path); 2335 2336 if (newdevid == NULL || 2337 strcmp(devid, newdevid) != 0) { 2338 char *newpath; 2339 2340 if ((newpath = devid_to_path(devid)) != NULL) { 2341 /* 2342 * Update the path appropriately. 2343 */ 2344 set_path(zhp, nv, newpath); 2345 if (nvlist_add_string(nv, 2346 ZPOOL_CONFIG_PATH, newpath) == 0) 2347 verify(nvlist_lookup_string(nv, 2348 ZPOOL_CONFIG_PATH, 2349 &path) == 0); 2350 free(newpath); 2351 } 2352 } 2353 2354 if (newdevid) 2355 devid_str_free(newdevid); 2356 } 2357 2358 if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 2359 path += sizeof(_PATH_DEV) - 1; 2360 2361 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 2362 &value) == 0 && value) { 2363 char *tmp = zfs_strdup(hdl, path); 2364 if (tmp == NULL) 2365 return (NULL); 2366 tmp[strlen(path) - 2] = '\0'; 2367 return (tmp); 2368 } 2369 } else { 2370 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0); 2371 2372 /* 2373 * If it's a raidz device, we need to stick in the parity level. 2374 */ 2375 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) { 2376 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY, 2377 &value) == 0); 2378 (void) snprintf(buf, sizeof (buf), "%s%llu", path, 2379 (u_longlong_t)value); 2380 path = buf; 2381 } 2382 } 2383 2384 return (zfs_strdup(hdl, path)); 2385} 2386 2387static int 2388zbookmark_compare(const void *a, const void *b) 2389{ 2390 return (memcmp(a, b, sizeof (zbookmark_t))); 2391} 2392 2393/* 2394 * Retrieve the persistent error log, uniquify the members, and return to the 2395 * caller. 2396 */ 2397int 2398zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp) 2399{ 2400 zfs_cmd_t zc = { 0 }; 2401 uint64_t count; 2402 zbookmark_t *zb = NULL; 2403 int i; 2404 2405 /* 2406 * Retrieve the raw error list from the kernel. If the number of errors 2407 * has increased, allocate more space and continue until we get the 2408 * entire list. 2409 */ 2410 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT, 2411 &count) == 0); 2412 if (count == 0) 2413 return (0); 2414 if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl, 2415 count * sizeof (zbookmark_t))) == (uintptr_t)NULL) 2416 return (-1); 2417 zc.zc_nvlist_dst_size = count; 2418 (void) strcpy(zc.zc_name, zhp->zpool_name); 2419 for (;;) { 2420 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG, 2421 &zc) != 0) { 2422 free((void *)(uintptr_t)zc.zc_nvlist_dst); 2423 if (errno == ENOMEM) { 2424 count = zc.zc_nvlist_dst_size; 2425 if ((zc.zc_nvlist_dst = (uintptr_t) 2426 zfs_alloc(zhp->zpool_hdl, count * 2427 sizeof (zbookmark_t))) == (uintptr_t)NULL) 2428 return (-1); 2429 } else { 2430 return (-1); 2431 } 2432 } else { 2433 break; 2434 } 2435 } 2436 2437 /* 2438 * Sort the resulting bookmarks. This is a little confusing due to the 2439 * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last 2440 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks 2441 * _not_ copied as part of the process. So we point the start of our 2442 * array appropriate and decrement the total number of elements. 2443 */ 2444 zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) + 2445 zc.zc_nvlist_dst_size; 2446 count -= zc.zc_nvlist_dst_size; 2447 2448 qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare); 2449 2450 verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0); 2451 2452 /* 2453 * Fill in the nverrlistp with nvlist's of dataset and object numbers. 2454 */ 2455 for (i = 0; i < count; i++) { 2456 nvlist_t *nv; 2457 2458 /* ignoring zb_blkid and zb_level for now */ 2459 if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset && 2460 zb[i-1].zb_object == zb[i].zb_object) 2461 continue; 2462 2463 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0) 2464 goto nomem; 2465 if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET, 2466 zb[i].zb_objset) != 0) { 2467 nvlist_free(nv); 2468 goto nomem; 2469 } 2470 if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT, 2471 zb[i].zb_object) != 0) { 2472 nvlist_free(nv); 2473 goto nomem; 2474 } 2475 if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) { 2476 nvlist_free(nv); 2477 goto nomem; 2478 } 2479 nvlist_free(nv); 2480 } 2481 2482 free((void *)(uintptr_t)zc.zc_nvlist_dst); 2483 return (0); 2484 2485nomem: 2486 free((void *)(uintptr_t)zc.zc_nvlist_dst); 2487 return (no_memory(zhp->zpool_hdl)); 2488} 2489 2490/* 2491 * Upgrade a ZFS pool to the latest on-disk version. 2492 */ 2493int 2494zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version) 2495{ 2496 zfs_cmd_t zc = { 0 }; 2497 libzfs_handle_t *hdl = zhp->zpool_hdl; 2498 2499 (void) strcpy(zc.zc_name, zhp->zpool_name); 2500 zc.zc_cookie = new_version; 2501 2502 if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0) 2503 return (zpool_standard_error_fmt(hdl, errno, 2504 dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"), 2505 zhp->zpool_name)); 2506 return (0); 2507} 2508 2509void 2510zpool_set_history_str(const char *subcommand, int argc, char **argv, 2511 char *history_str) 2512{ 2513 int i; 2514 2515 (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN); 2516 for (i = 1; i < argc; i++) { 2517 if (strlen(history_str) + 1 + strlen(argv[i]) > 2518 HIS_MAX_RECORD_LEN) 2519 break; 2520 (void) strlcat(history_str, " ", HIS_MAX_RECORD_LEN); 2521 (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN); 2522 } 2523} 2524 2525/* 2526 * Stage command history for logging. 2527 */ 2528int 2529zpool_stage_history(libzfs_handle_t *hdl, const char *history_str) 2530{ 2531 if (history_str == NULL) 2532 return (EINVAL); 2533 2534 if (strlen(history_str) > HIS_MAX_RECORD_LEN) 2535 return (EINVAL); 2536 2537 if (hdl->libzfs_log_str != NULL) 2538 free(hdl->libzfs_log_str); 2539 2540 if ((hdl->libzfs_log_str = strdup(history_str)) == NULL) 2541 return (no_memory(hdl)); 2542 2543 return (0); 2544} 2545 2546/* 2547 * Perform ioctl to get some command history of a pool. 2548 * 2549 * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the 2550 * logical offset of the history buffer to start reading from. 2551 * 2552 * Upon return, 'off' is the next logical offset to read from and 2553 * 'len' is the actual amount of bytes read into 'buf'. 2554 */ 2555static int 2556get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len) 2557{ 2558 zfs_cmd_t zc = { 0 }; 2559 libzfs_handle_t *hdl = zhp->zpool_hdl; 2560 2561 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 2562 2563 zc.zc_history = (uint64_t)(uintptr_t)buf; 2564 zc.zc_history_len = *len; 2565 zc.zc_history_offset = *off; 2566 2567 if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) { 2568 switch (errno) { 2569 case EPERM: 2570 return (zfs_error_fmt(hdl, EZFS_PERM, 2571 dgettext(TEXT_DOMAIN, 2572 "cannot show history for pool '%s'"), 2573 zhp->zpool_name)); 2574 case ENOENT: 2575 return (zfs_error_fmt(hdl, EZFS_NOHISTORY, 2576 dgettext(TEXT_DOMAIN, "cannot get history for pool " 2577 "'%s'"), zhp->zpool_name)); 2578 case ENOTSUP: 2579 return (zfs_error_fmt(hdl, EZFS_BADVERSION, 2580 dgettext(TEXT_DOMAIN, "cannot get history for pool " 2581 "'%s', pool must be upgraded"), zhp->zpool_name)); 2582 default: 2583 return (zpool_standard_error_fmt(hdl, errno, 2584 dgettext(TEXT_DOMAIN, 2585 "cannot get history for '%s'"), zhp->zpool_name)); 2586 } 2587 } 2588 2589 *len = zc.zc_history_len; 2590 *off = zc.zc_history_offset; 2591 2592 return (0); 2593} 2594 2595/* 2596 * Process the buffer of nvlists, unpacking and storing each nvlist record 2597 * into 'records'. 'leftover' is set to the number of bytes that weren't 2598 * processed as there wasn't a complete record. 2599 */ 2600static int 2601zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover, 2602 nvlist_t ***records, uint_t *numrecords) 2603{ 2604 uint64_t reclen; 2605 nvlist_t *nv; 2606 int i; 2607 2608 while (bytes_read > sizeof (reclen)) { 2609 2610 /* get length of packed record (stored as little endian) */ 2611 for (i = 0, reclen = 0; i < sizeof (reclen); i++) 2612 reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i); 2613 2614 if (bytes_read < sizeof (reclen) + reclen) 2615 break; 2616 2617 /* unpack record */ 2618 if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0) 2619 return (ENOMEM); 2620 bytes_read -= sizeof (reclen) + reclen; 2621 buf += sizeof (reclen) + reclen; 2622 2623 /* add record to nvlist array */ 2624 (*numrecords)++; 2625 if (ISP2(*numrecords + 1)) { 2626 *records = realloc(*records, 2627 *numrecords * 2 * sizeof (nvlist_t *)); 2628 } 2629 (*records)[*numrecords - 1] = nv; 2630 } 2631 2632 *leftover = bytes_read; 2633 return (0); 2634} 2635 2636#define HIS_BUF_LEN (128*1024) 2637 2638/* 2639 * Retrieve the command history of a pool. 2640 */ 2641int 2642zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp) 2643{ 2644 char buf[HIS_BUF_LEN]; 2645 uint64_t off = 0; 2646 nvlist_t **records = NULL; 2647 uint_t numrecords = 0; 2648 int err, i; 2649 2650 do { 2651 uint64_t bytes_read = sizeof (buf); 2652 uint64_t leftover; 2653 2654 if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0) 2655 break; 2656 2657 /* if nothing else was read in, we're at EOF, just return */ 2658 if (!bytes_read) 2659 break; 2660 2661 if ((err = zpool_history_unpack(buf, bytes_read, 2662 &leftover, &records, &numrecords)) != 0) 2663 break; 2664 off -= leftover; 2665 2666 /* CONSTCOND */ 2667 } while (1); 2668 2669 if (!err) { 2670 verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0); 2671 verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD, 2672 records, numrecords) == 0); 2673 } 2674 for (i = 0; i < numrecords; i++) 2675 nvlist_free(records[i]); 2676 free(records); 2677 2678 return (err); 2679} 2680 2681void 2682zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj, 2683 char *pathname, size_t len) 2684{ 2685 zfs_cmd_t zc = { 0 }; 2686 boolean_t mounted = B_FALSE; 2687 char *mntpnt = NULL; 2688 char dsname[MAXNAMELEN]; 2689 2690 if (dsobj == 0) { 2691 /* special case for the MOS */ 2692 (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj); 2693 return; 2694 } 2695 2696 /* get the dataset's name */ 2697 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 2698 zc.zc_obj = dsobj; 2699 if (ioctl(zhp->zpool_hdl->libzfs_fd, 2700 ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) { 2701 /* just write out a path of two object numbers */ 2702 (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>", 2703 dsobj, obj); 2704 return; 2705 } 2706 (void) strlcpy(dsname, zc.zc_value, sizeof (dsname)); 2707 2708 /* find out if the dataset is mounted */ 2709 mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt); 2710 2711 /* get the corrupted object's path */ 2712 (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name)); 2713 zc.zc_obj = obj; 2714 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH, 2715 &zc) == 0) { 2716 if (mounted) { 2717 (void) snprintf(pathname, len, "%s%s", mntpnt, 2718 zc.zc_value); 2719 } else { 2720 (void) snprintf(pathname, len, "%s:%s", 2721 dsname, zc.zc_value); 2722 } 2723 } else { 2724 (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj); 2725 } 2726 free(mntpnt); 2727} 2728 2729#define RDISK_ROOT "/dev/rdsk" 2730#define BACKUP_SLICE "s2" 2731/* 2732 * Don't start the slice at the default block of 34; many storage 2733 * devices will use a stripe width of 128k, so start there instead. 2734 */ 2735#define NEW_START_BLOCK 256 2736 2737#if defined(sun) 2738/* 2739 * Read the EFI label from the config, if a label does not exist then 2740 * pass back the error to the caller. If the caller has passed a non-NULL 2741 * diskaddr argument then we set it to the starting address of the EFI 2742 * partition. 2743 */ 2744static int 2745read_efi_label(nvlist_t *config, diskaddr_t *sb) 2746{ 2747 char *path; 2748 int fd; 2749 char diskname[MAXPATHLEN]; 2750 int err = -1; 2751 2752 if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0) 2753 return (err); 2754 2755 (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT, 2756 strrchr(path, '/')); 2757 if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) { 2758 struct dk_gpt *vtoc; 2759 2760 if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) { 2761 if (sb != NULL) 2762 *sb = vtoc->efi_parts[0].p_start; 2763 efi_free(vtoc); 2764 } 2765 (void) close(fd); 2766 } 2767 return (err); 2768} 2769 2770/* 2771 * determine where a partition starts on a disk in the current 2772 * configuration 2773 */ 2774static diskaddr_t 2775find_start_block(nvlist_t *config) 2776{ 2777 nvlist_t **child; 2778 uint_t c, children; 2779 diskaddr_t sb = MAXOFFSET_T; 2780 uint64_t wholedisk; 2781 2782 if (nvlist_lookup_nvlist_array(config, 2783 ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) { 2784 if (nvlist_lookup_uint64(config, 2785 ZPOOL_CONFIG_WHOLE_DISK, 2786 &wholedisk) != 0 || !wholedisk) { 2787 return (MAXOFFSET_T); 2788 } 2789 if (read_efi_label(config, &sb) < 0) 2790 sb = MAXOFFSET_T; 2791 return (sb); 2792 } 2793 2794 for (c = 0; c < children; c++) { 2795 sb = find_start_block(child[c]); 2796 if (sb != MAXOFFSET_T) { 2797 return (sb); 2798 } 2799 } 2800 return (MAXOFFSET_T); 2801} 2802#endif /* sun */ 2803 2804/* 2805 * Label an individual disk. The name provided is the short name, 2806 * stripped of any leading /dev path. 2807 */ 2808int 2809zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) 2810{ 2811#if defined(sun) 2812 char path[MAXPATHLEN]; 2813 struct dk_gpt *vtoc; 2814 int fd; 2815 size_t resv = EFI_MIN_RESV_SIZE; 2816 uint64_t slice_size; 2817 diskaddr_t start_block; 2818 char errbuf[1024]; 2819 2820 /* prepare an error message just in case */ 2821 (void) snprintf(errbuf, sizeof (errbuf), 2822 dgettext(TEXT_DOMAIN, "cannot label '%s'"), name); 2823 2824 if (zhp) { 2825 nvlist_t *nvroot; 2826 2827 verify(nvlist_lookup_nvlist(zhp->zpool_config, 2828 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); 2829 2830 if (zhp->zpool_start_block == 0) 2831 start_block = find_start_block(nvroot); 2832 else 2833 start_block = zhp->zpool_start_block; 2834 zhp->zpool_start_block = start_block; 2835 } else { 2836 /* new pool */ 2837 start_block = NEW_START_BLOCK; 2838 } 2839 2840 (void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name, 2841 BACKUP_SLICE); 2842 2843 if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) { 2844 /* 2845 * This shouldn't happen. We've long since verified that this 2846 * is a valid device. 2847 */ 2848 zfs_error_aux(hdl, 2849 dgettext(TEXT_DOMAIN, "unable to open device")); 2850 return (zfs_error(hdl, EZFS_OPENFAILED, errbuf)); 2851 } 2852 2853 if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) { 2854 /* 2855 * The only way this can fail is if we run out of memory, or we 2856 * were unable to read the disk's capacity 2857 */ 2858 if (errno == ENOMEM) 2859 (void) no_memory(hdl); 2860 2861 (void) close(fd); 2862 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2863 "unable to read disk capacity"), name); 2864 2865 return (zfs_error(hdl, EZFS_NOCAP, errbuf)); 2866 } 2867 2868 slice_size = vtoc->efi_last_u_lba + 1; 2869 slice_size -= EFI_MIN_RESV_SIZE; 2870 if (start_block == MAXOFFSET_T) 2871 start_block = NEW_START_BLOCK; 2872 slice_size -= start_block; 2873 2874 vtoc->efi_parts[0].p_start = start_block; 2875 vtoc->efi_parts[0].p_size = slice_size; 2876 2877 /* 2878 * Why we use V_USR: V_BACKUP confuses users, and is considered 2879 * disposable by some EFI utilities (since EFI doesn't have a backup 2880 * slice). V_UNASSIGNED is supposed to be used only for zero size 2881 * partitions, and efi_write() will fail if we use it. V_ROOT, V_BOOT, 2882 * etc. were all pretty specific. V_USR is as close to reality as we 2883 * can get, in the absence of V_OTHER. 2884 */ 2885 vtoc->efi_parts[0].p_tag = V_USR; 2886 (void) strcpy(vtoc->efi_parts[0].p_name, "zfs"); 2887 2888 vtoc->efi_parts[8].p_start = slice_size + start_block; 2889 vtoc->efi_parts[8].p_size = resv; 2890 vtoc->efi_parts[8].p_tag = V_RESERVED; 2891 2892 if (efi_write(fd, vtoc) != 0) { 2893 /* 2894 * Some block drivers (like pcata) may not support EFI 2895 * GPT labels. Print out a helpful error message dir- 2896 * ecting the user to manually label the disk and give 2897 * a specific slice. 2898 */ 2899 (void) close(fd); 2900 efi_free(vtoc); 2901 2902 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2903 "try using fdisk(1M) and then provide a specific slice")); 2904 return (zfs_error(hdl, EZFS_LABELFAILED, errbuf)); 2905 } 2906 2907 (void) close(fd); 2908 efi_free(vtoc); 2909#endif /* sun */ 2910 return (0); 2911} 2912 2913static boolean_t 2914supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf) 2915{ 2916 char *type; 2917 nvlist_t **child; 2918 uint_t children, c; 2919 2920 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0); 2921 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 || 2922 strcmp(type, VDEV_TYPE_FILE) == 0 || 2923 strcmp(type, VDEV_TYPE_LOG) == 0 || 2924 strcmp(type, VDEV_TYPE_MISSING) == 0) { 2925 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2926 "vdev type '%s' is not supported"), type); 2927 (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf); 2928 return (B_FALSE); 2929 } 2930 if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, 2931 &child, &children) == 0) { 2932 for (c = 0; c < children; c++) { 2933 if (!supported_dump_vdev_type(hdl, child[c], errbuf)) 2934 return (B_FALSE); 2935 } 2936 } 2937 return (B_TRUE); 2938} 2939 2940/* 2941 * check if this zvol is allowable for use as a dump device; zero if 2942 * it is, > 0 if it isn't, < 0 if it isn't a zvol 2943 */ 2944int 2945zvol_check_dump_config(char *arg) 2946{ 2947 zpool_handle_t *zhp = NULL; 2948 nvlist_t *config, *nvroot; 2949 char *p, *volname; 2950 nvlist_t **top; 2951 uint_t toplevels; 2952 libzfs_handle_t *hdl; 2953 char errbuf[1024]; 2954 char poolname[ZPOOL_MAXNAMELEN]; 2955 int pathlen = strlen(ZVOL_FULL_DEV_DIR); 2956 int ret = 1; 2957 2958 if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) { 2959 return (-1); 2960 } 2961 2962 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, 2963 "dump is not supported on device '%s'"), arg); 2964 2965 if ((hdl = libzfs_init()) == NULL) 2966 return (1); 2967 libzfs_print_on_error(hdl, B_TRUE); 2968 2969 volname = arg + pathlen; 2970 2971 /* check the configuration of the pool */ 2972 if ((p = strchr(volname, '/')) == NULL) { 2973 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2974 "malformed dataset name")); 2975 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf); 2976 return (1); 2977 } else if (p - volname >= ZFS_MAXNAMELEN) { 2978 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2979 "dataset name is too long")); 2980 (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf); 2981 return (1); 2982 } else { 2983 (void) strncpy(poolname, volname, p - volname); 2984 poolname[p - volname] = '\0'; 2985 } 2986 2987 if ((zhp = zpool_open(hdl, poolname)) == NULL) { 2988 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2989 "could not open pool '%s'"), poolname); 2990 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf); 2991 goto out; 2992 } 2993 config = zpool_get_config(zhp, NULL); 2994 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2995 &nvroot) != 0) { 2996 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 2997 "could not obtain vdev configuration for '%s'"), poolname); 2998 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf); 2999 goto out; 3000 } 3001 3002 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 3003 &top, &toplevels) == 0); 3004 if (toplevels != 1) { 3005 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 3006 "'%s' has multiple top level vdevs"), poolname); 3007 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf); 3008 goto out; 3009 } 3010 3011 if (!supported_dump_vdev_type(hdl, top[0], errbuf)) { 3012 goto out; 3013 } 3014 ret = 0; 3015 3016out: 3017 if (zhp) 3018 zpool_close(zhp); 3019 libzfs_fini(hdl); 3020 return (ret); 3021} 3022