[libvirt] [PATCH] util: Fix return value for virJSONValueFromString if it fails
by Osier Yang
Problem:
"parser.head" is not NULL even if it's free'ed by "virJSONValueFree",
returning "parser.head" when "virJSONValueFromString" fails will cause
unexpected errors (libvirtd will crash sometimes), e.g.
In function "qemuMonitorJSONArbitraryCommand":
if (!(cmd = virJSONValueFromString(cmd_str)))
goto cleanup;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
goto cleanup;
......
cleanup:
virJSONValueFree(cmd);
It will continues to send command to monitor even if "virJSONValueFromString"
is failed, and more worse, it trys to free "cmd" again.
Crash example:
{"error":{"class":"QMPBadInputObject","desc":"Expected 'execute' in QMP input","data":{"expected":"execute"}}}
{"error":{"class":"QMPBadInputObject","desc":"Expected 'execute' in QMP input","data":{"expected":"execute"}}}
error: server closed connection:
error: unable to connect to '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: Connection refused
error: failed to connect to the hypervisor
This fix is to:
1) return NULL for failure of "virJSONValueFromString",
2) and it seems "virJSONValueFree" uses incorrect loop index for type
of "VIR_JSON_TYPE_OBJECT", fix it together.
* src/util/json.c
---
src/util/json.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/util/json.c b/src/util/json.c
index f90594c..be47f64 100644
--- a/src/util/json.c
+++ b/src/util/json.c
@@ -65,7 +65,7 @@ void virJSONValueFree(virJSONValuePtr value)
switch (value->type) {
case VIR_JSON_TYPE_OBJECT:
- for (i = 0 ; i < value->data.array.nvalues ; i++) {
+ for (i = 0 ; i < value->data.object.npairs; i++) {
VIR_FREE(value->data.object.pairs[i].key);
virJSONValueFree(value->data.object.pairs[i].value);
}
@@ -897,6 +897,7 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring)
yajl_parser_config cfg = { 1, 1 };
yajl_handle hand;
virJSONParser parser = { NULL, NULL, 0 };
+ virJSONValuePtr ret = NULL;
VIR_DEBUG("string=%s", jsonstring);
@@ -917,6 +918,8 @@ virJSONValuePtr virJSONValueFromString(const char *jsonstring)
goto cleanup;
}
+ ret = parser.head;
+
cleanup:
yajl_free(hand);
@@ -930,7 +933,7 @@ cleanup:
VIR_DEBUG("result=%p", parser.head);
- return parser.head;
+ return ret;
}
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] Initialization error of qemuCgroupData in Qemu host usb hotplug
by Wen Congyang
Steps to reproduce this bug:
# cat usb.xml
<hostdev mode='subsystem' type='usb'>
<source>
<address bus='0x001' device='0x003'/>
</source>
</hostdev>
# virsh attach-device vm1 usb.xml
error: Failed to attach device from usb.xml
error: server closed connection:
The reason of this bug is that we set data.cgroup to NULL, and this will cause
libvirtd crashed.
Signed-off-by: Wen Congyang <wency(a)cn.fujitsu.com>
---
src/qemu/qemu_hotplug.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 36b343d..9082515 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -860,7 +860,7 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver,
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
virCgroupPtr cgroup = NULL;
usbDevice *usb;
- qemuCgroupData data = { vm, cgroup };
+ qemuCgroupData data;
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) !=0 ) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -873,6 +873,8 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver,
hostdev->source.subsys.u.usb.device)) == NULL)
goto error;
+ data.vm = vm;
+ data.cgroup = cgroup;
if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, &data) < 0)
goto error;
}
--
1.7.1
13 years, 8 months
[libvirt] [PATCH 0/2] improve driver module building
by Eric Blake
This comment:
https://www.redhat.com/archives/libvir-list/2011-March/msg00899.html
> > No change to src/libvirt_private.syms to list all these new functions?
> Nothing required this (yet)
made me double check behavior of ./autogen.sh --with-driver-modules,
and sure enough, things were broken.
Patch 1 fixes the breakage, and patch 2 tries to improve automation
to make it easier to prevent (or detect sooner) in the future.
Eric Blake (2):
build: fix driver module build
build: let autobuild check module build
autobuild.sh | 10 ++++++++++
src/Makefile.am | 9 +++++++--
src/libvirt_private.syms | 20 ++++++++++++++++++++
src/libvirt_xenxs.syms | 22 ++++++++++++++++++++++
tests/Makefile.am | 30 +++++++++++++++++-------------
5 files changed, 76 insertions(+), 15 deletions(-)
create mode 100644 src/libvirt_xenxs.syms
--
1.7.4
13 years, 8 months
[libvirt] [PATCHv5 1/3] libivrt/qemu - support persistent modification of devices
by KAMEZAWA Hiroyuki
Thank you for review and feedbacks. This is v5 onto the latest git tree.
Any comments are welcome.
==
>From ef85d268a0b553cdb784a1d1916ff8cf171adace Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
Date: Wed, 16 Mar 2011 11:35:41 +0900
Subject: [PATCHv5 1/3] libivrt/qemu - support persistent modification of devices.
Now, qemudDomainAttachDeviceFlags() and qemudDomainDetachDeviceFlags()
doesn't support VIR_DOMAIN_DEVICE_MODIFY_CONFIG. By this, virsh's
at(de)tatch-device --persistent cannot modify qemu config.
(Xen allows it.)
This patch is a base patch for adding support of devices in
step by step manner. Following patches will add some device
support.
Changelog v4->v5:
- fixed error codes at reporting Error.
- fixed unlock code after calling qemuDomainObjBeginJobWithDriver()
- fixed virDomainFindByUUID() to be virDomainFindByName()
- fixed spelling, indent, etc..
- removed unnecessary checks.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
---
src/qemu/qemu_driver.c | 141 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 129 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dac2bf2..dbd5bd3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4130,16 +4130,129 @@ cleanup:
return ret;
}
-static int qemudDomainAttachDeviceFlags(virDomainPtr dom,
+/*
+ * Attach a device given by XML, the change will be persistent
+ * and domain XML definition file is updated.
+ */
+static int qemuDomainAttachDevicePersistent(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr newdev)
+{
+
+ switch(newdev->type) {
+ default:
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Sorry, the device is not supported for now"));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int qemuDomainDetachDevicePersistent(virDomainDefPtr vmdef,
+ virDomainDeviceDefPtr device)
+{
+ switch(device->type) {
+ default:
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Sorry, the device is not supported for now"));
+ return -1;
+ }
+ return 0;
+}
+
+static int qemuDomainModifyDevicePersistent(virDomainPtr dom,
const char *xml,
- unsigned int flags) {
- if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot modify the persistent configuration of a domain"));
+ unsigned int attach, unsigned int flags)
+{
+ struct qemud_driver *driver;
+ virDomainDeviceDefPtr device;
+ virDomainDefPtr vmdef;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ if (!xml) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("internal error"));
return -1;
}
+ /*
+ * When both of MODIFY_CONFIG and MODIFY_LIVE is specified at the same time,
+ * return error for now. We should support this later.
+ */
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Now, cannot modify alive domain and its definition "
+ "at the same time."));
+ return -1;
+ }
+
+ driver = dom->conn->privateData;
+ qemuDriverLock(driver);
+ vm = virDomainFindByName(&driver->domains, dom->name);
+ if (!vm) {
+ qemuReportError(VIR_ERR_NO_DOMAIN, _("no domain with name : '%s'"),
+ dom->name);
+ goto unlock_out;
+ }
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
+ goto unlock_out;
+
+ if (virDomainObjIsActive(vm)) {
+ /*
+ * For now, just allow updating inactive domains. Further development
+ * will allow updating both active domain and its config file at
+ * the same time.
+ */
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Now, it's unsupported to update active domain's definition."));
+ goto endjob;
+ }
+
+ vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
+
+ if (!vmdef)
+ goto endjob;
+
+ device = virDomainDeviceDefParse(driver->caps,
+ vmdef, xml, VIR_DOMAIN_XML_INACTIVE);
+ if (!device)
+ goto endjob;
+
+ if (attach)
+ ret = qemuDomainAttachDevicePersistent(vmdef, device);
+ else
+ ret = qemuDomainDetachDevicePersistent(vmdef, device);
+
+ if (!ret) /* save the result */
+ ret = virDomainSaveConfig(driver->configDir, vmdef);
+
+ virDomainDeviceDefFree(device);
+
+endjob:
+ if (qemuDomainObjEndJob(vm) == 0)
+ vm = NULL;
+unlock_out:
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
+static int qemudDomainAttachDeviceFlags(virDomainPtr dom,
+ const char *xml,
+ unsigned int flags)
+{
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)
+ return qemuDomainModifyDevicePersistent(dom, xml, 1, flags);
+
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)
+ return qemudDomainAttachDevice(dom, xml);
+
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("bad flag: %x only MODIFY_LIVE, MODIFY_CONFIG are supported now"),
+ flags);
- return qemudDomainAttachDevice(dom, xml);
+ return -1;
}
@@ -4354,13 +4467,17 @@ cleanup:
static int qemudDomainDetachDeviceFlags(virDomainPtr dom,
const char *xml,
unsigned int flags) {
- if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot modify the persistent configuration of a domain"));
- return -1;
- }
- return qemudDomainDetachDevice(dom, xml);
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)
+ return qemuDomainModifyDevicePersistent(dom, xml, 0, flags);
+
+ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)
+ return qemudDomainDetachDevice(dom, xml);
+
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("bad flag: %x only MODIFY_LIVE, MODIFY_CONFIG are supported now"),
+ flags);
+ return -1;
}
static int qemudDomainGetAutostart(virDomainPtr dom,
--
1.7.4.1
13 years, 8 months
[libvirt] [PATCH v2 0/3] qemu: fallback to HMP drive_add/drive_del
by Jiri Denemark
Version 2:
- provide nicer errors when human-monitor-command is not available
Hu Tao (1):
qemu: fallback to HMP drive_add/drive_del
Jiri Denemark (2):
qemu: Detect support for HMP passthrough
qemu: Only use HMP passthrough if it is supported
src/qemu/qemu_monitor.c | 22 +++++++++-
src/qemu/qemu_monitor.h | 2 +
src/qemu/qemu_monitor_json.c | 98 ++++++++++++++++++++++++++++++++++--------
src/qemu/qemu_monitor_json.h | 2 +
4 files changed, 104 insertions(+), 20 deletions(-)
--
1.7.4.1
13 years, 8 months
[libvirt] [PATCH] build: fix missing initializer
by Eric Blake
Commit cb4aba9b6 forgot xenapi.
* src/xenapi/xenapi_driver.c (xenapiDriver): Adjust to recent API.
---
Pushing under the build-breaker rule.
src/xenapi/xenapi_driver.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index e2d4dd3..27206a0 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -1868,6 +1868,7 @@ static virDriver xenapiDriver = {
NULL, /* domainGetJobInfo */
NULL, /* domainAbortJob */
NULL, /* domainMigrateSetMaxDowntime */
+ NULL, /* domainMigrateSetMaxSpeed */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
NULL, /* domainManagedSave */
--
1.7.4
13 years, 8 months
[libvirt] [PATCH] 8021Qbh: use preassociate-rr during the migration prepare stage
by Roopa Prabhu
From: Roopa Prabhu <roprabhu(a)cisco.com>
This patch introduces PREASSOCIATE-RR during incoming VM migration on the
destination host. This is similar to the usage of PREASSOCIATE during
migration in 8021qbg libvirt code today. PREASSOCIATE-RR is a VDP operation.
With the latest at IEEE, 8021qbh will need to support VDP operations.
A corresponding enic driver patch to support PREASSOCIATE-RR for 8021qbh
will be posted for net-next-2.6 inclusion soon.
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
Signed-off-by: David Wang <dwang2(a)cisco.com>
Signed-off-by: Christian Benvenuti <benve(a)cisco.com>
---
src/util/macvtap.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 2d3ff87..346eaf6 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -87,6 +87,7 @@ enum virVirtualPortOp {
ASSOCIATE = 0x1,
DISASSOCIATE = 0x2,
PREASSOCIATE = 0x3,
+ PREASSOCIATE_RR = 0x4,
};
@@ -1452,6 +1453,7 @@ doPortProfileOp8021Qbh(const char *ifname,
}
switch (virtPortOp) {
+ case PREASSOCIATE_RR:
case ASSOCIATE:
rc = virGetHostUUID(hostuuid);
if (rc)
@@ -1465,7 +1467,9 @@ doPortProfileOp8021Qbh(const char *ifname,
vm_uuid,
hostuuid,
vf,
- PORT_REQUEST_ASSOCIATE);
+ (virtPortOp == PREASSOCIATE_RR) ?
+ PORT_REQUEST_PREASSOCIATE_RR
+ : PORT_REQUEST_ASSOCIATE);
if (rc == -ETIMEDOUT)
/* Association timed out, disassociate */
doPortProfileOpCommon(nltarget_kernel, NULL, ifindex,
@@ -1553,10 +1557,11 @@ vpAssociatePortProfileId(const char *macvtap_ifname,
break;
case VIR_VIRTUALPORT_8021QBH:
- /* avoid associating twice */
- if (vmOp != VIR_VM_OP_MIGRATE_IN_FINISH)
- rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr,
- virtPort, vmuuid, ASSOCIATE);
+ rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr,
+ virtPort, vmuuid,
+ (vmOp == VIR_VM_OP_MIGRATE_IN_START)
+ ? PREASSOCIATE_RR
+ : ASSOCIATE);
if (vmOp != VIR_VM_OP_MIGRATE_IN_START && !rc)
ifaceUp(linkdev);
break;
13 years, 8 months
[libvirt] [PATCH] Fix uninitialized variable & error reporting in LXC veth setup
by Daniel P. Berrange
THe veth setup in LXC had a couple of flaws, first brInit did
not report any error when it failed. Second vethCreate() did
not correctly initialize the variable containing the return
code, so could report failure even when it succeeded.
* src/lxc/lxc_driver.c: Report error when brInit fails
* src/lxc/veth.c: Fix uninitialized variable
---
src/lxc/lxc_driver.c | 8 ++++++--
src/lxc/veth.c | 17 +++++++++--------
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 79b6879..9b131cc 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1024,9 +1024,13 @@ static int lxcSetupInterfaces(virConnectPtr conn,
int rc = -1, i;
char *bridge = NULL;
brControl *brctl = NULL;
+ int ret;
- if (brInit(&brctl) != 0)
+ if ((ret = brInit(&brctl)) != 0) {
+ virReportSystemError(ret, "%s",
+ _("Unable to initialize bridging"));
return -1;
+ }
for (i = 0 ; i < def->nnets ; i++) {
char *parentVeth;
@@ -1095,7 +1099,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
goto error_exit;
}
- if (0 != (rc = brAddInterface(brctl, bridge, parentVeth))) {
+ if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) {
virReportSystemError(rc,
_("Failed to add %s device to %s"),
parentVeth, bridge);
diff --git a/src/lxc/veth.c b/src/lxc/veth.c
index 0fa76cf..deca26d 100644
--- a/src/lxc/veth.c
+++ b/src/lxc/veth.c
@@ -90,7 +90,7 @@ static int getFreeVethName(char **veth, int startDev)
*/
int vethCreate(char** veth1, char** veth2)
{
- int rc;
+ int rc = -1;
const char *argv[] = {
"ip", "link", "add", NULL, "type", "veth", "peer", "name", NULL, NULL
};
@@ -100,9 +100,8 @@ int vethCreate(char** veth1, char** veth2)
VIR_DEBUG("veth1: %s veth2: %s", NULLSTR(*veth1), NULLSTR(*veth2));
if (*veth1 == NULL) {
- vethDev = getFreeVethName(veth1, vethDev);
- if (vethDev < 0)
- return vethDev;
+ if ((vethDev = getFreeVethName(veth1, vethDev)) < 0)
+ goto cleanup;
VIR_DEBUG("Assigned veth1: %s", *veth1);
veth1_alloc = true;
}
@@ -110,11 +109,10 @@ int vethCreate(char** veth1, char** veth2)
while (*veth2 == NULL || STREQ(*veth1, *veth2)) {
VIR_FREE(*veth2);
- vethDev = getFreeVethName(veth2, vethDev + 1);
- if (vethDev < 0) {
+ if ((vethDev = getFreeVethName(veth2, vethDev + 1)) < 0) {
if (veth1_alloc)
VIR_FREE(*veth1);
- return vethDev;
+ goto cleanup;
}
VIR_DEBUG("Assigned veth2: %s", *veth2);
}
@@ -125,9 +123,12 @@ int vethCreate(char** veth1, char** veth2)
if (veth1_alloc)
VIR_FREE(*veth1);
VIR_FREE(*veth2);
- rc = -1;
+ goto cleanup;
}
+ rc = 0;
+
+cleanup:
return rc;
}
--
1.7.1
13 years, 8 months