Change in vdsm[master]: vdsm hostdev: add support for USB devices
by mpoledni@redhat.com
Martin Polednik has uploaded a new change for review.
Change subject: vdsm hostdev: add support for USB devices
......................................................................
vdsm hostdev: add support for USB devices
Libvirt allows passthrough of USB devices (not busses) - this patch
exposes the functionality in vdsm
Change-Id: Iac74e7537d56bcb940ef07a4654d45cbcdbb1fb0
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M vdsm/caps.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/vm.py
3 files changed, 71 insertions(+), 10 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/29054/1
diff --git a/vdsm/caps.py b/vdsm/caps.py
index d937d4e..8c16af6 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -530,7 +530,12 @@
# back that we could use to uniquely identify and initiate a device
continue
- if capability in ('pci',):
+ if capability in ('pci', 'usb_device'):
+ # Libvirt only allows to attach USB device with capability 'usb',
+ # but the bus identifies itself as 'usb' while device as
+ # 'usb_device'
+ if dev['capability'] == 'usb_device':
+ dev['capability'] = 'usb'
devices.append(dev)
return devices
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 921f3d4..ac10144 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3156,33 +3156,55 @@
'specParams': 'VmRngDeviceSpecParams'}}
##
+# @StartupPolicy:
+#
+# Possible policies for startup with device
+#
+# @mandatory: fail if missing for any reason (the default)
+#
+# @requisite: fail if missing on boot up, drop if missing
+# on migrate/restore/revert
+#
+# @optional: drop if missing at any start attempt
+#
+# Since: 4.16.0
+##
+{'enum': 'StartupPolicy', 'data': ['mandatory', 'requisite', 'optional']}
+
+##
# @HostDeviceCapability:
#
# Properties of a host device.
#
# @pci: PCI device
#
+# @usb: USB device
+#
# Since: 4.16.0
##
-{'enum': 'HostDeviceCapability', 'data': ['pci']}
+{'enum': 'HostDeviceCapability', 'data': ['pci', 'usb']}
##
# @HostDeviceSpecParams:
#
# Properties of a host device.
#
-# @bootorder: #optional If specified, this device is part of the boot
-# sequence at the specified position
+# @bootorder: #optional If specified, this device is part of the boot
+# sequence at the specified position (for @pci and @usb)
#
-# @bar: #optional ROM visibility in the guest's memory map (for @pci)
+# @bar: #optional ROM visibility in the guest's
+# memory map (for @pci)
#
-# @file: #optional Binary file to be used as device's ROM (for @pci)
+# @file: #optional Binary file to be used as device's ROM (for @pci)
+#
+# @startupPolicy: #optional Possible boot handling with attached device
+# (for @usb)
#
# Since: 4.16.0
##
{'type': 'HostDeviceSpecParams',
- 'data': {'*bootorder': 'int', '*bar': 'bool',
- '*file': 'str'}}
+ 'data': {'*bootorder': 'int', '*bar': 'bool', '*file': 'str',
+ '*startupPolicy': 'StartupPolicy'}}
##
# @HostDevice:
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 6143cfa..6a6978e 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -1631,13 +1631,16 @@
self.log.debug('Detaching hostdev %s', self.name)
self._node.dettach()
- def getPciAddr(self):
+ def _parsecaps(self):
capsxml = _domParseStr(self._node.XMLDesc(0)).childNodes[0]
self.log.debug('Got nodeDevice XML:\n%s',
capsxml.toprettyxml(encoding='utf-8'))
- capsxml = capsxml.getElementsByTagName('capability')[0]
+ return capsxml.getElementsByTagName('capability')[0]
+
+ def getPciAddr(self):
+ capsxml = self._parsecaps()
domain = capsxml.getElementsByTagName('domain')[0]. \
firstChild.nodeValue
bus = capsxml.getElementsByTagName('bus')[0].firstChild.nodeValue
@@ -1646,6 +1649,26 @@
self.log.debug('PCI device %s at address {domain: %s bus: %s '
'slot: %s}', self.name, domain, bus, slot)
return {'domain': domain, 'bus': bus, 'slot': slot}
+
+ def getUsbAddr(self):
+ capsxml = self._parsecaps()
+ addr = {}
+
+ addr['bus'] = capsxml.getElementsByTagName('bus')[0].firstChild. \
+ nodeValue
+ addr['device'] = capsxml.getElementsByTagName('device')[0]. \
+ firstChild.nodeValue
+ # TODO: handle nonexistant product_id and vendor_id by not adding them
+ # to addr
+ addr['product_id'] = capsxml.getElementsByTagName('product')[0].\
+ getAttribute('id')
+ addr['vendor_id'] = capsxml.getElementsByTagName('vendor')[0].\
+ getAttribute('id')
+
+ self.log.debug('USB device %s {product: %s, vendor: %s} at address '
+ '{bus: %s device: %s}', self.name, addr['product_id'],
+ addr['vendor_id'], addr['bus'], addr['device'])
+ return addr
def getXML(self):
"""
@@ -1683,6 +1706,17 @@
rom.setAttrs(**romAttrs)
+ elif self.capability == 'usb_device':
+ addr = self.getPciAddr()
+ try:
+ source.appendChildWithArgs('vendor', None, addr['vendor'])
+ source.appendChildWithArgs('vendor', None, addr['product'])
+ except:
+ source.appendChildWithArgs('address', None, **addr)
+
+ if 'startupPolicy' in self.specParams:
+ source.setAttrs(startupPolicy=self.specParams['startupPolicy'])
+
return hostdev
--
To view, visit http://gerrit.ovirt.org/29054
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iac74e7537d56bcb940ef07a4654d45cbcdbb1fb0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpoledni(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: vdsm hostdev: add support for SCSI devices
by mpoledni@redhat.com
Martin Polednik has uploaded a new change for review.
Change subject: vdsm hostdev: add support for SCSI devices
......................................................................
vdsm hostdev: add support for SCSI devices
Libvirt allows passthrough of SCSI devices - this patch
exposes the functionality in vdsm
Change-Id: Ia953bcd5eda1b97235a8dd2f5f9593d8f302e5d6
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M vdsm/caps.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/vm.py
3 files changed, 51 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/58/29058/1
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 8c16af6..6112763 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -530,7 +530,7 @@
# back that we could use to uniquely identify and initiate a device
continue
- if capability in ('pci', 'usb_device'):
+ if capability in ('pci', 'usb_device', 'scsi'):
# Libvirt only allows to attach USB device with capability 'usb',
# but the bus identifies itself as 'usb' while device as
# 'usb_device'
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index ac10144..52f20c1 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -3180,9 +3180,11 @@
#
# @usb: USB device
#
+# @scsi: SCSI device
+#
# Since: 4.16.0
##
-{'enum': 'HostDeviceCapability', 'data': ['pci', 'usb']}
+{'enum': 'HostDeviceCapability', 'data': ['pci', 'usb', 'scsi']}
##
# @HostDeviceSpecParams:
@@ -3200,11 +3202,18 @@
# @startupPolicy: #optional Possible boot handling with attached device
# (for @usb)
#
+# @readonly #optional If present, indicates that the device is read
+# only (for @scsi)
+#
+# @shareable #optional If present, this indicates the device is
+# expected to be shared between domains (for @scsi)
+#
# Since: 4.16.0
##
{'type': 'HostDeviceSpecParams',
'data': {'*bootorder': 'int', '*bar': 'bool', '*file': 'str',
- '*startupPolicy': 'StartupPolicy'}}
+ '*startupPolicy': 'StartupPolicy', '*shareable': 'bool',
+ '*readonly*': 'bool'}}
##
# @HostDevice:
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 6a6978e..3cb2eb9 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -1670,6 +1670,33 @@
addr['vendor_id'], addr['bus'], addr['device'])
return addr
+ def getScsiAddr(self):
+ capsxml = self._parsecaps()
+ addr = {}
+
+ addr['type'] = 'scsi'
+ addr['bus'] = capsxml.getElementsByTagName('bus')[0].firstChild. \
+ nodeValue
+ addr['target'] = capsxml.getElementsByTagName('target')[0]. \
+ firstChild.nodeValue
+ addr['unit'] = capsxml.getElementsByTagName('lun')[0]. \
+ firstChild.nodeValue
+
+ self.log.debug('SCSI device %s at address '
+ '{bus: %s, target: %s, unit: %s}',
+ self.name, addr['bus'], addr['target'], addr['unit'],
+ addr['device'])
+ return addr
+
+ def getScsiAdapter(self):
+ capsxml = self._parsecaps()
+
+ adapter = 'scsi_host{}'.format(
+ capsxml.getElementsByTagName('host')[0].firstChild.nodeValue)
+
+ self.log.debug('SCSI device %s adapter %s', self.name, adapter)
+ return adapter
+
def getXML(self):
"""
Create domxml for a hostdev device.
@@ -1717,6 +1744,18 @@
if 'startupPolicy' in self.specParams:
source.setAttrs(startupPolicy=self.specParams['startupPolicy'])
+ elif self.capability == 'scsi':
+ source.appendChildWithArgs('address', None,
+ **self.getScsiHost())
+ source.appendChildWithArgs('adapter', None,
+ **self.getScsiAdapter())
+
+ if 'readonly' in self.specParams:
+ hostdev.appendChild('readonly')
+
+ if 'shareable' in self.specParams:
+ hostdev.appendChild('shareable')
+
return hostdev
--
To view, visit http://gerrit.ovirt.org/29058
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia953bcd5eda1b97235a8dd2f5f9593d8f302e5d6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpoledni(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: VDSM: implement nodeDeviceMapper
by Martin Polednik
Martin Polednik has uploaded a new change for review.
Change subject: VDSM: implement nodeDeviceMapper
......................................................................
VDSM: implement nodeDeviceMapper
NodeDeviceMapper is structure to keep track of available node devices
and provide easy access to querying and managing them. The mapper
is needed in order to allow VDSM to meaningfully report the usage
of these devices, along with managing their availability.
Change-Id: I6f21d465a90cfe2eb16ba70943e5fcf1683f1656
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M client/vdsClient.py
M debian/vdsm.install
M vdsm.spec.in
M vdsm/API.py
M vdsm/clientIF.py
M vdsm/rpc/BindingXMLRPC.py
M vdsm/virt/Makefile.am
7 files changed, 44 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/30209/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 2c09b28..89dceab 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -461,6 +461,14 @@
def do_getAllVmStats(self, args):
return self.ExecAndExit(self.s.getAllVmStats())
+ def do_getDevicesByCaps(self, args):
+ caps = list(args)
+ return self.ExecAndExit(self.s.getDevicesByCaps(caps))
+
+ def do_getDevicesByDomain(self, args):
+ vmId = args[0]
+ return self.ExecAndExit(self.s.getDevicesByDomain(vmId))
+
def desktopLogin(self, args):
vmId, domain, user, password = tuple(args)
response = self.s.desktopLogin(vmId, domain, user, password)
@@ -2077,6 +2085,16 @@
('',
'Get Statistics info for all existing VMs'
)),
+ 'getDevicesByCaps': (serv.do_getDevicesByCaps,
+ ('[<caps>]',
+ 'Get available node devices on the host with '
+ 'given capability'
+ )),
+ 'getDevicesByDomain': (serv.do_getDevicesByDomain,
+ ('<vmId>',
+ 'Get available node devices attached to specified '
+ 'domain'
+ )),
'getVGList': (serv.getVGList,
('storageType',
'List of all VGs.'
diff --git a/debian/vdsm.install b/debian/vdsm.install
index 3af1100..e1d8652 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -142,6 +142,7 @@
./usr/share/vdsm/virt/__init__.py
./usr/share/vdsm/virt/guestagent.py
./usr/share/vdsm/virt/migration.py
+./usr/share/vdsm/virt/nodedev.py
./usr/share/vdsm/virt/sampling.py
./usr/share/vdsm/virt/vm.py
./usr/share/vdsm/virt/vmchannels.py
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 16b7834..0ddacbe 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -939,6 +939,7 @@
%{_datadir}/%{vdsm_name}/virt/__init__.py*
%{_datadir}/%{vdsm_name}/virt/guestagent.py*
%{_datadir}/%{vdsm_name}/virt/migration.py*
+%{_datadir}/%{vdsm_name}/virt/nodedev.py*
%{_datadir}/%{vdsm_name}/virt/vmchannels.py*
%{_datadir}/%{vdsm_name}/virt/vmstatus.py*
%{_datadir}/%{vdsm_name}/virt/vmtune.py*
diff --git a/vdsm/API.py b/vdsm/API.py
index 6feccf6..e891b80 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1244,6 +1244,18 @@
statsList = hooks.after_get_all_vm_stats(statsList)
return {'status': doneCode, 'statsList': statsList}
+ def getDevicesByCaps(self, caps):
+ """
+ """
+ devices = self._cif.nodeDeviceMapper.getDevicesByCaps(caps)
+ return {'status': doneCode, 'devices': devices}
+
+ def getDevicesByDomain(self, vmId):
+ """
+ """
+ devices = self._cif.nodeDeviceMapper.getDevicesByDomain(vmId)
+ return {'status': doneCode, 'devices': devices}
+
def getStats(self):
"""
Report host statistics.
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index d5372f3..118652d 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -91,6 +91,7 @@
self.gluster = None
try:
self.vmContainer = {}
+ self.nodeDeviceMapper = NodeDeviceMapper(vmContainer, log)
self._hostStats = sampling.HostStatsThread(log=log)
self._hostStats.start()
self.lastRemoteAccess = 0
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index d6663c3..a31d76c 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -482,6 +482,14 @@
api = API.Global()
return api.getAllVmStats()
+ def getDevicesByCaps(self, caps):
+ api = API.Global()
+ return api.getDevicesByCaps(caps)
+
+ def getDevicesByDomain(self, vmId):
+ api = API.Global()
+ return api.getDevicesByDomain(vmId)
+
def vmGetIoTunePolicy(self, vmId):
vm = API.VM(vmId)
return vm.getIoTunePolicy()
@@ -989,6 +997,8 @@
(self.getStats, 'getVdsStats'),
(self.vmGetStats, 'getVmStats'),
(self.getAllVmStats, 'getAllVmStats'),
+ (self.getDevicesByCaps, 'getDevicesByCaps'),
+ (self.getDevicesByDomain, 'getDevicesByDomain'),
(self.vmMigrationCreate, 'migrationCreate'),
(self.vmDesktopLogin, 'desktopLogin'),
(self.vmDesktopLogoff, 'desktopLogoff'),
diff --git a/vdsm/virt/Makefile.am b/vdsm/virt/Makefile.am
index 423839b..4b7b1cc 100644
--- a/vdsm/virt/Makefile.am
+++ b/vdsm/virt/Makefile.am
@@ -25,6 +25,7 @@
__init__.py \
guestagent.py \
migration.py \
+ nodedev.py \
sampling.py \
vm.py \
vmchannels.py \
--
To view, visit http://gerrit.ovirt.org/30209
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6f21d465a90cfe2eb16ba70943e5fcf1683f1656
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpolednik(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: [WIP] vdsm: add support for PCI passthrough
by mpoledni@redhat.com
Martin Polednik has uploaded a new change for review.
Change subject: [WIP] vdsm: add support for PCI passthrough
......................................................................
[WIP] vdsm: add support for PCI passthrough
required functionality:
* report PCI devices available on host [x]
* handle createVm xml generation [x]
* hotplugHostdev [ ] (required for after-migration)
* hotpunlugHostdev [ ] (required for migration)
Change-Id: I363d2622d72ca2db75f60032fe0892c348bab121
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M lib/vdsm/define.py
M vdsm/caps.py
M vdsm/vm.py
3 files changed, 83 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/62/22462/1
diff --git a/lib/vdsm/define.py b/lib/vdsm/define.py
index eb78633..9605f93 100644
--- a/lib/vdsm/define.py
+++ b/lib/vdsm/define.py
@@ -132,6 +132,12 @@
'transientErr': {'status': {
'code': 59,
'message': 'Action not permitted on a VM with transient disks'}},
+ 'hotplugHostdev': {'status': {
+ 'code': 60,
+ 'message': 'Failed to hotplug hostdev'}},
+ 'hotunplugHostdev': {'status': {
+ 'code': 61,
+ 'message': 'Failed to hotunplug hostdev'}},
'recovery': {'status': {
'code': 99,
'message': 'Recovering from crash or Initializing'}},
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 3839134..d6af375 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -308,6 +308,38 @@
return dict(release=release, version=version, name=osname)
+def hostdevList():
+ devices = []
+ for device in libvirtconnection.get().listAllDevices():
+ devXML = minidom.parseString(device.XMLDesc())
+ dev = {}
+
+ # we have to grab attributes that will most likely not only
+ # uniquely identify device, but also serve as human readable
+ # representation of the device
+ try:
+ dev['name'] = devXML.getElementsByTagName('name')[0].\
+ childNodes[0].data
+ capability = devXML.getElementsByTagName('capability')[0]
+ try:
+ dev['product'] = capability.getElementsByTagName('product')[0]\
+ .childNodes[0].data
+ dev['vendor'] = capability.getElementsByTagName('vendor')[0].\
+ childNodes[0].data
+ except IndexError:
+ # althought the retrieval of product/vendor was not successful,
+ # we can still report back the name
+ pass
+ except IndexError:
+ # should device not have a name, there is nothing engine could send
+ # back that we could use to uniquely identify and initiate a device
+ continue
+
+ devices.append(dev)
+
+ return devices
+
+
def get():
targetArch = platform.machine()
@@ -360,6 +392,7 @@
config.getint('vars', 'extra_mem_reserve'))
caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')
caps['rngSources'] = _getRngSources()
+ caps['hostDevices'] = hostdevList()
return caps
diff --git a/vdsm/vm.py b/vdsm/vm.py
index a5d923b..a477bc9 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -78,6 +78,7 @@
WATCHDOG_DEVICES = 'watchdog'
CONSOLE_DEVICES = 'console'
SMARTCARD_DEVICES = 'smartcard'
+HOSTDEV_DEVICES = 'hostdev'
def isVdsmImage(drive):
@@ -1656,6 +1657,27 @@
return m
+class HostDevice(VmDevice):
+ def getXML(self):
+ """
+ Create domxml for a hostdev device.
+
+ <devices>
+ <hostdev mode='subsystem' type='usb'>
+ <source startupPolicy='optional'>
+ <vendor id='0x1234'/>
+ <product id='0xbeef'/>
+ </source>
+ <boot order='2'/>
+ </hostdev>
+ </devices>
+ """
+ # libvirt gives us direct api call to construct the XML
+ return xml.dom.minidom.parseString(libvirtconnection.get().
+ nodeDeviceLookupByName(self.name).
+ XMLDesc())
+
+
class WatchdogDevice(VmDevice):
def __init__(self, *args, **kwargs):
super(WatchdogDevice, self).__init__(*args, **kwargs)
@@ -1769,7 +1791,8 @@
(CONSOLE_DEVICES, ConsoleDevice),
(REDIR_DEVICES, RedirDevice),
(RNG_DEVICES, RngDevice),
- (SMARTCARD_DEVICES, SmartCardDevice))
+ (SMARTCARD_DEVICES, SmartCardDevice),
+ (HOSTDEV_DEVICES, HostDevice))
def _makeDeviceDict(self):
return dict((dev, []) for dev, _ in self.DeviceMapping)
@@ -3127,6 +3150,26 @@
break
+ def hotplugHostdev(self, params):
+ hostdev = HostDevice(self.conf, self.log, **params)
+ self._devices[HOSTDEV_DEVICES].append(hostdev)
+ hostdevXML = hostdev.getXML().toprettyxml(encoding='utf-8')
+ hostdev._deviceXML = hostdevXML
+ self.log.debug("Hotplug hostdev xml: %s", hostdevXML)
+
+ try:
+ self._dom.attachDevice(hostdevXML)
+ except libvirt.libvirtError as e:
+ self.log.error("Hotplug failed", exc_info=True)
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return errCode['noVM']
+ return {'status': {'code':
+ errCode['hotplugHostdev']['status']['code'],
+ 'message': e.message}}
+
+ def hotunplugHostdev(self, name):
+ pass
+
def hotplugNic(self, params):
if self.isMigrating():
return errCode['migInProgress']
--
To view, visit http://gerrit.ovirt.org/22462
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I363d2622d72ca2db75f60032fe0892c348bab121
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpoledni(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: netinfo: improve which ipv4 addr is reported if there are mu...
by asegurap@redhat.com
Antoni Segura Puimedon has uploaded a new change for review.
Change subject: netinfo: improve which ipv4 addr is reported if there are multiple primary
......................................................................
netinfo: improve which ipv4 addr is reported if there are multiple primary
The current code assumed that additional configured addresses for a
device would have the 'secondary' flag. However, this is no longer
true in recent kernels, as multiple primary addresses can be set for
a device.
The improvement is that now we will check if any of the addresses is
in the subnet of the gateway and report one of them. If there is no
default gw in the main table for the device we return the last
set primary ip and if there is a default gw but going through another
hop, we return the first set ip.
Change-Id: I8666cfef5bd8ea63edf8979e501d4785db5f4893
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
M lib/vdsm/netinfo.py
1 file changed, 35 insertions(+), 7 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/33375/1
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 6491505..816810d 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -292,25 +292,49 @@
struct.pack("!I", int('1' * prefix + '0' * (32 - prefix), 2)))
+def prefix2int(prefix):
+ if not 0 <= prefix <= 32:
+ raise ValueError('%s is not a valid prefix value. It must be between '
+ '0 and 32')
+ return (2 ** prefix - 1) << (32 - prefix)
+
+
+def addr2int(address):
+ return struct.unpack('!I', socket.inet_aton(address))[0]
+
+
def getDefaultGateway():
output = routeShowGateways('main')
return Route.fromText(output[0]) if output else None
-def getIpInfo(dev, ipaddrs=None):
+def getIpInfo(dev, ipaddrs=None, ipv4_gateway=None):
if ipaddrs is None:
ipaddrs = _getIpAddrs()
ipv4addr = ipv4netmask = ''
ipv4addrs = []
ipv6addrs = []
+ gateway_int = addr2int(ipv4_gateway) if ipv4_gateway else None
+
for addr in ipaddrs[dev]:
if addr['family'] == 'inet':
ipv4addrs.append(addr['address'])
if 'secondary' not in addr['flags']:
- ipv4addr, prefix = addr['address'].split('/')
- ipv4netmask = prefix2netmask(addr['prefixlen'])
+ address, _ = addr['address'].split('/')
+ mask = prefix2int(addr['prefixlen'])
+ if (gateway_int is None or
+ addr2int(address) & mask == gateway_int & mask):
+ ipv4addr = address
+ ipv4netmask = prefix2netmask(addr['prefixlen'])
else:
ipv6addrs.append(addr['address'])
+ if ipv4addrs and ipv4addr == '':
+ # If we didn't find an address in the gateway subnet (which is
+ # legal if there is another route that takes us to the gateway) we
+ # choose to report the first address
+ ipv4addr, prefix = ipv4addrs[0].split('/')
+ ipv4netmask = prefix2netmask(int(prefix))
+
return ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs
@@ -501,14 +525,16 @@
# comment when the version is no longer supported.
data['interface'] = iface
- ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(iface, ipaddrs)
+ gateway = _get_gateway(routes, iface)
+ ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
+ iface, ipaddrs, gateway)
data.update({'iface': iface, 'bridged': bridged,
'addr': ipv4addr, 'netmask': ipv4netmask,
'bootproto4': ('dhcp' if ipv4addr and iface in dhcp4
else 'none'),
'ipv4addrs': ipv4addrs,
'ipv6addrs': ipv6addrs,
- 'gateway': _get_gateway(routes, iface),
+ 'gateway': gateway,
'ipv6gateway': _get_gateway(routes, iface, family=6),
'mtu': str(getMtu(iface))})
except (IOError, OSError) as e:
@@ -549,12 +575,14 @@
def _devinfo(link, routes, ipaddrs, dhcp4):
- ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(link.name, ipaddrs)
+ gateway = _get_gateway(routes, link.name)
+ ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(
+ link.name, ipaddrs, gateway)
info = {'addr': ipv4addr,
'cfg': getIfaceCfg(link.name),
'ipv4addrs': ipv4addrs,
'ipv6addrs': ipv6addrs,
- 'gateway': _get_gateway(routes, link.name),
+ 'gateway': gateway,
'ipv6gateway': _get_gateway(routes, link.name, family=6),
'bootproto4': ('dhcp' if ipv4addr and link.name in dhcp4
else 'none'),
--
To view, visit http://gerrit.ovirt.org/33375
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8666cfef5bd8ea63edf8979e501d4785db5f4893
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
8 years, 9 months
Change in vdsm[master]: vm: make acpiShutdown more robust
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: vm: make acpiShutdown more robust
......................................................................
vm: make acpiShutdown more robust
In the Vm shutdown flow, the actual 'destruction'
of the domain -in libvirt jargon- may already happen
asynchonously, e.g. if QEMU dies suddenly.
Moreover, we want to make it asynchronously even on
our own code for performance reasons.
This means that the Vm._dom attribute may become None
asyncrhonously, even inside the Vm powerdown flow
itself.
This patch address the case for the acpiShutdown,
fixing this issue:
Thread-259072::ERROR::2014-10-15 12:06:52,842::utils::1193::utils.Callback::(__call__) acpiCallback failed
Traceback (most recent call last):
File "/usr/lib64/python2.6/site-packages/vdsm/utils.py", line 1191, in __call__
result = self.func(*self.args, **self.kwargs)
File "/usr/share/vdsm/virt/vmpowerdown.py", line 91, in acpiCallback
self.vm.acpiShutdown()
File "/usr/share/vdsm/virt/vm.py", line 4942, in acpiShutdown
self._dom.shutdownFlags(libvirt.VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN)
AttributeError: 'NoneType' object has no attribute 'shutdownFlags'
Change-Id: I244f00d62ee24fb42ba3d654961a8fc22f4a6c25
Related-To: https://bugzilla.redhat.com/show_bug.cgi?id=1154389
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M vdsm/virt/vm.py
1 file changed, 7 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/79/34879/1
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 9740ab3..2384aca 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -4402,7 +4402,13 @@
def acpiShutdown(self):
self._shutdownReason = vmexitreason.ADMIN_SHUTDOWN
- self._dom.shutdownFlags(libvirt.VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN)
+ try:
+ self._dom.shutdownFlags(libvirt.VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN)
+ except AttributeError:
+ if not self._released:
+ raise
+ # else the VM was already shut off asynchronously,
+ # so ignore error and quickly exit
def setBalloonTarget(self, target):
--
To view, visit http://gerrit.ovirt.org/34879
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I244f00d62ee24fb42ba3d654961a8fc22f4a6c25
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
8 years, 9 months
Change in vdsm[master]: netinfo: Replace misused asserts with InvalidConfiguration
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: netinfo: Replace misused asserts with InvalidConfiguration
......................................................................
netinfo: Replace misused asserts with InvalidConfiguration
The code was assuming that asserts are always available, and if running
with in optimized mode, the code would skip the assert and use invalid
configuration, possibly corrupting application state or failing with
unrelated errors, hiding the root cause of the error.
The asserts are replaced now with new InvalidConfiguration exception and
the error messages are improved.
Change-Id: I99ee49aa7e2364f57112e2452e3eab3940b6b00a
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M lib/vdsm/netinfo.py
1 file changed, 17 insertions(+), 5 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/61/34361/1
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index d818249..e848abc 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -84,6 +84,10 @@
DUMMY_BRIDGE # Appease flake8 since dummy bridge should be exported from here
+class InvalidConfiguration(Exception):
+ """ Raise when getting an invalid conifguration """
+
+
def _visible_devs(predicate):
"""Returns a list of visible (vdsm manageable) links for which the
predicate is True"""
@@ -834,8 +838,9 @@
bondings = [b for (b, attrs) in self.bondings.iteritems() if
nic in attrs['slaves']]
if bondings:
- assert len(bondings) == 1, \
- "Unexpected configuration: More than one bonding per nic"
+ if len(bondings) != 1:
+ raise InvalidConfiguration(
+ "Unexpected configuration: More than one bonding per nic")
return bondings[0]
return None
@@ -853,13 +858,20 @@
for port in ports:
if port in self.vlans:
- assert vlan is None
+ if vlan is not None:
+ raise InvalidConfiguration(
+ "Unexpected vlan: %s exepected: None" % (vlan,))
nic = getVlanDevice(port)
vlan = getVlanID(port)
- assert self.vlans[port]['iface'] == nic
+ if self.vlans[port]['iface'] != nic:
+ raise InvalidConfiguration(
+ "Unexpected iface: %s expected: %s" %
+ (self.vlans[port]['iface'], nic))
port = nic
if port in self.bondings:
- assert bonding is None
+ if bonding is not None:
+ raise InvalidConfiguration(
+ "Unexpected bonding: %s expected: None" % bonding)
bonding = port
lnics += self.bondings[bonding]['slaves']
elif port in self.nics:
--
To view, visit http://gerrit.ovirt.org/34361
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I99ee49aa7e2364f57112e2452e3eab3940b6b00a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
8 years, 9 months
Change in vdsm[master]: ipwrapper: Use zombiereaper to wait for process
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: ipwrapper: Use zombiereaper to wait for process
......................................................................
ipwrapper: Use zombiereaper to wait for process
Commit aea8aab95f eliminated ip process zombies by waiting for ip
process. This is may introduce unlimited wait if the process is not
responsive. We can avoid this issue by using zombiereaper.
Note that zombiereaper requires explicit initialization (registering
signal handler for SIGCHLD), so this make ipwrapper less useful as
generic utility.
Change-Id: I26263c5b4811d7f46f7c65d1d1b00bd96af02eb8
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M lib/vdsm/ipwrapper.py
1 file changed, 2 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/16/32216/1
diff --git a/lib/vdsm/ipwrapper.py b/lib/vdsm/ipwrapper.py
index af31159..781e95b 100644
--- a/lib/vdsm/ipwrapper.py
+++ b/lib/vdsm/ipwrapper.py
@@ -27,6 +27,7 @@
import signal
import socket
import struct
+import zombiereaper
from netaddr.core import AddrFormatError
from netaddr import IPAddress
@@ -638,7 +639,7 @@
def stop(self):
self.proc.kill()
- self.proc.wait()
+ zombiereaper.autoReapPID(self.proc.pid)
@classmethod
def _parseLine(cls, line):
--
To view, visit http://gerrit.ovirt.org/32216
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I26263c5b4811d7f46f7c65d1d1b00bd96af02eb8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
8 years, 9 months
Change in vdsm[master]: schema: Fix asserts that had side effect
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: schema: Fix asserts that had side effect
......................................................................
schema: Fix asserts that had side effect
Asserts should never have side effects, so optimizing them out will not
change the semantics of the code. Running with optimization would break
parsing, eliminating line.pop(0) operations. Now the only difference is
the warning if the line is not empty.
Change-Id: I59dbb1c8d3760af7d3f3049227f6ad8ceeaa402a
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M vdsm/rpc/process-schema.py
1 file changed, 4 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/62/34362/1
diff --git a/vdsm/rpc/process-schema.py b/vdsm/rpc/process-schema.py
index 4b1c3cf..8e56a1a 100755
--- a/vdsm/rpc/process-schema.py
+++ b/vdsm/rpc/process-schema.py
@@ -103,7 +103,8 @@
'xxx': []})
# Pop a blank line
- assert('' == lines.pop(0))
+ line = lines.pop(0)
+ assert line == '', "Expected empty line: %r" % line
# Grab the entity description. It might span multiple lines.
symbol['desc'] = lines.pop(0)
@@ -111,7 +112,8 @@
symbol['desc'] += lines.pop(0)
# Pop a blank line
- assert ('' == lines.pop(0))
+ line = lines.pop(0)
+ assert line == '', "Expected empty line: %r" % line
# Populate the rest of the human-readable data.
# First try to read the parameters/members information. We are finished
--
To view, visit http://gerrit.ovirt.org/34362
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I59dbb1c8d3760af7d3f3049227f6ad8ceeaa402a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
8 years, 9 months
Change in vdsm[master]: spec: Require newer version of sanlock
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: spec: Require newer version of sanlock
......................................................................
spec: Require newer version of sanlock
For EL7 PPC, we must use sanlock 3.2.2-2 for compatibility between x86
and ppc hosts. On x86, we can use sanlock 3.2.1, which is good as 3.2.2.
Change-Id: I531bf060ef27a6d33a5cdae133fde557afea8ee5
Bug-Url: https://bugzilla.redhat.com/1150008
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 6 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/21/36321/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 85c9f83..f2d0f99 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -191,7 +191,7 @@
Requires: iscsi-initiator-utils >= 6.2.0.873-21
%endif
-Requires: sanlock >= 2.8, sanlock-python
+Requires: sanlock-python
%if 0%{?rhel}
%if 0%{?rhel} >= 7
@@ -201,6 +201,8 @@
Requires: lvm2
Requires: python
Requires: policycoreutils-python
+# 3.2.2-2 required for ppc64
+Requires: sanlock >= 3.2.2-2
Requires: selinux-policy-targeted >= 3.12.1-153.el7_0.13
%else
Requires: python
@@ -214,6 +216,7 @@
Requires: selinux-policy-targeted >= 3.7.19-260.el6_6.1
Requires: lvm2 >= 2.02.100-5
Requires: logrotate < 3.8.0
+Requires: sanlock >= 2.8
%endif
%else
Requires: fence-agents-all
@@ -227,6 +230,8 @@
Requires: sed >= 4.2.1-10
Requires: ed
Requires: lvm2 >= 2.02.98-15
+# Same as 3.2.2 on x86
+Requires: sanlock >= 3.2.1-2
Requires: selinux-policy-targeted >= 3.12.1-71
# In order to avoid a policycoreutils bug (rhbz 889698) when selinux is
# disabled we now require the version 2.1.13-55 (or newer) of Fedora.
--
To view, visit http://gerrit.ovirt.org/36321
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I531bf060ef27a6d33a5cdae133fde557afea8ee5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
8 years, 9 months