[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] LXC: Detect fs support. Mount only supported fs in containers



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 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]