From a3c763361d39daa2b724a97c9ac672dfe45287c7 Mon Sep 17 00:00:00 2001
From: Martin Kletzander <mkletzan@redhat.com>
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 <mkletzan@redhat.com>
---
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