mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
virfile: Take symlink into account in virFileIsSharedFixFUSE
https://bugzilla.redhat.com/show_bug.cgi?id=1640465 Weirdly enough, there can be symlinks in the path we are trying to fix. If it is the case our clever algorithm that finds matches against mount table won't work. Canonicalize path at the beginning then. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
f4966b8522
commit
c0790e3a09
2
cfg.mk
2
cfg.mk
@ -1229,7 +1229,7 @@ exclude_file_name_regexp--sc_prohibit_select = \
|
|||||||
^cfg\.mk$$
|
^cfg\.mk$$
|
||||||
|
|
||||||
exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \
|
exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \
|
||||||
^cfg\.mk$$
|
^(cfg\.mk|tests/virfilemock\.c)$$
|
||||||
|
|
||||||
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
|
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
|
||||||
^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c)$$
|
^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c)$$
|
||||||
|
@ -3473,9 +3473,19 @@ virFileIsSharedFixFUSE(const char *path,
|
|||||||
char mntbuf[1024];
|
char mntbuf[1024];
|
||||||
char *mntDir = NULL;
|
char *mntDir = NULL;
|
||||||
char *mntType = NULL;
|
char *mntType = NULL;
|
||||||
|
char *canonPath = NULL;
|
||||||
size_t maxMatching = 0;
|
size_t maxMatching = 0;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(canonPath = virFileCanonicalizePath(path))) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("unable to canonicalize %s"),
|
||||||
|
path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("Path canonicalization: %s->%s", path, canonPath);
|
||||||
|
|
||||||
if (!(f = setmntent(PROC_MOUNTS, "r"))) {
|
if (!(f = setmntent(PROC_MOUNTS, "r"))) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("Unable to open %s"),
|
_("Unable to open %s"),
|
||||||
@ -3487,7 +3497,7 @@ virFileIsSharedFixFUSE(const char *path,
|
|||||||
const char *p;
|
const char *p;
|
||||||
size_t len = strlen(mb.mnt_dir);
|
size_t len = strlen(mb.mnt_dir);
|
||||||
|
|
||||||
if (!(p = STRSKIP(path, mb.mnt_dir)))
|
if (!(p = STRSKIP(canonPath, mb.mnt_dir)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*(p - 1) != '/' && *p != '/' && *p != '\0')
|
if (*(p - 1) != '/' && *p != '/' && *p != '\0')
|
||||||
@ -3505,12 +3515,13 @@ virFileIsSharedFixFUSE(const char *path,
|
|||||||
|
|
||||||
if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
|
if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
|
||||||
VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
|
VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. "
|
||||||
"Fixing shared FS type", mntDir, path);
|
"Fixing shared FS type", mntDir, canonPath);
|
||||||
*f_type = GFS2_MAGIC;
|
*f_type = GFS2_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
|
VIR_FREE(canonPath);
|
||||||
VIR_FREE(mntType);
|
VIR_FREE(mntType);
|
||||||
VIR_FREE(mntDir);
|
VIR_FREE(mntDir);
|
||||||
endmntent(f);
|
endmntent(f);
|
||||||
|
@ -28,11 +28,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "virmock.h"
|
#include "virmock.h"
|
||||||
|
#include "virstring.h"
|
||||||
|
#include "viralloc.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
static FILE *(*real_setmntent)(const char *filename, const char *type);
|
static FILE *(*real_setmntent)(const char *filename, const char *type);
|
||||||
static int (*real_statfs)(const char *path, struct statfs *buf);
|
static int (*real_statfs)(const char *path, struct statfs *buf);
|
||||||
|
static char *(*real_canonicalize_file_name)(const char *path);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -43,6 +46,7 @@ init_syms(void)
|
|||||||
|
|
||||||
VIR_MOCK_REAL_INIT(setmntent);
|
VIR_MOCK_REAL_INIT(setmntent);
|
||||||
VIR_MOCK_REAL_INIT(statfs);
|
VIR_MOCK_REAL_INIT(statfs);
|
||||||
|
VIR_MOCK_REAL_INIT(canonicalize_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -94,6 +98,7 @@ statfs_mock(const char *mtab,
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
struct mntent mb;
|
struct mntent mb;
|
||||||
char mntbuf[1024];
|
char mntbuf[1024];
|
||||||
|
char *canonPath = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!(f = real_setmntent(mtab, "r"))) {
|
if (!(f = real_setmntent(mtab, "r"))) {
|
||||||
@ -101,10 +106,16 @@ statfs_mock(const char *mtab,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We don't need to do this in callers because real statfs(2)
|
||||||
|
* does that for us. However, in mocked implementation we
|
||||||
|
* need to do this. */
|
||||||
|
if (!(canonPath = canonicalize_file_name(path)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
|
while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
|
||||||
int ftype;
|
int ftype;
|
||||||
|
|
||||||
if (STRNEQ(mb.mnt_dir, path))
|
if (STRNEQ(mb.mnt_dir, canonPath))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (STREQ(mb.mnt_type, "nfs") ||
|
if (STREQ(mb.mnt_type, "nfs") ||
|
||||||
@ -136,6 +147,7 @@ statfs_mock(const char *mtab,
|
|||||||
}
|
}
|
||||||
|
|
||||||
endmntent(f);
|
endmntent(f);
|
||||||
|
VIR_FREE(canonPath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,3 +164,22 @@ statfs(const char *path, struct statfs *buf)
|
|||||||
|
|
||||||
return real_statfs(path, buf);
|
return real_statfs(path, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
canonicalize_file_name(const char *path)
|
||||||
|
{
|
||||||
|
if (getenv("LIBVIRT_MTAB")) {
|
||||||
|
const char *p;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if ((p = STRSKIP(path, "/some/symlink")))
|
||||||
|
ignore_value(virAsprintfQuiet(&ret, "/gluster%s", p));
|
||||||
|
else
|
||||||
|
ignore_value(VIR_STRDUP_QUIET(ret, path));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return real_canonicalize_file_name(path);
|
||||||
|
}
|
||||||
|
@ -456,6 +456,7 @@ mymain(void)
|
|||||||
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false);
|
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false);
|
||||||
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true);
|
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true);
|
||||||
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false);
|
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false);
|
||||||
|
DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/some/symlink/file", true);
|
||||||
|
|
||||||
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user