summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-10-18 23:09:09 +0200
committerLennart Poettering <lennart@poettering.net>2010-10-18 23:09:09 +0200
commit4e4343146ade25b1ccfc927e2807d854be863ec4 (patch)
treee33d93110852b91bdf43732a538283c651346894
parent5a33f657b52f30a77fac41feb8854b563d77382e (diff)
swap: listen for POLLPRI events on /proc/swaps if available
-rw-r--r--TODO6
-rw-r--r--src/manager.c7
-rw-r--r--src/manager.h2
-rw-r--r--src/mount.c4
-rw-r--r--src/swap.c29
-rw-r--r--src/swap.h1
6 files changed, 37 insertions, 12 deletions
diff --git a/TODO b/TODO
index a1bdcade1c..0e7987dff7 100644
--- a/TODO
+++ b/TODO
@@ -48,8 +48,6 @@
* system.conf/session.conf man page
-* exec /sbin/poweroff as PID 1 and do the shutdown
-
* suspend, resume
* passphrase agent https://bugs.freedesktop.org/show_bug.cgi?id=30038
@@ -84,14 +82,14 @@ External:
* patch kernel for cpu feature modalias for autoloading aes/kvm/...
+* patch fsck to support --lock
+
* place /etc/inittab with explaining blurb.
* pam_securetty should honour console=
* procps, psmisc, sysvinit-tools, hostname → util-linux-ng
-* nologin nach /var/run https://bugzilla.redhat.com/show_bug.cgi?id=624489
-
* make sysinit honour forcefsck/fastboot from the kernel command line fsck.mode=auto|force|skip
* pam: fix double sudo session cleanup:
diff --git a/src/manager.c b/src/manager.c
index e4559ffcb8..fb2656eb3d 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -216,7 +216,7 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) {
m->audit_fd = -1;
#endif
- m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1;
+ m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
if (!(m->environment = strv_copy(environ)))
@@ -2171,6 +2171,11 @@ static int process_event(Manager *m, struct epoll_event *ev) {
mount_fd_event(m, ev->events);
break;
+ case WATCH_SWAP:
+ /* Some swap table change, intended for the swap subsystem */
+ swap_fd_event(m, ev->events);
+ break;
+
case WATCH_UDEV:
/* Some notification from udev, intended for the device subsystem */
device_fd_event(m, ev->events);
diff --git a/src/manager.h b/src/manager.h
index a573debe03..8a64750584 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -64,6 +64,7 @@ enum WatchType {
WATCH_UNIT_TIMER,
WATCH_JOB_TIMER,
WATCH_MOUNT,
+ WATCH_SWAP,
WATCH_UDEV,
WATCH_DBUS_WATCH,
WATCH_DBUS_TIMEOUT
@@ -161,6 +162,7 @@ struct Manager {
FILE *proc_swaps;
Hashmap *swaps_by_proc_swaps;
bool request_reload;
+ Watch swap_watch;
/* Data specific to the D-Bus subsystem */
DBusConnection *api_bus, *system_bus;
diff --git a/src/mount.c b/src/mount.c
index c7df923f85..284fcb94b2 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -1526,7 +1526,7 @@ static int mount_enumerate(Manager *m) {
m->mount_watch.fd = fileno(m->proc_self_mountinfo);
zero(ev);
- ev.events = EPOLLERR;
+ ev.events = EPOLLPRI;
ev.data.ptr = &m->mount_watch;
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
@@ -1551,7 +1551,7 @@ void mount_fd_event(Manager *m, int events) {
int r;
assert(m);
- assert(events == EPOLLERR);
+ assert(events & EPOLLPRI);
/* The manager calls this for every fd event happening on the
* /proc/self/mountinfo file, which informs us about mounting
diff --git a/src/swap.c b/src/swap.c
index 487b18350a..cf9644fc69 100644
--- a/src/swap.c
+++ b/src/swap.c
@@ -1056,16 +1056,23 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
}
int swap_dispatch_reload(Manager *m) {
- Meta *meta;
- int r;
-
- assert(m);
+ /* This function should go as soon as the kernel properly notifies us */
if (_likely_(!m->request_reload))
return 0;
m->request_reload = false;
+ return swap_fd_event(m, EPOLLPRI);
+}
+
+int swap_fd_event(Manager *m, int events) {
+ Meta *meta;
+ int r;
+
+ assert(m);
+ assert(events & EPOLLPRI);
+
if ((r == swap_load_proc_swaps(m, true)) < 0) {
log_error("Failed to reread /proc/swaps: %s", strerror(-r));
@@ -1169,12 +1176,24 @@ static void swap_shutdown(Manager *m) {
static int swap_enumerate(Manager *m) {
int r;
+ struct epoll_event ev;
assert(m);
- if (!m->proc_swaps)
+ if (!m->proc_swaps) {
if (!(m->proc_swaps = fopen("/proc/swaps", "re")))
return -errno;
+ m->swap_watch.type = WATCH_SWAP;
+ m->swap_watch.fd = fileno(m->proc_swaps);
+
+ zero(ev);
+ ev.events = EPOLLPRI;
+ ev.data.ptr = &m->swap_watch;
+
+ if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0)
+ return -errno;
+ }
+
/* We rely on mount.c to load /etc/fstab for us */
if ((r = swap_load_proc_swaps(m, false)) < 0)
diff --git a/src/swap.h b/src/swap.h
index 8a60416900..c39caa6658 100644
--- a/src/swap.h
+++ b/src/swap.h
@@ -103,6 +103,7 @@ int swap_add_one(Manager *m, const char *what, const char *what_proc_swaps, int
int swap_add_one_mount_link(Swap *s, Mount *m);
int swap_dispatch_reload(Manager *m);
+int swap_fd_event(Manager *m, int events);
const char* swap_state_to_string(SwapState i);
SwapState swap_state_from_string(const char *s);