mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
daemon: Fix /dev/mapper paths from mounts and mountpoints (RHBZ#646432).
Make the LV paths returned by these two commands canonical.
This commit is contained in:
@@ -124,6 +124,9 @@ extern struct optgroup optgroups[];
|
||||
/* Use this as a replacement for sync(2). */
|
||||
extern int sync_disks (void);
|
||||
|
||||
/*-- in lvm.c --*/
|
||||
extern int lv_canonical (const char *device, char **ret);
|
||||
|
||||
/*-- in proto.c --*/
|
||||
extern void main_loop (int sock) __attribute__((noreturn));
|
||||
|
||||
|
||||
68
daemon/lvm.c
68
daemon/lvm.c
@@ -664,7 +664,8 @@ do_vgscan (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test if a device is a logical volume (RHBZ#619793).
|
||||
/* Convert a non-canonical LV path like /dev/mapper/vg-lv or /dev/dm-0
|
||||
* to a canonical one.
|
||||
*
|
||||
* This is harder than it should be. A LV device like /dev/VG/LV is
|
||||
* really a symlink to a device-mapper device like /dev/dm-0. However
|
||||
@@ -675,9 +676,16 @@ do_vgscan (void)
|
||||
*
|
||||
* Note use of 'stat' instead of 'lstat' so that symlinks are fully
|
||||
* resolved.
|
||||
*
|
||||
* Returns:
|
||||
* 1 = conversion was successful, path is an LV
|
||||
* '*ret' is set to the updated path if 'ret' is non-NULL.
|
||||
* 0 = path is not an LV
|
||||
* -1 = error, reply_with_* has been called
|
||||
*
|
||||
*/
|
||||
int
|
||||
do_is_lv (const char *device)
|
||||
lv_canonical (const char *device, char **ret)
|
||||
{
|
||||
struct stat stat1, stat2;
|
||||
|
||||
@@ -700,6 +708,14 @@ do_is_lv (const char *device)
|
||||
return -1;
|
||||
}
|
||||
if (stat1.st_rdev == stat2.st_rdev) { /* found it */
|
||||
if (ret) {
|
||||
*ret = strdup (lvs[i]);
|
||||
if (*ret == NULL) {
|
||||
reply_with_perror ("strdup");
|
||||
free_strings (lvs);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free_strings (lvs);
|
||||
return 1;
|
||||
}
|
||||
@@ -710,44 +726,26 @@ do_is_lv (const char *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Similar to is_lv above (RHBZ#638899). */
|
||||
/* Test if a device is a logical volume (RHBZ#619793). */
|
||||
int
|
||||
do_is_lv (const char *device)
|
||||
{
|
||||
return lv_canonical (device, NULL);
|
||||
}
|
||||
|
||||
/* Return canonical name of LV to caller (RHBZ#638899). */
|
||||
char *
|
||||
do_lvm_canonical_lv_name (const char *device)
|
||||
{
|
||||
struct stat stat1, stat2;
|
||||
char *canonical;
|
||||
int r = lv_canonical (device, &canonical);
|
||||
if (r == -1)
|
||||
return NULL;
|
||||
|
||||
int r = stat (device, &stat1);
|
||||
if (r == -1) {
|
||||
reply_with_perror ("stat: %s", device);
|
||||
if (r == 0) {
|
||||
reply_with_error ("%s: not a logical volume", device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **lvs = do_lvs ();
|
||||
if (lvs == NULL)
|
||||
return NULL;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; lvs[i] != NULL; ++i) {
|
||||
r = stat (lvs[i], &stat2);
|
||||
if (r == -1) {
|
||||
reply_with_perror ("stat: %s", lvs[i]);
|
||||
free_strings (lvs);
|
||||
return NULL;
|
||||
}
|
||||
if (stat1.st_rdev == stat2.st_rdev) { /* found it */
|
||||
char *r = strdup (lvs[i]);
|
||||
if (r == NULL) {
|
||||
reply_with_perror ("strdup");
|
||||
free_strings (lvs);
|
||||
}
|
||||
free_strings (lvs);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
free_strings (lvs);
|
||||
|
||||
/* not found */
|
||||
reply_with_error ("%s: not a logical volume", device);
|
||||
return NULL;
|
||||
return canonical; /* caller frees */
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ mounts_or_mountpoints (int mp)
|
||||
char *p, *pend, *p2;
|
||||
int len;
|
||||
char matching[5 + sysroot_len];
|
||||
size_t i;
|
||||
|
||||
r = command (&out, &err, "mount", NULL);
|
||||
if (r == -1) {
|
||||
@@ -204,6 +205,26 @@ mounts_or_mountpoints (int mp)
|
||||
if (add_string (&ret, &size, &alloc, NULL) == -1)
|
||||
return NULL;
|
||||
|
||||
/* Convert /dev/mapper LV paths into canonical paths (RHBZ#646432). */
|
||||
for (i = 0; ret[i] != NULL; i += mp ? 2 : 1) {
|
||||
if (STRPREFIX (ret[i], "/dev/mapper/") || STRPREFIX (ret[i], "/dev/dm-")) {
|
||||
char *canonical;
|
||||
r = lv_canonical (ret[i], &canonical);
|
||||
if (r == -1) {
|
||||
free_strings (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (r == 1) {
|
||||
free (ret[i]);
|
||||
ret[i] = canonical;
|
||||
}
|
||||
/* Ignore the case where r == 0. This might happen where
|
||||
* eg. a LUKS /dev/mapper device is mounted, but that won't
|
||||
* correspond to any LV.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user