qemu: Add flag to force a CDROM eject

QEMU allows forcing a CDROM eject even if the guest has locked the device.
Expose this via a new UpdateDevice flag, VIR_DOMAIN_DEVICE_MODIFY_FORCE.

This has been requested for RHEV:

https://bugzilla.redhat.com/show_bug.cgi?id=626305

v2: Change flag name, bool cleanups
This commit is contained in:
Cole Robinson 2010-11-08 12:52:48 -05:00
parent f970d802ab
commit 96d52fcf43
8 changed files with 29 additions and 19 deletions

View File

@ -1033,6 +1033,8 @@ typedef enum {
VIR_DOMAIN_DEVICE_MODIFY_CURRENT = 0, /* Modify device allocation based on current domain state */ VIR_DOMAIN_DEVICE_MODIFY_CURRENT = 0, /* Modify device allocation based on current domain state */
VIR_DOMAIN_DEVICE_MODIFY_LIVE = (1 << 0), /* Modify live device allocation */ VIR_DOMAIN_DEVICE_MODIFY_LIVE = (1 << 0), /* Modify live device allocation */
VIR_DOMAIN_DEVICE_MODIFY_CONFIG = (1 << 1), /* Modify persisted device allocation */ VIR_DOMAIN_DEVICE_MODIFY_CONFIG = (1 << 1), /* Modify persisted device allocation */
VIR_DOMAIN_DEVICE_MODIFY_FORCE = (1 << 2), /* Forcibly modify device
(ex. force eject a cdrom) */
} virDomainDeviceModifyFlags; } virDomainDeviceModifyFlags;
int virDomainAttachDevice(virDomainPtr domain, const char *xml); int virDomainAttachDevice(virDomainPtr domain, const char *xml);

View File

@ -7704,7 +7704,8 @@ cleanup:
static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver, static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDiskDefPtr disk, virDomainDiskDefPtr disk,
unsigned long long qemuCmdFlags) unsigned long long qemuCmdFlags,
bool force)
{ {
virDomainDiskDefPtr origdisk = NULL; virDomainDiskDefPtr origdisk = NULL;
int i; int i;
@ -7765,7 +7766,7 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
driveAlias, driveAlias,
disk->src, format); disk->src, format);
} else { } else {
ret = qemuMonitorEjectMedia(priv->mon, driveAlias); ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
} }
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
@ -8732,7 +8733,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
case VIR_DOMAIN_DISK_DEVICE_FLOPPY: case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
ret = qemudDomainChangeEjectableMedia(driver, vm, ret = qemudDomainChangeEjectableMedia(driver, vm,
dev->data.disk, dev->data.disk,
qemuCmdFlags); qemuCmdFlags,
false);
if (ret == 0) if (ret == 0)
dev->data.disk = NULL; dev->data.disk = NULL;
break; break;
@ -8919,10 +8921,12 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
unsigned long long qemuCmdFlags; unsigned long long qemuCmdFlags;
virCgroupPtr cgroup = NULL; virCgroupPtr cgroup = NULL;
int ret = -1; int ret = -1;
bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0;
virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_CURRENT | virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_CURRENT |
VIR_DOMAIN_DEVICE_MODIFY_LIVE | VIR_DOMAIN_DEVICE_MODIFY_LIVE |
VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1); VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1);
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
qemuReportError(VIR_ERR_OPERATION_INVALID, qemuReportError(VIR_ERR_OPERATION_INVALID,
@ -8977,7 +8981,8 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
case VIR_DOMAIN_DISK_DEVICE_FLOPPY: case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
ret = qemudDomainChangeEjectableMedia(driver, vm, ret = qemudDomainChangeEjectableMedia(driver, vm,
dev->data.disk, dev->data.disk,
qemuCmdFlags); qemuCmdFlags,
force);
if (ret == 0) if (ret == 0)
dev->data.disk = NULL; dev->data.disk = NULL;
break; break;

View File

@ -1147,10 +1147,11 @@ int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, int online)
int qemuMonitorEjectMedia(qemuMonitorPtr mon, int qemuMonitorEjectMedia(qemuMonitorPtr mon,
const char *devname) const char *devname,
bool force)
{ {
int ret; int ret;
DEBUG("mon=%p devname=%s", mon, devname); DEBUG("mon=%p devname=%s force=%d", mon, devname, force);
if (!mon) { if (!mon) {
qemuReportError(VIR_ERR_INVALID_ARG, "%s", qemuReportError(VIR_ERR_INVALID_ARG, "%s",
@ -1159,9 +1160,9 @@ int qemuMonitorEjectMedia(qemuMonitorPtr mon,
} }
if (mon->json) if (mon->json)
ret = qemuMonitorJSONEjectMedia(mon, devname); ret = qemuMonitorJSONEjectMedia(mon, devname, force);
else else
ret = qemuMonitorTextEjectMedia(mon, devname); ret = qemuMonitorTextEjectMedia(mon, devname, force);
return ret; return ret;
} }

View File

@ -203,12 +203,10 @@ int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, int online);
/* XXX should we pass the virDomainDiskDefPtr instead /* XXX should we pass the virDomainDiskDefPtr instead
* and hide devname details inside monitor. Reconsider * and hide devname details inside monitor. Reconsider
* this when doing the QMP implementation * this when doing the QMP implementation
*
* XXXX 'eject' has gained a 'force' flag we might like
* to make use of...
*/ */
int qemuMonitorEjectMedia(qemuMonitorPtr mon, int qemuMonitorEjectMedia(qemuMonitorPtr mon,
const char *devname); const char *devname,
bool force);
int qemuMonitorChangeMedia(qemuMonitorPtr mon, int qemuMonitorChangeMedia(qemuMonitorPtr mon,
const char *devname, const char *devname,
const char *newmedia, const char *newmedia,

View File

@ -1348,12 +1348,13 @@ cleanup:
int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon, int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
const char *devname) const char *devname,
bool force)
{ {
int ret; int ret;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("eject", virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("eject",
"s:device", devname, "s:device", devname,
"b:force", 0, "b:force", force ? 1 : 0,
NULL); NULL);
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
if (!cmd) if (!cmd)

View File

@ -68,7 +68,8 @@ int qemuMonitorJSONSetBalloon(qemuMonitorPtr mon,
int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, int cpu, int online); int qemuMonitorJSONSetCPU(qemuMonitorPtr mon, int cpu, int online);
int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon, int qemuMonitorJSONEjectMedia(qemuMonitorPtr mon,
const char *devname); const char *devname,
bool force);
int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon, int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
const char *devname, const char *devname,
const char *newmedia, const char *newmedia,

View File

@ -848,13 +848,14 @@ int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, int online)
int qemuMonitorTextEjectMedia(qemuMonitorPtr mon, int qemuMonitorTextEjectMedia(qemuMonitorPtr mon,
const char *devname) const char *devname,
bool force)
{ {
char *cmd = NULL; char *cmd = NULL;
char *reply = NULL; char *reply = NULL;
int ret = -1; int ret = -1;
if (virAsprintf(&cmd, "eject %s", devname) < 0) { if (virAsprintf(&cmd, "eject %s%s", force ? "-f " : "", devname) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }

View File

@ -66,7 +66,8 @@ int qemuMonitorTextSetBalloon(qemuMonitorPtr mon,
int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, int online); int qemuMonitorTextSetCPU(qemuMonitorPtr mon, int cpu, int online);
int qemuMonitorTextEjectMedia(qemuMonitorPtr mon, int qemuMonitorTextEjectMedia(qemuMonitorPtr mon,
const char *devname); const char *devname,
bool force);
int qemuMonitorTextChangeMedia(qemuMonitorPtr mon, int qemuMonitorTextChangeMedia(qemuMonitorPtr mon,
const char *devname, const char *devname,
const char *newmedia, const char *newmedia,