Blame SOURCES/0002-Repeat-pututxline-if-it-fails-with-EINTR.patch

f22e83
From 896b3694ca062d747cd67e9e9ba246adb3fc706b Mon Sep 17 00:00:00 2001
f22e83
From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
f22e83
Date: Mon, 5 Aug 2019 13:55:37 +0200
f22e83
Subject: [PATCH 2/2] Repeat pututxline() if it fails with EINTR
f22e83
f22e83
This is a partial fix for rhbz#1688848. We cannot resolve it
f22e83
completely until glibc bug rhbz#1734791 is fixed. See
f22e83
https://bugzilla.redhat.com/show_bug.cgi?id=1688848#c13.
f22e83
f22e83
The maximum number of attempts is currently 2, which might seem
f22e83
low. However setting it to 2 was a decision based on data - see
f22e83
https://bugzilla.redhat.com/show_bug.cgi?id=1688848#c16.
f22e83
f22e83
Resolves: rhbz#1688848
f22e83
---
f22e83
 sysdeputil.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-------
f22e83
 1 file changed, 46 insertions(+), 7 deletions(-)
f22e83
f22e83
diff --git a/sysdeputil.c b/sysdeputil.c
f22e83
index bd1e8c9..4fbcca7 100644
f22e83
--- a/sysdeputil.c
f22e83
+++ b/sysdeputil.c
f22e83
@@ -1203,6 +1203,8 @@ void
f22e83
 vsf_insert_uwtmp(const struct mystr* p_user_str,
f22e83
                  const struct mystr* p_host_str)
f22e83
 {
f22e83
+  int attempts;
f22e83
+
f22e83
   if (sizeof(s_utent.ut_line) < 16)
f22e83
   {
f22e83
     return;
f22e83
@@ -1231,16 +1233,35 @@ vsf_insert_uwtmp(const struct mystr* p_user_str,
f22e83
   vsf_sysutil_strcpy(s_utent.ut_host, str_getbuf(p_host_str),
f22e83
                      sizeof(s_utent.ut_host));
f22e83
   s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
f22e83
-  setutxent();
f22e83
-  (void) pututxline(&s_utent);
f22e83
-  endutxent();
f22e83
-  s_uwtmp_inserted = 1;
f22e83
+  for (attempts = 2; attempts > 0; --attempts)
f22e83
+  {
f22e83
+    struct utmpx* p_res;
f22e83
+    setutxent();
f22e83
+    p_res = pututxline(&s_utent);
f22e83
+    /* For now we'll ignore errors other than EINTR and EAGAIN */
f22e83
+    if (p_res != NULL || (errno != EINTR && errno != EAGAIN))
f22e83
+    {
f22e83
+      break;
f22e83
+    }
f22e83
+  }
f22e83
+  if (attempts == 0)
f22e83
+  {
f22e83
+    /* This makes us skip pututxline() in vsf_remove_uwtmp() */
f22e83
+    s_uwtmp_inserted = -1;
f22e83
+  }
f22e83
+  else
f22e83
+  {
f22e83
+    s_uwtmp_inserted = 1;
f22e83
+    endutxent();
f22e83
+  }
f22e83
   updwtmpx(WTMPX_FILE, &s_utent);
f22e83
 }
f22e83
 
f22e83
 void
f22e83
 vsf_remove_uwtmp(void)
f22e83
 {
f22e83
+  int attempts;
f22e83
+
f22e83
   if (!s_uwtmp_inserted)
f22e83
   {
f22e83
     return;
f22e83
@@ -1249,9 +1270,27 @@ vsf_remove_uwtmp(void)
f22e83
   vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));
f22e83
   vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));
f22e83
   s_utent.ut_tv.tv_sec = 0;
f22e83
-  setutxent();
f22e83
-  (void) pututxline(&s_utent);
f22e83
-  endutxent();
f22e83
+  if (s_uwtmp_inserted == 1)
f22e83
+  {
f22e83
+    for (attempts = 2; attempts > 0; --attempts)
f22e83
+    {
f22e83
+      struct utmpx* p_res;
f22e83
+      setutxent();
f22e83
+      p_res = pututxline(&s_utent);
f22e83
+      /* For now we'll ignore errors other than EINTR and EAGAIN */
f22e83
+      if (p_res != NULL || (errno != EINTR && errno != EAGAIN))
f22e83
+      {
f22e83
+        break;
f22e83
+      }
f22e83
+    }
f22e83
+    if (attempts != 0)
f22e83
+    {
f22e83
+      endutxent();
f22e83
+    }
f22e83
+  }
f22e83
+  /* Set s_uwtmp_inserted to 0 regardless of the result of
f22e83
+   * pututxline() to make sure we won't run this function twice.
f22e83
+   */
f22e83
   s_uwtmp_inserted = 0;
f22e83
   s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
f22e83
   updwtmpx(WTMPX_FILE, &s_utent);
f22e83
-- 
f22e83
2.20.1
f22e83