Change in vdsm[master]: supervdsm: move udev-related functions to udev.py

mpolednik at redhat.com mpolednik at redhat.com
Tue Mar 8 10:22:01 UTC 2016


Martin Polednik has uploaded a new change for review.

Change subject: supervdsm: move udev-related functions to udev.py
......................................................................

supervdsm: move udev-related functions to udev.py

Change-Id: If8c4a5120887c2cbf13463f33fad2ef5e002e0d6
Signed-off-by: Martin Polednik <mpolednik at redhat.com>
---
M vdsm.spec.in
M vdsm/supervdsmServer
M vdsm/supervdsm_api/Makefile.am
A vdsm/supervdsm_api/udev.py
4 files changed, 196 insertions(+), 137 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/58/54458/1

diff --git a/vdsm.spec.in b/vdsm.spec.in
index e4dddbf..2f25f51 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -909,6 +909,7 @@
 %{_datadir}/%{vdsm_name}/supervdsm_api/mkimage.py*
 %{_datadir}/%{vdsm_name}/supervdsm_api/ksm.py*
 %{_datadir}/%{vdsm_name}/supervdsm_api/network.py*
+%{_datadir}/%{vdsm_name}/supervdsm_api/udev.py*
 %{_datadir}/%{vdsm_name}/supervdsm_api/virt.py*
 %{_datadir}/%{vdsm_name}/storage/__init__.py*
 %{_datadir}/%{vdsm_name}/storage/blockSD.py*
diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer
index 121f07b..4f995bc 100755
--- a/vdsm/supervdsmServer
+++ b/vdsm/supervdsmServer
@@ -24,7 +24,6 @@
 import importlib
 import pkgutil
 from functools import wraps
-import re
 import getopt
 import resource
 import signal
@@ -32,7 +31,6 @@
 import logging.config
 from contextlib import closing
 
-from vdsm import commands
 from vdsm import concurrent
 from vdsm.infra import sigutils
 from vdsm.infra import zombiereaper
@@ -56,8 +54,6 @@
 except ImportError:
     _glusterEnabled = False
 
-from vdsm import cmdutils
-from vdsm import udevadm
 from vdsm import utils
 from vdsm import sysctl
 from vdsm.supervdsm import _SuperVdsmManager
@@ -72,9 +68,8 @@
 from storage import multipath
 from storage.fileUtils import chown, resolveGid, resolveUid
 from storage.fileUtils import validateAccess as _validateAccess
-from vdsm.constants import METADATA_GROUP, EXT_CHOWN, \
-    DISKIMAGE_USER, DISKIMAGE_GROUP, \
-    VDSM_USER, QEMU_PROCESS_USER, QEMU_PROCESS_GROUP, GLUSTER_MGMT_ENABLED
+from vdsm.constants import METADATA_GROUP, \
+    VDSM_USER, GLUSTER_MGMT_ENABLED
 from storage.devicemapper import _removeMapping, _getPathsStatus
 from vdsm.config import config
 import supervdsm_api
@@ -235,129 +230,6 @@
         self._udevTrigger(property_matches=(('DM_NAME', guid),))
 
     @logDecorator
-    def appropriateMultipathDevice(self, guid, thiefId):
-        ruleFile = _UDEV_RULE_FILE_NAME % (guid, thiefId)
-        # WARNING: we cannot use USER, GROUP and MODE since using any of them
-        # will change the selinux label to the default, causing vms to pause.
-        # See https://bugzilla.redhat.com/1147910
-        rule = 'SYMLINK=="mapper/%s", RUN+="%s %s:%s $env{DEVNAME}"\n' % (
-            guid, EXT_CHOWN, DISKIMAGE_USER, DISKIMAGE_GROUP)
-        with open(ruleFile, "w") as rf:
-            self.log.debug("Creating rule %s: %r", ruleFile, rule)
-            rf.write(rule)
-
-    @logDecorator
-    def rmAppropriateMultipathRules(self, thiefId):
-        re_apprDevRule = "^" + _UDEV_RULE_FILE_PREFIX + ".*?-" + thiefId + \
-                         _UDEV_RULE_FILE_EXT + "$"
-        rules = [os.path.join(_UDEV_RULE_FILE_DIR, r) for r in
-                 os.listdir(_UDEV_RULE_FILE_DIR)
-                 if re.match(re_apprDevRule, r)]
-        fails = []
-        for r in rules:
-            try:
-                self.log.debug("Removing rule %s", r)
-                os.remove(r)
-            except OSError:
-                fails.append(r)
-        return fails
-
-    @logDecorator
-    def appropriateIommuGroup(self, iommu_group):
-        """
-        Create udev rule in /etc/udev/rules.d/ to change ownership
-        of /dev/vfio/$iommu_group to qemu:qemu. This method should be called
-        when detaching a device from the host.
-        """
-        rule_file = _UDEV_RULE_FILE_NAME_VFIO % iommu_group
-
-        if not os.path.isfile(rule_file):
-            # If the file exists, different device from the same group has
-            # already been detached and we therefore can skip overwriting the
-            # file. Also, this file should only be created/removed via the
-            # means of supervdsm.
-
-            rule = ('KERNEL=="{}", SUBSYSTEM=="vfio" RUN+="{} {}:{} '
-                    '/dev/vfio/{}"').format(iommu_group, EXT_CHOWN,
-                                            QEMU_PROCESS_USER,
-                                            QEMU_PROCESS_GROUP,
-                                            iommu_group)
-
-            with open(rule_file, "w") as rf:
-                self.log.debug("Creating rule %s: %r", rule_file, rule)
-                rf.write(rule)
-
-            self._udevTrigger(subsystem_matches=('vfio',))
-
-    @logDecorator
-    def rmAppropriateIommuGroup(self, iommu_group):
-        """
-        Remove udev rule in /etc/udev/rules.d/ created by
-        vfioAppropriateDevice.
-        """
-        rule_file = os.path.join(_UDEV_RULE_FILE_DIR, _UDEV_RULE_FILE_PREFIX +
-                                 "iommu_group_" + iommu_group +
-                                 _UDEV_RULE_FILE_EXT)
-        error = False
-
-        try:
-            os.remove(rule_file)
-        except OSError as e:
-            if e.errno == errno.ENOENT:
-                # OSError with ENOENT errno here means that the rule file does
-                # not exist - this is expected when multiple devices in one
-                # iommu group were passed through.
-                error = True
-            else:
-                raise
-        else:
-            self.log.debug("Removing rule %s", rule_file)
-
-        if not error:
-            self._udevTrigger(subsystem_matches=('vfio',))
-
-    @logDecorator
-    def appropriateUSBDevice(self, bus, device):
-        rule_file = _UDEV_RULE_FILE_NAME_USB % (bus, device)
-        rule = ('SUBSYSTEM=="usb", ATTRS{{busnum}}=="{}", '
-                'ATTRS{{devnum}}=="{}", OWNER:="{}", GROUP:="{}"\n').format(
-                    bus, device, QEMU_PROCESS_USER, QEMU_PROCESS_GROUP)
-
-        self.log.debug("Creating rule %s: %r", rule_file, rule)
-
-        with open(rule_file, "w") as rf:
-            rf.write(rule)
-
-        self._udevTrigger(attr_matches=(('busnum', int(bus)),
-                                        ('devnum', int(device))))
-
-    @logDecorator
-    def rmAppropriateUSBDevice(self, bus, device):
-        rule_file = _UDEV_RULE_FILE_NAME_USB % (bus, device)
-        self.log.debug("Removing rule %s", rule_file)
-        try:
-            os.remove(rule_file)
-        except OSError as e:
-            if e.errno != errno.ENOENT:
-                raise
-
-            self.log.warning('Rule %s missing', rule_file)
-
-        self.log.debug('Changing ownership (to root:root) of device '
-                       'bus: %s, device:: %s', bus, device)
-        device_path = _USB_DEVICE_PATH % (int(bus), int(device))
-        cmd = [EXT_CHOWN, 'root:root', device_path]
-        rc, out, err = commands.execCmd(cmd)
-        if err:
-            raise OSError(errno.EINVAL, 'Could not change ownership'
-                          'out %s\nerr %s' % (out, err))
-
-        # It's possible that the device was in input class or had rule
-        # matched against it, trigger to make sure everything is fine.
-        self._udevTrigger(attr_matches=(('busnum', int(bus)),
-                                        ('devnum', int(device))))
-
-    @logDecorator
     def fuser(self, *args, **kwargs):
         return fuser.fuser(*args, **kwargs)
 
@@ -372,13 +244,6 @@
     @logDecorator
     def set_rp_filter_strict(self, dev):
         sysctl.set_rp_filter_strict(dev)
-
-    def _udevTrigger(self, *args, **kwargs):
-        try:
-            udevadm.trigger(*args, **kwargs)
-        except cmdutils.Error as e:
-            raise OSError(errno.EINVAL, 'Could not trigger change '
-                          'out %s\nerr %s' % (e.out, e.err))
 
 
 def terminate(signo, frame):
diff --git a/vdsm/supervdsm_api/Makefile.am b/vdsm/supervdsm_api/Makefile.am
index c951570..e59c6b5 100644
--- a/vdsm/supervdsm_api/Makefile.am
+++ b/vdsm/supervdsm_api/Makefile.am
@@ -27,5 +27,6 @@
 	ksm.py \
 	mkimage.py \
 	network.py \
+	udev.py \
 	virt.py \
 	$(NULL)
diff --git a/vdsm/supervdsm_api/udev.py b/vdsm/supervdsm_api/udev.py
new file mode 100644
index 0000000..1af3de1
--- /dev/null
+++ b/vdsm/supervdsm_api/udev.py
@@ -0,0 +1,192 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from __future__ import absolute_import
+
+import os
+import errno
+import re
+import logging
+
+from . import expose
+
+from vdsm import commands
+from vdsm.constants import EXT_CHOWN, \
+    DISKIMAGE_USER, DISKIMAGE_GROUP, \
+    QEMU_PROCESS_USER, QEMU_PROCESS_GROUP
+from vdsm import cmdutils
+from vdsm import udevadm
+
+
+_UDEV_RULE_FILE_DIR = "/etc/udev/rules.d/"
+_UDEV_RULE_FILE_PREFIX = "99-vdsm-"
+_UDEV_RULE_FILE_EXT = ".rules"
+_UDEV_RULE_FILE_NAME = os.path.join(
+    _UDEV_RULE_FILE_DIR, _UDEV_RULE_FILE_PREFIX + '%s-%s' +
+    _UDEV_RULE_FILE_EXT)
+_UDEV_RULE_FILE_NAME_VFIO = os.path.join(
+    _UDEV_RULE_FILE_DIR, _UDEV_RULE_FILE_PREFIX + "iommu_group_%s" +
+    _UDEV_RULE_FILE_EXT)
+_UDEV_RULE_FILE_NAME_USB = os.path.join(
+    _UDEV_RULE_FILE_DIR, _UDEV_RULE_FILE_PREFIX + "usb_%s_%s" +
+    _UDEV_RULE_FILE_EXT)
+_USB_DEVICE_PATH = '/dev/bus/usb/%03d/%03d'
+
+_LOG = logging.getLogger("SuperVdsm.ServerCallback")
+
+
+ at expose
+def udevTriggerMultipath(guid):
+    _udevTrigger(property_matches=(('DM_NAME', guid),))
+
+
+ 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
+    # will change the selinux label to the default, causing vms to pause.
+    # See https://bugzilla.redhat.com/1147910
+    rule = 'SYMLINK=="mapper/%s", RUN+="%s %s:%s $env{DEVNAME}"\n' % (
+        guid, EXT_CHOWN, DISKIMAGE_USER, DISKIMAGE_GROUP)
+    with open(ruleFile, "w") as rf:
+        _LOG.debug("Creating rule %s: %r", ruleFile, rule)
+        rf.write(rule)
+
+
+ at expose
+def rmAppropriateMultipathRules(thiefId):
+    re_apprDevRule = "^" + _UDEV_RULE_FILE_PREFIX + ".*?-" + thiefId + \
+        _UDEV_RULE_FILE_EXT + "$"
+    rules = [os.path.join(_UDEV_RULE_FILE_DIR, r) for r in
+             os.listdir(_UDEV_RULE_FILE_DIR)
+             if re.match(re_apprDevRule, r)]
+    fails = []
+    for r in rules:
+        try:
+            _LOG.debug("Removing rule %s", r)
+            os.remove(r)
+        except OSError:
+            fails.append(r)
+    return fails
+
+
+ at expose
+def appropriateIommuGroup(iommu_group):
+    """
+    Create udev rule in /etc/udev/rules.d/ to change ownership
+    of /dev/vfio/$iommu_group to qemu:qemu. This method should be called
+    when detaching a device from the host.
+    """
+    rule_file = _UDEV_RULE_FILE_NAME_VFIO % iommu_group
+
+    if not os.path.isfile(rule_file):
+        # If the file exists, different device from the same group has
+        # already been detached and we therefore can skip overwriting the
+        # file. Also, this file should only be created/removed via the
+        # means of supervdsm.
+
+        rule = ('KERNEL=="{}", SUBSYSTEM=="vfio" RUN+="{} {}:{} '
+                '/dev/vfio/{}"').format(iommu_group, EXT_CHOWN,
+                                        QEMU_PROCESS_USER,
+                                        QEMU_PROCESS_GROUP,
+                                        iommu_group)
+
+        with open(rule_file, "w") as rf:
+            _LOG.debug("Creating rule %s: %r", rule_file, rule)
+            rf.write(rule)
+
+        _udevTrigger(subsystem_matches=('vfio',))
+
+
+ at expose
+def rmAppropriateIommuGroup(iommu_group):
+    """
+    Remove udev rule in /etc/udev/rules.d/ created by
+    vfioAppropriateDevice.
+    """
+    rule_file = os.path.join(_UDEV_RULE_FILE_DIR, _UDEV_RULE_FILE_PREFIX +
+                             "iommu_group_" + iommu_group +
+                             _UDEV_RULE_FILE_EXT)
+    error = False
+
+    try:
+        os.remove(rule_file)
+    except OSError as e:
+        if e.errno == errno.ENOENT:
+            # OSError with ENOENT errno here means that the rule file does
+            # not exist - this is expected when multiple devices in one
+            # iommu group were passed through.
+            error = True
+        else:
+            raise
+    else:
+        _LOG.debug("Removing rule %s", rule_file)
+
+    if not error:
+        _udevTrigger(subsystem_matches=('vfio',))
+
+
+ at expose
+def appropriateUSBDevice(bus, device):
+    rule_file = _UDEV_RULE_FILE_NAME_USB % (bus, device)
+    rule = ('SUBSYSTEM=="usb", ATTRS{{busnum}}=="{}", '
+            'ATTRS{{devnum}}=="{}", OWNER:="{}", GROUP:="{}"\n').format(
+        bus, device, QEMU_PROCESS_USER, QEMU_PROCESS_GROUP)
+
+    _LOG.debug("Creating rule %s: %r", rule_file, rule)
+
+    with open(rule_file, "w") as rf:
+        rf.write(rule)
+
+    _udevTrigger(attr_matches=(('busnum', int(bus)),
+                               ('devnum', int(device))))
+
+
+ at expose
+def rmAppropriateUSBDevice(bus, device):
+    rule_file = _UDEV_RULE_FILE_NAME_USB % (bus, device)
+    _LOG.debug("Removing rule %s", rule_file)
+    try:
+        os.remove(rule_file)
+    except OSError as e:
+        if e.errno != errno.ENOENT:
+            raise
+
+        _LOG.warning('Rule %s missing', rule_file)
+
+    _LOG.debug('Changing ownership (to root:root) of device '
+               'bus: %s, device:: %s', bus, device)
+    device_path = _USB_DEVICE_PATH % (int(bus), int(device))
+    cmd = [EXT_CHOWN, 'root:root', device_path]
+    rc, out, err = commands.execCmd(cmd)
+    if err:
+        raise OSError(errno.EINVAL, 'Could not change ownership'
+                      'out %s\nerr %s' % (out, err))
+
+    # It's possible that the device was in input class or had rule
+    # matched against it, trigger to make sure everything is fine.
+    _udevTrigger(attr_matches=(('busnum', int(bus)),
+                               ('devnum', int(device))))
+
+
+def _udevTrigger(*args, **kwargs):
+    try:
+        udevadm.trigger(*args, **kwargs)
+    except cmdutils.Error as e:
+        raise OSError(errno.EINVAL, 'Could not trigger change '
+                      'out %s\nerr %s' % (e.out, e.err))


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If8c4a5120887c2cbf13463f33fad2ef5e002e0d6
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