]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
volatile-root: add overlay mode for host boots, too
authorLennart Poettering <lennart@poettering.net>
Wed, 19 Dec 2018 16:30:13 +0000 (17:30 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 1 Mar 2019 13:11:07 +0000 (14:11 +0100)
src/fstab-generator/fstab-generator.c
src/volatile-root/volatile-root.c

index 30a6d356d0e32d24c94c1b52123efc9094c318a0..d1bfa775e4375a5c39e242943253cf062c2295dd 100644 (file)
@@ -722,10 +722,11 @@ static int add_sysroot_usr_mount(void) {
 }
 
 static int add_volatile_root(void) {
+
         /* Let's add in systemd-remount-volatile.service which will remount the root device to tmpfs if this is
-         * requested, leaving only /usr from the root mount inside. */
+         * requested (or as an overlayfs), leaving only /usr from the root mount inside. */
 
-        if (arg_volatile_mode != VOLATILE_YES)
+        if (!IN_SET(arg_volatile_mode, VOLATILE_YES, VOLATILE_OVERLAY))
                 return 0;
 
         return generator_add_symlink(arg_dest, SPECIAL_INITRD_ROOT_FS_TARGET, "requires",
index d7f52e4a625f50b961117e98a22953ab3e429d12..02f6d31b0514b12ec42ee34a0b1a5434ee409b78 100644 (file)
@@ -3,6 +3,7 @@
 #include <sys/mount.h>
 
 #include "alloc-util.h"
+#include "escape.h"
 #include "fs-util.h"
 #include "main-func.h"
 #include "mkdir.h"
@@ -17,20 +18,7 @@ static int make_volatile(const char *path) {
         _cleanup_free_ char *old_usr = NULL;
         int r;
 
-        r = path_is_mount_point(path, NULL, AT_SYMLINK_FOLLOW);
-        if (r < 0)
-                return log_error_errno(r, "Couldn't determine whether %s is a mount point: %m", path);
-        if (r == 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "%s is not a mount point.", path);
-
-        r = path_is_temporary_fs(path);
-        if (r < 0)
-                return log_error_errno(r, "Couldn't determine whether %s is a temporary file system: %m", path);
-        if (r > 0) {
-                log_info("%s already is a temporary file system.", path);
-                return 0;
-        }
+        assert(path);
 
         r = chase_symlinks("/usr", path, CHASE_PREFIX_ROOT, &old_usr);
         if (r < 0)
@@ -79,6 +67,51 @@ finish_rmdir:
         return r;
 }
 
+static int make_overlay(const char *path) {
+        _cleanup_free_ char *escaped_path = NULL;
+        bool tmpfs_mounted = false;
+        const char *options = NULL;
+        int r;
+
+        assert(path);
+
+        r = mkdir_p("/run/systemd/overlay-sysroot", 0700);
+        if (r < 0)
+                return log_error_errno(r, "Couldn't create overlay sysroot directory: %m");
+
+        r = mount_verbose(LOG_ERR, "tmpfs", "/run/systemd/overlay-sysroot", "tmpfs", MS_STRICTATIME, "mode=755");
+        if (r < 0)
+                goto finish;
+
+        tmpfs_mounted = true;
+
+        if (mkdir("/run/systemd/overlay-sysroot/upper", 0755) < 0) {
+                r = log_error_errno(errno, "Failed to create /run/systemd/overlay-sysroot/upper: %m");
+                goto finish;
+        }
+
+        if (mkdir("/run/systemd/overlay-sysroot/work", 0755) < 0) {
+                r = log_error_errno(errno, "Failed to create /run/systemd/overlay-sysroot/work: %m");
+                goto finish;
+        }
+
+        escaped_path = shell_escape(path, ",:");
+        if (!escaped_path) {
+                r = log_oom();
+                goto finish;
+        }
+
+        options = strjoina("lowerdir=", escaped_path, ",upperdir=/run/systemd/overlay-sysroot/upper,workdir=/run/systemd/overlay-sysroot/work");
+        r = mount_verbose(LOG_ERR, "overlay", path, "overlay", 0, options);
+
+finish:
+        if (tmpfs_mounted)
+                (void) umount_verbose("/run/systemd/overlay-sysroot");
+
+        (void) rmdir("/run/systemd/overlay-sysroot");
+        return r;
+}
+
 static int run(int argc, char *argv[]) {
         VolatileMode m = _VOLATILE_MODE_INVALID;
         const char *path;
@@ -116,10 +149,29 @@ static int run(int argc, char *argv[]) {
                                                "Directory cannot be the root directory.");
         }
 
-        if (m != VOLATILE_YES)
+        if (!IN_SET(m, VOLATILE_YES, VOLATILE_OVERLAY))
                 return 0;
 
-        return make_volatile(path);
+        r = path_is_mount_point(path, NULL, AT_SYMLINK_FOLLOW);
+        if (r < 0)
+                return log_error_errno(r, "Couldn't determine whether %s is a mount point: %m", path);
+        if (r == 0)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "%s is not a mount point.", path);
+
+        r = path_is_temporary_fs(path);
+        if (r < 0)
+                return log_error_errno(r, "Couldn't determine whether %s is a temporary file system: %m", path);
+        if (r > 0) {
+                log_info("%s already is a temporary file system.", path);
+                return 0;
+        }
+
+        if (m == VOLATILE_YES)
+                return make_volatile(path);
+        else {
+                assert(m == VOLATILE_OVERLAY);
+                return make_overlay(path);
+        }
 }
 
 DEFINE_MAIN_FUNCTION(run);