1*789Sahrens /* 2*789Sahrens * CDDL HEADER START 3*789Sahrens * 4*789Sahrens * The contents of this file are subject to the terms of the 5*789Sahrens * Common Development and Distribution License, Version 1.0 only 6*789Sahrens * (the "License"). You may not use this file except in compliance 7*789Sahrens * with the License. 8*789Sahrens * 9*789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*789Sahrens * or http://www.opensolaris.org/os/licensing. 11*789Sahrens * See the License for the specific language governing permissions 12*789Sahrens * and limitations under the License. 13*789Sahrens * 14*789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15*789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*789Sahrens * If applicable, add the following below this CDDL HEADER, with the 17*789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18*789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19*789Sahrens * 20*789Sahrens * CDDL HEADER END 21*789Sahrens */ 22*789Sahrens /* 23*789Sahrens * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*789Sahrens * Use is subject to license terms. 25*789Sahrens */ 26*789Sahrens 27*789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28*789Sahrens 29*789Sahrens #include <assert.h> 30*789Sahrens #include <ctype.h> 31*789Sahrens #include <errno.h> 32*789Sahrens #include <devid.h> 33*789Sahrens #include <fcntl.h> 34*789Sahrens #include <libintl.h> 35*789Sahrens #include <stdio.h> 36*789Sahrens #include <stdlib.h> 37*789Sahrens #include <string.h> 38*789Sahrens #include <unistd.h> 39*789Sahrens #include <sys/zfs_ioctl.h> 40*789Sahrens 41*789Sahrens #include "zfs_namecheck.h" 42*789Sahrens #include "libzfs_impl.h" 43*789Sahrens 44*789Sahrens /* 45*789Sahrens * Validate the given pool name, optionally putting an extended error message in 46*789Sahrens * 'buf'. 47*789Sahrens */ 48*789Sahrens static int 49*789Sahrens zpool_name_valid(const char *pool, char *buf, size_t buflen) 50*789Sahrens { 51*789Sahrens namecheck_err_t why; 52*789Sahrens char what; 53*789Sahrens 54*789Sahrens if (strlen(pool) >= ZPOOL_MAXNAMELEN) { 55*789Sahrens if (buf) 56*789Sahrens (void) snprintf(buf, buflen, 57*789Sahrens dgettext(TEXT_DOMAIN, "name is too long")); 58*789Sahrens return (FALSE); 59*789Sahrens } 60*789Sahrens 61*789Sahrens if (pool_namecheck(pool, &why, &what) != 0) { 62*789Sahrens if (buf != NULL) { 63*789Sahrens switch (why) { 64*789Sahrens case NAME_ERR_INVALCHAR: 65*789Sahrens (void) snprintf(buf, buflen, 66*789Sahrens dgettext(TEXT_DOMAIN, "invalid character " 67*789Sahrens "'%c' in pool name"), what); 68*789Sahrens break; 69*789Sahrens 70*789Sahrens case NAME_ERR_NOLETTER: 71*789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 72*789Sahrens "name must begin with a letter"), buflen); 73*789Sahrens break; 74*789Sahrens 75*789Sahrens case NAME_ERR_RESERVED: 76*789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 77*789Sahrens "name is reserved\n" 78*789Sahrens "pool name may have been omitted"), buflen); 79*789Sahrens break; 80*789Sahrens 81*789Sahrens case NAME_ERR_DISKLIKE: 82*789Sahrens (void) strlcpy(buf, dgettext(TEXT_DOMAIN, 83*789Sahrens "pool name is reserved\n" 84*789Sahrens "pool name may have been omitted"), buflen); 85*789Sahrens break; 86*789Sahrens } 87*789Sahrens } 88*789Sahrens return (FALSE); 89*789Sahrens } 90*789Sahrens 91*789Sahrens return (TRUE); 92*789Sahrens } 93*789Sahrens 94*789Sahrens /* 95*789Sahrens * Set the pool-wide health based on the vdev state of the root vdev. 96*789Sahrens */ 97*789Sahrens void 98*789Sahrens set_pool_health(nvlist_t *config) 99*789Sahrens { 100*789Sahrens nvlist_t *nvroot; 101*789Sahrens vdev_stat_t *vs; 102*789Sahrens uint_t vsc; 103*789Sahrens char *health; 104*789Sahrens 105*789Sahrens verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 106*789Sahrens &nvroot) == 0); 107*789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 108*789Sahrens (uint64_t **)&vs, &vsc) == 0); 109*789Sahrens 110*789Sahrens switch (vs->vs_state) { 111*789Sahrens 112*789Sahrens case VDEV_STATE_CLOSED: 113*789Sahrens case VDEV_STATE_CANT_OPEN: 114*789Sahrens case VDEV_STATE_OFFLINE: 115*789Sahrens health = dgettext(TEXT_DOMAIN, "FAULTED"); 116*789Sahrens break; 117*789Sahrens 118*789Sahrens case VDEV_STATE_DEGRADED: 119*789Sahrens health = dgettext(TEXT_DOMAIN, "DEGRADED"); 120*789Sahrens break; 121*789Sahrens 122*789Sahrens case VDEV_STATE_HEALTHY: 123*789Sahrens health = dgettext(TEXT_DOMAIN, "ONLINE"); 124*789Sahrens break; 125*789Sahrens 126*789Sahrens default: 127*789Sahrens zfs_baderror(vs->vs_state); 128*789Sahrens } 129*789Sahrens 130*789Sahrens verify(nvlist_add_string(config, ZPOOL_CONFIG_POOL_HEALTH, 131*789Sahrens health) == 0); 132*789Sahrens } 133*789Sahrens 134*789Sahrens /* 135*789Sahrens * Open a handle to the given pool, even if the pool is currently in the FAULTED 136*789Sahrens * state. 137*789Sahrens */ 138*789Sahrens zpool_handle_t * 139*789Sahrens zpool_open_canfail(const char *pool) 140*789Sahrens { 141*789Sahrens zpool_handle_t *zhp; 142*789Sahrens nvlist_t *newconfig; 143*789Sahrens int error; 144*789Sahrens 145*789Sahrens /* 146*789Sahrens * Make sure the pool name is valid. 147*789Sahrens */ 148*789Sahrens if (!zpool_name_valid(pool, NULL, 0)) { 149*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': invalid " 150*789Sahrens "pool name"), pool); 151*789Sahrens return (NULL); 152*789Sahrens } 153*789Sahrens 154*789Sahrens zhp = zfs_malloc(sizeof (zpool_handle_t)); 155*789Sahrens 156*789Sahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 157*789Sahrens 158*789Sahrens if ((error = zpool_refresh_stats(zhp, NULL, &newconfig)) != 0) { 159*789Sahrens if (error == ENOENT || error == EINVAL) { 160*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot open '%s': no " 161*789Sahrens "such pool"), pool); 162*789Sahrens free(zhp); 163*789Sahrens return (NULL); 164*789Sahrens } else { 165*789Sahrens zhp->zpool_state = POOL_STATE_UNAVAIL; 166*789Sahrens } 167*789Sahrens } else { 168*789Sahrens zhp->zpool_state = POOL_STATE_ACTIVE; 169*789Sahrens } 170*789Sahrens 171*789Sahrens return (zhp); 172*789Sahrens } 173*789Sahrens 174*789Sahrens /* 175*789Sahrens * Like the above, but silent on error. Used when iterating over pools (because 176*789Sahrens * the configuration cache may be out of date). 177*789Sahrens */ 178*789Sahrens zpool_handle_t * 179*789Sahrens zpool_open_silent(const char *pool) 180*789Sahrens { 181*789Sahrens zpool_handle_t *zhp; 182*789Sahrens nvlist_t *newconfig; 183*789Sahrens int error; 184*789Sahrens 185*789Sahrens zhp = zfs_malloc(sizeof (zpool_handle_t)); 186*789Sahrens 187*789Sahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name)); 188*789Sahrens 189*789Sahrens if ((error = zpool_refresh_stats(zhp, NULL, &newconfig)) != 0) { 190*789Sahrens if (error == ENOENT || error == EINVAL) { 191*789Sahrens free(zhp); 192*789Sahrens return (NULL); 193*789Sahrens } else { 194*789Sahrens zhp->zpool_state = POOL_STATE_UNAVAIL; 195*789Sahrens } 196*789Sahrens } else { 197*789Sahrens zhp->zpool_state = POOL_STATE_ACTIVE; 198*789Sahrens } 199*789Sahrens 200*789Sahrens return (zhp); 201*789Sahrens } 202*789Sahrens 203*789Sahrens /* 204*789Sahrens * Similar to zpool_open_canfail(), but refuses to open pools in the faulted 205*789Sahrens * state. 206*789Sahrens */ 207*789Sahrens zpool_handle_t * 208*789Sahrens zpool_open(const char *pool) 209*789Sahrens { 210*789Sahrens zpool_handle_t *zhp; 211*789Sahrens 212*789Sahrens if ((zhp = zpool_open_canfail(pool)) == NULL) 213*789Sahrens return (NULL); 214*789Sahrens 215*789Sahrens if (zhp->zpool_state == POOL_STATE_UNAVAIL) { 216*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot open ' %s': pool is " 217*789Sahrens "currently unavailable\n"), zhp->zpool_name); 218*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "run 'zpool status -v %s' for " 219*789Sahrens "detailed information\n"), zhp->zpool_name); 220*789Sahrens zpool_close(zhp); 221*789Sahrens return (NULL); 222*789Sahrens } 223*789Sahrens 224*789Sahrens return (zhp); 225*789Sahrens } 226*789Sahrens 227*789Sahrens /* 228*789Sahrens * Close the handle. Simply frees the memory associated with the handle. 229*789Sahrens */ 230*789Sahrens void 231*789Sahrens zpool_close(zpool_handle_t *zhp) 232*789Sahrens { 233*789Sahrens if (zhp->zpool_config) 234*789Sahrens nvlist_free(zhp->zpool_config); 235*789Sahrens free(zhp); 236*789Sahrens } 237*789Sahrens 238*789Sahrens /* 239*789Sahrens * Return the name of the pool. 240*789Sahrens */ 241*789Sahrens const char * 242*789Sahrens zpool_get_name(zpool_handle_t *zhp) 243*789Sahrens { 244*789Sahrens return (zhp->zpool_name); 245*789Sahrens } 246*789Sahrens 247*789Sahrens /* 248*789Sahrens * Return the GUID of the pool. 249*789Sahrens */ 250*789Sahrens uint64_t 251*789Sahrens zpool_get_guid(zpool_handle_t *zhp) 252*789Sahrens { 253*789Sahrens uint64_t guid; 254*789Sahrens 255*789Sahrens verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID, 256*789Sahrens &guid) == 0); 257*789Sahrens return (guid); 258*789Sahrens } 259*789Sahrens 260*789Sahrens /* 261*789Sahrens * Return the amount of space currently consumed by the pool. 262*789Sahrens */ 263*789Sahrens uint64_t 264*789Sahrens zpool_get_space_used(zpool_handle_t *zhp) 265*789Sahrens { 266*789Sahrens nvlist_t *nvroot; 267*789Sahrens vdev_stat_t *vs; 268*789Sahrens uint_t vsc; 269*789Sahrens 270*789Sahrens verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 271*789Sahrens &nvroot) == 0); 272*789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 273*789Sahrens (uint64_t **)&vs, &vsc) == 0); 274*789Sahrens 275*789Sahrens return (vs->vs_alloc); 276*789Sahrens } 277*789Sahrens 278*789Sahrens /* 279*789Sahrens * Return the total space in the pool. 280*789Sahrens */ 281*789Sahrens uint64_t 282*789Sahrens zpool_get_space_total(zpool_handle_t *zhp) 283*789Sahrens { 284*789Sahrens nvlist_t *nvroot; 285*789Sahrens vdev_stat_t *vs; 286*789Sahrens uint_t vsc; 287*789Sahrens 288*789Sahrens verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, 289*789Sahrens &nvroot) == 0); 290*789Sahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 291*789Sahrens (uint64_t **)&vs, &vsc) == 0); 292*789Sahrens 293*789Sahrens return (vs->vs_space); 294*789Sahrens } 295*789Sahrens 296*789Sahrens /* 297*789Sahrens * Return the alternate root for this pool, if any. 298*789Sahrens */ 299*789Sahrens int 300*789Sahrens zpool_get_root(zpool_handle_t *zhp, char *buf, size_t buflen) 301*789Sahrens { 302*789Sahrens zfs_cmd_t zc = { 0 }; 303*789Sahrens 304*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 305*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 || 306*789Sahrens zc.zc_objset_stats.dds_altroot[0] == '\0') 307*789Sahrens return (-1); 308*789Sahrens 309*789Sahrens (void) strlcpy(buf, zc.zc_objset_stats.dds_altroot, buflen); 310*789Sahrens 311*789Sahrens return (0); 312*789Sahrens } 313*789Sahrens 314*789Sahrens /* 315*789Sahrens * Return the state of the pool (ACTIVE or UNAVAILABLE) 316*789Sahrens */ 317*789Sahrens int 318*789Sahrens zpool_get_state(zpool_handle_t *zhp) 319*789Sahrens { 320*789Sahrens return (zhp->zpool_state); 321*789Sahrens } 322*789Sahrens 323*789Sahrens /* 324*789Sahrens * Create the named pool, using the provided vdev list. It is assumed 325*789Sahrens * that the consumer has already validated the contents of the nvlist, so we 326*789Sahrens * don't have to worry about error semantics. 327*789Sahrens */ 328*789Sahrens int 329*789Sahrens zpool_create(const char *pool, nvlist_t *nvroot, const char *altroot) 330*789Sahrens { 331*789Sahrens zfs_cmd_t zc = { 0 }; 332*789Sahrens char *packed; 333*789Sahrens size_t len; 334*789Sahrens int err; 335*789Sahrens char reason[64]; 336*789Sahrens 337*789Sahrens if (!zpool_name_valid(pool, reason, sizeof (reason))) { 338*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': %s"), 339*789Sahrens pool, reason); 340*789Sahrens return (-1); 341*789Sahrens } 342*789Sahrens 343*789Sahrens if (altroot != NULL && altroot[0] != '/') { 344*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': alternate " 345*789Sahrens "root '%s' must be a complete path"), pool, altroot); 346*789Sahrens return (-1); 347*789Sahrens } 348*789Sahrens 349*789Sahrens if ((err = nvlist_size(nvroot, &len, NV_ENCODE_NATIVE)) != 0) 350*789Sahrens zfs_baderror(err); 351*789Sahrens 352*789Sahrens packed = zfs_malloc(len); 353*789Sahrens 354*789Sahrens if ((err = nvlist_pack(nvroot, &packed, &len, 355*789Sahrens NV_ENCODE_NATIVE, 0)) != 0) 356*789Sahrens zfs_baderror(err); 357*789Sahrens 358*789Sahrens (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name)); 359*789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 360*789Sahrens zc.zc_config_src_size = len; 361*789Sahrens 362*789Sahrens if (altroot != NULL) 363*789Sahrens (void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root)); 364*789Sahrens 365*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) { 366*789Sahrens switch (errno) { 367*789Sahrens case EEXIST: 368*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 369*789Sahrens "pool exists"), pool); 370*789Sahrens break; 371*789Sahrens 372*789Sahrens case EPERM: 373*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 374*789Sahrens "permission denied"), pool); 375*789Sahrens break; 376*789Sahrens 377*789Sahrens case EBUSY: 378*789Sahrens /* 379*789Sahrens * This can happen if the user has specified the same 380*789Sahrens * device multiple times. We can't reliably detect this 381*789Sahrens * until we try to add it and see we already have a 382*789Sahrens * label. 383*789Sahrens */ 384*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 385*789Sahrens "one or more vdevs refer to the same device"), 386*789Sahrens pool); 387*789Sahrens break; 388*789Sahrens 389*789Sahrens case EOVERFLOW: 390*789Sahrens /* 391*789Sahrens * This occurrs when one of the devices is below 392*789Sahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which 393*789Sahrens * device was the problem device since there's no 394*789Sahrens * reliable way to determine device size from userland. 395*789Sahrens */ 396*789Sahrens { 397*789Sahrens char buf[64]; 398*789Sahrens 399*789Sahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 400*789Sahrens 401*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot " 402*789Sahrens "create '%s': one or more devices is less " 403*789Sahrens "than the minimum size (%s)"), pool, 404*789Sahrens buf); 405*789Sahrens } 406*789Sahrens break; 407*789Sahrens 408*789Sahrens case ENAMETOOLONG: 409*789Sahrens /* 410*789Sahrens * One of the vdevs has exceeded VDEV_SPEC_MAX length in 411*789Sahrens * its plaintext representation. 412*789Sahrens */ 413*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 414*789Sahrens "too many devices in a single vdev"), pool); 415*789Sahrens break; 416*789Sahrens 417*789Sahrens case EIO: 418*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 419*789Sahrens "I/O error on one or more devices"), pool); 420*789Sahrens break; 421*789Sahrens 422*789Sahrens case ENXIO: 423*789Sahrens /* 424*789Sahrens * This is unlikely to happen since we've verified that 425*789Sahrens * all the devices can be opened from userland, but it's 426*789Sahrens * still possible in some circumstances. 427*789Sahrens */ 428*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 429*789Sahrens "one or more devices is unavailable"), pool); 430*789Sahrens break; 431*789Sahrens 432*789Sahrens case ENOSPC: 433*789Sahrens /* 434*789Sahrens * This can occur if we were incapable of writing to a 435*789Sahrens * file vdev because the underlying filesystem is out of 436*789Sahrens * space. This is very similar to EOVERFLOW, but we'll 437*789Sahrens * produce a slightly different message. 438*789Sahrens */ 439*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot create '%s': " 440*789Sahrens "one or more devices is out of space"), pool); 441*789Sahrens break; 442*789Sahrens 443*789Sahrens default: 444*789Sahrens zfs_baderror(errno); 445*789Sahrens } 446*789Sahrens 447*789Sahrens return (-1); 448*789Sahrens } 449*789Sahrens 450*789Sahrens free(packed); 451*789Sahrens 452*789Sahrens /* 453*789Sahrens * If this is an alternate root pool, then we automatically set the 454*789Sahrens * moutnpoint of the root dataset to be '/'. 455*789Sahrens */ 456*789Sahrens if (altroot != NULL) { 457*789Sahrens zfs_handle_t *zhp; 458*789Sahrens 459*789Sahrens verify((zhp = zfs_open(pool, ZFS_TYPE_ANY)) != NULL); 460*789Sahrens verify(zfs_prop_set(zhp, ZFS_PROP_MOUNTPOINT, "/") == 0); 461*789Sahrens 462*789Sahrens zfs_close(zhp); 463*789Sahrens } 464*789Sahrens 465*789Sahrens return (0); 466*789Sahrens } 467*789Sahrens 468*789Sahrens /* 469*789Sahrens * Destroy the given pool. It is up to the caller to ensure that there are no 470*789Sahrens * datasets left in the pool. 471*789Sahrens */ 472*789Sahrens int 473*789Sahrens zpool_destroy(zpool_handle_t *zhp) 474*789Sahrens { 475*789Sahrens zfs_cmd_t zc = { 0 }; 476*789Sahrens zfs_handle_t *zfp = NULL; 477*789Sahrens 478*789Sahrens if (zhp->zpool_state == POOL_STATE_ACTIVE && 479*789Sahrens (zfp = zfs_open(zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL) 480*789Sahrens return (-1); 481*789Sahrens 482*789Sahrens if (zpool_remove_zvol_links(zhp) != NULL) 483*789Sahrens return (-1); 484*789Sahrens 485*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 486*789Sahrens 487*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) { 488*789Sahrens switch (errno) { 489*789Sahrens case EPERM: 490*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 491*789Sahrens "cannot destroy '%s': permission denied"), 492*789Sahrens zhp->zpool_name); 493*789Sahrens break; 494*789Sahrens 495*789Sahrens case EBUSY: 496*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 497*789Sahrens "cannot destroy '%s': pool busy"), 498*789Sahrens zhp->zpool_name); 499*789Sahrens break; 500*789Sahrens 501*789Sahrens case ENOENT: 502*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 503*789Sahrens "cannot destroy '%s': no such pool"), 504*789Sahrens zhp->zpool_name); 505*789Sahrens break; 506*789Sahrens 507*789Sahrens case EROFS: 508*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 509*789Sahrens "cannot destroy '%s': one or more devices is " 510*789Sahrens "read only, or '/' is mounted read only"), 511*789Sahrens zhp->zpool_name); 512*789Sahrens break; 513*789Sahrens 514*789Sahrens default: 515*789Sahrens zfs_baderror(errno); 516*789Sahrens } 517*789Sahrens 518*789Sahrens if (zfp) 519*789Sahrens zfs_close(zfp); 520*789Sahrens return (-1); 521*789Sahrens } 522*789Sahrens 523*789Sahrens if (zfp) { 524*789Sahrens remove_mountpoint(zfp); 525*789Sahrens zfs_close(zfp); 526*789Sahrens } 527*789Sahrens 528*789Sahrens return (0); 529*789Sahrens } 530*789Sahrens 531*789Sahrens /* 532*789Sahrens * Add the given vdevs to the pool. The caller must have already performed the 533*789Sahrens * necessary verification to ensure that the vdev specification is well-formed. 534*789Sahrens */ 535*789Sahrens int 536*789Sahrens zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot) 537*789Sahrens { 538*789Sahrens char *packed; 539*789Sahrens size_t len; 540*789Sahrens zfs_cmd_t zc; 541*789Sahrens 542*789Sahrens verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0); 543*789Sahrens 544*789Sahrens packed = zfs_malloc(len); 545*789Sahrens 546*789Sahrens verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 547*789Sahrens 548*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 549*789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 550*789Sahrens zc.zc_config_src_size = len; 551*789Sahrens 552*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) { 553*789Sahrens switch (errno) { 554*789Sahrens case EPERM: 555*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 556*789Sahrens "permission denied"), zhp->zpool_name); 557*789Sahrens break; 558*789Sahrens 559*789Sahrens case EBUSY: 560*789Sahrens /* 561*789Sahrens * This can happen if the user has specified the same 562*789Sahrens * device multiple times. We can't reliably detect this 563*789Sahrens * until we try to add it and see we already have a 564*789Sahrens * label. 565*789Sahrens */ 566*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 567*789Sahrens "one or more vdevs refer to the same device"), 568*789Sahrens zhp->zpool_name); 569*789Sahrens break; 570*789Sahrens 571*789Sahrens case ENAMETOOLONG: 572*789Sahrens /* 573*789Sahrens * One of the vdevs has exceeded VDEV_SPEC_MAX length in 574*789Sahrens * its plaintext representation. 575*789Sahrens */ 576*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 577*789Sahrens "too many devices in a single vdev"), 578*789Sahrens zhp->zpool_name); 579*789Sahrens break; 580*789Sahrens 581*789Sahrens case ENXIO: 582*789Sahrens /* 583*789Sahrens * This is unlikely to happen since we've verified that 584*789Sahrens * all the devices can be opened from userland, but it's 585*789Sahrens * still possible in some circumstances. 586*789Sahrens */ 587*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot add to '%s': " 588*789Sahrens "one or more devices is unavailable"), 589*789Sahrens zhp->zpool_name); 590*789Sahrens break; 591*789Sahrens 592*789Sahrens case EOVERFLOW: 593*789Sahrens /* 594*789Sahrens * This occurrs when one of the devices is below 595*789Sahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which 596*789Sahrens * device was the problem device since there's no 597*789Sahrens * reliable way to determine device size from userland. 598*789Sahrens */ 599*789Sahrens { 600*789Sahrens char buf[64]; 601*789Sahrens 602*789Sahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf)); 603*789Sahrens 604*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot " 605*789Sahrens "add to '%s': one or more devices is less " 606*789Sahrens "than the minimum size (%s)"), 607*789Sahrens zhp->zpool_name, buf); 608*789Sahrens } 609*789Sahrens break; 610*789Sahrens 611*789Sahrens default: 612*789Sahrens zfs_baderror(errno); 613*789Sahrens } 614*789Sahrens 615*789Sahrens return (-1); 616*789Sahrens } 617*789Sahrens 618*789Sahrens free(packed); 619*789Sahrens 620*789Sahrens return (0); 621*789Sahrens } 622*789Sahrens 623*789Sahrens /* 624*789Sahrens * Exports the pool from the system. The caller must ensure that there are no 625*789Sahrens * mounted datasets in the pool. 626*789Sahrens */ 627*789Sahrens int 628*789Sahrens zpool_export(zpool_handle_t *zhp) 629*789Sahrens { 630*789Sahrens zfs_cmd_t zc = { 0 }; 631*789Sahrens 632*789Sahrens if (zpool_remove_zvol_links(zhp) != 0) 633*789Sahrens return (-1); 634*789Sahrens 635*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 636*789Sahrens 637*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_POOL_EXPORT, &zc) != 0) { 638*789Sahrens switch (errno) { 639*789Sahrens case EPERM: 640*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 641*789Sahrens "cannot export '%s': permission denied"), 642*789Sahrens zhp->zpool_name); 643*789Sahrens break; 644*789Sahrens 645*789Sahrens case EBUSY: 646*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 647*789Sahrens "cannot export '%s': pool is in use"), 648*789Sahrens zhp->zpool_name); 649*789Sahrens break; 650*789Sahrens 651*789Sahrens case ENOENT: 652*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 653*789Sahrens "cannot export '%s': no such pool"), 654*789Sahrens zhp->zpool_name); 655*789Sahrens break; 656*789Sahrens 657*789Sahrens default: 658*789Sahrens zfs_baderror(errno); 659*789Sahrens } 660*789Sahrens 661*789Sahrens return (-1); 662*789Sahrens } 663*789Sahrens 664*789Sahrens return (0); 665*789Sahrens } 666*789Sahrens 667*789Sahrens /* 668*789Sahrens * Import the given pool using the known configuration. The configuration 669*789Sahrens * should have come from zpool_find_import(). The 'newname' and 'altroot' 670*789Sahrens * parameters control whether the pool is imported with a different name or with 671*789Sahrens * an alternate root, respectively. 672*789Sahrens */ 673*789Sahrens int 674*789Sahrens zpool_import(nvlist_t *config, const char *newname, const char *altroot) 675*789Sahrens { 676*789Sahrens zfs_cmd_t zc; 677*789Sahrens char *packed; 678*789Sahrens size_t len; 679*789Sahrens char *thename; 680*789Sahrens char *origname; 681*789Sahrens int ret; 682*789Sahrens 683*789Sahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 684*789Sahrens &origname) == 0); 685*789Sahrens 686*789Sahrens if (newname != NULL) { 687*789Sahrens if (!zpool_name_valid(newname, NULL, 0)) { 688*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': " 689*789Sahrens "invalid pool name"), newname); 690*789Sahrens return (-1); 691*789Sahrens } 692*789Sahrens thename = (char *)newname; 693*789Sahrens } else { 694*789Sahrens thename = origname; 695*789Sahrens } 696*789Sahrens 697*789Sahrens if (altroot != NULL && altroot[0] != '/') { 698*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "cannot import '%s': alternate " 699*789Sahrens "root '%s' must be a complete path"), thename, 700*789Sahrens altroot); 701*789Sahrens return (-1); 702*789Sahrens } 703*789Sahrens 704*789Sahrens (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name)); 705*789Sahrens 706*789Sahrens if (altroot != NULL) 707*789Sahrens (void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root)); 708*789Sahrens else 709*789Sahrens zc.zc_root[0] = '\0'; 710*789Sahrens 711*789Sahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 712*789Sahrens &zc.zc_pool_guid) == 0); 713*789Sahrens 714*789Sahrens verify(nvlist_size(config, &len, NV_ENCODE_NATIVE) == 0); 715*789Sahrens 716*789Sahrens packed = zfs_malloc(len); 717*789Sahrens 718*789Sahrens verify(nvlist_pack(config, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 719*789Sahrens 720*789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 721*789Sahrens zc.zc_config_src_size = len; 722*789Sahrens 723*789Sahrens ret = 0; 724*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) { 725*789Sahrens char desc[1024]; 726*789Sahrens if (newname == NULL) 727*789Sahrens (void) snprintf(desc, sizeof (desc), 728*789Sahrens dgettext(TEXT_DOMAIN, "cannot import '%s'"), 729*789Sahrens thename); 730*789Sahrens else 731*789Sahrens (void) snprintf(desc, sizeof (desc), 732*789Sahrens dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"), 733*789Sahrens origname, thename); 734*789Sahrens 735*789Sahrens switch (errno) { 736*789Sahrens case EEXIST: 737*789Sahrens /* 738*789Sahrens * A pool with that name already exists. 739*789Sahrens */ 740*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: pool exists"), 741*789Sahrens desc); 742*789Sahrens break; 743*789Sahrens 744*789Sahrens case EPERM: 745*789Sahrens /* 746*789Sahrens * The user doesn't have permission to create pools. 747*789Sahrens */ 748*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission " 749*789Sahrens "denied"), desc); 750*789Sahrens break; 751*789Sahrens 752*789Sahrens case ENXIO: 753*789Sahrens case EDOM: 754*789Sahrens /* 755*789Sahrens * Device is unavailable, or vdev sum didn't match. 756*789Sahrens */ 757*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: one or more " 758*789Sahrens "devices is unavailable"), 759*789Sahrens desc); 760*789Sahrens break; 761*789Sahrens 762*789Sahrens default: 763*789Sahrens zfs_baderror(errno); 764*789Sahrens } 765*789Sahrens 766*789Sahrens ret = -1; 767*789Sahrens } else { 768*789Sahrens zpool_handle_t *zhp; 769*789Sahrens /* 770*789Sahrens * This should never fail, but play it safe anyway. 771*789Sahrens */ 772*789Sahrens if ((zhp = zpool_open_silent(thename)) != NULL) { 773*789Sahrens ret = zpool_create_zvol_links(zhp); 774*789Sahrens zpool_close(zhp); 775*789Sahrens } 776*789Sahrens } 777*789Sahrens 778*789Sahrens free(packed); 779*789Sahrens return (ret); 780*789Sahrens } 781*789Sahrens 782*789Sahrens /* 783*789Sahrens * Scrub the pool. 784*789Sahrens */ 785*789Sahrens int 786*789Sahrens zpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type) 787*789Sahrens { 788*789Sahrens zfs_cmd_t zc = { 0 }; 789*789Sahrens char msg[1024]; 790*789Sahrens 791*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 792*789Sahrens zc.zc_cookie = type; 793*789Sahrens 794*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_POOL_SCRUB, &zc) == 0) 795*789Sahrens return (0); 796*789Sahrens 797*789Sahrens (void) snprintf(msg, sizeof (msg), 798*789Sahrens dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name); 799*789Sahrens 800*789Sahrens switch (errno) { 801*789Sahrens case EPERM: 802*789Sahrens /* 803*789Sahrens * No permission to scrub this pool. 804*789Sahrens */ 805*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 806*789Sahrens break; 807*789Sahrens 808*789Sahrens case EBUSY: 809*789Sahrens /* 810*789Sahrens * Resilver in progress. 811*789Sahrens */ 812*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: currently resilvering"), 813*789Sahrens msg); 814*789Sahrens break; 815*789Sahrens 816*789Sahrens default: 817*789Sahrens zfs_baderror(errno); 818*789Sahrens } 819*789Sahrens return (-1); 820*789Sahrens } 821*789Sahrens 822*789Sahrens /* 823*789Sahrens * Bring the specified vdev online 824*789Sahrens */ 825*789Sahrens int 826*789Sahrens zpool_vdev_online(zpool_handle_t *zhp, const char *path) 827*789Sahrens { 828*789Sahrens zfs_cmd_t zc = { 0 }; 829*789Sahrens char msg[1024]; 830*789Sahrens 831*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 832*789Sahrens (void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value), 833*789Sahrens "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path); 834*789Sahrens 835*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_VDEV_ONLINE, &zc) == 0) 836*789Sahrens return (0); 837*789Sahrens 838*789Sahrens (void) snprintf(msg, sizeof (msg), 839*789Sahrens dgettext(TEXT_DOMAIN, "cannot online %s"), zc.zc_prop_value); 840*789Sahrens 841*789Sahrens switch (errno) { 842*789Sahrens case ENODEV: 843*789Sahrens /* 844*789Sahrens * Device doesn't exist 845*789Sahrens */ 846*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 847*789Sahrens break; 848*789Sahrens 849*789Sahrens case EPERM: 850*789Sahrens /* 851*789Sahrens * No permission to bring this vdev online. 852*789Sahrens */ 853*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 854*789Sahrens break; 855*789Sahrens 856*789Sahrens default: 857*789Sahrens zfs_baderror(errno); 858*789Sahrens } 859*789Sahrens return (-1); 860*789Sahrens } 861*789Sahrens 862*789Sahrens /* 863*789Sahrens * Take the specified vdev offline 864*789Sahrens */ 865*789Sahrens int 866*789Sahrens zpool_vdev_offline(zpool_handle_t *zhp, const char *path) 867*789Sahrens { 868*789Sahrens zfs_cmd_t zc = { 0 }; 869*789Sahrens char msg[1024]; 870*789Sahrens 871*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 872*789Sahrens (void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value), 873*789Sahrens "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path); 874*789Sahrens 875*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_VDEV_OFFLINE, &zc) == 0) 876*789Sahrens return (0); 877*789Sahrens 878*789Sahrens (void) snprintf(msg, sizeof (msg), 879*789Sahrens dgettext(TEXT_DOMAIN, "cannot offline %s"), zc.zc_prop_value); 880*789Sahrens 881*789Sahrens switch (errno) { 882*789Sahrens case ENODEV: 883*789Sahrens /* 884*789Sahrens * Device doesn't exist 885*789Sahrens */ 886*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 887*789Sahrens break; 888*789Sahrens 889*789Sahrens case EPERM: 890*789Sahrens /* 891*789Sahrens * No permission to take this vdev offline. 892*789Sahrens */ 893*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 894*789Sahrens break; 895*789Sahrens 896*789Sahrens case EBUSY: 897*789Sahrens /* 898*789Sahrens * There are no other replicas of this device. 899*789Sahrens */ 900*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg); 901*789Sahrens break; 902*789Sahrens 903*789Sahrens default: 904*789Sahrens zfs_baderror(errno); 905*789Sahrens } 906*789Sahrens return (-1); 907*789Sahrens } 908*789Sahrens 909*789Sahrens /* 910*789Sahrens * Attach new_disk (fully described by nvroot) to old_disk. 911*789Sahrens * If 'replacing' is specified, tne new disk will replace the old one. 912*789Sahrens */ 913*789Sahrens int 914*789Sahrens zpool_vdev_attach(zpool_handle_t *zhp, 915*789Sahrens const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing) 916*789Sahrens { 917*789Sahrens zfs_cmd_t zc = { 0 }; 918*789Sahrens char msg[1024]; 919*789Sahrens char *packed; 920*789Sahrens int ret; 921*789Sahrens size_t len; 922*789Sahrens 923*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 924*789Sahrens (void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value), 925*789Sahrens "%s%s", old_disk[0] == '/' ? "" : "/dev/dsk/", old_disk); 926*789Sahrens zc.zc_cookie = replacing; 927*789Sahrens 928*789Sahrens verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0); 929*789Sahrens 930*789Sahrens packed = zfs_malloc(len); 931*789Sahrens 932*789Sahrens verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 933*789Sahrens 934*789Sahrens zc.zc_config_src = (uint64_t)(uintptr_t)packed; 935*789Sahrens zc.zc_config_src_size = len; 936*789Sahrens 937*789Sahrens ret = ioctl(zfs_fd, ZFS_IOC_VDEV_ATTACH, &zc); 938*789Sahrens 939*789Sahrens free(packed); 940*789Sahrens 941*789Sahrens if (ret == 0) 942*789Sahrens return (0); 943*789Sahrens 944*789Sahrens if (replacing) 945*789Sahrens (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 946*789Sahrens "cannot replace %s with %s"), old_disk, new_disk); 947*789Sahrens else 948*789Sahrens (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN, 949*789Sahrens "cannot attach %s to %s"), new_disk, old_disk); 950*789Sahrens 951*789Sahrens switch (errno) { 952*789Sahrens case EPERM: 953*789Sahrens /* 954*789Sahrens * No permission to mess with the config. 955*789Sahrens */ 956*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 957*789Sahrens break; 958*789Sahrens 959*789Sahrens case ENODEV: 960*789Sahrens /* 961*789Sahrens * Device doesn't exist. 962*789Sahrens */ 963*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s not in pool"), 964*789Sahrens msg, old_disk); 965*789Sahrens break; 966*789Sahrens 967*789Sahrens case ENOTSUP: 968*789Sahrens /* 969*789Sahrens * Can't attach to or replace this type of vdev. 970*789Sahrens */ 971*789Sahrens if (replacing) 972*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 973*789Sahrens "%s: cannot replace a replacing device"), msg); 974*789Sahrens else 975*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 976*789Sahrens "%s: attach is only applicable to mirrors"), msg); 977*789Sahrens break; 978*789Sahrens 979*789Sahrens case EINVAL: 980*789Sahrens /* 981*789Sahrens * The new device must be a single disk. 982*789Sahrens */ 983*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 984*789Sahrens "%s: <new_device> must be a single disk"), msg); 985*789Sahrens break; 986*789Sahrens 987*789Sahrens case ENXIO: 988*789Sahrens /* 989*789Sahrens * This is unlikely to happen since we've verified that 990*789Sahrens * all the devices can be opened from userland, but it's 991*789Sahrens * still possible in some circumstances. 992*789Sahrens */ 993*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is unavailable"), 994*789Sahrens msg, new_disk); 995*789Sahrens break; 996*789Sahrens 997*789Sahrens case EBUSY: 998*789Sahrens /* 999*789Sahrens * The new device is is use. 1000*789Sahrens */ 1001*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s busy"), msg, new_disk); 1002*789Sahrens break; 1003*789Sahrens 1004*789Sahrens case EOVERFLOW: 1005*789Sahrens /* 1006*789Sahrens * The new device is too small. 1007*789Sahrens */ 1008*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: %s is too small"), 1009*789Sahrens msg, new_disk); 1010*789Sahrens break; 1011*789Sahrens 1012*789Sahrens case EDOM: 1013*789Sahrens /* 1014*789Sahrens * The new device has a different alignment requirement. 1015*789Sahrens */ 1016*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1017*789Sahrens "%s: devices have different sector alignment"), msg); 1018*789Sahrens break; 1019*789Sahrens 1020*789Sahrens case ENAMETOOLONG: 1021*789Sahrens /* 1022*789Sahrens * The resulting top-level vdev spec won't fit in the label. 1023*789Sahrens */ 1024*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1025*789Sahrens "%s: too many devices in a single vdev"), msg); 1026*789Sahrens break; 1027*789Sahrens 1028*789Sahrens default: 1029*789Sahrens zfs_baderror(errno); 1030*789Sahrens } 1031*789Sahrens 1032*789Sahrens return (1); 1033*789Sahrens } 1034*789Sahrens 1035*789Sahrens /* 1036*789Sahrens * Detach the specified device. 1037*789Sahrens */ 1038*789Sahrens int 1039*789Sahrens zpool_vdev_detach(zpool_handle_t *zhp, const char *path) 1040*789Sahrens { 1041*789Sahrens zfs_cmd_t zc = { 0 }; 1042*789Sahrens char msg[1024]; 1043*789Sahrens 1044*789Sahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); 1045*789Sahrens (void) snprintf(zc.zc_prop_value, sizeof (zc.zc_prop_value), 1046*789Sahrens "%s%s", path[0] == '/' ? "" : "/dev/dsk/", path); 1047*789Sahrens 1048*789Sahrens if (ioctl(zfs_fd, ZFS_IOC_VDEV_DETACH, &zc) == 0) 1049*789Sahrens return (0); 1050*789Sahrens 1051*789Sahrens (void) snprintf(msg, sizeof (msg), 1052*789Sahrens dgettext(TEXT_DOMAIN, "cannot detach %s"), zc.zc_prop_value); 1053*789Sahrens 1054*789Sahrens switch (errno) { 1055*789Sahrens case EPERM: 1056*789Sahrens /* 1057*789Sahrens * No permission to mess with the config. 1058*789Sahrens */ 1059*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: permission denied"), msg); 1060*789Sahrens break; 1061*789Sahrens 1062*789Sahrens case ENODEV: 1063*789Sahrens /* 1064*789Sahrens * Device doesn't exist. 1065*789Sahrens */ 1066*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: device not in pool"), msg); 1067*789Sahrens break; 1068*789Sahrens 1069*789Sahrens case ENOTSUP: 1070*789Sahrens /* 1071*789Sahrens * Can't detach from this type of vdev. 1072*789Sahrens */ 1073*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, 1074*789Sahrens "%s: only applicable to mirror and replacing vdevs"), msg); 1075*789Sahrens break; 1076*789Sahrens 1077*789Sahrens case EBUSY: 1078*789Sahrens /* 1079*789Sahrens * There are no other replicas of this device. 1080*789Sahrens */ 1081*789Sahrens zfs_error(dgettext(TEXT_DOMAIN, "%s: no valid replicas"), msg); 1082*789Sahrens break; 1083*789Sahrens 1084*789Sahrens default: 1085*789Sahrens zfs_baderror(errno); 1086*789Sahrens } 1087*789Sahrens 1088*789Sahrens return (1); 1089*789Sahrens } 1090*789Sahrens 1091*789Sahrens static int 1092*789Sahrens do_zvol(zfs_handle_t *zhp, void *data) 1093*789Sahrens { 1094*789Sahrens int linktype = (int)(uintptr_t)data; 1095*789Sahrens int ret; 1096*789Sahrens 1097*789Sahrens /* 1098*789Sahrens * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we 1099*789Sahrens * correctly handle snapshots of volumes. 1100*789Sahrens */ 1101*789Sahrens if (zhp->zfs_volblocksize != 0) { 1102*789Sahrens if (linktype) 1103*789Sahrens ret = zvol_create_link(zhp->zfs_name); 1104*789Sahrens else 1105*789Sahrens ret = zvol_remove_link(zhp->zfs_name); 1106*789Sahrens } 1107*789Sahrens 1108*789Sahrens ret = zfs_iter_children(zhp, do_zvol, data); 1109*789Sahrens 1110*789Sahrens zfs_close(zhp); 1111*789Sahrens return (ret); 1112*789Sahrens } 1113*789Sahrens 1114*789Sahrens /* 1115*789Sahrens * Iterate over all zvols in the pool and make any necessary minor nodes. 1116*789Sahrens */ 1117*789Sahrens int 1118*789Sahrens zpool_create_zvol_links(zpool_handle_t *zhp) 1119*789Sahrens { 1120*789Sahrens zfs_handle_t *zfp; 1121*789Sahrens int ret; 1122*789Sahrens 1123*789Sahrens /* 1124*789Sahrens * If the pool is unavailable, just return success. 1125*789Sahrens */ 1126*789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1127*789Sahrens return (0); 1128*789Sahrens 1129*789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)TRUE); 1130*789Sahrens 1131*789Sahrens zfs_close(zfp); 1132*789Sahrens return (ret); 1133*789Sahrens } 1134*789Sahrens 1135*789Sahrens /* 1136*789Sahrens * Iterate over all zvols in the poool and remove any minor nodes. 1137*789Sahrens */ 1138*789Sahrens int 1139*789Sahrens zpool_remove_zvol_links(zpool_handle_t *zhp) 1140*789Sahrens { 1141*789Sahrens zfs_handle_t *zfp; 1142*789Sahrens int ret; 1143*789Sahrens 1144*789Sahrens /* 1145*789Sahrens * If the pool is unavailable, just return success. 1146*789Sahrens */ 1147*789Sahrens if ((zfp = make_dataset_handle(zhp->zpool_name)) == NULL) 1148*789Sahrens return (0); 1149*789Sahrens 1150*789Sahrens ret = zfs_iter_children(zfp, do_zvol, (void *)FALSE); 1151*789Sahrens 1152*789Sahrens zfs_close(zfp); 1153*789Sahrens return (ret); 1154*789Sahrens } 1155