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