188 lines
5.7 KiB
Diff
188 lines
5.7 KiB
Diff
From 666d4aacfd91d8c0447a1e4f8d44d50a3fe40198 Mon Sep 17 00:00:00 2001
|
|
Message-Id: <666d4aacfd91d8c0447a1e4f8d44d50a3fe40198@dist-git>
|
|
From: Michal Privoznik <mprivozn@redhat.com>
|
|
Date: Tue, 23 Oct 2018 11:40:58 +0100
|
|
Subject: [PATCH] virfile: Take symlink into account in virFileIsSharedFixFUSE
|
|
|
|
RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1640465
|
|
RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1641798
|
|
RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782
|
|
|
|
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>
|
|
(cherry picked from commit c0790e3a09f57da0bd25c7eac4a35ed6e7e9e858)
|
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
|
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
|
---
|
|
cfg.mk | 2 +-
|
|
src/util/virfile.c | 15 +++++++++++++--
|
|
tests/virfilemock.c | 33 ++++++++++++++++++++++++++++++++-
|
|
tests/virfiletest.c | 1 +
|
|
4 files changed, 47 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/cfg.mk b/cfg.mk
|
|
index 6bebd0ad9f..e3e94bf6f0 100644
|
|
--- a/cfg.mk
|
|
+++ b/cfg.mk
|
|
@@ -1216,7 +1216,7 @@ exclude_file_name_regexp--sc_prohibit_select = \
|
|
^cfg\.mk$$
|
|
|
|
exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \
|
|
- ^cfg\.mk$$
|
|
+ ^(cfg\.mk|tests/virfilemock\.c)$$
|
|
|
|
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)$$
|
|
diff --git a/src/util/virfile.c b/src/util/virfile.c
|
|
index e1dee7633a..716b55d770 100644
|
|
--- a/src/util/virfile.c
|
|
+++ b/src/util/virfile.c
|
|
@@ -3549,9 +3549,19 @@ virFileIsSharedFixFUSE(const char *path,
|
|
char mntbuf[1024];
|
|
char *mntDir = NULL;
|
|
char *mntType = NULL;
|
|
+ char *canonPath = NULL;
|
|
size_t maxMatching = 0;
|
|
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"))) {
|
|
virReportSystemError(errno,
|
|
_("Unable to open %s"),
|
|
@@ -3563,7 +3573,7 @@ virFileIsSharedFixFUSE(const char *path,
|
|
const char *p;
|
|
size_t len = strlen(mb.mnt_dir);
|
|
|
|
- if (!(p = STRSKIP(path, mb.mnt_dir)))
|
|
+ if (!(p = STRSKIP(canonPath, mb.mnt_dir)))
|
|
continue;
|
|
|
|
if (*(p - 1) != '/' && *p != '/' && *p != '\0')
|
|
@@ -3581,12 +3591,13 @@ virFileIsSharedFixFUSE(const char *path,
|
|
|
|
if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) {
|
|
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;
|
|
}
|
|
|
|
ret = 0;
|
|
cleanup:
|
|
+ VIR_FREE(canonPath);
|
|
VIR_FREE(mntType);
|
|
VIR_FREE(mntDir);
|
|
endmntent(f);
|
|
diff --git a/tests/virfilemock.c b/tests/virfilemock.c
|
|
index 822c757380..ae5c8d025a 100644
|
|
--- a/tests/virfilemock.c
|
|
+++ b/tests/virfilemock.c
|
|
@@ -28,11 +28,14 @@
|
|
#endif
|
|
|
|
#include "virmock.h"
|
|
+#include "virstring.h"
|
|
+#include "viralloc.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
static FILE *(*real_setmntent)(const char *filename, const char *type);
|
|
static int (*real_statfs)(const char *path, struct statfs *buf);
|
|
+static char *(*real_canonicalize_file_name)(const char *path);
|
|
|
|
|
|
static void
|
|
@@ -43,6 +46,7 @@ init_syms(void)
|
|
|
|
VIR_MOCK_REAL_INIT(setmntent);
|
|
VIR_MOCK_REAL_INIT(statfs);
|
|
+ VIR_MOCK_REAL_INIT(canonicalize_file_name);
|
|
}
|
|
|
|
|
|
@@ -94,6 +98,7 @@ statfs_mock(const char *mtab,
|
|
FILE *f;
|
|
struct mntent mb;
|
|
char mntbuf[1024];
|
|
+ char *canonPath = NULL;
|
|
int ret = -1;
|
|
|
|
if (!(f = real_setmntent(mtab, "r"))) {
|
|
@@ -101,10 +106,16 @@ statfs_mock(const char *mtab,
|
|
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))) {
|
|
int ftype;
|
|
|
|
- if (STRNEQ(mb.mnt_dir, path))
|
|
+ if (STRNEQ(mb.mnt_dir, canonPath))
|
|
continue;
|
|
|
|
if (STREQ(mb.mnt_type, "nfs") ||
|
|
@@ -136,6 +147,7 @@ statfs_mock(const char *mtab,
|
|
}
|
|
|
|
endmntent(f);
|
|
+ VIR_FREE(canonPath);
|
|
return ret;
|
|
}
|
|
|
|
@@ -152,3 +164,22 @@ statfs(const char *path, struct statfs *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);
|
|
+}
|
|
diff --git a/tests/virfiletest.c b/tests/virfiletest.c
|
|
index be4dbf8910..a246d601ba 100644
|
|
--- a/tests/virfiletest.c
|
|
+++ b/tests/virfiletest.c
|
|
@@ -457,6 +457,7 @@ mymain(void)
|
|
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/sshfs/file", false);
|
|
+ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/some/symlink/file", true);
|
|
|
|
return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
}
|
|
--
|
|
2.19.2
|
|
|