[PATCH 00/11] Implement initiator IQN config for iSCSI hostdevs (and cleanups)

Last patch implements the initiator IQN, the rest is cleanups and preparation. Note that this series depends on: https://www.redhat.com/archives/libvir-list/2020-July/msg00567.html https://www.redhat.com/archives/libvir-list/2020-July/msg00717.html Peter Krempa (11): virDomainHostdevDefFormatSubsys: Use virXMLFormatElement virDomainHostdevDefFormatSubsys: Split out formatting of USB subsystem virDomainHostdevDefFormatSubsys: Split out formatting of PCI subsystem virDomainHostdevDefFormatSubsys: Split out formatting of SCSI subsystem virDomainHostdevDefFormatSubsysSCSI: Avoid ternary operator when formatting address virDomainHostdevDefFormatSubsys: Split out formatting of vHBA subsystem virDomainHostdevDefFormatSubsys: Split out formatting of mdev subsystem virDomainHostdevSubsysSCSIDefParseXML: Use typecasted switch virDomainHostdevSubsysSCSIiSCSIDefParseXML: Use XPath to fetch elements docs: formatdomain-devices: Split out '<hostdev>' into separate file conf: Add support for initiator IQN setting for iSCSI hostdevs docs/formatdomain-devices-hostdev.rst.in | 344 ++++++++++++++++++ docs/formatdomain-devices.rst.in | 338 +---------------- docs/schemas/domaincommon.rng | 3 + src/conf/domain_conf.c | 329 ++++++++++------- ...hostdev-scsi-virtio-scsi.x86_64-4.1.0.args | 3 +- ...ostdev-scsi-virtio-scsi.x86_64-latest.args | 1 + .../hostdev-scsi-virtio-scsi.xml | 3 + .../hostdev-scsi-virtio-scsi.xml | 3 + 8 files changed, 545 insertions(+), 479 deletions(-) create mode 100644 docs/formatdomain-devices-hostdev.rst.in -- 2.26.2

Refactor the formatter to the new multiple buffer based approach so that we can easily separate it into formatters per subsys type. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 65 ++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8f5a8ef4a4..4b1f27fcea 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26030,7 +26030,9 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, bool includeTypeInAddr, virDomainXMLOptionPtr xmlopt) { - bool closedSource = false; + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf); virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb; virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi; @@ -26053,18 +26055,17 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, virBufferAsprintf(buf, "<driver name='%s'/>\n", backend); } - virBufferAddLit(buf, "<source"); if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { if (def->startupPolicy) { const char *policy; policy = virDomainStartupPolicyTypeToString(def->startupPolicy); - virBufferAsprintf(buf, " startupPolicy='%s'", policy); + virBufferAsprintf(&sourceAttrBuf, " startupPolicy='%s'", policy); } if (usbsrc->autoAddress && (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE)) - virBufferAddLit(buf, " autoAddress='yes'"); + virBufferAddLit(&sourceAttrBuf, " autoAddress='yes'"); if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) - virBufferAddLit(buf, " missing='yes'"); + virBufferAddLit(&sourceAttrBuf, " missing='yes'"); } if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && @@ -26072,69 +26073,59 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, const char *protocol = virDomainHostdevSubsysSCSIProtocolTypeToString(scsisrc->protocol); - virBufferAsprintf(buf, " protocol='%s' name='%s'", + virBufferAsprintf(&sourceAttrBuf, " protocol='%s' name='%s'", protocol, iscsisrc->src->path); } if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) { const char *protocol = virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol); - closedSource = true; - virBufferAsprintf(buf, " protocol='%s' wwpn='%s'/", + virBufferAsprintf(&sourceAttrBuf, " protocol='%s' wwpn='%s'", protocol, hostsrc->wwpn); } - virBufferAddLit(buf, ">\n"); - - virBufferAdjustIndent(buf, 2); switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: if (usbsrc->vendor) { - virBufferAsprintf(buf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor); - virBufferAsprintf(buf, "<product id='0x%.4x'/>\n", usbsrc->product); + virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor); + virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product); } if (usbsrc->bus || usbsrc->device) { - virBufferAsprintf(buf, "<address %sbus='%d' device='%d'/>\n", + virBufferAsprintf(&sourceChildBuf, "<address %sbus='%d' device='%d'/>\n", includeTypeInAddr ? "type='usb' " : "", usbsrc->bus, usbsrc->device); } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - virPCIDeviceAddressFormat(buf, pcisrc->addr, + virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr); - if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES) && - (def->origstates.states.pci.unbind_from_stub || - def->origstates.states.pci.remove_slot || - def->origstates.states.pci.reprobe)) { - virBufferAddLit(buf, "<origstates>\n"); - virBufferAdjustIndent(buf, 2); + if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) { if (def->origstates.states.pci.unbind_from_stub) - virBufferAddLit(buf, "<unbind/>\n"); + virBufferAddLit(&origstatesChildBuf, "<unbind/>\n"); if (def->origstates.states.pci.remove_slot) - virBufferAddLit(buf, "<removeslot/>\n"); + virBufferAddLit(&origstatesChildBuf, "<removeslot/>\n"); if (def->origstates.states.pci.reprobe) - virBufferAddLit(buf, "<reprobe/>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</origstates>\n"); + virBufferAddLit(&origstatesChildBuf, "<reprobe/>\n"); + virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf); } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { - virBufferAddLit(buf, "<host"); - virBufferEscapeString(buf, " name='%s'", iscsisrc->src->hosts[0].name); + virBufferAddLit(&sourceChildBuf, "<host"); + virBufferEscapeString(&sourceChildBuf, " name='%s'", iscsisrc->src->hosts[0].name); if (iscsisrc->src->hosts[0].port) - virBufferAsprintf(buf, " port='%u'", iscsisrc->src->hosts[0].port); - virBufferAddLit(buf, "/>\n"); + virBufferAsprintf(&sourceChildBuf, " port='%u'", iscsisrc->src->hosts[0].port); + virBufferAddLit(&sourceChildBuf, "/>\n"); - if (virDomainDiskSourceFormatPrivateData(buf, iscsisrc->src, + if (virDomainDiskSourceFormatPrivateData(&sourceChildBuf, iscsisrc->src, flags, xmlopt) < 0) return -1; } else { - virBufferAsprintf(buf, "<adapter name='%s'/>\n", + virBufferAsprintf(&sourceChildBuf, "<adapter name='%s'/>\n", scsihostsrc->adapter); - virBufferAsprintf(buf, + virBufferAsprintf(&sourceChildBuf, "<address %sbus='%u' target='%u' unit='%llu'/>\n", includeTypeInAddr ? "type='scsi' " : "", scsihostsrc->bus, scsihostsrc->target, @@ -26144,7 +26135,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: - virBufferAsprintf(buf, "<address uuid='%s'/>\n", + virBufferAsprintf(&sourceChildBuf, "<address uuid='%s'/>\n", mdevsrc->uuidstr); break; default: @@ -26157,11 +26148,9 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI && iscsisrc->src->auth) - virStorageAuthDefFormat(buf, iscsisrc->src->auth); + virStorageAuthDefFormat(&sourceChildBuf, iscsisrc->src->auth); - virBufferAdjustIndent(buf, -2); - if (!closedSource) - virBufferAddLit(buf, "</source>\n"); + virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); return 0; } -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Refactor the formatter to the new multiple buffer based approach so that we can easily separate it into formatters per subsys type.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 65 ++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 38 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Separate out bits related to USB so that the logic isn't entangled in multiple conditional statements. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 73 +++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4b1f27fcea..7718a59c66 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26023,6 +26023,40 @@ virDomainNetIPInfoFormat(virBufferPtr buf, } +static void +virDomainHostdevDefFormatSubsysUSB(virBufferPtr buf, + virDomainHostdevDefPtr def, + unsigned int flags, + bool includeTypeInAddr) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb; + + if (def->startupPolicy) + virBufferAsprintf(&sourceAttrBuf, " startupPolicy='%s'", + virDomainStartupPolicyTypeToString(def->startupPolicy)); + + if (usbsrc->autoAddress && (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE)) + virBufferAddLit(&sourceAttrBuf, " autoAddress='yes'"); + + if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) + virBufferAddLit(&sourceAttrBuf, " missing='yes'"); + + if (usbsrc->vendor) { + virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor); + virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product); + } + + if (usbsrc->bus || usbsrc->device) + virBufferAsprintf(&sourceChildBuf, "<address %sbus='%d' device='%d'/>\n", + includeTypeInAddr ? "type='usb' " : "", + usbsrc->bus, usbsrc->device); + + virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def, @@ -26033,7 +26067,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf); - virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb; virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host; @@ -26041,6 +26074,23 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host; virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; + switch ((virDomainHostdevSubsysType) def->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: + virDomainHostdevDefFormatSubsysUSB(buf, def, flags, includeTypeInAddr); + return 0; + + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: + break; + + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: + default: + virReportEnumRangeError(virDomainHostdevSubsysType, def->source.subsys.type); + return -1; + } + if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { const char *backend = @@ -26055,18 +26105,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, virBufferAsprintf(buf, "<driver name='%s'/>\n", backend); } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { - if (def->startupPolicy) { - const char *policy; - policy = virDomainStartupPolicyTypeToString(def->startupPolicy); - virBufferAsprintf(&sourceAttrBuf, " startupPolicy='%s'", policy); - } - if (usbsrc->autoAddress && (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE)) - virBufferAddLit(&sourceAttrBuf, " autoAddress='yes'"); - - if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) - virBufferAddLit(&sourceAttrBuf, " missing='yes'"); - } if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { @@ -26087,15 +26125,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - if (usbsrc->vendor) { - virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor); - virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product); - } - if (usbsrc->bus || usbsrc->device) { - virBufferAsprintf(&sourceChildBuf, "<address %sbus='%d' device='%d'/>\n", - includeTypeInAddr ? "type='usb' " : "", - usbsrc->bus, usbsrc->device); - } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Separate out bits related to USB so that the logic isn't entangled in multiple conditional statements.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 73 +++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Similarly to previous commit split out formatting of the PCI subsystem related stuff. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 74 ++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7718a59c66..d4a2aa7623 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26057,6 +26057,50 @@ virDomainHostdevDefFormatSubsysUSB(virBufferPtr buf, } +static int +virDomainHostdevDefFormatSubsysPCI(virBufferPtr buf, + virDomainHostdevDefPtr def, + unsigned int flags, + bool includeTypeInAddr) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf); + virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; + + if (pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { + const char *backend = virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend); + + if (!backend) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected pci hostdev driver name type %d"), + pcisrc->backend); + return -1; + } + + virBufferAsprintf(buf, "<driver name='%s'/>\n", backend); + } + + virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr); + + if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) { + if (def->origstates.states.pci.unbind_from_stub) + virBufferAddLit(&origstatesChildBuf, "<unbind/>\n"); + + if (def->origstates.states.pci.remove_slot) + virBufferAddLit(&origstatesChildBuf, "<removeslot/>\n"); + + if (def->origstates.states.pci.reprobe) + virBufferAddLit(&origstatesChildBuf, "<reprobe/>\n"); + + virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf); + } + + virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); + return 0; +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def, @@ -26066,8 +26110,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, { g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); - g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf); - virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; @@ -26080,6 +26122,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return 0; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + return virDomainHostdevDefFormatSubsysPCI(buf, def, flags, includeTypeInAddr); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: @@ -26091,20 +26135,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return -1; } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && - pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) { - const char *backend = - virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend); - - if (!backend) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected pci hostdev driver name type %d"), - pcisrc->backend); - return -1; - } - virBufferAsprintf(buf, "<driver name='%s'/>\n", backend); - } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { @@ -26127,18 +26157,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, - includeTypeInAddr); - - if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) { - if (def->origstates.states.pci.unbind_from_stub) - virBufferAddLit(&origstatesChildBuf, "<unbind/>\n"); - if (def->origstates.states.pci.remove_slot) - virBufferAddLit(&origstatesChildBuf, "<removeslot/>\n"); - if (def->origstates.states.pci.reprobe) - virBufferAddLit(&origstatesChildBuf, "<reprobe/>\n"); - virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf); - } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Similarly to previous commit split out formatting of the PCI subsystem related stuff.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 74 ++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 28 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Similarly to previous commit split out formatting of the SCSI subsystem related stuff. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 83 ++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d4a2aa7623..b337bba534 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26101,6 +26101,51 @@ virDomainHostdevDefFormatSubsysPCI(virBufferPtr buf, } +static int +virDomainHostdevDefFormatSubsysSCSI(virBufferPtr buf, + virDomainHostdevDefPtr def, + unsigned int flags, + bool includeTypeInAddr, + virDomainXMLOptionPtr xmlopt) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi; + virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host; + virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; + + if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { + virBufferAsprintf(&sourceAttrBuf, " protocol='%s' name='%s'", + virDomainHostdevSubsysSCSIProtocolTypeToString(scsisrc->protocol), + iscsisrc->src->path); + + virBufferAddLit(&sourceChildBuf, "<host"); + virBufferEscapeString(&sourceChildBuf, " name='%s'", iscsisrc->src->hosts[0].name); + if (iscsisrc->src->hosts[0].port) + virBufferAsprintf(&sourceChildBuf, " port='%u'", iscsisrc->src->hosts[0].port); + virBufferAddLit(&sourceChildBuf, "/>\n"); + + if (virDomainDiskSourceFormatPrivateData(&sourceChildBuf, iscsisrc->src, + flags, xmlopt) < 0) + return -1; + + if (iscsisrc->src->auth) + virStorageAuthDefFormat(&sourceChildBuf, iscsisrc->src->auth); + } else { + virBufferAsprintf(&sourceChildBuf, "<adapter name='%s'/>\n", + scsihostsrc->adapter); + virBufferAsprintf(&sourceChildBuf, + "<address %sbus='%u' target='%u' unit='%llu'/>\n", + includeTypeInAddr ? "type='scsi' " : "", + scsihostsrc->bus, scsihostsrc->target, + scsihostsrc->unit); + } + + virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); + return 0; +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def, @@ -26110,11 +26155,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, { g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); - virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi; virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; - virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host; - virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; switch ((virDomainHostdevSubsysType) def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: @@ -26125,6 +26167,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return virDomainHostdevDefFormatSubsysPCI(buf, def, flags, includeTypeInAddr); case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: + return virDomainHostdevDefFormatSubsysSCSI(buf, def, flags, includeTypeInAddr, xmlopt); + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: break; @@ -26136,15 +26180,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && - scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { - const char *protocol = - virDomainHostdevSubsysSCSIProtocolTypeToString(scsisrc->protocol); - - virBufferAsprintf(&sourceAttrBuf, " protocol='%s' name='%s'", - protocol, iscsisrc->src->path); - } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) { const char *protocol = virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol); @@ -26159,25 +26194,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { - virBufferAddLit(&sourceChildBuf, "<host"); - virBufferEscapeString(&sourceChildBuf, " name='%s'", iscsisrc->src->hosts[0].name); - if (iscsisrc->src->hosts[0].port) - virBufferAsprintf(&sourceChildBuf, " port='%u'", iscsisrc->src->hosts[0].port); - virBufferAddLit(&sourceChildBuf, "/>\n"); - - if (virDomainDiskSourceFormatPrivateData(&sourceChildBuf, iscsisrc->src, - flags, xmlopt) < 0) - return -1; - } else { - virBufferAsprintf(&sourceChildBuf, "<adapter name='%s'/>\n", - scsihostsrc->adapter); - virBufferAsprintf(&sourceChildBuf, - "<address %sbus='%u' target='%u' unit='%llu'/>\n", - includeTypeInAddr ? "type='scsi' " : "", - scsihostsrc->bus, scsihostsrc->target, - scsihostsrc->unit); - } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: break; @@ -26192,11 +26208,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return -1; } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && - scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI && - iscsisrc->src->auth) - virStorageAuthDefFormat(&sourceChildBuf, iscsisrc->src->auth); - virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); return 0; -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Similarly to previous commit split out formatting of the SCSI subsystem related stuff.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 83 ++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 36 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Split up formatting of the '<address>' element rather that trying to optimize it with formatting string hacks. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b337bba534..7b181e0587 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26134,11 +26134,13 @@ virDomainHostdevDefFormatSubsysSCSI(virBufferPtr buf, } else { virBufferAsprintf(&sourceChildBuf, "<adapter name='%s'/>\n", scsihostsrc->adapter); - virBufferAsprintf(&sourceChildBuf, - "<address %sbus='%u' target='%u' unit='%llu'/>\n", - includeTypeInAddr ? "type='scsi' " : "", - scsihostsrc->bus, scsihostsrc->target, - scsihostsrc->unit); + + virBufferAddLit(&sourceChildBuf, "<address"); + if (includeTypeInAddr) + virBufferAddLit(&sourceChildBuf, " type='scsi'"); + virBufferAsprintf(&sourceChildBuf, " bus='%u' target='%u' unit='%llu'", + scsihostsrc->bus, scsihostsrc->target, scsihostsrc->unit); + virBufferAddLit(&sourceChildBuf, "/>\n"); } virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Split up formatting of the '<address>' element rather that trying to optimize it with formatting string hacks.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Similarly to previous commit split out formatting of the vHBA subsystem related stuff. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7b181e0587..facfddeea7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26148,6 +26148,21 @@ virDomainHostdevDefFormatSubsysSCSI(virBufferPtr buf, } +static void +virDomainHostdevDefFormatSubsysSCSIHost(virBufferPtr buf, + virDomainHostdevDefPtr def) +{ + g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; + virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host; + + virBufferAsprintf(&sourceAttrBuf, " protocol='%s' wwpn='%s'", + virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol), + hostsrc->wwpn); + + virXMLFormatElement(buf, "source", &sourceAttrBuf, NULL); +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def, @@ -26155,9 +26170,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, bool includeTypeInAddr, virDomainXMLOptionPtr xmlopt) { - g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); - virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host; virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; switch ((virDomainHostdevSubsysType) def->source.subsys.type) { @@ -26172,6 +26185,9 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return virDomainHostdevDefFormatSubsysSCSI(buf, def, flags, includeTypeInAddr, xmlopt); case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: + virDomainHostdevDefFormatSubsysSCSIHost(buf, def); + return 0; + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: break; @@ -26182,14 +26198,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) { - const char *protocol = - virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol); - - virBufferAsprintf(&sourceAttrBuf, " protocol='%s' wwpn='%s'", - protocol, hostsrc->wwpn); - } - switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: break; @@ -26210,7 +26218,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return -1; } - virXMLFormatElement(buf, "source", &sourceAttrBuf, &sourceChildBuf); + virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); return 0; } -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Similarly to previous commit split out formatting of the vHBA subsystem related stuff.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Similarly to previous commit split out formatting of the mdev subsystem related stuff. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index facfddeea7..e9fee10e31 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26163,6 +26163,19 @@ virDomainHostdevDefFormatSubsysSCSIHost(virBufferPtr buf, } +static void +virDomainHostdevDefFormatSubsysMDEV(virBufferPtr buf, + virDomainHostdevDefPtr def) +{ + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; + + virBufferAsprintf(&sourceChildBuf, "<address uuid='%s'/>\n", mdevsrc->uuidstr); + + virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def, @@ -26170,9 +26183,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, bool includeTypeInAddr, virDomainXMLOptionPtr xmlopt) { - g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); - virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; - switch ((virDomainHostdevSubsysType) def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: virDomainHostdevDefFormatSubsysUSB(buf, def, flags, includeTypeInAddr); @@ -26189,7 +26199,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return 0; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: - break; + virDomainHostdevDefFormatSubsysMDEV(buf, def); + return 0; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: default: @@ -26197,29 +26208,6 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, return -1; } - - switch (def->source.subsys.type) { - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - break; - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - break; - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - break; - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: - break; - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: - virBufferAsprintf(&sourceChildBuf, "<address uuid='%s'/>\n", - mdevsrc->uuidstr); - break; - default: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected hostdev type %d"), - def->source.subsys.type); - return -1; - } - - virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); - return 0; } -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Similarly to previous commit split out formatting of the mdev subsystem related stuff.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index facfddeea7..e9fee10e31 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -26163,6 +26163,19 @@ virDomainHostdevDefFormatSubsysSCSIHost(virBufferPtr buf, }
+static void +virDomainHostdevDefFormatSubsysMDEV(virBufferPtr buf,
Throughout libvirt code base, we capitalize this as 'Mdev'.
+ virDomainHostdevDefPtr def) +{ + g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf); + virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev; + + virBufferAsprintf(&sourceChildBuf, "<address uuid='%s'/>\n", mdevsrc->uuidstr); + + virXMLFormatElement(buf, "source", NULL, &sourceChildBuf); +} + + static int virDomainHostdevDefFormatSubsys(virBufferPtr buf, virDomainHostdevDefPtr def,
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Use a switch statement which will not be omitted when adding potential new types. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e9fee10e31..c8ac4380c4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8392,11 +8392,21 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode, } } - if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) + switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) { + case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE: + return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc); + + case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI: return virDomainHostdevSubsysSCSIiSCSIDefParseXML(sourcenode, scsisrc, ctxt, flags, xmlopt); - return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc); + case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST: + default: + virReportEnumRangeError(virDomainHostdevSCSIProtocolType, scsisrc->protocol); + return -1; + } + + return 0; } static int -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Use a switch statement which will not be omitted when adding potential new types.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Conver the code to the new approach which uses XPath to fetch known elements rather than looping through all XML children. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 51 ++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c8ac4380c4..5988a13986 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8295,9 +8295,12 @@ virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode, virDomainXMLOptionPtr xmlopt) { int auth_secret_usage = -1; - xmlNodePtr cur; virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &def->u.iscsi; g_autoptr(virStorageAuthDef) authdef = NULL; + xmlNodePtr node; + VIR_XPATH_NODE_AUTORESTORE(ctxt); + + ctxt->node = sourcenode; /* For the purposes of command line creation, this needs to look * like a disk storage source */ @@ -8328,42 +8331,26 @@ virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode, return -1; } - cur = sourcenode->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE && - virXMLNodeNameEqual(cur, "auth")) { - if (iscsisrc->src->auth) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("an <auth> definition already found for " - "the <hostdev> iSCSI definition")); - return -1; - } - if (!(authdef = virStorageAuthDefParse(cur, ctxt))) - return -1; - if ((auth_secret_usage = - virSecretUsageTypeFromString(authdef->secrettype)) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("invalid secret type %s"), - authdef->secrettype); - return -1; - } - if (auth_secret_usage != VIR_SECRET_USAGE_TYPE_ISCSI) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("hostdev invalid secret type '%s'"), - authdef->secrettype); - return -1; - } - iscsisrc->src->auth = g_steal_pointer(&authdef); + if ((node = virXPathNode("./auth", ctxt))) { + if (!(authdef = virStorageAuthDefParse(node, ctxt))) + return -1; + if ((auth_secret_usage = virSecretUsageTypeFromString(authdef->secrettype)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid secret type %s"), + authdef->secrettype); + return -1; } - cur = cur->next; + if (auth_secret_usage != VIR_SECRET_USAGE_TYPE_ISCSI) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("hostdev invalid secret type '%s'"), + authdef->secrettype); + return -1; + } + iscsisrc->src->auth = g_steal_pointer(&authdef); } if ((flags & VIR_DOMAIN_DEF_PARSE_STATUS) && xmlopt && xmlopt->privateData.storageParse) { - VIR_XPATH_NODE_AUTORESTORE(ctxt); - - ctxt->node = sourcenode; - if ((ctxt->node = virXPathNode("./privateData", ctxt)) && xmlopt->privateData.storageParse(ctxt, iscsisrc->src) < 0) return -1; -- 2.26.2

On a Tuesday in 2020, Peter Krempa wrote:
Conver the code to the new approach which uses XPath to fetch known elements rather than looping through all XML children.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 51 ++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 32 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain-devices-hostdev.rst.in | 337 ++++++++++++++++++++++ docs/formatdomain-devices.rst.in | 338 +---------------------- 2 files changed, 338 insertions(+), 337 deletions(-) create mode 100644 docs/formatdomain-devices-hostdev.rst.in diff --git a/docs/formatdomain-devices-hostdev.rst.in b/docs/formatdomain-devices-hostdev.rst.in new file mode 100644 index 0000000000..859c4b4ec5 --- /dev/null +++ b/docs/formatdomain-devices-hostdev.rst.in @@ -0,0 +1,337 @@ +:anchor:`<a id="elementsHostDev"/>` + +Host device assignment +~~~~~~~~~~~~~~~~~~~~~~ + +:anchor:`<a id="elementsHostDevSubsys"/>` + +USB / PCI / SCSI devices +^^^^^^^^^^^^^^^^^^^^^^^^ + +USB, PCI and SCSI devices attached to the host can be passed through to the +guest using the ``hostdev`` element. :since:`since after 0.4.4 for USB, 0.6.0 +for PCI (KVM only) and 1.0.6 for SCSI (KVM only)` : + +:: + + ... + <devices> + <hostdev mode='subsystem' type='usb'> + <source startupPolicy='optional'> + <vendor id='0x1234'/> + <product id='0xbeef'/> + </source> + <boot order='2'/> + </hostdev> + </devices> + ... + +or: + +:: + + ... + <devices> + <hostdev mode='subsystem' type='pci' managed='yes'> + <source> + <address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/> + </source> + <boot order='1'/> + <rom bar='on' file='/etc/fake/boot.bin'/> + </hostdev> + </devices> + ... + +or: + +:: + + ... + <devices> + <hostdev mode='subsystem' type='scsi' sgio='filtered' rawio='yes'> + <source> + <adapter name='scsi_host0'/> + <address bus='0' target='0' unit='0'/> + </source> + <readonly/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </hostdev> + </devices> + ... + +or: + +:: + + ... + <devices> + <hostdev mode='subsystem' type='scsi'> + <source protocol='iscsi' name='iqn.2014-08.com.example:iscsi-nopool/1'> + <host name='example.com' port='3260'/> + <auth username='myuser'> + <secret type='iscsi' usage='libvirtiscsi'/> + </auth> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </hostdev> + </devices> + ... + +or: + +:: + + ... + <devices> + <hostdev mode='subsystem' type='scsi_host'> + <source protocol='vhost' wwpn='naa.50014057667280d8'/> + </hostdev> + </devices> + ... + +or: + +:: + + ... + <devices> + <hostdev mode='subsystem' type='mdev' model='vfio-pci'> + <source> + <address uuid='c2177883-f1bb-47f0-914d-32a22e3a8804'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='mdev' model='vfio-ccw'> + <source> + <address uuid='9063cba3-ecef-47b6-abcf-3fef4fdcad85'/> + </source> + <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/> + </hostdev> + </devices> + ... + +``hostdev`` + The ``hostdev`` element is the main container for describing host devices. + For each device, the ``mode`` is always "subsystem" and the ``type`` is one + of the following values with additional attributes noted. + + ``usb`` + USB devices are detached from the host on guest startup and reattached + after the guest exits or the device is hot-unplugged. + ``pci`` + For PCI devices, when ``managed`` is "yes" it is detached from the host + before being passed on to the guest and reattached to the host after the + guest exits. If ``managed`` is omitted or "no", the user is responsible to + call ``virNodeDeviceDetachFlags`` (or ``virsh nodedev-detach`` before + starting the guest or hot-plugging the device and + ``virNodeDeviceReAttach`` (or ``virsh nodedev-reattach``) after hot-unplug + or stopping the guest. + ``scsi`` + For SCSI devices, user is responsible to make sure the device is not used + by host. If supported by the hypervisor and OS, the optional ``sgio`` ( + :since:`since 1.0.6` ) attribute indicates whether unprivileged SG_IO + commands are filtered for the disk. Valid settings are "filtered" or + "unfiltered", where the default is "filtered". The optional ``rawio`` ( + :since:`since 1.2.9` ) attribute indicates whether the lun needs the rawio + capability. Valid settings are "yes" or "no". See the rawio description + within the `disk <#elementsDisks>`__ section. If a disk lun in the domain + already has the rawio capability, then this setting not required. + ``scsi_host`` + :since:`since 2.5.0` For SCSI devices, user is responsible to make sure + the device is not used by host. This ``type`` passes all LUNs presented by + a single HBA to the guest. :since:`Since 5.2.0,` the ``model`` attribute + can be specified further with "virtio-transitional", + "virtio-non-transitional", or "virtio". See `Virtio transitional + devices <#elementsVirtioTransitional>`__ for more details. + ``mdev`` + For mediated devices ( :since:`Since 3.2.0` ) the ``model`` attribute + specifies the device API which determines how the host's vfio driver will + expose the device to the guest. Currently, ``model='vfio-pci'``, + ``model='vfio-ccw'`` ( :since:`Since 4.4.0` ) and ``model='vfio-ap'`` ( + :since:`Since 4.9.0` ) is supported. `MDEV <drvnodedev.html#MDEV>`__ + section provides more information about mediated devices as well as how to + create mediated devices on the host. :since:`Since 4.6.0 (QEMU 2.12)` an + optional ``display`` attribute may be used to enable or disable support + for an accelerated remote desktop backed by a mediated device (such as + NVIDIA vGPU or Intel GVT-g) as an alternative to emulated `video + devices <#elementsVideo>`__. This attribute is limited to + ``model='vfio-pci'`` only. Supported values are either ``on`` or ``off`` + (default is 'off'). It is required to use a `graphical + framebuffer <#elementsGraphics>`__ in order to use this attribute, + currently only supported with VNC, Spice and egl-headless graphics + devices. :since:`Since version 5.10.0` , there is an optional ``ramfb`` + attribute for devices with ``model='vfio-pci'``. Supported values are + either ``on`` or ``off`` (default is 'off'). When enabled, this attribute + provides a memory framebuffer device to the guest. This framebuffer will + be used as a boot display when a vgpu device is the primary display. + + Note: There are also some implications on the usage of guest's address + type depending on the ``model`` attribute, see the ``address`` element + below. + + Note: The ``managed`` attribute is only used with ``type='pci'`` and is + ignored by all the other device types, thus setting ``managed`` explicitly + with other than a PCI device has the same effect as omitting it. Similarly, + ``model`` attribute is only supported by mediated devices and ignored by all + other device types. + +``source`` + The source element describes the device as seen from the host using the + following mechanism to describe: + + ``usb`` + The USB device can either be addressed by vendor / product id using the + ``vendor`` and ``product`` elements or by the device's address on the host + using the ``address`` element. + + :since:`Since 1.0.0` , the ``source`` element of USB devices may contain + ``startupPolicy`` attribute which can be used to define policy what to do + if the specified host USB device is not found. The attribute accepts the + following values: + + ========= ===================================================================== + mandatory fail if missing for any reason (the default) + requisite fail if missing on boot up, drop if missing on migrate/restore/revert + optional drop if missing at any start attempt + ========= ===================================================================== + + ``pci`` + PCI devices can only be described by their ``address``. + ``scsi`` + SCSI devices are described by both the ``adapter`` and ``address`` + elements. The ``address`` element includes a ``bus`` attribute (a 2-digit + bus number), a ``target`` attribute (a 10-digit target number), and a + ``unit`` attribute (a 20-digit unit number on the bus). Not all + hypervisors support larger ``target`` and ``unit`` values. It is up to + each hypervisor to determine the maximum value supported for the adapter. + + :since:`Since 1.2.8` , the ``source`` element of a SCSI device may contain + the ``protocol`` attribute. When the attribute is set to "iscsi", the host + device XML follows the network `disk <#elementsDisks>`__ device using the + same ``name`` attribute and optionally using the ``auth`` element to + provide the authentication credentials to the iSCSI server. + + ``scsi_host`` + :since:`Since 2.5.0` , multiple LUNs behind a single SCSI HBA are + described by a ``protocol`` attribute set to "vhost" and a ``wwpn`` + attribute that is the vhost_scsi wwpn (16 hexadecimal digits with a prefix + of "naa.") established in the host configfs. + ``mdev`` + Mediated devices ( :since:`Since 3.2.0` ) are described by the ``address`` + element. The ``address`` element contains a single mandatory attribute + ``uuid``. + +``vendor``, ``product`` + The ``vendor`` and ``product`` elements each have an ``id`` attribute that + specifies the USB vendor and product id. The ids can be given in decimal, + hexadecimal (starting with 0x) or octal (starting with 0) form. +``boot`` + Specifies that the device is bootable. The ``order`` attribute determines the + order in which devices will be tried during boot sequence. The per-device + ``boot`` elements cannot be used together with general boot elements in `BIOS + bootloader <#elementsOSBIOS>`__ section. :since:`Since 0.8.8` for PCI + devices, :since:`Since 1.0.1` for USB devices. +``rom`` + The ``rom`` element is used to change how a PCI device's ROM is presented to + the guest. The optional ``bar`` attribute can be set to "on" or "off", and + determines whether or not the device's ROM will be visible in the guest's + memory map. (In PCI documentation, the "rombar" setting controls the presence + of the Base Address Register for the ROM). If no rom bar is specified, the + qemu default will be used (older versions of qemu used a default of "off", + while newer qemus have a default of "on"). :since:`Since 0.9.7 (QEMU and KVM + only)` . The optional ``file`` attribute contains an absolute path to a + binary file to be presented to the guest as the device's ROM BIOS. This can + be useful, for example, to provide a PXE boot ROM for a virtual function of + an sr-iov capable ethernet device (which has no boot ROMs for the VFs). + :since:`Since 0.9.10 (QEMU and KVM only)` . The optional ``enabled`` + attribute can be set to ``no`` to disable PCI ROM loading completely for the + device; if PCI ROM loading is disabled through this attribute, attempts to + tweak the loading process further using the ``bar`` or ``file`` attributes + will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)` . +``address`` + The ``address`` element for USB devices has a ``bus`` and ``device`` + attribute to specify the USB bus and device number the device appears at on + the host. The values of these attributes can be given in decimal, hexadecimal + (starting with 0x) or octal (starting with 0) form. For PCI devices the + element carries 4 attributes allowing to designate the device as can be found + with the ``lspci`` or with ``virsh nodedev-list``. For SCSI devices a 'drive' + address type must be used. For mediated devices, which are software-only + devices defining an allocation of resources on the physical parent device, + the address type used must conform to the ``model`` attribute of element + ``hostdev``, e.g. any address type other than PCI for ``vfio-pci`` device API + or any address type other than CCW for ``vfio-ccw`` device API will result in + an error. `See above <#elementsAddress>`__ for more details on the address + element. +``driver`` + PCI devices can have an optional ``driver`` subelement that specifies which + backend driver to use for PCI device assignment. Use the ``name`` attribute + to select either "vfio" (for the new VFIO device assignment backend, which is + compatible with UEFI SecureBoot) or "kvm" (the legacy device assignment + handled directly by the KVM kernel module) :since:`Since 1.0.5 (QEMU and KVM + only, requires kernel 3.6 or newer)` . When specified, device assignment will + fail if the requested method of device assignment isn't available on the + host. When not specified, the default is "vfio" on systems where the VFIO + driver is available and loaded, and "kvm" on older systems, or those where + the VFIO driver hasn't been loaded :since:`Since 1.1.3` (prior to that the + default was always "kvm"). +``readonly`` + Indicates that the device is readonly, only supported by SCSI host device + now. :since:`Since 1.0.6 (QEMU and KVM only)` +``shareable`` + If present, this indicates the device is expected to be shared between + domains (assuming the hypervisor and OS support this). Only supported by SCSI + host device. :since:`Since 1.0.6` + + Note: Although ``shareable`` was introduced :since:`in 1.0.6` , it did not + work as as expected until :since:`1.2.2` . + +:anchor:`<a id="elementsHostDevCaps"/>` + +Block / character devices +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Block / character devices from the host can be passed through to the guest using +the ``hostdev`` element. This is only possible with container based +virtualization. Devices are specified by a fully qualified path. :since:`since +after 1.0.1 for LXC` : + +:: + + ... + <hostdev mode='capabilities' type='storage'> + <source> + <block>/dev/sdf1</block> + </source> + </hostdev> + ... + +:: + + ... + <hostdev mode='capabilities' type='misc'> + <source> + <char>/dev/input/event3</char> + </source> + </hostdev> + ... + +:: + + ... + <hostdev mode='capabilities' type='net'> + <source> + <interface>eth0</interface> + </source> + </hostdev> + ... + +``hostdev`` + The ``hostdev`` element is the main container for describing host devices. + For block/character device passthrough ``mode`` is always "capabilities" and + ``type`` is "storage" for a block device, "misc" for a character device and + "net" for a host network interface. +``source`` + The source element describes the device as seen from the host. For block + devices, the path to the block device in the host OS is provided in the + nested "block" element, while for character devices the "char" element is + used. For network interfaces, the name of the interface is provided in the + "interface" element. diff --git a/docs/formatdomain-devices.rst.in b/docs/formatdomain-devices.rst.in index c7cc190918..ad24410ecb 100644 --- a/docs/formatdomain-devices.rst.in +++ b/docs/formatdomain-devices.rst.in @@ -706,343 +706,7 @@ acquired. The offset specifies where the lease is stored within the file. If the lock manager does not require an offset, just pass 0. -:anchor:`<a id="elementsHostDev"/>` - -Host device assignment -~~~~~~~~~~~~~~~~~~~~~~ - -:anchor:`<a id="elementsHostDevSubsys"/>` - -USB / PCI / SCSI devices -^^^^^^^^^^^^^^^^^^^^^^^^ - -USB, PCI and SCSI devices attached to the host can be passed through to the -guest using the ``hostdev`` element. :since:`since after 0.4.4 for USB, 0.6.0 -for PCI (KVM only) and 1.0.6 for SCSI (KVM only)` : - -:: - - ... - <devices> - <hostdev mode='subsystem' type='usb'> - <source startupPolicy='optional'> - <vendor id='0x1234'/> - <product id='0xbeef'/> - </source> - <boot order='2'/> - </hostdev> - </devices> - ... - -or: - -:: - - ... - <devices> - <hostdev mode='subsystem' type='pci' managed='yes'> - <source> - <address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/> - </source> - <boot order='1'/> - <rom bar='on' file='/etc/fake/boot.bin'/> - </hostdev> - </devices> - ... - -or: - -:: - - ... - <devices> - <hostdev mode='subsystem' type='scsi' sgio='filtered' rawio='yes'> - <source> - <adapter name='scsi_host0'/> - <address bus='0' target='0' unit='0'/> - </source> - <readonly/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </hostdev> - </devices> - ... - -or: - -:: - - ... - <devices> - <hostdev mode='subsystem' type='scsi'> - <source protocol='iscsi' name='iqn.2014-08.com.example:iscsi-nopool/1'> - <host name='example.com' port='3260'/> - <auth username='myuser'> - <secret type='iscsi' usage='libvirtiscsi'/> - </auth> - </source> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </hostdev> - </devices> - ... - -or: - -:: - - ... - <devices> - <hostdev mode='subsystem' type='scsi_host'> - <source protocol='vhost' wwpn='naa.50014057667280d8'/> - </hostdev> - </devices> - ... - -or: - -:: - - ... - <devices> - <hostdev mode='subsystem' type='mdev' model='vfio-pci'> - <source> - <address uuid='c2177883-f1bb-47f0-914d-32a22e3a8804'/> - </source> - </hostdev> - <hostdev mode='subsystem' type='mdev' model='vfio-ccw'> - <source> - <address uuid='9063cba3-ecef-47b6-abcf-3fef4fdcad85'/> - </source> - <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/> - </hostdev> - </devices> - ... - -``hostdev`` - The ``hostdev`` element is the main container for describing host devices. - For each device, the ``mode`` is always "subsystem" and the ``type`` is one - of the following values with additional attributes noted. - - ``usb`` - USB devices are detached from the host on guest startup and reattached - after the guest exits or the device is hot-unplugged. - ``pci`` - For PCI devices, when ``managed`` is "yes" it is detached from the host - before being passed on to the guest and reattached to the host after the - guest exits. If ``managed`` is omitted or "no", the user is responsible to - call ``virNodeDeviceDetachFlags`` (or ``virsh nodedev-detach`` before - starting the guest or hot-plugging the device and - ``virNodeDeviceReAttach`` (or ``virsh nodedev-reattach``) after hot-unplug - or stopping the guest. - ``scsi`` - For SCSI devices, user is responsible to make sure the device is not used - by host. If supported by the hypervisor and OS, the optional ``sgio`` ( - :since:`since 1.0.6` ) attribute indicates whether unprivileged SG_IO - commands are filtered for the disk. Valid settings are "filtered" or - "unfiltered", where the default is "filtered". The optional ``rawio`` ( - :since:`since 1.2.9` ) attribute indicates whether the lun needs the rawio - capability. Valid settings are "yes" or "no". See the rawio description - within the `disk <#elementsDisks>`__ section. If a disk lun in the domain - already has the rawio capability, then this setting not required. - ``scsi_host`` - :since:`since 2.5.0` For SCSI devices, user is responsible to make sure - the device is not used by host. This ``type`` passes all LUNs presented by - a single HBA to the guest. :since:`Since 5.2.0,` the ``model`` attribute - can be specified further with "virtio-transitional", - "virtio-non-transitional", or "virtio". See `Virtio transitional - devices <#elementsVirtioTransitional>`__ for more details. - ``mdev`` - For mediated devices ( :since:`Since 3.2.0` ) the ``model`` attribute - specifies the device API which determines how the host's vfio driver will - expose the device to the guest. Currently, ``model='vfio-pci'``, - ``model='vfio-ccw'`` ( :since:`Since 4.4.0` ) and ``model='vfio-ap'`` ( - :since:`Since 4.9.0` ) is supported. `MDEV <drvnodedev.html#MDEV>`__ - section provides more information about mediated devices as well as how to - create mediated devices on the host. :since:`Since 4.6.0 (QEMU 2.12)` an - optional ``display`` attribute may be used to enable or disable support - for an accelerated remote desktop backed by a mediated device (such as - NVIDIA vGPU or Intel GVT-g) as an alternative to emulated `video - devices <#elementsVideo>`__. This attribute is limited to - ``model='vfio-pci'`` only. Supported values are either ``on`` or ``off`` - (default is 'off'). It is required to use a `graphical - framebuffer <#elementsGraphics>`__ in order to use this attribute, - currently only supported with VNC, Spice and egl-headless graphics - devices. :since:`Since version 5.10.0` , there is an optional ``ramfb`` - attribute for devices with ``model='vfio-pci'``. Supported values are - either ``on`` or ``off`` (default is 'off'). When enabled, this attribute - provides a memory framebuffer device to the guest. This framebuffer will - be used as a boot display when a vgpu device is the primary display. - - Note: There are also some implications on the usage of guest's address - type depending on the ``model`` attribute, see the ``address`` element - below. - - Note: The ``managed`` attribute is only used with ``type='pci'`` and is - ignored by all the other device types, thus setting ``managed`` explicitly - with other than a PCI device has the same effect as omitting it. Similarly, - ``model`` attribute is only supported by mediated devices and ignored by all - other device types. - -``source`` - The source element describes the device as seen from the host using the - following mechanism to describe: - - ``usb`` - The USB device can either be addressed by vendor / product id using the - ``vendor`` and ``product`` elements or by the device's address on the host - using the ``address`` element. - - :since:`Since 1.0.0` , the ``source`` element of USB devices may contain - ``startupPolicy`` attribute which can be used to define policy what to do - if the specified host USB device is not found. The attribute accepts the - following values: - - ========= ===================================================================== - mandatory fail if missing for any reason (the default) - requisite fail if missing on boot up, drop if missing on migrate/restore/revert - optional drop if missing at any start attempt - ========= ===================================================================== - - ``pci`` - PCI devices can only be described by their ``address``. - ``scsi`` - SCSI devices are described by both the ``adapter`` and ``address`` - elements. The ``address`` element includes a ``bus`` attribute (a 2-digit - bus number), a ``target`` attribute (a 10-digit target number), and a - ``unit`` attribute (a 20-digit unit number on the bus). Not all - hypervisors support larger ``target`` and ``unit`` values. It is up to - each hypervisor to determine the maximum value supported for the adapter. - - :since:`Since 1.2.8` , the ``source`` element of a SCSI device may contain - the ``protocol`` attribute. When the attribute is set to "iscsi", the host - device XML follows the network `disk <#elementsDisks>`__ device using the - same ``name`` attribute and optionally using the ``auth`` element to - provide the authentication credentials to the iSCSI server. - - ``scsi_host`` - :since:`Since 2.5.0` , multiple LUNs behind a single SCSI HBA are - described by a ``protocol`` attribute set to "vhost" and a ``wwpn`` - attribute that is the vhost_scsi wwpn (16 hexadecimal digits with a prefix - of "naa.") established in the host configfs. - ``mdev`` - Mediated devices ( :since:`Since 3.2.0` ) are described by the ``address`` - element. The ``address`` element contains a single mandatory attribute - ``uuid``. - -``vendor``, ``product`` - The ``vendor`` and ``product`` elements each have an ``id`` attribute that - specifies the USB vendor and product id. The ids can be given in decimal, - hexadecimal (starting with 0x) or octal (starting with 0) form. -``boot`` - Specifies that the device is bootable. The ``order`` attribute determines the - order in which devices will be tried during boot sequence. The per-device - ``boot`` elements cannot be used together with general boot elements in `BIOS - bootloader <#elementsOSBIOS>`__ section. :since:`Since 0.8.8` for PCI - devices, :since:`Since 1.0.1` for USB devices. -``rom`` - The ``rom`` element is used to change how a PCI device's ROM is presented to - the guest. The optional ``bar`` attribute can be set to "on" or "off", and - determines whether or not the device's ROM will be visible in the guest's - memory map. (In PCI documentation, the "rombar" setting controls the presence - of the Base Address Register for the ROM). If no rom bar is specified, the - qemu default will be used (older versions of qemu used a default of "off", - while newer qemus have a default of "on"). :since:`Since 0.9.7 (QEMU and KVM - only)` . The optional ``file`` attribute contains an absolute path to a - binary file to be presented to the guest as the device's ROM BIOS. This can - be useful, for example, to provide a PXE boot ROM for a virtual function of - an sr-iov capable ethernet device (which has no boot ROMs for the VFs). - :since:`Since 0.9.10 (QEMU and KVM only)` . The optional ``enabled`` - attribute can be set to ``no`` to disable PCI ROM loading completely for the - device; if PCI ROM loading is disabled through this attribute, attempts to - tweak the loading process further using the ``bar`` or ``file`` attributes - will be rejected. :since:`Since 4.3.0 (QEMU and KVM only)` . -``address`` - The ``address`` element for USB devices has a ``bus`` and ``device`` - attribute to specify the USB bus and device number the device appears at on - the host. The values of these attributes can be given in decimal, hexadecimal - (starting with 0x) or octal (starting with 0) form. For PCI devices the - element carries 4 attributes allowing to designate the device as can be found - with the ``lspci`` or with ``virsh nodedev-list``. For SCSI devices a 'drive' - address type must be used. For mediated devices, which are software-only - devices defining an allocation of resources on the physical parent device, - the address type used must conform to the ``model`` attribute of element - ``hostdev``, e.g. any address type other than PCI for ``vfio-pci`` device API - or any address type other than CCW for ``vfio-ccw`` device API will result in - an error. `See above <#elementsAddress>`__ for more details on the address - element. -``driver`` - PCI devices can have an optional ``driver`` subelement that specifies which - backend driver to use for PCI device assignment. Use the ``name`` attribute - to select either "vfio" (for the new VFIO device assignment backend, which is - compatible with UEFI SecureBoot) or "kvm" (the legacy device assignment - handled directly by the KVM kernel module) :since:`Since 1.0.5 (QEMU and KVM - only, requires kernel 3.6 or newer)` . When specified, device assignment will - fail if the requested method of device assignment isn't available on the - host. When not specified, the default is "vfio" on systems where the VFIO - driver is available and loaded, and "kvm" on older systems, or those where - the VFIO driver hasn't been loaded :since:`Since 1.1.3` (prior to that the - default was always "kvm"). -``readonly`` - Indicates that the device is readonly, only supported by SCSI host device - now. :since:`Since 1.0.6 (QEMU and KVM only)` -``shareable`` - If present, this indicates the device is expected to be shared between - domains (assuming the hypervisor and OS support this). Only supported by SCSI - host device. :since:`Since 1.0.6` - - Note: Although ``shareable`` was introduced :since:`in 1.0.6` , it did not - work as as expected until :since:`1.2.2` . - -:anchor:`<a id="elementsHostDevCaps"/>` - -Block / character devices -^^^^^^^^^^^^^^^^^^^^^^^^^ - -Block / character devices from the host can be passed through to the guest using -the ``hostdev`` element. This is only possible with container based -virtualization. Devices are specified by a fully qualified path. :since:`since -after 1.0.1 for LXC` : - -:: - - ... - <hostdev mode='capabilities' type='storage'> - <source> - <block>/dev/sdf1</block> - </source> - </hostdev> - ... - -:: - - ... - <hostdev mode='capabilities' type='misc'> - <source> - <char>/dev/input/event3</char> - </source> - </hostdev> - ... - -:: - - ... - <hostdev mode='capabilities' type='net'> - <source> - <interface>eth0</interface> - </source> - </hostdev> - ... - -``hostdev`` - The ``hostdev`` element is the main container for describing host devices. - For block/character device passthrough ``mode`` is always "capabilities" and - ``type`` is "storage" for a block device, "misc" for a character device and - "net" for a host network interface. -``source`` - The source element describes the device as seen from the host. For block - devices, the path to the block device in the host OS is provided in the - nested "block" element, while for character devices the "char" element is - used. For network interfaces, the name of the interface is provided in the - "interface" element. +.. include:: formatdomain-devices-hostdev.rst.in :anchor:`<a id="elementsRedir"/>` -- 2.26.2

We already allow controlling the initiator IQN for iSCSI based disks. Add the same for host devices. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain-devices-hostdev.rst.in | 7 +++++++ docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_conf.c | 5 +++++ .../hostdev-scsi-virtio-scsi.x86_64-4.1.0.args | 3 ++- .../hostdev-scsi-virtio-scsi.x86_64-latest.args | 1 + tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml | 3 +++ tests/qemuxml2xmloutdata/hostdev-scsi-virtio-scsi.xml | 3 +++ 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain-devices-hostdev.rst.in b/docs/formatdomain-devices-hostdev.rst.in index 859c4b4ec5..1221627818 100644 --- a/docs/formatdomain-devices-hostdev.rst.in +++ b/docs/formatdomain-devices-hostdev.rst.in @@ -68,6 +68,9 @@ or: <hostdev mode='subsystem' type='scsi'> <source protocol='iscsi' name='iqn.2014-08.com.example:iscsi-nopool/1'> <host name='example.com' port='3260'/> + <initiator> + <iqn name='iqn.2020-07.com.example:test'/> + </initiator> <auth username='myuser'> <secret type='iscsi' usage='libvirtiscsi'/> </auth> @@ -210,6 +213,10 @@ or: same ``name`` attribute and optionally using the ``auth`` element to provide the authentication credentials to the iSCSI server. + :since:`Since 6.6.0`, the optional ``initiator`` sub-element controls the + IQN of the initiator ran by the hypervisor via it's ``<iqn name='iqn...'`` + subelement. + ``scsi_host`` :since:`Since 2.5.0` , multiple LUNs behind a single SCSI HBA are described by a ``protocol`` attribute set to "vhost" and a ``wwpn`` diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index a810f569c6..815793138e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5045,6 +5045,9 @@ <optional> <ref name='diskAuth'/> </optional> + <optional> + <ref name="initiatorinfo"/> + </optional> </interleave> </group> </choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5988a13986..5c23a52031 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8349,6 +8349,8 @@ virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode, iscsisrc->src->auth = g_steal_pointer(&authdef); } + virStorageSourceInitiatorParseXML(ctxt, &iscsisrc->src->initiator); + if ((flags & VIR_DOMAIN_DEF_PARSE_STATUS) && xmlopt && xmlopt->privateData.storageParse) { if ((ctxt->node = virXPathNode("./privateData", ctxt)) && @@ -26128,6 +26130,9 @@ virDomainHostdevDefFormatSubsysSCSI(virBufferPtr buf, if (iscsisrc->src->auth) virStorageAuthDefFormat(&sourceChildBuf, iscsisrc->src->auth); + + virStorageSourceInitiatorFormatXML(&iscsisrc->src->initiator, + &sourceChildBuf); } else { virBufferAsprintf(&sourceChildBuf, "<adapter name='%s'/>\n", scsihostsrc->adapter); diff --git a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-4.1.0.args b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-4.1.0.args index de4047000e..f2591d6956 100644 --- a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-4.1.0.args +++ b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-4.1.0.args @@ -60,7 +60,8 @@ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \ -drive file.driver=iscsi,file.portal=example.org:3260,\ file.target=iqn.1992-01.com.example:storage,file.lun=2,file.transport=tcp,\ -file.user=myname,file.password-secret=hostdev5-secret0,if=none,format=raw,\ +file.user=myname,file.password-secret=hostdev5-secret0,\ +file.initiator-name=iqn.2020-07.com.example:test,if=none,format=raw,\ id=drive-hostdev5 \ -device scsi-generic,bus=scsi0.0,channel=0,scsi-id=3,lun=5,\ drive=drive-hostdev5,id=hostdev5 \ diff --git a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-latest.args b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-latest.args index 72980d58b8..f86cbd7314 100644 --- a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-latest.args +++ b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.x86_64-latest.args @@ -67,6 +67,7 @@ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \ -blockdev '{"driver":"iscsi","portal":"example.org:3260",\ "target":"iqn.1992-01.com.example:storage","lun":2,"transport":"tcp",\ "user":"myname","password-secret":"hostdev5-secret0",\ +"initiator-name":"iqn.2020-07.com.example:test",\ "node-name":"libvirt-hostdev5-backend","read-only":false}' \ -device scsi-generic,bus=scsi0.0,channel=0,scsi-id=3,lun=5,\ drive=libvirt-hostdev5-backend,id=hostdev5 \ diff --git a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml index 775b678b36..f1caf80644 100644 --- a/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml +++ b/tests/qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml @@ -67,6 +67,9 @@ <auth username='myname'> <secret type='iscsi' usage='mycluster_myname'/> </auth> + <initiator> + <iqn name='iqn.2020-07.com.example:test'/> + </initiator> </source> <address type='drive' controller='0' bus='0' target='3' unit='5'/> </hostdev> diff --git a/tests/qemuxml2xmloutdata/hostdev-scsi-virtio-scsi.xml b/tests/qemuxml2xmloutdata/hostdev-scsi-virtio-scsi.xml index 9c823809ab..6c7e22d0c3 100644 --- a/tests/qemuxml2xmloutdata/hostdev-scsi-virtio-scsi.xml +++ b/tests/qemuxml2xmloutdata/hostdev-scsi-virtio-scsi.xml @@ -74,6 +74,9 @@ <auth username='myname'> <secret type='iscsi' usage='mycluster_myname'/> </auth> + <initiator> + <iqn name='iqn.2020-07.com.example:test'/> + </initiator> </source> <address type='drive' controller='0' bus='0' target='3' unit='5'/> </hostdev> -- 2.26.2
participants (2)
-
Ján Tomko
-
Peter Krempa