summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rw-r--r--man/systemd.path.xml22
-rw-r--r--src/dbus-path.c8
-rw-r--r--src/load-fragment.c2
-rw-r--r--src/mount-setup.c1
-rw-r--r--src/path.c39
-rw-r--r--src/path.h3
-rw-r--r--tmpfiles.d/systemd.conf2
-rw-r--r--units/systemd-ask-password-console.path1
-rw-r--r--units/systemd-ask-password-plymouth.path1
-rw-r--r--units/systemd-ask-password-wall.path1
11 files changed, 77 insertions, 9 deletions
diff --git a/TODO b/TODO
index 78ceddebbc..ce08b8ac8f 100644
--- 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"
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index d5495c7cc3..e816c3018c 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -168,6 +168,28 @@
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>
diff --git a/src/dbus-path.c b/src/dbus-path.c
index cb1d4f09cb..1e757a3060 100644
--- a/src/dbus-path.c
+++ b/src/dbus-path.c
@@ -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 }
};
diff --git a/src/load-fragment.c b/src/load-fragment.c
index c27c9d8477..aac27b56ed 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -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" },
diff --git a/src/mount-setup.c b/src/mount-setup.c
index 85205832a9..663a72fdd7 100644
--- a/src/mount-setup.c
+++ b/src/mount-setup.c
@@ -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();
}
diff --git a/src/path.c b/src/path.c
index f7878b56ae..1a3e28f89f 100644
--- a/src/path.c
+++ b/src/path.c
@@ -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,
diff --git a/src/path.h b/src/path.h
index 0dff120331..8ba0ce6890 100644
--- a/src/path.h
+++ b/src/path.h
@@ -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);
diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf
index 2ab8e2bba5..5e8ed99916 100644
--- a/tmpfiles.d/systemd.conf
+++ b/tmpfiles.d/systemd.conf
@@ -21,3 +21,5 @@ d /var/cache/man - - - 30d
r /forcefsck
r /forcequotacheck
r /fastboot
+
+d /run/systemd/ask-password 0755 root root -
diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path
index 4005a27734..b5acf943b4 100644
--- a/units/systemd-ask-password-console.path
+++ b/units/systemd-ask-password-console.path
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
[Path]
DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
diff --git a/units/systemd-ask-password-plymouth.path b/units/systemd-ask-password-plymouth.path
index a2aec44122..6a96520921 100644
--- a/units/systemd-ask-password-plymouth.path
+++ b/units/systemd-ask-password-plymouth.path
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
[Path]
DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path
index 7a883d5af8..050b73b2e1 100644
--- a/units/systemd-ask-password-wall.path
+++ b/units/systemd-ask-password-wall.path
@@ -13,3 +13,4 @@ Before=basic.target shutdown.target
[Path]
DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes