]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
sysdeps-unix: Factor out _dbus_reset_oom_score_adj
authorSimon McVittie <smcv@collabora.com>
Mon, 21 Feb 2022 15:41:41 +0000 (15:41 +0000)
committerSimon McVittie <smcv@collabora.com>
Tue, 22 Feb 2022 19:21:14 +0000 (19:21 +0000)
Signed-off-by: Simon McVittie <smcv@collabora.com>
dbus/dbus-spawn-unix.c
dbus/dbus-sysdeps-unix.h
dbus/dbus-sysdeps-util-unix.c

index 6a888eb572df15ac0c78195093cefcfea950d777..eecc3219bf19171cb87871e3d9dab73789b4ca27 100644 (file)
@@ -1444,26 +1444,14 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter          **sitter_p,
        }
       else if (grandchild_pid == 0)
         {
-#ifdef __linux__
-          int fd = -1;
+          const char *error_str = NULL;
 
-#ifdef O_CLOEXEC
-          fd = open ("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
-#endif
-
-          if (fd < 0)
+          if (!_dbus_reset_oom_score_adj (&error_str))
             {
-              fd = open ("/proc/self/oom_score_adj", O_WRONLY);
-              _dbus_fd_set_close_on_exec (fd);
+              /* TODO: Strictly speaking, this is not async-signal-safe. */
+              _dbus_warn ("%s: %s", error_str, strerror (errno));
             }
 
-          if (fd >= 0)
-            {
-              if (write (fd, "0", sizeof (char)) < 0)
-                _dbus_warn ("writing oom_score_adj error: %s", strerror (errno));
-              _dbus_close (fd, NULL);
-            }
-#endif
           /* Go back to ignoring SIGPIPE, since it's evil
            */
           signal (SIGPIPE, SIG_IGN);
index e86de6d94eb02e398663a9da3994dec54a4d5710..a051b5429b4681f8921ed988e79e68be7013a797 100644 (file)
@@ -174,6 +174,8 @@ typedef void (* DBusSignalHandler) (int sig);
 void _dbus_set_signal_handler (int               sig,
                                DBusSignalHandler handler);
 
+dbus_bool_t _dbus_reset_oom_score_adj (const char **error_str_p);
+
 /** @} */
 
 DBUS_END_DECLS
index 878ca2eaaa665f8745a8bdf2c852fc2077202411..799c6892aec47954a19bc50aef4c796637c932cf 100644 (file)
@@ -1603,3 +1603,68 @@ _dbus_daemon_report_stopping (void)
   sd_notify (0, "STOPPING=1");
 #endif
 }
+
+/**
+ * If the current process has been protected from the Linux OOM killer
+ * (the oom_score_adj process parameter is negative), reset it to the
+ * default level of protection from the OOM killer (set oom_score_adj
+ * to zero).
+ *
+ * This function does not use DBusError, to avoid calling malloc(), so
+ * that it can be used in contexts where an async-signal-safe function
+ * is required (for example after fork()). Instead, on failure it sets
+ * errno and returns something like "Failed to open /dev/null" in
+ * *error_str_p. Callers are expected to combine *error_str_p
+ * with _dbus_strerror (errno) to get a full error report.
+ */
+dbus_bool_t
+_dbus_reset_oom_score_adj (const char **error_str_p)
+{
+#ifdef __linux__
+  int fd = -1;
+  dbus_bool_t ret = FALSE;
+  int saved_errno = 0;
+  const char *error_str = NULL;
+
+#ifdef O_CLOEXEC
+  fd = open ("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
+#endif
+
+  if (fd < 0)
+    {
+      fd = open ("/proc/self/oom_score_adj", O_WRONLY);
+      _dbus_fd_set_close_on_exec (fd);
+    }
+
+  if (fd >= 0)
+    {
+      if (write (fd, "0", sizeof (char)) < 0)
+        {
+          ret = FALSE;
+          error_str = "writing oom_score_adj error";
+          saved_errno = errno;
+        }
+      else
+        {
+          ret = TRUE;
+        }
+
+      _dbus_close (fd, NULL);
+    }
+  else
+    {
+      /* TODO: Historically we ignored this error, although ideally we
+       * would diagnose it */
+      ret = TRUE;
+    }
+
+  if (error_str_p != NULL)
+    *error_str_p = error_str;
+
+  errno = saved_errno;
+  return ret;
+#else
+  /* nothing to do on this platform */
+  return TRUE;
+#endif
+}