manager.c revision a0b6422689e37ffee37742d027f91af8bacfa78d
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2010 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include <assert.h>
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include <errno.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <string.h>
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens#include <sys/epoll.h>
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include <signal.h>
51323288fc628a5cac50914df915545d685b793eLennart Poettering#include <sys/signalfd.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <sys/wait.h>
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include <unistd.h>
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include <sys/poll.h>
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include <sys/reboot.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <sys/ioctl.h>
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include <linux/kd.h>
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering#include <termios.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <fcntl.h>
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include <sys/types.h>
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include <sys/stat.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <dirent.h>
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include <sys/timerfd.h>
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#ifdef HAVE_AUDIT
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering#include <libaudit.h>
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering#endif
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include "systemd/sd-daemon.h"
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include "systemd/sd-id128.h"
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include "systemd/sd-messages.h"
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering#include "manager.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "transaction.h"
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering#include "hashmap.h"
a761c1ca851a9397b5a207ef600e077d0f7f4534Lennart Poettering#include "macro.h"
019036a47fcd10fcf0286800d144c706f3773e2fLennart Poettering#include "strv.h"
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering#include "log.h"
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering#include "util.h"
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering#include "mkdir.h"
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering#include "ratelimit.h"
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering#include "cgroup.h"
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering#include "mount-setup.h"
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering#include "unit-name.h"
3bbdc31df37a23b5134a115c01d15e7ff870b3ccLennart Poettering#include "dbus-unit.h"
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering#include "dbus-job.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "missing.h"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering#include "path-lookup.h"
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering#include "special.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "bus-errors.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "exit-status.h"
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#include "virt.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "watchdog.h"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering#include "cgroup-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "path-util.h"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering#include "audit-fd.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "efivars.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "env-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering#define GC_QUEUE_ENTRIES_MAX 16
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/* Initial delay and the interval for printing status messages about running jobs */
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#define JOBS_IN_PROGRESS_WAIT_SEC 5
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#define JOBS_IN_PROGRESS_PERIOD_SEC 1
ef9fb66c0b292d3543c16bfce99ad677bef0f401Lennart Poettering#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering/* Where clients shall send notification messages to */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int manager_setup_notify(Manager *m) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering union {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering struct sockaddr sa;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering struct sockaddr_un un;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering } sa;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering struct epoll_event ev;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering int one = 1;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(m);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m->notify_watch.type = WATCH_NOTIFY;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (m->notify_watch.fd < 0) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering log_error("Failed to allocate notification socket: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return -errno;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering }
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering zero(sa);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering sa.sa.sa_family = AF_UNIX;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (getpid() != 1 || detect_container(NULL) > 0)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull());
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering else
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path));
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering sa.un.sun_path[0] = 0;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("bind() failed: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return -errno;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering }
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering log_error("SO_PASSCRED failed: %m");
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return -errno;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering }
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering zero(ev);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering ev.events = EPOLLIN;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering ev.data.ptr = &m->notify_watch;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering log_error("Failed to add notification socket fd to epoll: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -errno;
51323288fc628a5cac50914df915545d685b793eLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering sa.un.sun_path[0] = '@';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->notify_socket = strdup(sa.un.sun_path);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!m->notify_socket)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return log_oom();
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_debug("Using notification socket %s", m->notify_socket);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int manager_jobs_in_progress_mod_timer(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering struct itimerspec its;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering zero(its);
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering its.it_value.tv_sec = JOBS_IN_PROGRESS_WAIT_SEC;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering its.it_interval.tv_sec = JOBS_IN_PROGRESS_PERIOD_SEC;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (timerfd_settime(m->jobs_in_progress_watch.fd, 0, &its, NULL) < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return 0;
51323288fc628a5cac50914df915545d685b793eLennart Poettering}
51323288fc628a5cac50914df915545d685b793eLennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poetteringstatic int manager_watch_jobs_in_progress(Manager *m) {
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering struct epoll_event ev;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (m->jobs_in_progress_watch.type != WATCH_INVALID)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->jobs_in_progress_watch.type = WATCH_JOBS_IN_PROGRESS;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->jobs_in_progress_watch.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (m->jobs_in_progress_watch.fd < 0) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_error("Failed to create timerfd: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = -errno;
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering goto err;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering r = manager_jobs_in_progress_mod_timer(m);
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to set up timer for jobs progress watch: %s", strerror(-r));
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering goto err;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering zero(ev);
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering ev.events = EPOLLIN;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering ev.data.ptr = &m->jobs_in_progress_watch;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->jobs_in_progress_watch.fd, &ev) < 0) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering log_error("Failed to add jobs progress timer fd to epoll: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto err;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_debug("Set up jobs progress timerfd.");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poetteringerr:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->jobs_in_progress_watch.fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->jobs_in_progress_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering watch_init(&m->jobs_in_progress_watch);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering return r;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering}
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poetteringstatic void manager_unwatch_jobs_in_progress(Manager *m) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (m->jobs_in_progress_watch.type != WATCH_JOBS_IN_PROGRESS)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->jobs_in_progress_watch.fd, NULL) >= 0);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt close_nointr_nofail(m->jobs_in_progress_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering watch_init(&m->jobs_in_progress_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering m->jobs_in_progress_iteration = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Closed jobs progress timerfd.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering#define CYLON_BUFFER_EXTRA (2*strlen(ANSI_RED_ON) + strlen(ANSI_HIGHLIGHT_RED_ON) + 2*strlen(ANSI_HIGHLIGHT_OFF))
51323288fc628a5cac50914df915545d685b793eLennart Poetteringstatic void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering char *p = buffer;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
51323288fc628a5cac50914df915545d685b793eLennart Poettering assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (pos > 1) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (pos > 2) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering memset(p, ' ', pos-2);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering p += pos-2;
51323288fc628a5cac50914df915545d685b793eLennart Poettering }
51323288fc628a5cac50914df915545d685b793eLennart Poettering memcpy(p, ANSI_RED_ON, strlen(ANSI_RED_ON));
51323288fc628a5cac50914df915545d685b793eLennart Poettering p += strlen(ANSI_RED_ON);
51323288fc628a5cac50914df915545d685b793eLennart Poettering *p++ = '*';
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (pos > 0 && pos <= width) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcpy(p, ANSI_HIGHLIGHT_RED_ON, strlen(ANSI_HIGHLIGHT_RED_ON));
51323288fc628a5cac50914df915545d685b793eLennart Poettering p += strlen(ANSI_HIGHLIGHT_RED_ON);
51323288fc628a5cac50914df915545d685b793eLennart Poettering *p++ = '*';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcpy(p, ANSI_HIGHLIGHT_OFF, strlen(ANSI_HIGHLIGHT_OFF));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p += strlen(ANSI_HIGHLIGHT_OFF);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (pos < width) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering memcpy(p, ANSI_RED_ON, strlen(ANSI_RED_ON));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering p += strlen(ANSI_RED_ON);
51323288fc628a5cac50914df915545d685b793eLennart Poettering *p++ = '*';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (pos < width-1) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memset(p, ' ', width-1-pos);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p += width-1-pos;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering memcpy(p, ANSI_HIGHLIGHT_OFF, strlen(ANSI_HIGHLIGHT_OFF));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p += strlen(ANSI_HIGHLIGHT_OFF);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering *p = 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void manager_print_jobs_in_progress(Manager *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Iterator i;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering Job *j;
51323288fc628a5cac50914df915545d685b793eLennart Poettering char *job_of_n = NULL;
51323288fc628a5cac50914df915545d685b793eLennart Poettering unsigned counter = 0, print_nr;
51323288fc628a5cac50914df915545d685b793eLennart Poettering char cylon[6 + CYLON_BUFFER_EXTRA + 1];
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering unsigned cylon_pos;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering HASHMAP_FOREACH(j, m->jobs, i)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (j->state == JOB_RUNNING && counter++ == print_nr)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering /* m->n_running_jobs must be consistent with the contents of m->jobs,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * so the above loop must have succeeded in finding j. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(counter == print_nr + 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cylon_pos = m->jobs_in_progress_iteration % 14;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (cylon_pos >= 8)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cylon_pos = 14 - cylon_pos;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
966c66e34940001a40806142ecebaae61b478444Lennart Poettering
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (m->n_running_jobs > 1)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering job_of_n = NULL;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_status_printf(m, true, cylon, "%sA %s job is running for %s",
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strempty(job_of_n), job_type_to_string(j->type), unit_description(j->unit));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(job_of_n);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->jobs_in_progress_iteration++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int manager_setup_time_change(Manager *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct epoll_event ev;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct itimerspec its;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering assert(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(m->time_change_watch.type == WATCH_INVALID);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->time_change_watch.type = WATCH_TIME_CHANGE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->time_change_watch.fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (m->time_change_watch.fd < 0) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_error("Failed to create timerfd: %m");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return -errno;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen zero(its);
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering /* We only care for the cancellation event, hence we set the
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen * timeout to the latest possible value. */
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen its.it_value.tv_sec = TIME_T_MAX;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->time_change_watch.fd);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering watch_init(&m->time_change_watch);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return 0;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering zero(ev);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering ev.events = EPOLLIN;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering ev.data.ptr = &m->time_change_watch;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->time_change_watch.fd, &ev) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to add timer change fd to epoll: %m");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return -errno;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poetteringstatic int enable_special_signals(Manager *m) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering int fd;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(m);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Enable that we get SIGINT on control-alt-del. In containers
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * this will fail with EPERM (older) or EINVAL (newer), so
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering * ignore that. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_warning("Failed to enable ctrl-alt-del handling: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (fd < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Support systems without virtual console */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (fd != -ENOENT)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_warning("Failed to open /dev/tty0: %m");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering } else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Enable that we get SIGWINCH on kbrequest */
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering close_nointr_nofail(fd);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int manager_setup_signals(Manager *m) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering sigset_t mask;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct epoll_event ev;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering struct sigaction sa;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* We are not interested in SIGSTOP and friends. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering zero(sa);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering sa.sa_handler = SIG_DFL;
51323288fc628a5cac50914df915545d685b793eLennart Poettering sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_se(sigemptyset(&mask) == 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sigset_add_many(&mask,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGCHLD, /* Child died */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGTERM, /* Reexecute daemon */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGHUP, /* Reload configuration */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SIGUSR2, /* systemd: dump status */
51323288fc628a5cac50914df915545d685b793eLennart Poettering SIGINT, /* Kernel sends us this on control-alt-del */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+0, /* systemd: start default.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+1, /* systemd: isolate rescue.target */
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering SIGRTMIN+2, /* systemd: isolate emergency.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+3, /* systemd: start halt.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+4, /* systemd: start poweroff.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+5, /* systemd: start reboot.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+6, /* systemd: start kexec.target */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+13, /* systemd: Immediate halt */
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering SIGRTMIN+14, /* systemd: Immediate poweroff */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+15, /* systemd: Immediate reboot */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SIGRTMIN+16, /* systemd: Immediate kexec */
51323288fc628a5cac50914df915545d685b793eLennart Poettering SIGRTMIN+20, /* systemd: enable status messages */
51323288fc628a5cac50914df915545d685b793eLennart Poettering SIGRTMIN+21, /* systemd: disable status messages */
51323288fc628a5cac50914df915545d685b793eLennart Poettering SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
51323288fc628a5cac50914df915545d685b793eLennart Poettering SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering SIGRTMIN+27, /* systemd: set log target to console */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering SIGRTMIN+28, /* systemd: set log target to kmsg */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering -1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->signal_watch.type = WATCH_SIGNAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m->signal_watch.fd < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering zero(ev);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ev.events = EPOLLIN;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ev.data.ptr = &m->signal_watch;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
966c66e34940001a40806142ecebaae61b478444Lennart Poettering if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering return -errno;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (m->running_as == SYSTEMD_SYSTEM)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering return enable_special_signals(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void manager_strip_environment(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Remove variables from the inherited set that are part of
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * the container interface:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_remove_prefix(m->environment, "container=");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_remove_prefix(m->environment, "container_");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Remove variables from the inherited set that are part of
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * the initrd interface:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_remove_prefix(m->environment, "RD_");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Drop invalid entries */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_env_clean(m->environment);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_new(SystemdRunningAs running_as, Manager **_m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Manager *m;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r = -ENOMEM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(_m);
4e2d538f33df8a425487aaa4facc23065a9bdaf7Lennart Poettering assert(running_as >= 0);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m = new0(Manager, 1);
4e2d538f33df8a425487aaa4facc23065a9bdaf7Lennart Poettering if (!m)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -ENOMEM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dual_timestamp_get(&m->userspace_timestamp);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dual_timestamp_from_monotonic(&m->kernel_timestamp, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#ifdef ENABLE_EFI
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering#endif
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->running_as = running_as;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->exit_code = _MANAGER_EXIT_CODE_INVALID;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->pin_cgroupfs_fd = -1;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering m->idle_pipe[0] = m->idle_pipe[1] = -1;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering watch_init(&m->signal_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering watch_init(&m->mount_watch);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering watch_init(&m->swap_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering watch_init(&m->udev_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering watch_init(&m->time_change_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering watch_init(&m->jobs_in_progress_watch);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->epoll_fd = m->dev_autofs_fd = -1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->environment = strv_copy(environ);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!m->environment)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen manager_strip_environment(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (running_as == SYSTEMD_SYSTEM) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering m->default_controllers = strv_new("cpu", NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (!m->default_controllers)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering goto fail;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering goto fail;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (m->epoll_fd < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = manager_setup_signals(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = manager_setup_cgroup(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = manager_setup_notify(m);
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto fail;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = manager_setup_time_change(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering /* Try to connect to the busses, if possible. */
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt r = bus_init(m, running_as != SYSTEMD_SYSTEM);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto fail;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering m->taint_usr = dir_is_empty("/usr") > 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering *_m = m;
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering return 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringfail:
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering manager_free(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poetteringstatic unsigned manager_dispatch_cleanup_queue(Manager *m) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering Unit *u;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering unsigned n = 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering while ((u = m->cleanup_queue)) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(u->in_cleanup_queue);
51323288fc628a5cac50914df915545d685b793eLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering unit_free(u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering n++;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering return n;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poetteringenum {
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
c463eb783e5ad999d400180c69b912c54fa07ee1Lennart Poettering GC_OFFSET_UNSURE, /* No clue */
eee026a7ba16336b6493828a2a13ddc9908667ffLennart Poettering GC_OFFSET_GOOD, /* We still need this unit */
d0129ddb9fbb07bed7c8ea51b8031f824bf506fbLennart Poettering GC_OFFSET_BAD, /* We don't need this unit anymore */
eee026a7ba16336b6493828a2a13ddc9908667ffLennart Poettering _GC_OFFSET_MAX
c463eb783e5ad999d400180c69b912c54fa07ee1Lennart Poettering};
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poetteringstatic void unit_gc_sweep(Unit *u, unsigned gc_marker) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering Iterator i;
51323288fc628a5cac50914df915545d685b793eLennart Poettering Unit *other;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering bool is_bad;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(u);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering u->gc_marker == gc_marker + GC_OFFSET_BAD ||
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (u->in_cleanup_queue)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto bad;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (unit_check_gc(u))
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto good;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering is_bad = true;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
966c66e34940001a40806142ecebaae61b478444Lennart Poettering SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering unit_gc_sweep(other, gc_marker);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto good;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering is_bad = false;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (is_bad)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto bad;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* We were unable to find anything out about this entry, so
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * let's investigate it later */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_gc_queue(u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringbad:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* We definitely know that this one is not useful anymore, so
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * let's mark it for deletion */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->gc_marker = gc_marker + GC_OFFSET_BAD;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_cleanup_queue(u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringgood:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->gc_marker = gc_marker + GC_OFFSET_GOOD;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic unsigned manager_dispatch_gc_queue(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Unit *u;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned n = 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering unsigned gc_marker;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering (m->gc_queue_timestamp <= 0 ||
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering log_debug("Running GC...");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->gc_marker += _GC_OFFSET_MAX;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->gc_marker = 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering gc_marker = m->gc_marker;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering while ((u = m->gc_queue)) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(u->in_gc_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_gc_sweep(u, gc_marker);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_REMOVE(Unit, gc_queue, m->gc_queue, u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->in_gc_queue = false;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering n++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_debug_unit(u->id, "Collecting %s", u->id);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->gc_marker = gc_marker + GC_OFFSET_BAD;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_cleanup_queue(u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->n_in_gc_queue = 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->gc_queue_timestamp = 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return n;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void manager_clear_jobs_and_units(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Unit *u;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering while ((u = hashmap_first(m->units)))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_free(u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_dispatch_cleanup_queue(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(!m->load_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(!m->run_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(!m->dbus_unit_queue);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(!m->dbus_job_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(!m->cleanup_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(!m->gc_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(hashmap_isempty(m->jobs));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(hashmap_isempty(m->units));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->n_on_console = 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->n_running_jobs = 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringvoid manager_free(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering UnitType c;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int i;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_clear_jobs_and_units(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering for (c = 0; c < _UNIT_TYPE_MAX; c++)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (unit_vtable[c]->shutdown)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_vtable[c]->shutdown(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* If we reexecute ourselves, we keep the root cgroup
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * around */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_undo_generators(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering bus_done(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering hashmap_free(m->units);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering hashmap_free(m->jobs);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering hashmap_free(m->watch_pids);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering hashmap_free(m->watch_bus);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->epoll_fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->epoll_fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->signal_watch.fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->signal_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->notify_watch.fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->notify_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->time_change_watch.fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->time_change_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (m->jobs_in_progress_watch.fd >= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_nointr_nofail(m->jobs_in_progress_watch.fd);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(m->notify_socket);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering lookup_paths_free(&m->lookup_paths);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_free(m->environment);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering strv_free(m->default_controllers);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering hashmap_free(m->cgroup_bondings);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering set_free_free(m->unit_path_cache);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_pipe(m->idle_pipe);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(m->switch_root);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(m->switch_root_init);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering for (i = 0; i < RLIMIT_NLIMITS; i++)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(m->rlimit[i]);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_enumerate(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r = 0, q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering UnitType c;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Let's ask every type to load all units from disk/kernel
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * that it might know */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering for (c = 0; c < _UNIT_TYPE_MAX; c++)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (unit_vtable[c]->enumerate)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if ((q = unit_vtable[c]->enumerate(m)) < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_dispatch_load_queue(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_coldplug(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r = 0, q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Iterator i;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Unit *u;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering char *k;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Then, let's set up their initial state. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering HASHMAP_FOREACH_KEY(u, k, m->units, i) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* ignore aliases */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (u->id != k)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q = unit_coldplug(u)) < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void manager_build_unit_path_cache(Manager *m) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering char **i;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DIR _cleanup_free_ *d = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering set_free_free(m->unit_path_cache);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->unit_path_cache = set_new(string_hash_func, string_compare_func);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!m->unit_path_cache) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error("Failed to allocate unit path cache.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This simply builds a list of files we know exist, so that
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * we don't always have to go to disk */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering STRV_FOREACH(i, m->lookup_paths.unit_path) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering struct dirent *de;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering d = opendir(*i);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!d) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (errno != ENOENT)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error("Failed to open directory %s: %m", *i);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering while ((de = readdir(d))) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering char *p;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (ignore_file(de->d_name))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (!p) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = -ENOMEM;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering goto fail;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = set_put(m->unit_path_cache, p);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r < 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering free(p);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering goto fail;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering closedir(d);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering d = NULL;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error("Failed to build unit path cache: %s", strerror(-r));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering set_free_free(m->unit_path_cache);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->unit_path_cache = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r, q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_run_generators(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = lookup_paths_init(
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering &m->lookup_paths, m->running_as, true,
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->generator_unit_path,
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->generator_unit_path_early,
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->generator_unit_path_late);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r < 0)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering manager_build_unit_path_cache(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering /* If we will deserialize make sure that during enumeration
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * this is already known, so we increase the counter here
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * already */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (serialization)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->n_reloading ++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* First, enumerate what we can from all config files */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = manager_enumerate(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Second, deserialize if there is something to deserialize */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (serialization) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q = manager_deserialize(m, serialization, fds);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering /* Any fds left? Find some unit which wants them. This is
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * useful to allow container managers to pass some file
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * descriptors to us pre-initialized. This enables
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * socket-based activation of entire containers. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (fdset_size(fds) > 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q = manager_distribute_fds(m, fds);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Third, fire things up! */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q = manager_coldplug(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (serialization) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m->n_reloading > 0);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering m->n_reloading --;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Transaction *tr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(type < _JOB_TYPE_MAX);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(unit);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(mode < _JOB_MODE_MAX);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (mode == JOB_ISOLATE && type != JOB_START) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -EINVAL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (mode == JOB_ISOLATE && !unit->allow_isolate) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -EPERM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_debug_unit(unit->id,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering "Trying to enqueue job %s/%s/%s", unit->id,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering job_type_to_string(type), job_mode_to_string(mode));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering job_type_collapse(&type, unit);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!tr)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -ENOMEM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering mode == JOB_IGNORE_DEPENDENCIES, e);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto tr_abort;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (mode == JOB_ISOLATE) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = transaction_add_isolate_jobs(tr, m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto tr_abort;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = transaction_activate(tr, m, mode, e);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto tr_abort;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_debug_unit(unit->id,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering "Enqueued job %s/%s as %u", unit->id,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering job_type_to_string(type), (unsigned) tr->anchor_job->id);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (_ret)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering *_ret = tr->anchor_job;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering transaction_free(tr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringtr_abort:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering transaction_abort(tr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering transaction_free(tr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Unit *unit;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering int r;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(type < _JOB_TYPE_MAX);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(mode < _JOB_MODE_MAX);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = manager_load_unit(m, name, NULL, NULL, &unit);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return manager_add_job(m, type, unit, mode, override, e, _ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart PoetteringJob *manager_get_job(Manager *m, uint32_t id) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return hashmap_get(m->jobs, UINT32_TO_PTR(id));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom GundersenUnit *manager_get_unit(Manager *m, const char *name) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(name);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return hashmap_get(m->units, name);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poetteringunsigned manager_dispatch_load_queue(Manager *m) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering Unit *u;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering unsigned n = 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering /* Make sure we are not run recursively */
9a1f0c283bac56eb26a2fa02d62e0e9ece82f25aLennart Poettering if (m->dispatching_load_queue)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->dispatching_load_queue = true;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Dispatches the load queue. Takes a unit from the queue and
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering * tries to load its data until the queue is empty */
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering while ((u = m->load_queue)) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(u->in_load_queue);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering unit_load(u);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering n++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
9a1f0c283bac56eb26a2fa02d62e0e9ece82f25aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering m->dispatching_load_queue = false;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return n;
9a1f0c283bac56eb26a2fa02d62e0e9ece82f25aLennart Poettering}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poetteringint manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering Unit *ret;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering UnitType t;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering int r;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(m);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering assert(name || path);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This will prepare the unit for loading, but not actually
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * load anything from disk. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (path && !is_path(path)) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -EINVAL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!name)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering name = path_get_file_name(path);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering t = unit_name_to_type(name);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, false)) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -EINVAL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering ret = manager_get_unit(m, name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (ret) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering *_ret = ret;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return 1;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering ret = unit_new(m, unit_vtable[t]->object_size);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!ret)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -ENOMEM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (path) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering ret->fragment_path = strdup(path);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!ret->fragment_path) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_free(ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return -ENOMEM;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((r = unit_add_name(ret, name)) < 0) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering unit_free(ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_load_queue(ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_dbus_queue(ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_add_to_gc_queue(ret);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (_ret)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering *_ret = ret;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
7e8131e9c6c150732503899a092206578fdc13deLennart Poettering}
7e8131e9c6c150732503899a092206578fdc13deLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringint manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This will load the service information files, but not actually
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * start any services or anything. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = manager_load_unit_prepare(m, name, path, e, _ret);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r != 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering manager_dispatch_load_queue(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (_ret)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering *_ret = unit_follow_merge(*_ret);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringvoid manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Iterator i;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering Job *j;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(s);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(f);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering HASHMAP_FOREACH(j, s->jobs, i)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering job_dump(j, f, prefix);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringvoid manager_dump_units(Manager *s, FILE *f, const char *prefix) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Iterator i;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Unit *u;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering const char *t;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(s);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(f);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering HASHMAP_FOREACH_KEY(u, t, s->units, i)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (u->id == t)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unit_dump(u, f, prefix);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringvoid manager_clear_jobs(Manager *m) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Job *j;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering while ((j = hashmap_first(m->jobs)))
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering /* No need to recurse. We're cancelling all jobs. */
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering job_finish_and_invalidate(j, JOB_CANCELED, false);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringunsigned manager_dispatch_run_queue(Manager *m) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Job *j;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering unsigned n = 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (m->dispatching_run_queue)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering m->dispatching_run_queue = true;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering while ((j = m->run_queue)) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(j->installed);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(j->in_run_queue);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering job_run_and_invalidate(j);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering n++;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering m->dispatching_run_queue = false;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (m->n_running_jobs > 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering manager_watch_jobs_in_progress(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return n;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringunsigned manager_dispatch_dbus_queue(Manager *m) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Job *j;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Unit *u;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering unsigned n = 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (m->dispatching_dbus_queue)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering m->dispatching_dbus_queue = true;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering while ((u = m->dbus_unit_queue)) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(u->in_dbus_queue);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering bus_unit_send_change_signal(u);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering n++;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering while ((j = m->dbus_job_queue)) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(j->in_dbus_queue);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering bus_job_send_change_signal(j);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering n++;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering m->dispatching_dbus_queue = false;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return n;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringstatic int manager_process_notify_fd(Manager *m) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering ssize_t n;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering for (;;) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering char buf[4096];
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering struct msghdr msghdr;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering struct iovec iovec;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering struct ucred *ucred;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering union {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering struct cmsghdr cmsghdr;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering } control;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Unit *u;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering char **tags;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering zero(iovec);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering iovec.iov_base = buf;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering iovec.iov_len = sizeof(buf)-1;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering zero(control);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering zero(msghdr);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering msghdr.msg_iov = &iovec;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering msghdr.msg_iovlen = 1;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering msghdr.msg_control = &control;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering msghdr.msg_controllen = sizeof(control);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (n <= 0) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (n >= 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return -EIO;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (errno == EAGAIN || errno == EINTR)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering break;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return -errno;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering control.cmsghdr.cmsg_level != SOL_SOCKET ||
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering log_warning("Received notify message without credentials. Ignoring.");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering continue;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (!u) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering u = cgroup_unit_by_pid(m, ucred->pid);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (!u) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering continue;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering assert((size_t) n < sizeof(buf));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering buf[n] = 0;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering tags = strv_split(buf, "\n\r");
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (!tags)
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return log_oom();
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering log_debug_unit(u->id, "Got notification message for unit %s", u->id);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (UNIT_VTABLE(u)->notify_message)
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering strv_free(tags);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return 0;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering}
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int manager_dispatch_sigchld(Manager *m) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering assert(m);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering for (;;) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering siginfo_t si;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering Unit *u;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering int r;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering zero(si);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering /* First we call waitd() for a PID and do not reap the
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering * zombie. That way we can still access /proc/$PID for
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering * it while it is a zombie. */
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (errno == ECHILD)
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering break;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (errno == EINTR)
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering continue;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return -errno;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (si.si_pid <= 0)
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering break;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering char _cleanup_free_ *name = NULL;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering get_process_comm(si.si_pid, &name);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering /* Let's flush any message the dying child might still
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering * have queued for us. This ensures that the process
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering * still exists in /proc so that we can figure out
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering * which cgroup and hence unit it belongs to. */
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering r = manager_process_notify_fd(m);
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (r < 0)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering return r;
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering /* And now figure out the unit this belongs to */
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid));
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (!u)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering u = cgroup_unit_by_pid(m, si.si_pid);
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering /* And now, we actually reap the zombie. */
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (errno == EINTR)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering continue;
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering return -errno;
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering }
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering continue;
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering log_debug("Child %lu died (code=%s, status=%i/%s)",
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering (long unsigned) si.si_pid,
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering sigchld_code_to_string(si.si_code),
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering si.si_status,
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering strna(si.si_code == CLD_EXITED
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering : signal_to_string(si.si_status)));
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering if (!u)
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering continue;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering log_debug_unit(u->id,
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering "Child %lu belongs to %s", (long unsigned) si.si_pid, u->id);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering return 0;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering}
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poetteringstatic int manager_start_target(Manager *m, const char *name, JobMode mode) {
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering int r;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering DBusError error;
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering dbus_error_init(&error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_debug_unit(name, "Activating special unit %s", name);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (r < 0)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_error_unit(name,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering "Failed to enqueue %s job: %s", name, bus_error(&error, r));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering dbus_error_free(&error);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int manager_process_signal_fd(Manager *m) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering ssize_t n;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering struct signalfd_siginfo sfsi;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering bool sigchld = false;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(m);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering for (;;) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (n != sizeof(sfsi)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (n >= 0)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return -EIO;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (errno == EINTR || errno == EAGAIN)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return -errno;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (sfsi.ssi_pid > 0) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering char *p = NULL;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering get_process_comm(sfsi.ssi_pid, &p);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_debug("Received SIG%s from PID %lu (%s).",
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering signal_to_string(sfsi.ssi_signo),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (unsigned long) sfsi.ssi_pid, strna(p));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering free(p);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering } else
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering switch (sfsi.ssi_signo) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGCHLD:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering sigchld = true;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGTERM:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (m->running_as == SYSTEMD_SYSTEM) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* This is for compatibility with the
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering * original sysvinit */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering m->exit_code = MANAGER_REEXECUTE;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Fall through */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGINT:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (m->running_as == SYSTEMD_SYSTEM) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Run the exit target if there is one, if not, just exit. */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering m->exit_code = MANAGER_EXIT;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 0;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGWINCH:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (m->running_as == SYSTEMD_SYSTEM)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* This is a nop on non-init */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGPWR:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (m->running_as == SYSTEMD_SYSTEM)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* This is a nop on non-init */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGUSR1: {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering Unit *u;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_info("Trying to reconnect to bus...");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering bus_init(m, true);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_info("Loading D-Bus service...");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGUSR2: {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering FILE *f;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering char *dump = NULL;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering size_t size;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (!(f = open_memstream(&dump, &size))) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_warning("Failed to allocate memory stream.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_dump_units(m, f, "\t");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_dump_jobs(m, f, "\t");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (ferror(f)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering fclose(f);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering free(dump);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_warning("Failed to write status stream");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering fclose(f);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_dump(LOG_INFO, dump);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering free(dump);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case SIGHUP:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering m->exit_code = MANAGER_RELOAD;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering default: {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Starting SIGRTMIN+0 */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering static const char * const target_table[] = {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [0] = SPECIAL_DEFAULT_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [1] = SPECIAL_RESCUE_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [2] = SPECIAL_EMERGENCY_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [3] = SPECIAL_HALT_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [4] = SPECIAL_POWEROFF_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [5] = SPECIAL_REBOOT_TARGET,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [6] = SPECIAL_KEXEC_TARGET
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering };
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering static const ManagerExitCode code_table[] = {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [0] = MANAGER_HALT,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [1] = MANAGER_POWEROFF,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [2] = MANAGER_REBOOT,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering [3] = MANAGER_KEXEC
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering };
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering int idx = (int) sfsi.ssi_signo - SIGRTMIN;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_start_target(m, target_table[idx],
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering switch (sfsi.ssi_signo - SIGRTMIN) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 20:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_debug("Enabling showing of status.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_set_show_status(m, true);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 21:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_debug("Disabling showing of status.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_set_show_status(m, false);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 22:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_max_level(LOG_DEBUG);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log level to debug.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 23:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_max_level(LOG_INFO);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log level to info.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 24:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (m->running_as == SYSTEMD_USER) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering m->exit_code = MANAGER_EXIT;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 0;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* This is a nop on init */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 26:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log target to journal-or-kmsg.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 27:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_target(LOG_TARGET_CONSOLE);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log target to console.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 28:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_target(LOG_TARGET_KMSG);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log target to kmsg.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case 29:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_notice("Setting log target to syslog-or-kmsg.");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering default:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (sigchld)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return manager_dispatch_sigchld(m);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 0;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int process_event(Manager *m, struct epoll_event *ev) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering int r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering Watch *w;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(m);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(ev);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert_se(w = ev->data.ptr);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (w->type == WATCH_INVALID)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 0;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering switch (w->type) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_SIGNAL:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* An incoming signal? */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (ev->events != EPOLLIN)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return -EINVAL;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if ((r = manager_process_signal_fd(m)) < 0)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_NOTIFY:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* An incoming daemon notification event? */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (ev->events != EPOLLIN)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return -EINVAL;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if ((r = manager_process_notify_fd(m)) < 0)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_FD:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Some fd event, to be dispatched to the units */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_UNIT_TIMER:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_JOB_TIMER: {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering uint64_t v;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering ssize_t k;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Some timer event, to be dispatched to the units */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering k = read(w->fd, &v, sizeof(v));
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (k != sizeof(v)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (k < 0 && (errno == EINTR || errno == EAGAIN))
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_error("Failed to read timer event counter: %s", k < 0 ? strerror(-k) : "Short read");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return k < 0 ? -errno : -EIO;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (w->type == WATCH_UNIT_TIMER)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering else
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering job_timer_event(w->data.job, v, w);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_MOUNT:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Some mount table change, intended for the mount subsystem */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering mount_fd_event(m, ev->events);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_SWAP:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Some swap table change, intended for the swap subsystem */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering swap_fd_event(m, ev->events);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_UDEV:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Some notification from udev, intended for the device subsystem */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering device_fd_event(m, ev->events);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_DBUS_WATCH:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering bus_watch_event(m, w, ev->events);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_DBUS_TIMEOUT:
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering bus_timeout_event(m, w, ev->events);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering case WATCH_TIME_CHANGE: {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering Unit *u;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering Iterator i;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_struct(LOG_INFO,
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering "MESSAGE=Time has been changed",
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering NULL);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Restart the watch */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering close_nointr_nofail(m->time_change_watch.fd);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering watch_init(&m->time_change_watch);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering manager_setup_time_change(m);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering HASHMAP_FOREACH(u, m->units, i) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (UNIT_VTABLE(u)->time_change)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering UNIT_VTABLE(u)->time_change(u);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering break;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case WATCH_JOBS_IN_PROGRESS: {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint64_t v;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
e40f0647b48b57af5e874501ad9c05dc459108deLennart Poettering /* not interested in the data */
e40f0647b48b57af5e874501ad9c05dc459108deLennart Poettering read(w->fd, &v, sizeof(v));
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering manager_print_jobs_in_progress(m);
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering break;
593f665cd5ffddbaa3ddbe9d963af923ed1cc5dcLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering default:
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error("event type=%i", w->type);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert_not_reached("Unknown epoll event type.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
a150ff5e4e2481eb28d6ed6e0d3e176623e25f5aLennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 0;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringint manager_loop(Manager *m) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering int r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->exit_code = MANAGER_RUNNING;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Release the path cache */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering set_free_free(m->unit_path_cache);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->unit_path_cache = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering manager_check_finished(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* There might still be some zombies hanging around from
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * before we were exec()'ed. Leat's reap them */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = manager_dispatch_sigchld(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering while (m->exit_code == MANAGER_RUNNING) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering struct epoll_event event;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering int n;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering int wait_msec = -1;
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering watchdog_ping();
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (!ratelimit_test(&rl)) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt /* Yay, something is going seriously wrong, pause a little */
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering log_warning("Looping too fast. Throttling execution a little.");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering sleep(1);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering continue;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering }
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (manager_dispatch_load_queue(m) > 0)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering continue;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (manager_dispatch_run_queue(m) > 0)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering continue;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (bus_dispatch(m) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (manager_dispatch_cleanup_queue(m) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (manager_dispatch_gc_queue(m) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (manager_dispatch_dbus_queue(m) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (swap_dispatch_reload(m) > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt /* Sleep for half the watchdog time */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (wait_msec <= 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt wait_msec = 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering wait_msec = -1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (n < 0) {
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (errno == EINTR)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -errno;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt } else if (n == 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(n == 1);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = process_event(m, &event);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering return r;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering }
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering return m->exit_code;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering}
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poetteringint manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering char *n;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering Unit *u;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt int r;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(s);
assert(_u);
if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
return -EINVAL;
n = bus_path_unescape(s+31);
if (!n)
return -ENOMEM;
r = manager_load_unit(m, n, NULL, e, &u);
free(n);
if (r < 0)
return r;
*_u = u;
return 0;
}
int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
Job *j;
unsigned id;
int r;
assert(m);
assert(s);
assert(_j);
if (!startswith(s, "/org/freedesktop/systemd1/job/"))
return -EINVAL;
r = safe_atou(s + 30, &id);
if (r < 0)
return r;
j = manager_get_job(m, id);
if (!j)
return -ENOENT;
*_j = j;
return 0;
}
void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
#ifdef HAVE_AUDIT
char *p;
int audit_fd;
audit_fd = get_audit_fd();
if (audit_fd < 0)
return;
/* Don't generate audit events if the service was already
* started and we're just deserializing */
if (m->n_reloading > 0)
return;
if (m->running_as != SYSTEMD_SYSTEM)
return;
if (u->type != UNIT_SERVICE)
return;
p = unit_name_to_prefix_and_instance(u->id);
if (!p) {
log_error_unit(u->id,
"Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
return;
}
if (audit_log_user_comm_message(audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
if (errno == EPERM) {
/* We aren't allowed to send audit messages?
* Then let's not retry again. */
close_audit_fd();
} else
log_warning("Failed to send audit message: %m");
}
free(p);
#endif
}
void manager_send_unit_plymouth(Manager *m, Unit *u) {
int fd = -1;
union sockaddr_union sa;
int n = 0;
char *message = NULL;
/* Don't generate plymouth events if the service was already
* started and we're just deserializing */
if (m->n_reloading > 0)
return;
if (m->running_as != SYSTEMD_SYSTEM)
return;
if (u->type != UNIT_SERVICE &&
u->type != UNIT_MOUNT &&
u->type != UNIT_SWAP)
return;
/* We set SOCK_NONBLOCK here so that we rather drop the
* message then wait for plymouth */
if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
log_error("socket() failed: %m");
return;
}
zero(sa);
sa.sa.sa_family = AF_UNIX;
strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
if (errno != EPIPE &&
errno != EAGAIN &&
errno != ENOENT &&
errno != ECONNREFUSED &&
errno != ECONNRESET &&
errno != ECONNABORTED)
log_error("connect() failed: %m");
goto finish;
}
if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
log_oom();
goto finish;
}
errno = 0;
if (write(fd, message, n + 1) != n + 1) {
if (errno != EPIPE &&
errno != EAGAIN &&
errno != ENOENT &&
errno != ECONNREFUSED &&
errno != ECONNRESET &&
errno != ECONNABORTED)
log_error("Failed to write Plymouth message: %m");
goto finish;
}
finish:
if (fd >= 0)
close_nointr_nofail(fd);
free(message);
}
void manager_dispatch_bus_name_owner_changed(
Manager *m,
const char *name,
const char* old_owner,
const char *new_owner) {
Unit *u;
assert(m);
assert(name);
if (!(u = hashmap_get(m->watch_bus, name)))
return;
UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
}
void manager_dispatch_bus_query_pid_done(
Manager *m,
const char *name,
pid_t pid) {
Unit *u;
assert(m);
assert(name);
assert(pid >= 1);
if (!(u = hashmap_get(m->watch_bus, name)))
return;
UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
}
int manager_open_serialization(Manager *m, FILE **_f) {
char *path = NULL;
mode_t saved_umask;
int fd;
FILE *f;
assert(_f);
if (m->running_as == SYSTEMD_SYSTEM)
asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
else
asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
if (!path)
return -ENOMEM;
saved_umask = umask(0077);
fd = mkostemp(path, O_RDWR|O_CLOEXEC);
umask(saved_umask);
if (fd < 0) {
free(path);
return -errno;
}
unlink(path);
log_debug("Serializing state to %s", path);
free(path);
f = fdopen(fd, "w+");
if (!f)
return -errno;
*_f = f;
return 0;
}
int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
Iterator i;
Unit *u;
const char *t;
char **e;
int r;
assert(m);
assert(f);
assert(fds);
m->n_reloading ++;
fprintf(f, "current-job-id=%i\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);
dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
if (!in_initrd()) {
dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
}
STRV_FOREACH(e, m->environment) {
_cleanup_free_ char *ce;
ce = cescape(*e);
if (ce)
fprintf(f, "env=%s\n", *e);
}
fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units, i) {
if (u->id != t)
continue;
if (!unit_can_serialize(u))
continue;
/* Start marker */
fputs(u->id, f);
fputc('\n', f);
if ((r = unit_serialize(u, f, fds, serialize_jobs)) < 0) {
m->n_reloading --;
return r;
}
}
assert(m->n_reloading > 0);
m->n_reloading --;
if (ferror(f))
return -EIO;
r = bus_fdset_add_all(m, fds);
if (r < 0)
return r;
return 0;
}
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
int r = 0;
assert(m);
assert(f);
log_debug("Deserializing state...");
m->n_reloading ++;
for (;;) {
char line[LINE_MAX], *l;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
r = 0;
else
r = -errno;
goto finish;
}
char_array_0(line);
l = strstrip(line);
if (l[0] == 0)
break;
if (startswith(l, "current-job-id=")) {
uint32_t id;
if (safe_atou32(l+15, &id) < 0)
log_debug("Failed to parse current job id value %s", l+15);
else
m->current_job_id = MAX(m->current_job_id, id);
} else if (startswith(l, "n-installed-jobs=")) {
uint32_t n;
if (safe_atou32(l+17, &n) < 0)
log_debug("Failed to parse installed jobs counter %s", l+17);
else
m->n_installed_jobs += n;
} else if (startswith(l, "n-failed-jobs=")) {
uint32_t n;
if (safe_atou32(l+14, &n) < 0)
log_debug("Failed to parse failed jobs counter %s", l+14);
else
m->n_failed_jobs += n;
} else if (startswith(l, "taint-usr=")) {
int b;
if ((b = parse_boolean(l+10)) < 0)
log_debug("Failed to parse taint /usr flag %s", l+10);
else
m->taint_usr = m->taint_usr || b;
} else if (startswith(l, "firmware-timestamp="))
dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
else if (startswith(l, "loader-timestamp="))
dual_timestamp_deserialize(l+17, &m->loader_timestamp);
else if (startswith(l, "kernel-timestamp="))
dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
else if (startswith(l, "initrd-timestamp="))
dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
else if (startswith(l, "userspace-timestamp="))
dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
else if (startswith(l, "finish-timestamp="))
dual_timestamp_deserialize(l+17, &m->finish_timestamp);
else if (startswith(l, "env=")) {
_cleanup_free_ char *uce = NULL;
char **e;
uce = cunescape(l+4);
if (!uce) {
r = -ENOMEM;
goto finish;
}
e = strv_env_set(m->environment, uce);
if (!e) {
r = -ENOMEM;
goto finish;
}
strv_free(m->environment);
m->environment = e;
} else
log_debug("Unknown serialization item '%s'", l);
}
for (;;) {
Unit *u;
char name[UNIT_NAME_MAX+2];
/* Start marker */
if (!fgets(name, sizeof(name), f)) {
if (feof(f))
r = 0;
else
r = -errno;
goto finish;
}
char_array_0(name);
r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
if (r < 0)
goto finish;
r = unit_deserialize(u, f, fds);
if (r < 0)
goto finish;
}
finish:
if (ferror(f)) {
r = -EIO;
goto finish;
}
assert(m->n_reloading > 0);
m->n_reloading --;
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;
assert(m);
r = manager_open_serialization(m, &f);
if (r < 0)
return r;
m->n_reloading ++;
fds = fdset_new();
if (!fds) {
m->n_reloading --;
r = -ENOMEM;
goto finish;
}
r = manager_serialize(m, f, fds, true);
if (r < 0) {
m->n_reloading --;
goto finish;
}
if (fseeko(f, 0, SEEK_SET) < 0) {
m->n_reloading --;
r = -errno;
goto finish;
}
/* From here on there is no way back. */
manager_clear_jobs_and_units(m);
manager_undo_generators(m);
lookup_paths_free(&m->lookup_paths);
/* Find new unit paths */
manager_run_generators(m);
q = lookup_paths_init(
&m->lookup_paths, m->running_as, true,
m->generator_unit_path,
m->generator_unit_path_early,
m->generator_unit_path_late);
if (q < 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)
r = q;
/* Second, deserialize our stored data */
q = manager_deserialize(m, f, fds);
if (q < 0)
r = q;
fclose(f);
f = NULL;
/* Third, fire things up! */
q = manager_coldplug(m);
if (q < 0)
r = q;
assert(m->n_reloading > 0);
m->n_reloading--;
finish:
if (f)
fclose(f);
if (fds)
fdset_free(fds);
return r;
}
static bool manager_is_booting_or_shutting_down(Manager *m) {
Unit *u;
assert(m);
/* Is the initial job still around? */
if (manager_get_job(m, m->default_unit_job_id))
return true;
/* Is there a job for the shutdown target? */
u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
if (u)
return !!u->job;
return false;
}
void manager_reset_failed(Manager *m) {
Unit *u;
Iterator i;
assert(m);
HASHMAP_FOREACH(u, m->units, i)
unit_reset_failed(u);
}
bool manager_unit_pending_inactive(Manager *m, const char *name) {
Unit *u;
assert(m);
assert(name);
/* Returns true if the unit is inactive or going down */
u = manager_get_unit(m, name);
if (!u)
return true;
return unit_pending_inactive(u);
}
void manager_check_finished(Manager *m) {
char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
assert(m);
if (m->n_running_jobs == 0)
manager_unwatch_jobs_in_progress(m);
if (hashmap_size(m->jobs) > 0)
return;
/* Notify Type=idle units that we are done now */
close_pipe(m->idle_pipe);
/* Turn off confirm spawn now */
m->confirm_spawn = false;
if (dual_timestamp_is_set(&m->finish_timestamp))
return;
dual_timestamp_get(&m->finish_timestamp);
if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
/* Note that m->kernel_usec.monotonic is always at 0,
* and m->firmware_usec.monotonic and
* m->loader_usec.monotonic should be considered
* negative values. */
firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
if (dual_timestamp_is_set(&m->initrd_timestamp)) {
kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
if (!log_on_console())
log_struct(LOG_INFO,
MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
"KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
"INITRD_USEC=%llu", (unsigned long long) initrd_usec,
"USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
"MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel), kernel_usec),
format_timespan(initrd, sizeof(initrd), initrd_usec),
format_timespan(userspace, sizeof(userspace), userspace_usec),
format_timespan(sum, sizeof(sum), total_usec),
NULL);
} else {
kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
initrd_usec = 0;
if (!log_on_console())
log_struct(LOG_INFO,
MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
"KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
"USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
"MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel), kernel_usec),
format_timespan(userspace, sizeof(userspace), userspace_usec),
format_timespan(sum, sizeof(sum), total_usec),
NULL);
}
} else {
firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
if (!log_on_console())
log_struct(LOG_INFO,
MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
"USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
"MESSAGE=Startup finished in %s.",
format_timespan(sum, sizeof(sum), total_usec),
NULL);
}
bus_broadcast_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
sd_notifyf(false,
"READY=1\nSTATUS=Startup finished in %s.",
format_timespan(sum, sizeof(sum), total_usec));
}
static int create_generator_dir(Manager *m, char **generator, const char *name) {
char *p;
int r;
assert(m);
assert(generator);
assert(name);
if (*generator)
return 0;
if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
p = strappend("/run/systemd/", name);
if (!p)
return log_oom();
r = mkdir_p_label(p, 0755);
if (r < 0) {
log_error("Failed to create generator directory %s: %s",
p, strerror(-r));
free(p);
return r;
}
} else {
p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
if (!p)
return log_oom();
if (!mkdtemp(p)) {
log_error("Failed to create generator directory %s: %m",
p);
free(p);
return -errno;
}
}
*generator = p;
return 0;
}
static void trim_generator_dir(Manager *m, char **generator) {
assert(m);
assert(generator);
if (!*generator)
return;
if (rmdir(*generator) >= 0) {
free(*generator);
*generator = NULL;
}
return;
}
void manager_run_generators(Manager *m) {
DIR *d = NULL;
const char *generator_path;
const char *argv[5];
mode_t u;
int r;
assert(m);
generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
d = opendir(generator_path);
if (!d) {
if (errno == ENOENT)
return;
log_error("Failed to enumerate generator directory %s: %m",
generator_path);
return;
}
r = create_generator_dir(m, &m->generator_unit_path, "generator");
if (r < 0)
goto finish;
r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
if (r < 0)
goto finish;
r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
if (r < 0)
goto finish;
argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
argv[1] = m->generator_unit_path;
argv[2] = m->generator_unit_path_early;
argv[3] = m->generator_unit_path_late;
argv[4] = NULL;
u = umask(0022);
execute_directory(generator_path, d, (char**) argv);
umask(u);
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);
finish:
if (d)
closedir(d);
}
static void remove_generator_dir(Manager *m, char **generator) {
assert(m);
assert(generator);
if (!*generator)
return;
strv_remove(m->lookup_paths.unit_path, *generator);
rm_rf(*generator, false, true, false);
free(*generator);
*generator = NULL;
}
void manager_undo_generators(Manager *m) {
assert(m);
remove_generator_dir(m, &m->generator_unit_path);
remove_generator_dir(m, &m->generator_unit_path_early);
remove_generator_dir(m, &m->generator_unit_path_late);
}
int manager_set_default_controllers(Manager *m, char **controllers) {
char **l;
assert(m);
l = strv_copy(controllers);
if (!l)
return -ENOMEM;
strv_free(m->default_controllers);
m->default_controllers = l;
cg_shorten_controllers(m->default_controllers);
return 0;
}
int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
int i;
assert(m);
for (i = 0; i < RLIMIT_NLIMITS; i++) {
if (!default_rlimit[i])
continue;
m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
if (!m->rlimit[i])
return -ENOMEM;
}
return 0;
}
void manager_recheck_journal(Manager *m) {
Unit *u;
assert(m);
if (m->running_as != SYSTEMD_SYSTEM)
return;
u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
if (u && SOCKET(u)->state != SOCKET_RUNNING) {
log_close_journal();
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 fully up and the service is up
* too, then let's make use of the thing. */
log_open();
}
void manager_set_show_status(Manager *m, bool b) {
assert(m);
if (m->running_as != SYSTEMD_SYSTEM)
return;
m->show_status = b;
if (b)
touch("/run/systemd/show-status");
else
unlink("/run/systemd/show-status");
}
static bool manager_get_show_status(Manager *m) {
assert(m);
if (m->running_as != SYSTEMD_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();
}
void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) {
va_list ap;
if (!manager_get_show_status(m))
return;
/* XXX We should totally drop the check for ephemeral here
* and thus effectively make 'Type=idle' pointless. */
if (ephemeral && m->n_on_console > 0)
return;
if (!manager_is_booting_or_shutting_down(m))
return;
va_start(ap, format);
status_vprintf(status, true, ephemeral, format, ap);
va_end(ap);
}
void watch_init(Watch *w) {
assert(w);
w->type = WATCH_INVALID;
w->fd = -1;
}