[libvirt] [PATCH v2] esx: Support VLAN tags in virtual network port groups
by Matthias Bolte
---
v2:
Utilize tag-less VLAN trunk mode:
https://www.redhat.com/archives/libvir-list/2012-October/msg00214.html
src/esx/esx_network_driver.c | 64 ++++++++++++++++++++++++++++++++++++++---
1 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c
index c8f101a..98e64ee 100644
--- a/src/esx/esx_network_driver.c
+++ b/src/esx/esx_network_driver.c
@@ -45,6 +45,9 @@
*/
verify(MD5_DIGEST_SIZE == VIR_UUID_BUFLEN);
+/* ESX utilizes the VLAN ID of 4095 to mean that this port is in trunk mode */
+#define ESX_VLAN_TRUNK 4095
+
static virDrvOpenStatus
@@ -489,7 +492,37 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
goto cleanup;
}
- hostPortGroupSpec->vlanId->value = 0;
+ if (def->portGroups[i].vlan.trunk) {
+ if (def->portGroups[i].vlan.nTags != 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Trunk mode cannot be limited to a subset of tags"));
+ goto cleanup;
+ }
+
+ hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+ } else if (def->portGroups[i].vlan.nTags == 1) {
+ hostPortGroupSpec->vlanId->value = *def->portGroups[i].vlan.tag;
+ } else if (def->portGroups[i].vlan.nTags > 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can apply one VLAN tag per port group only"));
+ goto cleanup;
+ } else if (def->vlan.trunk) {
+ if (def->vlan.nTags != 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Trunk mode cannot be limited to a subset of tags"));
+ goto cleanup;
+ }
+
+ hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+ } else if (def->vlan.nTags == 1) {
+ hostPortGroupSpec->vlanId->value = *def->vlan.tag;
+ } else if (def->vlan.nTags > 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can apply one VLAN tag per port group only"));
+ goto cleanup;
+ } else {
+ hostPortGroupSpec->vlanId->value = 0;
+ }
if (def->portGroups[i].bandwidth != NULL) {
if (esxBandwidthToShapingPolicy
@@ -519,6 +552,8 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
network = virGetNetwork(conn, hostVirtualSwitch->name, md5);
cleanup:
+ /* FIXME: need to remove virtual switch if adding port groups failed */
+
virNetworkDefFree(def);
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
esxVI_HostPortGroup_Free(&hostPortGroupList);
@@ -695,6 +730,7 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
esxVI_String *hostPortGroupKey = NULL;
esxVI_String *networkName = NULL;
virNetworkDefPtr def;
+ virPortGroupDefPtr portGroup;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
@@ -824,9 +860,12 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
for (networkName = networkNameList; networkName != NULL;
networkName = networkName->_next) {
if (STREQ(networkName->value, hostPortGroup->spec->name)) {
- def->portGroups[def->nPortGroups].name = strdup(networkName->value);
+ portGroup = &def->portGroups[def->nPortGroups];
+ ++def->nPortGroups;
+
+ portGroup->name = strdup(networkName->value);
- if (def->portGroups[def->nPortGroups].name == NULL) {
+ if (portGroup->name == NULL) {
virReportOOMError();
goto cleanup;
}
@@ -834,13 +873,28 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
if (hostPortGroup->spec->policy != NULL) {
if (esxShapingPolicyToBandwidth
(hostPortGroup->spec->policy->shapingPolicy,
- &def->portGroups[def->nPortGroups].bandwidth) < 0) {
+ &portGroup->bandwidth) < 0) {
++def->nPortGroups;
goto cleanup;
}
}
- ++def->nPortGroups;
+ if (hostPortGroup->spec->vlanId->value > 0) {
+ if (hostPortGroup->spec->vlanId->value == ESX_VLAN_TRUNK) {
+ portGroup->vlan.trunk = true;
+ } else {
+ portGroup->vlan.nTags = 1;
+
+ if (VIR_ALLOC_N(portGroup->vlan.tag, 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ *portGroup->vlan.tag =
+ hostPortGroup->spec->vlanId->value;
+ }
+ }
+
break;
}
}
--
1.7.4.1
12 years, 1 month
[libvirt] [PATCH] network: Allow <vlan trunk='yes'/> without explicit <tag> subelements
by Matthias Bolte
Until now at least one <tag> subelement was required for a <vlan> element.
An optional trunk='yes' attribute can be used to indicate trunking of the
given tags.
This is not how VLAN tagging works with ESX. One can either specify a
single VLAN tag per virtual network or enable trunking for all possible
VLAN tags. It is not possible to limit trunking to a subset of tags.
This cannot be represented properly with the current network config format.
This patch removes the requirement for at least on tag per <vlan> element
and adapts all related code to deal with the new situation.
---
docs/formatnetwork.html.in | 8 +++-
docs/schemas/networkcommon.rng | 4 +-
src/conf/domain_conf.c | 6 ++-
src/conf/netdev_vlan_conf.c | 58 ++++++++++++++++++++---------------
src/network/bridge_driver.c | 28 +++++++++++++++++
src/util/virnetdevopenvswitch.c | 9 ++++-
src/util/virnetdevvlan.c | 8 ++++-
tests/networkxml2xmlin/esx-net.xml | 15 +++++++++
tests/networkxml2xmlout/esx-net.xml | 15 +++++++++
tests/networkxml2xmltest.c | 1 +
10 files changed, 118 insertions(+), 34 deletions(-)
create mode 100644 tests/networkxml2xmlin/esx-net.xml
create mode 100644 tests/networkxml2xmlout/esx-net.xml
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 49206dd..5d601e1 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -398,7 +398,7 @@
transparent to the guest, an optional <code><vlan></code>
element can specify one or more vlan tags to apply to the
traffic of all guests using this
- network <span class="since">Since 0.10.0</span>. (openvswitch
+ network <span class="since">since 0.10.0</span>. (openvswitch
and type='hostdev' SR-IOV networks do support transparent vlan
tagging of guest traffic; everything else, including standard
linux bridges and libvirt's own virtual networks, <b>do not</b>
@@ -410,7 +410,11 @@
assumed that the user wants to do VLAN trunking using all the
specified tags. In the case that vlan trunking with a single tag
is desired, the optional attribute <code>trunk='yes'</code> can
- be added to the vlan element.
+ be added to the vlan element. <span class="since">Since 0.10.3</span>
+ <code>trunk='yes'</code> can be set while specifing no
+ <code><vlan></code> elements at all to indicate trunking of all
+ available vlan tags. This is supported by ESX only and is the only
+ trunking mode that ESX supports.
</p>
<p>
<code><vlan></code> elements can also be specified in
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index c7749e7..70cdcbb 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -192,7 +192,7 @@
<value>yes</value>
</attribute>
</optional>
- <oneOrMore>
+ <zeroOrMore>
<element name="tag">
<attribute name="id">
<data type="unsignedInt">
@@ -201,7 +201,7 @@
</attribute>
<empty/>
</element>
- </oneOrMore>
+ </zeroOrMore>
</element>
</define>
</grammar>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 33e1e7f..65a201c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14897,9 +14897,11 @@ virDomainNetGetActualVlan(virDomainNetDefPtr iface)
{
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
iface->data.network.actual &&
- iface->data.network.actual->vlan.nTags > 0)
+ (iface->data.network.actual->vlan.nTags > 0 ||
+ iface->data.network.actual->vlan.trunk))
return &iface->data.network.actual->vlan;
- if (iface->vlan.nTags > 0)
+ if (iface->vlan.nTags > 0 ||
+ iface->vlan.trunk)
return &iface->vlan;
return 0;
}
diff --git a/src/conf/netdev_vlan_conf.c b/src/conf/netdev_vlan_conf.c
index 6a0511a..8f9aa04 100644
--- a/src/conf/netdev_vlan_conf.c
+++ b/src/conf/netdev_vlan_conf.c
@@ -42,33 +42,28 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
if (nTags < 0)
goto error;
- if (nTags == 0) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing tag id - each <vlan> must have "
- "at least one <tag id='n'/> subelement"));
- goto error;
- }
-
- if (VIR_ALLOC_N(def->tag, nTags) < 0) {
- virReportOOMError();
- goto error;
- }
-
- for (ii = 0; ii < nTags; ii++) {
- unsigned long id;
-
- ctxt->node = tagNodes[ii];
- if (virXPathULong("string(./@id)", ctxt, &id) < 0) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing or invalid vlan tag id attribute"));
+ if (nTags > 0) {
+ if (VIR_ALLOC_N(def->tag, nTags) < 0) {
+ virReportOOMError();
goto error;
}
- if (id > 4095) {
- virReportError(VIR_ERR_XML_ERROR,
- _("vlan tag id %lu too large (maximum 4095)"), id);
- goto error;
+
+ for (ii = 0; ii < nTags; ii++) {
+ unsigned long id;
+
+ ctxt->node = tagNodes[ii];
+ if (virXPathULong("string(./@id)", ctxt, &id) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing or invalid vlan tag id attribute"));
+ goto error;
+ }
+ if (id > 4095) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("vlan tag id %lu too large (maximum 4095)"), id);
+ goto error;
+ }
+ def->tag[ii] = id;
}
- def->tag[ii] = id;
}
def->nTags = nTags;
@@ -99,6 +94,14 @@ virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr de
}
}
+ /* only in trunk mode the tag subelements can be omitted */
+ if (!def->trunk && nTags == 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("invalid element - each <vlan> must have at least "
+ "one <tag id='n'/> subelement and/or \"trunk='yes'\""));
+ goto error;
+ }
+
ret = 0;
error:
ctxt->node = save;
@@ -113,8 +116,13 @@ virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf)
{
int ii;
- if (def->nTags == 0)
+ if (def->nTags == 0) {
+ if (def->trunk) {
+ virBufferAddLit(buf, "<vlan trunk='yes'/>\n");
+ }
+
return 0;
+ }
if (!def->tag) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index e1846ee..37ddb07 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2616,6 +2616,14 @@ networkValidate(virNetworkDefPtr def)
int ii;
bool vlanUsed, vlanAllowed;
+ if (def->vlan.nTags == 0 && def->vlan.trunk) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("<vlan> element specified for network %s is missing at "
+ "least one <tag> subelement required for trunk mode"),
+ def->name);
+ return -1;
+ }
+
/* The only type of networks that currently support transparent
* vlan configuration are those using hostdev sr-iov devices from
* a pool, and those using an Open vSwitch bridge.
@@ -2627,6 +2635,13 @@ networkValidate(virNetworkDefPtr def)
vlanUsed = def->vlan.nTags > 0;
for (ii = 0; ii < def->nPortGroups && !(vlanUsed && vlanAllowed); ii++) {
+ if (def->portGroups[ii].vlan.nTags == 0 && def->portGroups[ii].vlan.trunk) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("<vlan> element specified for portgroup %s of network %s "
+ "is missing at least one <tag> subelement required for trunk mode"),
+ def->portGroups[ii].name, def->name);
+ return -1;
+ }
if (def->portGroups[ii].vlan.nTags > 0)
vlanUsed = true;
if (def->forwardType == VIR_NETWORK_FORWARD_BRIDGE &&
@@ -3352,6 +3367,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
/* it's handy to have this initialized if we skip directly to validate */
if (iface->vlan.nTags > 0)
vlan = &iface->vlan;
+ else if (iface->vlan.trunk)
+ goto trunk_error;
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
goto validate;
@@ -3627,10 +3644,16 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
/* copy appropriate vlan info to actualNet */
if (iface->vlan.nTags > 0)
vlan = &iface->vlan;
+ else if (iface->vlan.trunk)
+ goto trunk_error;
else if (portgroup && portgroup->vlan.nTags > 0)
vlan = &portgroup->vlan;
+ else if (portgroup && portgroup->vlan.trunk)
+ goto trunk_error;
else if (netdef && netdef->vlan.nTags > 0)
vlan = &netdef->vlan;
+ else if (netdef && netdef->vlan.trunk)
+ goto trunk_error;
if (virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
goto error;
@@ -3699,6 +3722,11 @@ error:
iface->data.network.actual = NULL;
}
goto cleanup;
+
+trunk_error:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vlan trunk mode without a tag is not supported"));
+ goto cleanup;
}
/* networkNotifyActualDevice:
diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index a6993b6..3b29dcc 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -80,14 +80,19 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname,
goto out_of_memory;
}
- if (virtVlan && virtVlan->nTags > 0) {
+ if (virtVlan && (virtVlan->nTags > 0 || virtVlan->trunk)) {
+ if (virtVlan->nTags == 0 && virtVlan->trunk) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vlan trunk mode without a tag is not supported"));
+ goto cleanup;
+ }
/* Trunk port first */
if (virtVlan->trunk) {
virBufferAddLit(&buf, "trunk=");
/*
- * Trunk ports have at least one VLAN. Do the first one
+ * Trunk ports must have at least one VLAN. Do the first one
* outside the "for" loop so we can put a "," at the
* start of the for loop if there are more than one VLANs
* on this trunk port.
diff --git a/src/util/virnetdevvlan.c b/src/util/virnetdevvlan.c
index 7a6ff9b..4cf95dc 100644
--- a/src/util/virnetdevvlan.c
+++ b/src/util/virnetdevvlan.c
@@ -31,6 +31,7 @@
void
virNetDevVlanClear(virNetDevVlanPtr vlan)
{
+ vlan->trunk = false;
VIR_FREE(vlan->tag);
vlan->nTags = 0;
}
@@ -79,9 +80,14 @@ virNetDevVlanEqual(const virNetDevVlanPtr a, const virNetDevVlanPtr b)
int
virNetDevVlanCopy(virNetDevVlanPtr dst, const virNetDevVlanPtr src)
{
- if (!src || src->nTags == 0)
+ if (!src)
return 0;
+ if (src->nTags == 0) {
+ dst->trunk = src->trunk;
+ return 0;
+ }
+
if (VIR_ALLOC_N(dst->tag, src->nTags) < 0) {
virReportOOMError();
return -1;
diff --git a/tests/networkxml2xmlin/esx-net.xml b/tests/networkxml2xmlin/esx-net.xml
new file mode 100644
index 0000000..546c634
--- /dev/null
+++ b/tests/networkxml2xmlin/esx-net.xml
@@ -0,0 +1,15 @@
+<network>
+ <name>vSwitch0</name>
+ <uuid>2f467347-8b4e-8655-e7d6-c4c3fb968009</uuid>
+ <forward dev='vmnic0' mode='bridge'>
+ <interface dev='vmnic0'/>
+ </forward>
+ <portgroup name='Network1'>
+ <vlan trunk='yes'/>
+ </portgroup>
+ <portgroup name='Network2'>
+ <vlan>
+ <tag id='536'/>
+ </vlan>
+ </portgroup>
+</network>
diff --git a/tests/networkxml2xmlout/esx-net.xml b/tests/networkxml2xmlout/esx-net.xml
new file mode 100644
index 0000000..546c634
--- /dev/null
+++ b/tests/networkxml2xmlout/esx-net.xml
@@ -0,0 +1,15 @@
+<network>
+ <name>vSwitch0</name>
+ <uuid>2f467347-8b4e-8655-e7d6-c4c3fb968009</uuid>
+ <forward dev='vmnic0' mode='bridge'>
+ <interface dev='vmnic0'/>
+ </forward>
+ <portgroup name='Network1'>
+ <vlan trunk='yes'/>
+ </portgroup>
+ <portgroup name='Network2'>
+ <vlan>
+ <tag id='536'/>
+ </vlan>
+ </portgroup>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index e57d190..426c541 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -108,6 +108,7 @@ mymain(void)
DO_TEST_FULL("passthrough-pf", VIR_NETWORK_XML_INACTIVE);
DO_TEST("hostdev");
DO_TEST_FULL("hostdev-pf", VIR_NETWORK_XML_INACTIVE);
+ DO_TEST("esx-net");
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.4.1
12 years, 1 month
[libvirt] [with libvirt-git] creating an f17 guest fails with -- Bus 'pci.0' not found
by Kashyap Chamarthy
Heya,
So, creating a guest w/ virt-install fails w/ latest libvirt
This is what I see in the guest logs:
qemu-kvm: -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2: Bus 'pci.0' not found
2012-10-07 11:24:49.145+0000: shutting down
This is clearly reproducible with latest git on Fedora-18. And I was able to create guest
just fine w/ 'libvirt-daemon-kvm-0.10.2-3')
----------------------------------------
$ rpm -q qemu-kvm libvirt-daemon-kvm python-virtinst
qemu-kvm-1.2.0-11.fc18.x86_64
libvirt-daemon-kvm-0.10.2-4.fc18.x86_64
python-virtinst-0.600.3-1.fc18.1.noarch
----------------------------------------
(NOTE: The above libvirt is built from git, on OCT-06-2012, hence you see a bump in the
'release' number there)
That's what the log in /var/log/libvirt/qemu/f17-jeos4.log says
----------------------------------------------------
2012-10-07 11:24:48.764+0000: starting up
LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin /usr/bin/qemu-kvm -name
f17jeos-4 -S -M isapc -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -uuid
32036aaf-f0c0-2922-056f-64986f63783e -nographic -no-user-config -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/f17jeos-4.monitor,server,nowait -mon
chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-reboot -no-shutdown -kernel
/var/lib/libvirt/boot/virtinst-vmlinuz.bfAHEc -initrd
/var/lib/libvirt/boot/virtinst-initrd.img.QEwMoX -append
method=http://download.eng.pnq.redhat.com/pub/fedora/linux/releases/17/Fe...
ks=file:/fed.ks console=tty0 console=ttyS0,115200 serial rd_NO_PLYMOUTH -device
piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
file=/export/vmimgs2/f17jeos-4.qcow2,if=none,id=drive-virtio-disk0,format=qcow2,cache=none
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-netdev tap,fd=27,id=hostnet0,vhost=on,vhostfd=28 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:48:3c:ac,bus=pci.0,addr=0x3 -chardev
pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device
usb-tablet,id=input0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
char device redirected to /dev/pts/11
qemu-kvm: -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2: Bus 'pci.0' not found
2012-10-07 11:24:49.145+0000: shutting down
[kashyap@moon virt-scripts]$
----------------------------------------------------
On virt-install stdout:
----------------------------------------------------
.
.
.
Retrieving file vmlinuz...
| 8.9 MB 00:00:00 !!!
Retrieving file initrd.img...
| 46 MB 00:00:02 !!!
ERROR Unable to read from monitor: Connection reset by peer
Domain installation does not appear to have been successful.
----------------------------------------------------
This was the script I used creat guest --
http://kashyapc.fedorapeople.org/virt/jeos-guest-create.bash
Any hints?
--
/kashyap
12 years, 1 month
[libvirt] Two core dumps are generated in multi-thread scenarios
by Benjamin Wang (gendwang)
Hi,
I found two core dumps generated in multi-thread scenarios in ESX part.
Case1: libcurl support multi-thread
core dump:
#12 0x00002aaabea89712 in addbyter () from /usr/local/lib/libcurl.so.4
#13 0x00002aaabea89b86 in dprintf_formatf () from /usr/local/lib/libcurl.so.4
#14 0x00002aaabea8b055 in curl_mvsnprintf () from /usr/local/lib/libcurl.so.4
#15 0x00002aaabea7678f in Curl_failf () from /usr/local/lib/libcurl.so.4
#16 0x00002aaabea6d871 in Curl_resolv_timeout () from /usr/local/lib/libcurl.so.4
#17 0x00000006e8a8f230 in ?? ()
Fix code:
esxVI_CURL_Connect() in esx_vi.c:
I add a new line as following:
curl_easy_setopt(curl->handle, CURLOPT_NOSIGNAL, 1);
Case2: libssl support multi-thread
core dump:
#0 0x0000003f9b030265 in raise () from /lib64/libc.so.6
#1 0x0000003f9b031d10 in abort () from /lib64/libc.so.6
#2 0x0000003f9b06a84b in __libc_message () from /lib64/libc.so.6
#3 0x0000003f9b072fae in _int_malloc () from /lib64/libc.so.6
#4 0x0000003f9b074cde in malloc () from /lib64/libc.so.6
#5 0x0000003f9b07963b in strerror () from /lib64/libc.so.6
#6 0x0000003fa188032a in ERR_load_ERR_strings () from /lib64/libcrypto.so.6
#7 0x0000003fa187fde9 in ERR_load_crypto_strings () from /lib64/libcrypto.so.6
#8 0x0000003fa48309d9 in SSL_load_error_strings () from /lib64/libssl.so.6
#9 0x00002aaaba8e612e in Curl_ossl_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#10 0x00002aaaba8ee6c1 in curl_global_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#11 0x00002aaaba8ee6f8 in curl_easy_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#12 0x00002aaaba0d932b in esxVI_RegisterVM_Task (ctx=0x2aaaba0d96d1, _this=0x5cf54b20, path=0x50e921c0 "10.74.125.50", name=0x2aaac0ae6e80 "root", asTemplate=3228119712, pool=0x5cf54b20, host=0x2aaac0693270, output=0x50e921a0)
at esx/esx_vi_methods.generated.c:480
Possible Problem:
Two callback functions(locking_function and threadid_func) need to be set.
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
Would you help to give some comments about this two core dump?
B.R.
Benjamin Wang
12 years, 1 month
[libvirt] [PATCH] esx: Disable libcurl's use of signals to fix a segfault
by Matthias Bolte
libcurl uses a SIGALRM in combination with sigsetjmp/siglongjmp to be
able to abort a DNS lookup when it takes too long. The problem with this
in a multi-threaded application is that the signal handler for SIGALRM
and the call to siglongjmp can be executed on a thread that is different
from the one that initially did the SIGALRM setup and the call to
sigsetjmp. In the reported case this triggered a segfault.
Disable libcurl's use of signals to avoid this situation. This has the
disadvantage of losing the ability to abort DNS lookups which might result
in libcurl getting stuck in a DNS lookup in the worst case.
Reported by Benjamin Wang.
---
src/esx/esx_vi.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 275b858..125eaee 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -330,6 +330,7 @@ esxVI_CURL_Connect(esxVI_CURL *curl, esxUtil_ParsedUri *parsedUri)
}
curl_easy_setopt(curl->handle, CURLOPT_USERAGENT, "libvirt-esx");
+ curl_easy_setopt(curl->handle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl->handle, CURLOPT_HEADER, 0);
curl_easy_setopt(curl->handle, CURLOPT_FOLLOWLOCATION, 0);
curl_easy_setopt(curl->handle, CURLOPT_SSL_VERIFYPEER,
--
1.7.4.1
12 years, 1 month
[libvirt] [with libvirt/qemu git] invoking 'qemu-system-x86_64' fails w/: -netdev bridge, br=virbr0, id=hostnet0 Device 'bridge' could not be initialized"
by Kashyap Chamarthy
Hi,
I'm on latest master, w/ Eric's block-commit patches applied
===========================================================
[kashyap@moon libvirt-k]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)
[kashyap@moon libvirt-k]$
===========================================================
[kashyap@moon libvirt-k]$ # ./autogen.sh ; make -j5 ; make check
===========================================================
Now, then define an xml [see complete xml at the bottom]
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ ./run ./tools/virsh define /var/tmp/f17-base.xml
Domain f17-base defined from /var/tmp/f17-base.xml
#-----------------------------------------------------------#
Try to start the guest now:
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ ./run ./tools/virsh start f17-base
error: Failed to start domain f17-base
error: internal error Process exited while reading console log output: char device
redirected to /dev/pts/6
failed to launch bridge helper
qemu-system-x86_64: -netdev bridge,br=virbr0,id=hostnet0: Device 'bridge' could not be
initialized
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
The emulator is pointed to latest qemu-system-x86_64 compiled from latest qemu-git
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ egrep -i 'emulator|bridge' /var/tmp/f17-base.xml
<emulator>/home/kashyap/projects/qemu/x86_64-softmmu/qemu-system-x86_64</emulator>
<interface type='bridge'>
<source bridge='virbr0'/>
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.00215e6fb9f4 no eth0
virbr0 8000.525400573710 yes virbr0-nic
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ ./run ./tools/virsh version
Compiled against library: libvirt 0.10.2
Using library: libvirt 0.10.2
Using API: QEMU 0.10.2
Cannot extract running QEMU hypervisor version
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ ps -ef | grep libvirtd
kashyap 2277 1 2 17:07 ? 00:00:00
/home/kashyap/projects/libvirt-k/daemon/.libs/lt-libvirtd --timeout=30
kashyap 2392 11303 0 17:07 pts/15 00:00:00 grep --color=auto libvirtd
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
That's what I see in the local log file:
#-----------------------------------------------------------#
[kashyap@moon libvirt-k]$ cat ~/.cache/libvirt/qemu/log/f17-base.log
2012-10-06 11:37:41.155+0000: starting up
LC_ALL=C LD_LIBRARY_PATH=/home/kashyap/projects/libvirt-k/src/.libs
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/kashyap/.local/bin:/home/kashyap/bin:/home/kashyap/.local/bin:/home/kashyap/bin
HOME=/home/kashyap USER=kashyap LOGNAME=kashyap
/home/kashyap/projects/qemu/x86_64-softmmu/qemu-system-x86_64 -name f17-base -S -M pc-1.2
-enable-kvm -m 2048 -smp 2,sockets=2,cores=1,threads=1 -uuid
8d54ced1-2662-bcae-0804-d4a3e65e9ff6 -nographic -no-user-config -nodefaults -chardev
socket,id=charmonitor,path=/home/kashyap/.config/libvirt/qemu/lib/f17-base.monitor,server,nowait
-mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device
piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
file=/var/lib/libvirt/images/f17-base.qcow2,if=none,id=drive-virtio-disk0,format=qcow2,cache=none
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-netdev bridge,br=virbr0,id=hostnet0 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:51:00:a9:f1:7f,bus=pci.0,addr=0x3 -chardev
pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device
usb-tablet,id=input0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
char device redirected to /dev/pts/6
failed to launch bridge helper
qemu-system-x86_64: -netdev bridge,br=virbr0,id=hostnet0: Device 'bridge' could not be
initialized
2012-10-06 11:37:41.281+0000: shutting down
[kashyap@moon libvirt-k]$
#-----------------------------------------------------------#
And that's the xml file:
#-----------------------------------------------------------#
<domain type='kvm'>
<name>f17-base</name>
<uuid>8d54ced1-2662-bcae-0804-d4a3e65e9ff6</uuid>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-1.2'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/home/kashyap/projects/qemu/x86_64-softmmu/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source file='/var/lib/libvirt/images/f17-base.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<interface type='bridge'>
<mac address='52:51:00:a9:f1:7f'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='tablet' bus='usb'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</memballoon>
</devices>
</domain>
#-----------------------------------------------------------#
Other notes: Rich Jones suggested me to do a build dep for qemu & re-try
[kashyap@moon qemu]$ yum-builddep qemu
[kashyap@moon qemu]$ ./configure --target-list=x86_64-softmmu --disable-werror ; make -j5
and re-configure qemu.
And still no dice, I see the same 'bridge' could not be initialized
Any hints here?
--
/kashyap
12 years, 1 month
[libvirt] [PATCHv5] interface: add udev based backend for virInterface
by Doug Goldstein
Add a read-only udev based backend for virInterface. Useful for distros
that do not have netcf support yet. Multiple libvirt based utilities use
a HAL based fallback when virInterface is not available which is less
than ideal. This implements:
* virConnectNumOfInterfaces()
* virConnectListInterfaces()
* virConnectNumOfDefinedInterfaces()
* virConnectListDefinedInterfaces()
* virConnectInterfaceLookupByName()
* virConnectInterfaceLookupByMACString()
---
Change from v4:
* Fix up udev reference counting
Change from v3:
* fix make syntax-check issues
* check strdup() and handle that case
* simplify configure check
Change from v2:
* rebase from master
Change from v1:
* rebase from master
configure.ac | 18 +-
po/POTFILES.in | 1 +
src/Makefile.am | 12 +-
src/interface/interface_backend_udev.c | 438 ++++++++++++++++++++++++++++++++
tools/virsh.c | 2 +
5 files changed, 458 insertions(+), 13 deletions(-)
create mode 100644 src/interface/interface_backend_udev.c
diff --git a/configure.ac b/configure.ac
index 13967e9..eee87ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2799,18 +2799,12 @@ if test "$with_libvirtd" = "no" ; then
with_interface=no
fi
-dnl The interface driver depends on the netcf library
-if test "$with_interface:$with_netcf" = "check:yes" ; then
- with_interface=yes
-fi
-
-if test "$with_interface:$with_netcf" = "check:no" ; then
- with_interface=no
-fi
-
-if test "$with_interface:$with_netcf" = "yes:no" ; then
- AC_MSG_ERROR([Requested the Interface driver without netcf support])
-fi
+dnl The interface driver depends on the netcf library or udev library
+case $with_interface:$with_netcf:$with_udev in
+ check:*yes*) with_interface=yes ;;
+ check:no:no) with_interface=no ;;
+ yes:no:no) AC_MSG_ERROR([Requested the Interface driver without netcf or udev support]) ;;
+esac
if test "$with_interface" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_INTERFACE], [1],
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 74d8dcc..2538225 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -41,6 +41,7 @@ src/hyperv/hyperv_driver.c
src/hyperv/hyperv_util.c
src/hyperv/hyperv_wmi.c
src/interface/interface_backend_netcf.c
+src/interface/interface_backend_udev.c
src/internal.h
src/libvirt.c
src/libvirt-qemu.c
diff --git a/src/Makefile.am b/src/Makefile.am
index ae3d491..98448c1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -558,11 +558,16 @@ INTERFACE_DRIVER_SOURCES =
if WITH_INTERFACE
INTERFACE_DRIVER_SOURCES += \
interface/interface_driver.h
-endif
if WITH_NETCF
INTERFACE_DRIVER_SOURCES += \
interface/interface_backend_netcf.c
+else
+if HAVE_UDEV
+INTERFACE_DRIVER_SOURCES += \
+ interface/interface_backend_udev.c
+endif
+endif
endif
SECRET_DRIVER_SOURCES = \
@@ -1045,6 +1050,11 @@ libvirt_driver_interface_la_LIBADD =
if WITH_NETCF
libvirt_driver_interface_la_CFLAGS += $(NETCF_CFLAGS)
libvirt_driver_interface_la_LIBADD += $(NETCF_LIBS)
+else
+if HAVE_UDEV
+libvirt_driver_interface_la_CFLAGS += $(UDEV_CFLAGS)
+libvirt_driver_interface_la_LIBADD += $(UDEV_LIBS)
+endif
endif
if WITH_DRIVER_MODULES
libvirt_driver_interface_la_LIBADD += ../gnulib/lib/libgnu.la
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
new file mode 100644
index 0000000..b6e9f55
--- /dev/null
+++ b/src/interface/interface_backend_udev.c
@@ -0,0 +1,438 @@
+/*
+ * interface_backend_udev.c: udev backend for virInterface
+ *
+ * Copyright (C) 2012 Doug Goldstein <cardoe(a)cardoe.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+#include <config.h>
+
+#include <libudev.h>
+
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "interface_driver.h"
+#include "interface_conf.h"
+#include "memory.h"
+
+#define VIR_FROM_THIS VIR_FROM_INTERFACE
+
+struct udev_iface_driver {
+ struct udev *udev;
+};
+
+enum udev_status { UDEV_IFACE_ACTIVE, UDEV_IFACE_INACTIVE, UDEV_IFACE_ALL };
+
+static struct udev_enumerate *
+udevIfaceGetDevices(struct udev *udev, enum udev_status status)
+{
+ struct udev_enumerate *enumerate;
+
+ /* Check input params for sanity */
+ if (!udev)
+ return NULL;
+
+ /* Create a new enumeration to create a list */
+ enumerate = udev_enumerate_new(udev);
+
+ if (!enumerate)
+ return NULL;
+
+ /* Enumerate all network subsystem devices */
+ udev_enumerate_add_match_subsystem(enumerate, "net");
+
+ /* Ignore devices that are part of a bridge */
+ udev_enumerate_add_nomatch_sysattr(enumerate, "brport/state", NULL);
+
+ /* State of the device */
+ switch (status) {
+ case UDEV_IFACE_ACTIVE:
+ udev_enumerate_add_match_sysattr(enumerate, "operstate", "up");
+ break;
+
+ case UDEV_IFACE_INACTIVE:
+ udev_enumerate_add_match_sysattr(enumerate, "operstate", "down");
+ break;
+
+ case UDEV_IFACE_ALL:
+ break;
+ }
+
+ /* We don't want to see the TUN devices that QEMU creates for other gets
+ * running on this machine. By saying nomatch NULL, we just are getting
+ * devices without the tun_flags sysattr.
+ */
+ udev_enumerate_add_nomatch_sysattr(enumerate, "tun_flags", NULL);
+
+ return enumerate;
+}
+
+static virDrvOpenStatus
+udevIfaceOpenInterface(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ struct udev_iface_driver *driverState = NULL;
+
+ virCheckFlags(0, VIR_DRV_OPEN_ERROR);
+
+ if (VIR_ALLOC(driverState) < 0) {
+ virReportOOMError();
+ goto err;
+ }
+
+ driverState->udev = udev_new();
+ if (!driverState->udev) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to create udev context"));
+ goto err;
+ }
+
+ conn->interfacePrivateData = driverState;
+
+ return VIR_DRV_OPEN_SUCCESS;
+
+err:
+ VIR_FREE(driverState);
+
+ return VIR_DRV_OPEN_ERROR;
+}
+
+static int
+udevIfaceCloseInterface(virConnectPtr conn)
+{
+ struct udev_iface_driver *driverState;
+
+ if (conn->interfacePrivateData != NULL) {
+ driverState = conn->interfacePrivateData;
+
+ udev_unref(driverState->udev);
+
+ VIR_FREE(driverState);
+ }
+
+ conn->interfacePrivateData = NULL;
+ return 0;
+}
+
+static int
+udevIfaceNumOfInterfaces(virConnectPtr conn)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_enumerate *enumerate = NULL;
+ struct udev_list_entry *devices;
+ struct udev_list_entry *dev_entry;
+ int count = 0;
+
+ enumerate = udevIfaceGetDevices(udev, UDEV_IFACE_ACTIVE);
+
+ if (!enumerate) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to get number of active interfaces on host"));
+ count = -1;
+ goto err;
+ }
+
+ /* Do the scan to load up the enumeration */
+ udev_enumerate_scan_devices(enumerate);
+
+ /* Get a list we can walk */
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ /* For each item so we can count */
+ udev_list_entry_foreach(dev_entry, devices) {
+ count++;
+ }
+
+err:
+ if (enumerate)
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return count;
+}
+
+static int
+udevIfaceListInterfaces(virConnectPtr conn, char **const names, int names_len)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_enumerate *enumerate = NULL;
+ struct udev_list_entry *devices;
+ struct udev_list_entry *dev_entry;
+ int count = 0;
+
+ enumerate = udevIfaceGetDevices(udev, UDEV_IFACE_ACTIVE);
+
+ if (!enumerate) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to get list of active interfaces on host"));
+ goto err;
+ }
+
+ /* Do the scan to load up the enumeration */
+ udev_enumerate_scan_devices(enumerate);
+
+ /* Get a list we can walk */
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ /* For each item so we can count */
+ udev_list_entry_foreach(dev_entry, devices) {
+ struct udev_device *dev;
+ const char *path;
+
+ /* Ensure we won't exceed the size of our array */
+ if (count > names_len)
+ break;
+
+ path = udev_list_entry_get_name(dev_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+ names[count] = strdup(udev_device_get_sysname(dev));
+ udev_device_unref(dev);
+
+ /* If strdup() failed, we are out of memory */
+ if (!names[count]) {
+ virReportOOMError();
+ goto err;
+ }
+
+ count++;
+ }
+
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return count;
+
+err:
+ if (enumerate)
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ for (names_len = 0; names_len < count; names_len++)
+ VIR_FREE(names[names_len]);
+
+ return -1;
+}
+
+static int
+udevIfaceNumOfDefinedInterfaces(virConnectPtr conn)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_enumerate *enumerate = NULL;
+ struct udev_list_entry *devices;
+ struct udev_list_entry *dev_entry;
+ int count = 0;
+
+ enumerate = udevIfaceGetDevices(udev, UDEV_IFACE_INACTIVE);
+
+ if (!enumerate) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to get number of defined interfaces on host"));
+ count = -1;
+ goto err;
+ }
+
+ /* Do the scan to load up the enumeration */
+ udev_enumerate_scan_devices(enumerate);
+
+ /* Get a list we can walk */
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ /* For each item so we can count */
+ udev_list_entry_foreach(dev_entry, devices) {
+ count++;
+ }
+
+err:
+ if (enumerate)
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return count;
+}
+
+static int
+udevIfaceListDefinedInterfaces(virConnectPtr conn,
+ char **const names,
+ int names_len)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_enumerate *enumerate = NULL;
+ struct udev_list_entry *devices;
+ struct udev_list_entry *dev_entry;
+ int count = 0;
+
+ enumerate = udevIfaceGetDevices(udev, UDEV_IFACE_INACTIVE);
+
+ if (!enumerate) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to get list of defined interfaces on host"));
+ goto err;
+ }
+
+ /* Do the scan to load up the enumeration */
+ udev_enumerate_scan_devices(enumerate);
+
+ /* Get a list we can walk */
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ /* For each item so we can count */
+ udev_list_entry_foreach(dev_entry, devices) {
+ struct udev_device *dev;
+ const char *path;
+
+ /* Ensure we won't exceed the size of our array */
+ if (count > names_len)
+ break;
+
+ path = udev_list_entry_get_name(dev_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+ names[count] = strdup(udev_device_get_sysname(dev));
+ udev_device_unref(dev);
+
+ /* If strdup() failed, we are out of memory */
+ if (!names[count]) {
+ virReportOOMError();
+ goto err;
+ }
+
+ count++;
+ }
+
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return count;
+
+err:
+ if (enumerate)
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ for (names_len = 0; names_len < count; names_len++)
+ VIR_FREE(names[names_len]);
+
+ return -1;
+}
+
+static virInterfacePtr
+udevIfaceLookupByName(virConnectPtr conn, const char *name)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_device *dev;
+ const char *macaddr;
+ virInterfacePtr ret = NULL;
+
+ /* get a device reference based on the device name */
+ dev = udev_device_new_from_subsystem_sysname(udev, "net", name);
+ if (!dev) {
+ virReportError(VIR_ERR_NO_INTERFACE,
+ _("couldn't find interface named '%s'"),
+ name);
+ goto err;
+ }
+
+ macaddr = udev_device_get_sysattr_value(dev, "address");
+ ret = virGetInterface(conn, name, macaddr);
+ udev_device_unref(dev);
+
+err:
+ udev_unref(udev);
+
+ return ret;
+}
+
+static virInterfacePtr
+udevIfaceLookupByMACString(virConnectPtr conn, const char *macstr)
+{
+ struct udev_iface_driver *driverState = conn->interfacePrivateData;
+ struct udev *udev = udev_ref(driverState->udev);
+ struct udev_enumerate *enumerate = NULL;
+ struct udev_list_entry *dev_entry;
+ struct udev_device *dev;
+ const char *name;
+ virInterfacePtr ret = NULL;
+
+ enumerate = udevIfaceGetDevices(udev, UDEV_IFACE_ALL);
+
+ if (!enumerate) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to lookup interface with MAC address '%s'"),
+ macstr);
+ goto err;
+ }
+
+ /* Match on MAC */
+ udev_enumerate_add_match_sysattr(enumerate, "address", macstr);
+
+ /* Do the scan to load up the enumeration */
+ udev_enumerate_scan_devices(enumerate);
+
+ /* Get a list we can walk */
+ dev_entry = udev_enumerate_get_list_entry(enumerate);
+
+ /* Check that we got something back */
+ if (!dev_entry) {
+ virReportError(VIR_ERR_NO_INTERFACE,
+ _("couldn't find interface with MAC address '%s'"),
+ macstr);
+ goto err;
+ }
+
+ /* Check that we didn't get multiple items back */
+ if (udev_list_entry_get_next(dev_entry)) {
+ virReportError(VIR_ERR_MULTIPLE_INTERFACES,
+ _("the MAC address '%s' matches multiple interfaces"),
+ macstr);
+ goto err;
+ }
+
+ dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(dev_entry));
+ name = udev_device_get_sysname(dev);
+ ret = virGetInterface(conn, name, macstr);
+ udev_device_unref(dev);
+
+err:
+ if (enumerate)
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
+
+ return ret;
+}
+
+static virInterfaceDriver udevIfaceDriver = {
+ "Interface",
+ .open = udevIfaceOpenInterface, /* 0.10.3 */
+ .close = udevIfaceCloseInterface, /* 0.10.3 */
+ .numOfInterfaces = udevIfaceNumOfInterfaces, /* 0.10.3 */
+ .listInterfaces = udevIfaceListInterfaces, /* 0.10.3 */
+ .numOfDefinedInterfaces = udevIfaceNumOfDefinedInterfaces, /* 0.10.3 */
+ .listDefinedInterfaces = udevIfaceListDefinedInterfaces, /* 0.10.3 */
+ .interfaceLookupByName = udevIfaceLookupByName, /* 0.10.3 */
+ .interfaceLookupByMACString = udevIfaceLookupByMACString, /* 0.10.3 */
+};
+
+int
+interfaceRegister(void) {
+ if (virRegisterInterfaceDriver(&udevIfaceDriver) < 0)
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to register udev interface driver"));
+ return 0;
+}
diff --git a/tools/virsh.c b/tools/virsh.c
index b32ee8b..f0ec625 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2708,6 +2708,8 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED)
vshPrint(ctl, " Interface");
# if defined(WITH_NETCF)
vshPrint(ctl, " netcf");
+# elif defined(HAVE_UDEV)
+ vshPrint(ctl, " udev");
# endif
#endif
#ifdef WITH_NWFILTER
--
1.7.8.6
12 years, 1 month
[libvirt] [PATCH 0/n] qemu block-commit support
by Eric Blake
I'm slowly making progress towards having block-commit doing something
useful. First up is online support, using qemu 1.3 block-commit (hmm,
that commit is in Kevin's pull request, but Anthony hasn't yet taken
it into qemu.git proper, and the interface might still have more tweaks
before the actual qemu 1.3 release in December, so this may be a case
of me posting patches but not applying them to libvirt for another
month or two). I'm still trying to test this code, as well as to
write followup patches to allow things to work with SELinux enforcing,
but wanted to at least get this thread started.
Eric Blake (2):
blockjob: manage qemu block-commit monitor command
blockjob: wire up online qemu block-commit
src/qemu/qemu_capabilities.c | 3 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_driver.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 30 +++++++++++++++++
src/qemu/qemu_monitor.h | 7 ++++
src/qemu/qemu_monitor_json.c | 34 +++++++++++++++++++
src/qemu/qemu_monitor_json.h | 7 ++++
7 files changed, 161 insertions(+)
--
1.7.11.4
12 years, 1 month
[libvirt] [PATCH 0/4] command line fd passing using fd sets
by Corey Bryant
This series adds command line file descriptor passing support
to the -drive option. This is a follow-on to the existing
QMP fd passing support provided in the following patch series:
comments.gmane.org/gmane.comp.emulators.qemu/165463
An example of using the new -drive fd and opaque options:
qemu-kvm -drive fd=24,opaque="rdwr:/path/file",index=0,media=disk
When an fd, and optionally opaque, are passed with -drive, they
are added to an automatically generated fd set. The file name
is also generated in the form of "/dev/fdset/nnn", where nnn is
the fd set ID. qemu_open() already knows how to handle a
filename of this format. qemu_open() searches the corresponding
fd set for an fd and when it finds a match, QEMU goes on to use a
dup of that fd just like it would have used an fd that it opened
itself.
Corey Bryant (4):
monitor: Less restrictive fd matching for fd sets
monitor: Enable adding an inherited fd to an fd set
qemu-config: Add -drive fd and opaque options
blockdev: Process -drive fd and opaque options
blockdev.c | 40 +++++++++++++++++-
monitor.c | 128 ++++++++++++++++++++++++++++++++------------------------
monitor.h | 3 ++
qemu-config.c | 8 ++++
qemu-options.hx | 15 ++++++-
5 files changed, 135 insertions(+), 59 deletions(-)
--
1.7.11.4
12 years, 1 month
[libvirt] with latest libvirt(from git) on F18, time to take internal snapshot increases as snapshot count rises
by Kashyap Chamarthy
Hi,
the below three internal snapshots were taken when the guest is running 'live'. Any hints
on why the time to take snapshots keep increasing ?
If you notice, the 2nd and 3rd internal snaphtots took more than 4 minutes each (note:
there is no noticeable content change from snap1 )
#==================================================#
[root@localhost vmimages]# time virsh snapshot-create-as f17vm3-with-b snap1
snap1-f17vm3-desc
Domain snapshot snap1 created
real 0m57.734s
user 0m0.009s
sys 0m0.024s
[root@localhost vmimages]#
[root@localhost vmimages]# virsh snapshot-list f17vm3-with-b
Name Creation Time State
------------------------------------------------------------
snap1 2012-10-04 06:55:38 -0400 running
[root@localhost vmimages]#
#==================================================#
[root@localhost vmimages]# time virsh snapshot-create-as f17vm3-with-b snap2
snap2-f17vm3-desc
Domain snapshot snap2 created
real 4m19.126s
user 0m0.020s
sys 0m0.030s
[root@localhost vmimages]#
#==================================================#
[root@localhost vmimages]# time virsh snapshot-create-as f17vm3-with-b snap3
snap3-f17vm3-desc
Domain snapshot snap3 created
real 4m45.053s
user 0m0.013s
sys 0m0.032s
[root@localhost vmimages]#
#==================================================#
[root@localhost qemu]# qemu-img info /home/kashyap/vmimages/f17vm3-with-b.qcow2
image: /home/kashyap/vmimages/f17vm3-with-b.qcow2
file format: qcow2
virtual size: 5.0G (5368709120 bytes)
disk size: 755M
cluster_size: 65536
backing file: /home/kashyap/vmimages/base-f17.qcow2
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 snap1 232M 2012-10-04 06:55:38 19:58:19.804
2 snap2 247M 2012-10-04 07:03:09 20:04:53.360
3 snap3 244M 2012-10-04 07:08:23 20:05:48.889
4 snap4 0 2012-10-04 08:51:16 00:00:00.000
5 snap5 0 2012-10-04 08:53:04 00:00:00.000
[root@localhost qemu]#
#==================================================#
[root@localhost qemu]# virsh snapshot-list f17vm3-with-b
Name Creation Time State
------------------------------------------------------------
snap1 2012-10-04 06:55:38 -0400 running
snap2 2012-10-04 07:03:08 -0400 running
snap3 2012-10-04 07:08:23 -0400 running
snap4 2012-10-04 08:51:16 -0400 shutoff
snap5 2012-10-04 08:53:04 -0400 shutoff
[root@localhost qemu]#
#==================================================#
--
/kashyap
12 years, 1 month