chiark / gitweb /
unit: trim cgroups when going down
[elogind.git] / src / unit.c
index 8f5ae8af3f8610ce10abdea7c8a85c853baaf141..18faae22e47c48b98bcbb9918e26014f354c1400 100644 (file)
@@ -282,7 +282,8 @@ void unit_add_to_dbus_queue(Unit *u) {
         if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue)
                 return;
 
-        if (set_isempty(u->meta.manager->subscribed)) {
+        /* Shortcut things if nobody cares */
+        if (!bus_has_subscriber(u->meta.manager)) {
                 u->meta.sent_dbus_new_signal = true;
                 return;
         }
@@ -737,7 +738,7 @@ fail:
         u->meta.load_state = UNIT_FAILED;
         unit_add_to_dbus_queue(u);
 
-        log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));
+        log_notice("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));
 
         return r;
 }
@@ -775,6 +776,9 @@ int unit_start(Unit *u) {
          * before it will start again. */
 
         unit_add_to_dbus_queue(u);
+
+        unit_status_printf(u, "Starting %s...\n", unit_description(u));
+
         return UNIT_VTABLE(u)->start(u);
 }
 
@@ -802,6 +806,9 @@ int unit_stop(Unit *u) {
                 return -EBADR;
 
         unit_add_to_dbus_queue(u);
+
+        unit_status_printf(u, "Stopping %s...\n", unit_description(u));
+
         return UNIT_VTABLE(u)->stop(u);
 }
 
@@ -871,10 +878,10 @@ static void unit_check_uneeded(Unit *u) {
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         return;
 
-        log_debug("Service %s is not needed anymore. Stopping.", u->meta.id);
+        log_info("Service %s is not needed anymore. Stopping.", u->meta.id);
 
         /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
-        manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL);
+        manager_add_job(u->meta.manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
 }
 
 static void retroactively_start_dependencies(Unit *u) {
@@ -886,23 +893,23 @@ static void retroactively_start_dependencies(Unit *u) {
 
         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
                 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
-                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
 
         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
                 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
-                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
 
         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
                 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
-                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
 
         SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
                 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
-                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
 
         SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i)
                 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
-                        manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
+                        manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
 }
 
 static void retroactively_stop_dependencies(Unit *u) {
@@ -916,7 +923,7 @@ static void retroactively_stop_dependencies(Unit *u) {
                 /* Pull down units need us recursively if enabled */
                 SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
                         if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
-                                manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
+                                manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
         }
 
         /* Garbage collect services that might not be needed anymore, if enabled */
@@ -938,7 +945,6 @@ static void retroactively_stop_dependencies(Unit *u) {
 }
 
 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
-        bool unexpected = false;
         dual_timestamp ts;
 
         assert(u);
@@ -964,10 +970,17 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
         else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
                 u->meta.active_exit_timestamp = ts;
 
+        if (ns != os && ns == UNIT_MAINTENANCE)
+                log_notice("Unit %s entered maintenance state.", u->meta.id);
+
+        if (UNIT_IS_INACTIVE_OR_MAINTENANCE(ns))
+                cgroup_bonding_trim_list(u->meta.cgroup_bondings, true);
+
         timer_unit_notify(u, ns);
         path_unit_notify(u, ns);
 
         if (u->meta.job) {
+                bool unexpected = false;
 
                 if (u->meta.job->state == JOB_WAITING)
 
@@ -1013,10 +1026,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
                 case JOB_RESTART:
                 case JOB_TRY_RESTART:
 
-                        if (ns == UNIT_INACTIVE)
+                        if (ns == UNIT_INACTIVE || ns == UNIT_MAINTENANCE)
                                 job_finish_and_invalidate(u->meta.job, true);
-                        else if (ns == UNIT_MAINTENANCE)
-                                job_finish_and_invalidate(u->meta.job, false);
                         else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
                                 unexpected = true;
                                 job_finish_and_invalidate(u->meta.job, false);
@@ -1027,16 +1038,17 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
                 default:
                         assert_not_reached("Job type unknown");
                 }
-        }
 
-        /* If this state change happened without being requested by a
-         * job, then let's retroactively start or stop dependencies */
+                /* If this state change happened without being
+                 * requested by a job, then let's retroactively start
+                 * or stop dependencies */
 
-        if (unexpected) {
-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
-                        retroactively_start_dependencies(u);
-                else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
-                        retroactively_stop_dependencies(u);
+                if (unexpected) {
+                        if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
+                                retroactively_start_dependencies(u);
+                        else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
+                                retroactively_stop_dependencies(u);
+                }
         }
 
         /* Some names are special */
@@ -1385,7 +1397,7 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, con
         if (!(name = resolve_template(u, name, path, &s)))
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
+        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
                 goto finish;
 
         r = unit_add_dependency(u, d, other, add_reference);
@@ -1406,7 +1418,7 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency
         if (!(name = resolve_template(u, name, path, &s)))
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
+        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
                 goto finish;
 
         r = unit_add_two_dependencies(u, d, e, other, add_reference);
@@ -1427,7 +1439,7 @@ int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *n
         if (!(name = resolve_template(u, name, path, &s)))
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
+        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
                 goto finish;
 
         r = unit_add_dependency(other, d, u, add_reference);
@@ -1448,7 +1460,7 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep
         if (!(name = resolve_template(u, name, path, &s)))
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->meta.manager, name, path, &other)) < 0)
+        if ((r = manager_load_unit(u->meta.manager, name, path, NULL, &other)) < 0)
                 goto finish;
 
         if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
@@ -1676,7 +1688,7 @@ int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
 
         assert(!unit_has_name(u, t));
 
-        r = manager_load_unit(u->meta.manager, t, NULL, _found);
+        r = manager_load_unit(u->meta.manager, t, NULL, NULL, _found);
         free(t);
 
         assert(r < 0 || *_found != u);
@@ -1961,7 +1973,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
         if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
                 return -ENOMEM;
 
-        r = manager_load_unit(u->meta.manager, e, NULL, &device);
+        r = manager_load_unit(u->meta.manager, e, NULL, NULL, &device);
         free(e);
 
         if (r < 0)
@@ -1987,7 +1999,7 @@ int unit_coldplug(Unit *u) {
                         return r;
 
         if (u->meta.deserialized_job >= 0) {
-                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL)) < 0)
+                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL, NULL)) < 0)
                         return r;
 
                 u->meta.deserialized_job = _JOB_TYPE_INVALID;
@@ -1996,6 +2008,29 @@ int unit_coldplug(Unit *u) {
         return 0;
 }
 
+void unit_status_printf(Unit *u, const char *format, ...) {
+        va_list ap;
+
+        assert(u);
+        assert(format);
+
+        if (!UNIT_VTABLE(u)->show_status)
+                return;
+
+        if (u->meta.manager->running_as != MANAGER_SYSTEM)
+                return;
+
+        if (!u->meta.manager->show_status)
+                return;
+
+        if (!manager_is_booting_or_shutting_down(u->meta.manager))
+                return;
+
+        va_start(ap, format);
+        status_vprintf(format, ap);
+        va_end(ap);
+}
+
 static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = "service",
         [UNIT_TIMER] = "timer",