core: do not segfault if swap activity happens when /proc/swaps is not open

In https://bugzilla.redhat.com/show_bug.cgi?id=969795 systemd crashes
in swap_dispatch_reload called from manager_loop becuase m->proc_swaps
is NULL. It can legitimately be NULL if something went wrong when
initially enumerating swap devices when starting the manager. This
is probably a sign of significant trouble, but let's do our best
to recover.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2014-02-23 12:41:54 +00:00
committed by Colin Guthrie
parent 5d976fa2fa
commit f84b1b1ff9
+29 -16
View File
@@ -1068,14 +1068,40 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
return r;
}
static int open_proc_swaps(Manager *m) {
if (!m->proc_swaps) {
struct epoll_event ev = {
.events = EPOLLPRI,
.data.ptr = &m->swap_watch,
};
m->proc_swaps = fopen("/proc/swaps", "re");
if (!m->proc_swaps)
return (errno == ENOENT) ? 0 : -errno;
m->swap_watch.type = WATCH_SWAP;
m->swap_watch.fd = fileno(m->proc_swaps);
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
return -errno;
}
return 0;
}
int swap_dispatch_reload(Manager *m) {
/* This function should go as soon as the kernel properly notifies us */
int r;
if (_likely_(!m->request_reload))
return 0;
m->request_reload = false;
r = open_proc_swaps(m);
if (r < 0)
return r;
return swap_fd_event(m, EPOLLPRI);
}
@@ -1225,22 +1251,9 @@ static int swap_enumerate(Manager *m) {
int r;
assert(m);
if (!m->proc_swaps) {
struct epoll_event ev = {
.events = EPOLLPRI,
.data.ptr = &m->swap_watch,
};
m->proc_swaps = fopen("/proc/swaps", "re");
if (!m->proc_swaps)
return (errno == ENOENT) ? 0 : -errno;
m->swap_watch.type = WATCH_SWAP;
m->swap_watch.fd = fileno(m->proc_swaps);
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
return -errno;
}
r = open_proc_swaps(m);
if (r < 0)
return r;
r = swap_load_proc_swaps(m, false);
if (r < 0)