From: Simon McVittie Date: Mon, 21 Feb 2022 15:41:41 +0000 (+0000) Subject: sysdeps-unix: Factor out _dbus_reset_oom_score_adj X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7200555694ed614cc91ddbc5dd17805f7d6d4111;p=platform%2Fupstream%2Fdbus.git sysdeps-unix: Factor out _dbus_reset_oom_score_adj Signed-off-by: Simon McVittie (cherry picked from commit f3ffe9a873708c679df88b9fc12b6b831539cf8a) --- diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index 61c7e61..b4aff67 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -1397,26 +1397,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); diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h index 830d5cd..5de8b73 100644 --- a/dbus/dbus-sysdeps-unix.h +++ b/dbus/dbus-sysdeps-unix.h @@ -173,6 +173,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 diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index cc7bbe6..dcf6dcf 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -1571,3 +1571,68 @@ _dbus_test_append_different_username (DBusString *username) } #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 +}