Some filesystems - specifically securityfs - are not supported in
all systems running libvirt containers. When starting a container,
mount only the filesystems that are supported on the host. Detection
of filesystem support is done at runtime.
Signed-off-by: Bogdan Purcareata <bogdan.purcareata(a)freescale.com>
---
src/lxc/lxc_container.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index c60f5d8..eff9a24 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -509,6 +509,61 @@ static int lxcContainerChildMountSort(const void *a, const void *b)
# define MS_SLAVE (1<<19)
#endif
+/*
+ * This function attempts to detect kernel support
+ * for a specific filesystem type. This is done by
+ * inspecting /proc/filesystems.
+ */
+static int lxcCheckFSSupport(const char *fs_type)
+{
+ FILE *fp = NULL;
+ int ret = -1;
+ const char *fslist = "/proc/filesystems";
+ char *line = NULL;
+ const char *type;
+
+ if (!fs_type)
+ return 1;
+
+ VIR_DEBUG("Checking kernel support for %s", fs_type);
+
+ VIR_DEBUG("Open %s", fslist);
+ if (!(fp = fopen(fslist, "r"))) {
+ if (errno == ENOENT)
+
+ virReportSystemError(errno,
+ _("Unable to read %s"),
+ fslist);
+ goto cleanup;
+ }
+
+ while (!feof(fp)) {
+ size_t n;
+ VIR_FREE(line);
+ if (getline(&line, &n, fp) <= 0) {
+ if (feof(fp))
+ break;
+
+ goto cleanup;
+ }
+
+ type = strstr(line, fs_type);
+ if (type) {
+ ret = 1;
+ goto cleanup;
+ }
+ }
+
+ VIR_DEBUG("No kernel support for %s", fs_type);
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(line);
+ VIR_FORCE_FCLOSE(fp);
+ return ret;
+}
+
static int lxcContainerGetSubtree(const char *prefix,
char ***mountsret,
size_t *nmountsret)
@@ -855,17 +910,23 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
for (i = 0; i < ARRAY_CARDINALITY(lxcBasicMounts); i++) {
virLXCBasicMountInfo const *mnt = &lxcBasicMounts[i];
const char *srcpath = NULL;
+ const char *dstpath = NULL;
VIR_DEBUG("Processing %s -> %s",
mnt->src, mnt->dst);
srcpath = mnt->src;
+ dstpath = mnt->dst;
/* Skip if mount doesn't exist in source */
if ((srcpath[0] == '/') &&
(access(srcpath, R_OK) < 0))
continue;
+ if ((access(dstpath, R_OK) < 0) || /* mount is not present on host */
+ (!lxcCheckFSSupport(mnt->type))) /* no fs support in kernel */
+ continue;
+
#if WITH_SELINUX
if (STREQ(mnt->src, SELINUX_MOUNT) &&
(!is_selinux_enabled() || userns_enabled))
--
1.7.11.7