X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=lib%2Flibzfs%2Flibzfs_pool.c;h=8339305717ebd676ecc6e1ceee1a12fa70e251dd;hb=756c3e5a9ce36461939a8dc421918e1c3a379fa6;hp=9213101e4314a7b5fc3181c6513880c0843ac686;hpb=ca5fd24984624146ebd1460d7554f42b0572e45f;p=zfs.git diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 9213101..8339305 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -21,6 +21,8 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2011 by Delphix. All rights reserved. */ #include @@ -443,7 +445,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, goto error; } - if (intval != 0 && (intval < 9 || intval > 12)) { + if (intval != 0 && (intval < 9 || intval > 13)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "property '%s' number %d is invalid."), propname, intval); @@ -490,6 +492,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); +#if defined(__sun__) || defined(__sun) /* * bootfs property cannot be set on a disk which has * been EFI labeled. @@ -502,6 +505,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, zpool_close(zhp); goto error; } +#endif zpool_close(zhp); break; @@ -670,10 +674,12 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp) * Don't start the slice at the default block of 34; many storage * devices will use a stripe width of 128k, other vendors prefer a 1m * alignment. It is best to play it safe and ensure a 1m alignment - * give 512b blocks. When the block size is larger by a power of 2 - * we will still be 1m aligned. + * given 512B blocks. When the block size is larger by a power of 2 + * we will still be 1m aligned. Some devices are sensitive to the + * partition ending alignment as well. */ -#define NEW_START_BLOCK 2048 +#define NEW_START_BLOCK 2048 +#define PARTITION_END_ALIGNMENT 2048 /* * Validate the given pool name, optionally putting an extended error message in @@ -1581,6 +1587,12 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, (void) zpool_standard_error(hdl, error, desc); break; + case EBUSY: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "one or more devices are already in use\n")); + (void) zfs_error(hdl, EZFS_BADDEV, desc); + break; + default: (void) zpool_standard_error(hdl, error, desc); zpool_explain_recover(hdl, @@ -2071,28 +2083,30 @@ zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size) * the disk to use the new unallocated space. */ static int -zpool_relabel_disk(libzfs_handle_t *hdl, const char *path) +zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg) { - char errbuf[1024]; int fd, error; if ((fd = open(path, O_RDWR|O_DIRECT)) < 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot " - "relabel '%s': unable to open device"), path); - return (zfs_error(hdl, EZFS_OPENFAILED, errbuf)); + "relabel '%s': unable to open device: %d"), path, errno); + return (zfs_error(hdl, EZFS_OPENFAILED, msg)); } /* * It's possible that we might encounter an error if the device * does not have any unallocated space left. If so, we simply * ignore that error and continue on. + * + * Also, we don't call efi_rescan() - that would just return EBUSY. + * The module will do it for us in vdev_disk_open(). */ error = efi_use_whole_disk(fd); (void) close(fd); if (error && error != VT_ENOSPC) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot " "relabel '%s': unable to read disk capacity"), path); - return (zfs_error(hdl, EZFS_NOCAP, errbuf)); + return (zfs_error(hdl, EZFS_NOCAP, msg)); } return (0); } @@ -2110,6 +2124,7 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, nvlist_t *tgt; boolean_t avail_spare, l2cache, islog; libzfs_handle_t *hdl = zhp->zpool_hdl; + int error; if (flags & ZFS_ONLINE_EXPAND) { (void) snprintf(msg, sizeof (msg), @@ -2131,13 +2146,10 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, if (flags & ZFS_ONLINE_EXPAND || zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) { - char *pathname = NULL; uint64_t wholedisk = 0; (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk); - verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, - &pathname) == 0); /* * XXX - L2ARC 1.0 devices can't support expansion. @@ -2149,8 +2161,22 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags, } if (wholedisk) { - pathname += strlen(DISK_ROOT) + 1; - (void) zpool_relabel_disk(hdl, pathname); + const char *fullpath = path; + char buf[MAXPATHLEN]; + + if (path[0] != '/') { + error = zfs_resolve_shortname(path, buf, + sizeof(buf)); + if (error != 0) + return (zfs_error(hdl, EZFS_NODEVICE, + msg)); + + fullpath = buf; + } + + error = zpool_relabel_disk(hdl, fullpath, msg); + if (error != 0) + return (error); } } @@ -2939,6 +2965,26 @@ zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid) } /* + * Change the GUID for a pool. + */ +int +zpool_reguid(zpool_handle_t *zhp) +{ + char msg[1024]; + libzfs_handle_t *hdl = zhp->zpool_hdl; + zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 }; + + (void) snprintf(msg, sizeof (msg), + dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name); + + (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); + if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0) + return (0); + + return (zpool_standard_error(hdl, errno, msg)); +} + +/* * Convert from a devid string to a path. */ static char * @@ -3759,8 +3805,8 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) * This shouldn't happen. We've long since verified that this * is a valid device. */ - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "unable to open device '%s': %d"), path, errno); + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot " + "label '%s': unable to open device: %d"), path, errno); return (zfs_error(hdl, EZFS_OPENFAILED, errbuf)); } @@ -3773,8 +3819,8 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) (void) no_memory(hdl); (void) close(fd); - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "unable to read disk capacity"), name); + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot " + "label '%s': unable to read disk capacity"), path); return (zfs_error(hdl, EZFS_NOCAP, errbuf)); } @@ -3784,6 +3830,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) if (start_block == MAXOFFSET_T) start_block = NEW_START_BLOCK; slice_size -= start_block; + slice_size = P2ALIGN(slice_size, PARTITION_END_ALIGNMENT); vtoc->efi_parts[0].p_start = start_block; vtoc->efi_parts[0].p_size = slice_size; @@ -3803,7 +3850,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name) vtoc->efi_parts[8].p_size = resv; vtoc->efi_parts[8].p_tag = V_RESERVED; - if ((rval = efi_write(fd, vtoc)) != 0) { + if ((rval = efi_write(fd, vtoc)) != 0 || (rval = efi_rescan(fd)) != 0) { /* * Some block drivers (like pcata) may not support EFI * GPT labels. Print out a helpful error message dir-