[RFC]: help, how to get the mac after create a VM interface.

when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac. Should the CREATE method always needs to return an interface info? Here is some of create code. def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """ dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT) # here I need to return the mac return ???? The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """ -- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

On 01/20/2014 09:34 PM, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """
check the libvirt code: libvirt will generate a mac address, and the mac starts with "52:52:00" and the others bit are generated by virRandomBits virDomainNetGenerateMAC(xmlopt, &def->mac); void virDomainNetGenerateMAC(virDomainXMLOptionPtr xmlopt, virMacAddrPtr mac) { virMacAddrGenerate(xmlopt->config.macPrefix, mac); } void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN], virMacAddrPtr addr) { addr->addr[0] = prefix[0]; addr->addr[1] = prefix[1]; addr->addr[2] = prefix[2]; addr->addr[3] = virRandomBits(8); addr->addr[4] = virRandomBits(8); addr->addr[5] = virRandomBits(8); } /** * virRandomBits: * @nbits: Number of bits of randommess required * * Generate an evenly distributed random number between [0,2^nbits), where * @nbits must be in the range (0,64]. * * Return: a random number with @nbits entropy */ uint64_t virRandomBits(int nbits) { uint64_t ret = 0; int32_t bits; if (virRandomInitialize() < 0) { /* You're already hosed, so this particular non-random value * isn't any worse. */ VIR_WARN("random number generation is broken"); return 0; } virMutexLock(&randomLock); while (nbits > RANDOM_BITS_PER_ITER) { random_r(&randomData, &bits); ret = (ret << RANDOM_BITS_PER_ITER) | (bits & RANDOM_BITS_MASK); nbits -= RANDOM_BITS_PER_ITER; } random_r(&randomData, &bits); ret = (ret << nbits) | (bits & ((1 << nbits) - 1)); virMutexUnlock(&randomLock); return ret; } /** * virDomainXMLOptionNew: * * Allocate a new domain XML configuration */ virDomainXMLOptionPtr virDomainXMLOptionNew(virDomainDefParserConfigPtr config, virDomainXMLPrivateDataCallbacksPtr priv, virDomainXMLNamespacePtr xmlns) { virDomainXMLOptionPtr xmlopt; ... /* Technically this forbids to use one of Xerox's MAC address prefixes in * our hypervisor drivers. This shouldn't ever be a problem. * * Use the KVM prefix as default as it's in the privately administered * range */ if (xmlopt->config.macPrefix[0] == 0 && xmlopt->config.macPrefix[1] == 0 && xmlopt->config.macPrefix[2] == 0) { xmlopt->config.macPrefix[0] = 0x52; xmlopt->config.macPrefix[1] = 0x54; } return xmlopt; } -- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

于 2014/1/20 23:22, Sheldon 写道:
On 01/20/2014 09:34 PM, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces.
If the vm have several interfaces, dictionary may help you to return these interfaces.
xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """
check the libvirt code: libvirt will generate a mac address, and the mac starts with "52:52:00" and the others bit are generated by virRandomBits
virDomainNetGenerateMAC(xmlopt, &def->mac);
void virDomainNetGenerateMAC(virDomainXMLOptionPtr xmlopt, virMacAddrPtr mac) { virMacAddrGenerate(xmlopt->config.macPrefix, mac); }
void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN], virMacAddrPtr addr) { addr->addr[0] = prefix[0]; addr->addr[1] = prefix[1]; addr->addr[2] = prefix[2]; addr->addr[3] = virRandomBits(8); addr->addr[4] = virRandomBits(8); addr->addr[5] = virRandomBits(8); }
/** * virRandomBits: * @nbits: Number of bits of randommess required * * Generate an evenly distributed random number between [0,2^nbits), where * @nbits must be in the range (0,64]. * * Return: a random number with @nbits entropy */ uint64_t virRandomBits(int nbits) { uint64_t ret = 0; int32_t bits;
if (virRandomInitialize() < 0) { /* You're already hosed, so this particular non-random value * isn't any worse. */ VIR_WARN("random number generation is broken"); return 0; }
virMutexLock(&randomLock);
while (nbits > RANDOM_BITS_PER_ITER) { random_r(&randomData, &bits); ret = (ret << RANDOM_BITS_PER_ITER) | (bits & RANDOM_BITS_MASK); nbits -= RANDOM_BITS_PER_ITER; }
random_r(&randomData, &bits); ret = (ret << nbits) | (bits & ((1 << nbits) - 1));
virMutexUnlock(&randomLock); return ret; }
/** * virDomainXMLOptionNew: * * Allocate a new domain XML configuration */ virDomainXMLOptionPtr virDomainXMLOptionNew(virDomainDefParserConfigPtr config, virDomainXMLPrivateDataCallbacksPtr priv, virDomainXMLNamespacePtr xmlns) { virDomainXMLOptionPtr xmlopt;
...
/* Technically this forbids to use one of Xerox's MAC address prefixes in * our hypervisor drivers. This shouldn't ever be a problem. * * Use the KVM prefix as default as it's in the privately administered * range */ if (xmlopt->config.macPrefix[0] == 0 && xmlopt->config.macPrefix[1] == 0 && xmlopt->config.macPrefix[2] == 0) { xmlopt->config.macPrefix[0] = 0x52; xmlopt->config.macPrefix[1] = 0x54; }
return xmlopt; }

On 01/20/2014 11:34 AM, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """
We can generate the mac and pass it to libvirt:
import virtinst.util print virtinst.util.randomMAC() 00:16:3e:fd:b4:3a
I don't if libvirt requires a mac starting with "52:52:00" Maybe it is used to avoid generating duplicated mac addresses.

于 2014/1/21 1:17, Aline Manera 写道:
On 01/20/2014 11:34 AM, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """
We can generate the mac and pass it to libvirt:
import virtinst.util print virtinst.util.randomMAC() 00:16:3e:fd:b4:3a
Let libvirt to generate the MAC addresses are better. randomMAC() does not gurantee that the MAC address generated is unique, so you need to handle that in your code. If libvirt doesn't gurantee that either, we can file a bug against libvirt.
I don't if libvirt requires a mac starting with "52:52:00" Maybe it is used to avoid generating duplicated mac addresses.
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

On 01/20/2014 10:43 PM, Shu Ming wrote:
于 2014/1/21 1:17, Aline Manera 写道:
On 01/20/2014 11:34 AM, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """
We can generate the mac and pass it to libvirt:
import virtinst.util print virtinst.util.randomMAC() 00:16:3e:fd:b4:3a
Let libvirt to generate the MAC addresses are better. randomMAC() does not gurantee that the MAC address generated is unique, so you need to handle that in your code. If libvirt doesn't gurantee that either, we can file a bug against libvirt.
Ok. But if we let libvirt generates the MAC we come back to the original problem mentioned by Sheldon. How do we get the MAC to return to kimchi API?
I don't if libvirt requires a mac starting with "52:52:00" Maybe it is used to avoid generating duplicated mac addresses.
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel

libvirt always adds the new interface to the end of the group. I did a little experimenting to make sure. So, you could just parse the interfaces and pull the MAC from the last one returned. It's not very elegant, though. On Mon, 2014-01-20 at 21:34 +0800, Sheldon wrote:
when I create a interface, There is no mac attribute in the xml. After create successfully, libvirt will allocate a mac. The problem is that, How can I get the mac.
Should the CREATE method always needs to return an interface info?
Here is some of create code.
def vmifaces_create(self, vm, params): dom = self._get_vm(vm) xml = """ <interface type='network'> <source network='default'/> </interface> """
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
# here I need to return the mac return ????
The libvirt will create a xml like the follow? The problem is that the a vm may have several interfaces. xml = """ <interface type='network'> <mac address='52:54:00:2a:53:8f'/> <source network='default'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> """

libvirt always adds the new interface to the end of the group. I did a little experimenting to make sure. So, you could just parse the interfaces and pull the MAC from the last one returned. It's not very elegant, though. ... and not very reliable. There may be other operations happening at
Am 22-01-2014 15:45, schrieb Christy Perez: the same time (like someone else creating another NIC), and the last interface returned may have been created by other user. It's a web app, we should expect simultaneous access. But I don't have another solution for this...

Agree. Not reliable. I did forget that other people may be doing the exact same thing at the exact same time, though, which makes it a bad approach. Regards, - Christy On Wed, 2014-01-22 at 15:51 -0200, Crístian Viana wrote:
libvirt always adds the new interface to the end of the group. I did a little experimenting to make sure. So, you could just parse the interfaces and pull the MAC from the last one returned. It's not very elegant, though. ... and not very reliable. There may be other operations happening at
Am 22-01-2014 15:45, schrieb Christy Perez: the same time (like someone else creating another NIC), and the last interface returned may have been created by other user. It's a web app, we should expect simultaneous access.
But I don't have another solution for this...

On 01/23/2014 06:55 AM, Christy Perez wrote:
Agree. Not reliable. I did forget that other people may be doing the exact same thing at the exact same time, though, which makes it a bad approach. a global lock just for mac?
Regards,
- Christy
On Wed, 2014-01-22 at 15:51 -0200, Crístian Viana wrote:
libvirt always adds the new interface to the end of the group. I did a little experimenting to make sure. So, you could just parse the interfaces and pull the MAC from the last one returned. It's not very elegant, though. ... and not very reliable. There may be other operations happening at
Am 22-01-2014 15:45, schrieb Christy Perez: the same time (like someone else creating another NIC), and the last interface returned may have been created by other user. It's a web app, we should expect simultaneous access.
But I don't have another solution for this...
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

On 01/23/2014 06:55 AM, Christy Perez wrote:
Agree. Not reliable. I did forget that other people may be doing the exact same thing at the exact same time, though, which makes it a bad approach. a global lock just for mac?
How about just using randomMAC() and then checking the ARP cache before
On Thu, 2014-01-23 at 10:13 +0800, Sheldon wrote: passing it to libvirt? I feel like the odds of two people generating the same MAC using randomMAC() at the same time are almost zero. Or -- we could just have a lock for any and all modifications to a VM. IOW - a VM-specific lock. Maybe not all modifications would need to acquire it, but this one would be one that would.
Regards,
- Christy
On Wed, 2014-01-22 at 15:51 -0200, Crístian Viana wrote:
libvirt always adds the new interface to the end of the group. I did a little experimenting to make sure. So, you could just parse the interfaces and pull the MAC from the last one returned. It's not very elegant, though. ... and not very reliable. There may be other operations happening at
Am 22-01-2014 15:45, schrieb Christy Perez: the same time (like someone else creating another NIC), and the last interface returned may have been created by other user. It's a web app, we should expect simultaneous access.
But I don't have another solution for this...
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
participants (5)
-
Aline Manera
-
Christy Perez
-
Crístian Viana
-
Sheldon
-
Shu Ming