[libvirt] RFC: a <uuid> for every <interface> in each domain

A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it: 1) In order to properly track information as a guest is disconnected and reconnected to an Open vSwitch bridge, the initial Open vSwitch support added an "interfaceid" parameter to virtualport. If the interfaceid isn't specified by the user when the interface is defined, one is automatically generated and placed into the persistent definition. But if the guest interface is just <interface type='network'>, it isn't known at the time of definition whether this interface will be using an Open vSwitch connection, or something else. Then, by the time we get into the network driver and decide that we're going to use Open vSwitch, it's too late to conveniently/cleanly generate an interfaceid and plug it back into the <virtualport> of the interface's persistent config. The result is that each time the guest is restarted, Open vSwitch gets a new interfaceid for it, and can't properly track things. If every interface had a uuid, the code that connects to an Open vSwitch network could just use the interface's uuid if interfaceid wasn't specified. 2) I'm about to write some patches that will allow enacting config changes to a network without needing to destroy/re-start the network. One thing that came up while I was mulling over what could and couldn't be modified without a restart is that it will be possible to allow removing physical interfaces from a network's interface pool (used for macvtap and hostdev modes), but only if that physical interface isn't currently in use. There is a use counter on each interface so we can easily tell when that situation occurs, but once we know of the failure, we have no way of pointing to which guest is causing the problem. If each interface had a uuid, we could save a list of the uuid's of all interfaces currently connected to a particular physical interface, and report that in the failure message. It would then be a fairly mechanical task to find that uuid in the guests' config. Does this sound like a reasonable idea? Any reasons *not* to do it? Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one?

On 08/15/2012 10:27 AM, Laine Stump wrote:
A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it:
Does this sound like a reasonable idea? Any reasons *not* to do it?
I think the idea makes sense.
Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one?
I'm worried about how it gets added. Adding it to src/datatypes.h virInterfacePtr would be most similar to how we do things for other objects with a UUID (virDomainPtr, virNetworkPtr, virStoragePoolPtr, virSecretPtr, virNWFilterPtr), but touching datatypes.h is a huge pain because it would be an ABI break. How do we keep RPC protocol sane without passing the UUID around, but client and server are still always referring to the same object? -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Wed, Aug 15, 2012 at 11:05:10AM -0600, Eric Blake wrote:
On 08/15/2012 10:27 AM, Laine Stump wrote:
A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it:
Does this sound like a reasonable idea? Any reasons *not* to do it?
I think the idea makes sense.
Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one?
I'm worried about how it gets added. Adding it to src/datatypes.h virInterfacePtr would be most similar to how we do things for other objects with a UUID (virDomainPtr, virNetworkPtr, virStoragePoolPtr, virSecretPtr, virNWFilterPtr), but touching datatypes.h is a huge pain because it would be an ABI break. How do we keep RPC protocol sane without passing the UUID around, but client and server are still always referring to the same object?
virInterfacePtr != <interface> in domain XML, so this isn't an issue Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 08/15/2012 01:05 PM, Eric Blake wrote:
On 08/15/2012 10:27 AM, Laine Stump wrote:
A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it:
Does this sound like a reasonable idea? Any reasons *not* to do it? I think the idea makes sense.
Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one? I'm worried about how it gets added. Adding it to src/datatypes.h virInterfacePtr would be most similar to how we do things for other objects with a UUID (virDomainPtr, virNetworkPtr, virStoragePoolPtr, virSecretPtr, virNWFilterPtr), but touching datatypes.h is a huge pain because it would be an ABI break. How do we keep RPC protocol sane without passing the UUID around, but client and server are still always referring to the same object?
I don't think we need to worry about that, because these aren't the interface objects that are passed around by the API (those are referring to physical host interfaces manipulated by the virInterface* API). The interfaces I'm talking about are the ones that are part of a domain's definition. - they're just a chunk of text inside the XML of a domain object (known as virDomainNetworkDef in C), and have no visibility in libvirt's public API (other than as elements of the domain XML).

On Wed, Aug 15, 2012 at 12:27:58PM -0400, Laine Stump wrote:
A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it:
1) In order to properly track information as a guest is disconnected and reconnected to an Open vSwitch bridge, the initial Open vSwitch support added an "interfaceid" parameter to virtualport. If the interfaceid isn't specified by the user when the interface is defined, one is automatically generated and placed into the persistent definition.
But if the guest interface is just <interface type='network'>, it isn't known at the time of definition whether this interface will be using an Open vSwitch connection, or something else. Then, by the time we get into the network driver and decide that we're going to use Open vSwitch, it's too late to conveniently/cleanly generate an interfaceid and plug it back into the <virtualport> of the interface's persistent config. The result is that each time the guest is restarted, Open vSwitch gets a new interfaceid for it, and can't properly track things.
If every interface had a uuid, the code that connects to an Open vSwitch network could just use the interface's uuid if interfaceid wasn't specified.
Can't we just query the network at time of domain definitiion to determine what type it is, and then just fill in a interfaceid ? In any case if someon really cares about stable interfaceids they ought to just be providing that info themselves in the domain XML, because nothing can make this work with transient VMs.
2) I'm about to write some patches that will allow enacting config changes to a network without needing to destroy/re-start the network. One thing that came up while I was mulling over what could and couldn't be modified without a restart is that it will be possible to allow removing physical interfaces from a network's interface pool (used for macvtap and hostdev modes), but only if that physical interface isn't currently in use. There is a use counter on each interface so we can easily tell when that situation occurs, but once we know of the failure, we have no way of pointing to which guest is causing the problem. If each interface had a uuid, we could save a list of the uuid's of all interfaces currently connected to a particular physical interface, and report that in the failure message. It would then be a fairly mechanical task to find that uuid in the guests' config.
I would have thought this could be solved just by having a reference back to the VM that is using the device, rather than the <interface>.
Does this sound like a reasonable idea? Any reasons *not* to do it? Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one?
I'm not too sure really, though my gut feeling is to not have a UUID against the interface, and I don't think the two scenarios above really require it Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 08/15/2012 01:07 PM, Daniel P. Berrange wrote:
On Wed, Aug 15, 2012 at 12:27:58PM -0400, Laine Stump wrote:
A couple of situations have come up recently that could be solved by every interface in every domain always having a unique identifier associated with it:
1) In order to properly track information as a guest is disconnected and reconnected to an Open vSwitch bridge, the initial Open vSwitch support added an "interfaceid" parameter to virtualport. If the interfaceid isn't specified by the user when the interface is defined, one is automatically generated and placed into the persistent definition.
But if the guest interface is just <interface type='network'>, it isn't known at the time of definition whether this interface will be using an Open vSwitch connection, or something else. Then, by the time we get into the network driver and decide that we're going to use Open vSwitch, it's too late to conveniently/cleanly generate an interfaceid and plug it back into the <virtualport> of the interface's persistent config. The result is that each time the guest is restarted, Open vSwitch gets a new interfaceid for it, and can't properly track things.
If every interface had a uuid, the code that connects to an Open vSwitch network could just use the interface's uuid if interfaceid wasn't specified. Can't we just query the network at time of domain definitiion to determine what type it is, and then just fill in a interfaceid ?
That doesn't work because the network on the host where the domain is defined isn't necessarily the network on the host where it will be running at some random time in the future. Even the same host might change its network setup. A large part of the motivation for creating the new network types was to eliminate this hard connection between the domain's definition and the hardware where it currently resides.
In any case if someon really cares about stable interfaceids they ought to just be providing that info themselves in the domain XML, because nothing can make this work with transient VMs.
You are correct about transient domains. The code that I just checked in solves the problem (for persistent domains of course) by allowing a <virtualport/> element to be added to the interface with no type and no parameters. If this is done, both the interfaceid and the instanceid are filled in with autogenerated uuids in anticipation that some time in the future there may be a need to connect to an Open vSwitch network or 802.1Qbg network. (or of course, those could be filled in beforehand with known data by whatever application/person is creating the XML) It just seems more elegant to have a single identifier that's guaranteed to be available, and can be used for multiple tasks, rather than tacking on a new one each time we come up with a new use case.
2) I'm about to write some patches that will allow enacting config changes to a network without needing to destroy/re-start the network. One thing that came up while I was mulling over what could and couldn't be modified without a restart is that it will be possible to allow removing physical interfaces from a network's interface pool (used for macvtap and hostdev modes), but only if that physical interface isn't currently in use. There is a use counter on each interface so we can easily tell when that situation occurs, but once we know of the failure, we have no way of pointing to which guest is causing the problem. If each interface had a uuid, we could save a list of the uuid's of all interfaces currently connected to a particular physical interface, and report that in the failure message. It would then be a fairly mechanical task to find that uuid in the guests' config. I would have thought this could be solved just by having a reference back to the VM that is using the device, rather than the <interface>.
Yeah, I could add that to the (currently internal) API instead.
Does this sound like a reasonable idea? Any reasons *not* to do it? Problems we'll need to take care of if we add it (for example, existing guest interfaces will all need to get a uuid during the upgrade process, similar to the way we add a mac address to all existing networks that don't have one). Any other things you can think of doing with uuid if we add one? I'm not too sure really, though my gut feeling is to not have a UUID against the interface, and I don't think the two scenarios above really require it
Okay. Since it's not 100% and there's not 100% consensus that it's worthwhile, I'll drop it unless/until another situation comes up. When in doubt, inaction is usually a good policy :-)
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Laine Stump