Blob Blame History Raw
From 0c5711f9bae1cb46d4cd3fbe5d86d8688087be13 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 12 Jun 2020 20:45:23 +0200
Subject: [PATCH] util/inotify: fixed bug in inotify event processing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Error was spotted with the help of the following warning:
```
Error: CLANG_WARNING:
sssd-2.3.1/src/util/inotify.c:327:21: warning: Value stored to 'rewatch' is never read
 #                    rewatch = true;
 #                    ^         ~~~~
```

First part of the issue was that EAGAIN returned by the process_dir_event()
didn't trigger snotify_rewatch() (as suggested by the comments).
Fixing this part is already enough to resolve issue #1031 (as it was
reported).

Another part of the issue was that process_file_event() return code wasn't
checked against EAGAIN (again, as suggested by the DEBUG message).
Strictly speaking, I'm not sure if this part is really required or
if processing DIR events would cover all cases, but rebuilding watches
on IN_IGNORED won't hurt.

Resolves: https://github.com/SSSD/sssd/issues/1031

Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
 src/util/inotify.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/util/inotify.c b/src/util/inotify.c
index cf3e3d84d..a3c33eddb 100644
--- a/src/util/inotify.c
+++ b/src/util/inotify.c
@@ -286,7 +286,7 @@ static void snotify_internal_cb(struct tevent_context *ev,
     struct snotify_ctx *snctx;
     ssize_t len;
     errno_t ret;
-    bool rewatch;
+    bool rewatch = false;
 
     snctx = talloc_get_type(data, struct snotify_ctx);
     if (snctx == NULL) {
@@ -305,7 +305,7 @@ static void snotify_internal_cb(struct tevent_context *ev,
             } else {
                 DEBUG(SSSDBG_TRACE_INTERNAL, "All inotify events processed\n");
             }
-            return;
+            break;
         }
 
         if ((size_t) len < sizeof(struct inotify_event)) {
@@ -325,26 +325,22 @@ static void snotify_internal_cb(struct tevent_context *ev,
 
             if (snctx->wctx->dir_wd == in_event->wd) {
                 ret = process_dir_event(snctx, in_event);
-                if (ret == EAGAIN) {
-                    rewatch = true;
-                    /* Continue with the loop and read all the events from
-                     * this descriptor first, then rewatch when done
-                     */
-                } else if (ret != EOK) {
-                    DEBUG(SSSDBG_MINOR_FAILURE,
-                        "Failed to process inotify event\n");
-                    continue;
-                }
             } else if (snctx->wctx->file_wd == in_event->wd) {
                 ret = process_file_event(snctx, in_event);
-                if (ret != EOK) {
-                    DEBUG(SSSDBG_MINOR_FAILURE,
-                        "Failed to process inotify event\n");
-                    continue;
-                }
             } else {
                 DEBUG(SSSDBG_MINOR_FAILURE,
                       "Unknown watch %d\n", in_event->wd);
+                ret = EOK;
+            }
+
+            if (ret == EAGAIN) {
+                rewatch = true;
+                /* Continue with the loop and read all the events from
+                 * this descriptor first, then rewatch when done
+                 */
+            } else if (ret != EOK) {
+                DEBUG(SSSDBG_MINOR_FAILURE,
+                      "Failed to process inotify event\n");
             }
         }
     }
-- 
2.21.3