]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxccontainer: detect if we should send SIGRTMIN+3 1086/head
authorChristian Brauner <cbrauner@suse.de>
Mon, 18 Jul 2016 20:21:56 +0000 (22:21 +0200)
committerChristian Brauner <cbrauner@suse.de>
Tue, 19 Jul 2016 14:20:02 +0000 (16:20 +0200)
This is required by systemd to cleanly shutdown. Other init systems should not
have SIGRTMIN+3 in the blocked signals set.

Signed-off-by: Christian Brauner <cbrauner@suse.de>
src/lxc/lxccontainer.c
src/lxc/utils.c
src/lxc/utils.h

index 4a4dc42baf92dcb773955735238cc99b1379fb26..8ea0005beb6c6489125da7b21435893dc55adbe4 100644 (file)
@@ -1604,8 +1604,16 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
        pid = do_lxcapi_init_pid(c);
        if (pid <= 0)
                return true;
+
+       /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
+       if (task_blocking_signal(pid, (SIGRTMIN + 3)))
+               haltsignal = (SIGRTMIN + 3);
+
        if (c->lxc_conf && c->lxc_conf->haltsignal)
                haltsignal = c->lxc_conf->haltsignal;
+
+       INFO("Using signal number '%d' as halt signal.", haltsignal);
+
        kill(pid, haltsignal);
        retv = do_lxcapi_wait(c, "STOPPED", timeout);
        return retv;
index 5c35ae8dd7033840bd730729adaa689f14a7d91b..614add5363d12dc88487f42acbe95e50eea407ee 100644 (file)
@@ -1838,3 +1838,41 @@ int lxc_strmunmap(void *addr, size_t length)
 {
        return munmap(addr, length + 1);
 }
+
+/* Check whether a signal is blocked by a process. */
+bool task_blocking_signal(pid_t pid, int signal)
+{
+       bool bret = false;
+       char *line = NULL;
+       long unsigned int sigblk = 0;
+       size_t n = 0;
+       int ret;
+       FILE *f;
+
+       /* The largest integer that can fit into long int is 2^64. This is a
+        * 20-digit number. */
+       size_t len = /* /proc */ 5 + /* /pid-to-str */ 21 + /* /status */ 7 + /* \0 */ 1;
+       char status[len];
+
+       ret = snprintf(status, len, "/proc/%d/status", pid);
+       if (ret < 0 || ret >= len)
+               return bret;
+
+       f = fopen(status, "r");
+       if (!f)
+               return bret;
+
+       while (getline(&line, &n, f) != -1) {
+               if (!strncmp(line, "SigBlk:\t", 8))
+                       if (sscanf(line + 8, "%lx", &sigblk) != 1)
+                               goto out;
+       }
+
+       if (sigblk & signal)
+               bret = true;
+
+out:
+       free(line);
+       fclose(f);
+       return bret;
+}
index 22161cbf65fd51ae2be06946ada6644377d86878..b541e07ec29c2791417662e68379315b8f4362b0 100644 (file)
@@ -296,4 +296,7 @@ int open_devnull(void);
 int set_stdfds(int fd);
 int null_stdfds(void);
 int lxc_count_file_lines(const char *fn);
+
+/* Check whether a signal is blocked by a process. */
+bool task_blocking_signal(pid_t pid, int signal);
 #endif /* __LXC_UTILS_H */