[libvirt] [PATCH V3 1/3] Improve netlink to support all protocol.
Daniel Veillard
veillard at redhat.com
Wed Aug 22 10:29:18 UTC 2012
On Wed, Aug 22, 2012 at 12:10:23PM +0800, Tang Chen wrote:
> This patch improve all the API in virnetlink.c to support
> all kinds of netlink protocols, and make all netlink sockets
> be able to join in groups.
>
> Signed-off-by: Tang Chen <tangchen at cn.fujitsu.com>
> ---
> daemon/libvirtd.c | 6 +-
> src/util/virnetdev.c | 6 +-
> src/util/virnetdevmacvlan.c | 12 +--
> src/util/virnetdevvportprofile.c | 7 +-
> src/util/virnetlink.c | 170 ++++++++++++++++++++++++++++----------
> src/util/virnetlink.h | 17 ++--
> 6 files changed, 156 insertions(+), 62 deletions(-)
>
> diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
> index f0b0a3c..e2e4fbd 100644
> --- a/daemon/libvirtd.c
> +++ b/daemon/libvirtd.c
> @@ -1310,8 +1310,8 @@ int main(int argc, char **argv) {
> goto cleanup;
> }
>
> - /* Register the netlink event service */
> - if (virNetlinkEventServiceStart() < 0) {
> + /* Register the netlink event service for NETLINK_ROUTE */
> + if (virNetlinkEventServiceStart(NETLINK_ROUTE, 0) < 0) {
> ret = VIR_DAEMON_ERR_NETWORK;
> goto cleanup;
> }
> @@ -1325,7 +1325,7 @@ int main(int argc, char **argv) {
> 0, "shutdown", NULL, NULL);
>
> cleanup:
> - virNetlinkEventServiceStop();
> + virNetlinkEventServiceStop(NETLINK_ROUTE);
> virObjectUnref(remoteProgram);
> virObjectUnref(qemuProgram);
> virNetServerClose(srv);
> diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
> index f9eba1a..d97820e 100644
> --- a/src/util/virnetdev.c
> +++ b/src/util/virnetdev.c
> @@ -1277,7 +1277,8 @@ virNetDevLinkDump(const char *ifname, int ifindex,
> goto buffer_too_small;
> }
>
> - if (virNetlinkCommand(nl_msg, recvbuf, &recvbuflen, src_pid, dst_pid) < 0)
> + if (virNetlinkCommand(nl_msg, recvbuf, &recvbuflen,
> + src_pid, dst_pid, NETLINK_ROUTE, 0) < 0)
> goto cleanup;
>
> if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
> @@ -1405,7 +1406,8 @@ virNetDevSetVfConfig(const char *ifname, int ifindex, int vf,
> }
> }
>
> - if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, pid) < 0)
> + if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, pid,
> + NETLINK_ROUTE, 0) < 0)
> goto cleanup;
>
> if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
> diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
> index cfad2de..74c56e0 100644
> --- a/src/util/virnetdevmacvlan.c
> +++ b/src/util/virnetdevmacvlan.c
> @@ -149,7 +149,8 @@ virNetDevMacVLanCreate(const char *ifname,
>
> nla_nest_end(nl_msg, linkinfo);
>
> - if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0) < 0) {
> + if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0,
> + NETLINK_ROUTE, 0) < 0) {
> goto cleanup;
> }
>
> @@ -237,7 +238,8 @@ int virNetDevMacVLanDelete(const char *ifname)
> if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
> goto buffer_too_small;
>
> - if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0) < 0) {
> + if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0,
> + NETLINK_ROUTE, 0) < 0) {
> goto cleanup;
> }
>
> @@ -757,7 +759,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
> {
> virNetlinkCallbackDataPtr calld = NULL;
>
> - if (virtPortProfile && virNetlinkEventServiceIsRunning()) {
> + if (virtPortProfile && virNetlinkEventServiceIsRunning(NETLINK_ROUTE)) {
> if (VIR_ALLOC(calld) < 0)
> goto memory_error;
> if ((calld->cr_ifname = strdup(ifname)) == NULL)
> @@ -774,7 +776,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
>
> if (virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback,
> virNetDevMacVLanVPortProfileDestroyCallback,
> - calld, macaddress) < 0)
> + calld, macaddress, NETLINK_ROUTE) < 0)
> goto error;
> }
>
> @@ -1000,7 +1002,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
> ret = -1;
> }
>
> - virNetlinkEventRemoveClient(0, macaddr);
> + virNetlinkEventRemoveClient(0, macaddr, NETLINK_ROUTE);
>
> return ret;
> }
> diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
> index f3f53c9..5213378 100644
> --- a/src/util/virnetdevvportprofile.c
> +++ b/src/util/virnetdevvportprofile.c
> @@ -705,13 +705,14 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
> }
>
> if (!nltarget_kernel) {
> - if ((src_pid = virNetlinkEventServiceLocalPid()) < 0)
> + if ((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0)
> goto cleanup;
> if ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0)
> goto cleanup;
> }
>
> - if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, src_pid, dst_pid) < 0)
> + if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen,
> + src_pid, dst_pid, NETLINK_ROUTE, 0) < 0)
> goto cleanup;
>
> if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
> @@ -868,7 +869,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex,
> return 0;
>
> if (!nltarget_kernel &&
> - (((src_pid = virNetlinkEventServiceLocalPid()) < 0) ||
> + (((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0) ||
> ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0))) {
> rc = -1;
> goto cleanup;
> diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
> index 4a31b1c..64bd47d 100644
> --- a/src/util/virnetlink.c
> +++ b/src/util/virnetlink.c
> @@ -33,6 +33,7 @@
> #include <errno.h>
> #include <unistd.h>
> #include <sys/types.h>
> +#include <sys/socket.h>
>
> #include "virnetlink.h"
> #include "logging.h"
> @@ -41,6 +42,10 @@
> #include "virmacaddr.h"
> #include "virterror_internal.h"
>
> +#ifndef SOL_NETLINK
> +#define SOL_NETLINK 270
> +#endif
> +
This needed some indetation otherwise "make syntax-check" would
complain. I wonder if MAX_LINKS shouldn't be checked too
#ifdef MAX_LINKS
# define MAX_LINKS 32
#endif
> #define VIR_FROM_THIS VIR_FROM_NET
>
> #define NETLINK_ACK_TIMEOUT_S 2
> @@ -93,7 +98,9 @@ static int nextWatch = 1;
> records in this multiple */
> # define NETLINK_EVENT_ALLOC_EXTENT 10
>
> -static virNetlinkEventSrvPrivatePtr server = NULL;
> +/* Linux kernel supports up to MAX_LINKS (32 at the time) individual
> + * netlink protocols. */
> +static virNetlinkEventSrvPrivatePtr server[MAX_LINKS] = {NULL};
> static virNetlinkHandle *placeholder_nlhandle = NULL;
>
> /* Function definitions */
> @@ -157,7 +164,10 @@ virNetlinkShutdown(void)
> * @respbuf: pointer to pointer where response buffer will be allocated
> * @respbuflen: pointer to integer holding the size of the response buffer
> * on return of the function.
> - * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
> + * @src_pid: the pid of the process to send a message
> + * @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
> + * @protocol: netlink protocol
> + * @groups: the group identifier
> *
> * Send the given message to the netlink layer and receive response.
> * Returns 0 on success, -1 on error. In case of error, no response
> @@ -165,7 +175,8 @@ virNetlinkShutdown(void)
> */
> int virNetlinkCommand(struct nl_msg *nl_msg,
> unsigned char **respbuf, unsigned int *respbuflen,
> - uint32_t src_pid, uint32_t dst_pid)
> + uint32_t src_pid, uint32_t dst_pid,
> + unsigned int protocol, unsigned int groups)
> {
> int rc = 0;
> struct sockaddr_nl nladdr = {
> @@ -181,17 +192,39 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
> int fd;
> int n;
> struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
> - virNetlinkHandle *nlhandle = virNetlinkAlloc();
> + virNetlinkHandle *nlhandle = NULL;
> +
> + if (protocol >= MAX_LINKS) {
> + virReportSystemError(EINVAL,
> + _("invalid protocol argument: %d"), protocol);
> + return -EINVAL;
> + }
>
> + nlhandle = virNetlinkAlloc();
> if (!nlhandle) {
> virReportSystemError(errno,
> "%s", _("cannot allocate nlhandle for netlink"));
> return -1;
> }
>
> - if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
> + if (nl_connect(nlhandle, protocol) < 0) {
> + virReportSystemError(errno,
> + _("cannot connect to netlink socket with protocol %d"), protocol);
> + rc = -1;
> + goto error;
> + }
> +
> + fd = nl_socket_get_fd(nlhandle);
> + if (fd < 0) {
> virReportSystemError(errno,
> - "%s", _("cannot connect to netlink socket"));
> + "%s", _("cannot get netlink socket fd"));
> + rc = -1;
> + goto error;
> + }
> +
> + if (groups && nl_socket_add_membership(nlhandle, groups) < 0) {
> + virReportSystemError(errno,
> + "%s", _("cannot add netlink membership"));
> rc = -1;
> goto error;
> }
> @@ -208,8 +241,6 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
> goto error;
> }
>
> - fd = nl_socket_get_fd(nlhandle);
> -
> FD_ZERO(&readfds);
> FD_SET(fd, &readfds);
>
> @@ -258,6 +289,7 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
> * virNetlinkEventRemoveClientPrimitive:
> *
> * @i: index of the client to remove from the table
> + * @protocol: netlink protocol
> *
> * This static function does the low level removal of a client from
> * the table once its index is known, including calling the remove
> @@ -267,17 +299,21 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
> *
> * assumes success, returns nothing.
> */
> -static void
> -virNetlinkEventRemoveClientPrimitive(size_t i)
> +static int
> +virNetlinkEventRemoveClientPrimitive(size_t i, unsigned int protocol)
> {
> - virNetlinkEventRemoveCallback removeCB = server->handles[i].removeCB;
> + if (protocol >= MAX_LINKS)
> + return -EINVAL;
> +
> + virNetlinkEventRemoveCallback removeCB = server[protocol]->handles[i].removeCB;
>
> if (removeCB) {
> - (removeCB)(server->handles[i].watch,
> - &server->handles[i].macaddr,
> - server->handles[i].opaque);
> + (removeCB)(server[protocol]->handles[i].watch,
> + &server[protocol]->handles[i].macaddr,
> + server[protocol]->handles[i].opaque);
> }
> - server->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
> + server[protocol]->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
> + return 0;
> }
>
> static void
> @@ -330,17 +366,22 @@ virNetlinkEventCallback(int watch,
> * stop the monitor to receive netlink messages for libvirtd.
> * This removes the netlink socket fd from the event handler.
> *
> + * @protocol: netlink protocol
> + *
> * Returns -1 if the monitor cannot be unregistered, 0 upon success
> */
> int
> -virNetlinkEventServiceStop(void)
> +virNetlinkEventServiceStop(unsigned int protocol)
> {
> - virNetlinkEventSrvPrivatePtr srv = server;
> + if (protocol >= MAX_LINKS)
> + return -EINVAL;
> +
> + virNetlinkEventSrvPrivatePtr srv = server[protocol];
> int i;
>
> VIR_INFO("stopping netlink event service");
>
> - if (!server)
> + if (!server[protocol])
> return 0;
>
> virNetlinkEventServerLock(srv);
> @@ -351,10 +392,10 @@ virNetlinkEventServiceStop(void)
> /* free any remaining clients on the list */
> for (i = 0; i < srv->handlesCount; i++) {
> if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
> - virNetlinkEventRemoveClientPrimitive(i);
> + virNetlinkEventRemoveClientPrimitive(i, protocol);
> }
>
> - server = 0;
> + server[protocol] = NULL;
> virNetlinkEventServerUnlock(srv);
>
> virMutexDestroy(&srv->lock);
> @@ -367,29 +408,42 @@ virNetlinkEventServiceStop(void)
> *
> * Returns if the netlink event service is running.
> *
> + * @protocol: netlink protocol
> + *
> * Returns 'true' if the service is running, 'false' if stopped.
> */
> bool
> -virNetlinkEventServiceIsRunning(void)
> +virNetlinkEventServiceIsRunning(unsigned int protocol)
> {
> - return server != NULL;
> + if (protocol >= MAX_LINKS) {
> + virReportSystemError(EINVAL,
> + _("invalid protocol argument: %d"), protocol);
> + return false;
> + }
> +
> + return server[protocol] != NULL;
> }
>
> /**
> * virNetlinkEventServiceLocalPid:
> *
> + * @protocol: netlink protocol
> + *
> * Returns the nl_pid value that was used to bind() the netlink socket
> * used by the netlink event service, or -1 on error (netlink
> * guarantees that this value will always be > 0).
> */
> -int virNetlinkEventServiceLocalPid(void)
> +int virNetlinkEventServiceLocalPid(unsigned int protocol)
> {
> - if (!(server && server->netlinknh)) {
> + if (protocol >= MAX_LINKS)
> + return -EINVAL;
> +
> + if (!(server[protocol] && server[protocol]->netlinknh)) {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> _("netlink event service not running"));
> return -1;
> }
> - return (int)nl_socket_get_local_port(server->netlinknh);
> + return (int)nl_socket_get_local_port(server[protocol]->netlinknh);
> }
>
>
> @@ -399,19 +453,27 @@ int virNetlinkEventServiceLocalPid(void)
> * start a monitor to receive netlink messages for libvirtd.
> * This registers a netlink socket with the event interface.
> *
> + * @protocol: netlink protocol
> + * @groups: broadcast groups to join in
> * Returns -1 if the monitor cannot be registered, 0 upon success
> */
> int
> -virNetlinkEventServiceStart(void)
> +virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
> {
> virNetlinkEventSrvPrivatePtr srv;
> int fd;
> int ret = -1;
>
> - if (server)
> + if (protocol >= MAX_LINKS) {
> + virReportSystemError(EINVAL,
> + _("invalid protocol argument: %d"), protocol);
> + return -EINVAL;
> + }
> +
> + if (server[protocol])
> return 0;
>
> - VIR_INFO("starting netlink event service");
> + VIR_INFO("starting netlink event service with protocol %d", protocol);
>
> if (VIR_ALLOC(srv) < 0) {
> virReportOOMError();
> @@ -434,20 +496,25 @@ virNetlinkEventServiceStart(void)
> goto error_locked;
> }
>
> - if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) {
> + if (nl_connect(srv->netlinknh, protocol) < 0) {
> virReportSystemError(errno,
> - "%s", _("cannot connect to netlink socket"));
> + _("cannot connect to netlink socket with protocol %d"), protocol);
> goto error_server;
> }
>
> fd = nl_socket_get_fd(srv->netlinknh);
> -
> if (fd < 0) {
> virReportSystemError(errno,
> "%s", _("cannot get netlink socket fd"));
> goto error_server;
> }
>
> + if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
> + virReportSystemError(errno,
> + "%s", _("cannot add netlink membership"));
> + goto error_server;
> + }
> +
> if (nl_socket_set_nonblocking(srv->netlinknh)) {
> virReportSystemError(errno, "%s",
> _("cannot set netlink socket nonblocking"));
> @@ -467,7 +534,7 @@ virNetlinkEventServiceStart(void)
> VIR_DEBUG("netlink event listener on fd: %i running", fd);
>
> ret = 0;
> - server = srv;
> + server[protocol] = srv;
>
> error_server:
> if (ret < 0) {
> @@ -491,6 +558,7 @@ error_locked:
> * @opaque: user data to pass to callback
> * @macaddr: macaddr to store with the data. Used to identify callers.
> * May be null.
> + * @protocol: netlink protocol
> *
> * register a callback for handling of netlink messages. The
> * registered function receives the entire netlink message and
> @@ -502,10 +570,16 @@ error_locked:
> int
> virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
> virNetlinkEventRemoveCallback removeCB,
> - void *opaque, const virMacAddrPtr macaddr)
> + void *opaque, const virMacAddrPtr macaddr,
> + unsigned int protocol)
> {
> int i, r, ret = -1;
> - virNetlinkEventSrvPrivatePtr srv = server;
> + virNetlinkEventSrvPrivatePtr srv = NULL;
> +
> + if (protocol >= MAX_LINKS)
> + return -EINVAL;
> +
> + srv = server[protocol];
>
> if (handleCB == NULL) {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> @@ -562,6 +636,7 @@ error:
> *
> * @watch: watch whose handle to remove
> * @macaddr: macaddr whose handle to remove
> + * @protocol: netlink protocol
> *
> * Unregister a callback from a netlink monitor.
> * The handler function referenced will no longer receive netlink messages.
> @@ -570,11 +645,17 @@ error:
> * Returns -1 if the file handle was not registered, 0 upon success
> */
> int
> -virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr)
> +virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
> + unsigned int protocol)
> {
> int i;
> int ret = -1;
> - virNetlinkEventSrvPrivatePtr srv = server;
> + virNetlinkEventSrvPrivatePtr srv = NULL;
> +
> + if (protocol >= MAX_LINKS)
> + return -EINVAL;
> +
> + srv = server[protocol];
>
> VIR_DEBUG("removing client watch=%d, mac=%p.", watch, macaddr);
>
> @@ -595,7 +676,7 @@ virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr)
>
> VIR_DEBUG("removed client: %d by %s.",
> srv->handles[i].watch, watch ? "index" : "mac");
> - virNetlinkEventRemoveClientPrimitive(i);
> + virNetlinkEventRemoveClientPrimitive(i, protocol);
> ret = 0;
> goto cleanup;
> }
> @@ -631,7 +712,9 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
> unsigned char **respbuf ATTRIBUTE_UNUSED,
> unsigned int *respbuflen ATTRIBUTE_UNUSED,
> uint32_t src_pid ATTRIBUTE_UNUSED,
> - uint32_t dst_pid ATTRIBUTE_UNUSED)
> + uint32_t dst_pid ATTRIBUTE_UNUSED,
> + unsigned int protocol ATTRIBUTE_UNUSED,
> + unsigned int groups ATTRIBUTE_UNUSED)
> {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
> return -1;
> @@ -641,7 +724,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
> * stopNetlinkEventServer: stop the monitor to receive netlink
> * messages for libvirtd
> */
> -int virNetlinkEventServiceStop(void)
> +int virNetlinkEventServiceStop(unsigned int protocol ATTRIBUTE_UNUSED)
> {
> VIR_DEBUG("%s", _(unsupported));
> return 0;
> @@ -651,7 +734,8 @@ int virNetlinkEventServiceStop(void)
> * startNetlinkEventServer: start a monitor to receive netlink
> * messages for libvirtd
> */
> -int virNetlinkEventServiceStart(void)
> +int virNetlinkEventServiceStart(unsigned int protocol ATTRIBUTE_UNUSED,
> + unsigned int groups ATTRIBUTE_UNUSED)
> {
> VIR_DEBUG("%s", _(unsupported));
> return 0;
> @@ -661,13 +745,13 @@ int virNetlinkEventServiceStart(void)
> * virNetlinkEventServiceIsRunning: returns if the netlink event
> * service is running.
> */
> -bool virNetlinkEventServiceIsRunning(void)
> +bool virNetlinkEventServiceIsRunning(unsigned int protocol ATTRIBUTE_UNUSED)
> {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
> return 0;
> }
>
> -int virNetlinkEventServiceLocalPid(void)
> +int virNetlinkEventServiceLocalPid(unsigned int protocol ATTRIBUTE_UNUSED)
> {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
> return -1;
> @@ -681,6 +765,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
> virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED,
> void *opaque ATTRIBUTE_UNUSED,
> const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
> + unsigned int protocol ATTRIBUTE_UNUSED)
> {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
> return -1;
> @@ -691,6 +776,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
> */
> int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED,
> const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
> + unsigned int protocol ATTRIBUTE_UNUSED)
> {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
> return -1;
> diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h
> index 5d8337d..2e18af4 100644
> --- a/src/util/virnetlink.h
> +++ b/src/util/virnetlink.h
> @@ -41,7 +41,8 @@ void virNetlinkShutdown(void);
>
> int virNetlinkCommand(struct nl_msg *nl_msg,
> unsigned char **respbuf, unsigned int *respbuflen,
> - uint32_t src_port, uint32_t dst_port);
> + uint32_t src_pid, uint32_t dst_pid,
> + unsigned int protocol, unsigned int groups);
>
> typedef void (*virNetlinkEventHandleCallback)(unsigned char *msg, int length, struct sockaddr_nl *peer, bool *handled, void *opaque);
>
> @@ -50,33 +51,35 @@ typedef void (*virNetlinkEventRemoveCallback)(int watch, const virMacAddrPtr mac
> /**
> * stopNetlinkEventServer: stop the monitor to receive netlink messages for libvirtd
> */
> -int virNetlinkEventServiceStop(void);
> +int virNetlinkEventServiceStop(unsigned int protocol);
>
> /**
> * startNetlinkEventServer: start a monitor to receive netlink messages for libvirtd
> */
> -int virNetlinkEventServiceStart(void);
> +int virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups);
>
> /**
> * virNetlinkEventServiceIsRunning: returns if the netlink event service is running.
> */
> -bool virNetlinkEventServiceIsRunning(void);
> +bool virNetlinkEventServiceIsRunning(unsigned int protocol);
>
> /**
> * virNetlinkEventServiceLocalPid: returns nl_pid used to bind() netlink socket
> */
> -int virNetlinkEventServiceLocalPid(void);
> +int virNetlinkEventServiceLocalPid(unsigned int protocol);
>
> /**
> * virNetlinkEventAddClient: register a callback for handling of netlink messages
> */
> int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
> virNetlinkEventRemoveCallback removeCB,
> - void *opaque, const virMacAddrPtr macaddr);
> + void *opaque, const virMacAddrPtr macaddr,
> + unsigned int protocol);
>
> /**
> * virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
> */
> -int virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr);
> +int virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
> + unsigned int protocol);
>
> #endif /* __VIR_NETLINK_H__ */
Overall looks fine, though i had to apply the following patch for
cleanup, ACK
Daniel
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 64bd47d..1ec9976 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -43,7 +43,7 @@
#include "virterror_internal.h"
#ifndef SOL_NETLINK
-#define SOL_NETLINK 270
+# define SOL_NETLINK 270
#endif
#define VIR_FROM_THIS VIR_FROM_NET
@@ -193,7 +193,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
int n;
struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
virNetlinkHandle *nlhandle = NULL;
-
+
if (protocol >= MAX_LINKS) {
virReportSystemError(EINVAL,
_("invalid protocol argument: %d"), protocol);
@@ -209,7 +209,8 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
if (nl_connect(nlhandle, protocol) < 0) {
virReportSystemError(errno,
- _("cannot connect to netlink socket with protocol %d"), protocol);
+ _("cannot connect to netlink socket with protocol %d"),
+ protocol);
rc = -1;
goto error;
}
@@ -575,7 +576,7 @@ virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
{
int i, r, ret = -1;
virNetlinkEventSrvPrivatePtr srv = NULL;
-
+
if (protocol >= MAX_LINKS)
return -EINVAL;
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list