From a3c763361d39daa2b724a97c9ac672dfe45287c7 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Thu, 27 Feb 2014 13:57:37 +0100 Subject: [PATCH 3/3] addhardware: Rework the addition of controllers for virtio-scsi disks https://bugzilla.redhat.com/show_bug.cgi?id=1036716 After this patch the virtio-scsi controller should be added only if needed and its index used for the target generation of the added disk. RHEL-only; upstream counterpart of this work was done in commits a9c791b5, 078e1a4d, bc5d84b0, 4aec369e, 7c437f6a, 466c2bcf and 0dceb24b. Signed-off-by: Martin Kletzander --- virtManager/addhardware.py | 57 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py index b2f5526..51a01da 100644 --- a/virtManager/addhardware.py +++ b/virtManager/addhardware.py @@ -20,6 +20,7 @@ import logging import traceback +import collections # pylint: disable=E0611 from gi.repository import Gtk @@ -1467,27 +1468,55 @@ class vmmAddHardware(vmmGObjectUI): disks = (self.vm.get_disk_devices() + self.vm.get_disk_devices(inactive=True)) for d in disks: - used.append(d.target) + if d.target not in used: + used.append(d.target) # Add a SCSI controller with model virtio-scsi if needed disk.vmm_controller = None if (controller_model == "virtio-scsi") and (bus == "scsi"): + # Get SCSI controllers controllers = self.vm.get_controller_devices() - controller = VirtualControllerSCSI(conn=self.conn.vmm) - controller.set_model(controller_model) - disk.vmm_controller = controller - for d in controllers: - if controller.type == d.type: - controller.index += 1 - if controller_model == d.model: - disk.vmm_controller = None - controller = d + ctrls_scsi = [x for x in controllers if + (x.type == VirtualControllerSCSI.CONTROLLER_TYPE_SCSI)] + + # Create possible new controller + controller = VirtualControllerSCSI(conn=self.conn.vmm, + model=controller_model) + + # And set its index + controller.index = 0 + if ctrls_scsi: + controller.index = max([int(x.index) for x in ctrls_scsi]) + 1 + + # Take only virtio-scsi ones + ctrls_scsi = [x for x in ctrls_scsi if + (x.model == controller_model)] + + # Save occupied places per controller + occupied = collections.defaultdict(int) + for d in disks: + if d.get_target_prefix() == disk.get_target_prefix(): + num = 0 + k = 0 + tgt = d.target + if tgt[0] == 'x': + # This case is here for 'xvda' + tgt = tgt[1:] + for i, c in enumerate(reversed(tgt[2:])): + if i != 0: + k = 1 + num += (ord(c) - ord('a') + k) * (26 ** i) + occupied[num / 7] += 1 + for c in ctrls_scsi: + if occupied[int(c.index)] < 7: + controller = c break + else: + disk.vmm_controller = controller - disk.address.type = disk.address.ADDRESS_TYPE_DRIVE - disk.address.controller = controller.index - - disk.generate_target(used) + disk.generate_target(used, int(controller.index)) + else: + disk.generate_target(used) isfatal, errmsg = disk.is_size_conflict() if not isfatal and errmsg: -- 1.8.5.3