]> err.no Git - systemd/commitdiff
path: optionally, create watched directories in .path units
authorLennart Poettering <lennart@poettering.net>
Sat, 9 Apr 2011 23:30:14 +0000 (01:30 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 9 Apr 2011 23:30:14 +0000 (01:30 +0200)
TODO
man/systemd.path.xml
src/dbus-path.c
src/load-fragment.c
src/mount-setup.c
src/path.c
src/path.h
tmpfiles.d/systemd.conf
units/systemd-ask-password-console.path
units/systemd-ask-password-plymouth.path
units/systemd-ask-password-wall.path

diff --git a/TODO b/TODO
index 78ceddebbccd34edfa9ac1969496fc97cd5a670a..ce08b8ac8f52e33f4675b7111f59e303ea5349f3 100644 (file)
--- a/TODO
+++ b/TODO
@@ -13,14 +13,14 @@ F15:
 
 * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target
 
-* hook emergency.target into local-fs.target in some way as OnFailure with isolate, add warning log message
-
 * bind mounts are ignored
   https://bugzilla.redhat.com/show_bug.cgi?id=682662
 
 * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown
     (path: after installing inotify watches, recheck file again to fix race)
 
+* be nice to ingo
+
 Features:
 
 * fix alsa mixer restore to not print error when no config is stored
@@ -95,8 +95,6 @@ Features:
   about policy loading. Probably check for available selinux in /proc/filesystems,
   and check for active selinux with getcon_raw() == "kernel"
 
-* optionally create watched directories in .path units
-
 * Support --test based on current system state
 
 * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled"
index d5495c7cc39222ae04a2ed68cfaf91e6b30b69a0..e816c3018c13430b2bd2332defb5c4ddfa03c254 100644 (file)
                                 identical, except for the
                                 suffix.</para></listitem>
                         </varlistentry>
+                        <varlistentry>
+                                <term><varname>MakeDirectory=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true the directories to
+                                watch are created before
+                                watching. This option is ignored for
+                                <varname>PathExists=</varname>
+                                settings. Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+
+                                <listitem><para>If
+                                <varname>MakeDirectory=</varname> is
+                                enabled use the mode specified here to
+                                create the directories in
+                                question. Takes an access mode in
+                                octal notation. Defaults to
+                                <option>0755</option>.</para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
index cb1d4f09cb0694f4ef47bfa794bb1c9db66e0fe3..1e757a30603e37559795f0dbf2680a77cbd220c6 100644 (file)
@@ -29,6 +29,8 @@
         " <interface name=\"org.freedesktop.systemd1.Path\">\n"         \
         "  <property name=\"Unit\" type=\"s\" access=\"read\"/>\n"      \
         "  <property name=\"Paths\" type=\"a(ss)\" access=\"read\"/>\n" \
+        "  <property name=\"MakeDirectory\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
         " </interface>\n"
 
 #define INTROSPECTION                                                   \
@@ -93,8 +95,10 @@ static int bus_path_append_unit(Manager *m, DBusMessageIter *i, const char *prop
 DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
         const BusProperty properties[] = {
                 BUS_UNIT_PROPERTIES,
-                { "org.freedesktop.systemd1.Path", "Unit",  bus_path_append_unit,       "s",     u                      },
-                { "org.freedesktop.systemd1.Path", "Paths", bus_path_append_paths,      "a(ss)", u                      },
+                { "org.freedesktop.systemd1.Path", "Unit",          bus_path_append_unit,     "s",     u                        },
+                { "org.freedesktop.systemd1.Path", "Paths",         bus_path_append_paths,    "a(ss)", u                        },
+                { "org.freedesktop.systemd1.Path", "MakeDirectory", bus_property_append_bool, "b",     &u->path.make_directory  },
+                { "org.freedesktop.systemd1.Path", "DirectoryMode", bus_property_append_mode, "u",     &u->path.directory_mode  },
                 { NULL, NULL, NULL, NULL, NULL }
         };
 
index c27c9d84777fa0bcae57688ac8980d746d6b854e..aac27b56ed7088b4b0fd340dc01e8726be32398d 100644 (file)
@@ -1944,6 +1944,8 @@ static int load_from_path(Unit *u, const char *path) {
                 { "PathChanged",            config_parse_path_spec,       0, &u->path,                                        "Path"    },
                 { "DirectoryNotEmpty",      config_parse_path_spec,       0, &u->path,                                        "Path"    },
                 { "Unit",                   config_parse_path_unit,       0, &u->path,                                        "Path"    },
+                { "MakeDirectory",          config_parse_bool,            0, &u->path.make_directory,                         "Path"    },
+                { "DirectoryMode",          config_parse_mode,            0, &u->path.directory_mode,                         "Path"    },
 
                 /* The [Install] section is ignored here. */
                 { "Alias",                  NULL,                         0, NULL,                                            "Install" },
index 85205832a988e41efa9e17f48c19348784bc8f93..663a72fdd7e9999952d266ee06e0d840638c75d9 100644 (file)
@@ -260,7 +260,6 @@ int mount_setup(void) {
 
         /* Create a few directories we always want around */
         mkdir("/run/systemd", 0755);
-        mkdir("/run/systemd/ask-password", 0755);
 
         return mount_cgroup_controllers();
 }
index f7878b56ae0cb9ca55d2f844219f8a9cce447847..1a3e28f89f33fc962f271a29c63bfb509e977546 100644 (file)
@@ -39,6 +39,15 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
         [PATH_FAILED] = UNIT_FAILED
 };
 
+static void path_init(Unit *u) {
+        Path *p = PATH(u);
+
+        assert(u);
+        assert(u->meta.load_state == UNIT_STUB);
+
+        p->directory_mode = 0755;
+}
+
 static void path_unwatch_one(Path *p, PathSpec *s) {
 
         if (s->inotify_fd < 0)
@@ -169,9 +178,13 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
 
         fprintf(f,
                 "%sPath State: %s\n"
-                "%sUnit: %s\n",
+                "%sUnit: %s\n"
+                "%sMakeDirectory: %s\n"
+                "%sDirectoryMode: %04o\n",
                 prefix, path_state_to_string(p->state),
-                prefix, p->unit->meta.id);
+                prefix, p->unit->meta.id,
+                prefix, yes_no(p->make_directory),
+                prefix, p->directory_mode);
 
         LIST_FOREACH(spec, s, p->specs)
                 fprintf(f,
@@ -408,6 +421,25 @@ fail:
         path_enter_dead(p, false);
 }
 
+static void path_mkdir(Path *p) {
+        PathSpec *s;
+
+        assert(p);
+
+        if (!p->make_directory)
+                return;
+
+        LIST_FOREACH(spec, s, p->specs) {
+                int r;
+
+                if (s->type == PATH_EXISTS)
+                        continue;
+
+                if ((r = mkdir_p(s->path, p->directory_mode)) < 0)
+                        log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
+        }
+}
+
 static int path_start(Unit *u) {
         Path *p = PATH(u);
 
@@ -417,6 +449,8 @@ static int path_start(Unit *u) {
         if (p->unit->meta.load_state != UNIT_LOADED)
                 return -ENOENT;
 
+        path_mkdir(p);
+
         p->failure = false;
         path_enter_waiting(p, true, true, false);
 
@@ -639,6 +673,7 @@ DEFINE_STRING_TABLE_LOOKUP(path_type, PathType);
 const UnitVTable path_vtable = {
         .suffix = ".path",
 
+        .init = path_init,
         .done = path_done,
         .load = path_load,
 
index 0dff1203318fa73a12285550f9f2fd77ec1563d8..8ba0ce6890f380e93cb5f9ae7644d8a3f8754f2f 100644 (file)
@@ -70,6 +70,9 @@ struct Path {
 
         bool failure;
         bool inotify_triggered;
+
+        bool make_directory;
+        mode_t directory_mode;
 };
 
 void path_unit_notify(Unit *u, UnitActiveState new_state);
index 2ab8e2bba5fa07366376ef47df323e74abda493b..5e8ed9991694aeab9ea4b43c584418b2a6fb12d0 100644 (file)
@@ -21,3 +21,5 @@ d /var/cache/man - - - 30d
 r /forcefsck
 r /forcequotacheck
 r /fastboot
+
+d /run/systemd/ask-password 0755 root root -
index 4005a277349dd57c5e40015f6853837c12861086..b5acf943b4c918ce552dd703b6e59ef8cf9fffd9 100644 (file)
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
 
 [Path]
 DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
index a2aec44122bd790dcea48e4ef3c0ce9df8f29840..6a96520921c1185d2abf4ce19e038c68689f48e9 100644 (file)
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
 
 [Path]
 DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
index 7a883d5af87235efeecbc8d0cf4ea5097f4410e7..050b73b2e1ba05a7cf41ec9318f742e5e528072f 100644 (file)
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
 
 [Path]
 DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes