X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fmanager.c;h=a549209ca6481c13bf09e07dd27adb81f083a511;hb=6ef25fb65ee0a62972ed7cbc01b6a11feb5fcb16;hp=cf308ac4d34834c3a52dacac045f1ecc289abec5;hpb=764e9b5f073e1d5216de150045ec85475835fe3c;p=elogind.git diff --git a/src/manager.c b/src/manager.c index cf308ac4d..a549209ca 100644 --- a/src/manager.c +++ b/src/manager.c @@ -41,6 +41,8 @@ #include #endif +#include + #include "manager.h" #include "hashmap.h" #include "macro.h" @@ -58,7 +60,7 @@ #include "special.h" #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 @@ -193,6 +195,7 @@ static int manager_setup_signals(Manager *m) { SIGRTMIN+21, /* systemd: disable status messages */ SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */ SIGRTMIN+23, /* systemd: set log level to LOG_INFO */ + SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */ SIGRTMIN+27, /* systemd: set log target to console */ SIGRTMIN+28, /* systemd: set log target to kmsg */ SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */ @@ -230,7 +233,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 +288,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 +1219,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; } } @@ -1600,7 +1611,9 @@ static int transaction_add_job_and_dependencies( dbus_error_free(e); } - } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { + } + + if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i) if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { @@ -1623,6 +1636,20 @@ static int transaction_add_job_and_dependencies( } } + if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) { + + SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO], i) { + r = transaction_add_job_and_dependencies(m, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL); + + if (r < 0) { + log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + } + /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ } @@ -2023,7 +2050,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 +2135,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) { @@ -2267,6 +2294,11 @@ static int manager_process_signal_fd(Manager *m) { log_notice("Setting log level to info."); break; + case 26: + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_notice("Setting log target to journal-or-kmsg."); + break; + case 27: log_set_target(LOG_TARGET_CONSOLE); log_notice("Setting log target to console."); @@ -2283,7 +2315,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)); } } } @@ -3095,7 +3127,7 @@ int manager_set_default_controllers(Manager *m, char **controllers) { return 0; } -void manager_recheck_syslog(Manager *m) { +void manager_recheck_journal(Manager *m) { Unit *u; assert(m); @@ -3103,36 +3135,20 @@ void manager_recheck_syslog(Manager *m) { if (m->running_as != MANAGER_SYSTEM) return; - if ((u = manager_get_unit(m, SPECIAL_SYSLOG_SOCKET))) { - SocketState state; - - state = SOCKET(u)->state; - - if (state != SOCKET_DEAD && - state != SOCKET_FAILED && - state != SOCKET_RUNNING) { - - /* Hmm, the socket is not set up, or is still - * listening, let's better not try to use - * it. Note that we have no problem if the - * socket is completely down, since there - * might be a foreign /dev/log socket around - * and we want to make use of that. - */ - - log_close_syslog(); - return; - } + u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); + if (u && SOCKET(u)->state != SOCKET_RUNNING) { + log_close_journal(); + return; } - if ((u = manager_get_unit(m, SPECIAL_SYSLOG_TARGET))) - if (TARGET(u)->state != TARGET_ACTIVE) { - log_close_syslog(); - return; - } + u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); + if (u && SERVICE(u)->state != SERVICE_RUNNING) { + log_close_journal(); + return; + } - /* Hmm, OK, so the socket is either fully up, or fully down, - * and the target is up, then let's make use of the socket */ + /* Hmm, OK, so the socket is fully up and the service is up + * too, then let's make use of the thing. */ log_open(); }