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,
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))
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
#include <grp.h>
#include <sys/socket.h>
#include <dirent.h>
}
#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;
+ /* Also ignore errors; if we fail, we will at least work
+ * up to whatever limit we had, which seems better than
+ * just outright aborting.
+ *
+ * However, in the future we should probably log this so OS builders
+ * have a chance to notice any misconfiguration like dbus-daemon
+ * being started without CAP_SYS_RESOURCE.
+ */
+ setrlimit (RLIMIT_NOFILE, &target_lim);
+#endif
+}
+
void
_dbus_init_system_log (void)
{