]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: create workdir/upperdir when mounting a Type=overlay mount unit
authorLuca Boccassi <bluca@debian.org>
Thu, 7 Dec 2023 23:19:36 +0000 (23:19 +0000)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Dec 2023 02:22:14 +0000 (11:22 +0900)
So far we created the target directory, and the source for bind mounts,
but not workdir/upperdir for overlays, so it has to be done separately
and strictly before the unit is started, which is annoying. Check the
options when creating directories, and if upper/work directories are
specified, create them.

man/systemd.mount.xml
src/core/mount.c
test/units/testsuite-74.mount.sh

index 790022193561691fcd623a2f574bf9a68afdf1e3..e11b9ffed42f4e92dffb341c09860154ff1db568 100644 (file)
         <term><varname>Type=</varname></term>
         <listitem><para>Takes a string for the file system type. See
         <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        for details. This setting is optional.</para></listitem>
+        for details. This setting is optional.</para>
+
+        <para>If the type is <literal>overlay</literal>, and <literal>upperdir=</literal> or
+        <literal>workdir=</literal> are specified as options and they don't exist, they will be created.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
index f364b2ab0b7ae5aafb291b144c1870cb9142b477..654be17c473d280d642f5cf967f23cc5cc888252 100644 (file)
@@ -1200,6 +1200,34 @@ static void mount_enter_mounting(Mount *m) {
         if (r < 0 && r != -EEXIST)
                 log_unit_warning_errno(UNIT(m), r, "Failed to create mount point '%s', ignoring: %m", m->where);
 
+        /* If we are asked to create an OverlayFS, create the upper/work directories if they are missing */
+        if (streq_ptr(p->fstype, "overlay")) {
+                _cleanup_strv_free_ char **dirs = NULL;
+
+                r = fstab_filter_options(
+                                p->options,
+                                "upperdir\0workdir\0",
+                                /* ret_namefound= */ NULL,
+                                /* ret_value= */ NULL,
+                                &dirs,
+                                /* ret_filtered= */ NULL);
+                if (r < 0)
+                        log_unit_warning_errno(
+                                        UNIT(m),
+                                        r,
+                                        "Failed to determine upper directory for OverlayFS, ignoring: %m");
+                else
+                        STRV_FOREACH(d, dirs) {
+                                r = mkdir_p_label(*d, m->directory_mode);
+                                if (r < 0 && r != -EEXIST)
+                                        log_unit_warning_errno(
+                                                        UNIT(m),
+                                                        r,
+                                                        "Failed to create overlay directory '%s', ignoring: %m",
+                                                        *d);
+                        }
+        }
+
         if (source_is_dir)
                 unit_warn_if_dir_nonempty(UNIT(m), m->where);
         unit_warn_leftover_processes(UNIT(m), unit_log_leftover_process_start);
index 41c5c8652a23bb40dd013d29cf08204b43783c24..594c123e1ba4067a9cb95630c91ca1fdd2389c72 100755 (executable)
@@ -149,3 +149,9 @@ touch "$WORK_DIR/mnt/foo/baz"
 systemd-umount "$WORK_DIR/mnt/foo"
 test -d "$WORK_DIR/mnt/foo/bar"
 test ! -e "$WORK_DIR/mnt/foo/baz"
+
+# overlay
+systemd-mount --type=overlay --options="lowerdir=/etc,upperdir=$WORK_DIR/upper,workdir=$WORK_DIR/work" /etc "$WORK_DIR/overlay"
+touch "$WORK_DIR/overlay/foo"
+test -e "$WORK_DIR/upper/foo"
+systemd-umount "$WORK_DIR/overlay"