util: extract the request sending code from virNetlinkCommand()

Allow to reuse as much as possible from virNetlinkCommand(). This
comment prepares for the introduction of virNetlinkDumpCommand()
only differing by how it handles the responses.
This commit is contained in:
Cédric Bosdonnat 2017-03-03 12:16:32 +01:00
parent 9b14b2bc3b
commit d68cb4f554

View File

@ -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:
*