#include "strv.h"
#include "log.h"
#include "util.h"
+#include "mkdir.h"
#include "ratelimit.h"
#include "cgroup.h"
#include "mount-setup.h"
#include "bus-errors.h"
#include "exit-status.h"
#include "virt.h"
+#include "watchdog.h"
/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_ENTRIES_MAX 16
return 0;
}
+static void manager_strip_environment(Manager *m) {
+ assert(m);
+
+ /* Remove variables from the inherited set that are part of
+ * the container interface:
+ * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
+ strv_remove_prefix(m->environment, "container=");
+ strv_remove_prefix(m->environment, "container_");
+
+ /* Remove variables from the inherited set that are part of
+ * the initrd interface:
+ * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
+ strv_remove_prefix(m->environment, "RD_");
+}
+
int manager_new(ManagerRunningAs running_as, Manager **_m) {
Manager *m;
int r = -ENOMEM;
m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
- if (!(m->environment = strv_copy(environ)))
+ m->environment = strv_copy(environ);
+ if (!m->environment)
goto fail;
- if (!(m->default_controllers = strv_new("cpu", NULL)))
- goto fail;
+ manager_strip_environment(m);
+
+ if (running_as == MANAGER_SYSTEM) {
+ m->default_controllers = strv_new("cpu", NULL);
+ if (!m->default_controllers)
+ goto fail;
+ }
if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
goto fail;
int manager_loop(Manager *m) {
int r;
+ int wait_msec = -1;
RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
/* There might still be some zombies hanging around from
* before we were exec()'ed. Leat's reap them */
- if ((r = manager_dispatch_sigchld(m)) < 0)
+ r = manager_dispatch_sigchld(m);
+ if (r < 0)
return r;
+ /* Sleep for half the watchdog time */
+ if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) {
+ wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
+ if (wait_msec <= 0)
+ wait_msec = 1;
+ }
+
while (m->exit_code == MANAGER_RUNNING) {
struct epoll_event event;
int n;
+ if (wait_msec >= 0)
+ watchdog_ping();
+
if (!ratelimit_test(&rl)) {
/* Yay, something is going seriously wrong, pause a little */
log_warning("Looping too fast. Throttling execution a little.");
sleep(1);
+ continue;
}
if (manager_dispatch_load_queue(m) > 0)
if (swap_dispatch_reload(m) > 0)
continue;
- if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {
+ n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
+ if (n < 0) {
if (errno == EINTR)
continue;
return -errno;
- }
+ } else if (n == 0)
+ continue;
assert(n == 1);
- if ((r = process_event(m, &event)) < 0)
+ r = process_event(m, &event);
+ if (r < 0)
return r;
}
assert(m);
/* Is the initial job still around? */
- if (manager_get_job(m, 1))
+ if (manager_get_job(m, m->default_unit_job_id))
return true;
/* Is there a job for the shutdown target? */