<br><tt><font size=2>libvir-list-bounces@redhat.com wrote on 05/25/2010
09:00:26 AM:<br>
<br>
</font></tt>
<br><tt><font size=2>> <br>
> Scott Feldman wrote:<br>
> > From: Scott Feldman <scofeldm@cisco.com><br>
> ...<br>
> > diff --git a/configure.ac b/configure.ac<br>
> ...<br>
> > -if test "$with_macvtap" = "yes"; then<br>
> > +if test "$with_macvtap" = "yes" || "$with_virtualport"
= "yes"; then<br>
> <br>
> Hi Scott,<br>
> <br>
> The above introduces a syntax error.<br>
> Fix it by inserting a "test" after the "||":</font></tt>
<br>
<br><tt><font size=2>My bad. Will fix it.</font></tt>
<br>
<br><tt><font size=2><br>
> > +static int<br>
> > +nlCommWaitSuccess(struct nlmsghdr *nlmsg, int nl_groups,<br>
> > + char
**respbuf, int *respbuflen, long to_usecs)<br>
> <br>
> The parameters, respbuflen and nl_groups make sense only when<br>
> non-negative, so my reflex is to make their types reflect that.<br>
> Any reason not to use an unsigned type in those cases?</font></tt>
<br>
<br><tt><font size=2>nl_groups should be uint32_t or even __u32 to reflect
the kernel includes.</font></tt>
<br><tt><font size=2>I'll fix them.</font></tt>
<br><tt><font size=2><br>
> <br>
> This "to_usecs" parameter is in the same boat, in that it
is<br>
> logically non-negative. I suggest using unsigned long long<br>
> for it, since technically (with the two longs in struct timeval)<br>
> a portable timeout can be as large as 2^31 * 1000^2 microseconds.</font></tt>
<br>
<br><tt><font size=2>I'll do that.</font></tt>
<br><tt><font size=2><br>
> Also, it'd be nice to rename it to "timeout_usecs", since
"to_usecs"<br>
> made me think of a flag that says whether to convert "to microseconds".<br>
> </font></tt>
<br>
<br>
<br><tt><font size=2>Will rename the variable.</font></tt>
<br><tt><font size=2><br>
> > +{<br>
> > + int rc = 0;<br>
> > + struct sockaddr_nl nladdr = {<br>
> > + .nl_family = AF_NETLINK,<br>
> > + .nl_pid =
getpid(),<br>
> > + .nl_groups = nl_groups,<br>
> > + };<br>
> > + int rcvChunkSize = 1024; // expecting less than
that<br>
> > + int rcvoffset = 0;<br>
> <br>
> This should be of type size_t.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> It is used as an accumulator, and we do add nbytes (of type ssize_t)
to it,<br>
> and (esp!) use it as an array index, so its type must be unsigned.<br>
> Otherwise, overflow could be exploitable.<br>
> <br>
> > + ssize_t nbytes;<br>
> > + int n;<br>
> > + struct timeval tv = {<br>
> > + .tv_sec = to_usecs / MICROSEC_PER_SEC,<br>
> > + .tv_usec = to_usecs % MICROSEC_PER_SEC,<br>
> > + };<br>
> > + fd_set rfds;<br>
> <br>
> At least "n" and "rfds" are used only in the while
loop,<br>
> so their declarations belong "down" there, too.</font></tt>
<br>
<br><tt><font size=2>Sure, I'll move them.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + bool gotvalid = false;<br>
> <br>
> Personal preference:<br>
> I find that a name like "got_valid" is easier to read than
a<br>
> variablenamewithnoseparatorbetweenwords.</font></tt>
<br><tt><font size=2>> Same for rcvoffset vs. rcv_offset, etc.</font></tt>
<br>
<br><tt><font size=2>Ok. I can rename them as well.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + int fd = nlOpen();<br>
> > + static uint32_t seq = 0x1234;<br>
> > + uint32_t myseq = seq++;<br>
> > + uint32_t mypid = getpid();<br>
> > +<br>
> > + if (fd < 0)<br>
> > + return -1;<br>
> > +<br>
> > + nlmsg->nlmsg_pid = mypid;<br>
> > + nlmsg->nlmsg_seq = myseq;<br>
> > + nlmsg->nlmsg_flags |= NLM_F_ACK;<br>
> > +<br>
> > + nbytes = sendto(fd, (void *)nlmsg, nlmsg->nlmsg_len,
0,<br>
> > +
(struct sockaddr *)&nladdr, sizeof(nladdr));<br>
> > + if (nbytes < 0) {<br>
> > + virReportSystemError(errno,<br>
> > +
"%s", _("cannot send
to netlink socket"));<br>
> > + rc = -1;<br>
> > + goto err_exit;<br>
> > + }<br>
> > +<br>
> > + while (!gotvalid) {<br>
> > + rcvoffset = 0;<br>
> > + while (1) {<br>
> > + socklen_t addrlen
= sizeof(nladdr);<br>
> > +<br>
> > + if (VIR_REALLOC_N(*respbuf,
rcvoffset+rcvChunkSize) < 0) {<br>
> > + virReportOOMError();<br>
> > + rc =
-1;<br>
> > + goto
err_exit;<br>
> > + }<br>
> > +<br>
> > + FD_ZERO(&rfds);<br>
> > + FD_SET(fd, &rfds);<br>
> > +<br>
> > + n = select(fd + 1,
&rfds, NULL, NULL, &tv);<br>
> > + if (n == 0) {<br>
> <br>
> That handles the case of an expired timeout.<br>
> However, if select fails, it returns -1.<br>
> You should diagnose that failure rather than going<br>
> ahead and reading from "fd".</font></tt>
<br>
<br><tt><font size=2>I'll dump an error and will return in case of -1.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + rc =
-1;<br>
> > + goto
err_exit;<br>
> > + }<br>
> > +<br>
> > + nbytes = recvfrom(fd,
&((*respbuf)[rcvoffset]), <br>
> rcvChunkSize, 0,<br>
> > +
(struct sockaddr *)&nladdr,
&addrlen);<br>
> > + if (nbytes < 0)
{<br>
> > + if (errno
== EAGAIN || errno == EINTR)<br>
> > +
continue;<br>
> > + virReportSystemError(errno,
"%s",<br>
> > +
_("error
receiving from <br>
> netlink socket"));<br>
> > + rc =
-1;<br>
> > + goto
err_exit;<br>
> > + }<br>
> > + rcvoffset += nbytes;<br>
> > + break;<br>
> > + }<br>
> > + *respbuflen = rcvoffset;<br>
> > +<br>
> > + /* check message for error */<br>
> > + if (*respbuflen > NLMSG_LENGTH(0)
&& *respbuf != NULL) {<br>
> > + struct nlmsghdr *resp
= (struct nlmsghdr *)*respbuf;<br>
> > + struct nlmsgerr *err;<br>
> > +<br>
> > + if (resp->nlmsg_pid
!= mypid ||<br>
> > + resp->nlmsg_seq
!= myseq)<br>
> > + continue;<br>
> > +<br>
> > + /* skip reflected
message */<br>
> > + if (resp->nlmsg_type
& 0x10)<br>
> > + continue;<br>
> > +<br>
> > + switch (resp->nlmsg_type)
{<br>
> > + case NLMSG_ERROR:<br>
> > + err
= (struct nlmsgerr *)NLMSG_DATA(resp);<br>
> > + if
(resp->nlmsg_len >= NLMSG_LENGTH(sizeof(*err))) {<br>
> > +
if (-err->error != EOPNOTSUPP) {<br>
> <br>
> I'm used to seeing this:<br>
>
if (err->error != -EOPNOTSUPP) {<br>
> why do you do it the other way?</font></tt>
<br><tt><font size=2>> Such differences are generally discouraged.</font></tt>
<br>
<br><tt><font size=2>Alright. Will fix it.</font></tt>
<br><tt><font size=2><br>
> <br>
> > +
/* assuming error msg from daemon */<br>
> > +
gotvalid = true;<br>
> > +
break;<br>
> > +
}<br>
> > + }<br>
> > + /*
whatever this is, skip it */<br>
> > + VIR_FREE(*respbuf);<br>
> > + *respbuf
= NULL;<br>
> <br>
> The above is a dead store, since VIR_FREE has just done that.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + *respbuflen
= 0;<br>
> > + break;<br>
> > +<br>
> > + case NLMSG_DONE:<br>
> > + gotvalid
= true;<br>
> > + break;<br>
> > +<br>
> > + default:<br>
> > + VIR_FREE(*respbuf);<br>
> > + *respbuf
= NULL;<br>
> <br>
> Likewise. Remove the dead store.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + *respbuflen
= 0;<br>
> > + break;<br>
> > + }<br>
> > + }<br>
> > + }<br>
> > +<br>
> > +err_exit:<br>
> > + if (rc == -1) {<br>
> > + VIR_FREE(*respbuf);<br>
> > + *respbuf = NULL;<br>
> <br>
> Likewise. Remove the dead store.</font></tt>
<br>
<br><tt><font size=2>OK.<br>
> <br>
> > + *respbuflen = 0;<br>
> > + }<br>
> > +<br>
> > + nlClose(fd);<br>
> > + return rc;<br>
> > +}<br>
> > +<br>
> > +# endif<br>
> ...<br>
> <br>
> > +static int<br>
> > +link_dump(int ifindex, struct nlattr **tb, char **recvbuf)<br>
> > +{<br>
> > + int rc = 0;<br>
> > + char nlmsgbuf[256] = { 0, };<br>
> > + struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf,
*resp;<br>
> > + struct nlmsgerr *err;<br>
> > + struct ifinfomsg i = {<br>
> > + .ifi_family = AF_UNSPEC,<br>
> > + .ifi_index = ifindex<br>
> > + };<br>
> <br>
> When I first read the "sizeof(i)" below I did a double take.<br>
> I'd prefer a name that does not make me think of an integer index.</font></tt>
<br>
<br><tt><font size=2>Will fix this.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + int recvbuflen;<br>
> > +<br>
> > + *recvbuf = NULL;<br>
> > +<br>
> > + nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK);<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (nlComm(nlm, recvbuf, &recvbuflen) <
0)<br>
> > + return -1;<br>
> > +<br>
> > + if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf
== NULL)<br>
> > + goto malformed_resp;<br>
> > +<br>
> > + resp = (struct nlmsghdr *)*recvbuf;<br>
> > +<br>
> > + switch (resp->nlmsg_type) {<br>
> > + case NLMSG_ERROR:<br>
> > + err = (struct nlmsgerr *)NLMSG_DATA(resp);<br>
> > + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))<br>
> > + goto malformed_resp;<br>
> > +<br>
> > + switch (-err->error) {<br>
> <br>
> Please remove the unary "-", since it's not used here.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + case 0:<br>
> > + break;<br>
> <br>
> That "break;" should be indented.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > +<br>
> > + default:<br>
> > + virReportSystemError(-err->error,<br>
> > +
_("error dumping
%d interface"),<br>
> > +
ifindex);<br>
> > + rc = -1;<br>
> > + }<br>
> > + break;<br>
> <br>
> Same here. Indent.</font></tt>
<br><tt><font size=2><br>
> <br>
> > +<br>
> > + case GENL_ID_CTRL:<br>
> > + case NLMSG_DONE:<br>
> > + if (nlmsg_parse(resp, sizeof(struct
ifinfomsg),<br>
> > +
tb, IFLA_MAX, ifla_policy)) {<br>
> > + goto malformed_resp;<br>
> > + }<br>
> > + break;<br>
> <br>
> And here. Indent the "break".<br>
> <br>
> > +<br>
> > + default:<br>
> > + goto malformed_resp;<br>
> > + }<br>
> > +<br>
> > + if (rc != 0)<br>
> > + VIR_FREE(*recvbuf);<br>
> > +<br>
> > + return rc;<br>
> > +<br>
> > +malformed_resp:<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",<br>
> > + _("malformed
netlink response message"));<br>
> > + VIR_FREE(*recvbuf);<br>
> > + return -1;<br>
> > +<br>
> > +buffer_too_small:<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",<br>
> > + _("internal
buffer is too small"));<br>
> > + return -1;<br>
> > +}<br>
> ...<br>
> > +static int<br>
> > +doPortProfileOpSetLink(bool multicast,<br>
> > +
int ifindex,<br>
> > +
const char *profileId,<br>
> > +
struct ifla_port_vsi *portVsi,<br>
> > +
const unsigned char *instanceId,<br>
> > +
const unsigned char *hostUUID,<br>
> > +
int32_t vf,<br>
> > +
uint8_t op)<br>
> > +{<br>
> > + int rc = 0;<br>
> > + char nlmsgbuf[256];<br>
> > + struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf,
*resp;<br>
> > + struct nlmsgerr *err;<br>
> > + char rtattbuf[64];<br>
> <br>
> Can you use a symbolic constant instead of "64" ?<br>
</font></tt>
<br><tt><font size=2>Had a previous patch adding that but it was abandoned.
Will re-add this.</font></tt>
<br>
<br><tt><font size=2>> <br>
> > + struct rtattr *rta, *vfports, *vfport;<br>
> > + struct ifinfomsg ifinfo = {<br>
> > + .ifi_family = AF_UNSPEC,<br>
> > + .ifi_index = ifindex,<br>
> > + };<br>
> > + char *recvbuf = NULL;<br>
> > + int recvbuflen = 0;<br>
> > +<br>
> > + memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));<br>
> > +<br>
> > + nlInit(nlm, NLM_F_REQUEST, RTM_SETLINK);<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo,
sizeof(ifinfo)))<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (vf == PORT_SELF_VF) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
<br>
> IFLA_PORT_SELF, NULL, 0);<br>
> > + } else {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
<br>
> IFLA_VF_PORTS, NULL, 0);<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!(vfports = nlAppend(nlm, sizeof(nlmsgbuf),<br>
> > +
rtattbuf, rta->rta_len)))<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + /* beging nesting vfports */<br>
> <br>
> Typo.<br>
> s/beging/begin/</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
<br>
> IFLA_VF_PORT, NULL, 0);<br>
> > + }<br>
> > +<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!(vfport = nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, <br>
> rta->rta_len)))<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (profileId) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
IFLA_PORT_PROFILE,<br>
> > +
profileId, strlen(profileId) + 1);<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> > + }<br>
> > +<br>
> > + if (portVsi) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
IFLA_PORT_VSI_TYPE,<br>
> > +
portVsi, sizeof(*portVsi));<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> > + }<br>
> > +<br>
> > + if (instanceId) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
<br>
> IFLA_PORT_INSTANCE_UUID,<br>
> > +
instanceId, VIR_UUID_BUFLEN);<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> > + }<br>
> > +<br>
> > + if (hostUUID) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
IFLA_PORT_HOST_UUID,<br>
> > +
hostUUID, VIR_UUID_BUFLEN);<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> > + }<br>
> > +<br>
> > + if (vf != PORT_SELF_VF) {<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
IFLA_PORT_VF,<br>
> > +
&vf, sizeof(vf));<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf),
rtattbuf, rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> > + }<br>
> > +<br>
> > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf),
IFLA_PORT_REQUEST,<br>
> > +
&op, sizeof(op));<br>
> > + if (!rta)<br>
> > + goto buffer_too_small;<br>
> > +<br>
> > + if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf,
rta->rta_len))<br>
> > + goto buffer_too_small;<br>
> <br>
> There is too much duplication in the above 6 clauses.<br>
> Can you factor out a tiny helper function to make this more<br>
> readable/maintainable?<br>
> <br>
> At the very least, combine the two<br>
> "if...goto buffer_too_small" stmts into one:<br>
> <br>
> if (!rta || !nlAppend(nlm,
sizeof(nlmsgbuf), rtattbuf, <br>
> rta->rta_len))</font></tt>
<br>
<br><tt><font size=2>Alright. Will do. Though this may also tough existing
code.</font></tt>
<br>
<br><tt><font size=2><br>
> goto buffer_too_small;<br>
> > +<br>
> > + /* end nesting of vport */<br>
> > + vfport->rta_len = (char *)nlm + nlm->nlmsg_len
- (char *)vfport;<br>
> > +<br>
> > + if (vf != PORT_SELF_VF) {<br>
> > + /* end nesting of vfports */<br>
> > + vfports->rta_len = (char *)nlm
+ nlm->nlmsg_len - (char *)vfports;<br>
> > + }<br>
> > +<br>
> > + if (!multicast) {<br>
> > + if (nlComm(nlm, &recvbuf, &recvbuflen)
< 0)<br>
> > + return -1;<br>
> > + } else {<br>
> > + if (nlCommWaitSuccess(nlm, RTMGRP_LINK,
&recvbuf, &recvbuflen,<br>
> > +
5 * MICROSEC_PER_SEC) < 0)<br>
> > + return -1;<br>
> > + }<br>
> > +<br>
> > + if (recvbuflen < NLMSG_LENGTH(0) || recvbuf
== NULL)<br>
> > + goto malformed_resp;<br>
> > +<br>
> > + resp = (struct nlmsghdr *)recvbuf;<br>
> > +<br>
> > + switch (resp->nlmsg_type) {<br>
> > + case NLMSG_ERROR:<br>
> > + err = (struct nlmsgerr *)NLMSG_DATA(resp);<br>
> > + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))<br>
> > + goto malformed_resp;<br>
> ><br>
> > + switch (-err->error) {<br>
> > + case 0:<br>
> > + break;<br>
> <br>
> Indent the break:<br>
> case 0:<br>
> break;<br>
> <br>
> Actually, since there's only one action here,<br>
> just drop the switch in favor of a simple "if" stmt.<br>
> (same with the other switch (-err->error) above)<br>
> That makes the resulting code shorter by 4 lines per switch stmt.</font></tt>
<br>
<br><tt><font size=2>Ok. Had done that to be consistent with other code.</font></tt>
<br><tt><font size=2><br>
> <br>
> if (err->error) {<br>
> virReportSystemError(-err->error,<br>
> _("error
during virtual port configuration of ifindex %d"),<br>
> ifindex);<br>
> rc = -1;<br>
> }<br>
> <br>
> > + default:<br>
> > + virReportSystemError(-err->error,<br>
> > + _("error
during virtual port configuration of ifindex %d"),<br>
> > + ifindex);<br>
> > + rc = -1;<br>
> > + }<br>
> > + break;<br>
> <br>
> Indent.</font></tt>
<br>
<br><tt><font size=2>Ok.</font></tt>
<br><tt><font size=2><br>
> <br>
> > +<br>
> > + case NLMSG_DONE:<br>
> > + break;<br>
> <br>
> Indent.</font></tt>
<br>
<br><tt><font size=2>Ok.<br>
> <br>
> > +<br>
> > + default:<br>
> > + goto malformed_resp;<br>
> > + }<br>
> > +<br>
> > + VIR_FREE(recvbuf);<br>
> > +<br>
> > + return rc;<br>
> > +<br>
> > +malformed_resp:<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",<br>
> > + _("malformed
netlink response message"));<br>
> > + VIR_FREE(recvbuf);<br>
> > + return -1;<br>
> > +<br>
> > +buffer_too_small:<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",<br>
> > + _("internal
buffer is too small"));<br>
> > + return -1;<br>
> > +}<br>
> > +<br>
> > +<br>
> > +static int<br>
> > +doPortProfileOpCommon(bool multicast,<br>
> > +
int ifindex,<br>
> > +
const char *profileId,<br>
> > +
struct ifla_port_vsi *portVsi,<br>
> > +
const unsigned char *instanceId,<br>
> > +
const unsigned char *hostUUID,<br>
> > +
int32_t vf,<br>
> > +
uint8_t op)<br>
> > +{<br>
> > + int rc;<br>
> > + char *recvbuf = NULL;<br>
> > + struct nlattr *tb[IFLA_MAX + 1];<br>
> > + int repeats = 80;<br>
> <br>
> This can (hence should) be unsigned.<br>
> This number is obviously related to the 125000-microsecond<br>
> sleep below. Consider adding a comment saying up to how long<br>
> we should wait for a result.</font></tt>
<br>
<br><tt><font size=2>I'll add some math to this.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + uint16_t status = 0;<br>
> > +<br>
> > + rc = doPortProfileOpSetLink(multicast,<br>
> > +
ifindex,<br>
> > +
profileId,<br>
> > +
portVsi,<br>
> > +
instanceId,<br>
> > +
hostUUID,<br>
> > +
vf,<br>
> > +
op);<br>
> > +<br>
> > + if (rc != 0) {<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR,
"%s",<br>
> > +
_("sending of PortProfileRequest failed."));<br>
> > + return rc;<br>
> > + }<br>
> > +<br>
> > + if (!multicast) {<br>
> > + while (--repeats) {<br>
> > + rc = link_dump(ifindex,
tb, &recvbuf);<br>
> > + if (rc)<br>
> > + goto
err_exit;<br>
> > + rc = getPortProfileStatus(tb,
vf, &status);<br>
> > + if (rc == 0) {<br>
> <br>
> What if getPortProfileStatus returns something other than 0?<br>
> Currently, when that happens, this code just ignores it (failure?)<br>
> sleeps and retries.<br>
> Doesn't failure to get status deserve an error just<br>
> as much as when we do get status that indicates a failure?</font></tt>
<br>
<br><tt><font size=2>Yes, it should. Should only happen, though, if we
are all of a sudden on a wrong kernel...</font></tt>
<br><tt><font size=2><br>
> <br>
> > + if (status
== PORT_PROFILE_RESPONSE_SUCCESS ||<br>
> > +
status == PORT_VDP_RESPONSE_SUCCESS) {<br>
> > +
break;<br>
> > + } else
if (status == PORT_PROFILE_RESPONSE_INPROGRESS) {<br>
> > +
// keep trying...<br>
> > + } else
{<br>
> > +
virReportSystemError(EINVAL,<br>
> > +
_("error %d during port-profile setlink <br>
> on ifindex %d"),<br>
> > +
status, ifindex);<br>
> > +
rc = 1;<br>
> > +
break;<br>
> > + }<br>
> > + }<br>
> > + usleep(125000);<br>
> <br>
> Magic constant?<br>
> How did you determine this number?<br>
> How often are we expected to hit it?<br>
> Please add a comment.</font></tt>
<br>
<br><tt><font size=2>This *may* be something I suggested -- to wait for
1/8 sec. Not sure whether this is</font></tt>
<br><tt><font size=2>too much, or not fast enough, but more like a shot
into the 'blue'.</font></tt>
<br><tt><font size=2><br>
> <br>
> > + VIR_FREE(recvbuf);<br>
> > + }<br>
> > + }<br>
> > +</font></tt>
<br><tt><font size=2>> > + if (status == PORT_PROFILE_RESPONSE_INPROGRESS)
{<br>
> > + macvtapError(VIR_ERR_INTERNAL_ERROR,
"%s",<br>
> > +
_("port-profile setlink timed out"));<br>
> > + rc = -ETIMEDOUT;<br>
> > + }<br>
> > +<br>
> > +err_exit:<br>
> > + VIR_FREE(recvbuf);<br>
> > +<br>
> > + return rc;<br>
> > +}<br>
> > +<br>
> > +# endif /* IFLA_PORT_MAX */<br>
> <br>
> --<br>
> libvir-list mailing list<br>
> libvir-list@redhat.com<br>
> </font></tt><a href="https://www.redhat.com/mailman/listinfo/libvir-list"><tt><font size=2>https://www.redhat.com/mailman/listinfo/libvir-list</font></tt></a><tt><font size=2><br>
</font></tt>
<br><tt><font size=2>I'll post v7 addressing the comments.</font></tt>
<br>
<br><tt><font size=2> Stefan</font></tt>
<br>