chiark / gitweb /
socket: fix IPv6 availability detection
[elogind.git] / src / unit.c
index 9fc9be5c79a1810dc940cb3f3147f4ac10464589..0e9325dfa497067f141b4d7004d9f80d6b4114ab 100644 (file)
@@ -375,6 +375,8 @@ void unit_free(Unit *u) {
 
         set_free_free(u->meta.names);
 
+        condition_free_list(u->meta.conditions);
+
         free(u->meta.instance);
         free(u);
 }
@@ -639,6 +641,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
         if (u->meta.job_timeout > 0)
                 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->meta.job_timeout));
 
+        condition_dump_list(u->meta.conditions, f, prefix);
+
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
                 Unit *other;
 
@@ -840,6 +844,12 @@ int unit_start(Unit *u) {
         if (!UNIT_VTABLE(u)->start)
                 return -EBADR;
 
+        /* If the conditions failed, don't do anything at all */
+        if (!condition_test_list(u->meta.conditions)) {
+                log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id);
+                return -EALREADY;
+        }
+
         /* We don't suppress calls to ->start() here when we are
          * already starting, to allow this request to be used as a
          * "hurry up" call, for example when the unit is in some "auto
@@ -1870,6 +1880,16 @@ static char *specifier_instance_unescaped(char specifier, void *data, void *user
         return strdup("");
 }
 
+static char *specifier_filename(char specifier, void *data, void *userdata) {
+        Unit *u = userdata;
+        assert(u);
+
+        if (u->meta.instance)
+                return unit_name_path_unescape(u->meta.instance);
+
+        return unit_name_to_path(u->meta.instance);
+}
+
 char *unit_name_printf(Unit *u, const char* format) {
 
         /*
@@ -1908,6 +1928,7 @@ char *unit_full_printf(Unit *u, const char *format) {
                 { 'P', specifier_prefix_unescaped,    NULL },
                 { 'i', specifier_string,              u->meta.instance },
                 { 'I', specifier_instance_unescaped,  NULL },
+                { 'f', specifier_filename,            NULL },
                 { 0, NULL, NULL }
         };
 
@@ -1985,6 +2006,11 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
         if (u->meta.job)
                 unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type));
 
+        dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->meta.inactive_exit_timestamp);
+        dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp);
+        dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp);
+        dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp);
+
         /* End marker */
         fputc('\n', f);
         return 0;
@@ -2061,7 +2087,14 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                                 u->meta.deserialized_job = type;
 
                         continue;
-                }
+                } else if (streq(l, "inactive-exit-timestamp"))
+                        dual_timestamp_deserialize(f, v, &u->meta.inactive_exit_timestamp);
+                else if (streq(l, "active-enter-timestamp"))
+                        dual_timestamp_deserialize(f, v, &u->meta.active_enter_timestamp);
+                else if (streq(l, "active-exit-timestamp"))
+                        dual_timestamp_deserialize(f, v, &u->meta.active_exit_timestamp);
+                else if (streq(l, "inactive-enter-timestamp"))
+                        dual_timestamp_deserialize(f, v, &u->meta.inactive_enter_timestamp);
 
                 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
                         return r;
@@ -2231,6 +2264,22 @@ bool unit_name_is_valid(const char *n, bool template_ok) {
         return unit_name_is_valid_no_type(n, template_ok);
 }
 
+int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) {
+        assert(u);
+        assert(w >= 0 && w < _KILL_WHO_MAX);
+        assert(m >= 0 && m < _KILL_MODE_MAX);
+        assert(signo > 0);
+        assert(signo < _NSIG);
+
+        if (m == KILL_NONE)
+                return 0;
+
+        if (!UNIT_VTABLE(u)->kill)
+                return -ENOTSUP;
+
+        return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
+}
+
 static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
         [UNIT_STUB] = "stub",
         [UNIT_LOADED] = "loaded",
@@ -2271,12 +2320,3 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
-
-static const char* const kill_mode_table[_KILL_MODE_MAX] = {
-        [KILL_CONTROL_GROUP] = "control-group",
-        [KILL_PROCESS_GROUP] = "process-group",
-        [KILL_PROCESS] = "process",
-        [KILL_NONE] = "none"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode);