1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 09:48:03 -08:00

sd-bus: base message queue length on the RAM size

Change "sd-bus: bump message queue size again" increased message queue
length, which leads to OOM on small systems when the communication gets
stuck. Base the queue length on the amount of RAM to prevent that.

Use RAM_TOTAL/(10 * 2048) as the total queue length.
This commit is contained in:
Petr Malat 2024-11-29 09:58:10 +01:00
parent aed18d7e9a
commit cbbc236fb8
2 changed files with 33 additions and 5 deletions

View File

@ -336,9 +336,6 @@ struct sd_bus {
* with enough entropy yet and might delay the boot */
#define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC)
#define BUS_WQUEUE_MAX (384*1024)
#define BUS_RQUEUE_MAX (384*1024)
#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
#define BUS_AUTH_SIZE_MAX (64*1024)
/* Note that the D-Bus specification states that bus paths shall have no size limit. We enforce here one

View File

@ -7,6 +7,7 @@
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/wait.h>
#include <unistd.h>
@ -2114,10 +2115,40 @@ static int bus_read_message(sd_bus *bus) {
return bus_socket_read_message(bus);
}
static bool bus_queue_is_full(sd_bus *bus) {
static size_t bus_queue_max;
assert(bus);
if (_unlikely_(!bus_queue_max)) {
struct sysinfo info;
if (sysinfo(&info)) {
bus_queue_max = 768 * 1024;
} else {
// Assume avg. message size of 2k, allow 10% of RAM
uint64_t count = info.totalram;
assert_se(MUL_ASSIGN_SAFE(&count, info.mem_unit));
count /= 10 * 2048;
if (count >= SIZE_MAX/2)
bus_queue_max = SIZE_MAX/2;
else
bus_queue_max = (size_t)count;
}
}
if (bus->rqueue_size + bus->wqueue_size >= bus_queue_max)
return true;
if (bus->rqueue_size + bus->wqueue_size < bus->wqueue_size)
return true;
return false;
}
int bus_rqueue_make_room(sd_bus *bus) {
assert(bus);
if (bus->rqueue_size >= BUS_RQUEUE_MAX)
if (bus_queue_is_full(bus))
return -ENOBUFS;
if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_size + 1))
@ -2230,7 +2261,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
} else {
/* Just append it to the queue. */
if (bus->wqueue_size >= BUS_WQUEUE_MAX)
if (bus_queue_is_full(bus))
return -ENOBUFS;
if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_size + 1))