kernel-netlink: Add options to enable parallel Netlink queries explicitly
As under vanilla Linux the kernel can't handle parallel dump queries and returns EBUSY, it makes not much sense to use them. Disable parallel queries by default to basically restore original behavior, improving performance.
This commit is contained in:
@@ -2711,7 +2711,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names);
|
||||
this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names,
|
||||
lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns));
|
||||
if (!this->socket_xfrm)
|
||||
{
|
||||
destroy(this);
|
||||
|
||||
@@ -2499,7 +2499,9 @@ kernel_netlink_net_t *kernel_netlink_net_create()
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names),
|
||||
.socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names,
|
||||
lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)),
|
||||
.rt_exclude = linked_list_create(),
|
||||
.routes = hashtable_create((hashtable_hash_t)route_entry_hash,
|
||||
(hashtable_equals_t)route_entry_equals, 16),
|
||||
|
||||
@@ -75,6 +75,11 @@ struct private_netlink_socket_t {
|
||||
* Number of times to repeat timed out queries
|
||||
*/
|
||||
u_int retries;
|
||||
|
||||
/**
|
||||
* Use parallel netlink queries
|
||||
*/
|
||||
bool parallel;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -290,7 +295,8 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
|
||||
|
||||
while (!entry->complete)
|
||||
{
|
||||
if (lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
|
||||
if (this->parallel &&
|
||||
lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
|
||||
{
|
||||
if (this->timeout)
|
||||
{
|
||||
@@ -450,7 +456,10 @@ METHOD(netlink_socket_t, destroy, void,
|
||||
{
|
||||
if (this->socket != -1)
|
||||
{
|
||||
lib->watcher->remove(lib->watcher, this->socket);
|
||||
if (this->parallel)
|
||||
{
|
||||
lib->watcher->remove(lib->watcher, this->socket);
|
||||
}
|
||||
close(this->socket);
|
||||
}
|
||||
this->entries->destroy(this->entries);
|
||||
@@ -461,7 +470,8 @@ METHOD(netlink_socket_t, destroy, void,
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
|
||||
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
|
||||
bool parallel)
|
||||
{
|
||||
private_netlink_socket_t *this;
|
||||
struct sockaddr_nl addr = {
|
||||
@@ -483,6 +493,7 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
|
||||
"%s.plugins.kernel-netlink.timeout", 0, lib->ns),
|
||||
.retries = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.kernel-netlink.retries", 0, lib->ns),
|
||||
.parallel = parallel,
|
||||
);
|
||||
|
||||
if (this->socket == -1)
|
||||
@@ -497,8 +508,10 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
|
||||
if (this->parallel)
|
||||
{
|
||||
lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,10 @@ struct netlink_socket_t {
|
||||
*
|
||||
* @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
|
||||
* @param names optional enum names for Netlink messages
|
||||
* @param parallel support parallel queries on this Netlink socket
|
||||
*/
|
||||
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names);
|
||||
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
|
||||
bool parallel);
|
||||
|
||||
/**
|
||||
* Creates an rtattr and adds it to the given netlink message.
|
||||
|
||||
@@ -60,7 +60,7 @@ START_TEST(test_echo)
|
||||
netlink_add_attribute(&request.hdr, RTA_DST,
|
||||
chunk_from_thing(dst), sizeof(request));
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
|
||||
ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
|
||||
ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
|
||||
@@ -83,7 +83,7 @@ START_TEST(test_echo_dump)
|
||||
},
|
||||
};
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
msg = NLMSG_DATA(&request.hdr);
|
||||
msg->rtgen_family = AF_UNSPEC;
|
||||
|
||||
@@ -179,7 +179,7 @@ START_TEST(test_stress)
|
||||
netlink_socket_t *s;
|
||||
int i;
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
for (i = 0; i < countof(threads); i++)
|
||||
{
|
||||
threads[i] = thread_create(stress, s);
|
||||
@@ -198,7 +198,7 @@ START_TEST(test_stress_dump)
|
||||
netlink_socket_t *s;
|
||||
int i;
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
for (i = 0; i < countof(threads); i++)
|
||||
{
|
||||
threads[i] = thread_create(stress_dump, s);
|
||||
@@ -232,7 +232,7 @@ START_TEST(test_retransmit_success)
|
||||
lib->settings->set_int(lib->settings,
|
||||
"%s.plugins.kernel-netlink.retries", 1, lib->ns);
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
msg = NLMSG_DATA(&request.hdr);
|
||||
msg->rtgen_family = AF_UNSPEC;
|
||||
|
||||
@@ -265,7 +265,7 @@ START_TEST(test_retransmit_fail)
|
||||
lib->settings->set_int(lib->settings,
|
||||
"%s.plugins.kernel-netlink.retries", 3, lib->ns);
|
||||
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL);
|
||||
s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
|
||||
msg = NLMSG_DATA(&request.hdr);
|
||||
msg->rtgen_family = AF_UNSPEC;
|
||||
|
||||
@@ -284,18 +284,18 @@ Suite *socket_suite_create()
|
||||
s = suite_create("netlink socket");
|
||||
|
||||
tc = tcase_create("echo");
|
||||
tcase_add_test(tc, test_echo);
|
||||
tcase_add_test(tc, test_echo_dump);
|
||||
tcase_add_loop_test(tc, test_echo, 0, 2);
|
||||
tcase_add_loop_test(tc, test_echo_dump, 0, 2);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("stress");
|
||||
tcase_add_test(tc, test_stress);
|
||||
tcase_add_test(tc, test_stress_dump);
|
||||
tcase_add_loop_test(tc, test_stress, 0, 2);
|
||||
tcase_add_loop_test(tc, test_stress_dump, 0, 2);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("retransmit");
|
||||
tcase_add_test(tc, test_retransmit_success);
|
||||
tcase_add_test(tc, test_retransmit_fail);
|
||||
tcase_add_loop_test(tc, test_retransmit_success, 0, 2);
|
||||
tcase_add_loop_test(tc, test_retransmit_fail, 0, 2);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
||||
Reference in New Issue
Block a user