mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
util: increase libnl buffer size
In the following cases nl_recv() was returning the error "No buffer space available": * When switching CPUs to offline/online in a system more than 128 cpus * When using virsh to destroy domain in a system with many interfaces This patch sets the buffer size for all netlink sockets created by libnl to 128K and turns on message peeking for nl_recv(). This eliminates the "No buffer space available" errors seen in the cases above, and also preempts other future errors the smaller buffers could have caused. Signed-off-by: Leno Hou <houqy@linux.vnet.ibm.com> Signed-off-by: Laine Stump <laine@laine.org>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2015 Red Hat, Inc.
|
* Copyright (C) 2010-2016 Red Hat, Inc.
|
||||||
* Copyright (C) 2010-2012 IBM Corporation
|
* Copyright (C) 2010-2012, 2016 IBM Corporation
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -65,10 +65,12 @@ struct virNetlinkEventHandle {
|
|||||||
|
|
||||||
# ifdef HAVE_LIBNL1
|
# ifdef HAVE_LIBNL1
|
||||||
# define virNetlinkAlloc nl_handle_alloc
|
# define virNetlinkAlloc nl_handle_alloc
|
||||||
|
# define virNetlinkSetBufferSize nl_set_buffer_size
|
||||||
# define virNetlinkFree nl_handle_destroy
|
# define virNetlinkFree nl_handle_destroy
|
||||||
typedef struct nl_handle virNetlinkHandle;
|
typedef struct nl_handle virNetlinkHandle;
|
||||||
# else
|
# else
|
||||||
# define virNetlinkAlloc nl_socket_alloc
|
# define virNetlinkAlloc nl_socket_alloc
|
||||||
|
# define virNetlinkSetBufferSize nl_socket_set_buffer_size
|
||||||
# define virNetlinkFree nl_socket_free
|
# define virNetlinkFree nl_socket_free
|
||||||
typedef struct nl_sock virNetlinkHandle;
|
typedef struct nl_sock virNetlinkHandle;
|
||||||
# endif
|
# endif
|
||||||
@@ -160,6 +162,57 @@ virNetlinkShutdown(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNetLinkCreateSocket:
|
||||||
|
*
|
||||||
|
* @protocol: which protocol to connect to (e.g. NETLINK_ROUTE,
|
||||||
|
*
|
||||||
|
* Create a netlink socket, set its buffer size, and turn on message
|
||||||
|
* peeking (so the buffer size can be dynamically increased if
|
||||||
|
* needed).
|
||||||
|
*
|
||||||
|
* Returns a handle to the new netlink socket, or 0 if there was a failure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static virNetlinkHandle *
|
||||||
|
virNetlinkCreateSocket(int protocol)
|
||||||
|
{
|
||||||
|
virNetlinkHandle *nlhandle = NULL;
|
||||||
|
|
||||||
|
if (!(nlhandle = virNetlinkAlloc())) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("cannot allocate nlhandle for netlink"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (nl_connect(nlhandle, protocol) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot connect to netlink socket "
|
||||||
|
"with protocol %d"), protocol);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetlinkSetBufferSize(nlhandle, 131702, 0) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("cannot set netlink socket buffer "
|
||||||
|
"size to 128k"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
nl_socket_enable_msg_peek(nlhandle);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return nlhandle;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (nlhandle) {
|
||||||
|
nl_close(nlhandle);
|
||||||
|
virNetlinkFree(nlhandle);
|
||||||
|
nlhandle = NULL;
|
||||||
|
}
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNetlinkCommand:
|
* virNetlinkCommand:
|
||||||
* @nlmsg: pointer to netlink message
|
* @nlmsg: pointer to netlink message
|
||||||
@@ -200,19 +253,8 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
nlhandle = virNetlinkAlloc();
|
if (!(nlhandle = virNetlinkCreateSocket(protocol)))
|
||||||
if (!nlhandle) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
"%s", _("cannot allocate nlhandle for netlink"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (nl_connect(nlhandle, protocol) < 0) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot connect to netlink socket with protocol %d"),
|
|
||||||
protocol);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = nl_socket_get_fd(nlhandle);
|
fd = nl_socket_get_fd(nlhandle);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -663,19 +705,8 @@ virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
|
|||||||
virNetlinkEventServerLock(srv);
|
virNetlinkEventServerLock(srv);
|
||||||
|
|
||||||
/* Allocate a new socket and get fd */
|
/* Allocate a new socket and get fd */
|
||||||
srv->netlinknh = virNetlinkAlloc();
|
if (!(srv->netlinknh = virNetlinkCreateSocket(protocol)))
|
||||||
|
|
||||||
if (!srv->netlinknh) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
"%s", _("cannot allocate nlhandle for virNetlinkEvent server"));
|
|
||||||
goto error_locked;
|
goto error_locked;
|
||||||
}
|
|
||||||
|
|
||||||
if (nl_connect(srv->netlinknh, protocol) < 0) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot connect to netlink socket with protocol %d"), protocol);
|
|
||||||
goto error_server;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = nl_socket_get_fd(srv->netlinknh);
|
fd = nl_socket_get_fd(srv->netlinknh);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user