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>
^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)$$
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"),
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')
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);
#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
VIR_MOCK_REAL_INIT(setmntent);
VIR_MOCK_REAL_INIT(statfs);
+ VIR_MOCK_REAL_INIT(canonicalize_file_name);
}
FILE *f;
struct mntent mb;
char mntbuf[1024];
+ char *canonPath = NULL;
int ret = -1;
if (!(f = real_setmntent(mtab, "r"))) {
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") ||
}
endmntent(f);
+ VIR_FREE(canonPath);
return ret;
}
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);
+}
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;
}