|
|
c401cc |
From 7ca06472a3169d7c6b3816ad06b2d393298514bc Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <7ca06472a3169d7c6b3816ad06b2d393298514bc.1386348946.git.jdenemar@redhat.com>
|
|
|
c401cc |
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
|
c401cc |
Date: Mon, 2 Dec 2013 13:39:11 +0000
|
|
|
c401cc |
Subject: [PATCH] Pull lxcContainerGetSubtree out into shared virfile module
|
|
|
c401cc |
|
|
|
c401cc |
For
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1035403
|
|
|
c401cc |
|
|
|
c401cc |
Move the code for lxcContainerGetSubtree into the virfile
|
|
|
c401cc |
module creating 2 new functions
|
|
|
c401cc |
|
|
|
c401cc |
int virFileGetMountSubtree(const char *mtabpath,
|
|
|
c401cc |
const char *prefix,
|
|
|
c401cc |
char ***mountsret,
|
|
|
c401cc |
size_t *nmountsret);
|
|
|
c401cc |
int virFileGetMountReverseSubtree(const char *mtabpath,
|
|
|
c401cc |
const char *prefix,
|
|
|
c401cc |
char ***mountsret,
|
|
|
c401cc |
size_t *nmountsret);
|
|
|
c401cc |
|
|
|
c401cc |
Add a new virfiletest.c test case to validate the new code.
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
c401cc |
(cherry picked from commit d45b833d14477b46e084ef8c629522afa36c7322)
|
|
|
c401cc |
|
|
|
c401cc |
Conflicts:
|
|
|
c401cc |
tests/Makefile.am
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
.gitignore | 1 +
|
|
|
c401cc |
src/libvirt_private.syms | 2 +
|
|
|
c401cc |
src/lxc/lxc_container.c | 51 +----------------
|
|
|
c401cc |
src/util/virfile.c | 112 ++++++++++++++++++++++++++++++++++++++
|
|
|
c401cc |
src/util/virfile.h | 9 +++
|
|
|
c401cc |
tests/Makefile.am | 6 ++
|
|
|
c401cc |
tests/virfiledata/mounts1.txt | 31 +++++++++++
|
|
|
c401cc |
tests/virfiletest.c | 124 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
c401cc |
8 files changed, 288 insertions(+), 48 deletions(-)
|
|
|
c401cc |
create mode 100644 tests/virfiledata/mounts1.txt
|
|
|
c401cc |
create mode 100644 tests/virfiletest.c
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
c401cc |
index fa36b31..22df5a9 100644
|
|
|
c401cc |
--- a/src/libvirt_private.syms
|
|
|
c401cc |
+++ b/src/libvirt_private.syms
|
|
|
c401cc |
@@ -1380,6 +1380,8 @@ virFileExists;
|
|
|
c401cc |
virFileFclose;
|
|
|
c401cc |
virFileFdopen;
|
|
|
c401cc |
virFileFindMountPoint;
|
|
|
c401cc |
+virFileGetMountReverseSubtree;
|
|
|
c401cc |
+virFileGetMountSubtree;
|
|
|
c401cc |
virFileHasSuffix;
|
|
|
c401cc |
virFileIsAbsPath;
|
|
|
c401cc |
virFileIsDir;
|
|
|
c401cc |
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
|
|
|
c401cc |
index c2cbfb4..3f54f82 100644
|
|
|
c401cc |
--- a/src/lxc/lxc_container.c
|
|
|
c401cc |
+++ b/src/lxc/lxc_container.c
|
|
|
c401cc |
@@ -499,50 +499,6 @@ extern int pivot_root(const char * new_root,const char * put_old);
|
|
|
c401cc |
# define MS_SLAVE (1<<19)
|
|
|
c401cc |
#endif
|
|
|
c401cc |
|
|
|
c401cc |
-static int lxcContainerGetSubtree(const char *prefix,
|
|
|
c401cc |
- char ***mountsret,
|
|
|
c401cc |
- size_t *nmountsret)
|
|
|
c401cc |
-{
|
|
|
c401cc |
- FILE *procmnt;
|
|
|
c401cc |
- struct mntent mntent;
|
|
|
c401cc |
- char mntbuf[1024];
|
|
|
c401cc |
- int ret = -1;
|
|
|
c401cc |
- char **mounts = NULL;
|
|
|
c401cc |
- size_t nmounts = 0;
|
|
|
c401cc |
-
|
|
|
c401cc |
- VIR_DEBUG("prefix=%s", prefix);
|
|
|
c401cc |
-
|
|
|
c401cc |
- *mountsret = NULL;
|
|
|
c401cc |
- *nmountsret = 0;
|
|
|
c401cc |
-
|
|
|
c401cc |
- if (!(procmnt = setmntent("/proc/mounts", "r"))) {
|
|
|
c401cc |
- virReportSystemError(errno, "%s",
|
|
|
c401cc |
- _("Failed to read /proc/mounts"));
|
|
|
c401cc |
- return -1;
|
|
|
c401cc |
- }
|
|
|
c401cc |
-
|
|
|
c401cc |
- while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) {
|
|
|
c401cc |
- if (!STRPREFIX(mntent.mnt_dir, prefix))
|
|
|
c401cc |
- continue;
|
|
|
c401cc |
-
|
|
|
c401cc |
- if (VIR_REALLOC_N(mounts, nmounts+1) < 0)
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
- if (VIR_STRDUP(mounts[nmounts], mntent.mnt_dir) < 0)
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
- nmounts++;
|
|
|
c401cc |
- }
|
|
|
c401cc |
-
|
|
|
c401cc |
- if (mounts)
|
|
|
c401cc |
- qsort(mounts, nmounts, sizeof(mounts[0]),
|
|
|
c401cc |
- virStringSortRevCompare);
|
|
|
c401cc |
-
|
|
|
c401cc |
- ret = 0;
|
|
|
c401cc |
-cleanup:
|
|
|
c401cc |
- *mountsret = mounts;
|
|
|
c401cc |
- *nmountsret = nmounts;
|
|
|
c401cc |
- endmntent(procmnt);
|
|
|
c401cc |
- return ret;
|
|
|
c401cc |
-}
|
|
|
c401cc |
|
|
|
c401cc |
static int lxcContainerUnmountSubtree(const char *prefix,
|
|
|
c401cc |
bool isOldRootFS)
|
|
|
c401cc |
@@ -556,7 +512,8 @@ static int lxcContainerUnmountSubtree(const char *prefix,
|
|
|
c401cc |
|
|
|
c401cc |
VIR_DEBUG("Unmount subtreee from %s", prefix);
|
|
|
c401cc |
|
|
|
c401cc |
- if (lxcContainerGetSubtree(prefix, &mounts, &nmounts) < 0)
|
|
|
c401cc |
+ if (virFileGetMountReverseSubtree("/proc/mounts", prefix,
|
|
|
c401cc |
+ &mounts, &nmounts) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
for (i = 0; i < nmounts; i++) {
|
|
|
c401cc |
VIR_DEBUG("Umount %s", mounts[i]);
|
|
|
c401cc |
@@ -592,9 +549,7 @@ static int lxcContainerUnmountSubtree(const char *prefix,
|
|
|
c401cc |
ret = 0;
|
|
|
c401cc |
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
- for (i = 0; i < nmounts; i++)
|
|
|
c401cc |
- VIR_FREE(mounts[i]);
|
|
|
c401cc |
- VIR_FREE(mounts);
|
|
|
c401cc |
+ virStringFreeList(mounts);
|
|
|
c401cc |
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
diff --git a/src/util/virfile.c b/src/util/virfile.c
|
|
|
c401cc |
index b396b16..e2a5f7a 100644
|
|
|
c401cc |
--- a/src/util/virfile.c
|
|
|
c401cc |
+++ b/src/util/virfile.c
|
|
|
c401cc |
@@ -1492,6 +1492,118 @@ int virFileIsMountPoint(const char *file)
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+
|
|
|
c401cc |
+#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
|
|
|
c401cc |
+static int
|
|
|
c401cc |
+virFileGetMountSubtreeImpl(const char *mtabpath,
|
|
|
c401cc |
+ const char *prefix,
|
|
|
c401cc |
+ char ***mountsret,
|
|
|
c401cc |
+ size_t *nmountsret,
|
|
|
c401cc |
+ bool reverse)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ FILE *procmnt;
|
|
|
c401cc |
+ struct mntent mntent;
|
|
|
c401cc |
+ char mntbuf[1024];
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+ char **mounts = NULL;
|
|
|
c401cc |
+ size_t nmounts = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ VIR_DEBUG("prefix=%s", prefix);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *mountsret = NULL;
|
|
|
c401cc |
+ *nmountsret = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (!(procmnt = setmntent(mtabpath, "r"))) {
|
|
|
c401cc |
+ virReportSystemError(errno,
|
|
|
c401cc |
+ _("Failed to read %s"), mtabpath);
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ while (getmntent_r(procmnt, &mntent, mntbuf, sizeof(mntbuf)) != NULL) {
|
|
|
c401cc |
+ if (!STRPREFIX(mntent.mnt_dir, prefix))
|
|
|
c401cc |
+ continue;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (VIR_EXPAND_N(mounts, nmounts, nmounts ? 1 : 2) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ if (VIR_STRDUP(mounts[nmounts - 2], mntent.mnt_dir) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (mounts)
|
|
|
c401cc |
+ qsort(mounts, nmounts - 1, sizeof(mounts[0]),
|
|
|
c401cc |
+ reverse ? virStringSortRevCompare : virStringSortCompare);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *mountsret = mounts;
|
|
|
c401cc |
+ *nmountsret = nmounts ? nmounts - 1 : 0;
|
|
|
c401cc |
+ ret = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+cleanup:
|
|
|
c401cc |
+ if (ret < 0)
|
|
|
c401cc |
+ virStringFreeList(mounts);
|
|
|
c401cc |
+ endmntent(procmnt);
|
|
|
c401cc |
+ return ret;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+#else /* ! defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */
|
|
|
c401cc |
+static int
|
|
|
c401cc |
+virFileGetMountSubtreeImpl(const char *mtabpath ATTRIBUTE_UNUSED,
|
|
|
c401cc |
+ const char *prefix ATTRIBUTE_UNUSED,
|
|
|
c401cc |
+ char ***mountsret ATTRIBUTE_UNUSED,
|
|
|
c401cc |
+ size_t *nmountsret ATTRIBUTE_UNUSED,
|
|
|
c401cc |
+ bool reverse ATTRIBUTE_UNUSED)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ virReportSystemError(ENOSYS, "%s",
|
|
|
c401cc |
+ _("Unable to determine mount table on this platform"));
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+#endif /* ! defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */
|
|
|
c401cc |
+
|
|
|
c401cc |
+/**
|
|
|
c401cc |
+ * virFileGetMountSubtree:
|
|
|
c401cc |
+ * @mtabpath: mount file to parser (eg /proc/mounts)
|
|
|
c401cc |
+ * @prefix: mount path prefix to match
|
|
|
c401cc |
+ * @mountsret: allocated and filled with matching mounts
|
|
|
c401cc |
+ * @nmountsret: filled with number of matching mounts, not counting NULL terminator
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Return the list of mounts from @mtabpath which contain
|
|
|
c401cc |
+ * the path @prefix, sorted from shortest to longest path.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * The @mountsret array will be NULL terminated and should
|
|
|
c401cc |
+ * be freed with virStringFreeList
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Returns 0 on success, -1 on error
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+int virFileGetMountSubtree(const char *mtabpath,
|
|
|
c401cc |
+ const char *prefix,
|
|
|
c401cc |
+ char ***mountsret,
|
|
|
c401cc |
+ size_t *nmountsret)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ return virFileGetMountSubtreeImpl(mtabpath, prefix, mountsret, nmountsret, false);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+/**
|
|
|
c401cc |
+ * virFileGetMountReverseSubtree:
|
|
|
c401cc |
+ * @mtabpath: mount file to parser (eg /proc/mounts)
|
|
|
c401cc |
+ * @prefix: mount path prefix to match
|
|
|
c401cc |
+ * @mountsret: allocated and filled with matching mounts
|
|
|
c401cc |
+ * @nmountsret: filled with number of matching mounts, not counting NULL terminator
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Return the list of mounts from @mtabpath which contain
|
|
|
c401cc |
+ * the path @prefix, sorted from longest to shortest path.
|
|
|
c401cc |
+ * ie opposite order to which they appear in @mtabpath
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * The @mountsret array will be NULL terminated and should
|
|
|
c401cc |
+ * be freed with virStringFreeList
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Returns 0 on success, -1 on error
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+int virFileGetMountReverseSubtree(const char *mtabpath,
|
|
|
c401cc |
+ const char *prefix,
|
|
|
c401cc |
+ char ***mountsret,
|
|
|
c401cc |
+ size_t *nmountsret)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ return virFileGetMountSubtreeImpl(mtabpath, prefix, mountsret, nmountsret, true);
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
#ifndef WIN32
|
|
|
c401cc |
/* Check that a file is accessible under certain
|
|
|
c401cc |
* user & gid.
|
|
|
c401cc |
diff --git a/src/util/virfile.h b/src/util/virfile.h
|
|
|
c401cc |
index ff84719..f6e087e 100644
|
|
|
c401cc |
--- a/src/util/virfile.h
|
|
|
c401cc |
+++ b/src/util/virfile.h
|
|
|
c401cc |
@@ -158,6 +158,15 @@ bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);
|
|
|
c401cc |
|
|
|
c401cc |
int virFileIsMountPoint(const char *file) ATTRIBUTE_NONNULL(1);
|
|
|
c401cc |
|
|
|
c401cc |
+int virFileGetMountSubtree(const char *mtabpath,
|
|
|
c401cc |
+ const char *prefix,
|
|
|
c401cc |
+ char ***mountsret,
|
|
|
c401cc |
+ size_t *nmountsret) ATTRIBUTE_RETURN_CHECK;
|
|
|
c401cc |
+int virFileGetMountReverseSubtree(const char *mtabpath,
|
|
|
c401cc |
+ const char *prefix,
|
|
|
c401cc |
+ char ***mountsret,
|
|
|
c401cc |
+ size_t *nmountsret) ATTRIBUTE_RETURN_CHECK;
|
|
|
c401cc |
+
|
|
|
c401cc |
char *virFileSanitizePath(const char *path);
|
|
|
c401cc |
|
|
|
c401cc |
enum {
|
|
|
c401cc |
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
|
c401cc |
index 3d5ac72..4141c47 100644
|
|
|
c401cc |
--- a/tests/Makefile.am
|
|
|
c401cc |
+++ b/tests/Makefile.am
|
|
|
c401cc |
@@ -102,6 +102,7 @@ EXTRA_DIST = \
|
|
|
c401cc |
sysinfodata \
|
|
|
c401cc |
test-lib.sh \
|
|
|
c401cc |
virsh-uriprecedence \
|
|
|
c401cc |
+ virfiledata \
|
|
|
c401cc |
vmx2xmldata \
|
|
|
c401cc |
xencapsdata \
|
|
|
c401cc |
xmconfigdata \
|
|
|
c401cc |
@@ -121,6 +122,7 @@ test_programs = virshtest sockettest \
|
|
|
c401cc |
virbitmaptest \
|
|
|
c401cc |
vircgrouptest \
|
|
|
c401cc |
virendiantest \
|
|
|
c401cc |
+ virfiletest \
|
|
|
c401cc |
viridentitytest \
|
|
|
c401cc |
virkeycodetest \
|
|
|
c401cc |
virlockspacetest \
|
|
|
c401cc |
@@ -759,6 +761,10 @@ virendiantest_SOURCES = \
|
|
|
c401cc |
virendiantest.c testutils.h testutils.c
|
|
|
c401cc |
virendiantest_LDADD = $(LDADDS)
|
|
|
c401cc |
|
|
|
c401cc |
+virfiletest_SOURCES = \
|
|
|
c401cc |
+ virfiletest.c testutils.h testutils.c
|
|
|
c401cc |
+virfiletest_LDADD = $(LDADDS)
|
|
|
c401cc |
+
|
|
|
c401cc |
jsontest_SOURCES = \
|
|
|
c401cc |
jsontest.c testutils.h testutils.c
|
|
|
c401cc |
jsontest_LDADD = $(LDADDS)
|
|
|
c401cc |
diff --git a/tests/virfiledata/mounts1.txt b/tests/virfiledata/mounts1.txt
|
|
|
c401cc |
new file mode 100644
|
|
|
c401cc |
index 0000000..79434cc
|
|
|
c401cc |
--- /dev/null
|
|
|
c401cc |
+++ b/tests/virfiledata/mounts1.txt
|
|
|
c401cc |
@@ -0,0 +1,31 @@
|
|
|
c401cc |
+rootfs / rootfs rw 0 0
|
|
|
c401cc |
+proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
|
|
|
c401cc |
+sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
|
|
|
c401cc |
+devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=8057768k,nr_inodes=2014442,mode=755 0 0
|
|
|
c401cc |
+securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
|
|
|
c401cc |
+selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
|
|
|
c401cc |
+tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev 0 0
|
|
|
c401cc |
+devpts /dev/pts devpts rw,seclabel,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
|
|
|
c401cc |
+tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0
|
|
|
c401cc |
+tmpfs /sys/fs/cgroup tmpfs rw,seclabel,nosuid,nodev,noexec,mode=755 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
|
|
|
c401cc |
+pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/net_cls cgroup rw,nosuid,nodev,noexec,relatime,net_cls 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
|
|
|
c401cc |
+cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
|
|
|
c401cc |
+/dev/mapper/fedora-root / ext4 rw,seclabel,relatime,data=ordered 0 0
|
|
|
c401cc |
+systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=33,pgrp=1,timeout=300,minproto=5,maxproto=5,direct 0 0
|
|
|
c401cc |
+configfs /sys/kernel/config configfs rw,relatime 0 0
|
|
|
c401cc |
+debugfs /sys/kernel/debug debugfs rw,relatime 0 0
|
|
|
c401cc |
+mqueue /dev/mqueue mqueue rw,seclabel,relatime 0 0
|
|
|
c401cc |
+tmpfs /tmp tmpfs rw,seclabel 0 0
|
|
|
c401cc |
+hugetlbfs /dev/hugepages hugetlbfs rw,seclabel,relatime 0 0
|
|
|
c401cc |
+binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
|
|
|
c401cc |
+/dev/sda1 /boot ext4 rw,seclabel,relatime,stripe=4,data=ordered 0 0
|
|
|
c401cc |
+fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0
|
|
|
c401cc |
+gvfsd-fuse /run/user/501/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=501,group_id=501 0 0
|
|
|
c401cc |
diff --git a/tests/virfiletest.c b/tests/virfiletest.c
|
|
|
c401cc |
new file mode 100644
|
|
|
c401cc |
index 0000000..fd6761d
|
|
|
c401cc |
--- /dev/null
|
|
|
c401cc |
+++ b/tests/virfiletest.c
|
|
|
c401cc |
@@ -0,0 +1,124 @@
|
|
|
c401cc |
+/*
|
|
|
c401cc |
+ * Copyright (C) 2013 Red Hat, Inc.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * This library is free software; you can redistribute it and/or
|
|
|
c401cc |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
c401cc |
+ * License as published by the Free Software Foundation; either
|
|
|
c401cc |
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * This library is distributed in the hope that it will be useful,
|
|
|
c401cc |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
c401cc |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
c401cc |
+ * Lesser General Public License for more details.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
c401cc |
+ * License along with this library. If not, see
|
|
|
c401cc |
+ * <http://www.gnu.org/licenses/>.
|
|
|
c401cc |
+ *
|
|
|
c401cc |
+ * Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
c401cc |
+ */
|
|
|
c401cc |
+
|
|
|
c401cc |
+#include <config.h>
|
|
|
c401cc |
+
|
|
|
c401cc |
+#include <stdlib.h>
|
|
|
c401cc |
+
|
|
|
c401cc |
+#include "testutils.h"
|
|
|
c401cc |
+#include "virfile.h"
|
|
|
c401cc |
+#include "virstring.h"
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
+#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
|
|
|
c401cc |
+static int testFileCheckMounts(const char *prefix,
|
|
|
c401cc |
+ char **gotmounts,
|
|
|
c401cc |
+ size_t gotnmounts,
|
|
|
c401cc |
+ const char *const*wantmounts,
|
|
|
c401cc |
+ size_t wantnmounts)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ size_t i;
|
|
|
c401cc |
+ if (gotnmounts != wantnmounts) {
|
|
|
c401cc |
+ fprintf(stderr, "Expected %zu mounts under %s, but got %zu\n",
|
|
|
c401cc |
+ wantnmounts, prefix, gotnmounts);
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ for (i = 0; i < gotnmounts; i++) {
|
|
|
c401cc |
+ if (STRNEQ(gotmounts[i], wantmounts[i])) {
|
|
|
c401cc |
+ fprintf(stderr, "Expected mount[%zu] '%s' but got '%s'\n",
|
|
|
c401cc |
+ i, wantmounts[i], gotmounts[i]);
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ return 0;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+struct testFileGetMountSubtreeData {
|
|
|
c401cc |
+ const char *path;
|
|
|
c401cc |
+ const char *prefix;
|
|
|
c401cc |
+ const char *const *mounts;
|
|
|
c401cc |
+ size_t nmounts;
|
|
|
c401cc |
+ bool rev;
|
|
|
c401cc |
+};
|
|
|
c401cc |
+
|
|
|
c401cc |
+static int testFileGetMountSubtree(const void *opaque)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+ char **gotmounts = NULL;
|
|
|
c401cc |
+ size_t gotnmounts = 0;
|
|
|
c401cc |
+ const struct testFileGetMountSubtreeData *data = opaque;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (data->rev) {
|
|
|
c401cc |
+ if (virFileGetMountReverseSubtree(data->path,
|
|
|
c401cc |
+ data->prefix,
|
|
|
c401cc |
+ &gotmounts,
|
|
|
c401cc |
+ &gotnmounts) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ } else {
|
|
|
c401cc |
+ if (virFileGetMountSubtree(data->path,
|
|
|
c401cc |
+ data->prefix,
|
|
|
c401cc |
+ &gotmounts,
|
|
|
c401cc |
+ &gotnmounts) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ ret = testFileCheckMounts(data->prefix,
|
|
|
c401cc |
+ gotmounts, gotnmounts,
|
|
|
c401cc |
+ data->mounts, data->nmounts);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ cleanup:
|
|
|
c401cc |
+ virStringFreeList(gotmounts);
|
|
|
c401cc |
+ return ret;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+#endif /* ! defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */
|
|
|
c401cc |
+
|
|
|
c401cc |
+static int
|
|
|
c401cc |
+mymain(void)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ int ret = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
|
|
|
c401cc |
+# define MTAB_PATH1 abs_srcdir "/virfiledata/mounts1.txt"
|
|
|
c401cc |
+# define MTAB_PATH2 abs_srcdir "/virfiledata/mounts2.txt"
|
|
|
c401cc |
+
|
|
|
c401cc |
+ static const char *wantmounts1[] = {
|
|
|
c401cc |
+ "/proc", "/proc/sys/fs/binfmt_misc", "/proc/sys/fs/binfmt_misc",
|
|
|
c401cc |
+ };
|
|
|
c401cc |
+ static const char *wantmounts1rev[] = {
|
|
|
c401cc |
+ "/proc/sys/fs/binfmt_misc", "/proc/sys/fs/binfmt_misc", "/proc"
|
|
|
c401cc |
+ };
|
|
|
c401cc |
+
|
|
|
c401cc |
+# define DO_TEST_MOUNT_SUBTREE(name, path, prefix, mounts, rev) \
|
|
|
c401cc |
+ do { \
|
|
|
c401cc |
+ struct testFileGetMountSubtreeData data = { \
|
|
|
c401cc |
+ path, prefix, mounts, ARRAY_CARDINALITY(mounts), rev \
|
|
|
c401cc |
+ }; \
|
|
|
c401cc |
+ if (virtTestRun(name, 1, testFileGetMountSubtree, &data) < 0) \
|
|
|
c401cc |
+ ret = -1; \
|
|
|
c401cc |
+ } while (0)
|
|
|
c401cc |
+
|
|
|
c401cc |
+ DO_TEST_MOUNT_SUBTREE("/proc normal", MTAB_PATH1, "/proc", wantmounts1, false);
|
|
|
c401cc |
+ DO_TEST_MOUNT_SUBTREE("/proc reverse", MTAB_PATH1, "/proc", wantmounts1rev, true);
|
|
|
c401cc |
+#endif /* ! defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R */
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+VIRT_TEST_MAIN(mymain)
|
|
|
c401cc |
--
|
|
|
c401cc |
1.8.4.5
|
|
|
c401cc |
|