[systemd-devel] [PATCH] core: add default extra dependency option
WaLyong Cho
walyong.cho at samsung.com
Fri Feb 28 01:02:47 PST 2014
systemd is already provide a special unit. If the type of unit is
service then that is 'basic.target'. Additionally default extra
dependency can be listed in system.conf and then other service unit will
have "After=" dependency implicitly.
In config directory /etc/systemd/default-extra-dependencies, if a
service unit is listed ignore-units or exist symlink in ignore-units.d
then the service units can be launched before extra dependencies.
---
src/core/main.c | 4 +++
src/core/manager.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/core/manager.h | 2 ++
src/core/service.c | 50 +++++++++++++++++++++++++++++
src/core/system.conf | 1 +
5 files changed, 142 insertions(+)
diff --git a/src/core/main.c b/src/core/main.c
index d3581fc..4352138 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -102,6 +102,7 @@ static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
static usec_t arg_runtime_watchdog = 0;
static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
static char **arg_default_environment = NULL;
+static char **arg_default_extra_dependencies = NULL;
static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
static uint64_t arg_capability_bounding_set_drop = 0;
static nsec_t arg_timer_slack_nsec = (nsec_t) -1;
@@ -660,6 +661,7 @@ static int parse_config_file(void) {
{ "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval },
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
{ "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
+ { "Manager", "DefaultExtraDependencies", config_parse_strv, 0, &arg_default_extra_dependencies },
{ "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU] },
{ "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE] },
{ "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA] },
@@ -1611,6 +1613,8 @@ int main(int argc, char *argv[]) {
manager_set_default_rlimits(m, arg_default_rlimit);
manager_environment_add(m, NULL, arg_default_environment);
manager_set_show_status(m, arg_show_status);
+ if (arg_running_as == SYSTEMD_SYSTEM && arg_default_extra_dependencies)
+ manager_set_default_extra_dependencies(m, arg_default_extra_dependencies);
/* Remember whether we should queue the default job */
queue_default_job = !arg_serialization || arg_switched_root;
diff --git a/src/core/manager.c b/src/core/manager.c
index f5801b4..7605777 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -67,6 +67,7 @@
#include "audit-fd.h"
#include "boot-timestamps.h"
#include "env-util.h"
+#include "fileio.c"
#include "bus-errors.h"
#include "bus-error.h"
#include "bus-util.h"
@@ -2720,6 +2721,90 @@ int manager_environment_add(Manager *m, char **minus, char **plus) {
return 0;
}
+int manager_set_default_extra_dependencies(Manager *m, char **dependencies) {
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_closedir_ DIR *dir = NULL;
+ struct dirent *de;
+ char *state, *word, **d = NULL;
+ size_t len;
+ int r = 0;
+
+ assert(m);
+
+ if (strv_extend_strv(&m->dependencies, dependencies) < 0) {
+ strv_free(m->dependencies);
+ return log_oom();
+ }
+
+ if (mkdir("/run/systemd/default-extra-dependencies", 0755) && errno != EEXIST)
+ return -errno;
+
+ f = fopen("/run/systemd/default-extra-dependencies/ignore-units", "we");
+ if (!f)
+ return -errno;
+
+ STRV_FOREACH(d, m->dependencies) {
+ r = write_string_to_file(f, *d);
+ if (r < 0)
+ return r;
+ }
+
+ r = read_full_file(PKGSYSCONFDIR "/default-extra-dependencies/ignore-units",
+ &buf, NULL);
+ if (r < 0)
+ goto dir;
+
+ FOREACH_WORD_SEPARATOR(word, len, buf, NEWLINE, state) {
+ _cleanup_free_ char *copy;
+
+ copy = strndup(word, len);
+ if (!copy)
+ return -ENOMEM;
+
+ if (len <= 0)
+ continue;
+
+ r = write_string_to_file(f, copy);
+ if (r < 0)
+ return r;
+ }
+
+dir:
+ dir = opendir(PKGSYSCONFDIR "/default-extra-dependencies/ignore-units.d");
+ if (!dir)
+ return 0;
+
+ FOREACH_DIRENT(de, dir, return -errno) {
+ _cleanup_free_ char *src = NULL, *dst = NULL;
+
+ if (de->d_type != DT_LNK)
+ continue;
+
+ src = strappend(PKGSYSCONFDIR "/default-extra-dependencies/ignore-units.d/",
+ de->d_name);
+ if (!src) {
+ r = -ENOMEM;
+ return r;
+ }
+
+ r = readlink_and_canonicalize(src, &dst);
+ if (r < 0)
+ continue;
+
+ if (access(dst, F_OK) < 0) {
+ log_debug("Failed to add extra dependency for unit %s, ignoring: %m", dst);
+ continue;
+ }
+
+ r = write_string_to_file(f, basename(dst));
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
int i;
diff --git a/src/core/manager.h b/src/core/manager.h
index 9dee48d..f1a353f 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -125,6 +125,7 @@ struct Manager {
Set *unit_path_cache;
char **environment;
+ char **dependencies;
usec_t runtime_watchdog;
usec_t shutdown_watchdog;
@@ -278,6 +279,7 @@ void manager_clear_jobs(Manager *m);
unsigned manager_dispatch_load_queue(Manager *m);
int manager_environment_add(Manager *m, char **minus, char **plus);
+int manager_set_default_extra_dependencies(Manager *m, char **dependencies);
int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
int manager_loop(Manager *m);
diff --git a/src/core/service.c b/src/core/service.c
index 6de24ec..f38b5ad 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1123,6 +1123,53 @@ static int service_verify(Service *s) {
return 0;
}
+static bool check_ignore_default_extra_dependencies(Service *s) {
+ _cleanup_free_ char *buf = NULL, *p = NULL;
+ _cleanup_closedir_ DIR *dir = NULL;
+ char *state, *word;
+ int r;
+ size_t len;
+
+ r = read_full_file("/run/systemd/default-extra-dependencies/ignore-units",
+ &buf, NULL);
+ if (r < 0)
+ return false;
+
+ FOREACH_WORD_SEPARATOR(word, len, buf, NEWLINE, state) {
+ _cleanup_free_ char *copy;
+
+ copy = strndup(word, len);
+ if (streq(copy, UNIT(s)->id))
+ return true;
+ }
+
+ return false;
+}
+
+static int add_default_extra_dependencies(Service *s) {
+ char **d;
+ int r;
+ bool ignore;
+
+ if (!(UNIT(s)->manager->dependencies))
+ return 0;
+
+ /* Do NOT add dependencies for systemd unit files */
+ if (startswith(UNIT(s)->id, "systemd-"))
+ return 0;
+
+ ignore = check_ignore_default_extra_dependencies(s);
+ if (ignore)
+ return 0;
+
+ STRV_FOREACH(d, UNIT(s)->manager->dependencies) {
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, *d, NULL, true);
+ if (r < 0)
+ return r;
+ }
+ return 0;
+}
+
static int service_add_default_dependencies(Service *s) {
int r;
@@ -1137,6 +1184,9 @@ static int service_add_default_dependencies(Service *s) {
if (r < 0)
return r;
+ r = add_default_extra_dependencies(s);
+ if (r < 0)
+ return r;
/* Second, activate normal shutdown */
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS,
SPECIAL_SHUTDOWN_TARGET, NULL, true);
diff --git a/src/core/system.conf b/src/core/system.conf
index 5be158d..aa7d80a 100644
--- a/src/core/system.conf
+++ b/src/core/system.conf
@@ -31,6 +31,7 @@
#DefaultStartLimitInterval=10s
#DefaultStartLimitBurst=5
#DefaultEnvironment=
+#DefaultExtraDependencies=
#DefaultCPUAccounting=no
#DefaultBlockIOAccounting=no
#DefaultMemoryAccounting=no
--
1.7.9.5
More information about the systemd-devel
mailing list