Skip to content

Commit ac116f8

Browse files
authored
Merge pull request #30268 from yuwata/network-fix-too-many-waiting-replies
network: fix issue caused by too many waiting replies
2 parents ef87c84 + 4e6a35e commit ac116f8

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

src/libsystemd/sd-netlink/netlink-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,7 @@ int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, O
107107

108108
void netlink_seal_message(sd_netlink *nl, sd_netlink_message *m);
109109

110+
size_t netlink_get_reply_callback_count(sd_netlink *nl);
111+
110112
/* TODO: to be exported later */
111113
int sd_netlink_sendv(sd_netlink *nl, sd_netlink_message **messages, size_t msgcnt, uint32_t **ret_serial);

src/libsystemd/sd-netlink/sd-netlink.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ static int timeout_compare(const void *a, const void *b) {
458458
return CMP(x->timeout, y->timeout);
459459
}
460460

461+
size_t netlink_get_reply_callback_count(sd_netlink *nl) {
462+
assert(nl);
463+
464+
return hashmap_size(nl->reply_callbacks);
465+
}
466+
461467
int sd_netlink_call_async(
462468
sd_netlink *nl,
463469
sd_netlink_slot **ret_slot,
@@ -477,7 +483,7 @@ int sd_netlink_call_async(
477483
assert_return(!netlink_pid_changed(nl), -ECHILD);
478484

479485
if (hashmap_size(nl->reply_callbacks) >= REPLY_CALLBACKS_MAX)
480-
return -ERANGE;
486+
return -EXFULL;
481487

482488
r = hashmap_ensure_allocated(&nl->reply_callbacks, &trivial_hash_ops);
483489
if (r < 0)

src/network/networkd-queue.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "networkd-queue.h"
88
#include "string-table.h"
99

10+
#define REPLY_CALLBACK_COUNT_THRESHOLD 128
11+
1012
static Request *request_free(Request *req) {
1113
if (!req)
1214
return NULL;
@@ -220,6 +222,13 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
220222
if (req->waiting_reply)
221223
continue; /* Waiting for netlink reply. */
222224

225+
/* Typically, requests send netlink message asynchronously. If there are many requests
226+
* queued, then this event may make reply callback queue in sd-netlink full. */
227+
if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
228+
netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
229+
fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
230+
return 0;
231+
223232
r = req->process(req, link, req->userdata);
224233
if (r == 0)
225234
continue;

src/shared/firewall-util.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "firewall-util.h"
99
#include "firewall-util-private.h"
1010
#include "log.h"
11+
#include "netlink-util.h"
1112
#include "string-table.h"
1213

1314
static const char * const firewall_backend_table[_FW_BACKEND_MAX] = {
@@ -90,6 +91,13 @@ FirewallContext *fw_ctx_free(FirewallContext *ctx) {
9091
return mfree(ctx);
9192
}
9293

94+
size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx) {
95+
if (!ctx || !ctx->nfnl)
96+
return 0;
97+
98+
return netlink_get_reply_callback_count(ctx->nfnl);
99+
}
100+
93101
int fw_add_masquerade(
94102
FirewallContext **ctx,
95103
bool add,

src/shared/firewall-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ FirewallContext *fw_ctx_free(FirewallContext *ctx);
1515

1616
DEFINE_TRIVIAL_CLEANUP_FUNC(FirewallContext *, fw_ctx_free);
1717

18+
size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx);
19+
1820
int fw_add_masquerade(
1921
FirewallContext **ctx,
2022
bool add,

0 commit comments

Comments
 (0)