Add helper functions for manipulating device names
This change adds two helper functions for working with vdev names and paths. zfs_resolve_shortname() resolves a shorthand vdev name to an absolute path of a file in /dev, /dev/disk/by-id, /dev/disk/by-label, /dev/disk/by-path, /dev/disk/by-uuid, /dev/disk/zpool. This was previously done only in the function is_shorthand_path(), but we need a general helper function to implement shorthand names for additional zpool subcommands like remove. is_shorthand_path() is accordingly updated to call the helper function. There is a minor change in the way zfs_resolve_shortname() tests if a file exists. is_shorthand_path() effectively used open() and stat64() to test for file existence, since its scope includes testing if a device is a whole disk and collecting file status information. zfs_resolve_shortname(), on the other hand, only uses access() to test for existence and leaves it to the caller to perform any additional file operations. This seemed like the most general and lightweight approach, and still preserves the semantics of is_shorthand_path(). zfs_append_partition() appends a partition suffix to a device path. This should be used to generate the name of a whole disk as it is stored in the vdev label. The user-visible names of whole disks do not contain the partition information, while the name in the vdev label does. The code was lifted from the function make_disks(), which now just calls the helper function. Again, having a helper function to do this supports general handling of shorthand names in the user interface. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
0ee8118bd3
commit
79e7242a91
|
@ -384,23 +384,9 @@ static int
|
||||||
is_shorthand_path(const char *arg, char *path,
|
is_shorthand_path(const char *arg, char *path,
|
||||||
struct stat64 *statbuf, boolean_t *wholedisk)
|
struct stat64 *statbuf, boolean_t *wholedisk)
|
||||||
{
|
{
|
||||||
char dirs[5][9] = {"by-id", "by-label", "by-path", "by-uuid", "zpool"};
|
if (zfs_resolve_shortname(arg, path, MAXPATHLEN) == 0) {
|
||||||
int i, err;
|
|
||||||
|
|
||||||
/* /dev/<name> */
|
|
||||||
(void) snprintf(path, MAXPATHLEN, "%s/%s", DISK_ROOT, arg);
|
|
||||||
*wholedisk = is_whole_disk(path);
|
|
||||||
err = stat64(path, statbuf);
|
|
||||||
if (*wholedisk || err == 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
/* /dev/disk/<dirs>/<name> */
|
|
||||||
for (i = 0; i < 5; i++) {
|
|
||||||
(void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
|
|
||||||
UDISK_ROOT, dirs[i], arg);
|
|
||||||
*wholedisk = is_whole_disk(path);
|
*wholedisk = is_whole_disk(path);
|
||||||
err = stat64(path, statbuf);
|
if (*wholedisk || (stat64(path, statbuf) == 0))
|
||||||
if (*wholedisk || err == 0)
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,13 +995,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
||||||
* for *-part# to be created. Otherwise just use the normal
|
* for *-part# to be created. Otherwise just use the normal
|
||||||
* syntax for devices in /dev.
|
* syntax for devices in /dev.
|
||||||
*/
|
*/
|
||||||
if (strncmp(path, UDISK_ROOT, strlen(UDISK_ROOT)) == 0)
|
zfs_append_partition(path, buf, sizeof (buf));
|
||||||
(void) snprintf(buf, sizeof (buf),
|
|
||||||
"%s%s%s", path, "-part", FIRST_SLICE);
|
|
||||||
else
|
|
||||||
(void) snprintf(buf, sizeof (buf),
|
|
||||||
"%s%s%s", path, isdigit(path[strlen(path)-1]) ?
|
|
||||||
"p" : "", FIRST_SLICE);
|
|
||||||
|
|
||||||
if ((ret = zpool_label_disk_wait(buf, 1000)) != 0) {
|
if ((ret = zpool_label_disk_wait(buf, 1000)) != 0) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
|
|
|
@ -630,6 +630,8 @@ extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
|
||||||
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
|
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
|
||||||
zfs_type_t);
|
zfs_type_t);
|
||||||
extern int zfs_spa_version(zfs_handle_t *, int *);
|
extern int zfs_spa_version(zfs_handle_t *, int *);
|
||||||
|
extern void zfs_append_partition(const char *path, char *buf, size_t buflen);
|
||||||
|
extern int zfs_resolve_shortname(const char *name, char *path, size_t pathlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount support functions.
|
* Mount support functions.
|
||||||
|
|
|
@ -801,6 +801,46 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
|
||||||
return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM));
|
return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a shorthand device name, check if a file by that name exists in a list
|
||||||
|
* of directories under /dev. If one is found, store its full path in the
|
||||||
|
* buffer pointed to by the path argument and return 0, else return -1. The
|
||||||
|
* path buffer must be allocated by the caller.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zfs_resolve_shortname(const char *name, char *path, size_t pathlen)
|
||||||
|
{
|
||||||
|
int i, err;
|
||||||
|
char dirs[5][9] = {"by-id", "by-label", "by-path", "by-uuid", "zpool"};
|
||||||
|
|
||||||
|
(void) snprintf(path, pathlen, "%s/%s", DISK_ROOT, name);
|
||||||
|
err = access(path, F_OK);
|
||||||
|
for (i = 0; i < 5 && err < 0; i++) {
|
||||||
|
(void) snprintf(path, pathlen, "%s/%s/%s",
|
||||||
|
UDISK_ROOT, dirs[i], name);
|
||||||
|
err = access(path, F_OK);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append partition suffix to a device path. This should be used to generate
|
||||||
|
* the name of a whole disk as it is stored in the vdev label. The
|
||||||
|
* user-visible names of whole disks do not contain the partition information.
|
||||||
|
* Modifies buf which must be allocated by the caller.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
zfs_append_partition(const char *path, char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
if (strncmp(path, UDISK_ROOT, strlen(UDISK_ROOT)) == 0)
|
||||||
|
(void) snprintf(buf, buflen, "%s%s%s", path, "-part",
|
||||||
|
FIRST_SLICE);
|
||||||
|
else
|
||||||
|
(void) snprintf(buf, buflen, "%s%s%s", path,
|
||||||
|
isdigit(path[strlen(path)-1]) ? "p" : "",
|
||||||
|
FIRST_SLICE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from
|
* Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from
|
||||||
* an ioctl().
|
* an ioctl().
|
||||||
|
|
Loading…
Reference in New Issue