[PATCHv2 2/2] util:veth: Create veth device pair by netlink

Laine Stump laine at redhat.com
Tue Dec 8 15:04:59 UTC 2020


On 12/8/20 4:19 AM, Daniel P. Berrangé wrote:
> On Mon, Dec 07, 2020 at 05:54:51PM -0500, Laine Stump wrote:
>> On 11/22/20 10:28 PM, Shi Lei wrote:
>>> When netlink is supported, use netlink to create veth device pair
>>> rather than 'ip link' command.
>>>
>>> Signed-off-by: Shi Lei <shi_lei at massclouds.com>
>>> ---
>>>    src/util/virnetdevveth.c | 85 ++++++++++++++++++++++++++--------------
>>>    1 file changed, 56 insertions(+), 29 deletions(-)
>>>
>>> diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
>>> index b3eee1af..b4074371 100644
>>> --- a/src/util/virnetdevveth.c
>>> +++ b/src/util/virnetdevveth.c
>>> @@ -27,6 +27,7 @@
>>>    #include "virfile.h"
>>>    #include "virstring.h"
>>>    #include "virnetdev.h"
>>> +#include "virnetlink.h"
>>>    #define VIR_FROM_THIS VIR_FROM_NONE
>>> @@ -75,6 +76,55 @@ static int virNetDevVethGetFreeNum(int startDev)
>>>        return -1;
>>>    }
>>> +#if defined(WITH_LIBNL)
>>> +static int
>>> +virNetDevVethCreateInternal(const char *veth1, const char *veth2, int *status)
>>> +{
>>> +    virNetlinkNewLinkData data = { .veth_peer = veth2 };
>>> +
>>> +    return virNetlinkNewLink(veth1, "veth", &data, status);
>>> +}
>>
>> The only thing that makes me uncomfortable in this patch is that the two
>> versions of virNetDevVethCreateInternal() each return something different
>> for "status". In this first case, it is returning 0 on success, and -errno
>> on failure...
> 
> Just change this to return -1, as we very rarely want to return -errno
> in libvirt, as we have formal error reporting.

I guess I should give a bit more detail here - the "-errno" returned by 
virNetlinkNewLink() isn't the value of errno in the libvirt process at 
the time it learns there was an error - it is the value of errno 
returned in the netlink response message, ie what errno was set to in 
the kernel context that is handling and responding to netlink messages. 
errno in the libvirt process will not be set to this value.

And since the libvirt functions that are decoding the response messages 
don't themselves log any errors, they aren't reporting that exact error...

...

Hmmm. this points out that we really need to be logging the exact error 
in virNetDevVethCreateInternal(), since once we return from that 
function we no longer have full info on the reason for the failure. This 
would have been a problem if we had any inclination to retry the 
operation (with a new device name, which the current code must do), but 
once the other series from Shi is applied (the one that changes veth 
name generation to mimic what is done for tap and macvtap), we won't 
need to worry about retrying, and so it will be acceptable to 
immediately log the error.


> 
>>
>>
>>> [...]
>>
>>> +#else
>>> +static int
>>> +virNetDevVethCreateInternal(const char *veth1, const char *veth2, int *status)
>>> +{
>>> +    g_autoptr(virCommand) cmd = virCommandNew("ip");
>>> +    virCommandAddArgList(cmd, "link", "add", veth1, "type", "veth",
>>> +                         "peer", "name", veth2, NULL);
>>> +
>>> +    return virCommandRun(cmd, status);
>>> +}
>>
>>
>> But in this case it is returning the exit code of the "ip link add" command.

Also in this case if status != NULL then virCommandRun() will only log 
an error if it failed to run the "ip" command; if ip runs but fails to 
create the device and returns an error exit code, virCommandRun() will 
silently return the exit code. In this case, we can just call 
"virCommandRun(cmd, NULL)" - when status is NULL, virCommandRun() will 
log an error if the exec fails, and also if the exec is successful but 
the command returns an error.

And since I'm already here typing - when I reviewed the other series 
(the ones that change the device name generation) I did arrive at the 
opinion that we should apply those patches first, and these patches on 
top of that - that way you won't have to worry about the possibility of 
needing to retry virNetDevVethCreateInternal with a new name, and it 
will be okay for its implementations to immediately log errors.





More information about the libvir-list mailing list