Allow platform dependent path stripping for vdevs
On Linux the full path preceding devices is stripped when formatting vdev names. On FreeBSD we only want to strip "/dev/". Hide the implementation details of path stripping behind zfs_strip_path(). Make zfs_strip_partition_path() static in Linux implementation while here, since it is never used outside of the file it is defined in. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ryan Moeller <ryan@ixsystems.com> Closes #9565
This commit is contained in:
parent
5a6ac4cffc
commit
035ebb3653
|
@ -97,7 +97,7 @@ extern int zfs_append_partition(char *path, size_t max_len);
|
||||||
extern int zfs_resolve_shortname(const char *name, char *path, size_t pathlen);
|
extern int zfs_resolve_shortname(const char *name, char *path, size_t pathlen);
|
||||||
|
|
||||||
extern char *zfs_strip_partition(char *);
|
extern char *zfs_strip_partition(char *);
|
||||||
extern char *zfs_strip_partition_path(char *);
|
extern char *zfs_strip_path(char *);
|
||||||
|
|
||||||
extern int zfs_strcmp_pathname(const char *, const char *, int);
|
extern int zfs_strcmp_pathname(const char *, const char *, int);
|
||||||
|
|
||||||
|
|
|
@ -3911,8 +3911,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
||||||
*/
|
*/
|
||||||
if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
|
if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
|
||||||
!(name_flags & VDEV_NAME_PATH)) {
|
!(name_flags & VDEV_NAME_PATH)) {
|
||||||
path = strrchr(path, '/');
|
path = zfs_strip_path(path);
|
||||||
path++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -71,6 +71,89 @@ zfs_append_partition(char *path, size_t max_len)
|
||||||
return (len);
|
return (len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove partition suffix from a vdev path. Partition suffixes may take three
|
||||||
|
* forms: "-partX", "pX", or "X", where X is a string of digits. The second
|
||||||
|
* case only occurs when the suffix is preceded by a digit, i.e. "md0p0" The
|
||||||
|
* third case only occurs when preceded by a string matching the regular
|
||||||
|
* expression "^([hsv]|xv)d[a-z]+", i.e. a scsi, ide, virtio or xen disk.
|
||||||
|
*
|
||||||
|
* caller must free the returned string
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
zfs_strip_partition(char *path)
|
||||||
|
{
|
||||||
|
char *tmp = strdup(path);
|
||||||
|
char *part = NULL, *d = NULL;
|
||||||
|
if (!tmp)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if ((part = strstr(tmp, "-part")) && part != tmp) {
|
||||||
|
d = part + 5;
|
||||||
|
} else if ((part = strrchr(tmp, 'p')) &&
|
||||||
|
part > tmp + 1 && isdigit(*(part-1))) {
|
||||||
|
d = part + 1;
|
||||||
|
} else if ((tmp[0] == 'h' || tmp[0] == 's' || tmp[0] == 'v') &&
|
||||||
|
tmp[1] == 'd') {
|
||||||
|
for (d = &tmp[2]; isalpha(*d); part = ++d) { }
|
||||||
|
} else if (strncmp("xvd", tmp, 3) == 0) {
|
||||||
|
for (d = &tmp[3]; isalpha(*d); part = ++d) { }
|
||||||
|
}
|
||||||
|
if (part && d && *d != '\0') {
|
||||||
|
for (; isdigit(*d); d++) { }
|
||||||
|
if (*d == '\0')
|
||||||
|
*part = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as zfs_strip_partition, but allows "/dev/" to be in the pathname
|
||||||
|
*
|
||||||
|
* path: /dev/sda1
|
||||||
|
* returns: /dev/sda
|
||||||
|
*
|
||||||
|
* Returned string must be freed.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
zfs_strip_partition_path(char *path)
|
||||||
|
{
|
||||||
|
char *newpath = strdup(path);
|
||||||
|
char *sd_offset;
|
||||||
|
char *new_sd;
|
||||||
|
|
||||||
|
if (!newpath)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Point to "sda1" part of "/dev/sda1" */
|
||||||
|
sd_offset = strrchr(newpath, '/') + 1;
|
||||||
|
|
||||||
|
/* Get our new name "sda" */
|
||||||
|
new_sd = zfs_strip_partition(sd_offset);
|
||||||
|
if (!new_sd) {
|
||||||
|
free(newpath);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paste the "sda" where "sda1" was */
|
||||||
|
strlcpy(sd_offset, new_sd, strlen(sd_offset) + 1);
|
||||||
|
|
||||||
|
/* Free temporary "sda" */
|
||||||
|
free(new_sd);
|
||||||
|
|
||||||
|
return (newpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Strip the unwanted portion of a device path.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
zfs_strip_path(char *path)
|
||||||
|
{
|
||||||
|
return (strrchr(path, '/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and return the underlying device name for a device mapper device.
|
* Allocate and return the underlying device name for a device mapper device.
|
||||||
* If a device mapper device maps to multiple devices, return the first device.
|
* If a device mapper device maps to multiple devices, return the first device.
|
||||||
|
@ -349,80 +432,6 @@ end:
|
||||||
return (path);
|
return (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove partition suffix from a vdev path. Partition suffixes may take three
|
|
||||||
* forms: "-partX", "pX", or "X", where X is a string of digits. The second
|
|
||||||
* case only occurs when the suffix is preceded by a digit, i.e. "md0p0" The
|
|
||||||
* third case only occurs when preceded by a string matching the regular
|
|
||||||
* expression "^([hsv]|xv)d[a-z]+", i.e. a scsi, ide, virtio or xen disk.
|
|
||||||
*
|
|
||||||
* caller must free the returned string
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
zfs_strip_partition(char *path)
|
|
||||||
{
|
|
||||||
char *tmp = strdup(path);
|
|
||||||
char *part = NULL, *d = NULL;
|
|
||||||
if (!tmp)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if ((part = strstr(tmp, "-part")) && part != tmp) {
|
|
||||||
d = part + 5;
|
|
||||||
} else if ((part = strrchr(tmp, 'p')) &&
|
|
||||||
part > tmp + 1 && isdigit(*(part-1))) {
|
|
||||||
d = part + 1;
|
|
||||||
} else if ((tmp[0] == 'h' || tmp[0] == 's' || tmp[0] == 'v') &&
|
|
||||||
tmp[1] == 'd') {
|
|
||||||
for (d = &tmp[2]; isalpha(*d); part = ++d) { }
|
|
||||||
} else if (strncmp("xvd", tmp, 3) == 0) {
|
|
||||||
for (d = &tmp[3]; isalpha(*d); part = ++d) { }
|
|
||||||
}
|
|
||||||
if (part && d && *d != '\0') {
|
|
||||||
for (; isdigit(*d); d++) { }
|
|
||||||
if (*d == '\0')
|
|
||||||
*part = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same as zfs_strip_partition, but allows "/dev/" to be in the pathname
|
|
||||||
*
|
|
||||||
* path: /dev/sda1
|
|
||||||
* returns: /dev/sda
|
|
||||||
*
|
|
||||||
* Returned string must be freed.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
zfs_strip_partition_path(char *path)
|
|
||||||
{
|
|
||||||
char *newpath = strdup(path);
|
|
||||||
char *sd_offset;
|
|
||||||
char *new_sd;
|
|
||||||
|
|
||||||
if (!newpath)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
/* Point to "sda1" part of "/dev/sda1" */
|
|
||||||
sd_offset = strrchr(newpath, '/') + 1;
|
|
||||||
|
|
||||||
/* Get our new name "sda" */
|
|
||||||
new_sd = zfs_strip_partition(sd_offset);
|
|
||||||
if (!new_sd) {
|
|
||||||
free(newpath);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Paste the "sda" where "sda1" was */
|
|
||||||
strlcpy(sd_offset, new_sd, strlen(sd_offset) + 1);
|
|
||||||
|
|
||||||
/* Free temporary "sda" */
|
|
||||||
free(new_sd);
|
|
||||||
|
|
||||||
return (newpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBUDEV
|
#ifdef HAVE_LIBUDEV
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue