summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-27 17:23:38 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-27 17:23:38 +0100
commit8788bf0fbfdd98c82fd899658d363f34d38be47e (patch)
treeaa10fd0ea9a1cee77d431495efa79a18c83451ff
parent8bf48247176886c6ca5a51b94c97a7c50ddbd270 (diff)
downloadrvnit-8788bf0fbfdd98c82fd899658d363f34d38be47e.tar.gz
rvnit-8788bf0fbfdd98c82fd899658d363f34d38be47e.tar.xz
rvnit-8788bf0fbfdd98c82fd899658d363f34d38be47e.zip
support early mounting of /proc and /run on linux
-rw-r--r--rvnit.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/rvnit.c b/rvnit.c
index 04b6f80..d8fcd56 100644
--- a/rvnit.c
+++ b/rvnit.c
@@ -6,6 +6,10 @@
 #include <sys/stat.h>
 #include <sys/un.h>
 #include <sys/wait.h>
+#ifdef __linux__
+#include <sys/mount.h>
+#include <sys/reboot.h>
+#endif
 
 #include <ctype.h>
 #include <dirent.h>
@@ -618,6 +622,36 @@ own_console()
 	ioctl(0, TIOCSCTTY, 1);
 }
 
+/* only detects toplevel mount points */
+static int
+mounted(const char *dir)
+{
+	struct stat rootst;
+	struct stat dirst;
+
+	stat("/", &rootst);
+	if (stat(dir, &dirst) < 0)
+		return 1;  /* can't mount if mountpoint doesn't exist */
+
+	return rootst.st_dev != dirst.st_dev;
+}
+
+void
+init_mount() {
+#ifdef __linux__
+	LOG("init_mount");
+	if (!mounted("/proc")) {
+		LOG("mounting /proc");
+		mount("proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, "");
+	}
+	if (!mounted("/run")) {
+		LOG("mounting /run");
+		mount("run", "/run", "tmpfs", MS_NOSUID|MS_NODEV, "mode=0755");
+	}
+	LOG("init_mount done");
+#endif
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -633,12 +667,6 @@ main(int argc, char *argv[])
 		return 111;
 	}
 
-	pid1 = (getpid() == 1);
-	if (pid1) {
-		setenv("PATH", "/usr/bin:/usr/sbin", 0);
-		own_console();
-	}
-
 	pipe(selflogfd);
 	fcntl(selflogfd[0], F_SETFL, O_NONBLOCK);
 	fcntl(selflogfd[1], F_SETFL, O_NONBLOCK);
@@ -657,6 +685,15 @@ main(int argc, char *argv[])
 	fcntl(globallogfd[0], F_SETFD, FD_CLOEXEC);
 	fcntl(globallogfd[1], F_SETFD, FD_CLOEXEC);
 
+	LOG("booting");
+
+	pid1 = (getpid() == 1);
+	if (pid1) {
+		setenv("PATH", "/usr/bin:/usr/sbin", 0);
+		init_mount();
+		own_console();
+	}
+
 	if (pthread_mutex_init(&services_lock, 0) != 0) {
 		perror("pthread_mutex_init");
 		return 111;
@@ -679,7 +716,6 @@ main(int argc, char *argv[])
 	if (pid1)
 		ioctl(0, TIOCNOTTY);
 
-	LOG("booting");
 
 	int i;
 	for (level = 0; level < 100; level++) {