On 5/21/10 6:50 AM, "Stefan Berger" <stefanb@xxxxxxxxxxxxxxxxxx> wrote: > This patch may get 802.1Qbh devices working. I am adding some code to > poll for the status of an 802.1Qbh device and loop for a while until the > status indicates success. This part for sure needs more work and > testing... I think we can drop this patch 3/3. For bh, we don't want to poll for status because it may take awhile before status of other than in-progress is indicated. Link UP on the eth is the async notification of status=success. > I am recycling link_dump from a previous patch. > > Changes from V1 to V2: > - Following tree > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> > > --- > src/util/macvtap.c | 116 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 116 insertions(+) > > Index: libvirt-acl/src/util/macvtap.c > =================================================================== > --- libvirt-acl.orig/src/util/macvtap.c > +++ libvirt-acl/src/util/macvtap.c > @@ -960,6 +960,95 @@ getPortProfileStatus(struct nlmsghdr *nl > > > static int > +link_dump(int ifindex, const char *ifname, struct nlattr **tb, > + char **recvbuf) > +{ > + int rc = 0; > + char nlmsgbuf[256] = { 0, }; > + struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp; > + struct nlmsgerr *err; > + char rtattbuf[64]; > + struct rtattr *rta; > + struct ifinfomsg i = { > + .ifi_family = AF_UNSPEC, > + .ifi_index = ifindex > + }; > + int recvbuflen; > + > + *recvbuf = NULL; > + > + nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK); > + > + if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i))) > + goto buffer_too_small; > + > + if (ifindex < 0 && ifname != NULL) { > + rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME, > + ifname, strlen(ifname) + 1); > + if (!rta) > + goto buffer_too_small; > + > + if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)) > + goto buffer_too_small; > + } > + > + if (nlComm(nlm, recvbuf, &recvbuflen) < 0) > + return -1; > + > + if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) > + goto malformed_resp; > + > + resp = (struct nlmsghdr *)*recvbuf; > + > + switch (resp->nlmsg_type) { > + case NLMSG_ERROR: > + err = (struct nlmsgerr *)NLMSG_DATA(resp); > + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) > + goto malformed_resp; > + > + switch (-err->error) { > + case 0: > + break; > + > + default: > + virReportSystemError(-err->error, > + _("error dumping %d interface"), > + ifindex); > + rc = -1; > + } > + break; > + > + case GENL_ID_CTRL: > + case NLMSG_DONE: > + if (nlmsg_parse(resp, sizeof(struct ifinfomsg), > + tb, IFLA_MAX, ifla_policy)) { > + goto malformed_resp; > + } > + break; > + > + default: > + goto malformed_resp; > + } > + > + if (rc != 0) > + VIR_FREE(*recvbuf); > + > + return rc; > + > +malformed_resp: > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("malformed netlink response message")); > + VIR_FREE(*recvbuf); > + return -1; > + > +buffer_too_small: > + macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("internal buffer is too small")); > + return -1; > +} > + > + > +static int > doPortProfileOpSetLink(bool multicast, > const char *ifname, int ifindex, > const char *profileId, > @@ -1151,6 +1240,10 @@ doPortProfileOpCommon(bool multicast, > uint8_t op) > { > int rc; > + char *recvbuf = NULL; > + struct nlattr *tb[IFLA_MAX + 1]; > + int repeats = 5; > + uint16_t status; > > rc = doPortProfileOpSetLink(multicast, > ifname, ifindex, > @@ -1167,6 +1260,30 @@ doPortProfileOpCommon(bool multicast, > return rc; > } > > + if (!multicast) { > + /* 802.1Qbh -- query for status */ > + while (--repeats) { > + rc = link_dump(ifindex, ifname, tb, &recvbuf); > + if (rc) > + goto err_exit; > + rc = getPortProfileStatus((struct nlmsghdr *)recvbuf, > &status); > + if (rc == 0) { > + if (status == 0) > + break; > + if (status != 0) { > + fprintf(stderr,"Current status: %d\n", status); > + rc = 1; > + } > + } > + usleep(10000); > + > + VIR_FREE(recvbuf); > + } > + } > + > +err_exit: > + VIR_FREE(recvbuf); > + > return rc; > } > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list