X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fmanager.c;h=9957bbf12ac56d26b1a64315f4a739c1600e041e;hp=a189479b364253f3a8f07dd5adf0226090653c6f;hb=4bba9156da3e1df2cee24d10d7cd88c776ef4179;hpb=1d6702e8d3877c0bebf3ac817dc45ff72f5ecfa9 diff --git a/src/manager.c b/src/manager.c index a189479b3..9957bbf12 100644 --- a/src/manager.c +++ b/src/manager.c @@ -59,6 +59,7 @@ #include "bus-errors.h" #include "exit-status.h" #include "sd-daemon.h" +#include "virt.h" /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */ #define GC_QUEUE_ENTRIES_MAX 16 @@ -230,7 +231,7 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { dual_timestamp_get(&m->startup_timestamp); m->running_as = running_as; - m->name_data_slot = m->subscribed_data_slot = -1; + m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1; m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->pin_cgroupfs_fd = -1; @@ -285,7 +286,10 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { goto fail; #ifdef HAVE_AUDIT - if ((m->audit_fd = audit_open()) < 0) + if ((m->audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error("Failed to connect to audit log: %m"); #endif @@ -1213,13 +1217,18 @@ static int transaction_apply(Manager *m, JobMode mode) { /* When isolating first kill all installed jobs which * aren't part of the new transaction */ + rescan: HASHMAP_FOREACH(j, m->jobs, i) { assert(j->installed); if (hashmap_get(m->transaction_jobs, j->unit)) continue; - job_finish_and_invalidate(j, JOB_CANCELED); + /* 'j' itself is safe to remove, but if other jobs + are invalidated recursively, our iterator may become + invalid and we need to start over. */ + if (job_finish_and_invalidate(j, JOB_CANCELED) > 0) + goto rescan; } } @@ -2023,7 +2032,7 @@ static int manager_dispatch_sigchld(Manager *m) { if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) { char *name = NULL; - get_process_name(si.si_pid, &name); + get_process_comm(si.si_pid, &name); log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name)); free(name); } @@ -2108,14 +2117,14 @@ static int manager_process_signal_fd(Manager *m) { if (sfsi.ssi_pid > 0) { char *p = NULL; - get_process_name(sfsi.ssi_pid, &p); + get_process_comm(sfsi.ssi_pid, &p); log_debug("Received SIG%s from PID %lu (%s).", - strna(signal_to_string(sfsi.ssi_signo)), + signal_to_string(sfsi.ssi_signo), (unsigned long) sfsi.ssi_pid, strna(p)); free(p); } else - log_debug("Received SIG%s.", strna(signal_to_string(sfsi.ssi_signo))); + log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo)); switch (sfsi.ssi_signo) { @@ -2233,8 +2242,9 @@ static int manager_process_signal_fd(Manager *m) { if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { - manager_start_target(m, target_table[sfsi.ssi_signo - SIGRTMIN], - (sfsi.ssi_signo == 1 || sfsi.ssi_signo == 2) ? JOB_ISOLATE : JOB_REPLACE); + int idx = (int) sfsi.ssi_signo - SIGRTMIN; + manager_start_target(m, target_table[idx], + (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE); break; } @@ -2248,12 +2258,12 @@ static int manager_process_signal_fd(Manager *m) { case 20: log_debug("Enabling showing of status."); - m->show_status = true; + manager_set_show_status(m, true); break; case 21: log_debug("Disabling showing of status."); - m->show_status = false; + manager_set_show_status(m, false); break; case 22: @@ -2282,7 +2292,7 @@ static int manager_process_signal_fd(Manager *m) { break; default: - log_warning("Got unhandled signal <%s>.", strna(signal_to_string(sfsi.ssi_signo))); + log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo)); } } } @@ -2904,7 +2914,8 @@ bool manager_is_booting_or_shutting_down(Manager *m) { return true; /* Is there a job for the shutdown target? */ - if (((u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET)))) + u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET); + if (u) return !!u->meta.job; return false; @@ -3073,7 +3084,7 @@ void manager_undo_generators(Manager *m) { return; strv_remove(m->lookup_paths.unit_path, m->generator_unit_path); - rm_rf(m->generator_unit_path, false, true); + rm_rf(m->generator_unit_path, false, true, false); free(m->generator_unit_path); m->generator_unit_path = NULL; @@ -3134,6 +3145,35 @@ void manager_recheck_syslog(Manager *m) { log_open(); } +void manager_set_show_status(Manager *m, bool b) { + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return; + + m->show_status = b; + + if (b) + touch("/run/systemd/show-status"); + else + unlink("/run/systemd/show-status"); +} + +bool manager_get_show_status(Manager *m) { + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return false; + + if (m->show_status) + return true; + + /* If Plymouth is running make sure we show the status, so + * that there's something nice to see when people press Esc */ + + return plymouth_running(); +} + static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = { [MANAGER_SYSTEM] = "system", [MANAGER_USER] = "user"