From 0e456f978134100d2e0cc28c7205b3abefcc9cde Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 10 Apr 2011 01:30:14 +0200 Subject: [PATCH] path: optionally, create watched directories in .path units --- TODO | 6 ++-- man/systemd.path.xml | 22 +++++++++++++ src/dbus-path.c | 8 +++-- src/load-fragment.c | 2 ++ src/mount-setup.c | 1 - src/path.c | 39 ++++++++++++++++++++++-- src/path.h | 3 ++ tmpfiles.d/systemd.conf | 2 ++ units/systemd-ask-password-console.path | 1 + units/systemd-ask-password-plymouth.path | 1 + units/systemd-ask-password-wall.path | 1 + 11 files changed, 77 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 78ceddebb..ce08b8ac8 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 d5495c7cc..e816c3018 100644 --- a/man/systemd.path.xml +++ b/man/systemd.path.xml @@ -168,6 +168,28 @@ identical, except for the suffix. + + MakeDirectory= + + Takes a boolean + argument. If true the directories to + watch are created before + watching. This option is ignored for + PathExists= + settings. Defaults to + . + + + DirectoryMode= + + If + MakeDirectory= is + enabled use the mode specified here to + create the directories in + question. Takes an access mode in + octal notation. Defaults to + . + diff --git a/src/dbus-path.c b/src/dbus-path.c index cb1d4f09c..1e757a306 100644 --- a/src/dbus-path.c +++ b/src/dbus-path.c @@ -29,6 +29,8 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ " \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 c27c9d847..aac27b56e 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 85205832a..663a72fdd 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 f7878b56a..1a3e28f89 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 0dff12033..8ba0ce689 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 2ab8e2bba..5e8ed9991 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 4005a2773..b5acf943b 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 a2aec4412..6a9652092 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 7a883d5af..050b73b2e 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 -- 2.30.2