return buf;
}
+void manager_ref_console(Manager *m) {
+ assert(m);
+
+ m->n_on_console++;
+}
+
+void manager_unref_console(Manager *m) {
+
+ assert(m->n_on_console > 0);
+ m->n_on_console--;
+
+ if (m->n_on_console == 0)
+ m->no_console_output = false; /* unset no_console_output flag, since the console is definitely free now */
+}
+
static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
[MANAGER_INITIALIZING] = "initializing",
[MANAGER_STARTING] = "starting",
char *manager_taint_string(Manager *m);
+void manager_ref_console(Manager *m);
+void manager_unref_console(Manager *m);
+
const char *manager_state_to_string(ManagerState m) _const_;
ManagerState manager_state_from_string(const char *s) _pure_;
if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(UNIT(s)->manager))
unit_prune_cgroup(UNIT(s));
- /* For remain_after_exit services, let's see if we can "release" the
- * hold on the console, since unit_notify() only does that in case of
- * change of state */
- if (state == SERVICE_EXITED &&
- s->remain_after_exit &&
- UNIT(s)->manager->n_on_console > 0) {
-
- ExecContext *ec;
-
- ec = unit_get_exec_context(UNIT(s));
- if (ec && exec_context_may_touch_console(ec)) {
- Manager *m = UNIT(s)->manager;
-
- m->n_on_console--;
- if (m->n_on_console == 0)
- /* unset no_console_output flag, since the console is free */
- m->no_console_output = false;
- }
- }
-
if (old_state != state)
log_unit_debug(UNIT(s), "Changed %s -> %s", service_state_to_string(old_state), service_state_to_string(state));
if (u->in_cgroup_empty_queue)
LIST_REMOVE(cgroup_empty_queue, u->manager->cgroup_empty_queue, u);
+ if (u->on_console)
+ manager_unref_console(u->manager);
+
unit_release_cgroup(u);
if (!MANAGER_IS_RELOADING(u->manager))
}
+static void unit_update_on_console(Unit *u) {
+ bool b;
+
+ assert(u);
+
+ b = unit_needs_console(u);
+ if (u->on_console == b)
+ return;
+
+ u->on_console = b;
+ if (b)
+ manager_ref_console(u->manager);
+ else
+ manager_unref_console(u->manager);
+
+}
+
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
Manager *m;
bool unexpected;
unit_unlink_state_files(u);
}
- /* Note that this doesn't apply to RemainAfterExit services exiting
- * successfully, since there's no change of state in that case. Which is
- * why it is handled in service_set_state() */
- if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
- ExecContext *ec;
-
- ec = unit_get_exec_context(u);
- if (ec && exec_context_may_touch_console(ec)) {
- if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
- m->n_on_console--;
-
- if (m->n_on_console == 0)
- /* unset no_console_output flag, since the console is free */
- m->no_console_output = false;
- } else
- m->n_on_console++;
- }
- }
+ unit_update_on_console(u);
if (u->job) {
unexpected = false;
bool sent_dbus_new_signal:1;
bool in_audit:1;
+ bool on_console:1;
bool cgroup_realized:1;
bool cgroup_members_mask_valid:1;