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