dcavalca / rpms / systemd

Forked from rpms/systemd 2 years ago
Clone
Zbigniew Jędrzejewski-Szmek a52f67
From f84b1b1ff9b1261cc9ee339fe0e5447f1573f807 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek b12ff7
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek b12ff7
Date: Sun, 12 Jan 2014 11:38:56 -0500
Zbigniew Jędrzejewski-Szmek b12ff7
Subject: [PATCH] core: do not segfault if swap activity happens when
Zbigniew Jędrzejewski-Szmek b12ff7
 /proc/swaps is not open
Zbigniew Jędrzejewski-Szmek b12ff7
Zbigniew Jędrzejewski-Szmek b12ff7
In https://bugzilla.redhat.com/show_bug.cgi?id=969795 systemd crashes
Zbigniew Jędrzejewski-Szmek b12ff7
in swap_dispatch_reload called from manager_loop becuase m->proc_swaps
Zbigniew Jędrzejewski-Szmek b12ff7
is NULL. It can legitimately be NULL if something went wrong when
Zbigniew Jędrzejewski-Szmek b12ff7
initially enumerating swap devices when starting the manager. This
Zbigniew Jędrzejewski-Szmek b12ff7
is probably a sign of significant trouble, but let's do our best
Zbigniew Jędrzejewski-Szmek b12ff7
to recover.
Zbigniew Jędrzejewski-Szmek b12ff7
---
Zbigniew Jędrzejewski-Szmek b12ff7
 src/core/swap.c | 45 +++++++++++++++++++++++++++++----------------
Zbigniew Jędrzejewski-Szmek b12ff7
 1 file changed, 29 insertions(+), 16 deletions(-)
Zbigniew Jędrzejewski-Szmek b12ff7
Zbigniew Jędrzejewski-Szmek b12ff7
diff --git a/src/core/swap.c b/src/core/swap.c
Zbigniew Jędrzejewski-Szmek b12ff7
index 147f710..f295b65 100644
Zbigniew Jędrzejewski-Szmek b12ff7
--- a/src/core/swap.c
Zbigniew Jędrzejewski-Szmek b12ff7
+++ b/src/core/swap.c
Zbigniew Jędrzejewski-Szmek b12ff7
@@ -1068,14 +1068,40 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
Zbigniew Jędrzejewski-Szmek b12ff7
         return r;
Zbigniew Jędrzejewski-Szmek b12ff7
 }
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
+static int open_proc_swaps(Manager *m) {
Zbigniew Jędrzejewski-Szmek b12ff7
+        if (!m->proc_swaps) {
Zbigniew Jędrzejewski-Szmek b12ff7
+                struct epoll_event ev = {
Zbigniew Jędrzejewski-Szmek b12ff7
+                        .events = EPOLLPRI,
Zbigniew Jędrzejewski-Szmek b12ff7
+                        .data.ptr = &m->swap_watch,
Zbigniew Jędrzejewski-Szmek b12ff7
+                };
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
+                m->proc_swaps = fopen("/proc/swaps", "re");
Zbigniew Jędrzejewski-Szmek b12ff7
+                if (!m->proc_swaps)
Zbigniew Jędrzejewski-Szmek b12ff7
+                        return (errno == ENOENT) ? 0 : -errno;
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
+                m->swap_watch.type = WATCH_SWAP;
Zbigniew Jędrzejewski-Szmek b12ff7
+                m->swap_watch.fd = fileno(m->proc_swaps);
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
+                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
Zbigniew Jędrzejewski-Szmek b12ff7
+                        return -errno;
Zbigniew Jędrzejewski-Szmek b12ff7
+        }
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
+        return 0;
Zbigniew Jędrzejewski-Szmek b12ff7
+}
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
 int swap_dispatch_reload(Manager *m) {
Zbigniew Jędrzejewski-Szmek b12ff7
         /* This function should go as soon as the kernel properly notifies us */
Zbigniew Jędrzejewski-Szmek b12ff7
+        int r;
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
         if (_likely_(!m->request_reload))
Zbigniew Jędrzejewski-Szmek b12ff7
                 return 0;
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
         m->request_reload = false;
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
+        r = open_proc_swaps(m);
Zbigniew Jędrzejewski-Szmek b12ff7
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek b12ff7
+                return r;
Zbigniew Jędrzejewski-Szmek b12ff7
+
Zbigniew Jędrzejewski-Szmek b12ff7
         return swap_fd_event(m, EPOLLPRI);
Zbigniew Jędrzejewski-Szmek b12ff7
 }
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
@@ -1225,22 +1251,9 @@ static int swap_enumerate(Manager *m) {
Zbigniew Jędrzejewski-Szmek b12ff7
         int r;
Zbigniew Jędrzejewski-Szmek b12ff7
         assert(m);
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
-        if (!m->proc_swaps) {
Zbigniew Jędrzejewski-Szmek b12ff7
-                struct epoll_event ev = {
Zbigniew Jędrzejewski-Szmek b12ff7
-                        .events = EPOLLPRI,
Zbigniew Jędrzejewski-Szmek b12ff7
-                        .data.ptr = &m->swap_watch,
Zbigniew Jędrzejewski-Szmek b12ff7
-                };
Zbigniew Jędrzejewski-Szmek b12ff7
-
Zbigniew Jędrzejewski-Szmek b12ff7
-                m->proc_swaps = fopen("/proc/swaps", "re");
Zbigniew Jędrzejewski-Szmek b12ff7
-                if (!m->proc_swaps)
Zbigniew Jędrzejewski-Szmek b12ff7
-                        return (errno == ENOENT) ? 0 : -errno;
Zbigniew Jędrzejewski-Szmek b12ff7
-
Zbigniew Jędrzejewski-Szmek b12ff7
-                m->swap_watch.type = WATCH_SWAP;
Zbigniew Jędrzejewski-Szmek b12ff7
-                m->swap_watch.fd = fileno(m->proc_swaps);
Zbigniew Jędrzejewski-Szmek b12ff7
-
Zbigniew Jędrzejewski-Szmek b12ff7
-                if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
Zbigniew Jędrzejewski-Szmek b12ff7
-                        return -errno;
Zbigniew Jędrzejewski-Szmek b12ff7
-        }
Zbigniew Jędrzejewski-Szmek b12ff7
+        r = open_proc_swaps(m);
Zbigniew Jędrzejewski-Szmek b12ff7
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek b12ff7
+                return r;
Zbigniew Jędrzejewski-Szmek b12ff7
 
Zbigniew Jędrzejewski-Szmek b12ff7
         r = swap_load_proc_swaps(m, false);
Zbigniew Jędrzejewski-Szmek b12ff7
         if (r < 0)