mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
Support CDROM media change for QEMU/KVM
This commit is contained in:
parent
97185033e5
commit
d6f351690e
@ -1,3 +1,7 @@
|
|||||||
|
Fri Oct 26 21:18:44 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/qemu_driver.c: Support CDROM media change for KVM/QEMU
|
||||||
|
|
||||||
Fri Oct 26 21:17:44 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
Fri Oct 26 21:17:44 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/qemu_driver.c: Refactor shell ecscaping function to reuse
|
* src/qemu_driver.c: Refactor shell ecscaping function to reuse
|
||||||
|
@ -1984,6 +1984,11 @@ static char *qemudEscape(const char *in, int shell)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *qemudEscapeMonitorArg(const char *in)
|
||||||
|
{
|
||||||
|
return qemudEscape(in, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static char *qemudEscapeShellArg(const char *in)
|
static char *qemudEscapeShellArg(const char *in)
|
||||||
{
|
{
|
||||||
return qemudEscape(in, 1);
|
return qemudEscape(in, 1);
|
||||||
@ -2331,6 +2336,94 @@ static int qemudDomainUndefine(virDomainPtr dom) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qemudDomainChangeCDROM(virDomainPtr dom,
|
||||||
|
struct qemud_vm *vm,
|
||||||
|
struct qemud_vm_disk_def *olddisk,
|
||||||
|
struct qemud_vm_disk_def *newdisk) {
|
||||||
|
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
||||||
|
char *cmd, *reply, *safe_path;
|
||||||
|
|
||||||
|
/* Migrate to file */
|
||||||
|
safe_path = qemudEscapeMonitorArg(newdisk->src);
|
||||||
|
if (!safe_path) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asprintf (&cmd, "change %s \"%s\"",
|
||||||
|
/* XXX qemu may support multiple CDROM in future */
|
||||||
|
/* olddisk->dst */ "cdrom",
|
||||||
|
safe_path) == -1) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"out of memory");
|
||||||
|
free(safe_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(safe_path);
|
||||||
|
|
||||||
|
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "cannot change cdrom media");
|
||||||
|
free(cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(reply);
|
||||||
|
free(cmd);
|
||||||
|
strcpy(olddisk->dst, newdisk->dst);
|
||||||
|
olddisk->type = newdisk->type;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qemudDomainAttachDevice(virDomainPtr dom,
|
||||||
|
const char *xml) {
|
||||||
|
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
||||||
|
struct qemud_vm *vm = qemudFindVMByUUID(driver, dom->uuid);
|
||||||
|
struct qemud_vm_device_def *dev;
|
||||||
|
struct qemud_vm_disk_def *disk;
|
||||||
|
|
||||||
|
if (!vm) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qemudIsActiveVM(vm)) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, "cannot attach device on inactive domain");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = qemudParseVMDeviceDef(dom->conn, driver, xml);
|
||||||
|
if (dev == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->type != QEMUD_DEVICE_DISK || dev->data.disk.device != QEMUD_DISK_CDROM) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "only CDROM disk devices can be attached");
|
||||||
|
free(dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
disk = vm->def->disks;
|
||||||
|
while (disk) {
|
||||||
|
if (disk->device == QEMUD_DISK_CDROM &&
|
||||||
|
STREQ(disk->dst, dev->data.disk.dst))
|
||||||
|
break;
|
||||||
|
disk = disk->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disk) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "CDROM not attached, cannot change media");
|
||||||
|
free(dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudDomainChangeCDROM(dom, vm, disk, &dev->data.disk) < 0) {
|
||||||
|
free(dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int qemudDomainGetAutostart(virDomainPtr dom,
|
static int qemudDomainGetAutostart(virDomainPtr dom,
|
||||||
int *autostart) {
|
int *autostart) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
|
||||||
@ -2723,7 +2816,7 @@ static virDriver qemuDriver = {
|
|||||||
qemudDomainStart, /* domainCreate */
|
qemudDomainStart, /* domainCreate */
|
||||||
qemudDomainDefine, /* domainDefineXML */
|
qemudDomainDefine, /* domainDefineXML */
|
||||||
qemudDomainUndefine, /* domainUndefine */
|
qemudDomainUndefine, /* domainUndefine */
|
||||||
NULL, /* domainAttachDevice */
|
qemudDomainAttachDevice, /* domainAttachDevice */
|
||||||
NULL, /* domainDetachDevice */
|
NULL, /* domainDetachDevice */
|
||||||
qemudDomainGetAutostart, /* domainGetAutostart */
|
qemudDomainGetAutostart, /* domainGetAutostart */
|
||||||
qemudDomainSetAutostart, /* domainSetAutostart */
|
qemudDomainSetAutostart, /* domainSetAutostart */
|
||||||
|
Loading…
Reference in New Issue
Block a user