Securityfs kernel support may not be available on all platforms
running libvirt containers. Since securityfs receives special
handling in the context of user namespaces, make an additional
check to see if it is supported, by inspecting /proc/filesystems.
Making this check for all lxcBasicMounts is a bit tedious, since
the /proc filesystem is first unmounted from host, so the
/proc/filesystems list should be saved before unmounting, to be
available at all times. However, checks for the support for /proc
or /sys are superfluous.
In the long run, to support the addition of new filesystems in
lxcBasicMounts, an additional "optional" flag should be introduced,
to mark that for a specific filesystem, the code should first check
for support in the kernel, before mounting it. For mandatory
filesystems, if mounting them fails, creating the container fails.
Right now, check for support only for securityfs, since right now
it is the only special case.
Signed-off-by: Bogdan Purcareata <bogdan.purcareata(a)freescale.com>
---
src/lxc/lxc_container.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index c60f5d8..cead026 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -509,6 +509,71 @@ 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;
+ char *type;
+ size_t n;
+
+ /* there should be no problem mounting an entry
+ * with NULL fs type, hence NULL fs types are
+ * supported */
+ if (!fs_type) {
+ ret = 1;
+ goto out;
+ }
+
+ VIR_DEBUG("Checking kernel support for %s in %s", fs_type, fslist);
+
+ if (!(fp = fopen(fslist, "r"))) {
+ virReportSystemError(errno,
+ _("Unable to read %s"),
+ fslist);
+ goto out;
+ }
+
+ while(getline(&line, &n, fp) > 0) {
+ type = strstr(line, fs_type);
+
+ if (!type)
+ continue;
+
+ /* eliminate trailing newline */
+ type[strlen(type) - 1] = '\0';
+
+ if (STREQ(type,fs_type)) {
+ VIR_DEBUG("Kernel support found for %s", fs_type);
+ ret = 1;
+ goto cleanup;
+ }
+ }
+
+ if (ferror(fp)) {
+ virReportSystemError(errno,
+ _("Error reading line from %s"),
+ fslist);
+ goto cleanup;
+ }
+
+ VIR_DEBUG("No kernel support for %s", fs_type);
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(line);
+ VIR_FORCE_FCLOSE(fp);
+out:
+ return ret;
+}
+
static int lxcContainerGetSubtree(const char *prefix,
char ***mountsret,
size_t *nmountsret)
@@ -872,7 +937,9 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
continue;
#endif
- if (STREQ(mnt->src, "securityfs") && userns_enabled)
+ if (STREQ(mnt->src, "securityfs") &&
+ (lxcCheckFSSupport(mnt->type) < 1 ||
+ userns_enabled))
continue;
if (virFileMakePath(mnt->dst) < 0) {
--
1.7.11.7