[libvirt] [PATCH] conf: forbid use of multicast mac addresses
by Laine Stump
A few times libvirt users manually setting mac addresses have
complained of networking failure that ends up being due to a multicast
mac address being used for a guest interface. This patch prevents that
by loggin an error and failing if a multicast mac address is
encountered in each of the three following cases:
1) domain xml <interface> mac address.
2) network xml bridge mac address.
3) network xml dhcp/host mac address.
There are several other places where a mac address cna be input that
aren't controlled in this manner because failure to do so has no
consequences (e.g., if the address will be used to search through
existing interfaces for a match).
The RNG has been updated to add multiMacAddr and uniMacAddr along with
the existing macAddr, and macAddr was switched to uniMacAddr where
appropriate.
---
docs/schemas/basictypes.rng | 17 ++++++++++++++++-
docs/schemas/domaincommon.rng | 6 +++---
docs/schemas/network.rng | 4 ++--
src/conf/domain_conf.c | 8 +++++++-
src/conf/network_conf.c | 33 ++++++++++++++++++++++++---------
src/libvirt_private.syms | 2 ++
src/util/virmacaddr.c | 13 +++++++++++++
src/util/virmacaddr.h | 3 ++-
8 files changed, 69 insertions(+), 17 deletions(-)
diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
index 7d7911d..9dbda4a 100644
--- a/docs/schemas/basictypes.rng
+++ b/docs/schemas/basictypes.rng
@@ -55,9 +55,24 @@
</define>
<!-- a 6 byte MAC address in ASCII-hex format, eg "12:34:56:78:9A:BC" -->
+ <!-- The lowest bit of the 1st byte is the "multicast" bit. a -->
+ <!-- uniMacAddr requires that bit to be 0, and a multiMacAddr -->
+ <!-- requires it to be 1. Plain macAddr will accept either. -->
+ <!-- Currently there is no use of multiMacAddr in libvirt, it -->
+ <!-- is included here for documentation/comparison purposes. -->
+ <define name="uniMacAddr">
+ <data type="string">
+ <param name="pattern">[a-fA-F0-9][02468aAcCeE](:[a-fA-F0-9]{2}){5}</param>
+ </data>
+ </define>
+ <define name="multiMacAddr">
+ <data type="string">
+ <param name="pattern">[a-fA-F0-9][13579bBdDfF](:[a-fA-F0-9]{2}){5}</param>
+ </data>
+ </define>
<define name="macAddr">
<data type="string">
- <param name="pattern">([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}</param>
+ <param name="pattern">[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}</param>
</data>
</define>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5b3e5fa..f629691 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1391,7 +1391,7 @@
<optional>
<element name="mac">
<attribute name="address">
- <ref name="macAddr"/>
+ <ref name="uniMacAddr"/>
</attribute>
<empty/>
</element>
@@ -1417,7 +1417,7 @@
<optional>
<element name="mac">
<attribute name="address">
- <ref name="macAddr"/>
+ <ref name="uniMacAddr"/>
</attribute>
<empty/>
</element>
@@ -1498,7 +1498,7 @@
<optional>
<element name="mac">
<attribute name="address">
- <ref name="macAddr"/>
+ <ref name="uniMacAddr"/>
</attribute>
<empty/>
</element>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 6e1002f..2ae879e 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -57,7 +57,7 @@
<!-- <mac> element -->
<optional>
<element name="mac">
- <attribute name="address"><ref name="macAddr"/></attribute>
+ <attribute name="address"><ref name="uniMacAddr"/></attribute>
<empty/>
</element>
</optional>
@@ -218,7 +218,7 @@
</zeroOrMore>
<zeroOrMore>
<element name="host">
- <attribute name="mac"><ref name="macAddr"/></attribute>
+ <attribute name="mac"><ref name="uniMacAddr"/></attribute>
<attribute name="name"><text/></attribute>
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
</element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e6d0f4b..d5def1c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4416,11 +4416,17 @@ virDomainNetDefParseXML(virCapsPtr caps,
if (macaddr) {
if (virMacAddrParse((const char *)macaddr, def->mac) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_XML_ERROR,
_("unable to parse mac address '%s'"),
(const char *)macaddr);
goto error;
}
+ if (virMacAddrIsMulticast(def->mac)) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("expected unicast mac address, found multicast '%s'"),
+ (const char *)macaddr);
+ goto error;
+ }
} else {
virCapabilitiesGenerateMac(caps, def->mac);
}
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 0fa58f8..87796b5 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -419,22 +419,30 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
def->nranges++;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "host")) {
- char *mac, *name, *ip;
+ char *mac = NULL, *name = NULL, *ip;
unsigned char addr[6];
virSocketAddr inaddr;
mac = virXMLPropString(cur, "mac");
- if ((mac != NULL) &&
- (virMacAddrParse(mac, &addr[0]) != 0)) {
- virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
- _("Cannot parse MAC address '%s' in network '%s'"),
- mac, networkName);
- VIR_FREE(mac);
- return -1;
+ if (mac != NULL) {
+ if (virMacAddrParse(mac, &addr[0]) < 0) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("Cannot parse MAC address '%s' in network '%s'"),
+ mac, networkName);
+ VIR_FREE(mac);
+ return -1;
+ }
+ if (virMacAddrIsMulticast(addr)) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("expected unicast mac address, found multicast '%s' in network '%s'"),
+ (const char *)mac, networkName);
+ VIR_FREE(mac);
+ return -1;
+ }
}
name = virXMLPropString(cur, "name");
if ((name != NULL) && (!c_isalpha(name[0]))) {
- virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
+ virNetworkReportError(VIR_ERR_XML_ERROR,
_("Cannot use name address '%s' in network '%s'"),
name, networkName);
VIR_FREE(name);
@@ -990,6 +998,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
VIR_FREE(tmp);
goto error;
}
+ if (virMacAddrIsMulticast(def->mac)) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("Invalid multicast bridge mac address '%s' in network '%s'"),
+ tmp, def->name);
+ VIR_FREE(tmp);
+ goto error;
+ }
VIR_FREE(tmp);
def->mac_specified = true;
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e40c80e..9a718b4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1208,6 +1208,8 @@ virKeycodeValueTranslate;
virMacAddrCompare;
virMacAddrFormat;
virMacAddrGenerate;
+virMacAddrIsMulticast;
+virMacAddrIsUnicast;
virMacAddrParse;
diff --git a/src/util/virmacaddr.c b/src/util/virmacaddr.c
index 70aef56..7b40397 100644
--- a/src/util/virmacaddr.c
+++ b/src/util/virmacaddr.c
@@ -126,3 +126,16 @@ void virMacAddrGenerate(const unsigned char *prefix,
addr[4] = virRandomBits(8);
addr[5] = virRandomBits(8);
}
+
+/* The low order bit of the first byte is the "multicast" bit. */
+bool
+virMacAddrIsMulticast(const unsigned char *addr)
+{
+ return !!(addr[0] & 1);
+}
+
+bool
+virMacAddrIsUnicast(const unsigned char *addr)
+{
+ return !(addr[0] & 1);
+}
diff --git a/src/util/virmacaddr.h b/src/util/virmacaddr.h
index 278f41e..f8d3e0c 100644
--- a/src/util/virmacaddr.h
+++ b/src/util/virmacaddr.h
@@ -37,5 +37,6 @@ void virMacAddrGenerate(const unsigned char *prefix,
unsigned char *addr);
int virMacAddrParse(const char* str,
unsigned char *addr) ATTRIBUTE_RETURN_CHECK;
-
+bool virMacAddrIsUnicast(const unsigned char *addr);
+bool virMacAddrIsMulticast(const unsigned char *addr);
#endif /* __VIR_MACADDR_H__ */
--
1.7.7.6
12 years, 9 months
[libvirt] [PATCH] conf: return immediately on error in dhcp host element
by Laine Stump
If and error was encountered parsing a dhcp host entry mac address or
name, parsing would continue and log a less descriptive error that
might make it more difficult to notice the true nature of the problem.
This patch returns immediately on logging the first error.
---
src/conf/network_conf.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 0333141..0fa58f8 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -430,6 +430,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
_("Cannot parse MAC address '%s' in network '%s'"),
mac, networkName);
VIR_FREE(mac);
+ return -1;
}
name = virXMLPropString(cur, "name");
if ((name != NULL) && (!c_isalpha(name[0]))) {
@@ -437,6 +438,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
_("Cannot use name address '%s' in network '%s'"),
name, networkName);
VIR_FREE(name);
+ return -1;
}
/*
* You need at least one MAC address or one host name
--
1.7.7.6
12 years, 9 months
[libvirt] [PATCH] Minor docs fix
by Martin Kletzander
End tag for "host" element was missing in example configuration
---
docs/formatnetwork.html.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 907c046..7e8e991 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -363,6 +363,7 @@
<host ip='192.168.122.2'>
<hostname>myhost</hostname>
<hostname>myhostalias</hostname>
+ </host>
</dns>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH] Cpu mapping cleanup
by Martin Kletzander
Using inheritance, this patch cleans up the cpu_map.xml file and also
sorts all CPU features according to the feature and registry
values. Model features are sorted the same way as foeatures in the
specification.
Also few models that are related were organized together and parts of
the XML are marked with comments
---
src/cpu/cpu_map.xml | 455 +++++++++-----------------------------------------
1 files changed, 82 insertions(+), 373 deletions(-)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index 6af9c40..9a89e2e 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -268,6 +268,7 @@
<feature name='pse'/>
</model>
+ <!-- Intel-based QEMU generic CPU models -->
<model name='pentium'>
<model name='486'/>
<feature name='de'/>
@@ -302,482 +303,190 @@
<feature name='pse'/>
<feature name='tsc'/>
<feature name='msr'/>
+ <feature name='pae'/>
<feature name='mce'/>
<feature name='cx8'/>
+ <feature name='apic'/>
+ <feature name='sep'/>
<feature name='pge'/>
<feature name='cmov'/>
<feature name='pat'/>
- <feature name='fxsr'/>
<feature name='mmx'/>
- <feature name='sse'/>
- <feature name='sse2'/>
- <feature name='pae'/>
- <feature name='sep'/>
- <feature name='apic'/>
- </model>
-
- <model name='qemu32'>
- <model name='pentiumpro'/>
- <feature name='pni'/>
- </model>
-
- <model name='cpu64-rhel5'>
- <feature name='apic'/>
- <feature name='clflush'/>
- <feature name='cmov'/>
- <feature name='cx8'/>
- <feature name='de'/>
- <feature name='fpu'/>
<feature name='fxsr'/>
- <feature name='lm'/>
- <feature name='mca'/>
- <feature name='mce'/>
- <feature name='mmx'/>
- <feature name='msr'/>
- <feature name='mtrr'/>
- <feature name='nx'/>
- <feature name='pae'/>
- <feature name='pat'/>
- <feature name='pge'/>
- <feature name='pse'/>
- <feature name='pse36'/>
- <feature name='sep'/>
<feature name='sse'/>
<feature name='sse2'/>
- <feature name='pni'/>
- <feature name='syscall'/>
- <feature name='tsc'/>
- </model>
-
- <model name='cpu64-rhel6'>
- <feature name='apic'/>
- <feature name='clflush'/>
- <feature name='cmov'/>
- <feature name='cx16'/>
- <feature name='cx8'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='fxsr'/>
- <feature name='lahf_lm'/>
- <feature name='lm'/>
- <feature name='mca'/>
- <feature name='mce'/>
- <feature name='mmx'/>
- <feature name='msr'/>
- <feature name='mtrr'/>
- <feature name='nx'/>
- <feature name='pae'/>
- <feature name='pat'/>
- <feature name='pge'/>
- <feature name='pse'/>
- <feature name='pse36'/>
- <feature name='sep'/>
- <feature name='sse'/>
- <feature name='sse2'/>
- <feature name='pni'/>
- <feature name='syscall'/>
- <feature name='tsc'/>
- </model>
-
- <model name='kvm32'>
- <model name='pentiumpro'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
</model>
<model name='coreduo'>
<model name='pentiumpro'/>
+ <vendor name='Intel'/>
<feature name='vme'/>
<feature name='mtrr'/>
- <feature name='clflush'/>
<feature name='mca'/>
+ <feature name='clflush'/>
<feature name='pni'/>
<feature name='monitor'/>
<feature name='nx'/>
</model>
- <model name='qemu64'>
- <model name='pentiumpro'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
- <feature name='cx16'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
- <feature name='svm'/>
- <!-- These are supported only by TCG. KVM supports them only if the
- host does. So we leave them out:
-
- <feature name='popcnt'/>
- <feature name='lahf_lm'/>
- <feature name='sse4a'/>
- <feature name='abm'/>
- -->
+ <model name='n270'>
+ <model name='coreduo'/>
+ <feature name='ssse3'/>
</model>
- <model name='kvm64'>
- <model name='pentiumpro'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
+ <model name='core2duo'>
+ <model name='n270'/>
<feature name='pse36'/>
- <feature name='pni'/>
- <feature name='cx16'/>
- <feature name='lm'/>
<feature name='syscall'/>
- <feature name='nx'/>
+ <feature name='lm'/>
</model>
- <model name='core2duo'>
+ <!-- Generic QEMU CPU models -->
+ <model name='qemu32'>
<model name='pentiumpro'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='vme'/>
- <feature name='pse36'/>
<feature name='pni'/>
- <feature name='monitor'/>
- <feature name='ssse3'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
</model>
- <model name='phenom'>
- <model name='pentiumpro'/>
- <vendor name='AMD'/>
+ <model name='kvm32'>
+ <model name='qemu32'/>
<feature name='mtrr'/>
- <feature name='clflush'/>
<feature name='mca'/>
<feature name='pse36'/>
- <feature name='pni'/>
- <feature name='monitor'/>
- <feature name='lm'/>
+ <feature name='clflush'/>
+ </model>
+
+ <model name='cpu64-rhel5'>
+ <model name='kvm32'/>
<feature name='syscall'/>
<feature name='nx'/>
- <feature name='3dnow'/>
- <feature name='3dnowext'/>
- <feature name='mmxext'/>
- <feature name='fxsr_opt'/>
- <feature name='svm'/>
+ <feature name='lm'/>
</model>
- <model name='athlon'>
- <model name='pentiumpro'/>
- <vendor name='AMD'/>
- <feature name='pse36'/>
- <feature name='vme'/>
- <feature name='mtrr'/>
- <feature name='mmxext'/>
- <feature name='3dnow'/>
- <feature name='3dnowext'/>
+ <model name='cpu64-rhel6'>
+ <model name='cpu64-rhel5'/>
+ <feature name='cx16'/>
+ <feature name='lahf_lm'/>
</model>
- <model name='n270'>
- <model name='pentiumpro'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='vme'/>
- <feature name='monitor'/>
- <feature name='pni'/>
- <feature name='ssse3'/>
- <feature name='nx'/>
+ <model name='kvm64'>
+ <model name='cpu64-rhel5'/>
+ <feature name='cx16'/>
</model>
+ <model name='qemu64'>
+ <model name='kvm64'/>
+ <!-- These are supported only by TCG. KVM supports them only if the
+ host does. So we leave them out:
+
+ <feature name='popcnt'/>
+ <feature name='lahf_lm'/>
+ <feature name='sse4a'/>
+ <feature name='abm'/>
+ -->
+ <feature name='svm'/>
+ </model>
+
+ <!-- Intel CPU models -->
<model name='Conroe'>
+ <model name='pentiumpro'/>
<vendor name='Intel'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
<feature name='mtrr'/>
- <feature name='clflush'/>
<feature name='mca'/>
<feature name='pse36'/>
+ <feature name='clflush'/>
<feature name='pni'/>
<feature name='ssse3'/>
- <feature name='lm'/>
<feature name='syscall'/>
<feature name='nx'/>
+ <feature name='lm'/>
<feature name='lahf_lm'/>
</model>
<model name='Penryn'>
- <vendor name='Intel'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
+ <model name='Conroe'/>
<feature name='cx16'/>
- <feature name='ssse3'/>
<feature name='sse4.1'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
- <feature name='lahf_lm'/>
</model>
<model name='Nehalem'>
- <vendor name='Intel'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
- <feature name='cx16'/>
- <feature name='ssse3'/>
- <feature name='sse4.1'/>
+ <model name='Penryn'/>
<feature name='sse4.2'/>
<feature name='popcnt'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
- <feature name='lahf_lm'/>
</model>
<model name='Westmere'>
- <vendor name='Intel'/>
<model name='Nehalem'/>
<feature name='aes'/>
</model>
<model name='SandyBridge'>
- <vendor name='Intel'/>
- <feature name='aes'/>
- <feature name='apic'/>
- <feature name='avx'/>
- <feature name='clflush'/>
- <feature name='cmov'/>
- <feature name='cx16'/>
- <feature name='cx8'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='fxsr'/>
- <feature name='lahf_lm'/>
- <feature name='lm'/>
- <feature name='mca'/>
- <feature name='mce'/>
- <feature name='mmx'/>
- <feature name='msr'/>
- <feature name='mtrr'/>
- <feature name='nx'/>
- <feature name='pae'/>
- <feature name='pat'/>
+ <model name='Westmere'/>
<feature name='pclmuldq'/>
- <feature name='pge'/>
- <feature name='pni'/>
- <feature name='popcnt'/>
- <feature name='pse'/>
- <feature name='pse36'/>
- <feature name='rdtscp'/>
- <feature name='sep'/>
- <feature name='sse'/>
- <feature name='sse2'/>
- <feature name='sse4.1'/>
- <feature name='sse4.2'/>
- <feature name='ssse3'/>
- <feature name='syscall'/>
- <feature name='tsc'/>
- <feature name='tsc-deadline'/>
<feature name='x2apic'/>
+ <feature name='tsc-deadline'/>
<feature name='xsave'/>
+ <feature name='avx'/>
+ <feature name='rdtscp'/>
</model>
- <model name='Opteron_G1'>
+ <!-- AMD CPUs -->
+ <model name='athlon'>
+ <model name='pentiumpro'/>
<vendor name='AMD'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
+ <feature name='vme'/>
<feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
<feature name='pse36'/>
- <feature name='pni'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
+ <feature name='mmxext'/>
+ <feature name='3dnowext'/>
+ <feature name='3dnow'/>
</model>
- <model name='Opteron_G2'>
+ <model name='phenom'>
+ <model name='cpu64-rhel5'/>
<vendor name='AMD'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
+ <feature name='monitor'/>
+ <feature name='mmxext'/>
+ <feature name='fxsr_opt'/>
+ <feature name='3dnowext'/>
+ <feature name='3dnow'/>
+ <feature name='svm'/>
+ </model>
+
+ <model name='Opteron_G1'>
+ <model name='cpu64-rhel5'/>
+ <vendor name='AMD'/>
+ </model>
+
+ <model name='Opteron_G2'>
+ <model name='Opteron_G1'/>
<feature name='cx16'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
<feature name='rdtscp'/>
- <feature name='svm'/>
<feature name='lahf_lm'/>
+ <feature name='svm'/>
</model>
<model name='Opteron_G3'>
- <vendor name='AMD'/>
- <feature name='sse2'/>
- <feature name='sse'/>
- <feature name='fxsr'/>
- <feature name='mmx'/>
- <feature name='pat'/>
- <feature name='cmov'/>
- <feature name='pge'/>
- <feature name='sep'/>
- <feature name='apic'/>
- <feature name='cx8'/>
- <feature name='mce'/>
- <feature name='pae'/>
- <feature name='msr'/>
- <feature name='tsc'/>
- <feature name='pse'/>
- <feature name='de'/>
- <feature name='fpu'/>
- <feature name='mtrr'/>
- <feature name='clflush'/>
- <feature name='mca'/>
- <feature name='pse36'/>
- <feature name='pni'/>
- <feature name='cx16'/>
+ <model name='Opteron_G2'/>
<feature name='monitor'/>
<feature name='popcnt'/>
- <feature name='lm'/>
- <feature name='syscall'/>
- <feature name='nx'/>
- <feature name='rdtscp'/>
- <feature name='svm'/>
- <feature name='sse4a'/>
<feature name='abm'/>
+ <feature name='sse4a'/>
<feature name='misalignsse'/>
- <feature name='lahf_lm'/>
</model>
<model name='Opteron_G4'>
- <vendor name='AMD'/>
- <feature name='fpu'/>
- <feature name='de'/>
- <feature name='pse'/>
- <feature name='tsc'/>
- <feature name='msr'/>
- <feature name='pae'/>
- <feature name='mce'/>
- <feature name='cx8'/>
- <feature name='apic'/>
- <feature name='sep'/>
- <feature name='mtrr'/>
- <feature name='pge'/>
- <feature name='mca'/>
- <feature name='cmov'/>
- <feature name='pat'/>
- <feature name='pse36'/>
- <feature name='clflush'/>
- <feature name='mmx'/>
- <feature name='fxsr'/>
- <feature name='sse'/>
- <feature name='sse2'/>
- <feature name='pni'/>
+ <model name='Opteron_G2'/>
+ <!-- Can't inherit from G3 because of missing "monitor"
+ feature -->
<feature name='pclmuldq'/>
<feature name='ssse3'/>
- <feature name='cx16'/>
<feature name='sse4.1'/>
<feature name='sse4.2'/>
<feature name='popcnt'/>
<feature name='aes'/>
<feature name='xsave'/>
<feature name='avx'/>
- <feature name='syscall'/>
- <feature name='nx'/>
<feature name='pdpe1gb'/>
- <feature name='rdtscp'/>
- <feature name='lm'/>
- <feature name='lahf_lm'/>
- <feature name='svm'/>
<feature name='abm'/>
<feature name='sse4a'/>
<feature name='misalignsse'/>
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH] snapshot: make quiesce a bit safer
by Eric Blake
If a guest is paused, we were silently ignoring the quiesce flag,
which results in unclean snapshots, contrary to the intent of the
flag. Since we can't quiesce without guest agent support, we should
instead fail if the guest is not running.
Meanwhile, if we attempt a quiesce command, but the guest agent
doesn't respond, and we time out, we may have left the command
pending on the guest's queue, and when the guest resumes parsing
commands, it will freeze even though our command is no longer
around to issue a thaw. To be safe, we must _always_ pair every
quiesce call with a counterpart thaw, even if the quiesce call
failed due to a timeout, so that if a guest wakes up and starts
processing a command backlog, it will not get stuck in a frozen
state.
* src/qemu/qemu_driver.c (qemuDomainSnapshotCreateDiskActive):
Always issue thaw after a quiesce, even if quiesce failed.
(qemuDomainSnapshotFSThaw): Add a parameter.
---
See also: https://bugzilla.redhat.com/show_bug.cgi?id=804210
https://www.redhat.com/archives/libvir-list/2012-March/msg00708.html
src/qemu/qemu_driver.c | 51 +++++++++++++++++++++++++++++++++--------------
1 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2c467ab..13ca92f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9584,24 +9584,36 @@ qemuDomainSnapshotFSFreeze(struct qemud_driver *driver,
static int
qemuDomainSnapshotFSThaw(struct qemud_driver *driver,
- virDomainObjPtr vm) {
+ virDomainObjPtr vm, bool report)
+{
qemuDomainObjPrivatePtr priv = vm->privateData;
int thawed;
+ virErrorPtr err = NULL;
if (priv->agentError) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("QEMU guest agent is not "
- "available due to an error"));
+ if (report)
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("QEMU guest agent is not "
+ "available due to an error"));
return -1;
}
if (!priv->agent) {
- qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("QEMU guest agent is not configured"));
+ if (report)
+ qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("QEMU guest agent is not configured"));
return -1;
}
qemuDomainObjEnterAgent(driver, vm);
+ if (!report)
+ err = virGetLastError();
thawed = qemuAgentFSThaw(priv->agent);
+ if (!report) {
+ if (err)
+ virResetError(err);
+ else
+ virResetLastError();
+ }
qemuDomainObjExitAgent(driver, vm);
return thawed;
@@ -9907,6 +9919,7 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
int ret = -1;
int i;
bool persist = false;
+ int thaw = 0; /* 1 if freeze succeeded, -1 if freeze failed */
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
return -1;
@@ -9917,14 +9930,21 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
goto endjob;
}
-
- if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
- if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
- (qemuDomainSnapshotFSFreeze(driver, vm) < 0)) {
+ /* If quiesce was requested, then issue a freeze command, and a
+ * counterpart thaw command, no matter what. The command will
+ * fail if the guest is paused or the guest agent is not
+ * running. */
+ if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) {
+ if (qemuDomainSnapshotFSFreeze(driver, vm) < 0) {
/* helper reported the error */
+ thaw = -1;
goto endjob;
+ } else {
+ thaw = 1;
}
+ }
+ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
/* In qemu, snapshot_blkdev on a single disk will pause cpus,
* but this confuses libvirt since notifications are not given
* when qemu resumes. And for multiple disks, libvirt must
@@ -10001,11 +10021,6 @@ cleanup:
_("resuming after snapshot failed"));
goto endjob;
}
-
- if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
- qemuDomainSnapshotFSThaw(driver, vm) < 0) {
- /* helper reported the error */
- }
}
if (vm) {
@@ -10016,6 +10031,12 @@ cleanup:
}
endjob:
+ if (vm && thaw != 0 &&
+ qemuDomainSnapshotFSThaw(driver, vm, thaw > 0) < 0) {
+ /* helper reported the error, if it was needed */
+ if (thaw > 0)
+ ret = -1;
+ }
if (vm && (qemuDomainObjEndJob(driver, vm) == 0)) {
/* Only possible if a transient vm quit while our locks were down,
* in which case we don't want to save snapshot metadata. */
--
1.7.7.6
12 years, 9 months
[libvirt] [PATCHv3] python: Avoid memory leaks on libvirt_virNodeGetMemoryStats
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Detected by valgrind. Leaks are introduced in commit 17c7795.
* python/libvirt-override.c (libvirt_virNodeGetMemoryStats): fix memory leaks
and improve codes return value.
For details, please see the following link:
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=770944
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
python/libvirt-override.c | 46 ++++++++++++++++++++++++++++++--------------
1 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 792cfa3..fb98627 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -2550,7 +2550,9 @@ libvirt_virNodeGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
static PyObject *
libvirt_virNodeGetMemoryStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
{
- PyObject *ret;
+ PyObject *ret = NULL;
+ PyObject *key = NULL;
+ PyObject *val = NULL;
PyObject *pyobj_conn;
virConnectPtr conn;
unsigned int flags;
@@ -2559,39 +2561,53 @@ libvirt_virNodeGetMemoryStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
virNodeMemoryStatsPtr stats = NULL;
if (!PyArg_ParseTuple(args, (char *)"Oii:virNodeGetMemoryStats", &pyobj_conn, &cellNum, &flags))
- return(NULL);
+ return ret;
conn = (virConnectPtr)(PyvirConnect_Get(pyobj_conn));
LIBVIRT_BEGIN_ALLOW_THREADS;
c_retval = virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, flags);
LIBVIRT_END_ALLOW_THREADS;
if (c_retval < 0)
- return VIR_PY_NONE;
+ return ret;
if (nparams) {
if (VIR_ALLOC_N(stats, nparams) < 0)
- return VIR_PY_NONE;
+ return PyErr_NoMemory();
LIBVIRT_BEGIN_ALLOW_THREADS;
c_retval = virNodeGetMemoryStats(conn, cellNum, stats, &nparams, flags);
LIBVIRT_END_ALLOW_THREADS;
- if (c_retval < 0) {
- VIR_FREE(stats);
- return VIR_PY_NONE;
- }
- }
- if (!(ret = PyDict_New())) {
- VIR_FREE(stats);
- return VIR_PY_NONE;
+ if (c_retval < 0)
+ goto error;
}
+
+ if (!(ret = PyDict_New()))
+ goto error;
+
for (i = 0; i < nparams; i++) {
- PyDict_SetItem(ret,
- libvirt_constcharPtrWrap(stats[i].field),
- libvirt_ulonglongWrap(stats[i].value));
+ key = libvirt_constcharPtrWrap(stats[i].field);
+ val = libvirt_ulonglongWrap(stats[i].value);
+
+ if (!key || !val)
+ goto error;
+
+ if (PyDict_SetItem(ret, key, val) < 0) {
+ Py_DECREF(ret);
+ goto error;
+ }
+
+ Py_DECREF(key);
+ Py_DECREF(val);
}
VIR_FREE(stats);
return ret;
+
+error:
+ VIR_FREE(stats);
+ Py_XDECREF(key);
+ Py_XDECREF(val);
+ return ret;
}
static PyObject *
--
1.7.1
12 years, 9 months
[libvirt] [PATCH] Fixed NULL pointer check
by Martin Kletzander
This patch fixes a NULL pointer check that was causing SegFault on
some specific configurations.
---
src/util/conf.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/util/conf.c b/src/util/conf.c
index 8ad60e0..e76362c 100644
--- a/src/util/conf.c
+++ b/src/util/conf.c
@@ -1,7 +1,7 @@
/**
* conf.c: parser for a subset of the Python encoded Xen configuration files
*
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
*
* See COPYING.LIB for the License of this software
*
@@ -836,6 +836,9 @@ virConfGetValue(virConfPtr conf, const char *setting)
{
virConfEntryPtr cur;
+ if (conf == NULL)
+ return(NULL);
+
cur = conf->entries;
while (cur != NULL) {
if ((cur->name != NULL) &&
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH v3] Fixed NULL pointer check
by Martin Kletzander
This patch fixes a NULL pointer check that was causing SegFault on
some specific configurations. It also reverts commit 59d0c9801c1ab
that was checking for this value in one place.
---
v3:
- added revert of 59d0c9801c1ab that's not needed anymore
- (comment) ATTRIBUTE_RETURN_CHECK not added as it is not used with other
functions defined in this file and the commit could be confusing modifying
all of them together. However, there should be one patch to fix all these
at once if possible
v2:
- removed parenthesis around return value
src/libvirt.c | 3 +--
src/util/conf.c | 5 ++++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 7f8d42c..99b263e 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1085,8 +1085,7 @@ virConnectOpenResolveURIAlias(virConfPtr conf,
*uri = NULL;
- if (conf &&
- (value = virConfGetValue(conf, "uri_aliases")))
+ if ((value = virConfGetValue(conf, "uri_aliases")))
ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
else
ret = 0;
diff --git a/src/util/conf.c b/src/util/conf.c
index 8ad60e0..3370337 100644
--- a/src/util/conf.c
+++ b/src/util/conf.c
@@ -1,7 +1,7 @@
/**
* conf.c: parser for a subset of the Python encoded Xen configuration files
*
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
*
* See COPYING.LIB for the License of this software
*
@@ -836,6 +836,9 @@ virConfGetValue(virConfPtr conf, const char *setting)
{
virConfEntryPtr cur;
+ if (conf == NULL)
+ return NULL;
+
cur = conf->entries;
while (cur != NULL) {
if ((cur->name != NULL) &&
--
1.7.3.4
12 years, 9 months
[libvirt] heisenbug in command.c
by Serge Hallyn
Hi,
It seems I've run into quite the heisenbug, reported at
https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/922628
It manifests itself as virPidWait returning status=4 for iptables (which
should never exit with status=4). But it's only been seen on two (very
different) machines, and the slightest shifting of the winds makes it go
away. Given how sneaky this bug appears to be, there's a slight
temptation to have iptablesAddRemoveRule pass in a int* for status and
better deal with the -EINTR. But I fear that might be papering over a
worse race.
Does anyone have any ideas on this? Has anyone else ever seen this?
-serge
12 years, 9 months
[libvirt] [PATCH v2] Fixed NULL pointer check
by Martin Kletzander
This patch fixes a NULL pointer check that was causing SegFault on
some specific configurations.
---
src/util/conf.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/util/conf.c b/src/util/conf.c
index 8ad60e0..3370337 100644
--- a/src/util/conf.c
+++ b/src/util/conf.c
@@ -1,7 +1,7 @@
/**
* conf.c: parser for a subset of the Python encoded Xen configuration files
*
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
*
* See COPYING.LIB for the License of this software
*
@@ -836,6 +836,9 @@ virConfGetValue(virConfPtr conf, const char *setting)
{
virConfEntryPtr cur;
+ if (conf == NULL)
+ return NULL;
+
cur = conf->entries;
while (cur != NULL) {
if ((cur->name != NULL) &&
--
1.7.3.4
12 years, 9 months