Merge pull request #30268 from yuwata/network-fix-too-many-waiting-replies
network: fix issue caused by too many waiting replies
This commit is contained in:
@@ -107,5 +107,7 @@ int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, O
|
||||
|
||||
void netlink_seal_message(sd_netlink *nl, sd_netlink_message *m);
|
||||
|
||||
size_t netlink_get_reply_callback_count(sd_netlink *nl);
|
||||
|
||||
/* TODO: to be exported later */
|
||||
int sd_netlink_sendv(sd_netlink *nl, sd_netlink_message **messages, size_t msgcnt, uint32_t **ret_serial);
|
||||
|
||||
@@ -458,6 +458,12 @@ static int timeout_compare(const void *a, const void *b) {
|
||||
return CMP(x->timeout, y->timeout);
|
||||
}
|
||||
|
||||
size_t netlink_get_reply_callback_count(sd_netlink *nl) {
|
||||
assert(nl);
|
||||
|
||||
return hashmap_size(nl->reply_callbacks);
|
||||
}
|
||||
|
||||
int sd_netlink_call_async(
|
||||
sd_netlink *nl,
|
||||
sd_netlink_slot **ret_slot,
|
||||
@@ -477,7 +483,7 @@ int sd_netlink_call_async(
|
||||
assert_return(!netlink_pid_changed(nl), -ECHILD);
|
||||
|
||||
if (hashmap_size(nl->reply_callbacks) >= REPLY_CALLBACKS_MAX)
|
||||
return -ERANGE;
|
||||
return -EXFULL;
|
||||
|
||||
r = hashmap_ensure_allocated(&nl->reply_callbacks, &trivial_hash_ops);
|
||||
if (r < 0)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "networkd-queue.h"
|
||||
#include "string-table.h"
|
||||
|
||||
#define REPLY_CALLBACK_COUNT_THRESHOLD 128
|
||||
|
||||
static Request *request_free(Request *req) {
|
||||
if (!req)
|
||||
return NULL;
|
||||
@@ -220,6 +222,13 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
if (req->waiting_reply)
|
||||
continue; /* Waiting for netlink reply. */
|
||||
|
||||
/* Typically, requests send netlink message asynchronously. If there are many requests
|
||||
* queued, then this event may make reply callback queue in sd-netlink full. */
|
||||
if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
|
||||
return 0;
|
||||
|
||||
r = req->process(req, link, req->userdata);
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "firewall-util.h"
|
||||
#include "firewall-util-private.h"
|
||||
#include "log.h"
|
||||
#include "netlink-util.h"
|
||||
#include "string-table.h"
|
||||
|
||||
static const char * const firewall_backend_table[_FW_BACKEND_MAX] = {
|
||||
@@ -90,6 +91,13 @@ FirewallContext *fw_ctx_free(FirewallContext *ctx) {
|
||||
return mfree(ctx);
|
||||
}
|
||||
|
||||
size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx) {
|
||||
if (!ctx || !ctx->nfnl)
|
||||
return 0;
|
||||
|
||||
return netlink_get_reply_callback_count(ctx->nfnl);
|
||||
}
|
||||
|
||||
int fw_add_masquerade(
|
||||
FirewallContext **ctx,
|
||||
bool add,
|
||||
|
||||
@@ -15,6 +15,8 @@ FirewallContext *fw_ctx_free(FirewallContext *ctx);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(FirewallContext *, fw_ctx_free);
|
||||
|
||||
size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx);
|
||||
|
||||
int fw_add_masquerade(
|
||||
FirewallContext **ctx,
|
||||
bool add,
|
||||
|
||||
Reference in New Issue
Block a user