From 819fd2606618534f8de74235fd0c6478aca4cbcd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jan 2011 15:22:14 -0500 Subject: [PATCH] bus: Raise file descriptor limit to match configuration The default configuration has hardcoded 2048 complete connections, and 64 incomplete. We need at least that number of file descriptors, plus some for internal use. In the bus, attempt to call setrlimit() before we drop privileges. Practically speaking for this means the system bus gets it, the session bus doesn't. http://bugs.freedesktop.org/show_bug.cgi?id=33474 --- bus/bus.c | 20 +++++++++++++++++++ dbus/dbus-sysdeps-util-unix.c | 43 +++++++++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps-util-win.c | 5 ++++ dbus/dbus-sysdeps.h | 2 + 4 files changed, 70 insertions(+), 0 deletions(-) diff --git a/bus/bus.c b/bus/bus.c index f892e26..6663347 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -644,6 +644,24 @@ oom: return FALSE; } +static void +raise_file_descriptor_limit (BusContext *context) +{ + + /* I just picked this out of thin air; we need some extra + * descriptors for things like any internal pipes we create, + * inotify, connections to SELinux, etc. + */ + unsigned int arbitrary_extra_fds = 32; + unsigned int limit; + + limit = context->limits.max_completed_connections + + context->limits.max_incomplete_connections + + arbitrary_extra_fds; + + _dbus_request_file_descriptor_limit (limit); +} + static dbus_bool_t process_config_postinit (BusContext *context, BusConfigParser *parser, @@ -652,6 +670,8 @@ process_config_postinit (BusContext *context, DBusHashTable *service_context_table; DBusList *watched_dirs = NULL; + raise_file_descriptor_limit (context); + service_context_table = bus_config_parser_steal_service_context_table (parser); if (!bus_registry_set_service_context_table (context->registry, service_context_table)) diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 6e09245..fc20313 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -369,6 +370,48 @@ _dbus_change_to_daemon_user (const char *user, } #endif /* !HAVE_LIBAUDIT */ + +/** + * Attempt to ensure that the current process can open + * at least @limit file descriptors. + * + * If @limit is lower than the current, it will not be + * lowered. No error is returned if the request can + * not be satisfied. + * + * @limit Number of file descriptors + */ +void +_dbus_request_file_descriptor_limit (unsigned int limit) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit lim; + struct rlimit target_lim; + unsigned int current_limit; + + /* No point to doing this practically speaking + * if we're not uid 0. We expect the system + * bus to use this before we change UID, and + * the session bus takes the Linux default + * of 1024 for both cur and max. + */ + if (getuid () != 0) + return; + + if (getrlimit (RLIMIT_NOFILE, &lim) < 0) + return; + + if (lim.rlim_cur >= limit) + return; + + /* Ignore "maximum limit", assume we have the "superuser" + * privileges. On Linux this is CAP_SYS_RESOURCE. + */ + target_lim.rlim_cur = target_lim.rlim_max = limit; + setrlimit (RLIMIT_NOFILE, &target_lim); +#endif +} + void _dbus_init_system_log (void) { diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index 2f21409..f10100b 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -257,6 +257,11 @@ _dbus_change_to_daemon_user (const char *user, } void +_dbus_request_file_descriptor_limit (unsigned int limit) +{ +} + +void _dbus_init_system_log (void) { // FIXME! diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 3955d82..22d7969 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -517,6 +517,8 @@ dbus_bool_t _dbus_change_to_daemon_user (const char *user, void _dbus_flush_caches (void); +void _dbus_request_file_descriptor_limit (unsigned int limit); + /* * replaces the term DBUS_PREFIX in configure_time_path by the * current dbus installation directory. On unix this function is a noop -- 1.7.4