chiark / gitweb /
tmpfiles: introduce the concept of unsafe operations
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 21 Dec 2013 01:25:39 +0000 (20:25 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 24 Dec 2013 20:48:06 +0000 (15:48 -0500)
Various operations done by systemd-tmpfiles may only be safely done at
boot (e.g. removal of X lockfiles in /tmp, creation of /run/nologin).
Other operations may be done at any point in time (e.g. setting the
ownership on /{run,var}/log/journal). This distinction is largely
orthogonal to the type of operation.

A new switch --unsafe is added, and operations which should only be
executed during bootup are marked with an exclamation mark in the
configuration files. systemd-tmpfiles.service is modified to use this
switch, and guards are added so it is hard to re-start it by mistake.

If we install a new version of systemd, we actually want to enforce
some changes to tmpfiles configuration immediately. This should now be
possible to do safely, so distribution packages can be modified to
execute the "safe" subset at package installation time.

/run/nologin creation is split out into a separate service, to make it
easy to override.

https://bugzilla.redhat.com/show_bug.cgi?id=1043212
https://bugzilla.redhat.com/show_bug.cgi?id=1045849

Makefile.am
man/systemd-tmpfiles.xml
man/tmpfiles.d.xml
src/tmpfiles/tmpfiles.c
tmpfiles.d/legacy.conf
tmpfiles.d/systemd-nologin.conf [new file with mode: 0644]
tmpfiles.d/systemd.conf
tmpfiles.d/x11.conf
units/systemd-tmpfiles-setup.service.in

index f4b19589a1b1c6f7d5938bdb6ef5d629a9fc90a6..b7a4681447f14532a4ef7a9ea80db1cd22e6cf75 100644 (file)
@@ -1584,6 +1584,7 @@ nodist_systemunit_DATA += \
 
 dist_tmpfiles_DATA = \
        tmpfiles.d/systemd.conf \
+       tmpfiles.d/systemd-nologin.conf \
        tmpfiles.d/tmp.conf \
        tmpfiles.d/x11.conf
 
index c65636b0fe65b48336a984358b0339902321d62c..9b8932c635e8b743f65bd955680512cca55fd1b2 100644 (file)
                                 configuration files are
                                 removed.</para></listitem>
                         </varlistentry>
+                        <varlistentry>
+                                <term><option>--unsafe</option></term>
+                                <listitem><para>Also execute lines
+                                with an exclamation mark.
+                                </para></listitem>
+                        </varlistentry>
                         <varlistentry>
                                 <term><option>--prefix=PATH</option></term>
                                 <listitem><para>Only apply rules that
index 331fd1b4721ddedb68446decc60de1d3f0e14e3a..0da52aedadf32b0f7665cde07d7c51cc9862fa9b 100644 (file)
@@ -113,6 +113,9 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
                 <refsect2>
                         <title>Type</title>
 
+                        <para>The type consists of a single letter and
+                        optionally an exclamation mark.</para>
+
                         <para>The following line types are understood:</para>
 
                         <variablelist>
@@ -262,6 +265,28 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
                                         names.</para></listitem>
                                 </varlistentry>
                         </variablelist>
+
+                        <para>If the exclamation mark is used, this
+                        line is only safe of execute during boot, and
+                        can break a running system. Lines without the
+                        exclamation mark are presumed to be safe to
+                        execute at any time, e.g. on package upgrades.
+                        <command>systemd-tmpfiles</command> will
+                        execute line with an exclamation mark only if
+                        option <option>--unsafe</option> is given.
+                        </para>
+
+                        <para>For example:
+                        <programlisting>
+# Make sure these are created by default so that nobody else can
+d /tmp/.X11-unix 1777 root root 10d
+
+# Unlink the X11 lock files
+r! /tmp/.X[0-9]*-lock
+                        </programlisting>
+                        The second line in contrast to the first one
+                        would break a running system, and will only be
+                        executed with <option>--unsafe</option>.</para>
                 </refsect2>
 
                 <refsect2>
index 02351e18f70b588d2d1f43768a82f3961a008135..881c3b0d7818fe963bb4dfa5435f3599efa285d6 100644 (file)
@@ -107,6 +107,7 @@ static Set *unix_sockets = NULL;
 static bool arg_create = false;
 static bool arg_clean = false;
 static bool arg_remove = false;
+static bool arg_unsafe = false;
 
 static char **include_prefixes = NULL;
 static char **exclude_prefixes = NULL;
@@ -1077,7 +1078,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         _cleanup_item_free_ Item *i = NULL;
         Item *existing;
         _cleanup_free_ char
-                *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
+                *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
         char type;
         Hashmap *h;
         int r, n = -1;
@@ -1087,8 +1088,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         assert(buffer);
 
         r = sscanf(buffer,
-                   "%c %ms %ms %ms %ms %ms %n",
-                   &type,
+                   "%ms %ms %ms %ms %ms %ms %n",
+                   &action,
                    &path,
                    &mode,
                    &user,
@@ -1100,6 +1101,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 return -EIO;
         }
 
+        if (strlen(action) > 2 || (strlen(action) > 1 && action[1] != '!')) {
+                log_error("[%s:%u] Unknown modifier '%s'", fname, line, action);
+                return -EINVAL;
+        } else if (strlen(action) > 1 && !arg_unsafe)
+                return 0;
+
+        type = action[0];
+
         i = new0(Item, 1);
         if (!i)
                 return log_oom();
@@ -1271,6 +1280,7 @@ static int help(void) {
                "     --create               Create marked files/directories\n"
                "     --clean                Clean up marked directories\n"
                "     --remove               Remove marked files/directories\n"
+               "     --unsafe               Execute actions only safe at boot\n"
                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
                "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n",
                program_invocation_short_name);
@@ -1285,6 +1295,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_CREATE,
                 ARG_CLEAN,
                 ARG_REMOVE,
+                ARG_UNSAFE,
                 ARG_PREFIX,
                 ARG_EXCLUDE_PREFIX,
         };
@@ -1295,6 +1306,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "create",         no_argument,         NULL, ARG_CREATE         },
                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
+                { "unsafe",         no_argument,         NULL, ARG_UNSAFE         },
                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
                 {}
@@ -1329,6 +1341,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_remove = true;
                         break;
 
+                case ARG_UNSAFE:
+                        arg_unsafe = true;
+                        break;
+
                 case ARG_PREFIX:
                         if (strv_extend(&include_prefixes, optarg) < 0)
                                 return log_oom();
index 3fff347db4e887d18f6e9ca851f6e7e707462540..a1656873da5b955c1072e75ba87b22792014920b 100644 (file)
@@ -29,6 +29,6 @@ d /run/lock/lockdev 0775 root lock -
 # kernel command line options 'fsck.mode=force', 'fsck.mode=skip' and
 # 'quotacheck.mode=force'
 
-r /forcefsck
-r /fastboot
-r /forcequotacheck
+r! /forcefsck
+r! /fastboot
+r! /forcequotacheck
diff --git a/tmpfiles.d/systemd-nologin.conf b/tmpfiles.d/systemd-nologin.conf
new file mode 100644 (file)
index 0000000..d61232b
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) and systemd-forbid-user-logins.service(5).
+# This file has special suffix so it is not run by mistake.
+
+F! /run/nologin 0644 - - - "System is booting up. See pam_nologin(8)"
index a05c6577d2363f62b27c1072891eaf4ab02ca7ea..7c6d6b9099b9d1be2919333d13489fe03ea2a573 100644 (file)
@@ -8,7 +8,7 @@
 # See tmpfiles.d(5) for details
 
 d /run/user 0755 root root ~10d
-F /run/utmp 0664 root utmp -
+F! /run/utmp 0664 root utmp -
 
 f /var/log/wtmp 0664 root utmp -
 f /var/log/btmp 0600 root utmp -
@@ -22,8 +22,6 @@ d /run/systemd/users 0755 root root -
 d /run/systemd/machines 0755 root root -
 d /run/systemd/shutdown 0755 root root -
 
-F /run/nologin 0644 - - - "System is booting up. See pam_nologin(8)"
-
 m /var/log/journal 2755 root systemd-journal - -
 m /var/log/journal/%m 2755 root systemd-journal - -
 m /run/log/journal 2755 root systemd-journal - -
index ece6a5ce985b5f13e48195a44800d2065c9167d4..4c96a54a139ffeffe486ff982bbfa937e5f55d7f 100644 (file)
@@ -15,4 +15,4 @@ d /tmp/.font-unix 1777 root root 10d
 d /tmp/.Test-unix 1777 root root 10d
 
 # Unlink the X11 lock files
-r /tmp/.X[0-9]*-lock
+r! /tmp/.X[0-9]*-lock
index 3405e2842ca6d2f3e7ebede2366e396cf15d976f..c2dcae0e135634153b7f6fa0fd936f4965a73636 100644 (file)
@@ -6,7 +6,7 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Recreate Volatile Files and Directories
+Description=Create Volatile Files and Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
 Wants=local-fs.target
@@ -18,8 +18,10 @@ ConditionDirectoryNotEmpty=|/lib/tmpfiles.d
 ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
 ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
 ConditionDirectoryNotEmpty=|/run/tmpfiles.d
+RefuseManualStart=yes
+RefuseManualStop=yes
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --exclude-prefix=/dev
+ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --unsafe --exclude-prefix=/dev