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