diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c index a5d10fa8ec..be00351db1 100644 --- a/src/util/virnetlink.c +++ b/src/util/virnetlink.c @@ -209,6 +209,72 @@ virNetlinkCreateSocket(int protocol) goto cleanup; } +static virNetlinkHandle * +virNetlinkSendRequest(struct nl_msg *nl_msg, uint32_t src_pid, + struct sockaddr_nl nladdr, + unsigned int protocol, unsigned int groups) +{ + ssize_t nbytes; + int fd; + int n; + virNetlinkHandle *nlhandle = NULL; + struct pollfd fds[1]; + struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg); + + if (protocol >= MAX_LINKS) { + virReportSystemError(EINVAL, + _("invalid protocol argument: %d"), protocol); + goto error; + } + + if (!(nlhandle = virNetlinkCreateSocket(protocol))) + goto error; + + fd = nl_socket_get_fd(nlhandle); + if (fd < 0) { + virReportSystemError(errno, + "%s", _("cannot get netlink socket fd")); + goto error; + } + + if (groups && nl_socket_add_membership(nlhandle, groups) < 0) { + virReportSystemError(errno, + "%s", _("cannot add netlink membership")); + goto error; + } + + nlmsg_set_dst(nl_msg, &nladdr); + + nlmsg->nlmsg_pid = src_pid ? src_pid : getpid(); + + nbytes = nl_send_auto_complete(nlhandle, nl_msg); + if (nbytes < 0) { + virReportSystemError(errno, + "%s", _("cannot send to netlink socket")); + goto error; + } + + memset(fds, 0, sizeof(fds)); + + fds[0].fd = fd; + fds[0].events = POLLIN; + + n = poll(fds, ARRAY_CARDINALITY(fds), NETLINK_ACK_TIMEOUT_S); + if (n <= 0) { + if (n < 0) + virReportSystemError(errno, "%s", + _("error in poll call")); + if (n == 0) + virReportSystemError(ETIMEDOUT, "%s", + _("no valid netlink response was received")); + } + + return nlhandle; + + error: + virNetlinkFree(nlhandle); + return NULL; +} /** * virNetlinkCommand: @@ -236,61 +302,15 @@ int virNetlinkCommand(struct nl_msg *nl_msg, .nl_pid = dst_pid, .nl_groups = 0, }; - ssize_t nbytes; struct pollfd fds[1]; - int fd; - int n; - struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg); virNetlinkHandle *nlhandle = NULL; int len = 0; - if (protocol >= MAX_LINKS) { - virReportSystemError(EINVAL, - _("invalid protocol argument: %d"), protocol); - goto cleanup; - } - - if (!(nlhandle = virNetlinkCreateSocket(protocol))) - goto cleanup; - - fd = nl_socket_get_fd(nlhandle); - if (fd < 0) { - virReportSystemError(errno, - "%s", _("cannot get netlink socket fd")); - goto cleanup; - } - - if (groups && nl_socket_add_membership(nlhandle, groups) < 0) { - virReportSystemError(errno, - "%s", _("cannot add netlink membership")); - goto cleanup; - } - - nlmsg_set_dst(nl_msg, &nladdr); - - nlmsg->nlmsg_pid = src_pid ? src_pid : getpid(); - - nbytes = nl_send_auto_complete(nlhandle, nl_msg); - if (nbytes < 0) { - virReportSystemError(errno, - "%s", _("cannot send to netlink socket")); - goto cleanup; - } - memset(fds, 0, sizeof(fds)); - fds[0].fd = fd; - fds[0].events = POLLIN; - n = poll(fds, ARRAY_CARDINALITY(fds), NETLINK_ACK_TIMEOUT_S); - if (n <= 0) { - if (n < 0) - virReportSystemError(errno, "%s", - _("error in poll call")); - if (n == 0) - virReportSystemError(ETIMEDOUT, "%s", - _("no valid netlink response was received")); + if (!(nlhandle = virNetlinkSendRequest(nl_msg, src_pid, nladdr, + protocol, groups))) goto cleanup; - } len = nl_recv(nlhandle, &nladdr, (unsigned char **)resp, NULL); if (len == 0) { @@ -315,7 +335,6 @@ int virNetlinkCommand(struct nl_msg *nl_msg, return ret; } - /** * virNetlinkDumpLink: *