* src/domain_conf.h src/qemu_driver.c: patch adding hor removal of

scsi/virtio disks for KVM, patch by Guido Günther
daniel
This commit is contained in:
Daniel Veillard 2008-10-29 14:32:40 +00:00
parent f79ebbd121
commit 4780a00b14
3 changed files with 135 additions and 5 deletions

View File

@ -1,3 +1,8 @@
Wed Oct 29 15:25:28 CET 2008 Daniel Veillard <veillard@redhat.com>
* src/domain_conf.h src/qemu_driver.c: patch adding hor removal of
scsi/virtio disks for KVM, patch by Guido Günther
Tue Oct 28 19:17:20 +0100 2008 Jim Meyering <meyering@redhat.com>
remove src/socketcompat.h; no longer needed

View File

@ -90,6 +90,7 @@ struct _virDomainDiskDef {
char *driverType;
unsigned int readonly : 1;
unsigned int shared : 1;
int slotnum; /* pci slot number for unattach */
};

View File

@ -2537,12 +2537,12 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
return 0;
}
static int qemudDomainAttachDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
static int qemudDomainAttachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
{
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int ret, i;
char *cmd, *reply;
char *cmd, *reply, *s;
char *safe_path;
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
@ -2590,7 +2590,14 @@ static int qemudDomainAttachDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr d
DEBUG ("pci_add reply: %s", reply);
/* If the command succeeds qemu prints:
* OK bus 0... */
if (!strstr(reply, "OK bus 0")) {
#define PCI_ATTACH_OK_MSG "OK bus 0, slot "
if ((s=strstr(reply, PCI_ATTACH_OK_MSG))) {
char* dummy = s;
s += strlen(PCI_ATTACH_OK_MSG);
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
qemudLog(QEMUD_WARN, _("Unable to parse slot number\n"));
} else {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed"), type);
VIR_FREE(reply);
@ -2773,7 +2780,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
} else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
supported = 1;
ret = qemudDomainAttachDiskDevice(dom, dev);
ret = qemudDomainAttachPciDiskDevice(dom, dev);
}
break;
}
@ -2794,6 +2801,123 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
return ret;
}
static int qemudDomainDetachPciDiskDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
{
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int i, ret = -1;
char *cmd, *reply;
virDomainDiskDefPtr detach = NULL;
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
detach = vm->def->disks[i];
break;
}
}
if (!detach) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("disk %s not found"), dev->data.disk->dst);
return -1;
}
if (detach->slotnum < 1) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("disk %s cannot be detached - invalid slot number %d"),
detach->dst, detach->slotnum);
return -1;
}
ret = asprintf(&cmd, "pci_del 0 %d", detach->slotnum);
if (ret == -1) {
qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return ret;
}
if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to execute detach disk %s command"), detach->dst);
VIR_FREE(cmd);
return -1;
}
DEBUG ("pci_del reply: %s", reply);
/* If the command fails due to a wrong slot qemu prints: invalid slot,
* nothing is printed on success */
if (strstr(reply, "invalid slot")) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("failed to detach disk %s: invalid slot %d"),
detach->dst, detach->slotnum);
ret = -1;
goto out;
}
if (vm->def->ndisks > 1) {
vm->def->disks[i] = vm->def->disks[--vm->def->ndisks];
if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
ret = -1;
goto out;
}
qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
virDomainDiskQSort);
} else {
VIR_FREE(vm->def->disks[0]);
vm->def->ndisks = 0;
}
ret = 0;
out:
VIR_FREE(reply);
VIR_FREE(cmd);
return ret;
}
static int qemudDomainDetachDevice(virDomainPtr dom,
const char *xml) {
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
virDomainDeviceDefPtr dev;
int ret = 0;
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return -1;
}
if (!virDomainIsActive(vm)) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot attach device on inactive domain"));
return -1;
}
dev = virDomainDeviceDefParse(dom->conn, driver->caps, vm->def, xml);
if (dev == NULL) {
return -1;
}
if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
(dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO))
ret = qemudDomainDetachPciDiskDevice(dom, dev);
else {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("only SCSI or virtio disk device can be detached dynamically"));
ret = -1;
}
VIR_FREE(dev);
return ret;
}
static int qemudDomainGetAutostart(virDomainPtr dom,
int *autostart) {
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
@ -3278,7 +3402,7 @@ static virDriver qemuDriver = {
qemudDomainDefine, /* domainDefineXML */
qemudDomainUndefine, /* domainUndefine */
qemudDomainAttachDevice, /* domainAttachDevice */
NULL, /* domainDetachDevice */
qemudDomainDetachDevice, /* domainDetachDevice */
qemudDomainGetAutostart, /* domainGetAutostart */
qemudDomainSetAutostart, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */