[PATCH 08/93] restorecond: Ignore IN_IGNORED inotify events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch looks good to me. acked.


I Believe we need to re-add because the inode changes?
>From 84b114a02a02d57eb02b583fcd255c7045343da3 Mon Sep 17 00:00:00 2001
From: Martin Orr <martin@xxxxxxxxxxxxxx>
Date: Thu, 24 Sep 2009 15:49:15 +0100
Subject: [PATCH 08/93] restorecond: Ignore IN_IGNORED inotify events

With kernel 2.6.31, restorecond uses 99% of my CPU.

This is because removing and readding the watch on utmp triggers inotify to
return an IN_IGNORED event for the old watch descriptor.  If the watch gets
allocated the same wd when it is readded, then restorecond thinks that utmp
has changed, so removes and readds the watch again, potentially looping.

With kernel <= 2.6.30, this never happened, because the kernel didn't reuse
watch descriptors.  So the IN_IGNORED event comes with a wd that is no
longer in use, and gets ignored.  But kernel 2.6.31 reuses the same watch
descriptor.

This patch fixes that by ignoring inotify events whose only bit set is
IN_IGNORED.

Note: it is not clear to me why it is necessary to remove and readd the
watch in the first place.

Note for testing: you need to log in (to cause a change in utmp) after
starting restorecond to trigger the bug.  In fact you need to log in twice
before the kernel reuses a watch descriptor.

Signed-off-by: Eric Paris <eparis@xxxxxxxxxx>
---
 policycoreutils/restorecond/restorecond.c |   29 ++++++++++++++++-------------
 1 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/policycoreutils/restorecond/restorecond.c b/policycoreutils/restorecond/restorecond.c
index 58774e6..4952632 100644
--- a/policycoreutils/restorecond/restorecond.c
+++ b/policycoreutils/restorecond/restorecond.c
@@ -315,21 +315,24 @@ static int watch(int fd)
 			printf("wd=%d mask=%u cookie=%u len=%u\n",
 			       event->wd, event->mask,
 			       event->cookie, event->len);
-		if (event->wd == master_wd)
-			read_config(fd);
-		else {
-			switch (utmpwatcher_handle(fd, event->wd)) {
-			case -1:	/* Message was not for utmpwatcher */
-				if (event->len)
-					watch_list_find(event->wd, event->name);
-				break;
 
-			case 1:	/* utmp has changed need to reload */
+		if (event->mask & ~IN_IGNORED) {
+			if (event->wd == master_wd)
 				read_config(fd);
-				break;
-
-			default:	/* No users logged in or out */
-				break;
+			else {
+				switch (utmpwatcher_handle(fd, event->wd)) {
+				case -1:	/* Message was not for utmpwatcher */
+					if (event->len)
+						watch_list_find(event->wd, event->name);
+					break;
+
+				case 1:	/* utmp has changed need to reload */
+					read_config(fd);
+					break;
+
+				default:	/* No users logged in or out */
+					break;
+				}
 			}
 		}
 
-- 
1.7.6


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux