[node-patches] Change in ovirt-node[master]: move some low level storage detection functions to the newer...

jboggs at redhat.com jboggs at redhat.com
Mon Nov 25 21:18:51 UTC 2013


Joey Boggs has uploaded a new change for review.

Change subject: move some low level storage detection functions to the newer modules
......................................................................

move some low level storage detection functions to the newer modules

Signed-off-by: Joey Boggs <jboggs at redhat.com>
Change-Id: I37df9b1cf77b3f4c89eb5695a9bc1e8277b918b6
---
M src/ovirt/node/utils/storage.py
M src/ovirtnode/ovirtfunctions.py
M src/ovirtnode/storage.py
3 files changed, 159 insertions(+), 182 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/60/21660/1

diff --git a/src/ovirt/node/utils/storage.py b/src/ovirt/node/utils/storage.py
index 8958b70..114059b 100644
--- a/src/ovirt/node/utils/storage.py
+++ b/src/ovirt/node/utils/storage.py
@@ -23,6 +23,8 @@
 from ovirt.node.utils import process
 from ovirt.node.utils.fs import File
 import os
+import gudev
+import re
 
 
 class iSCSI(base.Base):
@@ -89,9 +91,6 @@
                 args = ["%s%s" % (k, n) for k in "path", "bus", "name", "size",
                         "desc", "serial", "model"]
                 self._fake_devices[args[1]] = Device(*tuple(args))
-        else:
-            import ovirtnode.storage
-            self._storage = ovirtnode.storage.Storage()
 
     def live_disk_name(self):
         """get the device name of the live-media we are booting from
@@ -108,11 +107,10 @@
         """
         if self._fake_devices:
             return self._fake_devices
-        from ovirtnode.ovirtfunctions import translate_multipath_device
-        dev_names, disk_dict = self._storage.get_udev_devices()
+        dev_names, disk_dict = self.get_udev_devices()
         devices = {}
         for _dev in dev_names:
-            dev = translate_multipath_device(_dev)
+            dev = self.translate_multipath_device(_dev)
             self.logger.debug("Checking device %s (%s)" % (dev, _dev))
             if dev in devices:
                 self.logger.warning("Device is already in dict: %s" % dev)
@@ -128,16 +126,156 @@
             infos = disk_dict[dev].split(",", 5)
             device = Device(dev, *infos)
             device.name = os.path.basename(device.name).replace(" ", "")
-            device.name = translate_multipath_device(device.name)
+            device.name = self.translate_multipath_device(device.name)
             if device.name in devices:
                 self.logger.debug("Device with same name already " +
                                   "exists: %s" % device.name)
             devices[device.path] = device
         return devices
 
+    def get_udev_devices(self):
+        self.disk_dict = {}
+        client = gudev.Client(['block'])
+        for device in client.query_by_subsystem("block"):
+            dev_name = device.get_property("DEVNAME")
+            dev_bus = device.get_property("ID_BUS")
+            dev_model = device.get_property("ID_MODEL")
+            dev_serial = device.get_property("ID_SERIAL")
+            dev_desc = device.get_property("ID_SCSI_COMPAT")
+            dev_size_cmd = "sfdisk -s %s" % dev_name
+            dev_size = process.pipe(dev_size_cmd)
+            size_failed = 0
+            if not device.get_property("ID_CDROM"):
+                try:
+                    dev_size = int(dev_size) / 1024 / 1024
+                except:
+                    size_failed = 1
+            if not dev_desc:
+                if "/dev/vd" in dev_name:
+                    dev_desc = "virtio disk"
+                elif dev_serial is not None:
+                    dev_desc = dev_serial
+                else:
+                    dev_desc = "unknown"
+            if (not device.get_property("ID_CDROM") and
+                    not "/dev/dm-" in dev_name and
+                    not "/dev/loop" in dev_name and size_failed == 0):
+                dev_name = self.translate_multipath_device(dev_name)
+                busmap = {
+                    "usb": "USB Device          ",
+                    "ata": "Local / FibreChannel",
+                    "scsi": "Local / FibreChannel",
+                    "cciss": "CCISS               "
+                }
+                if dev_bus in busmap:
+                    dev_bus = busmap[dev_bus]
+                elif "/dev/vd" in dev_name:
+                    dev_bus = "Local (Virtio)      "
+                else:
+                    dev_bus = "                    "
+
+                self.disk_dict[dev_name] = "%s,%s,%s,%s,%s,%s" % (dev_bus,
+                                                                  dev_name,
+                                                                  dev_size,
+                                                                  dev_desc,
+                                                                  dev_serial,
+                                                                  dev_model)
+        devs = self.get_dev_name()
+        return (sorted(devs), self.disk_dict)
+
+    def get_multipath_deps(self, mpath_device):
+        deplist = ""
+        #get dependencies for multipath device
+        deps_cmd = "dmsetup deps -u mpath-%s | sed 's/^.*: //' \
+        | sed 's/, /:/g' | sed 's/[\(\)]//g'" % mpath_device
+        deps_output = process.pipe(deps_cmd).strip()
+        for dep in deps_output.split():
+            device = self.get_sd_name(dep)
+            if device is not None:
+                deplist = "%s %s" % (device, deplist)
+        return deplist
+
+    def get_sd_name(self, id):
+        device_sys_cmd = "grep -H \"^%s$\" /sys/block/*/dev | cut -d: -f1" % id
+        device_sys_output = process.pipe(device_sys_cmd).strip()
+        if not device_sys_output is "":
+            device = os.path.basename(os.path.dirname(device_sys_output))
+            return device
+
+    def get_dev_name(self):
+        devices = []
+        # list separator
+        for d in os.listdir("/sys/block/"):
+            if re.match("^[hsv]+d", d):
+                devices.append("/dev/%s" % d)
+            byid_list_cmd = ("find /dev/disk/by-id -mindepth 1 -not -name " +
+                             "'*-part*' 2>/dev/null")
+            byid_list_output = process.pipe(byid_list_cmd).strip()
+        for d in byid_list_output.split():
+            d = os.readlink(d)
+            d_basename = os.path.basename(d)
+            udev_cmd = ("udevadm info --name=/dev/ %s --query=property|" +
+                        "grep -q  ^ID_BUS:" % d_basename)
+            if process.pipe(udev_cmd):
+                devices.append("/dev/%s" % d_basename)
+        # FIXME: workaround for detecting cciss devices
+        if os.path.exists("/dev/cciss"):
+            for d in os.listdir("/dev/cciss"):
+                if not re.match("p[0-9]+\$", d):
+                    devices.append("/dev/cciss/%s" % d)
+
+        # include multipath devices
+        devs_to_remove = ""
+        multipath_list_cmd = "dmsetup ls --target=multipath | cut -f1"
+        multipath_list_output = process.pipe(multipath_list_cmd).strip()
+
+        for d in multipath_list_output.split():
+            devices.append("/dev/mapper/%s" % d)
+            sd_devs = ""
+            sd_devs = self.get_multipath_deps(d)
+
+            dm_dev_cmd = ("multipath -ll \"%s\" | grep \"%s\" | " +
+                          "sed -r 's/^.*(dm-[0-9]+ ).*$/\\1/'") % (d, d)
+            dm_dev_output = process.pipe(dm_dev_cmd).strip()
+            devs_to_remove = ("%s %s %s" % (devs_to_remove, sd_devs,
+                                            dm_dev_output))
+        # Remove /dev/sd* devices that are part of a multipath device
+        dev_list = []
+        for d in devices:
+            if (os.path.basename(d) not in devs_to_remove and
+                    not "/dev/dm-" in d):
+                dev_list.append(d)
+
+        for dev in dev_list:
+            if dev_list.count(dev) > 1:
+                count = dev_list.count(dev)
+                while (count > 1):
+                    dev_list.remove(dev)
+                    count = count - 1
+        return dev_list
+
+    def translate_multipath_device(self, dev):
+        #trim so that only sdX is stored, but support passing /dev/sdX
+        self.logger.debug("Translating: %s" % dev)
+        if dev is None:
+            return False
+        if "/dev/mapper" in dev:
+            return dev
+        if "/dev/cciss" in dev:
+            cciss_dev_cmd = "cciss_id %s" % dev
+            output = process.pipe(cciss_dev_cmd)
+            dev = "/dev/mapper/" + output.strip()
+        dm_dev = dm_dev_cmd = "multipath -ll %s | egrep dm-[0-9]+" % dev
+        dm_dev_output = process.pipe(dm_dev_cmd).strip()
+        if not dm_dev_output:
+            return dev
+        self.logger.info("Translated to: /dev/mapper/%s" %
+                         dm_dev_output.split()[0])
+        return "/dev/mapper/"+dm_dev_output.split()[0]
+
 
 class Device(base.Base):
-    """Wrapps the information about a udev storage device
+    """Wraps the information about a udev storage device
     """
     path = None
     bus = None
diff --git a/src/ovirtnode/ovirtfunctions.py b/src/ovirtnode/ovirtfunctions.py
index ace96b5..6163505 100644
--- a/src/ovirtnode/ovirtfunctions.py
+++ b/src/ovirtnode/ovirtfunctions.py
@@ -42,6 +42,7 @@
 import ovirt.node.utils.system as osystem
 from ovirt.node.utils.console import TransactionProgress, Transaction
 from ovirtnode.network import *
+from ovirt.node.utils.storage import Devices
 
 OVIRT_CONFIG="/config"
 OVIRT_LOGFILE="/var/log/ovirt.log"
@@ -1307,7 +1308,8 @@
 
 # Cleans partition tables
 def wipe_partitions(_drive):
-    drive = translate_multipath_device(_drive)
+    devices = Devices()
+    drive = devices.translate_multipath_device(_drive)
     logger.info("Wiping partitions on: %s->%s" % (_drive, drive))
     logger.info("Removing HostVG")
     if os.path.exists("/dev/mapper/HostVG-Swap"):
@@ -1383,26 +1385,6 @@
     else:
         return False
 
-def translate_multipath_device(dev):
-    #trim so that only sdX is stored, but support passing /dev/sdX
-    logger.debug("Translating: %s" % dev)
-    if dev is None:
-        return False
-    if "/dev/mapper" in dev:
-        return dev
-    if "/dev/cciss" in dev:
-        cciss_dev_cmd = "cciss_id " + dev
-        cciss_dev = subprocess_closefds(cciss_dev_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
-        output, err = cciss_dev.communicate()
-        dev = "/dev/mapper/" + output.strip()
-    dm_dev_cmd = "multipath -ll '%s' | egrep dm-[0-9]+" % dev
-    dm_dev = subprocess_closefds(dm_dev_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
-    (dm_dev_output, dummy) = dm_dev.communicate()
-    if dm_dev.returncode > 0:
-        return dev
-    else:
-        logger.debug("Translated to: /dev/mapper/" + dm_dev_output.split()[0])
-        return "/dev/mapper/"+dm_dev_output.split()[0]
 
 def pwd_lock_check(user):
     passwd_cmd = "passwd -S %s" % user
diff --git a/src/ovirtnode/storage.py b/src/ovirtnode/storage.py
index 2e11997..0ae5416 100644
--- a/src/ovirtnode/storage.py
+++ b/src/ovirtnode/storage.py
@@ -27,6 +27,7 @@
 import subprocess
 import shlex
 from ovirtnode.iscsi import set_iscsi_initiator
+from ovirt.node.utils.storage import Devices
 
 logger = logging.getLogger(__name__)
 
@@ -54,6 +55,7 @@
         self.DATA_SIZE = -1
         # gpt or msdos partition table type
         self.LABEL_TYPE = "gpt"
+        self.devices = Devices()
         if "OVIRT_INIT" in OVIRT_VARS:
             _functions.OVIRT_VARS["OVIRT_INIT"] = \
                                 _functions.OVIRT_VARS["OVIRT_INIT"].strip(",")
@@ -62,7 +64,7 @@
                 init = _functions.OVIRT_VARS["OVIRT_INIT"].strip(",").split(",")
                 for disk in init:
                     skip = False
-                    translated_disk = _functions.translate_multipath_device(disk)
+                    translated_disk = self.devices.translate_multipath_device(disk)
                     if disk_count < 1:
                         self.ROOTDRIVE = translated_disk
                         if len(init) == 1:
@@ -76,14 +78,14 @@
                         if not skip:
                             self.HOSTVGDRIVE += "%s," % translated_disk
             else:
-                self.ROOTDRIVE = _functions.translate_multipath_device(
+                self.ROOTDRIVE =  self.devices.translate_multipath_device(
                                     _functions.OVIRT_VARS["OVIRT_INIT"])
-                self.HOSTVGDRIVE = _functions.translate_multipath_device(
+                self.HOSTVGDRIVE =  self.devices.translate_multipath_device(
                                     _functions.OVIRT_VARS["OVIRT_INIT"])
             if _functions.is_iscsi_install():
                 logger.info(self.BOOTDRIVE)
                 logger.info(self.ROOTDRIVE)
-                self.BOOTDRIVE = _functions.translate_multipath_device( \
+                self.BOOTDRIVE =  self.devices.translate_multipath_device( \
                                                                 self.ROOTDRIVE)
         if "OVIRT_OVERCOMMIT" in OVIRT_VARS:
             self.overcommit = OVIRT_VARS["OVIRT_OVERCOMMIT"]
@@ -126,7 +128,7 @@
         if "OVIRT_INIT_APP" in OVIRT_VARS:
             if self.SWAP2_SIZE != 0 or self.DATA2_SIZE != 0:
                 for drv in _functions.OVIRT_VARS["OVIRT_INIT_APP"].split(","):
-                    DRIVE = _functions.translate_multipath_device(drv)
+                    DRIVE =  self.devices.translate_multipath_device(drv)
                     self.APPVGDRIVE.append(DRIVE)
         else:
             if self.SWAP2_SIZE != 0 or self.DATA2_SIZE != 0:
@@ -141,7 +143,7 @@
         if self.ROOTDRIVE:
             hostvg_drives.append(self.ROOTDRIVE)
         # Translate to DM name as APPVG is using it
-        hostvg_drives = [_functions.translate_multipath_device(drv)
+        hostvg_drives = [ self.devices.translate_multipath_device(drv)
                          for drv in hostvg_drives]
         return Storage._xcheck_vgs(hostvg_drives, self.APPVGDRIVE)
 
@@ -264,157 +266,12 @@
             _functions.passthrough("blockdev --rereadpt \"%s\"" % drive, \
                                    logger.debug)
 
-    def get_sd_name(self, id):
-        device_sys_cmd = "grep -H \"^%s$\" /sys/block/*/dev | cut -d: -f1" % id
-        device_sys = _functions.subprocess_closefds(device_sys_cmd, shell=True,
-                                         stdout=subprocess.PIPE,
-                                         stderr=subprocess.STDOUT)
-        device_sys_output, device_sys_err = device_sys.communicate()
-        device_sys_output = device_sys_output.strip()
-        if not device_sys_output is "":
-            device = os.path.basename(os.path.dirname(device_sys_output))
-            return device
-
-    # gets the dependent block devices for multipath devices
-    def get_multipath_deps(self, mpath_device):
-        deplist = ""
-        #get dependencies for multipath device
-        deps_cmd = "dmsetup deps -u mpath-%s | sed 's/^.*: //' \
-        | sed 's/, /:/g' | sed 's/[\(\)]//g'" % mpath_device
-        deps = _functions.subprocess_closefds(deps_cmd, shell=True,
-                                   stdout=subprocess.PIPE,
-                                   stderr=subprocess.STDOUT)
-        deps_output, deps_err = deps.communicate()
-        for dep in deps_output.split():
-            device = self.get_sd_name(dep)
-            if device is not None:
-                deplist = "%s %s" % (device, deplist)
-        return deplist
-
-    # Find a usable/selected storage device.
-    # If there are none, give a diagnostic and return nonzero.
-    # If there is just one, e.g., /dev/sda, treat it as selected (see below).
-    # and return 0.  If there are two or more, make the user select one
-    # or decline.  Upon decline, return nonzero. Otherwise, print the
-    # selected name, then return 0.
-    # Sample output: /dev/sda
-    def get_dev_name(self):
-        devices = []
-        # list separator
-        for d in os.listdir("/sys/block/"):
-            if re.match("^[hsv]+d", d):
-                devices.append("/dev/%s" % d)
-            byid_list_cmd = ("find /dev/disk/by-id -mindepth 1 -not -name " +
-                            "'*-part*' 2>/dev/null")
-            byid_list = _functions.subprocess_closefds(byid_list_cmd,
-                                            shell=True,
-                                            stdout=subprocess.PIPE,
-                                            stderr=subprocess.STDOUT)
-            byid_list_output, byid_list_err = byid_list.communicate()
-        for d in byid_list_output.split():
-            d = os.readlink(d)
-            d_basename = os.path.basename(d)
-            udev_cmd = ("udevadm info --name=/dev/" + d_basename +
-                        " --query=property | grep -q ^ID_BUS: &>>/dev/null")
-            if _functions.system_closefds(udev_cmd):
-                devices.append("/dev/%s" % d_basename)
-        # FIXME: workaround for detecting cciss devices
-        if os.path.exists("/dev/cciss"):
-            for d in os.listdir("/dev/cciss"):
-                if not re.match("p[0-9]+\$", d):
-                    devices.append("/dev/cciss/%s" % d)
-
-        # include multipath devices
-        devs_to_remove = ""
-        multipath_list_cmd = "dmsetup ls --target=multipath | cut -f1"
-        multipath_list = _functions.subprocess_closefds(multipath_list_cmd,
-                                             shell=True,
-                                             stdout=subprocess.PIPE,
-                                             stderr=subprocess.STDOUT)
-        multipath_list_output, multipath_list_err = multipath_list.communicate()
-
-        for d in multipath_list_output.split():
-            devices.append("/dev/mapper/%s" % d)
-            sd_devs = ""
-            sd_devs = self.get_multipath_deps(d)
-
-            dm_dev_cmd = ("multipath -ll \"%s\" | grep \"%s\" | " +
-                          "sed -r 's/^.*(dm-[0-9]+ ).*$/\\1/'") % (d, d)
-            dm_dev = _functions.subprocess_closefds(dm_dev_cmd, shell=True,
-                                         stdout=subprocess.PIPE,
-                                         stderr=subprocess.STDOUT)
-            dm_dev_output, dm_dev_err = dm_dev.communicate()
-            devs_to_remove = ("%s %s %s" % (devs_to_remove, sd_devs,
-                                          dm_dev_output))
-        # Remove /dev/sd* devices that are part of a multipath device
-        dev_list = []
-        for d in devices:
-            if (os.path.basename(d) not in devs_to_remove and
-                    not "/dev/dm-" in d):
-                dev_list.append(d)
-
-        for dev in dev_list:
-            if dev_list.count(dev) > 1:
-                count = dev_list.count(dev)
-                while (count > 1):
-                    dev_list.remove(dev)
-                    count = count - 1
-        return dev_list
-
-    def get_udev_devices(self):
-        self.disk_dict = {}
-        client = gudev.Client(['block'])
-        for device in client.query_by_subsystem("block"):
-            dev_name = device.get_property("DEVNAME")
-            dev_bus = device.get_property("ID_BUS")
-            dev_model = device.get_property("ID_MODEL")
-            dev_serial = device.get_property("ID_SERIAL")
-            dev_desc = device.get_property("ID_SCSI_COMPAT")
-            dev_size_cmd = "sfdisk -s %s 2>/dev/null" % dev_name
-            dev_size_popen = _functions.subprocess_closefds(dev_size_cmd, shell=True,
-                       stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-            dev_size, dev_size_err = dev_size_popen.communicate()
-            size_failed = 0
-            if not device.get_property("ID_CDROM"):
-                try:
-                    dev_size = int(dev_size) / 1024 / 1024
-                except:
-                    size_failed = 1
-            if not dev_desc:
-                if "/dev/vd" in dev_name:
-                    dev_desc = "virtio disk"
-                elif dev_serial is not None:
-                    dev_desc = dev_serial
-                else:
-                    dev_desc = "unknown"
-            if (not device.get_property("ID_CDROM") and
-                    not "/dev/dm-" in dev_name and
-                    not "/dev/loop" in dev_name and size_failed == 0):
-                dev_name = _functions.translate_multipath_device(dev_name)
-                busmap = { \
-                    "usb": "USB Device          ", \
-                    "ata": "Local / FibreChannel", \
-                    "scsi": "Local / FibreChannel", \
-                    "cciss": "CCISS               " \
-                }
-                if dev_bus in busmap:
-                    dev_bus = busmap[dev_bus]
-                elif "/dev/vd" in dev_name:
-                    dev_bus = "Local (Virtio)      "
-                else:
-                    dev_bus = "                    "
-
-                self.disk_dict[dev_name] = "%s,%s,%s,%s,%s,%s" % (dev_bus,
-                                            dev_name, dev_size, dev_desc,
-                                            dev_serial, dev_model)
-        devs = self.get_dev_name()
-        return (sorted(devs), self.disk_dict)
 
     def create_hostvg(self):
         logger.info("Creating LVM partition")
         self.physical_vols = []
         for drv in self.HOSTVGDRIVE.strip(",").split(","):
-            drv = _functions.translate_multipath_device(drv)
+            drv =  self.devices.translate_multipath_device(drv)
             if drv != "":
                 if self.ROOTDRIVE == drv and not _functions.is_iscsi_install():
                     self.reread_partitions(self.ROOTDRIVE)
@@ -827,7 +684,7 @@
                               str(partbootbackup) + "\"")
             _functions.system("ln -snf \"" + partbootbackup +
                    "\" /dev/disk/by-label/BootBackup")
-            self.ISCSIDRIVE = _functions.translate_multipath_device(
+            self.ISCSIDRIVE = self.devices.translate_multipath_device(
                                _functions.OVIRT_VARS["OVIRT_ISCSI_INIT"])
             logger.debug(self.ISCSIDRIVE)
             if self.create_iscsiroot():


-- 
To view, visit http://gerrit.ovirt.org/21660
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I37df9b1cf77b3f4c89eb5695a9bc1e8277b918b6
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Joey Boggs <jboggs at redhat.com>



More information about the node-patches mailing list