summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/load-fragment.c1
-rw-r--r--src/path.c6
-rw-r--r--src/service.c42
-rw-r--r--src/socket.c16
-rw-r--r--src/special.h2
-rw-r--r--src/target.c42
-rw-r--r--src/timer.c6
-rw-r--r--src/unit.c15
-rw-r--r--src/unit.h9
9 files changed, 123 insertions, 16 deletions
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 49b577fb2f..e5c7ba24ab 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1506,6 +1506,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Unit" },
{ "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" },
{ "OnlyByDependency", config_parse_bool, &u->meta.only_by_dependency, "Unit" },
+ { "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" },
{ "PIDFile", config_parse_path, &u->service.pid_file, "Service" },
{ "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" },
diff --git a/src/path.c b/src/path.c
index 56936fd673..30d946d788 100644
--- a/src/path.c
+++ b/src/path.c
@@ -29,6 +29,7 @@
#include "unit-name.h"
#include "path.h"
#include "dbus-path.h"
+#include "special.h"
static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
[PATH_DEAD] = UNIT_INACTIVE,
@@ -120,6 +121,11 @@ static int path_load(Unit *u) {
if ((r = path_add_mount_links(p)) < 0)
return r;
+
+ /* Path units shouldn't stay around on shutdown */
+ if (p->meta.default_dependencies)
+ if ((r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0)
+ return r;
}
return path_verify(p);
diff --git a/src/service.c b/src/service.c
index cbc9c9551a..04ed684393 100644
--- a/src/service.c
+++ b/src/service.c
@@ -665,20 +665,18 @@ static int service_load_sysv_path(Service *s, const char *path) {
if ((r = sysv_exec_commands(s)) < 0)
goto finish;
- if (!s->sysv_runlevels || chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
+ if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
/* If there a runlevels configured for this service
* but none of the standard ones, then we assume this
* is some special kind of service (which might be
* needed for early boot) and don't create any links
* to it. */
- if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0 ||
- (r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
- goto finish;
+ s->meta.default_dependencies = false;
- } else
/* Don't timeout special services during boot (like fsck) */
s->timeout_usec = 0;
+ }
/* Special setting for all SysV services */
s->type = SERVICE_FORKING;
@@ -827,6 +825,30 @@ static int service_verify(Service *s) {
return 0;
}
+static int service_add_default_dependencies(Service *s) {
+ int r;
+
+ assert(s);
+
+ /* Add a number of automatic dependencies useful for the
+ * majority of services. */
+
+ /* First, pull in base system */
+ if (s->meta.manager->running_as == MANAGER_SYSTEM) {
+
+ if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
+ return r;
+
+ } else if (s->meta.manager->running_as == MANAGER_SESSION) {
+
+ if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0)
+ return r;
+ }
+
+ /* Second, activate normal shutdown */
+ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
static int service_load(Unit *u) {
int r;
Service *s = SERVICE(u);
@@ -867,11 +889,19 @@ static int service_load(Unit *u) {
return r;
if ((r = unit_watch_bus_name(u, s->bus_name)) < 0)
- return r;
+ return r;
}
if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
s->notify_access = NOTIFY_MAIN;
+
+ if (s->type == SERVICE_DBUS || s->bus_name)
+ if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_TARGET, NULL, true)) < 0)
+ return r;
+
+ if (s->meta.default_dependencies)
+ if ((r = service_add_default_dependencies(s)) < 0)
+ return r;
}
return service_verify(s);
diff --git a/src/socket.c b/src/socket.c
index 91eea7d294..03e556c30e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -37,6 +37,7 @@
#include "unit-name.h"
#include "dbus-socket.h"
#include "missing.h"
+#include "special.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
@@ -241,6 +242,17 @@ static int socket_add_device_link(Socket *s) {
return r;
}
+static int socket_add_default_dependencies(Socket *s) {
+ int r;
+ assert(s);
+
+ if (s->meta.manager->running_as == MANAGER_SYSTEM)
+ if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0)
+ return r;
+
+ return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+}
+
static int socket_load(Unit *u) {
Socket *s = SOCKET(u);
int r;
@@ -273,6 +285,10 @@ static int socket_load(Unit *u) {
if ((r = unit_add_default_cgroup(u)) < 0)
return r;
+
+ if (s->meta.default_dependencies)
+ if ((r = socket_add_default_dependencies(s)) < 0)
+ return r;
}
return socket_verify(s);
diff --git a/src/special.h b/src/special.h
index 2d5bc7b89d..8cb500b8ad 100644
--- a/src/special.h
+++ b/src/special.h
@@ -46,7 +46,9 @@
#define SPECIAL_RTC_SET_TARGET "rtc-set.target" /* LSB's $time */
#define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Debian's $x-display-manager */
#define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */
+#define SPECIAL_DBUS_TARGET "dbus.target"
#define SPECIAL_BASIC_TARGET "basic.target"
+#define SPECIAL_SOCKETS_TARGET "sockets.target"
#define SPECIAL_SYSINIT_TARGET "sysinit.target"
#define SPECIAL_RESCUE_TARGET "rescue.target"
#define SPECIAL_EXIT_SERVICE "exit.service"
diff --git a/src/target.c b/src/target.c
index fba99568a3..f8df6fb757 100644
--- a/src/target.c
+++ b/src/target.c
@@ -50,6 +50,46 @@ static void target_set_state(Target *t, TargetState state) {
unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state]);
}
+static int target_add_default_dependencies(Target *t) {
+ Iterator i;
+ Unit *other;
+ int r;
+
+ /* Imply ordering for requirement dependencies
+ * on target units. */
+
+ SET_FOREACH(other, t->meta.dependencies[UNIT_REQUIRES], i)
+ if ((r = unit_add_dependency(UNIT(t), UNIT_AFTER, other, true)) < 0)
+ return r;
+ SET_FOREACH(other, t->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
+ if ((r = unit_add_dependency(UNIT(t), UNIT_AFTER, other, true)) < 0)
+ return r;
+ SET_FOREACH(other, t->meta.dependencies[UNIT_WANTS], i)
+ if ((r = unit_add_dependency(UNIT(t), UNIT_AFTER, other, true)) < 0)
+ return r;
+
+ return 0;
+}
+
+static int target_load(Unit *u) {
+ Target *t = TARGET(u);
+ int r;
+
+ assert(t);
+
+ if ((r = unit_load_fragment_and_dropin(u)) < 0)
+ return r;
+
+ /* This is a new unit? Then let's add in some extras */
+ if (u->meta.load_state == UNIT_LOADED) {
+ if (u->meta.default_dependencies)
+ if ((r = target_add_default_dependencies(t)) < 0)
+ return r;
+ }
+
+ return 0;
+}
+
static int target_coldplug(Unit *u) {
Target *t = TARGET(u);
@@ -177,7 +217,7 @@ DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
const UnitVTable target_vtable = {
.suffix = ".target",
- .load = unit_load_fragment_and_dropin,
+ .load = target_load,
.coldplug = target_coldplug,
.dump = target_dump,
diff --git a/src/timer.c b/src/timer.c
index f0005f55ce..e3c916bb0f 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -25,6 +25,7 @@
#include "unit-name.h"
#include "timer.h"
#include "dbus-timer.h"
+#include "special.h"
static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
[TIMER_DEAD] = UNIT_INACTIVE,
@@ -89,6 +90,11 @@ static int timer_load(Unit *u) {
if ((r = unit_add_dependency(u, UNIT_BEFORE, t->unit, true)) < 0)
return r;
+
+ /* Timers shouldn't stay around on shutdown */
+ if (t->meta.default_dependencies)
+ if ((r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0)
+ return r;
}
return timer_verify(t);
diff --git a/src/unit.c b/src/unit.c
index 8c495b46eb..8f5ae8af3f 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -69,6 +69,7 @@ Unit *unit_new(Manager *m) {
u->meta.manager = m;
u->meta.type = _UNIT_TYPE_INVALID;
u->meta.deserialized_job = _JOB_TYPE_INVALID;
+ u->meta.default_dependencies = true;
return u;
}
@@ -593,8 +594,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
"%s\tActive Enter Timestamp: %s\n"
"%s\tActive Exit Timestamp: %s\n"
"%s\tInactive Enter Timestamp: %s\n"
- "%s\tGC Check Good: %s\n"
- "%s\tOnly By Dependency: %s\n",
+ "%s\tGC Check Good: %s\n",
prefix, u->meta.id,
prefix, unit_description(u),
prefix, strna(u->meta.instance),
@@ -604,8 +604,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->meta.active_enter_timestamp.realtime)),
prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->meta.active_exit_timestamp.realtime)),
prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->meta.inactive_enter_timestamp.realtime)),
- prefix, yes_no(unit_check_gc(u)),
- prefix, yes_no(u->meta.only_by_dependency));
+ prefix, yes_no(unit_check_gc(u)));
SET_FOREACH(t, u->meta.names, i)
fprintf(f, "%s\tName: %s\n", prefix, t);
@@ -623,9 +622,13 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
if (u->meta.load_state == UNIT_LOADED) {
fprintf(f,
"%s\tRecursive Stop: %s\n"
- "%s\tStop When Unneeded: %s\n",
+ "%s\tStopWhenUnneeded: %s\n"
+ "%s\tOnlyByDependency: %s\n"
+ "%s\tDefaultDependencies: %s\n",
prefix, yes_no(u->meta.recursive_stop),
- prefix, yes_no(u->meta.stop_when_unneeded));
+ prefix, yes_no(u->meta.stop_when_unneeded),
+ prefix, yes_no(u->meta.only_by_dependency),
+ prefix, yes_no(u->meta.default_dependencies));
LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings)
fprintf(f, "%s\tControlGroup: %s:%s\n",
diff --git a/src/unit.h b/src/unit.h
index d3dd5decd2..b6351d5541 100644
--- a/src/unit.h
+++ b/src/unit.h
@@ -142,9 +142,6 @@ struct Meta {
UnitLoadState load_state;
Unit *merged_into;
- /* Refuse manual starting, allow starting only indirectly via dependency. */
- bool only_by_dependency;
-
char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
char *instance;
@@ -190,6 +187,12 @@ struct Meta {
/* Garbage collect us we nobody wants or requires us anymore */
bool stop_when_unneeded;
+ /* Refuse manual starting, allow starting only indirectly via dependency. */
+ bool only_by_dependency;
+
+ /* Create default depedencies */
+ bool default_dependencies;
+
/* When deserializing, temporarily store the job type for this
* unit here, if there was a job scheduled */
int deserialized_job; /* This is actually of type JobType */