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> 39*1544Seschrock #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) { 212*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': pool is " 213*1544Seschrock "currently unavailable"), zhp->zpool_name); 214*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "run 'zpool status %s' for " 215*1544Seschrock "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); 233*1544Seschrock if (zhp->zpool_error_log) { 234*1544Seschrock int i; 235*1544Seschrock for (i = 0; i < zhp->zpool_error_count; i++) 236*1544Seschrock free(zhp->zpool_error_log[i]); 237*1544Seschrock free(zhp->zpool_error_log); 238*1544Seschrock } 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)); 309*1544Seschrock if (zfs_ioctl(ZFS_IOC_OBJSET_STATS, &zc) != 0 || 310*1544Seschrock zc.zc_root[0] == '\0') 311789Sahrens return (-1); 312789Sahrens 313*1544Seschrock (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 369*1544Seschrock 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 491*1544Seschrock 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 556*1544Seschrock 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 641*1544Seschrock 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, 716*1544Seschrock &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; 728*1544Seschrock 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 766*1544Seschrock case ENOTSUP: 767*1544Seschrock /* 768*1544Seschrock * Unsupported version. 769*1544Seschrock */ 770*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, 771*1544Seschrock "%s: unsupported version"), desc); 772*1544Seschrock break; 773*1544Seschrock 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 806*1544Seschrock 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 834*1544Seschrock static uint64_t 835*1544Seschrock vdev_to_guid(nvlist_t *nv, const char *search, uint64_t guid) 836*1544Seschrock { 837*1544Seschrock uint_t c, children; 838*1544Seschrock nvlist_t **child; 839*1544Seschrock uint64_t ret, present; 840*1544Seschrock char *path; 841*1544Seschrock uint64_t wholedisk = 0; 842*1544Seschrock 843*1544Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &ret) == 0); 844*1544Seschrock 845*1544Seschrock if (search == NULL && 846*1544Seschrock nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &present) == 0) { 847*1544Seschrock /* 848*1544Seschrock * If the device has never been present since import, the only 849*1544Seschrock * reliable way to match the vdev is by GUID. 850*1544Seschrock */ 851*1544Seschrock if (ret == guid) 852*1544Seschrock return (ret); 853*1544Seschrock } else if (search != NULL && 854*1544Seschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 855*1544Seschrock (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 856*1544Seschrock &wholedisk); 857*1544Seschrock if (wholedisk) { 858*1544Seschrock /* 859*1544Seschrock * For whole disks, the internal path has 's0', but the 860*1544Seschrock * path passed in by the user doesn't. 861*1544Seschrock */ 862*1544Seschrock if (strlen(search) == strlen(path) - 2 && 863*1544Seschrock strncmp(search, path, strlen(search)) == 0) 864*1544Seschrock return (ret); 865*1544Seschrock } else if (strcmp(search, path) == 0) { 866*1544Seschrock return (ret); 867*1544Seschrock } 868*1544Seschrock } 869*1544Seschrock 870*1544Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 871*1544Seschrock &child, &children) != 0) 872*1544Seschrock return (0); 873*1544Seschrock 874*1544Seschrock for (c = 0; c < children; c++) 875*1544Seschrock if ((ret = vdev_to_guid(child[c], search, guid)) != 0) 876*1544Seschrock return (ret); 877*1544Seschrock 878*1544Seschrock return (0); 879*1544Seschrock } 880*1544Seschrock 881*1544Seschrock /* 882*1544Seschrock * Given a string describing a vdev, returns the matching GUID, or 0 if none. 883*1544Seschrock */ 884*1544Seschrock uint64_t 885*1544Seschrock zpool_vdev_to_guid(zpool_handle_t *zhp, const char *path) 886*1544Seschrock { 887*1544Seschrock char buf[MAXPATHLEN]; 888*1544Seschrock const char *search; 889*1544Seschrock char *end; 890*1544Seschrock nvlist_t *nvroot; 891*1544Seschrock uint64_t guid; 892*1544Seschrock 893*1544Seschrock guid = strtoull(path, &end, 16); 894*1544Seschrock if (guid != 0 && *end == '\0') { 895*1544Seschrock search = NULL; 896*1544Seschrock } else if (path[0] != '/') { 897*1544Seschrock (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path); 898*1544Seschrock search = buf; 899*1544Seschrock } else { 900*1544Seschrock search = path; 901*1544Seschrock } 902*1544Seschrock 903*1544Seschrock verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 904*1544Seschrock &nvroot) == 0); 905*1544Seschrock 906*1544Seschrock return (vdev_to_guid(nvroot, search, guid)); 907*1544Seschrock } 908*1544Seschrock 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 918*1544Seschrock (void) snprintf(msg, sizeof (msg), 919*1544Seschrock dgettext(TEXT_DOMAIN, "cannot online %s"), path); 920789Sahrens 921*1544Seschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 922*1544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 923*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 924*1544Seschrock msg); 925*1544Seschrock return (-1); 926*1544Seschrock } 927789Sahrens 928*1544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_ONLINE, &zc) == 0) 929*1544Seschrock 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 961*1544Seschrock (void) snprintf(msg, sizeof (msg), 962*1544Seschrock dgettext(TEXT_DOMAIN, "cannot offline %s"), path); 963*1544Seschrock 964789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 965*1544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 966*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 967*1544Seschrock msg); 968*1544Seschrock return (-1); 969*1544Seschrock } 970789Sahrens 9711485Slling zc.zc_cookie = istmp; 9721485Slling 973*1544Seschrock 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 1018*1544Seschrock if (replacing) 1019*1544Seschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1020*1544Seschrock "cannot replace %s with %s"), old_disk, new_disk); 1021*1544Seschrock else 1022*1544Seschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 1023*1544Seschrock "cannot attach %s to %s"), new_disk, old_disk); 1024*1544Seschrock 1025789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1026*1544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, old_disk)) == 0) { 1027*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 1028*1544Seschrock msg); 1029*1544Seschrock return (-1); 1030*1544Seschrock } 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 1042*1544Seschrock ret = zfs_ioctl(ZFS_IOC_VDEV_ATTACH, &zc); 1043789Sahrens 1044789Sahrens free(packed); 1045789Sahrens 1046789Sahrens if (ret == 0) 1047789Sahrens return (0); 1048789Sahrens 1049789Sahrens switch (errno) { 1050*1544Seschrock 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 1057*1544Seschrock 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 1065*1544Seschrock 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 1077*1544Seschrock 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 1085*1544Seschrock 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 1095*1544Seschrock 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 1102*1544Seschrock 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 1110*1544Seschrock 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 1118*1544Seschrock 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 1126*1544Seschrock 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 1142*1544Seschrock (void) snprintf(msg, sizeof (msg), 1143*1544Seschrock dgettext(TEXT_DOMAIN, "cannot detach %s"), path); 1144*1544Seschrock 1145789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1146*1544Seschrock if ((zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 1147*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool")); 1148*1544Seschrock return (-1); 1149*1544Seschrock } 1150789Sahrens 1151*1544Seschrock if (zfs_ioctl(ZFS_IOC_VDEV_DETACH, &zc) == 0) 1152789Sahrens return (0); 1153789Sahrens 1154789Sahrens switch (errno) { 1155*1544Seschrock case EPERM: 1156789Sahrens /* 1157789Sahrens * No permission to mess with the config. 1158789Sahrens */ 1159789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 1160789Sahrens break; 1161789Sahrens 1162*1544Seschrock case ENODEV: 1163789Sahrens /* 1164789Sahrens * Device doesn't exist. 1165789Sahrens */ 1166789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 1167789Sahrens break; 1168789Sahrens 1169*1544Seschrock case ENOTSUP: 1170789Sahrens /* 1171789Sahrens * Can't detach from this type of vdev. 1172789Sahrens */ 1173789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1174789Sahrens "%s: only applicable to mirror and replacing vdevs"), msg); 1175789Sahrens break; 1176789Sahrens 1177*1544Seschrock case EBUSY: 1178789Sahrens /* 1179789Sahrens * There are no other replicas of this device. 1180789Sahrens */ 1181789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg); 1182789Sahrens break; 1183789Sahrens 1184*1544Seschrock default: 1185*1544Seschrock zfs_baderror(errno); 1186*1544Seschrock } 1187*1544Seschrock 1188*1544Seschrock return (1); 1189*1544Seschrock } 1190*1544Seschrock 1191*1544Seschrock /* 1192*1544Seschrock * Clear the errors for the pool, or the particular device if specified. 1193*1544Seschrock */ 1194*1544Seschrock int 1195*1544Seschrock zpool_clear(zpool_handle_t *zhp, const char *path) 1196*1544Seschrock { 1197*1544Seschrock zfs_cmd_t zc = { 0 }; 1198*1544Seschrock char msg[1024]; 1199*1544Seschrock 1200*1544Seschrock if (path) 1201*1544Seschrock (void) snprintf(msg, sizeof (msg), 1202*1544Seschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1203*1544Seschrock zc.zc_prop_value); 1204*1544Seschrock else 1205*1544Seschrock (void) snprintf(msg, sizeof (msg), 1206*1544Seschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"), 1207*1544Seschrock zhp->zpool_name); 1208*1544Seschrock 1209*1544Seschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1210*1544Seschrock if (path && (zc.zc_guid = zpool_vdev_to_guid(zhp, path)) == 0) { 1211*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: no such device in pool"), 1212*1544Seschrock msg); 1213*1544Seschrock return (-1); 1214*1544Seschrock } 1215*1544Seschrock 1216*1544Seschrock if (zfs_ioctl(ZFS_IOC_CLEAR, &zc) == 0) 1217*1544Seschrock return (0); 1218*1544Seschrock 1219*1544Seschrock switch (errno) { 1220*1544Seschrock case EPERM: 1221*1544Seschrock /* 1222*1544Seschrock * No permission to mess with the config. 1223*1544Seschrock */ 1224*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 1225*1544Seschrock break; 1226*1544Seschrock 1227*1544Seschrock case ENODEV: 1228*1544Seschrock /* 1229*1544Seschrock * Device doesn't exist. 1230*1544Seschrock */ 1231*1544Seschrock zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 1232*1544Seschrock break; 1233*1544Seschrock 1234*1544Seschrock default: 1235789Sahrens zfs_baderror(errno); 1236789Sahrens } 1237789Sahrens 1238789Sahrens return (1); 1239789Sahrens } 1240789Sahrens 1241789Sahrens static int 1242789Sahrens do_zvol(zfs_handle_t *zhp, void *data) 1243789Sahrens { 1244789Sahrens int linktype = (int)(uintptr_t)data; 1245789Sahrens int ret; 1246789Sahrens 1247789Sahrens /* 1248789Sahrens * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we 1249789Sahrens * correctly handle snapshots of volumes. 1250789Sahrens */ 1251789Sahrens if (zhp->zfs_volblocksize != 0) { 1252789Sahrens if (linktype) 1253789Sahrens ret = zvol_create_link(zhp->zfs_name); 1254789Sahrens else 1255789Sahrens ret = zvol_remove_link(zhp->zfs_name); 1256789Sahrens } 1257789Sahrens 1258789Sahrens ret = zfs_iter_children(zhp, do_zvol, data); 1259789Sahrens 1260789Sahrens zfs_close(zhp); 1261789Sahrens return (ret); 1262789Sahrens } 1263789Sahrens 1264789Sahrens /* 1265789Sahrens * Iterate over all zvols in the pool and make any necessary minor nodes. 1266789Sahrens */ 1267789Sahrens int 1268789Sahrens zpool_create_zvol_links(zpool_handle_t *zhp) 1269789Sahrens { 1270789Sahrens zfs_handle_t *zfp; 1271789Sahrens int ret; 1272789Sahrens 1273789Sahrens /* 1274789Sahrens * If the pool is unavailable, just return success. 1275789Sahrens */ 1276789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1277789Sahrens return (0); 1278789Sahrens 1279789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)TRUE); 1280789Sahrens 1281789Sahrens zfs_close(zfp); 1282789Sahrens return (ret); 1283789Sahrens } 1284789Sahrens 1285789Sahrens /* 1286789Sahrens * Iterate over all zvols in the poool and remove any minor nodes. 1287789Sahrens */ 1288789Sahrens int 1289789Sahrens zpool_remove_zvol_links(zpool_handle_t *zhp) 1290789Sahrens { 1291789Sahrens zfs_handle_t *zfp; 1292789Sahrens int ret; 1293789Sahrens 1294789Sahrens /* 1295789Sahrens * If the pool is unavailable, just return success. 1296789Sahrens */ 1297789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1298789Sahrens return (0); 1299789Sahrens 1300789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)FALSE); 1301789Sahrens 1302789Sahrens zfs_close(zfp); 1303789Sahrens return (ret); 1304789Sahrens } 13051354Seschrock 13061354Seschrock /* 13071354Seschrock * Convert from a devid string to a path. 13081354Seschrock */ 13091354Seschrock static char * 13101354Seschrock devid_to_path(char *devid_str) 13111354Seschrock { 13121354Seschrock ddi_devid_t devid; 13131354Seschrock char *minor; 13141354Seschrock char *path; 13151354Seschrock devid_nmlist_t *list = NULL; 13161354Seschrock int ret; 13171354Seschrock 13181354Seschrock if (devid_str_decode(devid_str, &devid, &minor) != 0) 13191354Seschrock return (NULL); 13201354Seschrock 13211354Seschrock ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list); 13221354Seschrock 13231354Seschrock devid_str_free(minor); 13241354Seschrock devid_free(devid); 13251354Seschrock 13261354Seschrock if (ret != 0) 13271354Seschrock return (NULL); 13281354Seschrock 13291354Seschrock path = zfs_strdup(list[0].devname); 13301354Seschrock devid_free_nmlist(list); 13311354Seschrock 13321354Seschrock return (path); 13331354Seschrock } 13341354Seschrock 13351354Seschrock /* 13361354Seschrock * Convert from a path to a devid string. 13371354Seschrock */ 13381354Seschrock static char * 13391354Seschrock path_to_devid(const char *path) 13401354Seschrock { 13411354Seschrock int fd; 13421354Seschrock ddi_devid_t devid; 13431354Seschrock char *minor, *ret; 13441354Seschrock 13451354Seschrock if ((fd = open(path, O_RDONLY)) < 0) 13461354Seschrock return (NULL); 13471354Seschrock 13481354Seschrock minor = NULL; 13491354Seschrock ret = NULL; 13501354Seschrock if (devid_get(fd, &devid) == 0) { 13511354Seschrock if (devid_get_minor_name(fd, &minor) == 0) 13521354Seschrock ret = devid_str_encode(devid, minor); 13531354Seschrock if (minor != NULL) 13541354Seschrock devid_str_free(minor); 13551354Seschrock devid_free(devid); 13561354Seschrock } 13571354Seschrock (void) close(fd); 13581354Seschrock 13591354Seschrock return (ret); 13601354Seschrock } 13611354Seschrock 13621354Seschrock /* 13631354Seschrock * Issue the necessary ioctl() to update the stored path value for the vdev. We 13641354Seschrock * ignore any failure here, since a common case is for an unprivileged user to 13651354Seschrock * type 'zpool status', and we'll display the correct information anyway. 13661354Seschrock */ 13671354Seschrock static void 13681354Seschrock set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) 13691354Seschrock { 13701354Seschrock zfs_cmd_t zc = { 0 }; 13711354Seschrock 13721354Seschrock (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 13731354Seschrock (void) strncpy(zc.zc_prop_value, path, sizeof (zc.zc_prop_value)); 13741354Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1375*1544Seschrock &zc.zc_guid) == 0); 13761354Seschrock 1377*1544Seschrock (void) zfs_ioctl(ZFS_IOC_VDEV_SETPATH, &zc); 13781354Seschrock } 13791354Seschrock 13801354Seschrock /* 13811354Seschrock * Given a vdev, return the name to display in iostat. If the vdev has a path, 13821354Seschrock * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type. 13831354Seschrock * We also check if this is a whole disk, in which case we strip off the 13841354Seschrock * trailing 's0' slice name. 13851354Seschrock * 13861354Seschrock * This routine is also responsible for identifying when disks have been 13871354Seschrock * reconfigured in a new location. The kernel will have opened the device by 13881354Seschrock * devid, but the path will still refer to the old location. To catch this, we 13891354Seschrock * first do a path -> devid translation (which is fast for the common case). If 13901354Seschrock * the devid matches, we're done. If not, we do a reverse devid -> path 13911354Seschrock * translation and issue the appropriate ioctl() to update the path of the vdev. 13921354Seschrock * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any 13931354Seschrock * of these checks. 13941354Seschrock */ 13951354Seschrock char * 13961354Seschrock zpool_vdev_name(zpool_handle_t *zhp, nvlist_t *nv) 13971354Seschrock { 13981354Seschrock char *path, *devid; 1399*1544Seschrock uint64_t value; 1400*1544Seschrock char buf[64]; 14011354Seschrock 1402*1544Seschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1403*1544Seschrock &value) == 0) { 1404*1544Seschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1405*1544Seschrock &value) == 0); 1406*1544Seschrock (void) snprintf(buf, sizeof (buf), "%llx", value); 1407*1544Seschrock path = buf; 1408*1544Seschrock } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { 14091354Seschrock 14101354Seschrock if (zhp != NULL && 14111354Seschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) { 14121354Seschrock /* 14131354Seschrock * Determine if the current path is correct. 14141354Seschrock */ 14151354Seschrock char *newdevid = path_to_devid(path); 14161354Seschrock 14171354Seschrock if (newdevid == NULL || 14181354Seschrock strcmp(devid, newdevid) != 0) { 14191354Seschrock char *newpath; 14201354Seschrock 14211354Seschrock if ((newpath = devid_to_path(devid)) != NULL) { 14221354Seschrock /* 14231354Seschrock * Update the path appropriately. 14241354Seschrock */ 14251354Seschrock set_path(zhp, nv, newpath); 14261354Seschrock verify(nvlist_add_string(nv, 14271354Seschrock ZPOOL_CONFIG_PATH, newpath) == 0); 14281354Seschrock free(newpath); 14291354Seschrock verify(nvlist_lookup_string(nv, 14301354Seschrock ZPOOL_CONFIG_PATH, &path) == 0); 14311354Seschrock } 14321354Seschrock 14331354Seschrock if (newdevid) 14341354Seschrock devid_str_free(newdevid); 14351354Seschrock } 14361354Seschrock 14371354Seschrock } 14381354Seschrock 14391354Seschrock if (strncmp(path, "/dev/dsk/", 9) == 0) 14401354Seschrock path += 9; 14411354Seschrock 14421354Seschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, 1443*1544Seschrock &value) == 0 && value) { 14441354Seschrock char *tmp = zfs_strdup(path); 14451354Seschrock tmp[strlen(path) - 2] = '\0'; 14461354Seschrock return (tmp); 14471354Seschrock } 14481354Seschrock } else { 14491354Seschrock verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0); 14501354Seschrock } 14511354Seschrock 14521354Seschrock return (zfs_strdup(path)); 14531354Seschrock } 1454*1544Seschrock 1455*1544Seschrock static int 1456*1544Seschrock zbookmark_compare(const void *a, const void *b) 1457*1544Seschrock { 1458*1544Seschrock return (memcmp(a, b, sizeof (zbookmark_t))); 1459*1544Seschrock } 1460*1544Seschrock 1461*1544Seschrock /* 1462*1544Seschrock * Retrieve the persistent error log, uniquify the members, and return to the 1463*1544Seschrock * caller. 1464*1544Seschrock */ 1465*1544Seschrock int 1466*1544Seschrock zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem) 1467*1544Seschrock { 1468*1544Seschrock zfs_cmd_t zc = { 0 }; 1469*1544Seschrock uint64_t count; 1470*1544Seschrock zbookmark_t *zb; 1471*1544Seschrock int i, j; 1472*1544Seschrock 1473*1544Seschrock if (zhp->zpool_error_log != NULL) { 1474*1544Seschrock *list = zhp->zpool_error_log; 1475*1544Seschrock *nelem = zhp->zpool_error_count; 1476*1544Seschrock return (0); 1477*1544Seschrock } 1478*1544Seschrock 1479*1544Seschrock /* 1480*1544Seschrock * Retrieve the raw error list from the kernel. If the number of errors 1481*1544Seschrock * has increased, allocate more space and continue until we get the 1482*1544Seschrock * entire list. 1483*1544Seschrock */ 1484*1544Seschrock verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT, 1485*1544Seschrock &count) == 0); 1486*1544Seschrock zc.zc_config_dst = (uintptr_t)zfs_malloc(count * sizeof (zbookmark_t)); 1487*1544Seschrock zc.zc_config_dst_size = count; 1488*1544Seschrock (void) strcpy(zc.zc_name, zhp->zpool_name); 1489*1544Seschrock for (;;) { 1490*1544Seschrock if (zfs_ioctl(ZFS_IOC_ERROR_LOG, &zc) != 0) { 1491*1544Seschrock if (errno == ENOMEM) { 1492*1544Seschrock free((void *)(uintptr_t)zc.zc_config_dst); 1493*1544Seschrock zc.zc_config_dst = (uintptr_t) 1494*1544Seschrock zfs_malloc(zc.zc_config_dst_size); 1495*1544Seschrock } else { 1496*1544Seschrock return (-1); 1497*1544Seschrock } 1498*1544Seschrock } else { 1499*1544Seschrock break; 1500*1544Seschrock } 1501*1544Seschrock } 1502*1544Seschrock 1503*1544Seschrock /* 1504*1544Seschrock * Sort the resulting bookmarks. This is a little confusing due to the 1505*1544Seschrock * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last 1506*1544Seschrock * to first, and 'zc_config_dst_size' indicates the number of boomarks 1507*1544Seschrock * _not_ copied as part of the process. So we point the start of our 1508*1544Seschrock * array appropriate and decrement the total number of elements. 1509*1544Seschrock */ 1510*1544Seschrock zb = ((zbookmark_t *)(uintptr_t)zc.zc_config_dst) + 1511*1544Seschrock zc.zc_config_dst_size; 1512*1544Seschrock count -= zc.zc_config_dst_size; 1513*1544Seschrock 1514*1544Seschrock qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare); 1515*1544Seschrock 1516*1544Seschrock /* 1517*1544Seschrock * Count the number of unique elements 1518*1544Seschrock */ 1519*1544Seschrock j = 0; 1520*1544Seschrock for (i = 0; i < count; i++) { 1521*1544Seschrock if (i > 0 && memcmp(&zb[i - 1], &zb[i], 1522*1544Seschrock sizeof (zbookmark_t)) == 0) 1523*1544Seschrock continue; 1524*1544Seschrock j++; 1525*1544Seschrock } 1526*1544Seschrock 1527*1544Seschrock /* 1528*1544Seschrock * If the user has only requested the number of items, return it now 1529*1544Seschrock * without bothering with the extra work. 1530*1544Seschrock */ 1531*1544Seschrock if (list == NULL) { 1532*1544Seschrock *nelem = j; 1533*1544Seschrock return (0); 1534*1544Seschrock } 1535*1544Seschrock 1536*1544Seschrock zhp->zpool_error_count = j; 1537*1544Seschrock 1538*1544Seschrock /* 1539*1544Seschrock * Allocate an array of nvlists to hold the results 1540*1544Seschrock */ 1541*1544Seschrock zhp->zpool_error_log = zfs_malloc(j * sizeof (nvlist_t *)); 1542*1544Seschrock 1543*1544Seschrock /* 1544*1544Seschrock * Fill in the results with names from the kernel. 1545*1544Seschrock */ 1546*1544Seschrock j = 0; 1547*1544Seschrock for (i = 0; i < count; i++) { 1548*1544Seschrock char buf[64]; 1549*1544Seschrock nvlist_t *nv; 1550*1544Seschrock 1551*1544Seschrock if (i > 0 && memcmp(&zb[i - 1], &zb[i], 1552*1544Seschrock sizeof (zbookmark_t)) == 0) 1553*1544Seschrock continue; 1554*1544Seschrock 1555*1544Seschrock verify(nvlist_alloc(&nv, NV_UNIQUE_NAME, 1556*1544Seschrock 0) == 0); 1557*1544Seschrock zhp->zpool_error_log[j] = nv; 1558*1544Seschrock 1559*1544Seschrock zc.zc_bookmark = zb[i]; 1560*1544Seschrock if (zfs_ioctl(ZFS_IOC_BOOKMARK_NAME, &zc) == 0) { 1561*1544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_DATASET, 1562*1544Seschrock zc.zc_prop_name) == 0); 1563*1544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_OBJECT, 1564*1544Seschrock zc.zc_prop_value) == 0); 1565*1544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_RANGE, 1566*1544Seschrock zc.zc_filename) == 0); 1567*1544Seschrock } else { 1568*1544Seschrock (void) snprintf(buf, sizeof (buf), "%llx", 1569*1544Seschrock zb[i].zb_objset); 1570*1544Seschrock verify(nvlist_add_string(nv, 1571*1544Seschrock ZPOOL_ERR_DATASET, buf) == 0); 1572*1544Seschrock (void) snprintf(buf, sizeof (buf), "%llx", 1573*1544Seschrock zb[i].zb_object); 1574*1544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_OBJECT, 1575*1544Seschrock buf) == 0); 1576*1544Seschrock (void) snprintf(buf, sizeof (buf), "lvl=%u blkid=%llu", 1577*1544Seschrock (int)zb[i].zb_level, (long long)zb[i].zb_blkid); 1578*1544Seschrock verify(nvlist_add_string(nv, ZPOOL_ERR_RANGE, 1579*1544Seschrock buf) == 0); 1580*1544Seschrock } 1581*1544Seschrock 1582*1544Seschrock j++; 1583*1544Seschrock } 1584*1544Seschrock 1585*1544Seschrock *list = zhp->zpool_error_log; 1586*1544Seschrock *nelem = zhp->zpool_error_count; 1587*1544Seschrock 1588*1544Seschrock free((void *)(uintptr_t)zc.zc_config_dst); 1589*1544Seschrock 1590*1544Seschrock return (0); 1591*1544Seschrock } 1592