[systemd-commits] src/shutdown.c src/systemd src/util.c src/util.h

Lennart Poettering lennart at kemper.freedesktop.org
Mon Jan 9 20:04:13 PST 2012


 src/shutdown.c           |   44 ++++++++++++++++++++++++++--------------
 src/systemd/sd-journal.h |    4 +++
 src/util.c               |   51 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util.h               |    1 
 4 files changed, 85 insertions(+), 15 deletions(-)

New commits:
commit 7e4ab3c5a6295193d0c58d353b6430265d842f34
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 10 04:20:55 2012 +0100

    shutdown: exclude processes with argv[0][0] from killing

diff --git a/src/shutdown.c b/src/shutdown.c
index 11213f9..46b5aea 100644
--- a/src/shutdown.c
+++ b/src/shutdown.c
@@ -47,29 +47,45 @@
 #define FINALIZE_ATTEMPTS 50
 
 static bool ignore_proc(pid_t pid) {
+        char buf[PATH_MAX];
+        FILE *f;
+        char c;
+        size_t count;
+        uid_t uid;
+        int r;
+
+        /* We are PID 1, let's not commit suicide */
         if (pid == 1)
                 return true;
 
-        /* TODO: add more ignore rules here: device-mapper, etc */
+        r = get_process_uid(pid, &uid);
+        if (r < 0)
+                return true; /* not really, but better safe than sorry */
 
-        return false;
-}
+        /* Non-root processes otherwise are always subject to be killed */
+        if (uid != 0)
+                return false;
 
-static bool is_kernel_thread(pid_t pid)
-{
-        char buf[PATH_MAX];
-        FILE *f;
-        char c;
-        size_t count;
+        snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
+        char_array_0(buf);
 
-        snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long)pid);
         f = fopen(buf, "re");
         if (!f)
                 return true; /* not really, but has the desired effect */
 
         count = fread(&c, 1, 1, f);
         fclose(f);
-        return count != 1;
+
+        /* Kernel threads have an empty cmdline */
+        if (count <= 0)
+                return true;
+
+        /* Processes with argv[0][0] = '@' we ignore from the killing
+         * spree. */
+        if (count == 1 && c == '@')
+                return true;
+
+        return false;
 }
 
 static int killall(int sign) {
@@ -77,7 +93,8 @@ static int killall(int sign) {
         struct dirent *d;
         unsigned int n_processes = 0;
 
-        if ((dir = opendir("/proc")) == NULL)
+        dir = opendir("/proc");
+        if (!dir)
                 return -errno;
 
         while ((d = readdir(dir))) {
@@ -86,9 +103,6 @@ static int killall(int sign) {
                 if (parse_pid(d->d_name, &pid) < 0)
                         continue;
 
-                if (is_kernel_thread(pid))
-                        continue;
-
                 if (ignore_proc(pid))
                         continue;
 
diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
index f805bf9..d0cb950 100644
--- a/src/systemd/sd-journal.h
+++ b/src/systemd/sd-journal.h
@@ -36,6 +36,10 @@
  *   - accelerate looking for "all hostnames" and suchlike.
  *   - handle incomplete header
  *
+ *   - kann NTP nicht finden?
+ *   - in unit.c check ob syslog.socket wegen logging reconnect is kaputt
+ *
+ *
  *   - local deserializer
  *   - http server
  *   - message catalog
diff --git a/src/util.c b/src/util.c
index b4c5e2e..3179502 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1119,6 +1119,57 @@ int get_process_exe(pid_t pid, char **name) {
         return r;
 }
 
+int get_process_uid(pid_t pid, uid_t *uid) {
+        char *p;
+        FILE *f;
+        int r;
+
+        assert(uid);
+
+        if (pid == 0)
+                return getuid();
+
+        if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
+                return -ENOMEM;
+
+        f = fopen(p, "re");
+        free(p);
+
+        if (!f)
+                return -errno;
+
+        while (!feof(f)) {
+                char line[LINE_MAX], *l;
+
+                if (!fgets(line, sizeof(line), f)) {
+                        if (feof(f))
+                                break;
+
+                        r = -errno;
+                        goto finish;
+                }
+
+                l = strstrip(line);
+
+                if (startswith(l, "Uid:")) {
+                        l += 4;
+                        l += strspn(l, WHITESPACE);
+
+                        l[strcspn(l, WHITESPACE)] = 0;
+
+                        r = parse_uid(l, uid);
+                        goto finish;
+                }
+        }
+
+        r = -EIO;
+
+finish:
+        fclose(f);
+
+        return r;
+}
+
 char *strnappend(const char *s, const char *suffix, size_t b) {
         size_t a;
         char *r;
diff --git a/src/util.h b/src/util.h
index be05cc8..8de608f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -251,6 +251,7 @@ int rmdir_parents(const char *path, const char *stop);
 int get_process_comm(pid_t pid, char **name);
 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
 int get_process_exe(pid_t pid, char **name);
+int get_process_uid(pid_t pid, uid_t *uid);
 
 char hexchar(int x);
 int unhexchar(char c);



More information about the systemd-commits mailing list