[libvirt] [PATCH] Fix vlan ID detection in udev interface driver

Dave Allan dallan at redhat.com
Fri Apr 25 15:21:39 UTC 2014


On Thu, Apr 24, 2014 at 03:19:45PM +0200, Ján Tomko wrote:
> Instead of guessing it from the interface name, look into
> /proc/net/vlan/<interface>.
> 
> This works for devices not named <real_device>.<vlan ID>,
> avoiding an error flood when virt-manager keeps asking about
> them every second:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=966329

What's the equivalent virsh command that produces the errors?  

Dave


> ---
>  src/interface/interface_backend_udev.c | 67 ++++++++++++++++++++++++++--------
>  1 file changed, 51 insertions(+), 16 deletions(-)
> 
> diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
> index b05ac0e..bec8c45 100644
> --- a/src/interface/interface_backend_udev.c
> +++ b/src/interface/interface_backend_udev.c
> @@ -20,11 +20,13 @@
>   */
>  #include <config.h>
>  
> +#include <ctype.h>
>  #include <errno.h>
>  #include <dirent.h>
>  #include <libudev.h>
>  
>  #include "virerror.h"
> +#include "virfile.h"
>  #include "c-ctype.h"
>  #include "datatypes.h"
>  #include "domain_conf.h"
> @@ -966,31 +968,64 @@ udevGetIfaceDefVlan(struct udev *udev ATTRIBUTE_UNUSED,
>                      const char *name,
>                      virInterfaceDef *ifacedef)
>  {
> -    const char *vid;
> +    char *procpath = NULL;
> +    char *buf = NULL;
> +    char *vid_pos, *dev_pos;
> +    size_t vid_len, dev_len;
> +    const char *vid_prefix = "VID: ";
> +    const char *dev_prefix = "\nDevice: ";
> +    int ret = -1;
> +
> +    if (virAsprintf(&procpath, "/proc/net/vlan/%s", name) < 0)
> +        goto cleanup;
> +
> +    if (virFileReadAll(procpath, BUFSIZ, &buf) < 0)
> +        goto cleanup;
>  
> -    /* Find the DEVICE.VID again */
> -    vid = strrchr(name, '.');
> -    if (!vid) {
> +    if ((vid_pos = strstr(buf, vid_prefix)) == NULL) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         _("failed to find the VID for the VLAN device '%s'"),
>                         name);
> -        return -1;
> +        goto cleanup;
>      }
> +    vid_pos += strlen(vid_prefix);
>  
> -    /* Set the VLAN specifics */
> -    if (VIR_STRDUP(ifacedef->data.vlan.tag, vid + 1) < 0)
> -        goto error;
> -    if (VIR_STRNDUP(ifacedef->data.vlan.devname,
> -                    name, (vid - name)) < 0)
> -        goto error;
> +    if ((vid_len = strspn(vid_pos, "0123456789")) == 0 ||
> +        !isspace(vid_pos[vid_len])) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("failed to find the VID for the VLAN device '%s'"),
> +                       name);
> +        goto cleanup;
> +    }
>  
> -    return 0;
> +    if ((dev_pos = strstr(vid_pos + vid_len, dev_prefix)) == NULL) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("failed to find the real device for the VLAN device '%s'"),
> +                       name);
> +        goto cleanup;
> +    }
> +    dev_pos += strlen(dev_prefix);
>  
> - error:
> -    VIR_FREE(ifacedef->data.vlan.tag);
> -    VIR_FREE(ifacedef->data.vlan.devname);
> +    if ((dev_len = strcspn(dev_pos, "\n")) == 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("failed to find the real device for the VLAN device '%s'"),
> +                       name);
> +        goto cleanup;
> +    }
>  
> -    return -1;
> +    if (VIR_STRNDUP(ifacedef->data.vlan.tag, vid_pos, vid_len) < 0)
> +        goto cleanup;
> +    if (VIR_STRNDUP(ifacedef->data.vlan.devname, dev_pos, dev_len) < 0) {
> +        VIR_FREE(ifacedef->data.vlan.tag);
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +
> + cleanup:
> +    VIR_FREE(procpath);
> +    VIR_FREE(buf);
> +    return ret;
>  }
>  
>  static virInterfaceDef * ATTRIBUTE_NONNULL(1)
> -- 
> 1.8.3.2
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list




More information about the libvir-list mailing list