static virDomainDiskDefPtr
virDomainDiskDefParseXML(virConnectPtr conn,
xmlNodePtr node,
- int flags ATTRIBUTE_UNUSED) {
+ int flags) {
virDomainDiskDefPtr def;
xmlNodePtr cur;
char *type = NULL;
char *target = NULL;
char *bus = NULL;
char *cachetag = NULL;
+ char *devaddr = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError(conn);
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
def->shared = 1;
+ } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
+ xmlStrEqual(cur->name, BAD_CAST "state")) {
+ devaddr = virXMLPropString(cur, "devaddr");
}
}
cur = cur->next;
goto error;
}
+ if (devaddr &&
+ sscanf(devaddr, "%x:%x:%x",
+ &def->pci_addr.domain,
+ &def->pci_addr.bus,
+ &def->pci_addr.slot) < 3) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Unable to parse devaddr parameter '%s'"),
+ devaddr);
+ goto error;
+ }
+
def->src = source;
source = NULL;
def->dst = target;
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
+ VIR_FREE(devaddr);
return def;
static int
virDomainDiskDefFormat(virConnectPtr conn,
virBufferPtr buf,
- virDomainDiskDefPtr def)
+ virDomainDiskDefPtr def,
+ int flags)
{
const char *type = virDomainDiskTypeToString(def->type);
const char *device = virDomainDiskDeviceTypeToString(def->device);
if (def->shared)
virBufferAddLit(buf, " <shareable/>\n");
+ if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) {
+ virBufferAddLit(buf, " <state");
+ if (virDiskHasValidPciAddr(def))
+ virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'",
+ def->pci_addr.domain,
+ def->pci_addr.bus,
+ def->pci_addr.slot);
+ virBufferAddLit(buf, "/>\n");
+ }
+
virBufferAddLit(buf, " </disk>\n");
return 0;
def->emulator);
for (n = 0 ; n < def->ndisks ; n++)
- if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0)
+ if (virDomainDiskDefFormat(conn, &buf, def->disks[n], flags) < 0)
goto cleanup;
for (n = 0 ; n < def->nfss ; n++)
return -1;
}
+ VIR_FREE(cmd);
+
DEBUG ("%s: pci_add reply: %s", vm->def->name, reply);
/* If the command succeeds qemu prints:
* OK bus 0, slot XXX...
if ((s = strstr(reply, "OK ")) &&
(s = strstr(s, "slot "))) {
char *dummy = s;
+ unsigned slot;
+
s += strlen("slot ");
- if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
+ if (virStrToLong_ui((const char*)s, &dummy, 10, &slot) == -1)
VIR_WARN("%s", _("Unable to parse slot number\n"));
+
/* XXX not neccessarily always going to end up in domain 0 / bus 0 :-( */
- /* XXX this slotnum is not persistant across restarts :-( */
+ dev->data.disk->pci_addr.domain = 0;
+ dev->data.disk->pci_addr.bus = 0;
+ dev->data.disk->pci_addr.slot = slot;
} else if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
VIR_FREE(reply);
- VIR_FREE(cmd);
tryOldSyntax = 1;
goto try_command;
} else {
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed: %s"), type, reply);
VIR_FREE(reply);
- VIR_FREE(cmd);
return -1;
}
virDomainDiskQSort);
VIR_FREE(reply);
- VIR_FREE(cmd);
+
return 0;
}
goto cleanup;
}
- if (detach->slotnum < 1) {
+ if (!virDiskHasValidPciAddr(detach)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _("disk %s cannot be detached - invalid slot number %d"),
- detach->dst, detach->slotnum);
+ _("disk %s cannot be detached - no PCI address for device"),
+ detach->dst);
goto cleanup;
}
try_command:
if (tryOldSyntax) {
- if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
+ if (virAsprintf(&cmd, "pci_del 0 %.2x", detach->pci_addr.slot) < 0) {
virReportOOMError(conn);
goto cleanup;
}
} else {
- if (virAsprintf(&cmd, "pci_del pci_addr=0:0:%d", detach->slotnum) < 0) {
+ if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
+ detach->pci_addr.domain,
+ detach->pci_addr.bus,
+ detach->pci_addr.slot) < 0) {
virReportOOMError(conn);
goto cleanup;
}
if (strstr(reply, "invalid slot") ||
strstr(reply, "Invalid pci address")) {
qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
- _("failed to detach disk %s: invalid slot %d: %s"),
- detach->dst, detach->slotnum, reply);
+ _("failed to detach disk %s: invalid PCI address %.4x:%.2x:%.2x: %s"),
+ detach->dst,
+ detach->pci_addr.domain,
+ detach->pci_addr.bus,
+ detach->pci_addr.slot,
+ reply);
goto cleanup;
}