X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmanager.c;h=c99a022cd5390ffc42d66848c223d3c4d6f0ab8a;hb=5b1869eaa22e365ab6595924fe96549b279b5ebc;hp=669af1524f30b7f50bd29473062fe21c94720cd9;hpb=c9d954b27ee125c3c90a6d2951c62eec4abb160b;p=elogind.git diff --git a/src/core/manager.c b/src/core/manager.c index 669af1524..c99a022cd 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -70,7 +70,7 @@ #include "cgroup-util.h" #include "path-util.h" #include "audit-fd.h" -#include "efivars.h" +#include "boot-timestamps.h" #include "env-util.h" /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */ @@ -236,7 +236,7 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po *p++ = '*'; if (pos < width-1) p = mempset(p, ' ', width-1-pos); - p = stpcpy(p, ANSI_HIGHLIGHT_OFF); + strcpy(p, ANSI_HIGHLIGHT_OFF); } } @@ -257,6 +257,7 @@ static void manager_print_jobs_in_progress(Manager *m) { /* m->n_running_jobs must be consistent with the contents of m->jobs, * so the above loop must have succeeded in finding j. */ assert(counter == print_nr + 1); + assert(j); cylon_pos = m->jobs_in_progress_iteration % 14; if (cylon_pos >= 8) @@ -456,8 +457,6 @@ static int manager_setup_signals(Manager *m) { } static int manager_default_environment(Manager *m) { - const char *path = "PATH=" DEFAULT_PATH; - assert(m); if (m->running_as == SYSTEMD_SYSTEM) { @@ -468,7 +467,8 @@ static int manager_default_environment(Manager *m) { * The initial passed environ is untouched to keep * /proc/self/environ valid; it is used for tagging * the init process inside containers. */ - m->environment = strv_new(path, NULL); + m->environment = strv_new("PATH=" DEFAULT_PATH, + NULL); /* Import locale variables LC_*= from configuration */ locale_setup(&m->environment); @@ -486,6 +486,7 @@ static int manager_default_environment(Manager *m) { int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { Manager *m; int r = -ENOMEM; + bool try_bus_connect = false; assert(_m); assert(running_as >= 0); @@ -497,7 +498,7 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { #ifdef ENABLE_EFI if (detect_container(NULL) <= 0) - efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); + boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); #endif m->running_as = running_as; @@ -557,15 +558,18 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) { if (r < 0) goto fail; - /* Try to connect to the busses, if possible. */ - if ((running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS")) || - running_as == SYSTEMD_SYSTEM) { - r = bus_init(m, reexecuting || running_as != SYSTEMD_SYSTEM); - if (r < 0) - goto fail; - } else + if (running_as == SYSTEMD_SYSTEM) + try_bus_connect = reexecuting; + else if (getenv("DBUS_SESSION_BUS_ADDRESS")) + try_bus_connect = true; + else log_debug("Skipping DBus session bus connection attempt - no DBUS_SESSION_BUS_ADDRESS set..."); + /* Try to connect to the busses, if possible. */ + r = bus_init(m, try_bus_connect); + if (r < 0) + goto fail; + m->taint_usr = dir_is_empty("/usr") > 0; *_m = m; @@ -672,7 +676,7 @@ static unsigned manager_dispatch_gc_queue(Manager *m) { unit_gc_sweep(u, gc_marker); - LIST_REMOVE(Unit, gc_queue, m->gc_queue, u); + LIST_REMOVE(gc_queue, m->gc_queue, u); u->in_gc_queue = false; n++; @@ -771,6 +775,9 @@ void manager_free(Manager *m) { for (i = 0; i < RLIMIT_NLIMITS; i++) free(m->rlimit[i]); + assert(hashmap_isempty(m->units_requiring_mounts_for)); + hashmap_free(m->units_requiring_mounts_for); + free(m); } @@ -783,15 +790,17 @@ int manager_enumerate(Manager *m) { /* Let's ask every type to load all units from disk/kernel * that it might know */ for (c = 0; c < _UNIT_TYPE_MAX; c++) - if (unit_vtable[c]->enumerate) - if ((q = unit_vtable[c]->enumerate(m)) < 0) + if (unit_vtable[c]->enumerate) { + q = unit_vtable[c]->enumerate(m); + if (q < 0) r = q; + } manager_dispatch_load_queue(m); return r; } -int manager_coldplug(Manager *m) { +static int manager_coldplug(Manager *m) { int r = 0, q; Iterator i; Unit *u; @@ -871,6 +880,29 @@ fail: m->unit_path_cache = NULL; } + +static int manager_distribute_fds(Manager *m, FDSet *fds) { + Unit *u; + Iterator i; + int r; + + assert(m); + + HASHMAP_FOREACH(u, m->units, i) { + + if (fdset_size(fds) <= 0) + break; + + if (UNIT_VTABLE(u)->distribute_fds) { + r = UNIT_VTABLE(u)->distribute_fds(u, fds); + if (r < 0) + return r; + } + } + + return 0; +} + int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { int r, q; @@ -1178,7 +1210,7 @@ void manager_clear_jobs(Manager *m) { job_finish_and_invalidate(j, JOB_CANCELED, false); } -unsigned manager_dispatch_run_queue(Manager *m) { +static unsigned manager_dispatch_run_queue(Manager *m) { Job *j; unsigned n = 0; @@ -1206,7 +1238,7 @@ unsigned manager_dispatch_run_queue(Manager *m) { return n; } -unsigned manager_dispatch_dbus_queue(Manager *m) { +static unsigned manager_dispatch_dbus_queue(Manager *m) { Job *j; Unit *u; unsigned n = 0; @@ -1757,7 +1789,7 @@ static int process_event(Manager *m, struct epoll_event *ev) { } case WATCH_IDLE_PIPE: { - m->no_console_output = true; + m->no_console_output = m->n_on_console > 0; manager_unwatch_idle_pipe(m); close_idle_pipe(m); @@ -1787,7 +1819,7 @@ int manager_loop(Manager *m) { manager_check_finished(m); /* There might still be some zombies hanging around from - * before we were exec()'ed. Leat's reap them */ + * before we were exec()'ed. Let's reap them. */ r = manager_dispatch_sigchld(m); if (r < 0) return r; @@ -2053,7 +2085,7 @@ void manager_dispatch_bus_query_pid_done( int manager_open_serialization(Manager *m, FILE **_f) { char *path = NULL; - int fd; + int fd = -1; FILE *f; assert(_f); @@ -2289,32 +2321,10 @@ finish: return r; } -int manager_distribute_fds(Manager *m, FDSet *fds) { - Unit *u; - Iterator i; - int r; - - assert(m); - - HASHMAP_FOREACH(u, m->units, i) { - - if (fdset_size(fds) <= 0) - break; - - if (UNIT_VTABLE(u)->distribute_fds) { - r = UNIT_VTABLE(u)->distribute_fds(u, fds); - if (r < 0) - return r; - } - } - - return 0; -} - int manager_reload(Manager *m) { int r, q; - FILE *f; - FDSet *fds; + _cleanup_fclose_ FILE *f = NULL; + _cleanup_fdset_free_ FDSet *fds = NULL; assert(m); @@ -2328,20 +2338,18 @@ int manager_reload(Manager *m) { fds = fdset_new(); if (!fds) { m->n_reloading --; - r = -ENOMEM; - goto finish; + return -ENOMEM; } r = manager_serialize(m, f, fds, false); if (r < 0) { m->n_reloading --; - goto finish; + return r; } if (fseeko(f, 0, SEEK_SET) < 0) { m->n_reloading --; - r = -errno; - goto finish; + return -errno; } /* From here on there is no way back. */ @@ -2385,13 +2393,6 @@ int manager_reload(Manager *m) { m->send_reloading_done = true; -finish: - if (f) - fclose(f); - - if (fds) - fdset_free(fds); - return r; } @@ -2661,14 +2662,16 @@ void manager_undo_generators(Manager *m) { } int manager_environment_add(Manager *m, char **environment) { - char **e = NULL; assert(m); + e = strv_env_merge(2, m->environment, environment); if (!e) return -ENOMEM; + strv_free(m->environment); m->environment = e; + return 0; } @@ -2765,6 +2768,41 @@ void manager_status_printf(Manager *m, bool ephemeral, const char *status, const va_end(ap); } +int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) { + _cleanup_free_ char *p = NULL; + Unit *found; + + assert(m); + assert(path); + assert(suffix); + assert(_found); + + p = unit_name_from_path(path, suffix); + if (!p) + return -ENOMEM; + + found = manager_get_unit(m, p); + if (!found) { + *_found = NULL; + return 0; + } + + *_found = found; + return 1; +} + +Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { + char p[strlen(path)+1]; + + assert(m); + assert(path); + + strcpy(p, path); + path_kill_slashes(p); + + return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p); +} + void watch_init(Watch *w) { assert(w);