1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 51485Slling * Common Development and Distribution License (the "License"). 61485Slling * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 221354Seschrock * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 27789Sahrens 28789Sahrens #include <assert.h> 29789Sahrens #include <ctype.h> 30789Sahrens #include <errno.h> 31789Sahrens #include <devid.h> 32789Sahrens #include <fcntl.h> 33789Sahrens #include <libintl.h> 34789Sahrens #include <stdio.h> 35789Sahrens #include <stdlib.h> 36789Sahrens #include <string.h> 37789Sahrens #include <unistd.h> 38789Sahrens #include <sys/zfs_ioctl.h> 391544Seschrock #include <sys/zio.h> 40789Sahrens 41789Sahrens #include "zfs_namecheck.h" 42789Sahrens #include "libzfs_impl.h" 43789Sahrens 44789Sahrens /* 45789Sahrens * Validate the given pool name, optionally putting an extended error message in 46789Sahrens * 'buf'. 47789Sahrens */ 48789Sahrens static int 49789Sahrens zpool_name_valid(const char *pool, char *buf, size_t buflen) 50789Sahrens { 51789Sahrens namecheck_err_t why; 52789Sahrens char what; 53789Sahrens 54789Sahrens if (pool_namecheck(pool, &why, &what) != 0) { 55789Sahrens if (buf != NULL) { 56789Sahrens switch (why) { 571003Slling case NAME_ERR_TOOLONG: 581003Slling (void) snprintf(buf, buflen, 591003Slling dgettext(TEXT_DOMAIN, "name is too long")); 601003Slling break; 611003Slling 62789Sahrens case NAME_ERR_INVALCHAR: 63789Sahrens (void) snprintf(buf, buflen, 64789Sahrens dgettext(TEXT_DOMAIN, "invalid character " 65789Sahrens "'%c' in pool name"), what); 66789Sahrens break; 67789Sahrens 68789Sahrens case NAME_ERR_NOLETTER: 69789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 70789Sahrens "name must begin with a letter"), buflen); 71789Sahrens break; 72789Sahrens 73789Sahrens case NAME_ERR_RESERVED: 74789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 75789Sahrens "name is reserved\n" 76789Sahrens "pool name may have been omitted"), buflen); 77789Sahrens break; 78789Sahrens 79789Sahrens case NAME_ERR_DISKLIKE: 80789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 81789Sahrens "pool name is reserved\n" 82789Sahrens "pool name may have been omitted"), buflen); 83789Sahrens break; 84789Sahrens } 85789Sahrens } 86789Sahrens return (FALSE); 87789Sahrens } 88789Sahrens 89789Sahrens return (TRUE); 90789Sahrens } 91789Sahrens 92789Sahrens /* 93789Sahrens * Set the pool-wide health based on the vdev state of the root vdev. 94789Sahrens */ 95789Sahrens void 96789Sahrens set_pool_health(nvlist_t *config) 97789Sahrens { 98789Sahrens nvlist_t *nvroot; 99789Sahrens vdev_stat_t *vs; 100789Sahrens uint_t vsc; 101789Sahrens char *health; 102789Sahrens 103789Sahrens verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 104789Sahrens &nvroot) == 0); 105789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 106789Sahrens (uint64_t **)&vs, &vsc) == 0); 107789Sahrens 108789Sahrens switch (vs->vs_state) { 109789Sahrens 110789Sahrens case VDEV_STATE_CLOSED: 111789Sahrens case VDEV_STATE_CANT_OPEN: 112789Sahrens case VDEV_STATE_OFFLINE: 113789Sahrens health = dgettext(TEXT_DOMAIN, "FAULTED"); 114789Sahrens break; 115789Sahrens 116789Sahrens case VDEV_STATE_DEGRADED: 117789Sahrens health = dgettext(TEXT_DOMAIN, "DEGRADED"); 118789Sahrens break; 119789Sahrens 120789Sahrens case VDEV_STATE_HEALTHY: 121789Sahrens health = dgettext(TEXT_DOMAIN, "ONLINE"); 122789Sahrens break; 123789Sahrens 124789Sahrens default: 125789Sahrens zfs_baderror(vs->vs_state); 126789Sahrens } 127789Sahrens 128789Sahrens verify(nvlist_add_string(config, ZPOOL_CONFIG_POOL_HEALTH, 129789Sahrens health) == 0); 130789Sahrens } 131789Sahrens 132789Sahrens /* 133789Sahrens * Open a handle to the given pool, even if the pool is currently in the FAULTED 134789Sahrens * state. 135789Sahrens */ 136789Sahrens zpool_handle_t * 137789Sahrens zpool_open_canfail(const char *pool) 138789Sahrens { 139789Sahrens zpool_handle_t *zhp; 140789Sahrens int error; 141789Sahrens 142789Sahrens /* 143789Sahrens * Make sure the pool name is valid. 144789Sahrens */ 145789Sahrens if (!zpool_name_valid(pool, NULL, 0)) { 146789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': invalid " 147789Sahrens "pool name"), pool); 148789Sahrens return (NULL); 149789Sahrens } 150789Sahrens 151789Sahrens zhp = zfs_malloc(sizeof (zpool_handle_t)); 152789Sahrens 153789Sahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 154789Sahrens 155952Seschrock if ((error = zpool_refresh_stats(zhp)) != 0) { 156789Sahrens if (error == ENOENT || error == EINVAL) { 157789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': no " 158789Sahrens "such pool"), pool); 159789Sahrens free(zhp); 160789Sahrens return (NULL); 161789Sahrens } else { 162789Sahrens zhp->zpool_state = POOL_STATE_UNAVAIL; 163789Sahrens } 164789Sahrens } else { 165789Sahrens zhp->zpool_state = POOL_STATE_ACTIVE; 166789Sahrens } 167789Sahrens 168789Sahrens return (zhp); 169789Sahrens } 170789Sahrens 171789Sahrens /* 172789Sahrens * Like the above, but silent on error. Used when iterating over pools (because 173789Sahrens * the configuration cache may be out of date). 174789Sahrens */ 175789Sahrens zpool_handle_t * 176789Sahrens zpool_open_silent(const char *pool) 177789Sahrens { 178789Sahrens zpool_handle_t *zhp; 179789Sahrens int error; 180789Sahrens 181789Sahrens zhp = zfs_malloc(sizeof (zpool_handle_t)); 182789Sahrens 183789Sahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 184789Sahrens 185952Seschrock if ((error = zpool_refresh_stats(zhp)) != 0) { 186789Sahrens if (error == ENOENT || error == EINVAL) { 187789Sahrens free(zhp); 188789Sahrens return (NULL); 189789Sahrens } else { 190789Sahrens zhp->zpool_state = POOL_STATE_UNAVAIL; 191789Sahrens } 192789Sahrens } else { 193789Sahrens zhp->zpool_state = POOL_STATE_ACTIVE; 194789Sahrens } 195789Sahrens 196789Sahrens return (zhp); 197789Sahrens } 198789Sahrens 199789Sahrens /* 200789Sahrens * Similar to zpool_open_canfail(), but refuses to open pools in the faulted 201789Sahrens * state. 202789Sahrens */ 203789Sahrens zpool_handle_t * 204789Sahrens zpool_open(const char *pool) 205789Sahrens { 206789Sahrens zpool_handle_t *zhp; 207789Sahrens 208789Sahrens if ((zhp = zpool_open_canfail(pool)) == NULL) 209789Sahrens return (NULL); 210789Sahrens 211789Sahrens if (zhp->zpool_state == POOL_STATE_UNAVAIL) { 2121544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': pool is " 2131544Seschrock "currently unavailable"), zhp->zpool_name); 2141544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "run 'zpool status %s' for " 2151544Seschrock "detailed information"), zhp->zpool_name); 216789Sahrens zpool_close(zhp); 217789Sahrens return (NULL); 218789Sahrens } 219789Sahrens 220789Sahrens return (zhp); 221789Sahrens } 222789Sahrens 223789Sahrens /* 224789Sahrens * Close the handle. Simply frees the memory associated with the handle. 225789Sahrens */ 226789Sahrens void 227789Sahrens zpool_close(zpool_handle_t *zhp) 228789Sahrens { 229789Sahrens if (zhp->zpool_config) 230789Sahrens nvlist_free(zhp->zpool_config); 231952Seschrock if (zhp->zpool_old_config) 232952Seschrock nvlist_free(zhp->zpool_old_config); 2331544Seschrock if (zhp->zpool_error_log) { 2341544Seschrock int i; 2351544Seschrock for (i = 0; i < zhp->zpool_error_count; i++) 2361544Seschrock free(zhp->zpool_error_log[i]); 2371544Seschrock free(zhp->zpool_error_log); 2381544Seschrock } 239789Sahrens free(zhp); 240789Sahrens } 241789Sahrens 242789Sahrens /* 243789Sahrens * Return the name of the pool. 244789Sahrens */ 245789Sahrens const char * 246789Sahrens zpool_get_name(zpool_handle_t *zhp) 247789Sahrens { 248789Sahrens return (zhp->zpool_name); 249789Sahrens } 250789Sahrens 251789Sahrens /* 252789Sahrens * Return the GUID of the pool. 253789Sahrens */ 254789Sahrens uint64_t 255789Sahrens zpool_get_guid(zpool_handle_t *zhp) 256789Sahrens { 257789Sahrens uint64_t guid; 258789Sahrens 259789Sahrens verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID, 260789Sahrens &guid) == 0); 261789Sahrens return (guid); 262789Sahrens } 263789Sahrens 264789Sahrens /* 265789Sahrens * Return the amount of space currently consumed by the pool. 266789Sahrens */ 267789Sahrens uint64_t 268789Sahrens zpool_get_space_used(zpool_handle_t *zhp) 269789Sahrens { 270789Sahrens nvlist_t *nvroot; 271789Sahrens vdev_stat_t *vs; 272789Sahrens uint_t vsc; 273789Sahrens 274789Sahrens verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 275789Sahrens &nvroot) == 0); 276789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 277789Sahrens (uint64_t **)&vs, &vsc) == 0); 278789Sahrens 279789Sahrens return (vs->vs_alloc); 280789Sahrens } 281789Sahrens 282789Sahrens /* 283789Sahrens * Return the total space in the pool. 284789Sahrens */ 285789Sahrens uint64_t 286789Sahrens zpool_get_space_total(zpool_handle_t *zhp) 287789Sahrens { 288789Sahrens nvlist_t *nvroot; 289789Sahrens vdev_stat_t *vs; 290789Sahrens uint_t vsc; 291789Sahrens 292789Sahrens verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 293789Sahrens &nvroot) == 0); 294789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 295789Sahrens (uint64_t **)&vs, &vsc) == 0); 296789Sahrens 297789Sahrens return (vs->vs_space); 298789Sahrens } 299789Sahrens 300789Sahrens /* 301789Sahrens * Return the alternate root for this pool, if any. 302789Sahrens */ 303789Sahrens int 304789Sahrens zpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen) 305789Sahrens { 306789Sahrens zfs_cmd_t zc = { 0 }; 307789Sahrens 308789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 3091544Seschrock if (zfs_ioctl(ZFS_IOC_OBJSET_STATS, &zc) != 0 || 3101544Seschrock zc.zc_root[0] == '\0') 311789Sahrens return (-1); 312789Sahrens 3131544Seschrock (void) strlcpy(buf, zc.zc_root, buflen); 314789Sahrens 315789Sahrens return (0); 316789Sahrens } 317789Sahrens 318789Sahrens /* 319789Sahrens * Return the state of the pool (ACTIVE or UNAVAILABLE) 320789Sahrens */ 321789Sahrens int 322789Sahrens zpool_get_state(zpool_handle_t *zhp) 323789Sahrens { 324789Sahrens return (zhp->zpool_state); 325789Sahrens } 326789Sahrens 327789Sahrens /* 328789Sahrens * Create the named pool, using the provided vdev list. It is assumed 329789Sahrens * that the consumer has already validated the contents of the nvlist, so we 330789Sahrens * don't have to worry about error semantics. 331789Sahrens */ 332789Sahrens int 333789Sahrens zpool_create(const char *pool, nvlist_t *nvroot, const char *altroot) 334789Sahrens { 335789Sahrens zfs_cmd_t zc = { 0 }; 336789Sahrens char *packed; 337789Sahrens size_t len; 338789Sahrens int err; 339789Sahrens char reason[64]; 340789Sahrens 341789Sahrens if (!zpool_name_valid(pool, reason, sizeof (reason))) { 342789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': %s"), 343789Sahrens pool, reason); 344789Sahrens return (-1); 345789Sahrens } 346789Sahrens 347789Sahrens if (altroot != NULL && altroot[0] != '/') { 348789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': alternate " 349789Sahrens "root '%s' must be a complete path"), pool, altroot); 350789Sahrens return (-1); 351789Sahrens } 352789Sahrens 353789Sahrens if ((err = nvlist_size(nvroot, &len, NV_ENCODE_NATIVE)) != 0) 354789Sahrens zfs_baderror(err); 355789Sahrens 356789Sahrens packed = zfs_malloc(len); 357789Sahrens 358789Sahrens if ((err = nvlist_pack(nvroot, &packed, &len, 359789Sahrens NV_ENCODE_NATIVE, 0)) != 0) 360789Sahrens zfs_baderror(err); 361789Sahrens 362789Sahrens (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); 363789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 364789Sahrens zc.zc_config_src_size = len; 365789Sahrens 366789Sahrens if (altroot != NULL) 367789Sahrens (void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root)); 368789Sahrens 3691544Seschrock if (zfs_ioctl(ZFS_IOC_POOL_CREATE, &zc) != 0) { 370789Sahrens switch (errno) { 371789Sahrens case EEXIST: 372789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 373789Sahrens "pool exists"), pool); 374789Sahrens break; 375789Sahrens 376789Sahrens case EPERM: 377789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 378789Sahrens "permission denied"), pool); 379789Sahrens break; 380789Sahrens 381789Sahrens case EBUSY: 382789Sahrens /* 383789Sahrens * This can happen if the user has specified the same 384789Sahrens * device multiple times. We can't reliably detect this 385789Sahrens * until we try to add it and see we already have a 386789Sahrens * label. 387789Sahrens */ 388789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 389789Sahrens "one or more vdevs refer to the same device"), 390789Sahrens pool); 391789Sahrens break; 392789Sahrens 393789Sahrens case EOVERFLOW: 394789Sahrens /* 395789Sahrens * This occurrs when one of the devices is below 396789Sahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which 397789Sahrens * device was the problem device since there's no 398789Sahrens * reliable way to determine device size from userland. 399789Sahrens */ 400789Sahrens { 401789Sahrens char buf[64]; 402789Sahrens 403789Sahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 404789Sahrens 405789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot " 406789Sahrens "create '%s': one or more devices is less " 407789Sahrens "than the minimum size (%s)"), pool, 408789Sahrens buf); 409789Sahrens } 410789Sahrens break; 411789Sahrens 412789Sahrens case ENAMETOOLONG: 413789Sahrens /* 414789Sahrens * One of the vdevs has exceeded VDEV_SPEC_MAX length in 415789Sahrens * its plaintext representation. 416789Sahrens */ 417789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 418789Sahrens "too many devices in a single vdev"), pool); 419789Sahrens break; 420789Sahrens 421789Sahrens case EIO: 422789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 423789Sahrens "I/O error on one or more devices"), pool); 424789Sahrens break; 425789Sahrens 426789Sahrens case ENXIO: 427789Sahrens /* 428789Sahrens * This is unlikely to happen since we've verified that 429789Sahrens * all the devices can be opened from userland, but it's 430789Sahrens * still possible in some circumstances. 431789Sahrens */ 432789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 433789Sahrens "one or more devices is unavailable"), pool); 434789Sahrens break; 435789Sahrens 436789Sahrens case ENOSPC: 437789Sahrens /* 438789Sahrens * This can occur if we were incapable of writing to a 439789Sahrens * file vdev because the underlying filesystem is out of 440789Sahrens * space. This is very similar to EOVERFLOW, but we'll 441789Sahrens * produce a slightly different message. 442789Sahrens */ 443789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 444789Sahrens "one or more devices is out of space"), pool); 445789Sahrens break; 446789Sahrens 447789Sahrens default: 448789Sahrens zfs_baderror(errno); 449789Sahrens } 450789Sahrens 451789Sahrens return (-1); 452789Sahrens } 453789Sahrens 454789Sahrens free(packed); 455789Sahrens 456789Sahrens /* 457789Sahrens * If this is an alternate root pool, then we automatically set the 458789Sahrens * moutnpoint of the root dataset to be '/'. 459789Sahrens */ 460789Sahrens if (altroot != NULL) { 461789Sahrens zfs_handle_t *zhp; 462789Sahrens 463789Sahrens verify((zhp = zfs_open(pool, ZFS_TYPE_ANY)) != NULL); 464789Sahrens verify(zfs_prop_set(zhp, ZFS_PROP_MOUNTPOINT, "/") == 0); 465789Sahrens 466789Sahrens zfs_close(zhp); 467789Sahrens } 468789Sahrens 469789Sahrens return (0); 470789Sahrens } 471789Sahrens 472789Sahrens /* 473789Sahrens * Destroy the given pool. It is up to the caller to ensure that there are no 474789Sahrens * datasets left in the pool. 475789Sahrens */ 476789Sahrens int 477789Sahrens zpool_destroy(zpool_handle_t *zhp) 478789Sahrens { 479789Sahrens zfs_cmd_t zc = { 0 }; 480789Sahrens zfs_handle_t *zfp = NULL; 481789Sahrens 482789Sahrens if (zhp->zpool_state == POOL_STATE_ACTIVE && 483789Sahrens (zfp = zfs_open(zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL) 484789Sahrens return (-1); 485789Sahrens 486789Sahrens if (zpool_remove_zvol_links(zhp) != NULL) 487789Sahrens return (-1); 488789Sahrens 489789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 490789Sahrens 4911544Seschrock if (zfs_ioctl(ZFS_IOC_POOL_DESTROY, &zc) != 0) { 492789Sahrens switch (errno) { 493789Sahrens case EPERM: 494789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 495789Sahrens "cannot destroy '%s': permission denied"), 496789Sahrens zhp->zpool_name); 497789Sahrens break; 498789Sahrens 499789Sahrens case EBUSY: 500789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 501789Sahrens "cannot destroy '%s': pool busy"), 502789Sahrens zhp->zpool_name); 503789Sahrens break; 504789Sahrens 505789Sahrens case ENOENT: 506789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 507789Sahrens "cannot destroy '%s': no such pool"), 508789Sahrens zhp->zpool_name); 509789Sahrens break; 510789Sahrens 511789Sahrens case EROFS: 512789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 513789Sahrens "cannot destroy '%s': one or more devices is " 514789Sahrens "read only, or '/' is mounted read only"), 515789Sahrens zhp->zpool_name); 516789Sahrens break; 517789Sahrens 518789Sahrens default: 519789Sahrens zfs_baderror(errno); 520789Sahrens } 521789Sahrens 522789Sahrens if (zfp) 523789Sahrens zfs_close(zfp); 524789Sahrens return (-1); 525789Sahrens } 526789Sahrens 527789Sahrens if (zfp) { 528789Sahrens remove_mountpoint(zfp); 529789Sahrens zfs_close(zfp); 530789Sahrens } 531789Sahrens 532789Sahrens return (0); 533789Sahrens } 534789Sahrens 535789Sahrens /* 536789Sahrens * Add the given vdevs to the pool. The caller must have already performed the 537789Sahrens * necessary verification to ensure that the vdev specification is well-formed. 538789Sahrens */ 539789Sahrens int 540789Sahrens zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) 541789Sahrens { 542789Sahrens char *packed; 543789Sahrens size_t len; 544789Sahrens zfs_cmd_t zc; 545789Sahrens 546789Sahrens verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0); 547789Sahrens 548789Sahrens packed = zfs_malloc(len); 549789Sahrens 550789Sahrens verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 551789Sahrens 552789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 553789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 554789Sahrens zc.zc_config_src_size = len; 555789Sahrens 5561544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_ADD, &zc) != 0) { 557789Sahrens switch (errno) { 558789Sahrens case EPERM: 559789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 560789Sahrens "permission denied"), zhp->zpool_name); 561789Sahrens break; 562789Sahrens 563789Sahrens case EBUSY: 564789Sahrens /* 565789Sahrens * This can happen if the user has specified the same 566789Sahrens * device multiple times. We can't reliably detect this 567789Sahrens * until we try to add it and see we already have a 568789Sahrens * label. 569789Sahrens */ 570789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 571789Sahrens "one or more vdevs refer to the same device"), 572789Sahrens zhp->zpool_name); 573789Sahrens break; 574789Sahrens 575789Sahrens case ENAMETOOLONG: 576789Sahrens /* 577789Sahrens * One of the vdevs has exceeded VDEV_SPEC_MAX length in 578789Sahrens * its plaintext representation. 579789Sahrens */ 580789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 581789Sahrens "too many devices in a single vdev"), 582789Sahrens zhp->zpool_name); 583789Sahrens break; 584789Sahrens 585789Sahrens case ENXIO: 586789Sahrens /* 587789Sahrens * This is unlikely to happen since we've verified that 588789Sahrens * all the devices can be opened from userland, but it's 589789Sahrens * still possible in some circumstances. 590789Sahrens */ 591789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 592789Sahrens "one or more devices is unavailable"), 593789Sahrens zhp->zpool_name); 594789Sahrens break; 595789Sahrens 596789Sahrens case EOVERFLOW: 597789Sahrens /* 598789Sahrens * This occurrs when one of the devices is below 599789Sahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which 600789Sahrens * device was the problem device since there's no 601789Sahrens * reliable way to determine device size from userland. 602789Sahrens */ 603789Sahrens { 604789Sahrens char buf[64]; 605789Sahrens 606789Sahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 607789Sahrens 608789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot " 609789Sahrens "add to '%s': one or more devices is less " 610789Sahrens "than the minimum size (%s)"), 611789Sahrens zhp->zpool_name, buf); 612789Sahrens } 613789Sahrens break; 614789Sahrens 615789Sahrens default: 616789Sahrens zfs_baderror(errno); 617789Sahrens } 618789Sahrens 619789Sahrens return (-1); 620789Sahrens } 621789Sahrens 622789Sahrens free(packed); 623789Sahrens 624789Sahrens return (0); 625789Sahrens } 626789Sahrens 627789Sahrens /* 628789Sahrens * Exports the pool from the system. The caller must ensure that there are no 629789Sahrens * mounted datasets in the pool. 630789Sahrens */ 631789Sahrens int 632789Sahrens zpool_export(zpool_handle_t *zhp) 633789Sahrens { 634789Sahrens zfs_cmd_t zc = { 0 }; 635789Sahrens 636789Sahrens if (zpool_remove_zvol_links(zhp) != 0) 637789Sahrens return (-1); 638789Sahrens 639789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 640789Sahrens 6411544Seschrock if (zfs_ioctl(ZFS_IOC_POOL_EXPORT, &zc) != 0) { 642789Sahrens switch (errno) { 643789Sahrens case EPERM: 644789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 645789Sahrens "cannot export '%s': permission denied"), 646789Sahrens zhp->zpool_name); 647789Sahrens break; 648789Sahrens 649789Sahrens case EBUSY: 650789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 651789Sahrens "cannot export '%s': pool is in use"), 652789Sahrens zhp->zpool_name); 653789Sahrens break; 654789Sahrens 655789Sahrens case ENOENT: 656789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 657789Sahrens "cannot export '%s': no such pool"), 658789Sahrens zhp->zpool_name); 659789Sahrens break; 660789Sahrens 661789Sahrens default: 662789Sahrens zfs_baderror(errno); 663789Sahrens } 664789Sahrens 665789Sahrens return (-1); 666789Sahrens } 667789Sahrens 668789Sahrens return (0); 669789Sahrens } 670789Sahrens 671789Sahrens /* 672789Sahrens * Import the given pool using the known configuration. The configuration 673789Sahrens * should have come from zpool_find_import(). The 'newname' and 'altroot' 674789Sahrens * parameters control whether the pool is imported with a different name or with 675789Sahrens * an alternate root, respectively. 676789Sahrens */ 677789Sahrens int 678789Sahrens zpool_import(nvlist_t *config, const char *newname, const char *altroot) 679789Sahrens { 680789Sahrens zfs_cmd_t zc; 681789Sahrens char *packed; 682789Sahrens size_t len; 683789Sahrens char *thename; 684789Sahrens char *origname; 685789Sahrens int ret; 686789Sahrens 687789Sahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 688789Sahrens &origname) == 0); 689789Sahrens 690789Sahrens if (newname != NULL) { 691789Sahrens if (!zpool_name_valid(newname, NULL, 0)) { 692789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': " 693789Sahrens "invalid pool name"), newname); 694789Sahrens return (-1); 695789Sahrens } 696789Sahrens thename = (char *)newname; 697789Sahrens } else { 698789Sahrens thename = origname; 699789Sahrens } 700789Sahrens 701789Sahrens if (altroot != NULL && altroot[0] != '/') { 702789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': alternate " 703789Sahrens "root '%s' must be a complete path"), thename, 704789Sahrens altroot); 705789Sahrens return (-1); 706789Sahrens } 707789Sahrens 708789Sahrens (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); 709789Sahrens 710789Sahrens if (altroot != NULL) 711789Sahrens (void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root)); 712789Sahrens else 713789Sahrens zc.zc_root[0] = '\0'; 714789Sahrens 715789Sahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 7161544Seschrock &zc.zc_guid) == 0); 717789Sahrens 718789Sahrens verify(nvlist_size(config, &len, NV_ENCODE_NATIVE) == 0); 719789Sahrens 720789Sahrens packed = zfs_malloc(len); 721789Sahrens 722789Sahrens verify(nvlist_pack(config, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 723789Sahrens 724789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 725789Sahrens zc.zc_config_src_size = len; 726789Sahrens 727789Sahrens ret = 0; 7281544Seschrock if (zfs_ioctl(ZFS_IOC_POOL_IMPORT, &zc) != 0) { 729789Sahrens char desc[1024]; 730789Sahrens if (newname == NULL) 731789Sahrens (void) snprintf(desc, sizeof (desc), 732789Sahrens dgettext(TEXT_DOMAIN, "cannot import '%s'"), 733789Sahrens thename); 734789Sahrens else 735789Sahrens (void) snprintf(desc, sizeof (desc), 736789Sahrens dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), 737789Sahrens origname, thename); 738789Sahrens 739789Sahrens switch (errno) { 740789Sahrens case EEXIST: 741789Sahrens /* 742789Sahrens * A pool with that name already exists. 743789Sahrens */ 744789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: pool exists"), 745789Sahrens desc); 746789Sahrens break; 747789Sahrens 748789Sahrens case EPERM: 749789Sahrens /* 750789Sahrens * The user doesn't have permission to create pools. 751789Sahrens */ 752789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission " 753789Sahrens "denied"), desc); 754789Sahrens break; 755789Sahrens 756789Sahrens case ENXIO: 757789Sahrens case EDOM: 758789Sahrens /* 759789Sahrens * Device is unavailable, or vdev sum didn't match. 760789Sahrens */ 761789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: one or more " 762789Sahrens "devices is unavailable"), 763789Sahrens desc); 764789Sahrens break; 765789Sahrens 7661544Seschrock case ENOTSUP: 7671544Seschrock /* 7681544Seschrock * Unsupported version. 7691544Seschrock */ 7701544Seschrock zfs_error(dgettext(TEXT_DOMAIN, 7711544Seschrock "%s: unsupported version"), desc); 7721544Seschrock break; 7731544Seschrock 774789Sahrens default: 775789Sahrens zfs_baderror(errno); 776789Sahrens } 777789Sahrens 778789Sahrens ret = -1; 779789Sahrens } else { 780789Sahrens zpool_handle_t *zhp; 781789Sahrens /* 782789Sahrens * This should never fail, but play it safe anyway. 783789Sahrens */ 784789Sahrens if ((zhp = zpool_open_silent(thename)) != NULL) { 785789Sahrens ret = zpool_create_zvol_links(zhp); 786789Sahrens zpool_close(zhp); 787789Sahrens } 788789Sahrens } 789789Sahrens 790789Sahrens free(packed); 791789Sahrens return (ret); 792789Sahrens } 793789Sahrens 794789Sahrens /* 795789Sahrens * Scrub the pool. 796789Sahrens */ 797789Sahrens int 798789Sahrens zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type) 799789Sahrens { 800789Sahrens zfs_cmd_t zc = { 0 }; 801789Sahrens char msg[1024]; 802789Sahrens 803789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 804789Sahrens zc.zc_cookie = type; 805789Sahrens 8061544Seschrock if (zfs_ioctl(ZFS_IOC_POOL_SCRUB, &zc) == 0) 807789Sahrens return (0); 808789Sahrens 809789Sahrens (void) snprintf(msg, sizeof (msg), 810789Sahrens dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name); 811789Sahrens 812789Sahrens switch (errno) { 813789Sahrens case EPERM: 814789Sahrens /* 815789Sahrens * No permission to scrub this pool. 816789Sahrens */ 817789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 818789Sahrens break; 819789Sahrens 820789Sahrens case EBUSY: 821789Sahrens /* 822789Sahrens * Resilver in progress. 823789Sahrens */ 824789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: currently resilvering"), 825789Sahrens msg); 826789Sahrens break; 827789Sahrens 828789Sahrens default: 829789Sahrens zfs_baderror(errno); 830789Sahrens } 831789Sahrens return (-1); 832789Sahrens } 833789Sahrens 8341544Seschrock static uint64_t 8351544Seschrock vdev_to_guid(nvlist_t *nv, const char *search, uint64_t guid) 8361544Seschrock { 8371544Seschrock uint_t c, children; 8381544Seschrock nvlist_t **child; 8391544Seschrock uint64_t ret, present; 8401544Seschrock char *path; 8411544Seschrock uint64_t wholedisk = 0; 8421544Seschrock 8431544Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &ret) == 0); 8441544Seschrock 8451544Seschrock if (search == NULL && 8461544Seschrock nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) { 8471544Seschrock /* 8481544Seschrock * If the device has never been present since import, the only 8491544Seschrock * reliable way to match the vdev is by GUID. 8501544Seschrock */ 8511544Seschrock if (ret == guid) 8521544Seschrock return (ret); 8531544Seschrock } else if (search != NULL && 8541544Seschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 8551544Seschrock (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 8561544Seschrock &wholedisk); 8571544Seschrock if (wholedisk) { 8581544Seschrock /* 8591544Seschrock * For whole disks, the internal path has 's0', but the 8601544Seschrock * path passed in by the user doesn't. 8611544Seschrock */ 8621544Seschrock if (strlen(search) == strlen(path) - 2 && 8631544Seschrock strncmp(search, path, strlen(search)) == 0) 8641544Seschrock return (ret); 8651544Seschrock } else if (strcmp(search, path) == 0) { 8661544Seschrock return (ret); 8671544Seschrock } 8681544Seschrock } 8691544Seschrock 8701544Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 8711544Seschrock &child, &children) != 0) 8721544Seschrock return (0); 8731544Seschrock 8741544Seschrock for (c = 0; c < children; c++) 8751544Seschrock if ((ret = vdev_to_guid(child[c], search, guid)) != 0) 8761544Seschrock return (ret); 8771544Seschrock 8781544Seschrock return (0); 8791544Seschrock } 8801544Seschrock 8811544Seschrock /* 8821544Seschrock * Given a string describing a vdev, returns the matching GUID, or 0 if none. 8831544Seschrock */ 8841544Seschrock uint64_t 8851544Seschrock zpool_vdev_to_guid(zpool_handle_t *zhp, const char *path) 8861544Seschrock { 8871544Seschrock char buf[MAXPATHLEN]; 8881544Seschrock const char *search; 8891544Seschrock char *end; 8901544Seschrock nvlist_t *nvroot; 8911544Seschrock uint64_t guid; 8921544Seschrock 8931613Seschrock guid = strtoull(path, &end, 10); 8941544Seschrock if (guid != 0 && *end == '\0') { 8951544Seschrock search = NULL; 8961544Seschrock } else if (path[0] != '/') { 8971544Seschrock (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path); 8981544Seschrock search = buf; 8991544Seschrock } else { 9001544Seschrock search = path; 9011544Seschrock } 9021544Seschrock 9031544Seschrock verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 9041544Seschrock &nvroot) == 0); 9051544Seschrock 9061544Seschrock return (vdev_to_guid(nvroot, search, guid)); 9071544Seschrock } 9081544Seschrock 909789Sahrens /* 910789Sahrens * Bring the specified vdev online 911789Sahrens */ 912789Sahrens int 913789Sahrens zpool_vdev_online(zpool_handle_t *zhp, const char *path) 914789Sahrens { 915789Sahrens zfs_cmd_t zc = { 0 }; 916789Sahrens char msg[1024]; 917789Sahrens 9181544Seschrock (void) snprintf(msg, sizeof (msg), 9191544Seschrock dgettext(TEXT_DOMAIN, "cannot online %s"), path); 920789Sahrens 9211544Seschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 9221544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 9231544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 9241544Seschrock msg); 9251544Seschrock return (-1); 9261544Seschrock } 927789Sahrens 9281544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_ONLINE, &zc) == 0) 9291544Seschrock return (0); 930789Sahrens 931789Sahrens switch (errno) { 932789Sahrens case ENODEV: 933789Sahrens /* 934789Sahrens * Device doesn't exist 935789Sahrens */ 936789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 937789Sahrens break; 938789Sahrens 939789Sahrens case EPERM: 940789Sahrens /* 941789Sahrens * No permission to bring this vdev online. 942789Sahrens */ 943789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 944789Sahrens break; 945789Sahrens 946789Sahrens default: 947789Sahrens zfs_baderror(errno); 948789Sahrens } 949789Sahrens return (-1); 950789Sahrens } 951789Sahrens 952789Sahrens /* 953789Sahrens * Take the specified vdev offline 954789Sahrens */ 955789Sahrens int 9561485Slling zpool_vdev_offline(zpool_handle_t *zhp, const char *path, int istmp) 957789Sahrens { 958789Sahrens zfs_cmd_t zc = { 0 }; 959789Sahrens char msg[1024]; 960789Sahrens 9611544Seschrock (void) snprintf(msg, sizeof (msg), 9621544Seschrock dgettext(TEXT_DOMAIN, "cannot offline %s"), path); 9631544Seschrock 964789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 9651544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 9661544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 9671544Seschrock msg); 9681544Seschrock return (-1); 9691544Seschrock } 970789Sahrens 9711485Slling zc.zc_cookie = istmp; 9721485Slling 9731544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_OFFLINE, &zc) == 0) 974789Sahrens return (0); 975789Sahrens 976789Sahrens switch (errno) { 977789Sahrens case ENODEV: 978789Sahrens /* 979789Sahrens * Device doesn't exist 980789Sahrens */ 981789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 982789Sahrens break; 983789Sahrens 984789Sahrens case EPERM: 985789Sahrens /* 986789Sahrens * No permission to take this vdev offline. 987789Sahrens */ 988789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 989789Sahrens break; 990789Sahrens 991789Sahrens case EBUSY: 992789Sahrens /* 993789Sahrens * There are no other replicas of this device. 994789Sahrens */ 995789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg); 996789Sahrens break; 997789Sahrens 998789Sahrens default: 999789Sahrens zfs_baderror(errno); 1000789Sahrens } 1001789Sahrens return (-1); 1002789Sahrens } 1003789Sahrens 1004789Sahrens /* 1005789Sahrens * Attach new_disk (fully described by nvroot) to old_disk. 1006789Sahrens * If 'replacing' is specified, tne new disk will replace the old one. 1007789Sahrens */ 1008789Sahrens int 1009789Sahrens zpool_vdev_attach(zpool_handle_t *zhp, 1010789Sahrens const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing) 1011789Sahrens { 1012789Sahrens zfs_cmd_t zc = { 0 }; 1013789Sahrens char msg[1024]; 1014789Sahrens char *packed; 1015789Sahrens int ret; 1016789Sahrens size_t len; 1017789Sahrens 10181544Seschrock if (replacing) 10191544Seschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 10201544Seschrock "cannot replace %s with %s"), old_disk, new_disk); 10211544Seschrock else 10221544Seschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 10231544Seschrock "cannot attach %s to %s"), new_disk, old_disk); 10241544Seschrock 1025789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 10261544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, old_disk)) == 0) { 10271544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 10281544Seschrock msg); 10291544Seschrock return (-1); 10301544Seschrock } 1031789Sahrens zc.zc_cookie = replacing; 1032789Sahrens 1033789Sahrens verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0); 1034789Sahrens 1035789Sahrens packed = zfs_malloc(len); 1036789Sahrens 1037789Sahrens verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 1038789Sahrens 1039789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 1040789Sahrens zc.zc_config_src_size = len; 1041789Sahrens 10421544Seschrock ret = zfs_ioctl(ZFS_IOC_VDEV_ATTACH, &zc); 1043789Sahrens 1044789Sahrens free(packed); 1045789Sahrens 1046789Sahrens if (ret == 0) 1047789Sahrens return (0); 1048789Sahrens 1049789Sahrens switch (errno) { 10501544Seschrock case EPERM: 1051789Sahrens /* 1052789Sahrens * No permission to mess with the config. 1053789Sahrens */ 1054789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 1055789Sahrens break; 1056789Sahrens 10571544Seschrock case ENODEV: 1058789Sahrens /* 1059789Sahrens * Device doesn't exist. 1060789Sahrens */ 1061789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s not in pool"), 1062789Sahrens msg, old_disk); 1063789Sahrens break; 1064789Sahrens 10651544Seschrock case ENOTSUP: 1066789Sahrens /* 1067789Sahrens * Can't attach to or replace this type of vdev. 1068789Sahrens */ 1069789Sahrens if (replacing) 1070789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1071789Sahrens "%s: cannot replace a replacing device"), msg); 1072789Sahrens else 1073789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1074789Sahrens "%s: attach is only applicable to mirrors"), msg); 1075789Sahrens break; 1076789Sahrens 10771544Seschrock case EINVAL: 1078789Sahrens /* 1079789Sahrens * The new device must be a single disk. 1080789Sahrens */ 1081789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1082789Sahrens "%s: <new_device> must be a single disk"), msg); 1083789Sahrens break; 1084789Sahrens 10851544Seschrock case ENXIO: 1086789Sahrens /* 1087789Sahrens * This is unlikely to happen since we've verified that 1088789Sahrens * all the devices can be opened from userland, but it's 1089789Sahrens * still possible in some circumstances. 1090789Sahrens */ 1091789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is unavailable"), 1092789Sahrens msg, new_disk); 1093789Sahrens break; 1094789Sahrens 10951544Seschrock case EBUSY: 1096789Sahrens /* 1097789Sahrens * The new device is is use. 1098789Sahrens */ 1099789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s busy"), msg, new_disk); 1100789Sahrens break; 1101789Sahrens 11021544Seschrock case EOVERFLOW: 1103789Sahrens /* 1104789Sahrens * The new device is too small. 1105789Sahrens */ 1106789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is too small"), 1107789Sahrens msg, new_disk); 1108789Sahrens break; 1109789Sahrens 11101544Seschrock case EDOM: 1111789Sahrens /* 1112789Sahrens * The new device has a different alignment requirement. 1113789Sahrens */ 1114789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1115789Sahrens "%s: devices have different sector alignment"), msg); 1116789Sahrens break; 1117789Sahrens 11181544Seschrock case ENAMETOOLONG: 1119789Sahrens /* 1120789Sahrens * The resulting top-level vdev spec won't fit in the label. 1121789Sahrens */ 1122789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1123789Sahrens "%s: too many devices in a single vdev"), msg); 1124789Sahrens break; 1125789Sahrens 11261544Seschrock default: 1127789Sahrens zfs_baderror(errno); 1128789Sahrens } 1129789Sahrens 1130789Sahrens return (1); 1131789Sahrens } 1132789Sahrens 1133789Sahrens /* 1134789Sahrens * Detach the specified device. 1135789Sahrens */ 1136789Sahrens int 1137789Sahrens zpool_vdev_detach(zpool_handle_t *zhp, const char *path) 1138789Sahrens { 1139789Sahrens zfs_cmd_t zc = { 0 }; 1140789Sahrens char msg[1024]; 1141789Sahrens 11421544Seschrock (void) snprintf(msg, sizeof (msg), 11431544Seschrock dgettext(TEXT_DOMAIN, "cannot detach %s"), path); 11441544Seschrock 1145789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 11461544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 11471635Sbonwick zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 11481635Sbonwick msg); 11491544Seschrock return (-1); 11501544Seschrock } 1151789Sahrens 11521544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_DETACH, &zc) == 0) 1153789Sahrens return (0); 1154789Sahrens 1155789Sahrens switch (errno) { 11561544Seschrock case EPERM: 1157789Sahrens /* 1158789Sahrens * No permission to mess with the config. 1159789Sahrens */ 1160789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 1161789Sahrens break; 1162789Sahrens 11631544Seschrock case ENODEV: 1164789Sahrens /* 1165789Sahrens * Device doesn't exist. 1166789Sahrens */ 1167789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 1168789Sahrens break; 1169789Sahrens 11701544Seschrock case ENOTSUP: 1171789Sahrens /* 1172789Sahrens * Can't detach from this type of vdev. 1173789Sahrens */ 1174789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1175789Sahrens "%s: only applicable to mirror and replacing vdevs"), msg); 1176789Sahrens break; 1177789Sahrens 11781544Seschrock case EBUSY: 1179789Sahrens /* 1180789Sahrens * There are no other replicas of this device. 1181789Sahrens */ 1182789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg); 1183789Sahrens break; 1184789Sahrens 11851544Seschrock default: 11861544Seschrock zfs_baderror(errno); 11871544Seschrock } 11881544Seschrock 11891544Seschrock return (1); 11901544Seschrock } 11911544Seschrock 11921544Seschrock /* 11931544Seschrock * Clear the errors for the pool, or the particular device if specified. 11941544Seschrock */ 11951544Seschrock int 11961544Seschrock zpool_clear(zpool_handle_t *zhp, const char *path) 11971544Seschrock { 11981544Seschrock zfs_cmd_t zc = { 0 }; 11991544Seschrock char msg[1024]; 12001544Seschrock 12011544Seschrock if (path) 12021544Seschrock (void) snprintf(msg, sizeof (msg), 12031544Seschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 12041544Seschrock zc.zc_prop_value); 12051544Seschrock else 12061544Seschrock (void) snprintf(msg, sizeof (msg), 12071544Seschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 12081544Seschrock zhp->zpool_name); 12091544Seschrock 12101544Seschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 12111544Seschrock if (path && (zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 12121544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 12131544Seschrock msg); 12141544Seschrock return (-1); 12151544Seschrock } 12161544Seschrock 12171544Seschrock if (zfs_ioctl(ZFS_IOC_CLEAR, &zc) == 0) 12181544Seschrock return (0); 12191544Seschrock 12201544Seschrock switch (errno) { 12211544Seschrock case EPERM: 12221544Seschrock /* 12231544Seschrock * No permission to mess with the config. 12241544Seschrock */ 12251544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 12261544Seschrock break; 12271544Seschrock 12281544Seschrock case ENODEV: 12291544Seschrock /* 12301544Seschrock * Device doesn't exist. 12311544Seschrock */ 12321544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 12331544Seschrock break; 12341544Seschrock 12351544Seschrock default: 1236789Sahrens zfs_baderror(errno); 1237789Sahrens } 1238789Sahrens 1239789Sahrens return (1); 1240789Sahrens } 1241789Sahrens 1242789Sahrens static int 1243789Sahrens do_zvol(zfs_handle_t *zhp, void *data) 1244789Sahrens { 1245789Sahrens int linktype = (int)(uintptr_t)data; 1246789Sahrens int ret; 1247789Sahrens 1248789Sahrens /* 1249789Sahrens * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we 1250789Sahrens * correctly handle snapshots of volumes. 1251789Sahrens */ 1252789Sahrens if (zhp->zfs_volblocksize != 0) { 1253789Sahrens if (linktype) 1254789Sahrens ret = zvol_create_link(zhp->zfs_name); 1255789Sahrens else 1256789Sahrens ret = zvol_remove_link(zhp->zfs_name); 1257789Sahrens } 1258789Sahrens 1259789Sahrens ret = zfs_iter_children(zhp, do_zvol, data); 1260789Sahrens 1261789Sahrens zfs_close(zhp); 1262789Sahrens return (ret); 1263789Sahrens } 1264789Sahrens 1265789Sahrens /* 1266789Sahrens * Iterate over all zvols in the pool and make any necessary minor nodes. 1267789Sahrens */ 1268789Sahrens int 1269789Sahrens zpool_create_zvol_links(zpool_handle_t *zhp) 1270789Sahrens { 1271789Sahrens zfs_handle_t *zfp; 1272789Sahrens int ret; 1273789Sahrens 1274789Sahrens /* 1275789Sahrens * If the pool is unavailable, just return success. 1276789Sahrens */ 1277789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1278789Sahrens return (0); 1279789Sahrens 1280789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)TRUE); 1281789Sahrens 1282789Sahrens zfs_close(zfp); 1283789Sahrens return (ret); 1284789Sahrens } 1285789Sahrens 1286789Sahrens /* 1287789Sahrens * Iterate over all zvols in the poool and remove any minor nodes. 1288789Sahrens */ 1289789Sahrens int 1290789Sahrens zpool_remove_zvol_links(zpool_handle_t *zhp) 1291789Sahrens { 1292789Sahrens zfs_handle_t *zfp; 1293789Sahrens int ret; 1294789Sahrens 1295789Sahrens /* 1296789Sahrens * If the pool is unavailable, just return success. 1297789Sahrens */ 1298789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1299789Sahrens return (0); 1300789Sahrens 1301789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)FALSE); 1302789Sahrens 1303789Sahrens zfs_close(zfp); 1304789Sahrens return (ret); 1305789Sahrens } 13061354Seschrock 13071354Seschrock /* 13081354Seschrock * Convert from a devid string to a path. 13091354Seschrock */ 13101354Seschrock static char * 13111354Seschrock devid_to_path(char *devid_str) 13121354Seschrock { 13131354Seschrock ddi_devid_t devid; 13141354Seschrock char *minor; 13151354Seschrock char *path; 13161354Seschrock devid_nmlist_t *list = NULL; 13171354Seschrock int ret; 13181354Seschrock 13191354Seschrock if (devid_str_decode(devid_str, &devid, &minor) != 0) 13201354Seschrock return (NULL); 13211354Seschrock 13221354Seschrock ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list); 13231354Seschrock 13241354Seschrock devid_str_free(minor); 13251354Seschrock devid_free(devid); 13261354Seschrock 13271354Seschrock if (ret != 0) 13281354Seschrock return (NULL); 13291354Seschrock 13301354Seschrock path = zfs_strdup(list[0].devname); 13311354Seschrock devid_free_nmlist(list); 13321354Seschrock 13331354Seschrock return (path); 13341354Seschrock } 13351354Seschrock 13361354Seschrock /* 13371354Seschrock * Convert from a path to a devid string. 13381354Seschrock */ 13391354Seschrock static char * 13401354Seschrock path_to_devid(const char *path) 13411354Seschrock { 13421354Seschrock int fd; 13431354Seschrock ddi_devid_t devid; 13441354Seschrock char *minor, *ret; 13451354Seschrock 13461354Seschrock if ((fd = open(path, O_RDONLY)) < 0) 13471354Seschrock return (NULL); 13481354Seschrock 13491354Seschrock minor = NULL; 13501354Seschrock ret = NULL; 13511354Seschrock if (devid_get(fd, &devid) == 0) { 13521354Seschrock if (devid_get_minor_name(fd, &minor) == 0) 13531354Seschrock ret = devid_str_encode(devid, minor); 13541354Seschrock if (minor != NULL) 13551354Seschrock devid_str_free(minor); 13561354Seschrock devid_free(devid); 13571354Seschrock } 13581354Seschrock (void) close(fd); 13591354Seschrock 13601354Seschrock return (ret); 13611354Seschrock } 13621354Seschrock 13631354Seschrock /* 13641354Seschrock * Issue the necessary ioctl() to update the stored path value for the vdev. We 13651354Seschrock * ignore any failure here, since a common case is for an unprivileged user to 13661354Seschrock * type 'zpool status', and we'll display the correct information anyway. 13671354Seschrock */ 13681354Seschrock static void 13691354Seschrock set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) 13701354Seschrock { 13711354Seschrock zfs_cmd_t zc = { 0 }; 13721354Seschrock 13731354Seschrock (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 13741354Seschrock (void) strncpy(zc.zc_prop_value, path, sizeof (zc.zc_prop_value)); 13751354Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 13761544Seschrock &zc.zc_guid) == 0); 13771354Seschrock 13781544Seschrock (void) zfs_ioctl(ZFS_IOC_VDEV_SETPATH, &zc); 13791354Seschrock } 13801354Seschrock 13811354Seschrock /* 13821354Seschrock * Given a vdev, return the name to display in iostat. If the vdev has a path, 13831354Seschrock * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. 13841354Seschrock * We also check if this is a whole disk, in which case we strip off the 13851354Seschrock * trailing 's0' slice name. 13861354Seschrock * 13871354Seschrock * This routine is also responsible for identifying when disks have been 13881354Seschrock * reconfigured in a new location. The kernel will have opened the device by 13891354Seschrock * devid, but the path will still refer to the old location. To catch this, we 13901354Seschrock * first do a path -> devid translation (which is fast for the common case). If 13911354Seschrock * the devid matches, we're done. If not, we do a reverse devid -> path 13921354Seschrock * translation and issue the appropriate ioctl() to update the path of the vdev. 13931354Seschrock * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any 13941354Seschrock * of these checks. 13951354Seschrock */ 13961354Seschrock char * 13971354Seschrock zpool_vdev_name(zpool_handle_t *zhp, nvlist_t *nv) 13981354Seschrock { 13991354Seschrock char *path, *devid; 14001544Seschrock uint64_t value; 14011544Seschrock char buf[64]; 14021354Seschrock 14031544Seschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 14041544Seschrock &value) == 0) { 14051544Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 14061544Seschrock &value) == 0); 14071613Seschrock (void) snprintf(buf, sizeof (buf), "%llu", value); 14081544Seschrock path = buf; 14091544Seschrock } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 14101354Seschrock 14111354Seschrock if (zhp != NULL && 14121354Seschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { 14131354Seschrock /* 14141354Seschrock * Determine if the current path is correct. 14151354Seschrock */ 14161354Seschrock char *newdevid = path_to_devid(path); 14171354Seschrock 14181354Seschrock if (newdevid == NULL || 14191354Seschrock strcmp(devid, newdevid) != 0) { 14201354Seschrock char *newpath; 14211354Seschrock 14221354Seschrock if ((newpath = devid_to_path(devid)) != NULL) { 14231354Seschrock /* 14241354Seschrock * Update the path appropriately. 14251354Seschrock */ 14261354Seschrock set_path(zhp, nv, newpath); 14271354Seschrock verify(nvlist_add_string(nv, 14281354Seschrock ZPOOL_CONFIG_PATH, newpath) == 0); 14291354Seschrock free(newpath); 14301354Seschrock verify(nvlist_lookup_string(nv, 14311354Seschrock ZPOOL_CONFIG_PATH, &path) == 0); 14321354Seschrock } 14331354Seschrock 14341354Seschrock if (newdevid) 14351354Seschrock devid_str_free(newdevid); 14361354Seschrock } 14371354Seschrock 14381354Seschrock } 14391354Seschrock 14401354Seschrock if (strncmp(path, "/dev/dsk/", 9) == 0) 14411354Seschrock path += 9; 14421354Seschrock 14431354Seschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 14441544Seschrock &value) == 0 && value) { 14451354Seschrock char *tmp = zfs_strdup(path); 14461354Seschrock tmp[strlen(path) - 2] = '\0'; 14471354Seschrock return (tmp); 14481354Seschrock } 14491354Seschrock } else { 14501354Seschrock verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0); 14511354Seschrock } 14521354Seschrock 14531354Seschrock return (zfs_strdup(path)); 14541354Seschrock } 14551544Seschrock 14561544Seschrock static int 14571544Seschrock zbookmark_compare(const void *a, const void *b) 14581544Seschrock { 14591544Seschrock return (memcmp(a, b, sizeof (zbookmark_t))); 14601544Seschrock } 14611544Seschrock 14621544Seschrock /* 14631544Seschrock * Retrieve the persistent error log, uniquify the members, and return to the 14641544Seschrock * caller. 14651544Seschrock */ 14661544Seschrock int 14671544Seschrock zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem) 14681544Seschrock { 14691544Seschrock zfs_cmd_t zc = { 0 }; 14701544Seschrock uint64_t count; 14711544Seschrock zbookmark_t *zb; 14721544Seschrock int i, j; 14731544Seschrock 14741544Seschrock if (zhp->zpool_error_log != NULL) { 14751544Seschrock *list = zhp->zpool_error_log; 14761544Seschrock *nelem = zhp->zpool_error_count; 14771544Seschrock return (0); 14781544Seschrock } 14791544Seschrock 14801544Seschrock /* 14811544Seschrock * Retrieve the raw error list from the kernel. If the number of errors 14821544Seschrock * has increased, allocate more space and continue until we get the 14831544Seschrock * entire list. 14841544Seschrock */ 14851544Seschrock verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT, 14861544Seschrock &count) == 0); 14871544Seschrock zc.zc_config_dst = (uintptr_t)zfs_malloc(count * sizeof (zbookmark_t)); 14881544Seschrock zc.zc_config_dst_size = count; 14891544Seschrock (void) strcpy(zc.zc_name, zhp->zpool_name); 14901544Seschrock for (;;) { 14911544Seschrock if (zfs_ioctl(ZFS_IOC_ERROR_LOG, &zc) != 0) { 14921544Seschrock if (errno == ENOMEM) { 14931544Seschrock free((void *)(uintptr_t)zc.zc_config_dst); 14941544Seschrock zc.zc_config_dst = (uintptr_t) 14951544Seschrock zfs_malloc(zc.zc_config_dst_size); 14961544Seschrock } else { 14971544Seschrock return (-1); 14981544Seschrock } 14991544Seschrock } else { 15001544Seschrock break; 15011544Seschrock } 15021544Seschrock } 15031544Seschrock 15041544Seschrock /* 15051544Seschrock * Sort the resulting bookmarks. This is a little confusing due to the 15061544Seschrock * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last 15071544Seschrock * to first, and 'zc_config_dst_size' indicates the number of boomarks 15081544Seschrock * _not_ copied as part of the process. So we point the start of our 15091544Seschrock * array appropriate and decrement the total number of elements. 15101544Seschrock */ 15111544Seschrock zb = ((zbookmark_t *)(uintptr_t)zc.zc_config_dst) + 15121544Seschrock zc.zc_config_dst_size; 15131544Seschrock count -= zc.zc_config_dst_size; 15141544Seschrock 15151544Seschrock qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare); 15161544Seschrock 15171544Seschrock /* 15181544Seschrock * Count the number of unique elements 15191544Seschrock */ 15201544Seschrock j = 0; 15211544Seschrock for (i = 0; i < count; i++) { 15221544Seschrock if (i > 0 && memcmp(&zb[i - 1], &zb[i], 15231544Seschrock sizeof (zbookmark_t)) == 0) 15241544Seschrock continue; 15251544Seschrock j++; 15261544Seschrock } 15271544Seschrock 15281544Seschrock /* 15291544Seschrock * If the user has only requested the number of items, return it now 15301544Seschrock * without bothering with the extra work. 15311544Seschrock */ 15321544Seschrock if (list == NULL) { 15331544Seschrock *nelem = j; 15341544Seschrock return (0); 15351544Seschrock } 15361544Seschrock 15371544Seschrock zhp->zpool_error_count = j; 15381544Seschrock 15391544Seschrock /* 15401544Seschrock * Allocate an array of nvlists to hold the results 15411544Seschrock */ 15421544Seschrock zhp->zpool_error_log = zfs_malloc(j * sizeof (nvlist_t *)); 15431544Seschrock 15441544Seschrock /* 15451544Seschrock * Fill in the results with names from the kernel. 15461544Seschrock */ 15471544Seschrock j = 0; 15481544Seschrock for (i = 0; i < count; i++) { 15491544Seschrock char buf[64]; 15501544Seschrock nvlist_t *nv; 15511544Seschrock 15521544Seschrock if (i > 0 && memcmp(&zb[i - 1], &zb[i], 15531544Seschrock sizeof (zbookmark_t)) == 0) 15541544Seschrock continue; 15551544Seschrock 15561544Seschrock verify(nvlist_alloc(&nv, NV_UNIQUE_NAME, 15571544Seschrock 0) == 0); 15581544Seschrock zhp->zpool_error_log[j] = nv; 15591544Seschrock 15601544Seschrock zc.zc_bookmark = zb[i]; 15611544Seschrock if (zfs_ioctl(ZFS_IOC_BOOKMARK_NAME, &zc) == 0) { 15621544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_DATASET, 15631544Seschrock zc.zc_prop_name) == 0); 15641544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_OBJECT, 15651544Seschrock zc.zc_prop_value) == 0); 15661544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_RANGE, 15671544Seschrock zc.zc_filename) == 0); 15681544Seschrock } else { 15691544Seschrock (void) snprintf(buf, sizeof (buf), "%llx", 15701544Seschrock zb[i].zb_objset); 15711544Seschrock verify(nvlist_add_string(nv, 15721544Seschrock ZPOOL_ERR_DATASET, buf) == 0); 15731544Seschrock (void) snprintf(buf, sizeof (buf), "%llx", 15741544Seschrock zb[i].zb_object); 15751544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_OBJECT, 15761544Seschrock buf) == 0); 15771544Seschrock (void) snprintf(buf, sizeof (buf), "lvl=%u blkid=%llu", 15781544Seschrock (int)zb[i].zb_level, (long long)zb[i].zb_blkid); 15791544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_RANGE, 15801544Seschrock buf) == 0); 15811544Seschrock } 15821544Seschrock 15831544Seschrock j++; 15841544Seschrock } 15851544Seschrock 15861544Seschrock *list = zhp->zpool_error_log; 15871544Seschrock *nelem = zhp->zpool_error_count; 15881544Seschrock 15891544Seschrock free((void *)(uintptr_t)zc.zc_config_dst); 15901544Seschrock 15911544Seschrock return (0); 15921544Seschrock } 1593*1760Seschrock 1594*1760Seschrock /* 1595*1760Seschrock * Upgrade a ZFS pool to the latest on-disk version. 1596*1760Seschrock */ 1597*1760Seschrock int 1598*1760Seschrock zpool_upgrade(zpool_handle_t *zhp) 1599*1760Seschrock { 1600*1760Seschrock zfs_cmd_t zc = { 0 }; 1601*1760Seschrock 1602*1760Seschrock (void) strcpy(zc.zc_name, zhp->zpool_name); 1603*1760Seschrock if (zfs_ioctl(ZFS_IOC_POOL_UPGRADE, &zc) != 0) { 1604*1760Seschrock switch (errno) { 1605*1760Seschrock case EPERM: 1606*1760Seschrock zfs_error(dgettext(TEXT_DOMAIN, "cannot upgrade '%s': " 1607*1760Seschrock "permission denied"), zhp->zpool_name); 1608*1760Seschrock break; 1609*1760Seschrock default: 1610*1760Seschrock zfs_baderror(errno); 1611*1760Seschrock } 1612*1760Seschrock 1613*1760Seschrock return (-1); 1614*1760Seschrock } 1615*1760Seschrock 1616*1760Seschrock return (0); 1617*1760Seschrock } 1618