> OK, if I understand properly here, the problem is that asking the Linux
> kernel datapath to add a bridge named "default" does two things.  First,
> it fails.  Second, it triggers a notifier that causes OVS to try again.
> The second part is what makes this different from other failures and
> what makes OVS use 100% CPU in this case but not other cases.  Is that
> right?
>
Yes

> If I'm right, then how about something like the following instead?  It
> pushes this down to Linux-specific code, which seems better because this
> is a Linux-specific issue, and it thoroughly documents the problem.  It
> compiles but I have not tested it.
>
> Thanks,
>
> Ben.
>
> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
> index 9ff1333f8e85..79e827303d07 100644
> --- a/lib/netdev-linux.c
> +++ b/lib/netdev-linux.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
> + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 
> Nicira, Inc.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -773,10 +773,28 @@ netdev_linux_alloc(void)
>      return &netdev->up;
>  }
>
> -static void
> -netdev_linux_common_construct(struct netdev_linux *netdev)
> -{
> +static int
> +netdev_linux_common_construct(struct netdev *netdev_)
> +{
> +    /* Prevent any attempt to create (or open) a network device named 
> "default"
> +     * or "all".  These device names are effectively reserved on Linux 
> because
> +     * /proc/sys/net/ipv4/conf/ always contains directories by these names.  
> By
> +     * itself this wouldn't call for any special treatment, but in practice 
> if
> +     * a program tries to create devices with these names, it causes the 
> kernel
> +     * to fire a "new device" notification event even though creation failed,
> +     * and in turn that causes OVS to wake up and try to create them again,
> +     * which ends up as a 100% CPU loop. */
> +    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
> +    const char *name = netdev_->name;
> +    if (!strcmp(name, "default") || !strcmp(name, "all")) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
> +        VLOG_WARN_RL(&rl, "%s: Linux forbids network device with this name",
> +                     name);
> +        return EINVAL;
> +    }
> +
>      ovs_mutex_init(&netdev->mutex);
> +    return 0;
>  }
>
>  /* Creates system and internal devices. */
> @@ -784,9 +802,10 @@ static int
>  netdev_linux_construct(struct netdev *netdev_)
>  {
>      struct netdev_linux *netdev = netdev_linux_cast(netdev_);
> -    int error;
> -
> -    netdev_linux_common_construct(netdev);
> +    int error = netdev_linux_common_construct(netdev_);
> +    if (error) {
> +        return error;
> +    }
>
>      error = get_flags(&netdev->up, &netdev->ifi_flags);
>      if (error == ENODEV) {
> @@ -817,9 +836,11 @@ netdev_linux_construct_tap(struct netdev *netdev_)
>      static const char tap_dev[] = "/dev/net/tun";
>      const char *name = netdev_->name;
>      struct ifreq ifr;
> -    int error;
>
> -    netdev_linux_common_construct(netdev);
> +    int error = netdev_linux_common_construct(netdev_);
> +    if (error) {
> +        return error;
> +    }
>
>      /* Open tap device. */
>      netdev->tap_fd = open(tap_dev, O_RDWR);

Thanks! I've tested it and it works ok.
Regards,
William
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to