[libvirt] [PATCH 4/6] virNetDevMacVLanTapSetup: Rework to support multiple FDs
Laine Stump
laine at laine.org
Fri Dec 4 17:43:22 UTC 2015
On 12/04/2015 07:31 AM, Michal Privoznik wrote:
> So, for the multiqueue on macvtaps we are going to need to open
> the device multiple times. Currently, this is not supported.
> Rework the function, so that upper layers can be reworked too.
Either merge 3 & 4 together, or change the log message (I'm okay with
multiple functions at the same level being changed in the same patch).
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
> src/util/virnetdevmacvlan.c | 66 ++++++++++++++++++++++++---------------------
> 1 file changed, 35 insertions(+), 31 deletions(-)
>
> diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
> index d20990b..f7a7d72 100644
> --- a/src/util/virnetdevmacvlan.c
> +++ b/src/util/virnetdevmacvlan.c
> @@ -302,10 +302,9 @@ virNetDevMacVLanTapOpen(const char *ifname,
>
> /**
> * virNetDevMacVLanTapSetup:
> - * @tapfd: file descriptor of the macvtap tap
> - * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it
> - *
> - * Returns 0 on success, -1 in case of fatal error, error code otherwise.
> + * @tapfd: array of file descriptors of the macvtap tap
> + * @tapfdSize: number of file descriptors in @tapfd
> + * @vnet_hdr: whether to enable or disable IFF_VNET_HDR
> *
> * Turn the IFF_VNET_HDR flag, if requested and available, make sure
> * it's off in the other cases.
> @@ -313,47 +312,52 @@ virNetDevMacVLanTapOpen(const char *ifname,
> * be turned off for some reason. This is reported with -1. Other fatal
> * error is not being able to read the interface flags. In that case the
> * macvtap device should not be used.
> + *
Comparing this to the VNET_HDR stuff for tap devices, I see that in that
case lack of support for VNET_HDR isn't fatal - it simply isn't set. My
guess is that VNET_HDR support was probably added prior to macvtap, so
that it's always there if we're doing macvtap, but I don't know for
sure. (I'm just wondering if maybe there's some way code could be shared
between the two to reduce maintenance).
The other difference is that IFF_MULTI_QUEUE is set on each fd for a tap
device. Is this also needed for macvtap?
> + * Returns 0 on success, -1 in case of fatal error, error code otherwise.
> */
> static int
> -virNetDevMacVLanTapSetup(int tapfd, int vnet_hdr)
> +virNetDevMacVLanTapSetup(int *tapfd, size_t tapfdSize, bool vnet_hdr)
> {
> unsigned int features;
> struct ifreq ifreq;
> short new_flags = 0;
> int rc_on_fail = 0;
> const char *errmsg = NULL;
> + size_t i;
>
> - memset(&ifreq, 0, sizeof(ifreq));
> + for (i = 0; i < tapfdSize; i++) {
> + memset(&ifreq, 0, sizeof(ifreq));
>
> - if (ioctl(tapfd, TUNGETIFF, &ifreq) < 0) {
> - virReportSystemError(errno, "%s",
> - _("cannot get interface flags on macvtap tap"));
> - return -1;
> - }
> -
> - new_flags = ifreq.ifr_flags;
> -
> - if ((ifreq.ifr_flags & IFF_VNET_HDR) && !vnet_hdr) {
> - new_flags = ifreq.ifr_flags & ~IFF_VNET_HDR;
> - rc_on_fail = -1;
> - errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap");
> - } else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) {
> - if (ioctl(tapfd, TUNGETFEATURES, &features) < 0) {
> + if (ioctl(tapfd[i], TUNGETIFF, &ifreq) < 0) {
> virReportSystemError(errno, "%s",
> - _("cannot get feature flags on macvtap tap"));
> + _("cannot get interface flags on macvtap tap"));
> return -1;
> }
> - if ((features & IFF_VNET_HDR)) {
> - new_flags = ifreq.ifr_flags | IFF_VNET_HDR;
> - errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap");
> +
> + new_flags = ifreq.ifr_flags;
> +
> + if ((ifreq.ifr_flags & IFF_VNET_HDR) && !vnet_hdr) {
> + new_flags = ifreq.ifr_flags & ~IFF_VNET_HDR;
> + rc_on_fail = -1;
> + errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap");
> + } else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) {
> + if (ioctl(tapfd[i], TUNGETFEATURES, &features) < 0) {
> + virReportSystemError(errno, "%s",
> + _("cannot get feature flags on macvtap tap"));
> + return -1;
> + }
> + if ((features & IFF_VNET_HDR)) {
> + new_flags = ifreq.ifr_flags | IFF_VNET_HDR;
> + errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap");
> + }
> }
> - }
>
> - if (new_flags != ifreq.ifr_flags) {
> - ifreq.ifr_flags = new_flags;
> - if (ioctl(tapfd, TUNSETIFF, &ifreq) < 0) {
> - virReportSystemError(errno, "%s", errmsg);
> - return rc_on_fail;
> + if (new_flags != ifreq.ifr_flags) {
> + ifreq.ifr_flags = new_flags;
> + if (ioctl(tapfd[i], TUNSETIFF, &ifreq) < 0) {
> + virReportSystemError(errno, "%s", errmsg);
> + return rc_on_fail;
> + }
> }
> }
>
> @@ -864,7 +868,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
> if (virNetDevMacVLanTapOpen(cr_ifname, &rc, 1, 10) < 0)
> goto disassociate_exit;
>
> - if (virNetDevMacVLanTapSetup(rc, vnet_hdr) < 0) {
> + if (virNetDevMacVLanTapSetup(&rc, 1, vnet_hdr) < 0) {
> VIR_FORCE_CLOSE(rc); /* sets rc to -1 */
> goto disassociate_exit;
> }
More information about the libvir-list
mailing list