[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