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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <assert.h> 30 #include <ctype.h> 31 #include <errno.h> 32 #include <devid.h> 33 #include <fcntl.h> 34 #include <libintl.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include <sys/zfs_ioctl.h> 40 #include <sys/zio.h> 41 42 #include "zfs_namecheck.h" 43 #include "libzfs_impl.h" 44 45 /* 46 * Validate the given pool name, optionally putting an extended error message in 47 * 'buf'. 48 */ 49 static boolean_t 50 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool) 51 { 52 namecheck_err_t why; 53 char what; 54 int ret; 55 56 ret = pool_namecheck(pool, &why, &what); 57 58 /* 59 * The rules for reserved pool names were extended at a later point. 60 * But we need to support users with existing pools that may now be 61 * invalid. So we only check for this expanded set of names during a 62 * create (or import), and only in userland. 63 */ 64 if (ret == 0 && !isopen && 65 (strncmp(pool, "mirror", 6) == 0 || 66 strncmp(pool, "raidz", 5) == 0 || 67 strncmp(pool, "spare", 5) == 0)) { 68 zfs_error_aux(hdl, 69 dgettext(TEXT_DOMAIN, "name is reserved")); 70 return (B_FALSE); 71 } 72 73 74 if (ret != 0) { 75 if (hdl != NULL) { 76 switch (why) { 77 case NAME_ERR_TOOLONG: 78 zfs_error_aux(hdl, 79 dgettext(TEXT_DOMAIN, "name is too long")); 80 break; 81 82 case NAME_ERR_INVALCHAR: 83 zfs_error_aux(hdl, 84 dgettext(TEXT_DOMAIN, "invalid character " 85 "'%c' in pool name"), what); 86 break; 87 88 case NAME_ERR_NOLETTER: 89 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 90 "name must begin with a letter")); 91 break; 92 93 case NAME_ERR_RESERVED: 94 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 95 "name is reserved")); 96 break; 97 98 case NAME_ERR_DISKLIKE: 99 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 100 "pool name is reserved")); 101 break; 102 103 case NAME_ERR_LEADING_SLASH: 104 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 105 "leading slash in name")); 106 break; 107 108 case NAME_ERR_EMPTY_COMPONENT: 109 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 110 "empty component in name")); 111 break; 112 113 case NAME_ERR_TRAILING_SLASH: 114 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 115 "trailing slash in name")); 116 break; 117 118 case NAME_ERR_MULTIPLE_AT: 119 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 120 "multiple '@' delimiters in name")); 121 break; 122 123 } 124 } 125 return (B_FALSE); 126 } 127 128 return (B_TRUE); 129 } 130 131 /* 132 * Set the pool-wide health based on the vdev state of the root vdev. 133 */ 134 int 135 set_pool_health(nvlist_t *config) 136 { 137 nvlist_t *nvroot; 138 vdev_stat_t *vs; 139 uint_t vsc; 140 char *health; 141 142 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 143 &nvroot) == 0); 144 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 145 (uint64_t **)&vs, &vsc) == 0); 146 147 switch (vs->vs_state) { 148 149 case VDEV_STATE_CLOSED: 150 case VDEV_STATE_CANT_OPEN: 151 case VDEV_STATE_OFFLINE: 152 health = dgettext(TEXT_DOMAIN, "FAULTED"); 153 break; 154 155 case VDEV_STATE_DEGRADED: 156 health = dgettext(TEXT_DOMAIN, "DEGRADED"); 157 break; 158 159 case VDEV_STATE_HEALTHY: 160 health = dgettext(TEXT_DOMAIN, "ONLINE"); 161 break; 162 163 default: 164 abort(); 165 } 166 167 return (nvlist_add_string(config, ZPOOL_CONFIG_POOL_HEALTH, health)); 168 } 169 170 /* 171 * Open a handle to the given pool, even if the pool is currently in the FAULTED 172 * state. 173 */ 174 zpool_handle_t * 175 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool) 176 { 177 zpool_handle_t *zhp; 178 boolean_t missing; 179 180 /* 181 * Make sure the pool name is valid. 182 */ 183 if (!zpool_name_valid(hdl, B_TRUE, pool)) { 184 (void) zfs_error(hdl, EZFS_INVALIDNAME, 185 dgettext(TEXT_DOMAIN, "cannot open '%s'"), 186 pool); 187 return (NULL); 188 } 189 190 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL) 191 return (NULL); 192 193 zhp->zpool_hdl = hdl; 194 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 195 196 if (zpool_refresh_stats(zhp, &missing) != 0) { 197 zpool_close(zhp); 198 return (NULL); 199 } 200 201 if (missing) { 202 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 203 "no such pool")); 204 (void) zfs_error(hdl, EZFS_NOENT, 205 dgettext(TEXT_DOMAIN, "cannot open '%s'"), 206 pool); 207 zpool_close(zhp); 208 return (NULL); 209 } 210 211 return (zhp); 212 } 213 214 /* 215 * Like the above, but silent on error. Used when iterating over pools (because 216 * the configuration cache may be out of date). 217 */ 218 int 219 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret) 220 { 221 zpool_handle_t *zhp; 222 boolean_t missing; 223 224 if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL) 225 return (-1); 226 227 zhp->zpool_hdl = hdl; 228 (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 229 230 if (zpool_refresh_stats(zhp, &missing) != 0) { 231 zpool_close(zhp); 232 return (-1); 233 } 234 235 if (missing) { 236 zpool_close(zhp); 237 *ret = NULL; 238 return (0); 239 } 240 241 *ret = zhp; 242 return (0); 243 } 244 245 /* 246 * Similar to zpool_open_canfail(), but refuses to open pools in the faulted 247 * state. 248 */ 249 zpool_handle_t * 250 zpool_open(libzfs_handle_t *hdl, const char *pool) 251 { 252 zpool_handle_t *zhp; 253 254 if ((zhp = zpool_open_canfail(hdl, pool)) == NULL) 255 return (NULL); 256 257 if (zhp->zpool_state == POOL_STATE_UNAVAIL) { 258 (void) zfs_error(hdl, EZFS_POOLUNAVAIL, 259 dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name); 260 zpool_close(zhp); 261 return (NULL); 262 } 263 264 return (zhp); 265 } 266 267 /* 268 * Close the handle. Simply frees the memory associated with the handle. 269 */ 270 void 271 zpool_close(zpool_handle_t *zhp) 272 { 273 if (zhp->zpool_config) 274 nvlist_free(zhp->zpool_config); 275 if (zhp->zpool_old_config) 276 nvlist_free(zhp->zpool_old_config); 277 if (zhp->zpool_error_log) { 278 int i; 279 for (i = 0; i < zhp->zpool_error_count; i++) 280 nvlist_free(zhp->zpool_error_log[i]); 281 free(zhp->zpool_error_log); 282 } 283 free(zhp); 284 } 285 286 /* 287 * Return the name of the pool. 288 */ 289 const char * 290 zpool_get_name(zpool_handle_t *zhp) 291 { 292 return (zhp->zpool_name); 293 } 294 295 /* 296 * Return the GUID of the pool. 297 */ 298 uint64_t 299 zpool_get_guid(zpool_handle_t *zhp) 300 { 301 uint64_t guid; 302 303 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID, 304 &guid) == 0); 305 return (guid); 306 } 307 308 /* 309 * Return the version of the pool. 310 */ 311 uint64_t 312 zpool_get_version(zpool_handle_t *zhp) 313 { 314 uint64_t version; 315 316 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_VERSION, 317 &version) == 0); 318 319 return (version); 320 } 321 322 /* 323 * Return the amount of space currently consumed by the pool. 324 */ 325 uint64_t 326 zpool_get_space_used(zpool_handle_t *zhp) 327 { 328 nvlist_t *nvroot; 329 vdev_stat_t *vs; 330 uint_t vsc; 331 332 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 333 &nvroot) == 0); 334 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 335 (uint64_t **)&vs, &vsc) == 0); 336 337 return (vs->vs_alloc); 338 } 339 340 /* 341 * Return the total space in the pool. 342 */ 343 uint64_t 344 zpool_get_space_total(zpool_handle_t *zhp) 345 { 346 nvlist_t *nvroot; 347 vdev_stat_t *vs; 348 uint_t vsc; 349 350 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 351 &nvroot) == 0); 352 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 353 (uint64_t **)&vs, &vsc) == 0); 354 355 return (vs->vs_space); 356 } 357 358 /* 359 * Return the alternate root for this pool, if any. 360 */ 361 int 362 zpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen) 363 { 364 zfs_cmd_t zc = { 0 }; 365 366 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 367 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 || 368 zc.zc_value[0] == '\0') 369 return (-1); 370 371 (void) strlcpy(buf, zc.zc_value, buflen); 372 373 return (0); 374 } 375 376 /* 377 * Return the state of the pool (ACTIVE or UNAVAILABLE) 378 */ 379 int 380 zpool_get_state(zpool_handle_t *zhp) 381 { 382 return (zhp->zpool_state); 383 } 384 385 /* 386 * Create the named pool, using the provided vdev list. It is assumed 387 * that the consumer has already validated the contents of the nvlist, so we 388 * don't have to worry about error semantics. 389 */ 390 int 391 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, 392 const char *altroot) 393 { 394 zfs_cmd_t zc = { 0 }; 395 char msg[1024]; 396 397 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 398 "cannot create '%s'"), pool); 399 400 if (!zpool_name_valid(hdl, B_FALSE, pool)) 401 return (zfs_error(hdl, EZFS_INVALIDNAME, msg)); 402 403 if (altroot != NULL && altroot[0] != '/') 404 return (zfs_error(hdl, EZFS_BADPATH, 405 dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot)); 406 407 if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0) 408 return (-1); 409 410 (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); 411 412 if (altroot != NULL) 413 (void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value)); 414 415 if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) { 416 zcmd_free_nvlists(&zc); 417 418 switch (errno) { 419 case EBUSY: 420 /* 421 * This can happen if the user has specified the same 422 * device multiple times. We can't reliably detect this 423 * until we try to add it and see we already have a 424 * label. 425 */ 426 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 427 "one or more vdevs refer to the same device")); 428 return (zfs_error(hdl, EZFS_BADDEV, msg)); 429 430 case EOVERFLOW: 431 /* 432 * This occurs when one of the devices is below 433 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 434 * device was the problem device since there's no 435 * reliable way to determine device size from userland. 436 */ 437 { 438 char buf[64]; 439 440 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 441 442 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 443 "one or more devices is less than the " 444 "minimum size (%s)"), buf); 445 } 446 return (zfs_error(hdl, EZFS_BADDEV, msg)); 447 448 case ENOSPC: 449 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 450 "one or more devices is out of space")); 451 return (zfs_error(hdl, EZFS_BADDEV, msg)); 452 453 default: 454 return (zpool_standard_error(hdl, errno, msg)); 455 } 456 } 457 458 zcmd_free_nvlists(&zc); 459 460 /* 461 * If this is an alternate root pool, then we automatically set the 462 * mountpoint of the root dataset to be '/'. 463 */ 464 if (altroot != NULL) { 465 zfs_handle_t *zhp; 466 467 verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_ANY)) != NULL); 468 verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 469 "/") == 0); 470 471 zfs_close(zhp); 472 } 473 474 return (0); 475 } 476 477 /* 478 * Destroy the given pool. It is up to the caller to ensure that there are no 479 * datasets left in the pool. 480 */ 481 int 482 zpool_destroy(zpool_handle_t *zhp) 483 { 484 zfs_cmd_t zc = { 0 }; 485 zfs_handle_t *zfp = NULL; 486 libzfs_handle_t *hdl = zhp->zpool_hdl; 487 char msg[1024]; 488 489 if (zhp->zpool_state == POOL_STATE_ACTIVE && 490 (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name, 491 ZFS_TYPE_FILESYSTEM)) == NULL) 492 return (-1); 493 494 if (zpool_remove_zvol_links(zhp) != 0) 495 return (-1); 496 497 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 498 499 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) { 500 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 501 "cannot destroy '%s'"), zhp->zpool_name); 502 503 if (errno == EROFS) { 504 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 505 "one or more devices is read only")); 506 (void) zfs_error(hdl, EZFS_BADDEV, msg); 507 } else { 508 (void) zpool_standard_error(hdl, errno, msg); 509 } 510 511 if (zfp) 512 zfs_close(zfp); 513 return (-1); 514 } 515 516 if (zfp) { 517 remove_mountpoint(zfp); 518 zfs_close(zfp); 519 } 520 521 return (0); 522 } 523 524 /* 525 * Add the given vdevs to the pool. The caller must have already performed the 526 * necessary verification to ensure that the vdev specification is well-formed. 527 */ 528 int 529 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) 530 { 531 zfs_cmd_t zc = { 0 }; 532 int ret; 533 libzfs_handle_t *hdl = zhp->zpool_hdl; 534 char msg[1024]; 535 nvlist_t **spares; 536 uint_t nspares; 537 538 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 539 "cannot add to '%s'"), zhp->zpool_name); 540 541 if (zpool_get_version(zhp) < ZFS_VERSION_SPARES && 542 nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 543 &spares, &nspares) == 0) { 544 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be " 545 "upgraded to add hot spares")); 546 return (zfs_error(hdl, EZFS_BADVERSION, msg)); 547 } 548 549 if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0) 550 return (-1); 551 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 552 553 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) { 554 switch (errno) { 555 case EBUSY: 556 /* 557 * This can happen if the user has specified the same 558 * device multiple times. We can't reliably detect this 559 * until we try to add it and see we already have a 560 * label. 561 */ 562 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 563 "one or more vdevs refer to the same device")); 564 (void) zfs_error(hdl, EZFS_BADDEV, msg); 565 break; 566 567 case EOVERFLOW: 568 /* 569 * This occurrs when one of the devices is below 570 * SPA_MINDEVSIZE. Unfortunately, we can't detect which 571 * device was the problem device since there's no 572 * reliable way to determine device size from userland. 573 */ 574 { 575 char buf[64]; 576 577 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 578 579 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 580 "device is less than the minimum " 581 "size (%s)"), buf); 582 } 583 (void) zfs_error(hdl, EZFS_BADDEV, msg); 584 break; 585 586 case ENOTSUP: 587 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 588 "pool must be upgraded to add raidz2 vdevs")); 589 (void) zfs_error(hdl, EZFS_BADVERSION, msg); 590 break; 591 592 default: 593 (void) zpool_standard_error(hdl, errno, msg); 594 } 595 596 ret = -1; 597 } else { 598 ret = 0; 599 } 600 601 zcmd_free_nvlists(&zc); 602 603 return (ret); 604 } 605 606 /* 607 * Exports the pool from the system. The caller must ensure that there are no 608 * mounted datasets in the pool. 609 */ 610 int 611 zpool_export(zpool_handle_t *zhp) 612 { 613 zfs_cmd_t zc = { 0 }; 614 615 if (zpool_remove_zvol_links(zhp) != 0) 616 return (-1); 617 618 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 619 620 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_EXPORT, &zc) != 0) 621 return (zpool_standard_error(zhp->zpool_hdl, errno, 622 dgettext(TEXT_DOMAIN, "cannot export '%s'"), 623 zhp->zpool_name)); 624 625 return (0); 626 } 627 628 /* 629 * Import the given pool using the known configuration. The configuration 630 * should have come from zpool_find_import(). The 'newname' and 'altroot' 631 * parameters control whether the pool is imported with a different name or with 632 * an alternate root, respectively. 633 */ 634 int 635 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, 636 const char *altroot) 637 { 638 zfs_cmd_t zc = { 0 }; 639 char *thename; 640 char *origname; 641 int ret; 642 643 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 644 &origname) == 0); 645 646 if (newname != NULL) { 647 if (!zpool_name_valid(hdl, B_FALSE, newname)) 648 return (zfs_error(hdl, EZFS_INVALIDNAME, 649 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 650 newname)); 651 thename = (char *)newname; 652 } else { 653 thename = origname; 654 } 655 656 if (altroot != NULL && altroot[0] != '/') 657 return (zfs_error(hdl, EZFS_BADPATH, 658 dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), 659 altroot)); 660 661 (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); 662 663 if (altroot != NULL) 664 (void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value)); 665 else 666 zc.zc_value[0] = '\0'; 667 668 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 669 &zc.zc_guid) == 0); 670 671 if (zcmd_write_src_nvlist(hdl, &zc, config, NULL) != 0) 672 return (-1); 673 674 ret = 0; 675 if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) { 676 char desc[1024]; 677 if (newname == NULL) 678 (void) snprintf(desc, sizeof (desc), 679 dgettext(TEXT_DOMAIN, "cannot import '%s'"), 680 thename); 681 else 682 (void) snprintf(desc, sizeof (desc), 683 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), 684 origname, thename); 685 686 switch (errno) { 687 case ENOTSUP: 688 /* 689 * Unsupported version. 690 */ 691 (void) zfs_error(hdl, EZFS_BADVERSION, desc); 692 break; 693 694 case EINVAL: 695 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc); 696 break; 697 698 default: 699 (void) zpool_standard_error(hdl, errno, desc); 700 } 701 702 ret = -1; 703 } else { 704 zpool_handle_t *zhp; 705 /* 706 * This should never fail, but play it safe anyway. 707 */ 708 if (zpool_open_silent(hdl, thename, &zhp) != 0) { 709 ret = -1; 710 } else if (zhp != NULL) { 711 ret = zpool_create_zvol_links(zhp); 712 zpool_close(zhp); 713 } 714 } 715 716 zcmd_free_nvlists(&zc); 717 return (ret); 718 } 719 720 /* 721 * Scrub the pool. 722 */ 723 int 724 zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type) 725 { 726 zfs_cmd_t zc = { 0 }; 727 char msg[1024]; 728 libzfs_handle_t *hdl = zhp->zpool_hdl; 729 730 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 731 zc.zc_cookie = type; 732 733 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_SCRUB, &zc) == 0) 734 return (0); 735 736 (void) snprintf(msg, sizeof (msg), 737 dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name); 738 739 if (errno == EBUSY) 740 return (zfs_error(hdl, EZFS_RESILVERING, msg)); 741 else 742 return (zpool_standard_error(hdl, errno, msg)); 743 } 744 745 /* 746 * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL 747 * spare; but FALSE if its an INUSE spare. 748 */ 749 static nvlist_t * 750 vdev_to_nvlist_iter(nvlist_t *nv, const char *search, uint64_t guid, 751 boolean_t *avail_spare) 752 { 753 uint_t c, children; 754 nvlist_t **child; 755 uint64_t theguid, present; 756 char *path; 757 uint64_t wholedisk = 0; 758 nvlist_t *ret; 759 760 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &theguid) == 0); 761 762 if (search == NULL && 763 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) { 764 /* 765 * If the device has never been present since import, the only 766 * reliable way to match the vdev is by GUID. 767 */ 768 if (theguid == guid) 769 return (nv); 770 } else if (search != NULL && 771 nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 772 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 773 &wholedisk); 774 if (wholedisk) { 775 /* 776 * For whole disks, the internal path has 's0', but the 777 * path passed in by the user doesn't. 778 */ 779 if (strlen(search) == strlen(path) - 2 && 780 strncmp(search, path, strlen(search)) == 0) 781 return (nv); 782 } else if (strcmp(search, path) == 0) { 783 return (nv); 784 } 785 } 786 787 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 788 &child, &children) != 0) 789 return (NULL); 790 791 for (c = 0; c < children; c++) 792 if ((ret = vdev_to_nvlist_iter(child[c], search, guid, 793 avail_spare)) != NULL) 794 return (ret); 795 796 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 797 &child, &children) == 0) { 798 for (c = 0; c < children; c++) { 799 if ((ret = vdev_to_nvlist_iter(child[c], search, guid, 800 avail_spare)) != NULL) { 801 *avail_spare = B_TRUE; 802 return (ret); 803 } 804 } 805 } 806 807 return (NULL); 808 } 809 810 nvlist_t * 811 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare) 812 { 813 char buf[MAXPATHLEN]; 814 const char *search; 815 char *end; 816 nvlist_t *nvroot; 817 uint64_t guid; 818 819 guid = strtoull(path, &end, 10); 820 if (guid != 0 && *end == '\0') { 821 search = NULL; 822 } else if (path[0] != '/') { 823 (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path); 824 search = buf; 825 } else { 826 search = path; 827 } 828 829 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 830 &nvroot) == 0); 831 832 *avail_spare = B_FALSE; 833 return (vdev_to_nvlist_iter(nvroot, search, guid, avail_spare)); 834 } 835 836 /* 837 * Returns TRUE if the given guid corresponds to a spare (INUSE or not). 838 */ 839 static boolean_t 840 is_spare(zpool_handle_t *zhp, uint64_t guid) 841 { 842 uint64_t spare_guid; 843 nvlist_t *nvroot; 844 nvlist_t **spares; 845 uint_t nspares; 846 int i; 847 848 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 849 &nvroot) == 0); 850 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 851 &spares, &nspares) == 0) { 852 for (i = 0; i < nspares; i++) { 853 verify(nvlist_lookup_uint64(spares[i], 854 ZPOOL_CONFIG_GUID, &spare_guid) == 0); 855 if (guid == spare_guid) 856 return (B_TRUE); 857 } 858 } 859 860 return (B_FALSE); 861 } 862 863 /* 864 * Bring the specified vdev online 865 */ 866 int 867 zpool_vdev_online(zpool_handle_t *zhp, const char *path) 868 { 869 zfs_cmd_t zc = { 0 }; 870 char msg[1024]; 871 nvlist_t *tgt; 872 boolean_t avail_spare; 873 libzfs_handle_t *hdl = zhp->zpool_hdl; 874 875 (void) snprintf(msg, sizeof (msg), 876 dgettext(TEXT_DOMAIN, "cannot online %s"), path); 877 878 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 879 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == NULL) 880 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 881 882 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 883 884 if (avail_spare || is_spare(zhp, zc.zc_guid) == B_TRUE) 885 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 886 887 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ONLINE, &zc) == 0) 888 return (0); 889 890 return (zpool_standard_error(hdl, errno, msg)); 891 } 892 893 /* 894 * Take the specified vdev offline 895 */ 896 int 897 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, int istmp) 898 { 899 zfs_cmd_t zc = { 0 }; 900 char msg[1024]; 901 nvlist_t *tgt; 902 boolean_t avail_spare; 903 libzfs_handle_t *hdl = zhp->zpool_hdl; 904 905 (void) snprintf(msg, sizeof (msg), 906 dgettext(TEXT_DOMAIN, "cannot offline %s"), path); 907 908 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 909 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == NULL) 910 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 911 912 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 913 914 if (avail_spare || is_spare(zhp, zc.zc_guid) == B_TRUE) 915 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 916 917 zc.zc_cookie = istmp; 918 919 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_OFFLINE, &zc) == 0) 920 return (0); 921 922 switch (errno) { 923 case EBUSY: 924 925 /* 926 * There are no other replicas of this device. 927 */ 928 return (zfs_error(hdl, EZFS_NOREPLICAS, msg)); 929 930 default: 931 return (zpool_standard_error(hdl, errno, msg)); 932 } 933 } 934 935 /* 936 * Returns TRUE if the given nvlist is a vdev that was originally swapped in as 937 * a hot spare. 938 */ 939 static boolean_t 940 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which) 941 { 942 nvlist_t **child; 943 uint_t c, children; 944 char *type; 945 946 if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child, 947 &children) == 0) { 948 verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE, 949 &type) == 0); 950 951 if (strcmp(type, VDEV_TYPE_SPARE) == 0 && 952 children == 2 && child[which] == tgt) 953 return (B_TRUE); 954 955 for (c = 0; c < children; c++) 956 if (is_replacing_spare(child[c], tgt, which)) 957 return (B_TRUE); 958 } 959 960 return (B_FALSE); 961 } 962 963 /* 964 * Attach new_disk (fully described by nvroot) to old_disk. 965 * If 'replacing' is specified, tne new disk will replace the old one. 966 */ 967 int 968 zpool_vdev_attach(zpool_handle_t *zhp, 969 const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing) 970 { 971 zfs_cmd_t zc = { 0 }; 972 char msg[1024]; 973 int ret; 974 nvlist_t *tgt; 975 boolean_t avail_spare; 976 uint64_t val; 977 char *path; 978 nvlist_t **child; 979 uint_t children; 980 nvlist_t *config_root; 981 libzfs_handle_t *hdl = zhp->zpool_hdl; 982 983 if (replacing) 984 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 985 "cannot replace %s with %s"), old_disk, new_disk); 986 else 987 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 988 "cannot attach %s to %s"), new_disk, old_disk); 989 990 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 991 if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare)) == 0) 992 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 993 994 if (avail_spare) 995 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 996 997 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 998 zc.zc_cookie = replacing; 999 1000 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 1001 &child, &children) != 0 || children != 1) { 1002 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1003 "new device must be a single disk")); 1004 return (zfs_error(hdl, EZFS_INVALCONFIG, msg)); 1005 } 1006 1007 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 1008 ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0); 1009 1010 /* 1011 * If the target is a hot spare that has been swapped in, we can only 1012 * replace it with another hot spare. 1013 */ 1014 if (replacing && 1015 nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 && 1016 nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && 1017 (zpool_find_vdev(zhp, path, &avail_spare) == NULL || 1018 !avail_spare) && is_replacing_spare(config_root, tgt, 1)) { 1019 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1020 "can only be replaced by another hot spare")); 1021 return (zfs_error(hdl, EZFS_BADTARGET, msg)); 1022 } 1023 1024 /* 1025 * If we are attempting to replace a spare, it canot be applied to an 1026 * already spared device. 1027 */ 1028 if (replacing && 1029 nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 && 1030 zpool_find_vdev(zhp, path, &avail_spare) != NULL && avail_spare && 1031 is_replacing_spare(config_root, tgt, 0)) { 1032 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1033 "device has already been replaced with a spare")); 1034 return (zfs_error(hdl, EZFS_BADTARGET, msg)); 1035 } 1036 1037 if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0) 1038 return (-1); 1039 1040 ret = ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ATTACH, &zc); 1041 1042 zcmd_free_nvlists(&zc); 1043 1044 if (ret == 0) 1045 return (0); 1046 1047 switch (errno) { 1048 case ENOTSUP: 1049 /* 1050 * Can't attach to or replace this type of vdev. 1051 */ 1052 if (replacing) 1053 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1054 "cannot replace a replacing device")); 1055 else 1056 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1057 "can only attach to mirrors and top-level " 1058 "disks")); 1059 (void) zfs_error(hdl, EZFS_BADTARGET, msg); 1060 break; 1061 1062 case EINVAL: 1063 /* 1064 * The new device must be a single disk. 1065 */ 1066 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1067 "new device must be a single disk")); 1068 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg); 1069 break; 1070 1071 case EBUSY: 1072 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"), 1073 new_disk); 1074 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1075 break; 1076 1077 case EOVERFLOW: 1078 /* 1079 * The new device is too small. 1080 */ 1081 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1082 "device is too small")); 1083 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1084 break; 1085 1086 case EDOM: 1087 /* 1088 * The new device has a different alignment requirement. 1089 */ 1090 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1091 "devices have different sector alignment")); 1092 (void) zfs_error(hdl, EZFS_BADDEV, msg); 1093 break; 1094 1095 case ENAMETOOLONG: 1096 /* 1097 * The resulting top-level vdev spec won't fit in the label. 1098 */ 1099 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg); 1100 break; 1101 1102 default: 1103 (void) zpool_standard_error(hdl, errno, msg); 1104 } 1105 1106 return (-1); 1107 } 1108 1109 /* 1110 * Detach the specified device. 1111 */ 1112 int 1113 zpool_vdev_detach(zpool_handle_t *zhp, const char *path) 1114 { 1115 zfs_cmd_t zc = { 0 }; 1116 char msg[1024]; 1117 nvlist_t *tgt; 1118 boolean_t avail_spare; 1119 libzfs_handle_t *hdl = zhp->zpool_hdl; 1120 1121 (void) snprintf(msg, sizeof (msg), 1122 dgettext(TEXT_DOMAIN, "cannot detach %s"), path); 1123 1124 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1125 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0) 1126 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1127 1128 if (avail_spare) 1129 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1130 1131 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1132 1133 if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_DETACH, &zc) == 0) 1134 return (0); 1135 1136 switch (errno) { 1137 1138 case ENOTSUP: 1139 /* 1140 * Can't detach from this type of vdev. 1141 */ 1142 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only " 1143 "applicable to mirror and replacing vdevs")); 1144 (void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg); 1145 break; 1146 1147 case EBUSY: 1148 /* 1149 * There are no other replicas of this device. 1150 */ 1151 (void) zfs_error(hdl, EZFS_NOREPLICAS, msg); 1152 break; 1153 1154 default: 1155 (void) zpool_standard_error(hdl, errno, msg); 1156 } 1157 1158 return (-1); 1159 } 1160 1161 /* 1162 * Remove the given device. Currently, this is supported only for hot spares. 1163 */ 1164 int 1165 zpool_vdev_remove(zpool_handle_t *zhp, const char *path) 1166 { 1167 zfs_cmd_t zc = { 0 }; 1168 char msg[1024]; 1169 nvlist_t *tgt; 1170 boolean_t avail_spare; 1171 libzfs_handle_t *hdl = zhp->zpool_hdl; 1172 1173 (void) snprintf(msg, sizeof (msg), 1174 dgettext(TEXT_DOMAIN, "cannot remove %s"), path); 1175 1176 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1177 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0) 1178 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1179 1180 if (!avail_spare) { 1181 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1182 "only hot spares can be removed")); 1183 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1184 } 1185 1186 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0); 1187 1188 if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_REMOVE, &zc) == 0) 1189 return (0); 1190 1191 return (zpool_standard_error(hdl, errno, msg)); 1192 } 1193 1194 /* 1195 * Clear the errors for the pool, or the particular device if specified. 1196 */ 1197 int 1198 zpool_clear(zpool_handle_t *zhp, const char *path) 1199 { 1200 zfs_cmd_t zc = { 0 }; 1201 char msg[1024]; 1202 nvlist_t *tgt; 1203 boolean_t avail_spare; 1204 libzfs_handle_t *hdl = zhp->zpool_hdl; 1205 1206 if (path) 1207 (void) snprintf(msg, sizeof (msg), 1208 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1209 path); 1210 else 1211 (void) snprintf(msg, sizeof (msg), 1212 dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1213 zhp->zpool_name); 1214 1215 (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1216 if (path) { 1217 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare)) == 0) 1218 return (zfs_error(hdl, EZFS_NODEVICE, msg)); 1219 1220 if (avail_spare) 1221 return (zfs_error(hdl, EZFS_ISSPARE, msg)); 1222 1223 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, 1224 &zc.zc_guid) == 0); 1225 } 1226 1227 if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0) 1228 return (0); 1229 1230 return (zpool_standard_error(hdl, errno, msg)); 1231 } 1232 1233 static int 1234 do_zvol(zfs_handle_t *zhp, void *data) 1235 { 1236 int linktype = (int)(uintptr_t)data; 1237 int ret; 1238 1239 /* 1240 * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we 1241 * correctly handle snapshots of volumes. 1242 */ 1243 if (ZFS_IS_VOLUME(zhp)) { 1244 if (linktype) 1245 ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name); 1246 else 1247 ret = zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name); 1248 } 1249 1250 ret = zfs_iter_children(zhp, do_zvol, data); 1251 1252 zfs_close(zhp); 1253 return (ret); 1254 } 1255 1256 /* 1257 * Iterate over all zvols in the pool and make any necessary minor nodes. 1258 */ 1259 int 1260 zpool_create_zvol_links(zpool_handle_t *zhp) 1261 { 1262 zfs_handle_t *zfp; 1263 int ret; 1264 1265 /* 1266 * If the pool is unavailable, just return success. 1267 */ 1268 if ((zfp = make_dataset_handle(zhp->zpool_hdl, 1269 zhp->zpool_name)) == NULL) 1270 return (0); 1271 1272 ret = zfs_iter_children(zfp, do_zvol, (void *)B_TRUE); 1273 1274 zfs_close(zfp); 1275 return (ret); 1276 } 1277 1278 /* 1279 * Iterate over all zvols in the poool and remove any minor nodes. 1280 */ 1281 int 1282 zpool_remove_zvol_links(zpool_handle_t *zhp) 1283 { 1284 zfs_handle_t *zfp; 1285 int ret; 1286 1287 /* 1288 * If the pool is unavailable, just return success. 1289 */ 1290 if ((zfp = make_dataset_handle(zhp->zpool_hdl, 1291 zhp->zpool_name)) == NULL) 1292 return (0); 1293 1294 ret = zfs_iter_children(zfp, do_zvol, (void *)B_FALSE); 1295 1296 zfs_close(zfp); 1297 return (ret); 1298 } 1299 1300 /* 1301 * Convert from a devid string to a path. 1302 */ 1303 static char * 1304 devid_to_path(char *devid_str) 1305 { 1306 ddi_devid_t devid; 1307 char *minor; 1308 char *path; 1309 devid_nmlist_t *list = NULL; 1310 int ret; 1311 1312 if (devid_str_decode(devid_str, &devid, &minor) != 0) 1313 return (NULL); 1314 1315 ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list); 1316 1317 devid_str_free(minor); 1318 devid_free(devid); 1319 1320 if (ret != 0) 1321 return (NULL); 1322 1323 if ((path = strdup(list[0].devname)) == NULL) 1324 return (NULL); 1325 1326 devid_free_nmlist(list); 1327 1328 return (path); 1329 } 1330 1331 /* 1332 * Convert from a path to a devid string. 1333 */ 1334 static char * 1335 path_to_devid(const char *path) 1336 { 1337 int fd; 1338 ddi_devid_t devid; 1339 char *minor, *ret; 1340 1341 if ((fd = open(path, O_RDONLY)) < 0) 1342 return (NULL); 1343 1344 minor = NULL; 1345 ret = NULL; 1346 if (devid_get(fd, &devid) == 0) { 1347 if (devid_get_minor_name(fd, &minor) == 0) 1348 ret = devid_str_encode(devid, minor); 1349 if (minor != NULL) 1350 devid_str_free(minor); 1351 devid_free(devid); 1352 } 1353 (void) close(fd); 1354 1355 return (ret); 1356 } 1357 1358 /* 1359 * Issue the necessary ioctl() to update the stored path value for the vdev. We 1360 * ignore any failure here, since a common case is for an unprivileged user to 1361 * type 'zpool status', and we'll display the correct information anyway. 1362 */ 1363 static void 1364 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) 1365 { 1366 zfs_cmd_t zc = { 0 }; 1367 1368 (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1369 (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value)); 1370 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1371 &zc.zc_guid) == 0); 1372 1373 (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc); 1374 } 1375 1376 /* 1377 * Given a vdev, return the name to display in iostat. If the vdev has a path, 1378 * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. 1379 * We also check if this is a whole disk, in which case we strip off the 1380 * trailing 's0' slice name. 1381 * 1382 * This routine is also responsible for identifying when disks have been 1383 * reconfigured in a new location. The kernel will have opened the device by 1384 * devid, but the path will still refer to the old location. To catch this, we 1385 * first do a path -> devid translation (which is fast for the common case). If 1386 * the devid matches, we're done. If not, we do a reverse devid -> path 1387 * translation and issue the appropriate ioctl() to update the path of the vdev. 1388 * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any 1389 * of these checks. 1390 */ 1391 char * 1392 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv) 1393 { 1394 char *path, *devid; 1395 uint64_t value; 1396 char buf[64]; 1397 1398 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1399 &value) == 0) { 1400 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1401 &value) == 0); 1402 (void) snprintf(buf, sizeof (buf), "%llu", 1403 (u_longlong_t)value); 1404 path = buf; 1405 } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 1406 1407 if (zhp != NULL && 1408 nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { 1409 /* 1410 * Determine if the current path is correct. 1411 */ 1412 char *newdevid = path_to_devid(path); 1413 1414 if (newdevid == NULL || 1415 strcmp(devid, newdevid) != 0) { 1416 char *newpath; 1417 1418 if ((newpath = devid_to_path(devid)) != NULL) { 1419 /* 1420 * Update the path appropriately. 1421 */ 1422 set_path(zhp, nv, newpath); 1423 if (nvlist_add_string(nv, 1424 ZPOOL_CONFIG_PATH, newpath) == 0) 1425 verify(nvlist_lookup_string(nv, 1426 ZPOOL_CONFIG_PATH, 1427 &path) == 0); 1428 free(newpath); 1429 } 1430 } 1431 1432 if (newdevid) 1433 devid_str_free(newdevid); 1434 } 1435 1436 if (strncmp(path, "/dev/dsk/", 9) == 0) 1437 path += 9; 1438 1439 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 1440 &value) == 0 && value) { 1441 char *tmp = zfs_strdup(hdl, path); 1442 if (tmp == NULL) 1443 return (NULL); 1444 tmp[strlen(path) - 2] = '\0'; 1445 return (tmp); 1446 } 1447 } else { 1448 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0); 1449 1450 /* 1451 * If it's a raidz device, we need to stick in the parity level. 1452 */ 1453 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) { 1454 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY, 1455 &value) == 0); 1456 (void) snprintf(buf, sizeof (buf), "%s%llu", path, 1457 (u_longlong_t)value); 1458 path = buf; 1459 } 1460 } 1461 1462 return (zfs_strdup(hdl, path)); 1463 } 1464 1465 static int 1466 zbookmark_compare(const void *a, const void *b) 1467 { 1468 return (memcmp(a, b, sizeof (zbookmark_t))); 1469 } 1470 1471 /* 1472 * Retrieve the persistent error log, uniquify the members, and return to the 1473 * caller. 1474 */ 1475 int 1476 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem) 1477 { 1478 zfs_cmd_t zc = { 0 }; 1479 uint64_t count; 1480 zbookmark_t *zb = NULL; 1481 libzfs_handle_t *hdl = zhp->zpool_hdl; 1482 int i, j; 1483 1484 if (zhp->zpool_error_log != NULL) { 1485 *list = zhp->zpool_error_log; 1486 *nelem = zhp->zpool_error_count; 1487 return (0); 1488 } 1489 1490 /* 1491 * Retrieve the raw error list from the kernel. If the number of errors 1492 * has increased, allocate more space and continue until we get the 1493 * entire list. 1494 */ 1495 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT, 1496 &count) == 0); 1497 if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl, 1498 count * sizeof (zbookmark_t))) == (uintptr_t)NULL) 1499 return (-1); 1500 zc.zc_nvlist_dst_size = count; 1501 (void) strcpy(zc.zc_name, zhp->zpool_name); 1502 for (;;) { 1503 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG, 1504 &zc) != 0) { 1505 free((void *)(uintptr_t)zc.zc_nvlist_dst); 1506 if (errno == ENOMEM) { 1507 if ((zc.zc_nvlist_dst = (uintptr_t) 1508 zfs_alloc(zhp->zpool_hdl, 1509 zc.zc_nvlist_dst_size)) == (uintptr_t)NULL) 1510 return (-1); 1511 } else { 1512 return (-1); 1513 } 1514 } else { 1515 break; 1516 } 1517 } 1518 1519 /* 1520 * Sort the resulting bookmarks. This is a little confusing due to the 1521 * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last 1522 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks 1523 * _not_ copied as part of the process. So we point the start of our 1524 * array appropriate and decrement the total number of elements. 1525 */ 1526 zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) + 1527 zc.zc_nvlist_dst_size; 1528 count -= zc.zc_nvlist_dst_size; 1529 zc.zc_nvlist_dst = 0ULL; 1530 1531 qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare); 1532 1533 /* 1534 * Count the number of unique elements 1535 */ 1536 j = 0; 1537 for (i = 0; i < count; i++) { 1538 if (i > 0 && memcmp(&zb[i - 1], &zb[i], 1539 sizeof (zbookmark_t)) == 0) 1540 continue; 1541 j++; 1542 } 1543 1544 /* 1545 * If the user has only requested the number of items, return it now 1546 * without bothering with the extra work. 1547 */ 1548 if (list == NULL) { 1549 *nelem = j; 1550 free((void *)(uintptr_t)zc.zc_nvlist_dst); 1551 return (0); 1552 } 1553 1554 zhp->zpool_error_count = j; 1555 1556 /* 1557 * Allocate an array of nvlists to hold the results 1558 */ 1559 if ((zhp->zpool_error_log = zfs_alloc(zhp->zpool_hdl, 1560 j * sizeof (nvlist_t *))) == NULL) { 1561 free((void *)(uintptr_t)zc.zc_nvlist_dst); 1562 return (-1); 1563 } 1564 1565 /* 1566 * Fill in the results with names from the kernel. 1567 */ 1568 j = 0; 1569 for (i = 0; i < count; i++) { 1570 char buf[64]; 1571 nvlist_t *nv; 1572 1573 if (i > 0 && memcmp(&zb[i - 1], &zb[i], 1574 sizeof (zbookmark_t)) == 0) 1575 continue; 1576 1577 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) 1578 goto nomem; 1579 1580 zc.zc_bookmark = zb[i]; 1581 for (;;) { 1582 if (ioctl(zhp->zpool_hdl->libzfs_fd, 1583 ZFS_IOC_BOOKMARK_NAME, &zc) != 0) { 1584 if (errno == ENOMEM) { 1585 if (zcmd_expand_dst_nvlist(hdl, &zc) 1586 != 0) { 1587 zcmd_free_nvlists(&zc); 1588 goto nomem; 1589 } 1590 1591 continue; 1592 } else { 1593 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 1594 0) != 0) 1595 goto nomem; 1596 1597 zhp->zpool_error_log[j] = nv; 1598 (void) snprintf(buf, sizeof (buf), 1599 "%llx", (longlong_t) 1600 zb[i].zb_objset); 1601 if (nvlist_add_string(nv, 1602 ZPOOL_ERR_DATASET, buf) != 0) 1603 goto nomem; 1604 (void) snprintf(buf, sizeof (buf), 1605 "%llx", (longlong_t) 1606 zb[i].zb_object); 1607 if (nvlist_add_string(nv, 1608 ZPOOL_ERR_OBJECT, buf) != 0) 1609 goto nomem; 1610 (void) snprintf(buf, sizeof (buf), 1611 "lvl=%u blkid=%llu", 1612 (int)zb[i].zb_level, 1613 (long long)zb[i].zb_blkid); 1614 if (nvlist_add_string(nv, 1615 ZPOOL_ERR_RANGE, buf) != 0) 1616 goto nomem; 1617 } 1618 } else { 1619 if (zcmd_read_dst_nvlist(hdl, &zc, 1620 &zhp->zpool_error_log[j]) != 0) { 1621 zcmd_free_nvlists(&zc); 1622 goto nomem; 1623 } 1624 } 1625 1626 break; 1627 } 1628 1629 zcmd_free_nvlists(&zc); 1630 1631 j++; 1632 } 1633 1634 *list = zhp->zpool_error_log; 1635 *nelem = zhp->zpool_error_count; 1636 free(zb); 1637 1638 return (0); 1639 1640 nomem: 1641 free(zb); 1642 free((void *)(uintptr_t)zc.zc_nvlist_dst); 1643 for (i = 0; i < zhp->zpool_error_count; i++) 1644 nvlist_free(zhp->zpool_error_log[i]); 1645 free(zhp->zpool_error_log); 1646 zhp->zpool_error_log = NULL; 1647 return (no_memory(zhp->zpool_hdl)); 1648 } 1649 1650 /* 1651 * Upgrade a ZFS pool to the latest on-disk version. 1652 */ 1653 int 1654 zpool_upgrade(zpool_handle_t *zhp) 1655 { 1656 zfs_cmd_t zc = { 0 }; 1657 libzfs_handle_t *hdl = zhp->zpool_hdl; 1658 1659 (void) strcpy(zc.zc_name, zhp->zpool_name); 1660 if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_UPGRADE, &zc) != 0) 1661 return (zpool_standard_error(hdl, errno, 1662 dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"), 1663 zhp->zpool_name)); 1664 1665 return (0); 1666 } 1667