Change in vdsm[master]: multipath: Remove unused 'deduceType'
by ykaplan@redhat.com
Yeela Kaplan has uploaded a new change for review.
Change subject: multipath: Remove unused 'deduceType'
......................................................................
multipath: Remove unused 'deduceType'
Change-Id: I37a94c3d67641f1c78d8fbecd63cbf1480c6e1b0
Signed-off-by: Yeela Kaplan <ykaplan(a)redhat.com>
---
M vdsm/storage/multipath.py
1 file changed, 0 insertions(+), 7 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/63/13363/1
diff --git a/vdsm/storage/multipath.py b/vdsm/storage/multipath.py
index 94801ca..5fdaa27 100644
--- a/vdsm/storage/multipath.py
+++ b/vdsm/storage/multipath.py
@@ -184,13 +184,6 @@
raise se.MultipathRestartError()
-def deduceType(a, b):
- if a == b:
- return a
- else:
- return DEV_MIXED
-
-
def getDeviceBlockSizes(dev):
devName = os.path.basename(dev)
logical = int(file(os.path.join("/sys/block/", devName,
--
To view, visit http://gerrit.ovirt.org/13363
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I37a94c3d67641f1c78d8fbecd63cbf1480c6e1b0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yeela Kaplan <ykaplan(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: Adding monitorDomains.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Adding monitorDomains.
......................................................................
Adding monitorDomains.
Making repoStats pool independent.
Change-Id: I9f148764ac030730c93bfd9c8da25a7ea434dc33
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/hsm.py
1 file changed, 19 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/14674/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index d3e1beb..3fb0c30 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -40,6 +40,7 @@
from vdsm.config import config
import sp
+import domainMonitor
import sd
import blockSD
import nfsSD
@@ -93,6 +94,7 @@
QEMU_READABLE_TIMEOUT = 30
+HSM_DOM_MON_LOCK = "HsmDomainMonitorLock"
def public(f=None, **kwargs):
if f is None:
@@ -395,6 +397,9 @@
name="storageRefresh")
storageRefreshThread.daemon = True
storageRefreshThread.start()
+
+ monitorInterval = config.getint('irs', 'sd_health_check_delay')
+ self.domainMonitor = domainMonitor.DomainMonitor(monitorInterval)
def _hsmSchedule(self, name, func, *args):
self.taskMng.scheduleJob("hsm", self.tasksDir, vars.task,
@@ -934,7 +939,10 @@
"spUUID=%s, msdUUID=%s, masterVersion=%s, hostID=%s, "
"scsiKey=%s" % (spUUID, msdUUID, masterVersion,
hostID, scsiKey)))
- return self._connectStoragePool(spUUID, hostID, scsiKey, msdUUID,
+ with rmanager.acquireResource(STORAGE, HSM_DOM_MON_LOCK,
+ rm.LockType.exclusive):
+ self.domainMonitor.close()
+ return self._connectStoragePool(spUUID, hostID, scsiKey, msdUUID,
masterVersion, options)
def _connectStoragePool(self, spUUID, hostID, scsiKey, msdUUID,
@@ -3578,3 +3586,13 @@
result[d] = repo_stats[d]['result']
return result
+
+ @public
+ def monitorDomains(self, sdUUIDs, hostID, options=None):
+ with rmanager.acquireResource(STORAGE, HSM_DOM_MON_LOCK,
+ rm.LockType.exclusive):
+ if self.pools:
+ raise se.StoragePoolConnected()
+ self.domainMonitor.close()
+ for sdUUID in sdUUIDs:
+ self.domainMonitor.startMonitoring(sdUUID, hostId)
--
To view, visit http://gerrit.ovirt.org/14674
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9f148764ac030730c93bfd9c8da25a7ea434dc33
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: mount: Reassign mount specification in case of backup option
by ykaplan@redhat.com
Yeela Kaplan has uploaded a new change for review.
Change subject: mount: Reassign mount specification in case of backup option
......................................................................
mount: Reassign mount specification in case of backup option
When using glusterfs volumes the backup option
'backupvolfile-server' allows mount to an alternative volume
when mount source not available.
Change-Id: I3166c6863dffa297bc0adcdeb4c22f810d18de8e
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=922744
Signed-off-by: Yeela Kaplan <ykaplan(a)redhat.com>
---
M vdsm/storage/mount.py
M vdsm/storage/storageServer.py
2 files changed, 44 insertions(+), 20 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/34/16534/1
diff --git a/vdsm/storage/mount.py b/vdsm/storage/mount.py
index 90cacc7..8cade18 100644
--- a/vdsm/storage/mount.py
+++ b/vdsm/storage/mount.py
@@ -187,6 +187,15 @@
raise OSError(errno.ENOENT, 'device %s not mounted' % device)
+def _getRecord(spec, file):
+ for record in _iterMountRecords():
+ if (record.fs_spec == spec and record.fs_file == file):
+ return record
+
+ raise OSError(errno.ENOENT,
+ "Mount of `%s` at `%s` does not exist" % (spec, file))
+
+
class Mount(object):
def __init__(self, fs_spec, fs_file):
self.fs_spec = normpath(fs_spec)
@@ -261,14 +270,7 @@
return True
def getRecord(self):
- for record in _iterMountRecords():
- if (record.fs_spec == self.fs_spec and
- record.fs_file == self.fs_file):
- return record
-
- raise OSError(errno.ENOENT,
- "Mount of `%s` at `%s` does not exist" %
- (self.fs_spec, self.fs_file))
+ return _getRecord(self.fs_spec, self.fs_file)
def __repr__(self):
return ("<Mount fs_spec='%s' fs_file='%s'>" %
diff --git a/vdsm/storage/storageServer.py b/vdsm/storage/storageServer.py
index 023f607..515ebd9 100644
--- a/vdsm/storage/storageServer.py
+++ b/vdsm/storage/storageServer.py
@@ -197,14 +197,14 @@
self._remotePath.replace("_",
"__").replace("/", "_"))
- def connect(self):
+ def createConnection(self):
if self._mount.isMounted():
return
fileUtils.createdir(self._getLocalPath())
try:
- self._mount.mount(self.options, self._vfsType)
+ self._mount.mount(self.options, self.vfsType)
except MountError as e:
self.log.error("Mount failed: %s", e, exc_info=True)
try:
@@ -214,17 +214,21 @@
self._getLocalPath(), exc_info=True)
raise e
- else:
+ def validateConnection(self):
+ try:
+ fileSD.validateDirAccess(
+ self.getMountObj().getRecord().fs_file)
+ except se.StorageServerAccessPermissionError as e:
try:
- fileSD.validateDirAccess(
- self.getMountObj().getRecord().fs_file)
- except se.StorageServerAccessPermissionError as e:
- try:
- self.disconnect()
- except OSError:
- self.log.warn("Error while disconnecting after access"
- "problem", exc_info=True)
- raise e
+ self.disconnect()
+ except OSError:
+ self.log.warn("Error while disconnecting after access"
+ "problem", exc_info=True)
+ raise e
+
+ def connect(self):
+ self.createConnection()
+ self.validateConnection()
def isConnected(self):
return self._mount.isMounted()
@@ -255,6 +259,24 @@
def getLocalPathBase(cls):
return os.path.join(MountConnection.getLocalPathBase(), "glusterSD")
+ def updateBackup(self):
+ if self.options and not self.isConnected():
+ for opt in self.options.split(','):
+ if opt.strip().startswith("backupvolfile-server"):
+ backupSpec = opt.split('=', 1)[1].strip()
+ try:
+ mount._getRecord(backupSpec, self._mount.fs_file)
+ except OSError as e:
+ self.log.warning("Mount of backup failed: %s", e)
+ else:
+ self._mount.fs_spec = backupSpec
+ return
+
+ def connect(self):
+ self.createConnection()
+ self.updateBackup()
+ self.validateConnection()
+
class NFSConnection(object):
DEFAULT_OPTIONS = ["soft", "nosharecache"]
--
To view, visit http://gerrit.ovirt.org/16534
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3166c6863dffa297bc0adcdeb4c22f810d18de8e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yeela Kaplan <ykaplan(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: More precise exception when multipath failed.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: More precise exception when multipath failed.
......................................................................
More precise exception when multipath failed.
In spite that any OSError is translated to ENODEV in devicemapper,
the complete info is needed.
Related to BZ#965184.
Change-Id: I1b87e8e91b838db2c8a98c9afbbc998e8f4c792a
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/devicemapper.py
1 file changed, 4 insertions(+), 5 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/45/17145/1
diff --git a/vdsm/storage/devicemapper.py b/vdsm/storage/devicemapper.py
index 451c736..ff1fb7a 100644
--- a/vdsm/storage/devicemapper.py
+++ b/vdsm/storage/devicemapper.py
@@ -34,11 +34,10 @@
devlinkPath = DMPATH_FORMAT % deviceMultipathName
try:
devStat = os.stat(devlinkPath)
- except OSError:
- raise OSError(errno.ENODEV, "Could not find dm device named `%s`" %
- deviceMultipathName)
-
- return "dm-%d" % os.minor(devStat.st_rdev)
+ except OSError as e:
+ raise OSError(errno.ENODEV, "%s: %s" % (deviceMultipathName, e))
+ else:
+ return "dm-%d" % os.minor(devStat.st_rdev)
def findDev(major, minor):
--
To view, visit http://gerrit.ovirt.org/17145
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1b87e8e91b838db2c8a98c9afbbc998e8f4c792a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: Avoid hsm image deletions.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Avoid hsm image deletions.
......................................................................
Avoid hsm image deletions.
This code was introduced to fix BZ#560389.
The bug was in Image.delete() which was already removed.
Related to BZ#965184.
Change-Id: Ie1ec2ea8793a4ad63453559bc5f663b65f9b9336
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/blockSD.py
M vdsm/storage/fileSD.py
M vdsm/storage/sd.py
3 files changed, 0 insertions(+), 24 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/93/17193/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 72b3ef0..6507cbf 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -416,7 +416,6 @@
# _extendlock is used to prevent race between
# VG extend and LV extend.
self._extendlock = threading.Lock()
- self.imageGarbageCollector()
self._registerResourceNamespaces()
self._lastUncachedSelftest = 0
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 1651825..0042aab 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -165,7 +165,6 @@
if not self.oop.fileUtils.pathExists(self.metafile):
raise se.StorageDomainMetadataNotFound(sdUUID, self.metafile)
- self.imageGarbageCollector()
self._registerResourceNamespaces()
@property
@@ -515,20 +514,6 @@
mount.getMountFromTarget(self.mountpoint).umount()
raise se.FileStorageDomainStaleNFSHandle()
raise
-
- def imageGarbageCollector(self):
- """
- Image Garbage Collector
- remove the remnants of the removed images (they could be left sometimes
- (on NFS mostly) due to lazy file removal
- """
- removedPattern = os.path.join(self.domaindir, sd.DOMAIN_IMAGES,
- sd.REMOVED_IMAGE_PREFIX + '*')
- removedImages = self.oop.glob.glob(removedPattern)
- self.log.debug("Removing remnants of deleted images %s" %
- removedImages)
- for imageDir in removedImages:
- self.oop.fileUtils.cleanupdir(imageDir)
def templateRelink(self, imgUUID, volUUID):
"""
diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py
index fd79059..c764d2d 100644
--- a/vdsm/storage/sd.py
+++ b/vdsm/storage/sd.py
@@ -786,11 +786,3 @@
def isData(self):
return self.getMetaParam(DMDK_CLASS) == DATA_DOMAIN
-
- def imageGarbageCollector(self):
- """
- Image Garbage Collector
- remove the remnants of the removed images (they could be left sometimes
- (on NFS mostly) due to lazy file removal
- """
- pass
--
To view, visit http://gerrit.ovirt.org/17193
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie1ec2ea8793a4ad63453559bc5f663b65f9b9336
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: Refactor StoragePool.getPoolParams()
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Refactor StoragePool.getPoolParams()
......................................................................
Refactor StoragePool.getPoolParams()
Change-Id: Ibbeaaaf67a39f3ca8b27252fc631a91f266d1adc
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/sp.py
1 file changed, 4 insertions(+), 15 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/19232/1
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 38eda39..d5a8b4e 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -734,21 +734,10 @@
@unsecured
def getPoolParams(self):
- file = open(self._poolFile, "r")
- for line in file:
- pair = line.strip().split("=")
- if len(pair) == 2:
- if pair[0] == "id":
- hostId = int(pair[1])
- elif pair[0] == "scsiKey":
- scsiKey = pair[1]
- elif pair[0] == "sdUUID":
- msdUUID = pair[1]
- elif pair[0] == "version":
- masterVersion = pair[1]
- file.close()
-
- return hostId, scsiKey, msdUUID, masterVersion
+ lines = open(self._poolFile, "r").readlines()
+ params = dict(line.strip().split('=') for line in lines if '=' in line)
+ return tuple(params[k] for k in ('hostId', 'scsiKey', 'msdUUID',
+ 'masterVersion'))
@unsecured
def createMaster(self, poolName, domain, masterVersion, leaseParams):
--
To view, visit http://gerrit.ovirt.org/19232
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibbeaaaf67a39f3ca8b27252fc631a91f266d1adc
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: vdsm: Get underlying device info moved to Device classes
by Vinzenz Feenstra
Vinzenz Feenstra has uploaded a new change for review.
Change subject: vdsm: Get underlying device info moved to Device classes
......................................................................
vdsm: Get underlying device info moved to Device classes
Change-Id: I8f797baece3601b885777784f611b420523828f7
Signed-off-by: Vinzenz Feenstra <vfeenstr(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 379 insertions(+), 396 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/19732/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 4f2f35d..d23cd21 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -1196,6 +1196,98 @@
element.setAttrs(**elemAttrs)
return element
+ @classmethod
+ def _getDeviceAlias(cls, device):
+ return device.getElementsByTagName('alias')[0].getAttribute('name')
+
+ @classmethod
+ def _getDeviceAddress(cls, device):
+ """
+ Obtain device's address from libvirt
+ """
+ address = {}
+ dom = device.getElementsByTagName('address')[0]
+ # Parse address to create proper dictionary.
+ # Libvirt device's address definition is:
+ # PCI = {'type':'pci', 'domain':'0x0000', 'bus':'0x00',
+ # 'slot':'0x0c', 'function':'0x0'}
+ # IDE = {'type':'drive', 'controller':'0', 'bus':'0', 'unit':'0'}
+ for key in dom.attributes.keys():
+ address[key.strip()] = dom.getAttribute(key).strip()
+
+ return address
+
+ @classmethod
+ def _defaultUpdate(cls, element, type, desc, devices, conf, **kwargs):
+ getAddress = kwargs.get('address', True)
+ getAddressRequired = False
+ if 'getAddressRequired' in kwargs:
+ getAddressRequired = kwargs.get('aliasRequired')
+ getAddress = getAddressRequired
+
+ default = desc.getElementsByTagName(element)
+ for x in default:
+ if getAddressRequired:
+ if not x.getElementsByTagName('address'):
+ continue
+
+ address = None
+ if getAddress:
+ address = cls._getDeviceAddress(x)
+
+ alias = cls._getDeviceAliasName(x)
+
+ for x in devices[type]:
+ if address and not hasattr(x, 'address'):
+ x.address = address
+ if alias and not hasattr(x, 'alias'):
+ x.alias = alias
+
+ for dev in conf['devices']:
+ if dev['type'] == type:
+ if address and not dev.get('address'):
+ dev['address'] = address
+ if alias and not dev.get('alias'):
+ dev['alias'] = alias
+
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ pass
+
+
+class UnknownDevice(VmDevice):
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain unknown devices info from libvirt.
+
+ Unknown device is a device that has an address but wasn't
+ passed during VM creation request.
+ """
+ def isKnownDevice(alias):
+ for dev in conf['devices']:
+ if dev.get('alias') == alias:
+ return True
+ return False
+
+ for x in desc.childNodes:
+ # Ignore empty nodes and devices without address
+ if (x.nodeName == '#text' or
+ not x.getElementsByTagName('address')):
+ continue
+
+ alias = cls._getDeviceAliasName(x)
+ if not isKnownDevice(alias):
+ address = cls._getDeviceAddress(x)
+ # I general case we assume that device has attribute 'type',
+ # if it hasn't getAttribute returns ''.
+ device = x.getAttribute('type')
+ newDev = {'type': x.nodeName,
+ 'alias': alias,
+ 'device': device,
+ 'address': address}
+ conf['devices'].append(newDev)
+
class GeneralDevice(VmDevice):
@@ -1219,6 +1311,52 @@
return ctrl
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain controller devices info from libvirt.
+ """
+ controllers = desc.getElementsByTagName('controller')
+ for x in controllers:
+ # Ignore controller devices without address
+ if not x.getElementsByTagName('address'):
+ continue
+ alias = cls._getDeviceAliasName(x)
+ device = x.getAttribute('type')
+ # Get model and index. Relevant for USB controllers.
+ model = x.getAttribute('model')
+ index = x.getAttribute('index')
+
+ # Get controller address
+ address = cls._getDeviceAddress(x)
+
+ # In case the controller has index and/or model, they
+ # are compared. Currently relevant for USB controllers.
+ for ctrl in devices[CONTROLLER_DEVICES]:
+ if ((ctrl.device == device) and
+ (not hasattr(ctrl, 'index') or ctrl.index == index) and
+ (not hasattr(ctrl, 'model') or ctrl.model == model)):
+ ctrl.alias = alias
+ ctrl.address = address
+ # Update vm's conf with address for known controller devices
+ # In case the controller has index and/or model, they
+ # are compared. Currently relevant for USB controllers.
+ knownDev = False
+ for dev in conf['devices']:
+ if ((dev['type'] == CONTROLLER_DEVICES) and
+ (dev['device'] == device) and
+ (not 'index' in dev or dev['index'] == index) and
+ (not 'model' in dev or dev['model'] == model)):
+ dev['address'] = address
+ dev['alias'] = alias
+ knownDev = True
+ # Add unknown controller device to vm's conf
+ if not knownDev:
+ conf['devices'].append({'type': CONTROLLER_DEVICES,
+ 'device': device,
+ 'address': address,
+ 'alias': alias})
+
class VideoDevice(VmDevice):
@@ -1235,6 +1373,34 @@
video.appendChildWithArgs('model', type=self.device, **sourceAttrs)
return video
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain video devices info from libvirt.
+ """
+ videos = desc.getElementsByTagName('video')
+ for x in videos:
+ alias = cls._getDeviceAliasName(x)
+ # Get video card address
+ address = cls._getDeviceAddress(x)
+
+ # FIXME. We have an identification problem here.
+ # Video card device has not unique identifier, except the alias
+ # (but backend not aware to device's aliases). So, for now
+ # we can only assign the address according to devices order.
+ for vc in devices[VIDEO_DEVICES]:
+ if not hasattr(vc, 'address') or not hasattr(vc, 'alias'):
+ vc.alias = alias
+ vc.address = address
+ break
+ # Update vm's conf with address
+ for dev in conf['devices']:
+ if ((dev['type'] == VIDEO_DEVICES) and
+ (not dev.get('address') or not dev.get('alias'))):
+ dev['address'] = address
+ dev['alias'] = alias
+ break
+
class SoundDevice(VmDevice):
@@ -1245,6 +1411,34 @@
sound = self.createXmlElem('sound', None, ['address'])
sound.setAttrs(model=self.device)
return sound
+
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain sound devices info from libvirt.
+ """
+ soundDevices = desc.getElementsByTagName('sound')
+ for x in soundDevices:
+ alias = cls._getDeviceAliasName(x)
+ # Get sound card address
+ address = cls._getDeviceAddress(x)
+
+ # FIXME. We have an identification problem here.
+ # Sound device has not unique identifier, except the alias
+ # (but backend not aware to device's aliases). So, for now
+ # we can only assign the address according to devices order.
+ for sc in devices[SOUND_DEVICES]:
+ if not hasattr(sc, 'address') or not hasattr(sc, 'alias'):
+ sc.alias = alias
+ sc.address = address
+ break
+ # Update vm's conf with address
+ for dev in conf['devices']:
+ if ((dev['type'] == SOUND_DEVICES) and
+ (not dev.get('address') or not dev.get('alias'))):
+ dev['address'] = address
+ dev['alias'] = alias
+ break
class NetworkInterfaceDevice(VmDevice):
@@ -1337,6 +1531,73 @@
bandwidth.appendChildWithArgs('outbound', **outbound)
iface.appendChild(bandwidth)
return iface
+
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain network interface info from libvirt.
+ """
+ # TODO use xpath instead of parseString (here and elsewhere)
+ interfaces = desc.getElementsByTagName('interface')
+ for x in interfaces:
+ devType = x.getAttribute('type')
+ mac = x.getElementsByTagName('mac')[0].getAttribute('address')
+ alias = cls._getDeviceAliasName(x)
+ if devType == 'hostdev':
+ name = alias
+ model = 'passthrough'
+ else:
+ name = x.getElementsByTagName('target')[0].getAttribute('dev')
+ model = x.getElementsByTagName('model')[0].getAttribute('type')
+
+ network = None
+ try:
+ if x.getElementsByTagName('link')[0].getAttribute('state') == \
+ 'down':
+ linkActive = False
+ else:
+ linkActive = True
+ except IndexError:
+ linkActive = True
+ source = x.getElementsByTagName('source')
+ if source:
+ network = source[0].getAttribute('bridge')
+ if not network:
+ network = source[0].getAttribute('network')
+ network = network[len(netinfo.LIBVIRT_NET_PREFIX):]
+
+ # Get nic address
+ address = cls._getDeviceAddress(x)
+ for nic in devices[NIC_DEVICES]:
+ if nic.macAddr.lower() == mac.lower():
+ nic.name = name
+ nic.alias = alias
+ nic.address = address
+ nic.linkActive = linkActive
+ # Update vm's conf with address for known nic devices
+ knownDev = False
+ for dev in conf['devices']:
+ if (dev['type'] == NIC_DEVICES and
+ dev['macAddr'].lower() == mac.lower()):
+ dev['address'] = address
+ dev['alias'] = alias
+ dev['name'] = name
+ dev['linkActive'] = linkActive
+ knownDev = True
+ # Add unknown nic device to vm's conf
+ if not knownDev:
+ nicDev = {'type': NIC_DEVICES,
+ 'device': devType,
+ 'macAddr': mac,
+ 'nicModel': model,
+ 'address': address,
+ 'alias': alias,
+ 'name': name,
+ 'linkActive': linkActive}
+ if network:
+ nicDev['network'] = network
+ conf['devices'].append(nicDev)
+
class Drive(VmDevice):
@@ -1625,6 +1886,71 @@
return diskelem
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain block devices info from libvirt.
+ """
+ disks = desc.getElementsByTagName('disk')
+ # FIXME! We need to gather as much info as possible from the libvirt.
+ # In the future we can return this real data to management instead of
+ # vm's conf
+ for x in disks:
+ sources = x.getElementsByTagName('source')
+ if sources:
+ devPath = (sources[0].getAttribute('file') or
+ sources[0].getAttribute('dev'))
+ else:
+ devPath = ''
+
+ target = x.getElementsByTagName('target')
+ name = target[0].getAttribute('dev') if target else ''
+ alias = cls._getDeviceAliasName(x)
+ readonly = bool(x.getElementsByTagName('readonly'))
+ boot = x.getElementsByTagName('boot')
+ bootOrder = boot[0].getAttribute('order') if boot else ''
+
+ devType = x.getAttribute('device')
+ if devType == 'disk':
+ # raw/qcow2
+ drv = x.getElementsByTagName('driver')[0].getAttribute('type')
+ else:
+ drv = 'raw'
+ # Get disk address
+ address = cls._getDeviceAddress(x)
+
+ for d in devices[DISK_DEVICES]:
+ if d.path == devPath:
+ d.name = name
+ d.type = devType
+ d.drv = drv
+ d.alias = alias
+ d.address = address
+ d.readonly = readonly
+ if bootOrder:
+ d.bootOrder = bootOrder
+ # Update vm's conf with address for known disk devices
+ knownDev = False
+ for dev in conf['devices']:
+ if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
+ dev['name'] = name
+ dev['address'] = address
+ dev['alias'] = alias
+ dev['readonly'] = str(readonly)
+ if bootOrder:
+ dev['bootOrder'] = bootOrder
+ knownDev = True
+ # Add unknown disk device to vm's conf
+ if not knownDev:
+ iface = 'ide' if address['type'] == 'drive' else 'pci'
+ diskDev = {'type': DISK_DEVICES, 'device': devType,
+ 'iface': iface, 'path': devPath, 'name': name,
+ 'address': address, 'alias': alias,
+ 'readonly': str(readonly)}
+ if bootOrder:
+ diskDev['bootOrder'] = bootOrder
+ conf['devices'].append(diskDev)
+
class BalloonDevice(VmDevice):
@@ -1640,6 +1966,15 @@
m = self.createXmlElem(self.device, None, ['address'])
m.setAttrs(model=self.specParams['model'])
return m
+
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain balloon device info from libvirt.
+ """
+ balloon = desc.getElementsByTagName('memballoon')
+ cls._defaultUpdate('watchdog', WATCHDOG_DEVICES, desc, devices, conf,
+ addressRequired=False)
class WatchdogDevice(VmDevice):
@@ -1657,6 +1992,14 @@
action=self.specParams['action'])
return m
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain watchdog device info from libvirt.
+ """
+ cls._defaultUpdate('watchdog', WATCHDOG_DEVICES, desc, devices, conf,
+ addressRequired=True)
+
class SmartCardDevice(VmDevice):
def getXML(self):
@@ -1673,6 +2016,13 @@
sourceAttrs['type'] = self.specParams['type']
card.setAttrs(**sourceAttrs)
return card
+
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain smartcard device info from libvirt.
+ """
+ cls._defaultUpdate('smartcard', SMARTCARD_DEVICES, desc, devices, conf)
class RedirDevice(VmDevice):
@@ -1700,6 +2050,13 @@
m.appendChildWithArgs('target', type='virtio', port='0')
return m
+ @classmethod
+ def updateFromDesc(cls, desc, devices, conf):
+ """
+ Obtain the alias for the console device from libvirt
+ """
+ cls._defaultUpdate('console', CONSOLE_DEVICES, desc, devices, conf,
+ address=False)
class Vm(object):
"""
@@ -1713,6 +2070,18 @@
# limit threads number until the libvirt lock will be fixed
_ongoingCreations = threading.BoundedSemaphore(4)
MigrationSourceThreadClass = MigrationSourceThread
+ DeviceMapping = ((DISK_DEVICES, Drive),
+ (NIC_DEVICES, NetworkInterfaceDevice),
+ (SOUND_DEVICES, SoundDevice),
+ (VIDEO_DEVICES, VideoDevice),
+ (CONTROLLER_DEVICES, ControllerDevice),
+ (GENERAL_DEVICES, GeneralDevice),
+ (BALLOON_DEVICES, BalloonDevice),
+ (WATCHDOG_DEVICES, WatchdogDevice),
+ (CONSOLE_DEVICES, ConsoleDevice),
+ (REDIR_DEVICES, RedirDevice),
+ (SMARTCARD_DEVICES, SmartCardDevice))
+
def _makeChannelPath(self, deviceName):
return constants.P_LIBVIRT_VMCHANNELS + self.id + '.' + deviceName
@@ -2747,7 +3116,7 @@
self._qemuguestSocketFile.decode('utf-8'),
_QEMU_GA_DEVICE_NAME)
domxml.appendInput()
- domxml.appendGraphics()
+ domxml.appendGraphics()
self._appendDevices(domxml)
@@ -2785,19 +3154,12 @@
Obtain underlying vm's devices info from libvirt.
"""
devicesXml = self._getDevicesXml()
- self._getUnderlyingNetworkInterfaceInfo(devicesXml=devicesXml)
- self._getUnderlyingDriveInfo(devicesXml=devicesXml)
+ for _, cls in self.DeviceMapping:
+ cls.updateFromDesc(devicesXml, self._devices, self.conf)
self._getUnderlyingDisplayPort(xml=self._lastXMLDesc.dom())
- self._getUnderlyingSoundDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingVideoDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingControllerDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingBalloonDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingWatchdogDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingSmartcardDeviceInfo(devicesXml=devicesXml)
- self._getUnderlyingConsoleDeviceInfo(devicesXml=devicesXml)
self._updateAgentChannels(devicesXml=devicesXml)
# Obtain info of all unknown devices. Must be last!
- self._getUnderlyingUnknownDeviceInfo(devicesXml=devicesXml)
+ UnknownDevice.updateFromDesc(devicesXml, self._devices, self.conf)
def _updateAgentChannels(self, devicesXml):
"""
@@ -2914,19 +3276,7 @@
else:
devices = self.getConfDevices()
- devMap = {DISK_DEVICES: Drive,
- NIC_DEVICES: NetworkInterfaceDevice,
- SOUND_DEVICES: SoundDevice,
- VIDEO_DEVICES: VideoDevice,
- CONTROLLER_DEVICES: ControllerDevice,
- GENERAL_DEVICES: GeneralDevice,
- BALLOON_DEVICES: BalloonDevice,
- WATCHDOG_DEVICES: WatchdogDevice,
- REDIR_DEVICES: RedirDevice,
- CONSOLE_DEVICES: ConsoleDevice,
- SMARTCARD_DEVICES: SmartCardDevice}
-
- for devType, devClass in devMap.items():
+ for devType, devClass in self.DeviceMapping:
for dev in devices[devType]:
self._devices[devType].append(devClass(self.conf, self.log,
**dev))
@@ -3066,10 +3416,9 @@
with self._confLock:
self.conf['devices'].append(nicParams)
self.saveState()
- self._getUnderlyingNetworkInterfaceInfo(
- devicesXml=self._getDevicesXml())
- hooks.after_nic_hotplug(nicXml, self.conf,
- params=customProps)
+ NetworkInterfaceDevice.updateFromDesc(self._getDevicesXml(),
+ self._devices, self.conf)
+ hooks.after_nic_hotplug(nicXml, self.conf, params=customProps)
if hasattr(nic, 'portMirroring'):
mirroredNetworks = []
@@ -3327,7 +3676,8 @@
with self._confLock:
self.conf['devices'].append(diskParams)
self.saveState()
- self._getUnderlyingDriveInfo(devicesXml=self._getDevicesXml())
+ Drive.updateFromDesc(self._getDevicesXml(), self._devices,
+ self.conf)
hooks.after_disk_hotplug(driveXml, self.conf,
params=customProps)
@@ -4397,308 +4747,6 @@
self.saveState()
return {'status': doneCode}
- def _getUnderlyingDeviceAliasName(self, devXml):
- return devXml.getElementsByTagName('alias')[0].getAttribute('name')
-
- def _getUnderlyingDeviceAddress(self, devXml):
- """
- Obtain device's address from libvirt
- """
- address = {}
- adrXml = devXml.getElementsByTagName('address')[0]
- # Parse address to create proper dictionary.
- # Libvirt device's address definition is:
- # PCI = {'type':'pci', 'domain':'0x0000', 'bus':'0x00',
- # 'slot':'0x0c', 'function':'0x0'}
- # IDE = {'type':'drive', 'controller':'0', 'bus':'0', 'unit':'0'}
- for key in adrXml.attributes.keys():
- address[key.strip()] = adrXml.getAttribute(key).strip()
-
- return address
-
- def _getUnderlyingUnknownDeviceInfo(self, devicesXml):
- """
- Obtain unknown devices info from libvirt.
-
- Unknown device is a device that has an address but wasn't
- passed during VM creation request.
- """
- def isKnownDevice(alias):
- for dev in self.conf['devices']:
- if dev.get('alias') == alias:
- return True
- return False
-
- for x in devicesXml.childNodes:
- # Ignore empty nodes and devices without address
- if (x.nodeName == '#text' or
- not x.getElementsByTagName('address')):
- continue
-
- alias = self._getUnderlyingDeviceAliasName(x)
- if not isKnownDevice(alias):
- address = self._getUnderlyingDeviceAddress(x)
- # I general case we assume that device has attribute 'type',
- # if it hasn't getAttribute returns ''.
- device = x.getAttribute('type')
- newDev = {'type': x.nodeName,
- 'alias': alias,
- 'device': device,
- 'address': address}
- self.conf['devices'].append(newDev)
-
- def _getUnderlyingControllerDeviceInfo(self, devicesXml):
- """
- Obtain controller devices info from libvirt.
- """
- ctrlsxml = devicesXml.getElementsByTagName('controller')
- for x in ctrlsxml:
- # Ignore controller devices without address
- if not x.getElementsByTagName('address'):
- continue
- alias = self._getUnderlyingDeviceAliasName(x)
- device = x.getAttribute('type')
- # Get model and index. Relevant for USB controllers.
- model = x.getAttribute('model')
- index = x.getAttribute('index')
-
- # Get controller address
- address = self._getUnderlyingDeviceAddress(x)
-
- # In case the controller has index and/or model, they
- # are compared. Currently relevant for USB controllers.
- for ctrl in self._devices[CONTROLLER_DEVICES]:
- if ((ctrl.device == device) and
- (not hasattr(ctrl, 'index') or ctrl.index == index) and
- (not hasattr(ctrl, 'model') or ctrl.model == model)):
- ctrl.alias = alias
- ctrl.address = address
- # Update vm's conf with address for known controller devices
- # In case the controller has index and/or model, they
- # are compared. Currently relevant for USB controllers.
- knownDev = False
- for dev in self.conf['devices']:
- if ((dev['type'] == CONTROLLER_DEVICES) and
- (dev['device'] == device) and
- (not 'index' in dev or dev['index'] == index) and
- (not 'model' in dev or dev['model'] == model)):
- dev['address'] = address
- dev['alias'] = alias
- knownDev = True
- # Add unknown controller device to vm's conf
- if not knownDev:
- self.conf['devices'].append({'type': CONTROLLER_DEVICES,
- 'device': device,
- 'address': address,
- 'alias': alias})
-
- def _getUnderlyingBalloonDeviceInfo(self, devicesXml):
- """
- Obtain balloon device info from libvirt.
- """
- balloonxml = devicesXml.getElementsByTagName('memballoon')
- for x in balloonxml:
- # Ignore balloon devices without address.
- if not x.getElementsByTagName('address'):
- address = None
- else:
- address = self._getUnderlyingDeviceAddress(x)
- alias = self._getUnderlyingDeviceAliasName(x)
-
- for dev in self._devices[BALLOON_DEVICES]:
- if address and not hasattr(dev, 'address'):
- dev.address = address
- if not hasattr(dev, 'alias'):
- dev.alias = alias
-
- for dev in self.conf['devices']:
- if dev['type'] == BALLOON_DEVICES:
- if address and not dev.get('address'):
- dev['address'] = address
- if not dev.get('alias'):
- dev['alias'] = alias
-
- def _getUnderlyingConsoleDeviceInfo(self, devicesXml):
- """
- Obtain the alias for the console device from libvirt
- """
- consolexml = devicesXml.getElementsByTagName('console')
- for x in consolexml:
- # All we care about is the alias
- alias = self._getUnderlyingDeviceAliasName(x)
- for dev in self._devices[CONSOLE_DEVICES]:
- if not hasattr(dev, 'alias'):
- dev.alias = alias
-
- for dev in self.conf['devices']:
- if dev['device'] == CONSOLE_DEVICES and \
- not dev.get('alias'):
- dev['alias'] = alias
-
- def _getUnderlyingSmartcardDeviceInfo(self, devicesXml):
- """
- Obtain smartcard device info from libvirt.
- """
- smartcardxml = devicesXml.getElementsByTagName('smartcard')
- for x in smartcardxml:
- if not x.getElementsByTagName('address'):
- continue
-
- address = self._getUnderlyingDeviceAddress(x)
- alias = self._getUnderlyingDeviceAliasName(x)
-
- for dev in self._devices[SMARTCARD_DEVICES]:
- if not hasattr(dev, 'address'):
- dev.address = address
- dev.alias = alias
-
- for dev in self.conf['devices']:
- if dev['device'] == SMARTCARD_DEVICES and \
- not dev.get('address'):
- dev['address'] = address
- dev['alias'] = alias
-
- def _getUnderlyingWatchdogDeviceInfo(self, devicesXml):
- """
- Obtain watchdog device info from libvirt.
- """
- watchdogxml = devicesXml.getElementsByTagName('watchdog')
- for x in watchdogxml:
-
- # PCI watchdog has "address" different from ISA watchdog
- if x.getElementsByTagName('address'):
- address = self._getUnderlyingDeviceAddress(x)
- alias = self._getUnderlyingDeviceAliasName(x)
-
- for wd in self._devices[WATCHDOG_DEVICES]:
- if not hasattr(wd, 'address') or not hasattr(wd, 'alias'):
- wd.address = address
- wd.alias = alias
-
- for dev in self.conf['devices']:
- if ((dev['type'] == WATCHDOG_DEVICES) and
- (not dev.get('address') or not dev.get('alias'))):
- dev['address'] = address
- dev['alias'] = alias
-
- def _getUnderlyingVideoDeviceInfo(self, devicesXml):
- """
- Obtain video devices info from libvirt.
- """
- videosxml = devicesXml.getElementsByTagName('video')
- for x in videosxml:
- alias = self._getUnderlyingDeviceAliasName(x)
- # Get video card address
- address = self._getUnderlyingDeviceAddress(x)
-
- # FIXME. We have an identification problem here.
- # Video card device has not unique identifier, except the alias
- # (but backend not aware to device's aliases). So, for now
- # we can only assign the address according to devices order.
- for vc in self._devices[VIDEO_DEVICES]:
- if not hasattr(vc, 'address') or not hasattr(vc, 'alias'):
- vc.alias = alias
- vc.address = address
- break
- # Update vm's conf with address
- for dev in self.conf['devices']:
- if ((dev['type'] == VIDEO_DEVICES) and
- (not dev.get('address') or not dev.get('alias'))):
- dev['address'] = address
- dev['alias'] = alias
- break
-
- def _getUnderlyingSoundDeviceInfo(self, devicesXml):
- """
- Obtain sound devices info from libvirt.
- """
- soundsxml = devicesXml.getElementsByTagName('sound')
- for x in soundsxml:
- alias = self._getUnderlyingDeviceAliasName(x)
- # Get sound card address
- address = self._getUnderlyingDeviceAddress(x)
-
- # FIXME. We have an identification problem here.
- # Sound device has not unique identifier, except the alias
- # (but backend not aware to device's aliases). So, for now
- # we can only assign the address according to devices order.
- for sc in self._devices[SOUND_DEVICES]:
- if not hasattr(sc, 'address') or not hasattr(sc, 'alias'):
- sc.alias = alias
- sc.address = address
- break
- # Update vm's conf with address
- for dev in self.conf['devices']:
- if ((dev['type'] == SOUND_DEVICES) and
- (not dev.get('address') or not dev.get('alias'))):
- dev['address'] = address
- dev['alias'] = alias
- break
-
- def _getUnderlyingDriveInfo(self, devicesXml):
- """
- Obtain block devices info from libvirt.
- """
- disksxml = devicesXml.getElementsByTagName('disk')
- # FIXME! We need to gather as much info as possible from the libvirt.
- # In the future we can return this real data to management instead of
- # vm's conf
- for x in disksxml:
- sources = x.getElementsByTagName('source')
- if sources:
- devPath = (sources[0].getAttribute('file') or
- sources[0].getAttribute('dev'))
- else:
- devPath = ''
-
- target = x.getElementsByTagName('target')
- name = target[0].getAttribute('dev') if target else ''
- alias = self._getUnderlyingDeviceAliasName(x)
- readonly = bool(x.getElementsByTagName('readonly'))
- boot = x.getElementsByTagName('boot')
- bootOrder = boot[0].getAttribute('order') if boot else ''
-
- devType = x.getAttribute('device')
- if devType == 'disk':
- # raw/qcow2
- drv = x.getElementsByTagName('driver')[0].getAttribute('type')
- else:
- drv = 'raw'
- # Get disk address
- address = self._getUnderlyingDeviceAddress(x)
-
- for d in self._devices[DISK_DEVICES]:
- if d.path == devPath:
- d.name = name
- d.type = devType
- d.drv = drv
- d.alias = alias
- d.address = address
- d.readonly = readonly
- if bootOrder:
- d.bootOrder = bootOrder
- # Update vm's conf with address for known disk devices
- knownDev = False
- for dev in self.conf['devices']:
- if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
- dev['name'] = name
- dev['address'] = address
- dev['alias'] = alias
- dev['readonly'] = str(readonly)
- if bootOrder:
- dev['bootOrder'] = bootOrder
- knownDev = True
- # Add unknown disk device to vm's conf
- if not knownDev:
- iface = 'ide' if address['type'] == 'drive' else 'pci'
- diskDev = {'type': DISK_DEVICES, 'device': devType,
- 'iface': iface, 'path': devPath, 'name': name,
- 'address': address, 'alias': alias,
- 'readonly': str(readonly)}
- if bootOrder:
- diskDev['bootOrder'] = bootOrder
- self.conf['devices'].append(diskDev)
-
def _getUnderlyingDisplayPort(self, xml):
"""
Obtain display port info from libvirt.
@@ -4710,71 +4758,6 @@
port = graphics.getAttribute('tlsPort')
if port:
self.conf['displaySecurePort'] = port
-
- def _getUnderlyingNetworkInterfaceInfo(self, devicesXml):
- """
- Obtain network interface info from libvirt.
- """
- # TODO use xpath instead of parseString (here and elsewhere)
- ifsxml = devicesXml.getElementsByTagName('interface')
- for x in ifsxml:
- devType = x.getAttribute('type')
- mac = x.getElementsByTagName('mac')[0].getAttribute('address')
- alias = self._getUnderlyingDeviceAliasName(x)
- if devType == 'hostdev':
- name = alias
- model = 'passthrough'
- else:
- name = x.getElementsByTagName('target')[0].getAttribute('dev')
- model = x.getElementsByTagName('model')[0].getAttribute('type')
-
- network = None
- try:
- if x.getElementsByTagName('link')[0].getAttribute('state') == \
- 'down':
- linkActive = False
- else:
- linkActive = True
- except IndexError:
- linkActive = True
- source = x.getElementsByTagName('source')
- if source:
- network = source[0].getAttribute('bridge')
- if not network:
- network = source[0].getAttribute('network')
- network = network[len(netinfo.LIBVIRT_NET_PREFIX):]
-
- # Get nic address
- address = self._getUnderlyingDeviceAddress(x)
- for nic in self._devices[NIC_DEVICES]:
- if nic.macAddr.lower() == mac.lower():
- nic.name = name
- nic.alias = alias
- nic.address = address
- nic.linkActive = linkActive
- # Update vm's conf with address for known nic devices
- knownDev = False
- for dev in self.conf['devices']:
- if (dev['type'] == NIC_DEVICES and
- dev['macAddr'].lower() == mac.lower()):
- dev['address'] = address
- dev['alias'] = alias
- dev['name'] = name
- dev['linkActive'] = linkActive
- knownDev = True
- # Add unknown nic device to vm's conf
- if not knownDev:
- nicDev = {'type': NIC_DEVICES,
- 'device': devType,
- 'macAddr': mac,
- 'nicModel': model,
- 'address': address,
- 'alias': alias,
- 'name': name,
- 'linkActive': linkActive}
- if network:
- nicDev['network'] = network
- self.conf['devices'].append(nicDev)
def _setWriteWatermarks(self):
"""
--
To view, visit http://gerrit.ovirt.org/19732
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8f797baece3601b885777784f611b420523828f7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <vfeenstr(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: vdsm: export mininum kernel via caps
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: vdsm: export mininum kernel via caps
......................................................................
vdsm: export mininum kernel via caps
Export to engine the minimum kernel required for vdsm.
Change-Id: I16c496e1a77639c39fae733e3a34c974b6f10b5c
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=966158
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M .gitignore
M configure.ac
M vdsm.spec.in
M vdsm/Makefile.am
R vdsm/caps.py.in
5 files changed, 20 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/92/19792/1
diff --git a/.gitignore b/.gitignore
index 295e1fb..290bf67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@
vdsm.spec
vdsm/dsaversion.py
vdsm/dumpStorageTable.py
+vdsm/caps.py
vdsm/logger.conf
vdsm/mk_sysprep_floppy
vdsm/mom.conf
diff --git a/configure.ac b/configure.ac
index 93b6b96..694242d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,6 +119,10 @@
AC_SUBST([SNLKUSER], [sanlock])
AC_SUBST([SNLKGROUP], [sanlock])
+# Minimum Kernel
+AC_SUBST([KERNEL_MINIMUM_VERSION_EL6], [2.6.32-279.9.1])
+AC_SUBST([KERNEL_MINIMUM_UPSTREAM], [3.6])
+
# VDSM default paths
AC_SUBST([vdsmdir], ['${datarootdir}/vdsm'])
AC_SUBST([vdsmconfdir], ['${sysconfdir}/vdsm'])
diff --git a/vdsm.spec.in b/vdsm.spec.in
index e175ff8..942d417 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -150,7 +150,7 @@
Requires: device-mapper-multipath >= 0.4.9-52
Requires: e2fsprogs >= 1.41.12-11
Requires: fence-agents
-Requires: kernel >= 2.6.32-279.9.1
+Requires: kernel >= @KERNEL_MINIMUM_VERSION_EL6@
Requires: sanlock >= 2.3-4, sanlock-python
Requires: initscripts >= 9.03.31-2.el6_3.1
Requires: policycoreutils >= 2.0.83-19.30
@@ -179,7 +179,7 @@
Requires: iscsi-initiator-utils >= 6.2.0.872-14
Requires: device-mapper-multipath >= 0.4.9-18
Requires: e2fsprogs >= 1.41.14
-Requires: kernel >= 3.6
+Requires: kernel >= @KERNEL_MINIMUM_UPSTREAM@
Requires: sanlock >= 2.4-2, sanlock-python
Requires: policycoreutils-python
Requires: sed >= 4.2.1-10
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 305ef6b..f135f73 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -27,7 +27,6 @@
API.py \
BindingXMLRPC.py \
blkid.py \
- caps.py \
clientIF.py \
configNetwork.py \
debugPluginClient.py \
@@ -64,6 +63,7 @@
$(NULL)
nodist_vdsm_PYTHON = \
+ caps.py \
dsaversion.py \
dumpStorageTable.py
@@ -94,6 +94,7 @@
vdsmd.8
CLEANFILES = \
+ caps.py \
config.log \
$(nodist_vdsm_SCRIPTS) \
$(nodist_vdsmlib_PYTHON) \
@@ -103,6 +104,7 @@
$(nodist_man8_MANS)
EXTRA_DIST = \
+ caps.py.in \
dsaversion.py.in \
dumpStorageTable.py.in \
libvirt_password \
diff --git a/vdsm/caps.py b/vdsm/caps.py.in
similarity index 96%
rename from vdsm/caps.py
rename to vdsm/caps.py.in
index 3a7a6a2..fd6d528 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py.in
@@ -318,7 +318,16 @@
except:
logging.error('kernel build time not found', exc_info=True)
t = '0'
- return dict(version=ver, release=rel, buildtime=t)
+
+ # kernel minimum version
+ osname = getos()
+ if osname == OSName.RHEL:
+ kernel_min_version = '@KERNEL_MINIMUM_VERSION_EL6@'
+ else:
+ kernel_min_version = '@KERNEL_MINIMUM_UPSTREAM@'
+
+ return dict(version=ver, release=rel, buildtime=t,
+ kernel_minimum_version=kernel_min_version)
pkgs = {'kernel': kernelDict()}
--
To view, visit http://gerrit.ovirt.org/19792
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I16c496e1a77639c39fae733e3a34c974b6f10b5c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: lvm: refresh on mda permission mismatch
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: lvm: refresh on mda permission mismatch
......................................................................
lvm: refresh on mda permission mismatch
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=905665
Change-Id: I6a77b967a057329a90499d7707074befe756b68a
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/lvm.py
1 file changed, 3 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/21/20121/1
diff --git a/vdsm/storage/lvm.py b/vdsm/storage/lvm.py
index 0c2964e..3686570 100644
--- a/vdsm/storage/lvm.py
+++ b/vdsm/storage/lvm.py
@@ -1299,6 +1299,9 @@
changelv(vg, lv, ("--permission", permission))
except se.StorageException:
l = getLV(vg, lv)
+ if l.attr.permission == 'R':
+ refreshLV(vg, lv)
+ l = getLV(vg, lv)
if l.writeable == rw:
# Ignore the error since lv is now rw, hoping that the error was
# because lv was already rw, see BZ#654691. We may hide here
--
To view, visit http://gerrit.ovirt.org/20121
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6a77b967a057329a90499d7707074befe756b68a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: hooks: macbind - This hook support binding specified mac add...
by hchiramm@redhat.com
humble devassy has uploaded a new change for review.
Change subject: hooks: macbind - This hook support binding specified mac address to custom/other bridge than the currently defined bridge in ovirt. This hook is also capable of binding a mac address to openvswitch bridge.
......................................................................
hooks: macbind - This hook support binding specified
mac address to custom/other bridge than the currently defined
bridge in ovirt. This hook is also capable of binding
a mac address to openvswitch bridge.
Change-Id: I0356dfab224a9082b44aae1c66df050f7456301c
Signed-off-by: Humble Chirammal <hchiramm(a)redhat.com>
---
A vdsm_hooks/macbind/Makefile.am
A vdsm_hooks/macbind/README
A vdsm_hooks/macbind/before_vm_start.py
3 files changed, 187 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/95/17895/1
diff --git a/vdsm_hooks/macbind/Makefile.am b/vdsm_hooks/macbind/Makefile.am
new file mode 100644
index 0000000..27dc5af
--- /dev/null
+++ b/vdsm_hooks/macbind/Makefile.am
@@ -0,0 +1,30 @@
+#
+# Copyright 2013 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
+#
+
+EXTRA_DIST = \
+ before_vm_start.py
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_macbind
+
+uninstall-local:
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_macbind
diff --git a/vdsm_hooks/macbind/README b/vdsm_hooks/macbind/README
new file mode 100644
index 0000000..15bcfeb
--- /dev/null
+++ b/vdsm_hooks/macbind/README
@@ -0,0 +1,39 @@
+macbind vdsm hook:
+============
+This hook goes through all of the VM's interfaces and manipulate its
+XML file acccording to the input. This can be used to attach a VM nic
+to a specific bridge which is available in the hypervisor for 'that' VM run
+or permanently.
+
+
+One specific use case being attach a virtual network interface to an
+openvswitch bridge. Other being, attach vm nic to a different bridge
+than the defined/default bridge for that NIC.
+
+
+Syntax:
+ macbind=macaddress-brName-portType,...
+
+where:
+
+macaddress: specify a macaddress which need to be attached to the VM
+brName : Bridge Name available in hypervisor
+portType : This have to either 'ovs' or 'lb' or ''
+
+For ex:
+
+macbind= 00:1a:4a:41:d2:5f-ovsbr0-ovs,00:1a:4a:41:d2:b8-br88-lb
+
+Installation:
+* Use the engine-config to append the appropriate custom property as such:
+ sudo engine-config -s UserDefinedVMProperties=
+ 'previousProperties;macbind=^.*$' --cver=3.2
+
+* Verify that the macbind custom property was properly added:
+ sudo engine-config -g UserDefinedVMProperties
+
+Usage:
+In the VM configuration window, open the custom properites tab
+and add macbind=
+
+NOTE: Live migration is **not** tested.
diff --git a/vdsm_hooks/macbind/before_vm_start.py b/vdsm_hooks/macbind/before_vm_start.py
new file mode 100755
index 0000000..5606614
--- /dev/null
+++ b/vdsm_hooks/macbind/before_vm_start.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+
+import os
+import sys
+import hooking
+import traceback
+
+'''
+
+macbind:
+
+syntax:
+macbind=macaddress-brName-portType,...
+refer README for more details.
+
+
+if 'ovs' as portType:
+
+<interface type='bridge'>
+ <mac address='00:1a:4a:41:d2:5f'/>
+ <source bridge='ovsbr0'/>
+ <model type='virtio'/>
+ <virtualport type='openvswitch'/>
+ <filterref filter='vdsm-no-mac-spoofing'/>
+ <link state='up'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+</interface>
+
+If 'lb' or '' as portType:
+The given bridge will be replaced with current bridge:
+
+<interface type='bridge'>
+ <mac address='00:1a:4a:41:d2:b8'/>
+ <source bridge='br0'/>
+ <model type='virtio'/>
+ <filterref filter='vdsm-no-mac-spoofing'/>
+ <link state='up'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+</interface>
+
+'''
+
+
+def createVportElement(domxml, porttype):
+ vPort = domxml.createElement('virtualport')
+ vPort.setAttribute('type', 'openvswitch')
+ return vPort
+
+
+def createSbridgeElement(domxml, brName):
+ sBridge = domxml.createElement('source')
+ sBridge.setAttribute('bridge', brName)
+ return sBridge
+
+
+def removeElement(interface, Element):
+ interface.removeChild(Element)
+
+
+if 'macbind' in os.environ:
+ try:
+
+ macbinds = os.environ['macbind']
+ domxml = hooking.read_domxml()
+ macAddr = ''
+ brName = ''
+ pType = ''
+
+ for nic in macbinds.split(','):
+ try:
+ macAddr, brName, pType = nic.split('-')
+ macAddr = macAddr.strip()
+ brName = brName.strip()
+ pType = pType.strip()
+
+ except ValueError:
+ sys.stderr.write('macbind: input error, expected '
+ 'macbind:macAddr:brName:pType,'
+ 'where brName is bridgename'
+ 'pType can be ovs|lb')
+ sys.exit(2)
+ if pType == "ovs":
+ command = ['/usr/bin/ovs-vsctl', 'br-exists %s' % (brName)]
+ retcode, out, err = hooking.execCmd(
+ command, sudo=False, raw=True)
+ if retcode != 0:
+ sys.stderr.write('macbind: Error in finding ovsbridge:'
+ '%s: %s, err = %s' %
+ (brName, ' '.join(command), err))
+ continue
+ if pType == "lb" or pType == '':
+ command = ['/usr/sbin/brctl', 'show', brName]
+ retcode, out, err = hooking.execCmd(
+ command, sudo=False, raw=True)
+
+ if err or retcode != 0:
+ sys.stderr.write('macbind: Error in finding Linuxbridge:'
+ ' %s \n: %s, err = %s\n' %
+ (brName, ' '.join(command), err))
+ continue
+
+ for interface in domxml.getElementsByTagName('interface'):
+ for macaddress in interface.getElementsByTagName('mac'):
+ addr = macaddress.getAttribute('address')
+ if addr == macAddr:
+ for bridge in interface.getElementsByTagName('source'):
+ interface.removeChild(bridge)
+ interface.appendChild(
+ createSbridgeElement(domxml, brName))
+ if pType == "ovs":
+ interface.appendChild(
+ createVportElement(domxml, 'openvswitch'))
+
+ hooking.write_domxml(domxml)
+ except:
+ sys.stderr.write('macbind: [unexpected error]: %s\n' %
+ traceback.format_exc())
+ sys.exit(2)
--
To view, visit http://gerrit.ovirt.org/17895
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0356dfab224a9082b44aae1c66df050f7456301c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: humble devassy <hchiramm(a)redhat.com>
9 years, 11 months