kernel-netlink: Retry netlink query while kernel returns EBUSY
If the kernel can't execute a Netlink query because a different query is already active, it returns EBUSY. As this can happen now as we support parallel queries, retry on this error condition.
This commit is contained in:
@@ -211,9 +211,11 @@ CALLBACK(watch, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(netlink_socket_t, netlink_send, status_t,
|
/**
|
||||||
private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
|
* Send a netlink request, try once
|
||||||
size_t *out_len)
|
*/
|
||||||
|
static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
|
||||||
|
struct nlmsghdr **out, size_t *out_len)
|
||||||
{
|
{
|
||||||
struct nlmsghdr *hdr;
|
struct nlmsghdr *hdr;
|
||||||
chunk_t result = {};
|
chunk_t result = {};
|
||||||
@@ -277,6 +279,38 @@ METHOD(netlink_socket_t, netlink_send, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(netlink_socket_t, netlink_send, status_t,
|
||||||
|
private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
|
||||||
|
size_t *out_len)
|
||||||
|
{
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *hdr;
|
||||||
|
status_t status;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
status = send_once(this, in, &hdr, &len);
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (hdr->nlmsg_type == NLMSG_ERROR)
|
||||||
|
{
|
||||||
|
struct nlmsgerr* err;
|
||||||
|
|
||||||
|
err = NLMSG_DATA(hdr);
|
||||||
|
if (err->error == -EBUSY)
|
||||||
|
{
|
||||||
|
free(hdr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*out = hdr;
|
||||||
|
*out_len = len;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(netlink_socket_t, netlink_send_ack, status_t,
|
METHOD(netlink_socket_t, netlink_send_ack, status_t,
|
||||||
private_netlink_socket_t *this, struct nlmsghdr *in)
|
private_netlink_socket_t *this, struct nlmsghdr *in)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user