chiark / gitweb /
cgroup: Handle error when destroying cgroup
[elogind.git] / src / core / unit.c
index 66f53ddc7c61012c9a59dbdb2206f964f14766b4..7daf170e29416245046c299f77d2ef99503259c2 100644 (file)
@@ -92,6 +92,7 @@ Unit *unit_new(Manager *m, size_t size) {
         u->deserialized_job = _JOB_TYPE_INVALID;
         u->default_dependencies = true;
         u->unit_file_state = _UNIT_FILE_STATE_INVALID;
+        u->unit_file_preset = -1;
         u->on_failure_job_mode = JOB_REPLACE;
 
         return u;
@@ -1218,7 +1219,7 @@ int unit_load(Unit *u) {
                         goto fail;
 
                 if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
-                        log_error_unit(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
+                        log_unit_error(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
                         r = -EINVAL;
                         goto fail;
                 }
@@ -1239,17 +1240,64 @@ fail:
         unit_add_to_dbus_queue(u);
         unit_add_to_gc_queue(u);
 
-        log_debug_unit(u->id, "Failed to load configuration for %s: %s",
+        log_unit_debug(u->id, "Failed to load configuration for %s: %s",
                        u->id, strerror(-r));
 
         return r;
 }
 
+static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to_string)(ConditionType t)) {
+        Condition *c;
+        int triggered = -1;
+
+        assert(u);
+        assert(to_string);
+
+        /* If the condition list is empty, then it is true */
+        if (!first)
+                return true;
+
+        /* Otherwise, if all of the non-trigger conditions apply and
+         * if any of the trigger conditions apply (unless there are
+         * none) we return true */
+        LIST_FOREACH(conditions, c, first) {
+                int r;
+
+                r = condition_test(c);
+                if (r < 0)
+                        log_unit_warning(u->id,
+                                         "Couldn't determine result for %s=%s%s%s for %s, assuming failed: %s",
+                                         to_string(c->type),
+                                         c->trigger ? "|" : "",
+                                         c->negate ? "!" : "",
+                                         c->parameter,
+                                         u->id,
+                                         strerror(-r));
+                else
+                        log_unit_debug(u->id,
+                                       "%s=%s%s%s %s for %s.",
+                                       to_string(c->type),
+                                       c->trigger ? "|" : "",
+                                       c->negate ? "!" : "",
+                                       c->parameter,
+                                       condition_result_to_string(c->result),
+                                       u->id);
+
+                if (!c->trigger && r <= 0)
+                        return false;
+
+                if (c->trigger && triggered <= 0)
+                        triggered = r > 0;
+        }
+
+        return triggered != 0;
+}
+
 static bool unit_condition_test(Unit *u) {
         assert(u);
 
         dual_timestamp_get(&u->condition_timestamp);
-        u->condition_result = condition_test_list(u->id, u->conditions, condition_type_to_string);
+        u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string);
 
         return u->condition_result;
 }
@@ -1258,7 +1306,7 @@ static bool unit_assert_test(Unit *u) {
         assert(u);
 
         dual_timestamp_get(&u->assert_timestamp);
-        u->assert_result = condition_test_list(u->id, u->asserts, assert_type_to_string);
+        u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string);
 
         return u->assert_result;
 }
@@ -1347,10 +1395,10 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
               t == JOB_STOP  ? SD_MESSAGE_UNIT_STOPPING :
                                SD_MESSAGE_UNIT_RELOADING;
 
-        log_struct_unit(LOG_INFO,
-                        u->id,
-                        MESSAGE_ID(mid),
-                        "MESSAGE=%s", buf,
+        log_unit_struct(u->id,
+                        LOG_INFO,
+                        LOG_MESSAGE_ID(mid),
+                        LOG_MESSAGE("%s", buf),
                         NULL);
 }
 
@@ -1384,21 +1432,21 @@ int unit_start(Unit *u) {
          * but we don't want to recheck the condition in that case. */
         if (state != UNIT_ACTIVATING &&
             !unit_condition_test(u)) {
-                log_debug_unit(u->id, "Starting of %s requested but condition failed. Not starting unit.", u->id);
+                log_unit_debug(u->id, "Starting of %s requested but condition failed. Not starting unit.", u->id);
                 return -EALREADY;
         }
 
         /* If the asserts failed, fail the entire job */
         if (state != UNIT_ACTIVATING &&
             !unit_assert_test(u)) {
-                log_debug_unit(u->id, "Starting of %s requested but asserts failed.", u->id);
+                log_unit_debug(u->id, "Starting of %s requested but asserts failed.", u->id);
                 return -EPROTO;
         }
 
         /* Forward to the main object, if we aren't it. */
         following = unit_following(u);
         if (following) {
-                log_debug_unit(u->id, "Redirecting start request from %s to %s.", u->id, following->id);
+                log_unit_debug(u->id, "Redirecting start request from %s to %s.", u->id, following->id);
                 return unit_start(following);
         }
 
@@ -1449,7 +1497,7 @@ int unit_stop(Unit *u) {
                 return -EALREADY;
 
         if ((following = unit_following(u))) {
-                log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
+                log_unit_debug(u->id, "Redirecting stop request from %s to %s.",
                                u->id, following->id);
                 return unit_stop(following);
         }
@@ -1487,14 +1535,14 @@ int unit_reload(Unit *u) {
                 return -EALREADY;
 
         if (state != UNIT_ACTIVE) {
-                log_warning_unit(u->id, "Unit %s cannot be reloaded because it is inactive.",
+                log_unit_warning(u->id, "Unit %s cannot be reloaded because it is inactive.",
                                  u->id);
                 return -ENOEXEC;
         }
 
         following = unit_following(u);
         if (following) {
-                log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
+                log_unit_debug(u->id, "Redirecting reload request from %s to %s.",
                                u->id, following->id);
                 return unit_reload(following);
         }
@@ -1548,7 +1596,7 @@ static void unit_check_unneeded(Unit *u) {
                 if (unit_active_or_pending(other))
                         return;
 
-        log_info_unit(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
+        log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
 
         /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
         manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
@@ -1580,7 +1628,7 @@ static void unit_check_binds_to(Unit *u) {
         if (!stop)
                 return;
 
-        log_info_unit(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
+        log_unit_info(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
 
         /* A unit we need to run is gone. Sniff. Let's stop this. */
         manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
@@ -1672,14 +1720,14 @@ void unit_start_on_failure(Unit *u) {
         if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
                 return;
 
-        log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
+        log_unit_info(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
 
         SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
                 int r;
 
                 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
                 if (r < 0)
-                        log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
+                        log_unit_error_errno(u->id, r, "Failed to enqueue OnFailure= job: %m");
         }
 }
 
@@ -1843,7 +1891,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                         check_unneeded_dependencies(u);
 
                 if (ns != os && ns == UNIT_FAILED) {
-                        log_notice_unit(u->id, "Unit %s entered failed state.", u->id);
+                        log_unit_notice(u->id, "Unit %s entered failed state.", u->id);
                         unit_start_on_failure(u);
                 }
         }
@@ -2105,10 +2153,10 @@ static int maybe_warn_about_dependency(const char *id, const char *other, UnitDe
         case UNIT_TRIGGERS:
         case UNIT_TRIGGERED_BY:
                 if (streq_ptr(id, other))
-                        log_warning_unit(id, "Dependency %s=%s dropped from unit %s",
+                        log_unit_warning(id, "Dependency %s=%s dropped from unit %s",
                                          unit_dependency_to_string(dependency), id, other);
                 else
-                        log_warning_unit(id, "Dependency %s=%s dropped from unit %s merged into %s",
+                        log_unit_warning(id, "Dependency %s=%s dropped from unit %s merged into %s",
                                          unit_dependency_to_string(dependency), id,
                                          strna(other), id);
                 return -EINVAL;
@@ -3043,6 +3091,17 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
         return u->unit_file_state;
 }
 
+int unit_get_unit_file_preset(Unit *u) {
+        assert(u);
+
+        if (u->unit_file_preset < 0 && u->fragment_path)
+                u->unit_file_preset = unit_file_query_preset(
+                                u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
+                                NULL, basename(u->fragment_path));
+
+        return u->unit_file_preset;
+}
+
 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
         assert(ref);
         assert(u);
@@ -3388,7 +3447,7 @@ int unit_kill_context(
                         _cleanup_free_ char *comm = NULL;
                         get_process_comm(main_pid, &comm);
 
-                        log_warning_unit(u->id, "Failed to kill main process " PID_FMT " (%s): %s", main_pid, strna(comm), strerror(-r));
+                        log_unit_warning_errno(u->id, r, "Failed to kill main process " PID_FMT " (%s): %m", main_pid, strna(comm));
                 } else {
                         if (!main_pid_alien)
                                 wait_for_exit = true;
@@ -3405,7 +3464,7 @@ int unit_kill_context(
                         _cleanup_free_ char *comm = NULL;
                         get_process_comm(control_pid, &comm);
 
-                        log_warning_unit(u->id, "Failed to kill control process " PID_FMT " (%s): %s", control_pid, strna(comm), strerror(-r));
+                        log_unit_warning_errno(u->id, r, "Failed to kill control process " PID_FMT " (%s): %m", control_pid, strna(comm));
                 } else {
                         wait_for_exit = true;
 
@@ -3425,7 +3484,7 @@ int unit_kill_context(
                 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
                 if (r < 0) {
                         if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
-                                log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
+                                log_unit_warning_errno(u->id, r, "Failed to kill control group: %m");
                 } else if (r > 0) {
 
                         /* FIXME: For now, we will not wait for the