[libvirt] [PATCH] qemu: Distinguish between domain shutdown and crash
by Jiri Denemark
When we get an EOF event on monitor connection, it may be a result of
either crash or graceful shutdown. QEMU which supports async events
(i.e., we are talking to it using JSON monitor) emits SHUTDOWN event on
graceful shutdown. In case we don't get this event by the time monitor
connection is closed, we assume the associated domain crashed.
---
src/qemu/qemu_driver.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4e65f3b..ab42a6d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -129,6 +129,7 @@ struct _qemuDomainObjPrivate {
virDomainChrDefPtr monConfig;
int monJSON;
int monitor_warned;
+ bool gotShutdown;
int nvcpupids;
int *vcpupids;
@@ -919,11 +920,19 @@ qemuHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
int hasError) {
struct qemud_driver *driver = qemu_driver;
virDomainEventPtr event = NULL;
+ qemuDomainObjPrivatePtr priv;
VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);
virDomainObjLock(vm);
+ priv = vm->privateData;
+ if (!hasError && priv->monJSON && !priv->gotShutdown) {
+ VIR_DEBUG("Monitor connection to '%s' closed without SHUTDOWN event; "
+ "assuming the domain crashed", vm->def->name);
+ hasError = 1;
+ }
+
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
hasError ?
@@ -1120,6 +1129,18 @@ qemuHandleDomainReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
static int
+qemuHandleDomainShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm)
+{
+ virDomainObjLock(vm);
+ ((qemuDomainObjPrivatePtr) vm->privateData)->gotShutdown = true;
+ virDomainObjUnlock(vm);
+
+ return 0;
+}
+
+
+static int
qemuHandleDomainStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
@@ -1382,6 +1403,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.destroy = qemuHandleMonitorDestroy,
.eofNotify = qemuHandleMonitorEOF,
.diskSecretLookup = findVolumeQcowPassphrase,
+ .domainShutdown = qemuHandleDomainShutdown,
.domainStop = qemuHandleDomainStop,
.domainReset = qemuHandleDomainReset,
.domainRTCChange = qemuHandleDomainRTCChange,
@@ -3997,6 +4019,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
priv->monJSON = 0;
priv->monitor_warned = 0;
+ priv->gotShutdown = false;
if ((ret = virFileDeletePid(driver->stateDir, vm->def->name)) != 0) {
virReportSystemError(ret,
--
1.7.3.3
13 years, 11 months
[libvirt] Create VMWare ESXi domain via virsh error(error: this function is not supported by the connection driver: virDomainCreateXML)
by mop amg
Hi, Dear.
I have two questions ask for help:
my virt-manager and libvirt version is :
linux-vaan:~ # rpm -q libvirt
libvirt-0.8.5-1.2.i586
linux-vaan:~ # uname -a
Linux linux-vaan 2.6.34-12-desktop #1 SMP PREEMPT 2010-06-29 02:39:08 +0200
i686 i386 GNU/Linux
linux-vaan:~ # rpm -q virt-manager
virt-manager-0.8.5-3.1.i586
linux-vaan:~ # cat /etc/SuSE-release
openSUSE 11.3 (i586)
VERSION = 11.3
virsh # version
Compiled against library: libvir 0.8.5
Using library: libvir 0.8.5
Using API: ESX 0.8.5
Running hypervisor: ESX 4.1.0
*question 1 : *
When I try to create a vmware esxi domain from virsh like this :
create --file /work/dom1.x
there is a error message :
error: Failed to create domain from /work/dom1.xml
error: this function is not supported by the connection driver:
virDomainCreateXML
it seems dosen't support create esxi domain, but the
http://libvirt.org/hvsupport.html show that is supported after ≥ 0.7.0
or create via virt-install
linux-vaan:~ # virt-install --connect=esx://
root(a)192.168.8.162/?no_verify=1 -n rhel5 -r 512 --vcpus=1 --nodisks
bridge=vmk0 --network bridge=vmk0 --pxe
Enter root's password for 192.168.8.162:
Starting install...
ERROR this function is not supported by the connection driver:
virDomainCreateXML
how to fix it ?
*dom1.xml*
<domain type='vmware'>
<name>dom1</name>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686'>hvm</type>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='file' device='disk'>
<source file='[datastore1] rhel5/rhel5_2.vmdk'/>
<target dev='sda' bus='scsi'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='scsi' index='0' model='lsilogic'/>
<interface type='bridge'>
<mac address='00:0c:29:51:f1:1c'/>
<source bridge='VM Network'/>
</interface>
</devices>
</domain>
*question 2:*
vol-clone failed
virsh # vol-clone --pool datastore1 rhel5/rhel5.vmdk rhel5/rhel5_2.vmdk
error: Failed to clone vol from rhel5/rhel5.vmdk
error: this function is not supported by the connection driver:
virStorageVolCreateXMLFrom
thanks for help!
best regards!
13 years, 11 months
[libvirt] [PATCH] qemu: Set domain def as updated and transient if changes
by Osier Yang
As qemu driver doesn't allow to make changes on persistent
domain configuration via "attach/detach/update device",
and all the changes made on the running domain configuration
should not be persistent across next boot (without the need
of restarting libvirtd), so:
1) Set the running domain def as transient, and restore
the domain configuration to original configuration when
shutdown.
2) Set the running domain def as updated, and reset it as
not updated when shutdown.
Also for "live VCPU set", it doesn't change the persistent
domain configuration, so, we also set the running domain
def as updated and transient, and restore the original def
when shutdown.
* src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags,
qemudDomainAttachDevice, qemuDomainUpdateDeviceFlags,
qemudDomainDetachDevice)
---
src/qemu/qemu_driver.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1b86b5e..7825e2b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4369,11 +4369,18 @@ retry:
VIR_FREE(priv->vcpupids);
priv->nvcpupids = 0;
+ /* Restore original domain def, so that changes on running domain def
+ * will not be persistent across next boot
+ */
if (vm->newDef) {
virDomainDefFree(vm->def);
vm->def = vm->newDef;
vm->def->id = -1;
vm->newDef = NULL;
+
+ /* Now set domain def as not updated */
+ if (vm->updated)
+ vm->updated = 0;
}
if (orig_err) {
@@ -6353,6 +6360,17 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
if (flags & VIR_DOMAIN_VCPU_CONFIG)
ret = virDomainSaveConfig(driver->configDir, persistentDef);
+ if (flags & VIR_DOMAIN_VCPU_LIVE) {
+ /* Set running domain def as updated */
+ if (ret == 0) {
+ vm->updated = 1;
+
+ if (virDomainObjSetDefTransient(driver->caps, vm) < 0)
+ VIR_ERROR("Unable to set domain %s's running config as transient",
+ vm->def->name);
+ }
+ }
+
endjob:
if (qemuDomainObjEndJob(vm) == 0)
vm = NULL;
@@ -8781,6 +8799,15 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
goto endjob;
}
+ /* Set running domain def as updated */
+ if (ret == 0) {
+ vm->updated = 1;
+
+ if (virDomainObjSetDefTransient(driver->caps, vm) < 0)
+ VIR_ERROR("Unable to set domain %s's running config as transient",
+ vm->def->name);
+ }
+
if (!ret && virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
ret = -1;
@@ -8991,6 +9018,15 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
break;
}
+ /* Set running domain def as updated */
+ if (ret == 0) {
+ vm->updated = 1;
+
+ if (virDomainObjSetDefTransient(driver->caps, vm) < 0)
+ VIR_ERROR("Unable to set domain %s's running config as transient",
+ vm->def->name);
+ }
+
if (!ret && virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
ret = -1;
@@ -9665,6 +9701,15 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
"%s", _("This type of device cannot be hot unplugged"));
}
+ /* Set running domain def as updated */
+ if (ret == 0) {
+ vm->updated = 1;
+
+ if (virDomainObjSetDefTransient(driver->caps, vm) < 0)
+ VIR_ERROR("Unable to set domain %s's running config as transient",
+ vm->def->name);
+ }
+
if (!ret && virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
ret = -1;
--
1.7.3.2
13 years, 11 months
[libvirt] [PATCH] qemu: use virAsprintf instead of PATH_MAX
by Eric Blake
* src/qemu/qemu_driver.c (qemudLogFD, qemudLogReadFD)
(qemudStartup, qemudGetProcessInfo)
(qemudDomainDetachPciDiskDevice)
(qemudDomainDetachSCSIDiskDevice): Use heap instead of stack.
---
src/qemu/qemu_driver.c | 72 ++++++++++++++++++++++++------------------------
1 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 75f4563..6739b89 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -744,13 +744,11 @@ static int qemuCgroupControllerActive(struct qemud_driver *driver,
static int
qemudLogFD(struct qemud_driver *driver, const char* name, bool append)
{
- char logfile[PATH_MAX];
+ char *logfile;
mode_t logmode;
- int ret, fd = -1;
+ int fd = -1;
- if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log",
- driver->logDir, name))
- < 0 || ret >= sizeof(logfile)) {
+ if (virAsprintf(&logfile, "%s/%s.log", driver->logDir, name) < 0) {
virReportOOMError();
return -1;
}
@@ -766,8 +764,10 @@ qemudLogFD(struct qemud_driver *driver, const char* name, bool append)
virReportSystemError(errno,
_("failed to create logfile %s"),
logfile);
+ VIR_FREE(logfile);
return -1;
}
+ VIR_FREE(logfile);
if (virSetCloseExec(fd) < 0) {
virReportSystemError(errno, "%s",
_("Unable to set VM logfile close-on-exec flag"));
@@ -781,30 +781,28 @@ qemudLogFD(struct qemud_driver *driver, const char* name, bool append)
static int
qemudLogReadFD(const char* logDir, const char* name, off_t pos)
{
- char logfile[PATH_MAX];
+ char *logfile;
mode_t logmode = O_RDONLY;
- int ret, fd = -1;
+ int fd = -1;
- if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
- < 0 || ret >= sizeof(logfile)) {
+ if (virAsprintf(&logfile, "%s/%s.log", logDir, name) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to build logfile name %s/%s.log"),
logDir, name);
return -1;
}
-
if ((fd = open(logfile, logmode)) < 0) {
virReportSystemError(errno,
_("failed to create logfile %s"),
logfile);
- return -1;
+ goto cleanup;
}
if (virSetCloseExec(fd) < 0) {
virReportSystemError(errno, "%s",
_("Unable to set VM logfile close-on-exec flag"));
VIR_FORCE_CLOSE(fd);
- return -1;
+ goto cleanup;
}
if (pos < 0 || lseek(fd, pos, SEEK_SET) < 0) {
virReportSystemError(pos < 0 ? 0 : errno,
@@ -812,6 +810,9 @@ qemudLogReadFD(const char* logDir, const char* name, off_t pos)
(long long) pos, logfile);
VIR_FORCE_CLOSE(fd);
}
+
+cleanup:
+ VIR_FREE(logfile);
return fd;
}
@@ -1721,7 +1722,7 @@ cleanup:
static int
qemudStartup(int privileged) {
char *base = NULL;
- char driverConf[PATH_MAX];
+ char *driverConf = NULL;
int rc;
virConnectPtr conn = NULL;
@@ -1850,14 +1851,9 @@ qemudStartup(int privileged) {
/* Configuration paths are either ~/.libvirt/qemu/... (session) or
* /etc/libvirt/qemu/... (system).
*/
- if (snprintf (driverConf, sizeof(driverConf), "%s/qemu.conf", base) == -1)
- goto out_of_memory;
- driverConf[sizeof(driverConf)-1] = '\0';
-
- if (virAsprintf(&qemu_driver->configDir, "%s/qemu", base) == -1)
- goto out_of_memory;
-
- if (virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) == -1)
+ if (virAsprintf(&driverConf, "%s/qemu.conf", base) < 0 ||
+ virAsprintf(&qemu_driver->configDir, "%s/qemu", base) < 0 ||
+ virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) < 0)
goto out_of_memory;
VIR_FREE(base);
@@ -1872,6 +1868,7 @@ qemudStartup(int privileged) {
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
+ VIR_FREE(driverConf);
if (qemudSecurityInit(qemu_driver) < 0)
goto error;
@@ -1984,6 +1981,7 @@ error:
if (conn)
virConnectClose(conn);
VIR_FREE(base);
+ VIR_FREE(driverConf);
qemudShutdown();
return -1;
}
@@ -4552,18 +4550,20 @@ cleanup:
}
-static int qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, int pid, int tid) {
- char proc[PATH_MAX];
+static int
+qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, int pid,
+ int tid) {
+ char *proc;
FILE *pidinfo;
unsigned long long usertime, systime;
int cpu;
int ret;
if (tid)
- ret = snprintf(proc, sizeof(proc), "/proc/%d/task/%d/stat", pid, tid);
+ ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", pid, tid);
else
- ret = snprintf(proc, sizeof(proc), "/proc/%d/stat", pid);
- if (ret >= (int)sizeof(proc)) {
+ ret = virAsprintf(&proc, "/proc/%d/stat", pid);
+ if (ret < 0) {
errno = E2BIG;
return -1;
}
@@ -4574,8 +4574,10 @@ static int qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, int pi
*cpuTime = 0;
if (lastCpu)
*lastCpu = 0;
+ VIR_FREE(proc);
return 0;
}
+ VIR_FREE(proc);
/* See 'man proc' for information about what all these fields are. We're
* only interested in a very few of them */
@@ -9033,7 +9035,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
- char drivestr[PATH_MAX];
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -9063,10 +9065,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
/* build the actual drive id string as the disk->info.alias doesn't
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
- if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
- QEMU_DRIVE_HOST_PREFIX,
- detach->info.alias))
- < 0 || ret >= sizeof(drivestr)) {
+ if (virAsprintf(&drivestr, QEMU_DRIVE_HOST_PREFIX "%s",
+ detach->info.alias) < 0) {
virReportOOMError();
goto cleanup;
}
@@ -9124,6 +9124,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
ret = 0;
cleanup:
+ VIR_FREE(drivestr);
return ret;
}
@@ -9136,7 +9137,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
- char drivestr[PATH_MAX];
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -9165,10 +9166,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
/* build the actual drive id string as the disk->info.alias doesn't
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
- if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
- QEMU_DRIVE_HOST_PREFIX,
- detach->info.alias))
- < 0 || ret >= sizeof(drivestr)) {
+ if (virAsprintf(&drivestr, QEMU_DRIVE_HOST_PREFIX "%s",
+ detach->info.alias) < 0) {
virReportOOMError();
goto cleanup;
}
@@ -9207,6 +9206,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
cleanup:
virCgroupFree(&cgroup);
+ VIR_FREE(drivestr);
return ret;
}
--
1.7.3.2
13 years, 11 months
[libvirt] [PATCH v5] qemu: call drive_del in DetachPciDiskDevice
by Ryan Harper
Currently libvirt doesn't confirm whether the guest has responded to the
disk removal request. In some cases this can leave the guest with
continued access to the device while the mgmt layer believes that it has
been removed. With a recent qemu monitor command[1] we can
deterministically revoke a guests access to the disk (on the QEMU side)
to ensure no futher access is permitted.
This patch adds support for the drive_del() command and introduces it
in the disk removal paths. If the guest is running in a QEMU without this
command we currently explicitly check for unknown command/CommandNotFound
and log the issue.
If QEMU supports the command we issue the drive_del command after we attempt
to remove the device. The guest may respond and remove the block device
before we get to attempt to call drive_del. In that case, we explicitly check
for 'Device not found' from the monitor indicating that the target drive
was auto-deleted upon guest responds to the device removal notification.
1. http://thread.gmane.org/gmane.comp.emulators.qemu/84745
Signed-off-by: Ryan Harper <ryanh(a)us.ibm.com>
---
Changes since v4:
- removed PATH_MAX, use virAsprintf()
- moved drivestr allocation before call to EnterMonitor
Changes since v3:
- Renamed DriveUnplug -> DriveDel, use drive_del monitor cmd.
- Moved invocation to after DelDevice and guest notification.
- Handle the case where drive is auto-deleted before we call
DriveDel by catching and ignoring 'Device not found' error.
- Simplified DriveDel invocation; no need to check return codes
as the monitor implementations handle all failure case and logs
or ignores as needed.
Changes since v2:
- use VIR_ERROR to report when unplug command not found
Changes since v1:
- return > 0 when command isn't present, < 0 on command failure
- detect when drive_unplug command isn't present and log error
instead of failing entire command
src/qemu/qemu_driver.c | 28 +++++++++++++++++++++
src/qemu/qemu_monitor.c | 19 ++++++++++++++
src/qemu/qemu_monitor.h | 3 ++
src/qemu/qemu_monitor_json.c | 38 +++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 3 ++
src/qemu/qemu_monitor_text.c | 54 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 3 ++
7 files changed, 148 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e7b37e1..a6a7b8d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9037,6 +9037,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -9064,6 +9065,14 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
goto cleanup;
}
+ /* build the actual drive id string as the disk->info.alias doesn't
+ * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
+ if (virAsprintf(&drivestr, "%s%s",
+ QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@@ -9077,6 +9086,10 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
goto cleanup;
}
}
+
+ /* disconnect guest from host device */
+ qemuMonitorDriveDel(priv->mon, drivestr);
+
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
@@ -9104,6 +9117,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
ret = 0;
cleanup:
+ VIR_FREE(drivestr);
return ret;
}
@@ -9116,6 +9130,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
+ char *drivestr = NULL;
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -9142,11 +9157,23 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
}
}
+ /* build the actual drive id string as the disk->info.alias doesn't
+ * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
+ if (virAsprintf(&drivestr, "%s%s",
+ QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
}
+
+ /* disconnect guest from host device */
+ qemuMonitorDriveDel(priv->mon, drivestr);
+
qemuDomainObjExitMonitorWithDriver(driver, vm);
qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0);
@@ -9170,6 +9197,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
ret = 0;
cleanup:
+ VIR_FREE(drivestr);
virCgroupFree(&cgroup);
return ret;
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 2366fdb..80adba4 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1781,6 +1781,25 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
return ret;
}
+int qemuMonitorDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ DEBUG("mon=%p drivestr=%s", mon, drivestr);
+ int ret;
+
+ if (!mon) {
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (mon->json)
+ ret = qemuMonitorJSONDriveDel(mon, drivestr);
+ else
+ ret = qemuMonitorTextDriveDel(mon, drivestr);
+ return ret;
+}
+
int qemuMonitorDelDevice(qemuMonitorPtr mon,
const char *devalias)
{
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 7d09145..8cda43b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -381,6 +381,9 @@ int qemuMonitorDelDevice(qemuMonitorPtr mon,
int qemuMonitorAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorDriveDel(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d2c6f0a..a380ab2 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2244,6 +2244,44 @@ int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
}
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ DEBUG("JSONDriveDel drivestr=%s", drivestr);
+ cmd = qemuMonitorJSONMakeCommand("drive_del",
+ "s:id", drivestr,
+ NULL);
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0) {
+ /* See if drive_del isn't supported */
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ VIR_ERROR0(_("deleting disk is not supported. "
+ "This may leak data if disk is reassigned"));
+ ret = 1;
+ goto cleanup;
+ } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) {
+ /* NB: device not found errors mean the drive was
+ * auto-deleted and we ignore the error */
+ ret = 0;
+ } else {
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+ }
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 94806c1..82671c7 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -188,6 +188,9 @@ int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorJSONDriveDel(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 7f15008..483ceb0 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -2285,6 +2285,7 @@ int qemuMonitorTextDelDevice(qemuMonitorPtr mon,
goto cleanup;
}
+ DEBUG("TextDelDevice devalias=%s", devalias);
if (qemuMonitorCommand(mon, cmd, &reply) < 0) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("cannot detach %s device"), devalias);
@@ -2391,6 +2392,59 @@ cleanup:
return ret;
}
+/* Attempts to remove a host drive.
+ * Returns 1 if unsupported, 0 if ok, and -1 on other failure */
+int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ char *cmd = NULL;
+ char *reply = NULL;
+ char *safedev;
+ int ret = -1;
+ DEBUG("TextDriveDel drivestr=%s", drivestr);
+
+ if (!(safedev = qemuMonitorEscapeArg(drivestr))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&cmd, "drive_del %s", safedev) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (qemuMonitorCommand(mon, cmd, &reply) < 0) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot delete %s drive"), drivestr);
+ goto cleanup;
+ }
+
+ if (strstr(reply, "unknown command:")) {
+ VIR_ERROR0(_("deleting drive is not supported. "
+ "This may leak data if disk is reassigned"));
+ ret = 1;
+ goto cleanup;
+
+ /* (qemu) drive_del wark
+ * Device 'wark' not found */
+ } else if (STRPREFIX(reply, "Device '") && (strstr(reply, "not found"))) {
+ /* NB: device not found errors mean the drive was auto-deleted and we
+ * ignore the error */
+ ret = 0;
+ } else if (STRNEQ(reply, "")) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("deleting %s drive failed: %s"), drivestr, reply);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(reply);
+ VIR_FREE(safedev);
+ return ret;
+}
int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index c017509..3a88f87 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -186,6 +186,9 @@ int qemuMonitorTextDelDevice(qemuMonitorPtr mon,
int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
--
1.6.3.3
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
ryanh(a)us.ibm.com
13 years, 11 months
[libvirt] [PATCH v3] qemu: call drive_unplug in DetachPciDiskDevice
by Ryan Harper
Currently libvirt doesn't confirm whether the guest has responded to the
disk removal request. In some cases this can leave the guest with
continued access to the device while the mgmt layer believes that it has
been removed. With a recent qemu monitor command[1] we can
deterministically revoke a guests access to the disk (on the QEMU side)
to ensure no futher access is permitted.
This patch adds support for the drive_unplug() command and introduces it
in the disk removal paths. There is some discussion to be had about how
to handle the case where the guest is running in a QEMU without this
command (and the fact that we currently don't have a way of detecting
what monitor commands are available).
Changes since v2:
- use VIR_ERROR to report when unplug command not found
Changes since v1:
- return > 0 when command isn't present, < 0 on command failure
- detect when drive_unplug command isn't present and log error
instead of failing entire command
Signed-off-by: Ryan Harper <ryanh(a)us.ibm.com>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index abd8e9d..615427a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8646,6 +8646,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
+ char drivestr[PATH_MAX];
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -8673,13 +8674,36 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
goto cleanup;
}
+ /* build the actual drive id string as the disk->info.alias doesn't
+ * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
+ if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
+ QEMU_DRIVE_HOST_PREFIX,
+ detach->info.alias))
+ < 0 || ret >= sizeof(drivestr)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+ ret = qemuMonitorDriveUnplug(priv->mon, drivestr);
+ DEBUG("DriveUnplug ret=%d", ret);
+ /* ret > 0 indicates unplug isn't supported, issue will be logged */
+ if (ret < 0) {
+ qemuDomainObjExitMonitor(vm);
+ goto cleanup;
+ }
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
}
} else {
+ ret = qemuMonitorDriveUnplug(priv->mon, drivestr);
+ /* ret > 0 indicates unplug isn't supported, issue will be logged */
+ if (ret < 0) {
+ qemuDomainObjExitMonitor(vm);
+ goto cleanup;
+ }
if (qemuMonitorRemovePCIDevice(priv->mon,
&detach->info.addr.pci) < 0) {
qemuDomainObjExitMonitor(vm);
@@ -8723,6 +8747,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
+ char drivestr[PATH_MAX];
i = qemudFindDisk(vm->def, dev->data.disk->dst);
@@ -8749,7 +8774,22 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
}
}
+ /* build the actual drive id string as the disk->info.alias doesn't
+ * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
+ if ((ret = snprintf(drivestr, sizeof(drivestr), "%s%s",
+ QEMU_DRIVE_HOST_PREFIX,
+ detach->info.alias))
+ < 0 || ret >= sizeof(drivestr)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ /* ret > 0 indicates unplug isn't supported, issue will be logged */
+ if (qemuMonitorDriveUnplug(priv->mon, drivestr) < 0) {
+ qemuDomainObjExitMonitor(vm);
+ goto cleanup;
+ }
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
qemuDomainObjExitMonitor(vm);
goto cleanup;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 2366fdb..285381d 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1781,6 +1781,25 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon,
return ret;
}
+int qemuMonitorDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ DEBUG("mon=%p drivestr=%s", mon, drivestr);
+ int ret;
+
+ if (!mon) {
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (mon->json)
+ ret = qemuMonitorJSONDriveUnplug(mon, drivestr);
+ else
+ ret = qemuMonitorTextDriveUnplug(mon, drivestr);
+ return ret;
+}
+
int qemuMonitorDelDevice(qemuMonitorPtr mon,
const char *devalias)
{
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 48f4c20..bfe3641 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -381,6 +381,9 @@ int qemuMonitorDelDevice(qemuMonitorPtr mon,
int qemuMonitorAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d3ab25f..b11fd4f 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2243,6 +2243,39 @@ int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
}
+int qemuMonitorJSONDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ DEBUG("JSONDriveUnplug drivestr=%s", drivestr);
+ cmd = qemuMonitorJSONMakeCommand("drive_unplug",
+ "s:id", drivestr,
+ NULL);
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0) {
+ /* See if drive_unplug isn't supported */
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) {
+ VIR_ERROR0(_("unplugging disk is not supported. "
+ "This may leak data if disk is reassigned"));
+ ret = 1;
+ goto cleanup;
+ }
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 94806c1..6a8692e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -188,6 +188,9 @@ int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
int qemuMonitorJSONAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorJSONDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 69971a6..6e5bc95 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -2380,6 +2380,52 @@ cleanup:
return ret;
}
+/* Attempts to unplug a drive. Returns 1 if unsupported, 0 if ok, and -1 on
+ * other failure */
+int qemuMonitorTextDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr)
+{
+ char *cmd = NULL;
+ char *reply = NULL;
+ char *safedev;
+ int ret = -1;
+ DEBUG("TextDriveUnplug drivestr=%s", drivestr);
+
+ if (!(safedev = qemuMonitorEscapeArg(drivestr))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&cmd, "drive_unplug %s", safedev) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (qemuMonitorCommand(mon, cmd, &reply) < 0) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot unplug %s drive"), drivestr);
+ goto cleanup;
+ }
+
+ if (strstr(reply, "unknown command:")) {
+ VIR_ERROR0(_("unplugging disk is not supported. "
+ "This may leak data if disk is reassigned"));
+ ret = 1;
+ goto cleanup;
+ } else if (STRNEQ(reply, "")) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("unplugging %s drive failed: %s"), drivestr, reply);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(reply);
+ VIR_FREE(safedev);
+ return ret;
+}
int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index c017509..8355ce8 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -186,6 +186,9 @@ int qemuMonitorTextDelDevice(qemuMonitorPtr mon,
int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
const char *drivestr);
+int qemuMonitorTextDriveUnplug(qemuMonitorPtr mon,
+ const char *drivestr);
+
int qemuMonitorTextSetDrivePassphrase(qemuMonitorPtr mon,
const char *alias,
const char *passphrase);
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
ryanh(a)us.ibm.com
13 years, 11 months
[libvirt] [PATCH] build: find xdr headers on cygwin
by Eric Blake
* configure.ac (XDR_CFLAGS): Define when needed.
* src/Makefile.am (libvirt_driver_remote_la_CFLAGS): Use it.
---
On cygwin, './autogen.sh' still tries to enable --with-libvirtd, which
also enables networking, but that fails to compile because bridge.c
assumes <linux/param.h> and friends exist. Also, vbox_XPCOMCGlue.c
fails to compile because it can't figure out an appropriate DYNLIB_NAME;
I don't know if anyone has ported a vbox shared library to cygwin
(where it would probably be named cygVBoxXPCMC.dll).
But with this patch, './autogen.sh --without-libvirtd --without-vbox'
successfully compiles. It still fails several tests in 'make check',
which I hope to have time to look at next.
configure.ac | 24 ++++++++++++++++++++++++
src/Makefile.am | 2 +-
2 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/configure.ac b/configure.ac
index dde2cde..1c31e73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -333,6 +333,25 @@ if test x"$with_remote" = x"yes" || test x"$with_libvirtd" = x"yes"; then
dnl check for cygwin's variation in xdr function names
AC_CHECK_FUNCS([xdr_u_int64_t],[],[],[#include <rpc/xdr.h>])
+
+ dnl Cygwin requires -I/usr/include/tirpc for <rpc/rpc.h>
+ old_CFLAGS=$CFLAGS
+ AC_CACHE_CHECK([where to find <rpc/rpc.h>], [lv_cv_xdr_cflags], [
+ for CFLAGS in '' '-I/usr/include/tirpc' 'missing'; do
+ if test x"$CFLAGS" = xmissing; then
+ lv_cv_xdr_cflags=missing; break
+ fi
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <rpc/rpc.h>
+ ]])], [lv_cv_xdr_cflags=${CFLAGS:-none}; break])
+ done
+ ])
+ CFLAGS=$old_CFLAGS
+ case $lv_cv_xdr_cflags in
+ none) XDR_CFLAGS= ;;
+ missing) AC_MSG_ERROR([Unable to find <rpc/rpc.h>]) ;;
+ *) XDR_CFLAGS=$lv_cv_xdr_cflags ;;
+ esac
+ AC_SUBST([XDR_CFLAGS])
fi
@@ -2415,6 +2434,11 @@ AC_MSG_NOTICE([ nl: $LIBNL_CFLAGS $LIBNL_LIBS])
else
AC_MSG_NOTICE([ nl: no])
fi
+if test "$with_remote" = "yes" || test "$with_libvirtd" = "yes" ; then
+AC_MSG_NOTICE([ xdr: $XDR_CFLAGS])
+else
+AC_MSG_NOTICE([ xdr: no])
+fi
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Test suite])
AC_MSG_NOTICE([])
diff --git a/src/Makefile.am b/src/Makefile.am
index 0923d60..baa1bfd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -473,7 +473,7 @@ libvirt_la_BUILT_LIBADD += libvirt_driver_remote.la
endif
libvirt_driver_remote_la_CFLAGS = \
$(GNUTLS_CFLAGS) \
- $(SASL_CFLAGS) \
+ $(SASL_CFLAGS) $(XDR_CFLAGS) \
-I@top_srcdir@/src/conf \
$(AM_CFLAGS)
libvirt_driver_remote_la_LDFLAGS = $(AM_LDFLAGS)
--
1.7.3.2
13 years, 11 months
[libvirt] [PATCH] qemud: fix memory leak in io error events
by Anthony Liguori
The extra data isn't being free()'d for IO error events that have a reason.
Signed-off-by: Anthony Liguori <aliguori(a)us.ibm.com>
---
I wasn't able to test this because the build is broken for me. I won't be able
to test it in the field for a couple days.
The problem we're seeing is a rather fast memory leak that exhausts all system
memory. I believe the source of the leak is that our underlying storage is
throwing an I/O error and libvirt is not properly freeing the resulting IO
error event object.
Because the storage is constantly generating errors and the guest is constantly
reading, memory is just consumed until the system is exhausted.
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index e88aafe..5f086bd 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -472,6 +472,7 @@ void virDomainEventFree(virDomainEventPtr event)
return;
switch (event->eventID) {
+ case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
VIR_FREE(event->data.ioError.srcPath);
VIR_FREE(event->data.ioError.devAlias);
--
1.7.0.4
13 years, 11 months
[libvirt] [PATCH] qemu: Enable disabled debug messages
by Jiri Denemark
---
src/qemu/qemu_conf.c | 2 +-
src/qemu/qemu_conf.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index d81e6cc..08c084b 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1449,7 +1449,7 @@ int qemudParseHelpStr(const char *qemu,
*flags = qemudComputeCmdFlags(help, *version, *is_kvm, *kvm_version);
- qemudDebug("Version %u.%u.%u, cooked version %u, flags %u",
+ qemudDebug("Version %u.%u.%u, cooked version %u, flags 0x%llx",
major, minor, micro, *version, *flags);
if (*kvm_version)
qemudDebug("KVM version %d detected", *kvm_version);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index a1556cb..50938f5 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -44,7 +44,7 @@
# include "macvtap.h"
# include "command.h"
-# define qemudDebug(fmt, ...) do {} while(0)
+# define qemudDebug DEBUG
# define QEMUD_CPUMASK_LEN CPU_SETSIZE
--
1.7.3.2
13 years, 11 months
[libvirt] [PATCH] qemu: Only build devstr when needs (attach PCI controller)
by Osier Yang
- qemudDomainAttachPciControllerDevice: Don't build "devstr"
if "-device" of qemu is not available, as "devstr" will only
be used by "qemuMonitorAddDevice", which depends on "-device"
argument of qemu is supported.
- "qemudDomainSaveImageOpen": Fix indent problem.
* src/qemu/qemu_driver.c
---
src/qemu/qemu_driver.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 54e9dcb..4ef186f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6844,10 +6844,10 @@ static int qemudDomainSaveImageClose(int fd, pid_t read_pid, int *status)
static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5)
qemudDomainSaveImageOpen(struct qemud_driver *driver,
- const char *path,
- virDomainDefPtr *ret_def,
- struct qemud_save_header *ret_header,
- pid_t *ret_read_pid)
+ const char *path,
+ virDomainDefPtr *ret_def,
+ struct qemud_save_header *ret_header,
+ pid_t *ret_read_pid)
{
int fd;
pid_t read_pid = -1;
@@ -7902,11 +7902,11 @@ static int qemudDomainAttachPciControllerDevice(struct qemud_driver *driver,
goto cleanup;
if (qemuAssignDeviceControllerAlias(controller) < 0)
goto cleanup;
- }
- if (!(devstr = qemuBuildControllerDevStr(controller))) {
- virReportOOMError();
- goto cleanup;
+ if (!(devstr = qemuBuildControllerDevStr(controller))) {
+ virReportOOMError();
+ goto cleanup;
+ }
}
if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0) {
--
1.7.3.2
13 years, 11 months