From: Wolfgang Mauerer <wolfgang.mauerer(a)siemens.com>
This allows us to connect a disk with a specific controller,
which is required for disk hotadd/remove. A new XML child
element is added to the <disk> container:
<disk>
...
<controller name="<identifier>" pci_addr="<addr>"
bus="<number>" unit="<number>"/>
</disk>
Normally the name of the controller must be specified. Using pci_addr
instead is supported for qemu guests that don't define a controller
in their main configuration file and cannot hotplug controllers.
When the controller has been brought into the system via the hotplug
mechanism also included in this patch series, it will have an ID.
Wrt. the data structures touched in this commit, notice
that while "bus" as subelement of target specifies
the type of bus (e.g., scsi, ide,...), it is used
to enumerate the buses on the controller here.
Signed-off-by: Wolfgang Mauerer <wolfgang.mauerer(a)siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka(a)siemens.com>
---
src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++++
src/conf/domain_conf.h | 5 ++++-
2 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 28bee54..ecddb68 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -724,7 +724,12 @@ virDomainDiskDefParseXML(virConnectPtr conn,
char *driverType = NULL;
char *source = NULL;
char *target = NULL;
+ char *controller = NULL;
+ char *bus_id = NULL;
+ char *unit_id = NULL;
+ char *controller_id = NULL;
char *bus = NULL;
+ char *unit = NULL;
char *cachetag = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
@@ -768,12 +773,18 @@ virDomainDiskDefParseXML(virConnectPtr conn,
(xmlStrEqual(cur->name, BAD_CAST "target"))) {
target = virXMLPropString(cur, "dev");
bus = virXMLPropString(cur, "bus");
+ unit = virXMLPropString(cur, "unit");
/* HACK: Work around for compat with Xen
* driver in previous libvirt releases */
if (target &&
STRPREFIX(target, "ioemu:"))
memmove(target, target+6, strlen(target)-5);
+ } else if ((controller == NULL) &&
+ (xmlStrEqual(cur->name, BAD_CAST "controller"))) {
+ controller_id = virXMLPropString(cur, "id");
+ bus_id = virXMLPropString(cur, "bus");
+ unit_id = virXMLPropString(cur, "unit");
} else if ((driverName == NULL) &&
(xmlStrEqual(cur->name, BAD_CAST "driver"))) {
driverName = virXMLPropString(cur, "name");
@@ -874,6 +885,24 @@ virDomainDiskDefParseXML(virConnectPtr conn,
}
}
+ if (controller) {
+ def->controller_id = controller_id;
+
+ def->bus_id = -1;
+ if (bus_id && virStrToLong_i(bus_id, NULL, 10, &def->bus_id) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <controller> 'bus' attribute"));
+ goto error;
+ }
+
+ def->unit_id = -1;
+ if (unit_id && virStrToLong_i(unit_id, NULL, 10, &def->unit_id) < 0)
{
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <controller> 'unit' attribute"));
+ goto error;
+ }
+ }
+
if (def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
def->bus != VIR_DOMAIN_DISK_BUS_FDC) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fadf43f..c034ae4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -107,9 +107,12 @@ typedef virDomainDiskDef *virDomainDiskDefPtr;
struct _virDomainDiskDef {
int type;
int device;
- int bus;
+ int bus; /* Bus type, e.g. scsi or ide */
+ int bus_id; /* Bus number on the controller */
+ int unit_id; /* Unit on the controller */
char *src;
char *dst;
+ char *controller_id;
char *driverName;
char *driverType;
char *serial;
--
1.6.4