]> git.proxmox.com Git - mirror_lxc.git/commitdiff
tests: add test for detect_ramfs_rootfs()
authorChristian Brauner <christian.brauner@canonical.com>
Tue, 6 Sep 2016 12:51:01 +0000 (14:51 +0200)
committerChristian Brauner <christian.brauner@canonical.com>
Tue, 27 Sep 2016 20:51:46 +0000 (22:51 +0200)
Signed-off-by: Christian Brauner <christian.brauner@canonical.com>
.gitignore
src/tests/Makefile.am
src/tests/lxc-test-utils.c

index a89968f1ffe10472b958859817825a553aec950f..9ad094b04e2cf735f218eaf5043119022d49c4cc 100644 (file)
@@ -91,7 +91,7 @@ src/tests/lxc-test-shutdowntest
 src/tests/lxc-test-snapshot
 src/tests/lxc-test-startone
 src/tests/lxc-test-usernic
-src/tests/lxc-test-utils
+src/tests/lxc-test-utils*
 src/tests/lxc-usernic-test
 
 config/compile
index 2e7dd5602ca0bc66399068b54306b538a9057e93..322b8bbc4df8de0325ad8986517b094d0111c1b1 100644 (file)
@@ -105,3 +105,6 @@ EXTRA_DIST = \
        shutdowntest.c \
        snapshot.c \
        startone.c
+
+clean-local:
+       rm -f lxc-test-utils-*
index 5b213c84fb97460b3e587fe53a62261a0c92e5ec..081ed4b9eb5e69013d2381af840bad02b9a26382 100644 (file)
  */
 
 #define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "lxctest.h"
 #include "utils.h"
@@ -60,6 +67,161 @@ void test_lxc_deslashify(void)
        free(s);
 }
 
+void test_detect_ramfs_rootfs(void)
+{
+       size_t i;
+       int ret;
+       int fret = EXIT_FAILURE;
+       size_t len = 5 /* /proc */ + 21 /* /int_as_str */ + 7 /* /ns/mnt */ + 1 /* \0 */;
+       char path[len];
+       int init_ns = -1;
+       char tmpf1[] = "lxc-test-utils-XXXXXX";
+       char tmpf2[] = "lxc-test-utils-XXXXXX";
+       int fd1 = -1, fd2 = -1;
+       FILE *fp1 = NULL, *fp2 = NULL;
+       char *mountinfo[] = {
+               "18 24 0:17 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw",
+               "19 24 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:13 - proc proc rw",
+               "20 24 0:6 / /dev rw,nosuid,relatime shared:2 - devtmpfs udev rw,size=4019884k,nr_inodes=1004971,mode=755",
+               "21 20 0:14 / /dev/pts rw,nosuid,noexec,relatime shared:3 - devpts devpts rw,gid=5,mode=620,ptmxmode=000",
+               "22 24 0:18 / /run rw,nosuid,noexec,relatime shared:5 - tmpfs tmpfs rw,size=807912k,mode=755",
+
+               /* This is what we care about. */
+               "24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099",
+
+               "25 18 0:12 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:8 - securityfs securityfs rw",
+               "26 20 0:20 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw",
+               "27 22 0:21 / /run/lock rw,nosuid,nodev,noexec,relatime shared:6 - tmpfs tmpfs rw,size=5120k",
+               "28 18 0:22 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:9 - tmpfs tmpfs ro,mode=755",
+               "29 28 0:23 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd",
+               "30 18 0:24 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:11 - pstore pstore rw",
+               "31 18 0:25 / /sys/firmware/efi/efivars rw,nosuid,nodev,noexec,relatime shared:12 - efivarfs efivarfs rw",
+               "32 28 0:26 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,cpu,cpuacct",
+               "33 28 0:27 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,net_cls,net_prio",
+               "34 28 0:28 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,blkio",
+               "35 28 0:29 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,freezer",
+               "36 28 0:30 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,memory",
+               "37 28 0:31 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,hugetlb",
+               "38 28 0:32 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,cpuset",
+               "39 28 0:33 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,devices",
+               "40 28 0:34 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,pids",
+               "41 28 0:35 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:23 - cgroup cgroup rw,perf_event",
+               "42 19 0:36 / /proc/sys/fs/binfmt_misc rw,relatime shared:24 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct",
+               "43 18 0:7 / /sys/kernel/debug rw,relatime shared:25 - debugfs debugfs rw",
+               "44 20 0:37 / /dev/hugepages rw,relatime shared:26 - hugetlbfs hugetlbfs rw",
+               "45 20 0:16 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw",
+               "46 43 0:9 / /sys/kernel/debug/tracing rw,relatime shared:28 - tracefs tracefs rw",
+               "76 18 0:38 / /sys/fs/fuse/connections rw,relatime shared:29 - fusectl fusectl rw",
+               "78 24 8:1 / /boot/efi rw,relatime shared:30 - vfat /dev/sda1 rw,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro",
+       };
+
+       ret = snprintf(path, len, "/proc/self/ns/mnt");
+       if (ret < 0 || (size_t)ret >= len) {
+               lxc_error("%s\n", "Failed to create path with snprintf().");
+               goto non_test_error;
+       }
+
+       init_ns = open(path, O_RDONLY | O_CLOEXEC);
+       if (init_ns < 0) {
+               lxc_error("%s\n", "Failed to open initial mount namespace.");
+               goto non_test_error;
+       }
+
+       if (unshare(CLONE_NEWNS) < 0) {
+               lxc_error("%s\n", "Could not unshare mount namespace.");
+               close(init_ns);
+               init_ns = -1;
+               goto non_test_error;
+       }
+
+       if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) < 0) {
+               lxc_error("Failed to remount / private: %s.\n", strerror(errno));
+               goto non_test_error;
+       }
+
+       fd1 = mkstemp(tmpf1);
+       if (fd1 < 0) {
+               lxc_error("%s\n", "Could not create temporary file.");
+               goto non_test_error;
+       }
+
+       fd2 = mkstemp(tmpf2);
+       if (fd2 < 0) {
+               lxc_error("%s\n", "Could not create temporary file.");
+               goto non_test_error;
+       }
+
+       fp1 = fdopen(fd1, "r+");
+       if (!fp1) {
+               lxc_error("%s\n", "Could not fdopen() temporary file.");
+               goto non_test_error;
+       }
+
+       fp2 = fdopen(fd2, "r+");
+       if (!fp2) {
+               lxc_error("%s\n", "Could not fdopen() temporary file.");
+               goto non_test_error;
+       }
+
+       /* Test if it correctly detects - rootfs rootfs */
+       for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) {
+               if (fprintf(fp1, "%s\n", mountinfo[i]) < 0) {
+                       lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]);
+                       goto non_test_error;
+               }
+       }
+       fclose(fp1);
+       fp1 = NULL;
+
+       /* Test if it correctly fails to detect when no - rootfs rootfs */
+       for (i = 0; i < sizeof(mountinfo) / sizeof(mountinfo[0]); i++) {
+               if (strcmp(mountinfo[i], "24 0 8:2 / / rw - rootfs rootfs rw,size=1004396k,nr_inodes=251099") == 0)
+                       continue;
+               if (fprintf(fp2, "%s\n", mountinfo[i]) < 0) {
+                       lxc_error("Could not write \"%s\" to temporary file.", mountinfo[i]);
+                       goto non_test_error;
+               }
+       }
+       fclose(fp2);
+       fp2 = NULL;
+
+       if (mount(tmpf1, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) {
+               lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\".");
+               goto non_test_error;
+       }
+
+       lxc_test_assert_abort(detect_ramfs_rootfs());
+
+       if (mount(tmpf2, "/proc/self/mountinfo", NULL, MS_BIND, 0) < 0) {
+               lxc_error("%s\n", "Could not overmount \"/proc/self/mountinfo\".");
+               goto non_test_error;
+       }
+
+       lxc_test_assert_abort(!detect_ramfs_rootfs());
+       fret = EXIT_SUCCESS;
+
+non_test_error:
+       if (fp1)
+               fclose(fp1);
+       else if (fd1 > 0)
+               close(fd1);
+       if (fp2)
+               fclose(fp2);
+       else if (fd2 > 0)
+               close(fd2);
+
+       if (init_ns > 0) {
+               if (setns(init_ns, 0) < 0) {
+                       lxc_error("Failed to switch back to initial mount namespace: %s.\n", strerror(errno));
+                       fret = EXIT_FAILURE;
+               }
+               close(init_ns);
+       }
+       if (fret == EXIT_SUCCESS)
+               return;
+       exit(fret);
+}
+
 void test_lxc_string_replace(void)
 {
        char *s;
@@ -117,6 +279,7 @@ int main(int argc, char *argv[])
        test_lxc_string_replace();
        test_lxc_string_in_array();
        test_lxc_deslashify();
+       test_detect_ramfs_rootfs();
 
        exit(EXIT_SUCCESS);
 }