Change in vdsm[master]: hostdev: add support for SCSI

mpolednik at redhat.com mpolednik at redhat.com
Mon Mar 21 17:32:20 UTC 2016


Martin Polednik has uploaded a new change for review.

Change subject: hostdev: add support for SCSI
......................................................................

hostdev: add support for SCSI

SCSI devices inside sysfs device tree are different. Normally, we
require a single sysfs entry in listAllDevices to determine the
endpoint and address of the devices. SCSI requires two entries -
generic one to determine endpoint, and scsi entry to determine address
and it's host adapter.

Change-Id: Ib049bc8669d3dc14a83c89c0d03f3410f242e1cd
Signed-off-by: Martin Polednik <mpolednik at redhat.com>
---
M lib/vdsm/hostdev.py
M tests/hostdevTests.py
M vdsm/supervdsm_api/udev.py
M vdsm/virt/vmdevices/hostdevice.py
4 files changed, 69 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/55024/1

diff --git a/lib/vdsm/hostdev.py b/lib/vdsm/hostdev.py
index c9371eb..0904f61 100644
--- a/lib/vdsm/hostdev.py
+++ b/lib/vdsm/hostdev.py
@@ -29,6 +29,7 @@
 
 CAPABILITY_TO_XML_ATTR = {'pci': 'pci',
                           'scsi': 'scsi',
+                          'scsi_generic': 'scsi_generic',
                           'usb_device': 'usb'}
 
 
@@ -50,6 +51,19 @@
 
 def name_to_pci_path(device_name):
     return device_name[4:].replace('_', '.').replace('.', ':', 2)
+
+
+def scsi_address_to_adapter(scsi_address):
+    """
+    Read adapter info from scsi host address, and mutate the adress (removing
+    'host' key) to conform to libvirt.
+    """
+    adapter = 'scsi_host{}'.format(scsi_address['host'])
+    scsi_address['unit'] = scsi_address['lun']
+    del scsi_address['lun']
+    del scsi_address['host']
+
+    return {'name': adapter}
 
 
 def pci_address_to_name(domain, bus, slot, function):
@@ -225,6 +239,12 @@
         supervdsm.getProxy().appropriateUSBDevice(
             device_params['address']['bus'],
             device_params['address']['device'])
+    elif capability == 'scsi_generic':
+        supervdsm.getProxy().appropriateSCSIDevice(device_name,
+                                                   device_params['endpoint'])
+        # SCSI is uncool. We need the generic device for endpoint, but it's
+        # parent (proper SCSI device) for it's address.
+        device_params = get_device_params(device_params['parent'])
 
     return device_params
 
@@ -244,6 +264,8 @@
         supervdsm.getProxy().rmAppropriateUSBDevice(
             device_params['address']['bus'],
             device_params['address']['device'])
+    elif capability == 'scsi_generic':
+        supervdsm.getProxy().rmAppropriateSCSIDevice(device_params['endpoint'])
 
 
 def change_numvfs(device_name, numvfs):
diff --git a/tests/hostdevTests.py b/tests/hostdevTests.py
index 5af9cd5..2df05ef 100644
--- a/tests/hostdevTests.py
+++ b/tests/hostdevTests.py
@@ -114,6 +114,16 @@
             %s
     </hostdev>
     ''',
+    'scsi_0_0_0_0':
+    '''
+    <hostdev managed="no" mode="subsystem" type="scsi">
+            <source>
+                    <adapter name="scsi_host0"/>
+                    <address bus="0" unit="0" target="0"/>
+            </source>
+            %s
+    </hostdev>
+    ''',
     _SRIOV_VF:
     '''
     <interface managed="no" type="hostdev">
@@ -402,7 +412,8 @@
             'smp': '8', 'maxVCpus': '160',
             'memSize': '1024', 'memGuaranteedSize': '512'}
 
-    @permutations([[device] for device in _PCI_DEVICES + _USB_DEVICES])
+    @permutations([[device] for device in _PCI_DEVICES + _USB_DEVICES +
+                   [_SCSI_DEVICES[2]]])
     def testCreateHostDevice(self, device_name):
         dev_spec = {'type': 'hostdev', 'device': device_name}
         device = hostdevice.HostDevice(self.conf, self.log, **dev_spec)
diff --git a/vdsm/supervdsm_api/udev.py b/vdsm/supervdsm_api/udev.py
index 26b3a61..82ad49e 100644
--- a/vdsm/supervdsm_api/udev.py
+++ b/vdsm/supervdsm_api/udev.py
@@ -26,6 +26,7 @@
 from vdsm import commands
 from vdsm import cmdutils
 from vdsm import udevadm
+from vdsm import utils
 
 from vdsm.constants import EXT_CHOWN, \
     DISKIMAGE_USER, DISKIMAGE_GROUP, \
@@ -56,6 +57,32 @@
 
 
 @expose
+def appropriateSCSIDevice(device_name, endpoint):
+    ruleFile = _UDEV_RULE_FILE_NAME % ('scsi', device_name)
+    rule = 'RUN+="%s %s:%s %s"\n' % (
+        EXT_CHOWN, QEMU_PROCESS_USER, QEMU_PROCESS_GROUP, endpoint)
+    with open(ruleFile, "w") as rf:
+        _log.debug("Creating rule %s: %r", ruleFile, rule)
+        rf.write(rule)
+
+    _udevTrigger(subsystem_matches=('scsi_generic',))
+
+
+ at expose
+def rmAppropriateSCSIDevice(device_name, endpoint):
+    rule_file = _UDEV_RULE_FILE_NAME % ('scsi', device_name)
+    _log.debug("Removing rule %s", rule_file)
+    utils.rmFile(rule_file)
+
+    _log.debug('Changing ownership (to root:disk) of device %s', endpoint)
+    cmd = [EXT_CHOWN, 'root:disk', endpoint]
+    rc, out, err = commands.execCmd(cmd)
+    if err:
+        raise OSError(errno.EINVAL, 'Could not change ownership'
+                      'out %s\nerr %s' % (out, err))
+
+
+ at expose
 def appropriateMultipathDevice(guid, thiefId):
     ruleFile = _UDEV_RULE_FILE_NAME % (guid, thiefId)
     # WARNING: we cannot use USER, GROUP and MODE since using any of them
diff --git a/vdsm/virt/vmdevices/hostdevice.py b/vdsm/virt/vmdevices/hostdevice.py
index e528487..9bf2cf5 100644
--- a/vdsm/virt/vmdevices/hostdevice.py
+++ b/vdsm/virt/vmdevices/hostdevice.py
@@ -20,7 +20,7 @@
 
 from vdsm import utils
 from vdsm.hostdev import get_device_params, detach_detachable, \
-    pci_address_to_name, CAPABILITY_TO_XML_ATTR
+    pci_address_to_name, CAPABILITY_TO_XML_ATTR, scsi_address_to_adapter
 from . import core
 from . import hwclass
 from .. import vmxml
@@ -41,6 +41,7 @@
         called before getXML in order to populate _deviceParams.
         """
         self._deviceParams = detach_detachable(self.device)
+        self.hostAddress = self._deviceParams.get('address')
 
     def getXML(self):
         """
@@ -67,6 +68,12 @@
             type=CAPABILITY_TO_XML_ATTR[self._deviceParams['capability']])
         source = hostdev.appendChildWithArgs('source')
 
+        # This must be done *before* creating the address element, as we need
+        # remove the 'host' key from real address.
+        if CAPABILITY_TO_XML_ATTR[self._deviceParams['capability']] == 'scsi':
+            source.appendChildWithArgs(
+                'adapter', **scsi_address_to_adapter(self.hostAddress))
+
         source.appendChildWithArgs('address', **self.hostAddress)
 
         if hasattr(self, 'bootOrder'):


-- 
To view, visit https://gerrit.ovirt.org/55024
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib049bc8669d3dc14a83c89c0d03f3410f242e1cd
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpolednik at redhat.com>


More information about the vdsm-patches mailing list