[libvirt] [PATCH v3] conf: Generate address for scsi host device automatically

With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress). Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead. --- v2 - v3: * Improve the for loop a bit with John's suggestion v1 - v2: * A new helper virDomainSCSIDriveAddressIsUsed * Move virDomainDefMaybeAddHostdevSCSIcontroller * More comments * Add testing. * problems fixed with the testing: 1) s/nscsi_controllers + 1/nscsi_controllers/, 2) Add the controller implicitly after a scsi hostdev def parsing, as it can use a new scsi controller index (nscsi_controllers), which should be added implicitly. --- src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b4e160..46d49a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3782,6 +3782,141 @@ cleanup: return ret; } +/* Check if a drive type address $controller:0:0:$unit is already + * taken by a disk or not. + */ +static bool +virDomainDriveAddressIsUsedByDisk(virDomainDefPtr def, + enum virDomainDiskBus type, + unsigned int controller, + unsigned int unit) +{ + virDomainDiskDefPtr disk; + int i; + + for (i = 0; i < def->ndisks; i++) { + disk = def->disks[i]; + + if (disk->bus != type || + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + continue; + + if (disk->info.addr.drive.controller == controller && + disk->info.addr.drive.unit == unit && + disk->info.addr.drive.bus == 0 && + disk->info.addr.drive.target == 0) + return true; + } + + return false; +} + +/* Check if a drive type address $controller:0:0:$unit is already + * taken by a host device or not. + */ +static bool +virDomainDriveAddressIsUsedByHostdev(virDomainDefPtr def, + enum virDomainHostdevSubsysType type, + unsigned int controller, + unsigned int unit) +{ + virDomainHostdevDefPtr hostdev; + int i; + + for (i = 0; i < def->nhostdevs; i++) { + hostdev = def->hostdevs[i]; + + if (hostdev->source.subsys.type != type) + continue; + + if (hostdev->info->addr.drive.controller == controller && + hostdev->info->addr.drive.unit == unit && + hostdev->info->addr.drive.bus == 0 && + hostdev->info->addr.drive.target == 0) + return true; + } + + return false; +} + +static bool +virDomainSCSIDriveAddressIsUsed(virDomainDefPtr def, + unsigned int controller, + unsigned int unit) +{ + /* In current implementation, the maximum unit number of a controller + * is either 16 or 7 (narrow SCSI bus), and if the maximum unit number + * is 16, the controller itself is on unit 7 */ + if (unit == 7) + return true; + + if (virDomainDriveAddressIsUsedByDisk(def, VIR_DOMAIN_DISK_BUS_SCSI, + controller, unit) || + virDomainDriveAddressIsUsedByHostdev(def, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI, + controller, unit)) + return true; + + return false; +} + +/* Find out the next usable "unit" of a specific controller */ +static int +virDomainControllerSCSINextUnit(virDomainDefPtr def, + unsigned int max_unit, + unsigned int controller) +{ + int i; + + for (i = 0; i < max_unit; i++) { + if (!virDomainSCSIDriveAddressIsUsed(def, controller, i)) + return i; + } + + return -1; +} + +#define SCSI_WIDE_BUS_MAX_CONT_UNIT 16 +#define SCSI_NARROW_BUS_MAX_CONT_UNIT 7 + +static int +virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr def, + virDomainHostdevDefPtr hostdev) +{ + int next_unit; + unsigned nscsi_controllers = 0; + bool found = false; + int i; + + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) + return -1; + + for (i = 0; i < def->ncontrollers && !found; i++) { + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + nscsi_controllers++; + next_unit = virDomainControllerSCSINextUnit(def, + xmlopt->config.hasWideScsiBus ? + SCSI_WIDE_BUS_MAX_CONT_UNIT : + SCSI_NARROW_BUS_MAX_CONT_UNIT, + def->controllers[i]->idx); + if (next_unit >= 0) + found = true; + } + + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + + hostdev->info->addr.drive.controller = found ? + def->controllers[i - 1]->idx : + nscsi_controllers; + hostdev->info->addr.drive.bus = 0; + hostdev->info->addr.drive.target = 0; + hostdev->info->addr.drive.unit = found ? next_unit : 0; + + return 0; +} + static int virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, xmlXPathContextPtr ctxt, @@ -8802,7 +8937,9 @@ error: } static virDomainHostdevDefPtr -virDomainHostdevDefParseXML(const xmlNodePtr node, +virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr vmdef, + const xmlNodePtr node, xmlXPathContextPtr ctxt, virHashTablePtr bootHash, unsigned int flags) @@ -8862,7 +8999,9 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + virDomainHostdevAssignAddress(xmlopt, vmdef, def) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", _("SCSI host devices must have address specified")); goto error; @@ -9271,8 +9410,8 @@ virDomainDeviceDefParse(const char *xmlStr, goto error; } else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) { dev->type = VIR_DOMAIN_DEVICE_HOSTDEV; - if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, ctxt, NULL, - flags))) + if (!(dev->data.hostdev = virDomainHostdevDefParseXML(xmlopt, def, node, + ctxt, NULL, flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "controller")) { dev->type = VIR_DOMAIN_DEVICE_CONTROLLER; @@ -10255,6 +10394,30 @@ error: return NULL; } +static int +virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def) +{ + /* Look for any hostdev scsi dev */ + int i; + int maxController = -1; + virDomainHostdevDefPtr hostdev; + + for (i = 0; i < def->nhostdevs; i++) { + hostdev = def->hostdevs[i]; + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && + (int)hostdev->info->addr.drive.controller > maxController) { + maxController = hostdev->info->addr.drive.controller; + } + } + + for (i = 0; i <= maxController; i++) { + if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0) + return -1; + } + + return 0; +} static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, @@ -11618,7 +11781,8 @@ virDomainDefParseXML(xmlDocPtr xml, for (i = 0; i < n; i++) { virDomainHostdevDefPtr hostdev; - hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags); + hostdev = virDomainHostdevDefParseXML(xmlopt, def, nodes[i], + ctxt, bootHash, flags); if (!hostdev) goto error; @@ -11631,6 +11795,9 @@ virDomainDefParseXML(xmlDocPtr xml, } def->hostdevs[def->nhostdevs++] = hostdev; + + if (virDomainDefMaybeAddHostdevSCSIcontroller(def) < 0) + goto error; } VIR_FREE(nodes); @@ -13232,31 +13399,6 @@ virDomainDefMaybeAddSmartcardController(virDomainDefPtr def) return 0; } -static int -virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def) -{ - /* Look for any hostdev scsi dev */ - int i; - int maxController = -1; - virDomainHostdevDefPtr hostdev; - - for (i = 0; i < def->nhostdevs; i++) { - hostdev = def->hostdevs[i]; - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && - (int)hostdev->info->addr.drive.controller > maxController) { - maxController = hostdev->info->addr.drive.controller; - } - } - - for (i = 0; i <= maxController; i++) { - if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0) - return -1; - } - - return 0; -} - /* * Based on the declared <address/> info for any devices, * add necessary drive controllers which are not already present diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml new file mode 100644 index 0000000..21f112b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml @@ -0,0 +1,95 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='scsi' index='0' model='virtio-scsi'/> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host0'/> + <address bus='0' target='0' unit='0'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host1'/> + <address bus='0' target='0' unit='1'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host2'/> + <address bus='0' target='0' unit='2'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host3'/> + <address bus='0' target='0' unit='3'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host4'/> + <address bus='0' target='0' unit='4'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host5'/> + <address bus='0' target='0' unit='5'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host6'/> + <address bus='0' target='0' unit='6'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host7'/> + <address bus='0' target='0' unit='7'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host8'/> + <address bus='0' target='0' unit='8'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host9'/> + <address bus='0' target='0' unit='9'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host10'/> + <address bus='0' target='0' unit='10'/> + </source> + </hostdev> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml new file mode 100644 index 0000000..e416654 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml @@ -0,0 +1,106 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='scsi' index='0' model='virtio-scsi'/> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <controller type='scsi' index='1'/> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host0'/> + <address bus='0' target='0' unit='0'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host1'/> + <address bus='0' target='0' unit='1'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host2'/> + <address bus='0' target='0' unit='2'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='2'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host3'/> + <address bus='0' target='0' unit='3'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='3'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host4'/> + <address bus='0' target='0' unit='4'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='4'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host5'/> + <address bus='0' target='0' unit='5'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host6'/> + <address bus='0' target='0' unit='6'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='6'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host7'/> + <address bus='0' target='0' unit='7'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='0'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host8'/> + <address bus='0' target='0' unit='8'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='1'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host9'/> + <address bus='0' target='0' unit='9'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host10'/> + <address bus='0' target='0' unit='10'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='2'/> + </hostdev> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 64a271c..06e4206 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -298,6 +298,8 @@ mymain(void) DO_TEST("hostdev-scsi-shareable"); DO_TEST("hostdev-scsi-sgio"); + DO_TEST_DIFFERENT("hostdev-scsi-autogen-address"); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); -- 1.8.1.4

On 05/31/2013 04:09 AM, Osier Yang wrote:
With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead.
ACK.
src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
Relatively big to be pushing this late after freeze, but it can be argued that this is a bug fix and worth including in 1.0.6. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 31/05/13 22:09, Eric Blake wrote:
On 05/31/2013 04:09 AM, Osier Yang wrote:
With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead. ACK.
src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml Relatively big to be pushing this late after freeze, but it can be argued that this is a bug fix and worth including in 1.0.6.
I hope it could be included in 1.0.6. The scsi host device can work without it, but the address should be specified manually, which is not quite good, and better to have them together in one release. Osier

On 31/05/13 22:14, Osier Yang wrote:
On 31/05/13 22:09, Eric Blake wrote:
On 05/31/2013 04:09 AM, Osier Yang wrote:
With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead. ACK.
src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
Relatively big to be pushing this late after freeze, but it can be argued that this is a bug fix and worth including in 1.0.6.
I hope it could be included in 1.0.6. The scsi host device can work without it, but the address should be specified manually, which is not quite good, and better to have them together in one release.
Pushed as-is, John is a bit not fine with the comment, but it's trivial, and I do think it's not the time to change it to produce an inconsistent comment in virDomainDiskDefAssignAddress. As I said, I have to ensure the 7 is used for the controller itself indeed for narrow scsi bus, and it should be a independant patch, as it's for different purpose. Thanks. Osier

On 05/31/2013 06:09 AM, Osier Yang wrote:
With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead.
--- v2 - v3: * Improve the for loop a bit with John's suggestion
v1 - v2: * A new helper virDomainSCSIDriveAddressIsUsed * Move virDomainDefMaybeAddHostdevSCSIcontroller * More comments * Add testing. * problems fixed with the testing: 1) s/nscsi_controllers + 1/nscsi_controllers/, 2) Add the controller implicitly after a scsi hostdev def parsing, as it can use a new scsi controller index (nscsi_controllers), which should be added implicitly. --- src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b4e160..46d49a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3782,6 +3782,141 @@ cleanup: return ret; }
+/* Check if a drive type address $controller:0:0:$unit is already + * taken by a disk or not. + */ +static bool +virDomainDriveAddressIsUsedByDisk(virDomainDefPtr def, + enum virDomainDiskBus type, + unsigned int controller, + unsigned int unit) +{ + virDomainDiskDefPtr disk; + int i; + + for (i = 0; i < def->ndisks; i++) { + disk = def->disks[i]; + + if (disk->bus != type || + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + continue; + + if (disk->info.addr.drive.controller == controller && + disk->info.addr.drive.unit == unit && + disk->info.addr.drive.bus == 0 && + disk->info.addr.drive.target == 0) + return true; + } + + return false; +} + +/* Check if a drive type address $controller:0:0:$unit is already + * taken by a host device or not. + */ +static bool +virDomainDriveAddressIsUsedByHostdev(virDomainDefPtr def, + enum virDomainHostdevSubsysType type, + unsigned int controller, + unsigned int unit) +{ + virDomainHostdevDefPtr hostdev; + int i; + + for (i = 0; i < def->nhostdevs; i++) { + hostdev = def->hostdevs[i]; + + if (hostdev->source.subsys.type != type) + continue; + + if (hostdev->info->addr.drive.controller == controller && + hostdev->info->addr.drive.unit == unit && + hostdev->info->addr.drive.bus == 0 && + hostdev->info->addr.drive.target == 0) + return true; + } + + return false; +} + +static bool +virDomainSCSIDriveAddressIsUsed(virDomainDefPtr def, + unsigned int controller, + unsigned int unit) +{ + /* In current implementation, the maximum unit number of a controller + * is either 16 or 7 (narrow SCSI bus), and if the maximum unit number + * is 16, the controller itself is on unit 7 */ + if (unit == 7) + return true;
Given the comments in: https://www.redhat.com/archives/libvir-list/2013-May/msg02017.html The comment above is still confusing. As far as I understand things units are 0-7 with 8 being the max for narrow and 0-15 with 16 being the max for wide. It seems as though for narrow there are 8 units, but 7 is reserved for the controller, thus leaving a perception of only 7 max units. Make sense so far? What I'm not clear on with the above check is if we did have a wide bus (eg, 16 possible units), then is unit 7 still reserved for the controller? If so, indicate that and the code is fine, but the comment could be made less confusing. If not, then you need to have (readd) the check for max units again. I see Eric ACKed, but wanted to get this out before going through the rest... John
+ + if (virDomainDriveAddressIsUsedByDisk(def, VIR_DOMAIN_DISK_BUS_SCSI, + controller, unit) || + virDomainDriveAddressIsUsedByHostdev(def, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI, + controller, unit)) + return true; + + return false; +} + +/* Find out the next usable "unit" of a specific controller */ +static int +virDomainControllerSCSINextUnit(virDomainDefPtr def, + unsigned int max_unit, + unsigned int controller) +{ + int i; + + for (i = 0; i < max_unit; i++) { + if (!virDomainSCSIDriveAddressIsUsed(def, controller, i)) + return i; + } + + return -1; +} + +#define SCSI_WIDE_BUS_MAX_CONT_UNIT 16 +#define SCSI_NARROW_BUS_MAX_CONT_UNIT 7 + +static int +virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr def, + virDomainHostdevDefPtr hostdev) +{ + int next_unit; + unsigned nscsi_controllers = 0; + bool found = false; + int i; + + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) + return -1; + + for (i = 0; i < def->ncontrollers && !found; i++) { + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + nscsi_controllers++; + next_unit = virDomainControllerSCSINextUnit(def, + xmlopt->config.hasWideScsiBus ? + SCSI_WIDE_BUS_MAX_CONT_UNIT : + SCSI_NARROW_BUS_MAX_CONT_UNIT, + def->controllers[i]->idx); + if (next_unit >= 0) + found = true; + } + + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + + hostdev->info->addr.drive.controller = found ? + def->controllers[i - 1]->idx : + nscsi_controllers; + hostdev->info->addr.drive.bus = 0; + hostdev->info->addr.drive.target = 0; + hostdev->info->addr.drive.unit = found ? next_unit : 0; + + return 0; +} + static int virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, xmlXPathContextPtr ctxt, @@ -8802,7 +8937,9 @@ error: }
static virDomainHostdevDefPtr -virDomainHostdevDefParseXML(const xmlNodePtr node, +virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr vmdef, + const xmlNodePtr node, xmlXPathContextPtr ctxt, virHashTablePtr bootHash, unsigned int flags) @@ -8862,7 +8999,9 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + virDomainHostdevAssignAddress(xmlopt, vmdef, def) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", _("SCSI host devices must have address specified")); goto error; @@ -9271,8 +9410,8 @@ virDomainDeviceDefParse(const char *xmlStr, goto error; } else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) { dev->type = VIR_DOMAIN_DEVICE_HOSTDEV; - if (!(dev->data.hostdev = virDomainHostdevDefParseXML(node, ctxt, NULL, - flags))) + if (!(dev->data.hostdev = virDomainHostdevDefParseXML(xmlopt, def, node, + ctxt, NULL, flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "controller")) { dev->type = VIR_DOMAIN_DEVICE_CONTROLLER; @@ -10255,6 +10394,30 @@ error: return NULL; }
+static int +virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def) +{ + /* Look for any hostdev scsi dev */ + int i; + int maxController = -1; + virDomainHostdevDefPtr hostdev; + + for (i = 0; i < def->nhostdevs; i++) { + hostdev = def->hostdevs[i]; + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && + (int)hostdev->info->addr.drive.controller > maxController) { + maxController = hostdev->info->addr.drive.controller; + } + } + + for (i = 0; i <= maxController; i++) { + if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0) + return -1; + } + + return 0; +}
static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, @@ -11618,7 +11781,8 @@ virDomainDefParseXML(xmlDocPtr xml, for (i = 0; i < n; i++) { virDomainHostdevDefPtr hostdev;
- hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags); + hostdev = virDomainHostdevDefParseXML(xmlopt, def, nodes[i], + ctxt, bootHash, flags); if (!hostdev) goto error;
@@ -11631,6 +11795,9 @@ virDomainDefParseXML(xmlDocPtr xml, }
def->hostdevs[def->nhostdevs++] = hostdev; + + if (virDomainDefMaybeAddHostdevSCSIcontroller(def) < 0) + goto error; } VIR_FREE(nodes);
@@ -13232,31 +13399,6 @@ virDomainDefMaybeAddSmartcardController(virDomainDefPtr def) return 0; }
-static int -virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def) -{ - /* Look for any hostdev scsi dev */ - int i; - int maxController = -1; - virDomainHostdevDefPtr hostdev; - - for (i = 0; i < def->nhostdevs; i++) { - hostdev = def->hostdevs[i]; - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && - (int)hostdev->info->addr.drive.controller > maxController) { - maxController = hostdev->info->addr.drive.controller; - } - } - - for (i = 0; i <= maxController; i++) { - if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI, i, -1) < 0) - return -1; - } - - return 0; -} - /* * Based on the declared <address/> info for any devices, * add necessary drive controllers which are not already present diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml new file mode 100644 index 0000000..21f112b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml @@ -0,0 +1,95 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='scsi' index='0' model='virtio-scsi'/> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host0'/> + <address bus='0' target='0' unit='0'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host1'/> + <address bus='0' target='0' unit='1'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host2'/> + <address bus='0' target='0' unit='2'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host3'/> + <address bus='0' target='0' unit='3'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host4'/> + <address bus='0' target='0' unit='4'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host5'/> + <address bus='0' target='0' unit='5'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host6'/> + <address bus='0' target='0' unit='6'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host7'/> + <address bus='0' target='0' unit='7'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host8'/> + <address bus='0' target='0' unit='8'/> + </source> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host9'/> + <address bus='0' target='0' unit='9'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host10'/> + <address bus='0' target='0' unit='10'/> + </source> + </hostdev> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml new file mode 100644 index 0000000..e416654 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml @@ -0,0 +1,106 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='scsi' index='0' model='virtio-scsi'/> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <controller type='scsi' index='1'/> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host0'/> + <address bus='0' target='0' unit='0'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host1'/> + <address bus='0' target='0' unit='1'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='1'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host2'/> + <address bus='0' target='0' unit='2'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='2'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host3'/> + <address bus='0' target='0' unit='3'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='3'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host4'/> + <address bus='0' target='0' unit='4'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='4'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host5'/> + <address bus='0' target='0' unit='5'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host6'/> + <address bus='0' target='0' unit='6'/> + </source> + <address type='drive' controller='0' bus='0' target='0' unit='6'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host7'/> + <address bus='0' target='0' unit='7'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='0'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host8'/> + <address bus='0' target='0' unit='8'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='1'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host9'/> + <address bus='0' target='0' unit='9'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='5'/> + </hostdev> + <hostdev mode='subsystem' type='scsi' managed='yes'> + <source> + <adapter name='scsi_host10'/> + <address bus='0' target='0' unit='10'/> + </source> + <address type='drive' controller='1' bus='0' target='0' unit='2'/> + </hostdev> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 64a271c..06e4206 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -298,6 +298,8 @@ mymain(void) DO_TEST("hostdev-scsi-shareable"); DO_TEST("hostdev-scsi-sgio");
+ DO_TEST_DIFFERENT("hostdev-scsi-autogen-address"); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt);

On 31/05/13 22:11, John Ferlan wrote:
On 05/31/2013 06:09 AM, Osier Yang wrote:
With unknown good reasons, the attribute "bus" of scsi device address is always set to 0, same for attribute "target". (See virDomainDiskDefAssignAddress).
Though we might need to change the algorithm to honor "bus" and "target" too, that's a different issue. The address generator for scsi host device in this patch just follows the unknown good reasons, only considering the "controller" and "unit". It walks through all scsi controllers and their units, to see if the address $controller:0:0:$unit can be used (if not used by any disk or scsi host device yet), if found one, it sits on it, otherwise, it creates a new controller (actually the controller is implicitly created by someone else), and sits on $new_controller:0:0:0 instead.
--- v2 - v3: * Improve the for loop a bit with John's suggestion
v1 - v2: * A new helper virDomainSCSIDriveAddressIsUsed * Move virDomainDefMaybeAddHostdevSCSIcontroller * More comments * Add testing. * problems fixed with the testing: 1) s/nscsi_controllers + 1/nscsi_controllers/, 2) Add the controller implicitly after a scsi hostdev def parsing, as it can use a new scsi controller index (nscsi_controllers), which should be added implicitly. --- src/conf/domain_conf.c | 202 ++++++++++++++++++--- .../qemuxml2argv-hostdev-scsi-autogen-address.xml | 95 ++++++++++ ...qemuxml2xmlout-hostdev-scsi-autogen-address.xml | 106 +++++++++++ tests/qemuxml2xmltest.c | 2 + 4 files changed, 375 insertions(+), 30 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-autogen-address.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-hostdev-scsi-autogen-address.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b4e160..46d49a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3782,6 +3782,141 @@ cleanup: return ret; }
+/* Check if a drive type address $controller:0:0:$unit is already + * taken by a disk or not. + */ +static bool +virDomainDriveAddressIsUsedByDisk(virDomainDefPtr def, + enum virDomainDiskBus type, + unsigned int controller, + unsigned int unit) +{ + virDomainDiskDefPtr disk; + int i; + + for (i = 0; i < def->ndisks; i++) { + disk = def->disks[i]; + + if (disk->bus != type || + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + continue; + + if (disk->info.addr.drive.controller == controller && + disk->info.addr.drive.unit == unit && + disk->info.addr.drive.bus == 0 && + disk->info.addr.drive.target == 0) + return true; + } + + return false; +} + +/* Check if a drive type address $controller:0:0:$unit is already + * taken by a host device or not. + */ +static bool +virDomainDriveAddressIsUsedByHostdev(virDomainDefPtr def, + enum virDomainHostdevSubsysType type, + unsigned int controller, + unsigned int unit) +{ + virDomainHostdevDefPtr hostdev; + int i; + + for (i = 0; i < def->nhostdevs; i++) { + hostdev = def->hostdevs[i]; + + if (hostdev->source.subsys.type != type) + continue; + + if (hostdev->info->addr.drive.controller == controller && + hostdev->info->addr.drive.unit == unit && + hostdev->info->addr.drive.bus == 0 && + hostdev->info->addr.drive.target == 0) + return true; + } + + return false; +} + +static bool +virDomainSCSIDriveAddressIsUsed(virDomainDefPtr def, + unsigned int controller, + unsigned int unit) +{ + /* In current implementation, the maximum unit number of a controller + * is either 16 or 7 (narrow SCSI bus), and if the maximum unit number + * is 16, the controller itself is on unit 7 */ + if (unit == 7) + return true; Given the comments in:
https://www.redhat.com/archives/libvir-list/2013-May/msg02017.html
The comment above is still confusing.
As far as I understand things units are 0-7 with 8 being the max for narrow and 0-15 with 16 being the max for wide.
It seems as though for narrow there are 8 units, but 7 is reserved for the controller, thus leaving a perception of only 7 max units. Make sense so far?
Yes. But I need to confirm.
What I'm not clear on with the above check is if we did have a wide bus (eg, 16 possible units), then is unit 7 still reserved for the controller?
Yes, even if we add the hasWideScsiBus for qemu driver, as domain_conf.c is for all of the drivers, we need to keep it as 7. Unless there is critical reasons for changing it.
If so, indicate that and the code is fine, but the comment could be made less confusing. If not, then you need to have (readd) the check for max units again.
For narrow bus, we didn't declare anywhere to say the max unit "7" is occupied by the controller. And actually in the code, it only uses "0-6" for allocation. But regardless of whether it will use the 7 for the controller itself or not. Simple checking with if (unit == 7) return true; is fine. No need to have a redundant checking like: if (max_unit == 16 && unit ==7) Because even the 7 will be taken by the controller itself, it's still used, and returning true is correct. The comment like below + /* In current implementation, the maximum unit number of a controller + * is either 16 or 7 (narrow SCSI bus), and if the maximum unit number + * is 16, the controller itself is on unit 7 */ just follows what we do in the current code (it doesn't declare what will the 7 will be used for). I think what you are complaining is "and if the maximum unit number is 16, the controller itself is on unit 7", what you want to see is "the controller itself is on unit 7", right? I agree with it, but before make the changing, I need to confirm whether the controller is on the 7 indeed. And makes the changes if it is together with changing on comment in virDomainDiskDefAssignAddress too. And it can be a later patch. Osier

+ +static int +virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr def, + virDomainHostdevDefPtr hostdev) +{ + int next_unit; + unsigned nscsi_controllers = 0; + bool found = false; + int i; + + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) + return -1; + + for (i = 0; i < def->ncontrollers && !found; i++) { + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + nscsi_controllers++; + next_unit = virDomainControllerSCSINextUnit(def, + xmlopt->config.hasWideScsiBus ? + SCSI_WIDE_BUS_MAX_CONT_UNIT : + SCSI_NARROW_BUS_MAX_CONT_UNIT, + def->controllers[i]->idx); + if (next_unit >= 0) + found = true; + } + + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + + hostdev->info->addr.drive.controller = found ? + def->controllers[i - 1]->idx : + nscsi_controllers; + hostdev->info->addr.drive.bus = 0; + hostdev->info->addr.drive.target = 0; + hostdev->info->addr.drive.unit = found ? next_unit : 0; well, 1.0.6 is out of the door, but with this I hit the following
On 05/31/2013 12:09 PM, Osier Yang wrote: problem on Ubuntu 12.04 (gcc 4.6.3): ../../src/conf/domain_conf.c: In function 'virDomainHostdevDefParseXML': ../../src/conf/domain_conf.c:3915:36: error: 'next_unit' may be used uninitialized in this function [-Werror=uninitialized] ../../src/conf/domain_conf.c:3886:9: note: 'next_unit' was declared here It seems that the older compiler is not smart enough to grasp the tie between 'found' and 'next_unit'...
+ + return 0; +}
-- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On 03/06/13 22:15, Viktor Mihajlovski wrote:
+ +static int +virDomainHostdevAssignAddress(virDomainXMLOptionPtr xmlopt, + virDomainDefPtr def, + virDomainHostdevDefPtr hostdev) +{ + int next_unit; + unsigned nscsi_controllers = 0; + bool found = false; + int i; + + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) + return -1; + + for (i = 0; i < def->ncontrollers && !found; i++) { + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + nscsi_controllers++; + next_unit = virDomainControllerSCSINextUnit(def, + xmlopt->config.hasWideScsiBus ? + SCSI_WIDE_BUS_MAX_CONT_UNIT : + SCSI_NARROW_BUS_MAX_CONT_UNIT, + def->controllers[i]->idx); + if (next_unit >= 0) + found = true; + } + + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + + hostdev->info->addr.drive.controller = found ? + def->controllers[i - 1]->idx : + nscsi_controllers; + hostdev->info->addr.drive.bus = 0; + hostdev->info->addr.drive.target = 0; + hostdev->info->addr.drive.unit = found ? next_unit : 0; well, 1.0.6 is out of the door, but with this I hit the following
On 05/31/2013 12:09 PM, Osier Yang wrote: problem on Ubuntu 12.04 (gcc 4.6.3): ../../src/conf/domain_conf.c: In function 'virDomainHostdevDefParseXML': ../../src/conf/domain_conf.c:3915:36: error: 'next_unit' may be used uninitialized in this function [-Werror=uninitialized] ../../src/conf/domain_conf.c:3886:9: note: 'next_unit' was declared here
It seems that the older compiler is not smart enough to grasp the tie between 'found' and 'next_unit'...
fixed by Jirka with 4db39e3fee6
+ + return 0; +}

On 06/03/2013 04:29 PM, Osier Yang wrote:
fixed by Jirka with 4db39e3fee6
the post somehow went past me, sorry... :$ -- Mit freundlichen Grüßen/Kind Regards Viktor Mihajlovski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Martina Köderitz Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (4)
-
Eric Blake
-
John Ferlan
-
Osier Yang
-
Viktor Mihajlovski