X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmanager.c;h=7966b387fce0d838a66da1fc5ec8b5c0c147dfec;hb=c43b2132f37264600cc26e07c8d85dfdd6c969f0;hp=c18312a369c2a3aa9b93e11f175f4f2056f1e19a;hpb=a354329f724d6ce913d2ccffb2be8f3327a67faa;p=elogind.git
diff --git a/src/core/manager.c b/src/core/manager.c
index c18312a36..7966b387f 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -19,7 +19,6 @@
along with systemd; If not, see .
***/
-#include
#include
#include
#include
@@ -27,14 +26,10 @@
#include
#include
#include
-#include
#include
#include
#include
-#include
#include
-#include
-#include
#include
#include
@@ -43,7 +38,6 @@
#endif
#include "sd-daemon.h"
-#include "sd-id128.h"
#include "sd-messages.h"
#include "manager.h"
@@ -56,7 +50,6 @@
#include "mkdir.h"
#include "ratelimit.h"
#include "locale-setup.h"
-#include "mount-setup.h"
#include "unit-name.h"
#include "missing.h"
#include "path-lookup.h"
@@ -64,7 +57,6 @@
#include "exit-status.h"
#include "virt.h"
#include "watchdog.h"
-#include "cgroup-util.h"
#include "path-util.h"
#include "audit-fd.h"
#include "boot-timestamps.h"
@@ -84,15 +76,14 @@
#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
-#define NOTIFY_FD_MAX 768
-#define NOTIFY_BUFFER_MAX PIPE_BUF
-
static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
+static int manager_run_generators(Manager *m);
+static void manager_undo_generators(Manager *m);
static int manager_watch_jobs_in_progress(Manager *m) {
usec_t next;
@@ -550,6 +541,9 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
m->test_run = test_run;
+ /* Reboot immediately if the user hits C-A-D more often than 7x per 2s */
+ RATELIMIT_INIT(m->ctrl_alt_del_ratelimit, 2 * USEC_PER_SEC, 7);
+
r = manager_default_environment(m);
if (r < 0)
goto fail;
@@ -706,7 +700,7 @@ static int manager_setup_kdbus(Manager *m) {
if (m->test_run || m->kdbus_fd >= 0)
return 0;
- if (getpid() == 1)
+ if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
bus_kernel_fix_attach_mask();
m->kdbus_fd = bus_kernel_create_bus(
@@ -1086,8 +1080,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
assert(m);
dual_timestamp_get(&m->generators_start_timestamp);
- manager_run_generators(m);
+ r = manager_run_generators(m);
dual_timestamp_get(&m->generators_finish_timestamp);
+ if (r < 0)
+ return r;
r = lookup_paths_init(
&m->lookup_paths, m->running_as, true,
@@ -1517,8 +1513,6 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
return -errno;
}
- if (n == 0)
- return -ECONNRESET;
for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
@@ -1722,7 +1716,19 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
case SIGINT:
if (m->running_as == SYSTEMD_SYSTEM) {
- manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
+
+ /* If the user presses C-A-D more than
+ * 7 times within 2s, we reboot
+ * immediately. */
+
+ if (ratelimit_test(&m->ctrl_alt_del_ratelimit))
+ manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
+ else {
+ log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
+ status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
+ m->exit_code = MANAGER_REBOOT;
+ }
+
break;
}
@@ -2092,8 +2098,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
return;
}
- msg = strappenda("unit=", p);
-
+ msg = strjoina("unit=", p);
if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
if (errno == EPERM)
/* We aren't allowed to send audit messages?
@@ -2211,7 +2216,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
m->n_reloading ++;
- fprintf(f, "current-job-id=%i\n", m->current_job_id);
+ fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
@@ -2517,7 +2522,9 @@ int manager_reload(Manager *m) {
lookup_paths_free(&m->lookup_paths);
/* Find new unit paths */
- manager_run_generators(m);
+ q = manager_run_generators(m);
+ if (q < 0 && r >= 0)
+ r = q;
q = lookup_paths_init(
&m->lookup_paths, m->running_as, true,
@@ -2525,19 +2532,19 @@ int manager_reload(Manager *m) {
m->generator_unit_path,
m->generator_unit_path_early,
m->generator_unit_path_late);
- if (q < 0)
+ if (q < 0 && r >= 0)
r = q;
manager_build_unit_path_cache(m);
/* First, enumerate what we can from all config files */
q = manager_enumerate(m);
- if (q < 0)
+ if (q < 0 && r >= 0)
r = q;
/* Second, deserialize our stored data */
q = manager_deserialize(m, f, fds);
- if (q < 0)
+ if (q < 0 && r >= 0)
r = q;
fclose(f);
@@ -2545,12 +2552,12 @@ int manager_reload(Manager *m) {
/* Re-register notify_fd as event source */
q = manager_setup_notify(m);
- if (q < 0)
+ if (q < 0 && r >= 0)
r = q;
/* Third, fire things up! */
q = manager_coldplug(m);
- if (q < 0)
+ if (q < 0 && r >= 0)
r = q;
assert(m->n_reloading > 0);
@@ -2775,28 +2782,33 @@ static void trim_generator_dir(Manager *m, char **generator) {
return;
}
-void manager_run_generators(Manager *m) {
- _cleanup_closedir_ DIR *d = NULL;
- const char *generator_path;
+static int manager_run_generators(Manager *m) {
+ _cleanup_free_ char **paths = NULL;
const char *argv[5];
+ char **path;
int r;
assert(m);
if (m->test_run)
- return;
+ return 0;
- generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
- d = opendir(generator_path);
- if (!d) {
- if (errno == ENOENT)
- return;
+ paths = generator_paths(m->running_as);
+ if (!paths)
+ return log_oom();
- log_error_errno(errno, "Failed to enumerate generator directory %s: %m",
- generator_path);
- return;
+ /* Optimize by skipping the whole process by not creating output directories
+ * if no generators are found. */
+ STRV_FOREACH(path, paths) {
+ r = access(*path, F_OK);
+ if (r == 0)
+ goto found;
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
}
+ return 0;
+ found:
r = create_generator_dir(m, &m->generator_unit_path, "generator");
if (r < 0)
goto finish;
@@ -2816,12 +2828,13 @@ void manager_run_generators(Manager *m) {
argv[4] = NULL;
RUN_WITH_UMASK(0022)
- execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
+ execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv);
finish:
trim_generator_dir(m, &m->generator_unit_path);
trim_generator_dir(m, &m->generator_unit_path_early);
trim_generator_dir(m, &m->generator_unit_path_late);
+ return r;
}
static void remove_generator_dir(Manager *m, char **generator) {
@@ -2838,7 +2851,7 @@ static void remove_generator_dir(Manager *m, char **generator) {
*generator = NULL;
}
-void manager_undo_generators(Manager *m) {
+static void manager_undo_generators(Manager *m) {
assert(m);
remove_generator_dir(m, &m->generator_unit_path);
@@ -3040,6 +3053,23 @@ const char *manager_get_runtime_prefix(Manager *m) {
getenv("XDG_RUNTIME_DIR");
}
+void manager_update_failed_units(Manager *m, Unit *u, bool failed) {
+ unsigned size;
+
+ assert(m);
+ assert(u->manager == m);
+
+ size = set_size(m->failed_units);
+
+ if (failed)
+ set_put(m->failed_units, u);
+ else
+ set_remove(m->failed_units, u);
+
+ if (set_size(m->failed_units) != size)
+ bus_manager_send_change_signal(m);
+}
+
ManagerState manager_state(Manager *m) {
Unit *u;