chiark / gitweb /
manager: both rescue and emergency should be started in isolate mode
[elogind.git] / src / manager.c
index c93b7912eb7df42b3bf6343db611fd1bc59f2c97..f9763c838a2faab722fd6b0720579818931d31b7 100644 (file)
@@ -32,7 +32,6 @@
 #include <sys/reboot.h>
 #include <sys/ioctl.h>
 #include <linux/kd.h>
-#include <libcgroup.h>
 #include <termios.h>
 #include <fcntl.h>
 #include <sys/types.h>
@@ -70,7 +69,6 @@ static int manager_setup_notify(Manager *m) {
                 struct sockaddr_un un;
         } sa;
         struct epoll_event ev;
-        char *ne[2], **t;
         int one = 1;
 
         assert(m);
@@ -106,19 +104,9 @@ static int manager_setup_notify(Manager *m) {
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
                 return -errno;
 
-        if (asprintf(&ne[0], "NOTIFY_SOCKET=@%s", sa.un.sun_path+1) < 0)
+        if (!(m->notify_socket = strdup(sa.un.sun_path+1)))
                 return -ENOMEM;
 
-        ne[1] = NULL;
-        t = strv_env_merge(2, m->environment, ne);
-        free(ne[0]);
-
-        if (!t)
-                return -ENOMEM;
-
-        strv_free(m->environment);
-        m->environment = t;
-
         return 0;
 }
 
@@ -188,7 +176,7 @@ static int manager_setup_signals(Manager *m) {
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
                 return -errno;
 
-        if (m->running_as == MANAGER_INIT)
+        if (m->running_as == MANAGER_SYSTEM)
                 return enable_special_signals(m);
 
         return 0;
@@ -197,6 +185,7 @@ static int manager_setup_signals(Manager *m) {
 int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
         Manager *m;
         int r = -ENOMEM;
+        char *p;
 
         assert(_m);
         assert(running_as >= 0);
@@ -211,6 +200,7 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
         m->confirm_spawn = confirm_spawn;
         m->name_data_slot = -1;
         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
+        m->pin_cgroupfs_fd = -1;
 
         m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
@@ -252,9 +242,16 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
                 goto fail;
 
         /* Try to connect to the busses, if possible. */
-        if ((r = bus_init_system(m)) < 0 ||
-            (r = bus_init_api(m)) < 0)
+        if ((r = bus_init(m)) < 0)
+                goto fail;
+
+        if (asprintf(&p, "%s/%s", m->cgroup_mount_point, m->cgroup_hierarchy) < 0) {
+                r = -ENOMEM;
                 goto fail;
+        }
+
+        m->pin_cgroupfs_fd = open(p, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
+        free(p);
 
         *_m = m;
         return 0;
@@ -273,7 +270,7 @@ static unsigned manager_dispatch_cleanup_queue(Manager *m) {
         while ((meta = m->cleanup_queue)) {
                 assert(meta->in_cleanup_queue);
 
-                unit_free(UNIT(meta));
+                unit_free((Unit*) meta);
                 n++;
         }
 
@@ -363,7 +360,7 @@ static unsigned manager_dispatch_gc_queue(Manager *m) {
         while ((meta = m->gc_queue)) {
                 assert(meta->in_gc_queue);
 
-                unit_gc_sweep(UNIT(meta), gc_marker);
+                unit_gc_sweep((Unit*) meta, gc_marker);
 
                 LIST_REMOVE(Meta, gc_queue, m->gc_queue, meta);
                 meta->in_gc_queue = false;
@@ -374,7 +371,7 @@ static unsigned manager_dispatch_gc_queue(Manager *m) {
                     meta->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
                         log_debug("Collecting %s", meta->id);
                         meta->gc_marker = gc_marker + GC_OFFSET_BAD;
-                        unit_add_to_cleanup_queue(UNIT(meta));
+                        unit_add_to_cleanup_queue((Unit*) meta);
                 }
         }
 
@@ -423,10 +420,10 @@ void manager_free(Manager *m) {
 
         /* If we reexecute ourselves, we keep the root cgroup
          * around */
-        manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
+        if (m->exit_code != MANAGER_REEXECUTE)
+                manager_shutdown_cgroup(m);
 
-        bus_done_api(m);
-        bus_done_system(m);
+        bus_done(m);
 
         hashmap_free(m->units);
         hashmap_free(m->jobs);
@@ -441,14 +438,20 @@ void manager_free(Manager *m) {
         if (m->notify_watch.fd >= 0)
                 close_nointr_nofail(m->notify_watch.fd);
 
+        free(m->notify_socket);
+
         lookup_paths_free(&m->lookup_paths);
         strv_free(m->environment);
 
         free(m->cgroup_controller);
         free(m->cgroup_hierarchy);
+        free(m->cgroup_mount_point);
 
         hashmap_free(m->cgroup_bondings);
 
+        if (m->pin_cgroupfs_fd >= 0)
+                close_nointr_nofail(m->pin_cgroupfs_fd);
+
         free(m);
 }
 
@@ -1436,7 +1439,7 @@ unsigned manager_dispatch_load_queue(Manager *m) {
         while ((meta = m->load_queue)) {
                 assert(meta->in_load_queue);
 
-                unit_load(UNIT(meta));
+                unit_load((Unit*) meta);
                 n++;
         }
 
@@ -1582,7 +1585,7 @@ unsigned manager_dispatch_dbus_queue(Manager *m) {
         while ((meta = m->dbus_unit_queue)) {
                 assert(meta->in_dbus_queue);
 
-                bus_unit_send_change_signal(UNIT(meta));
+                bus_unit_send_change_signal((Unit*) meta);
                 n++;
         }
 
@@ -1651,14 +1654,15 @@ static int manager_process_notify_fd(Manager *m) {
                                 continue;
                         }
 
-                char_array_0(buf);
+                assert((size_t) n < sizeof(buf));
+                buf[n] = 0;
                 if (!(tags = strv_split(buf, "\n\r")))
                         return -ENOMEM;
 
                 log_debug("Got notification message for unit %s", u->meta.id);
 
                 if (UNIT_VTABLE(u)->notify_message)
-                        UNIT_VTABLE(u)->notify_message(u, tags);
+                        UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
 
                 strv_free(tags);
         }
@@ -1697,7 +1701,7 @@ static int manager_dispatch_sigchld(Manager *m) {
                         char *name = NULL;
 
                         get_process_name(si.si_pid, &name);
-                        log_debug("Got SIGCHLD for process %llu (%s)", (unsigned long long) si.si_pid, strna(name));
+                        log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
                         free(name);
                 }
 
@@ -1723,8 +1727,8 @@ static int manager_dispatch_sigchld(Manager *m) {
                 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
                         continue;
 
-                log_debug("Child %llu died (code=%s, status=%i/%s)",
-                          (long long unsigned) si.si_pid,
+                log_debug("Child %lu died (code=%s, status=%i/%s)",
+                          (long unsigned) si.si_pid,
                           sigchld_code_to_string(si.si_code),
                           si.si_status,
                           strna(si.si_code == CLD_EXITED ? exit_status_to_string(si.si_status) : strsignal(si.si_status)));
@@ -1776,7 +1780,7 @@ static int manager_process_signal_fd(Manager *m) {
                         break;
 
                 case SIGTERM:
-                        if (m->running_as == MANAGER_INIT) {
+                        if (m->running_as == MANAGER_SYSTEM) {
                                 /* This is for compatibility with the
                                  * original sysvinit */
                                 m->exit_code = MANAGER_REEXECUTE;
@@ -1786,7 +1790,7 @@ static int manager_process_signal_fd(Manager *m) {
                         /* Fall through */
 
                 case SIGINT:
-                        if (m->running_as == MANAGER_INIT) {
+                        if (m->running_as == MANAGER_SYSTEM) {
                                 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
                                 break;
                         }
@@ -1800,14 +1804,14 @@ static int manager_process_signal_fd(Manager *m) {
                         break;
 
                 case SIGWINCH:
-                        if (m->running_as == MANAGER_INIT)
+                        if (m->running_as == MANAGER_SYSTEM)
                                 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
 
                         /* This is a nop on non-init */
                         break;
 
                 case SIGPWR:
-                        if (m->running_as == MANAGER_INIT)
+                        if (m->running_as == MANAGER_SYSTEM)
                                 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
 
                         /* This is a nop on non-init */
@@ -1820,8 +1824,7 @@ static int manager_process_signal_fd(Manager *m) {
 
                         if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
                                 log_info("Trying to reconnect to bus...");
-                                bus_init_system(m);
-                                bus_init_api(m);
+                                bus_init(m);
                         }
 
                         if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
@@ -1876,7 +1879,7 @@ static int manager_process_signal_fd(Manager *m) {
                         if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
                             (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
                                 manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
-                                                     sfsi.ssi_signo == 2 ? JOB_ISOLATE : JOB_REPLACE);
+                                                     (sfsi.ssi_signo == 1 || sfsi.ssi_signo == 2) ? JOB_ISOLATE : JOB_REPLACE);
                                 break;
                         }
 
@@ -2102,7 +2105,7 @@ void manager_write_utmp_reboot(Manager *m) {
         if (m->utmp_reboot_written)
                 return;
 
-        if (m->running_as != MANAGER_INIT)
+        if (m->running_as != MANAGER_SYSTEM)
                 return;
 
         if (!manager_utmp_good(m))
@@ -2128,7 +2131,7 @@ void manager_write_utmp_runlevel(Manager *m, Unit *u) {
         if (u->meta.type != UNIT_TARGET)
                 return;
 
-        if (m->running_as != MANAGER_INIT)
+        if (m->running_as != MANAGER_SYSTEM)
                 return;
 
         if (!manager_utmp_good(m))
@@ -2334,7 +2337,6 @@ finish:
 }
 
 static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
-        [MANAGER_INIT] = "init",
         [MANAGER_SYSTEM] = "system",
         [MANAGER_SESSION] = "session"
 };