diff options
author | Ned Bass <[email protected]> | 2010-10-13 17:27:41 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2010-10-22 12:25:46 -0700 |
commit | a2c6816c34952eb6dad51248d31172189fba9126 (patch) | |
tree | 88d34b6138c54e561f9ceadf110f5fdd4e019d6d | |
parent | 79e7242a91c17f50c857b53d2a7313cf363ea535 (diff) |
Support shorthand names with zpool remove
zpool status displays abbreviated vdev names without leading path components
and, in the case of whole disks, without partition information. Also, the
zpool subcommands 'create' and 'add' support using shorthand devices names
without qualified paths. Prior to this change, however, removing a device
generally required specifying its name as it is stored in the vdev label. So
while zpool status might list a cache disk with a name like A16, removing it
would require a full path such as /dev/disk/zpool/A16-part1, which is
non-intuitive.
This change adds support for shorthand device names with the remove subcommand
so one can simply type, for example,
zpool remove tank A16
A consequence of this change is that including the partition information when
removing a whole-disk vdev now results in an error. While this is arguably the
correct behavior, it is a departure from how zpool previously worked in this
project.
This change removes the only reference to ctd_check_path(), so that function is
also removed to avoid compiler warnings.
Signed-off-by: Brian Behlendorf <[email protected]>
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 76 |
1 files changed, 12 insertions, 64 deletions
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 607e2e865..9a0e41af0 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -1645,38 +1645,6 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func) } /* - * This provides a very minimal check whether a given string is likely a - * c#t#d# style string. Users of this are expected to do their own - * verification of the s# part. - */ -#define CTD_CHECK(str) (str && str[0] == 'c' && isdigit(str[1])) - -/* - * More elaborate version for ones which may start with "/dev/dsk/" - * and the like. - */ -static int -ctd_check_path(char *str) { - /* - * If it starts with a slash, check the last component. - */ - if (str && str[0] == '/') { - char *tmp = strrchr(str, '/'); - - /* - * If it ends in "/old", check the second-to-last - * component of the string instead. - */ - if (tmp != str && strcmp(tmp, "/old") == 0) { - for (tmp--; *tmp != '/'; tmp--) - ; - } - str = tmp + 1; - } - return (CTD_CHECK(str)); -} - -/* * Find a vdev that matches the search criteria specified. We use the * the nvpair name to determine how we should look for the device. * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL @@ -1723,47 +1691,24 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, /* * Search for the requested value. Special cases: * - * - ZPOOL_CONFIG_PATH for whole disk entries. These end in - * "s0" or "s0/old". The "s0" part is hidden from the user, - * but included in the string, so this matches around it. + * - ZPOOL_CONFIG_PATH for whole disk entries. These end in with a + * partition suffix "1", "-part1", or "p1". The suffix is hidden + * from the user, but included in the string, so this matches around + * it. * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE). * * Otherwise, all other searches are simple string compares. */ - if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 && - ctd_check_path(val)) { + if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0) { uint64_t wholedisk = 0; (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &wholedisk); if (wholedisk) { - int slen = strlen(srchval); - int vlen = strlen(val); - - if (slen != vlen - 2) - break; - - /* - * make_leaf_vdev() should only set - * wholedisk for ZPOOL_CONFIG_PATHs which - * will include "/dev/dsk/", giving plenty of - * room for the indices used next. - */ - ASSERT(vlen >= 6); - - /* - * strings identical except trailing "s0" - */ - if (strcmp(&val[vlen - 2], "s0") == 0 && - strncmp(srchval, val, slen) == 0) - return (nv); + char buf[MAXPATHLEN]; - /* - * strings identical except trailing "s0/old" - */ - if (strcmp(&val[vlen - 6], "s0/old") == 0 && - strcmp(&srchval[slen - 4], "/old") == 0 && - strncmp(srchval, val, slen - 4) == 0) + zfs_append_partition(srchval, buf, sizeof (buf)); + if (strcmp(val, buf) == 0) return (nv); break; @@ -1931,7 +1876,10 @@ zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare, } else if (zpool_vdev_is_interior(path)) { verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0); } else if (path[0] != '/') { - (void) snprintf(buf, sizeof (buf), "%s/%s", DISK_ROOT, path); + if (zfs_resolve_shortname(path, buf, sizeof (buf)) < 0) { + nvlist_free(search); + return (NULL); + } verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0); } else { verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0); |