Change in vdsm[ovirt-3.4]: API: setHaMaintenanceMode command
by gpadgett@redhat.com
Greg Padgett has uploaded a new change for review.
Change subject: API: setHaMaintenanceMode command
......................................................................
API: setHaMaintenanceMode command
New API for setting hosted engine maintenance mode. This allows the
engine to send commands to the hosted engine agent in order to ease any
necessary maintenance tasks. The following modes are supported:
local - allow maintenance of the host by effectively stopping the ha
agent from performing any vm-related activity. The engine vm is
moved to another host in the ha cluster, and the host score is set
to 0. It is meant to correspond to vds maintenance operations
performed by the engine.
global - allow maintenance of the ha system or engine vm. All hosted
engine state changes are halted for all nodes in the ha cluster,
so that user-initiated changes to the vm or hosts are ignored.
This API improves usability for the hosted engine subsystem by enabling
changes in the engine ui that would otherwise require the command-line.
For more information:
http://www.ovirt.org/Features/Self_Hosted_Engine_Maintenance_Flows
Change-Id: Ic08c5edb0e9b8cc11eb70ef6a66301335c42aad3
Bug-Url: https://bugzilla.redhat.com/1053040
Signed-off-by: Greg Padgett <gpadgett(a)redhat.com>
---
M client/vdsClient.py
M lib/vdsm/define.py
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm_api/vdsmapi-schema.json
5 files changed, 75 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/91/24091/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 74361fb..90bceb3 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -1444,6 +1444,15 @@
return stats['status']['code'], stats['status']['message']
return 0, ''
+ def do_setHaMaintenanceMode(self, args):
+ mode = args[0]
+ enabled = utils.tobool(args[1])
+ assert len(args) == 2
+ stats = self.s.setHaMaintenanceMode(mode, enabled)
+ if stats['status']['code']:
+ return stats['status']['code'], stats['status']['message']
+ return 0, ''
+
def do_getVmsInfo(self, args):
spUUID = args[0]
if len(args) >= 2:
@@ -2344,6 +2353,11 @@
('key=python_code [key=python_code] ...',
'set variables for MOM policy fine '
'tuning')),
+ 'setHaMaintenanceMode': (serv.do_setHaMaintenanceMode,
+ ('<type = global/local>'
+ ' <enabled = true/false>',
+ 'Enable or disable Hosted Engine HA'
+ ' maintenance')),
'deleteImage': (serv.deleteImage,
('<sdUUID> <spUUID> <imgUUID> [<postZero>] [<force>]',
'Delete Image folder with all volumes.',
diff --git a/lib/vdsm/define.py b/lib/vdsm/define.py
index 5cd9b99..abf6437 100644
--- a/lib/vdsm/define.py
+++ b/lib/vdsm/define.py
@@ -135,6 +135,9 @@
'setNumberOfCpusErr': {'status': {
'code': 60,
'message': 'Failed to set the number of cpus'}},
+ 'haErr': {'status': {
+ 'code': 61,
+ 'message': 'Failed to set Hosted Engine HA policy'}},
'recovery': {'status': {
'code': 99,
'message': 'Recovering from crash or Initializing'}},
diff --git a/vdsm/API.py b/vdsm/API.py
index ae1ec79..9fd4294 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1487,6 +1487,30 @@
except:
return errCode['momErr']
+ def setHaMaintenanceMode(self, mode, enabled):
+ """
+ Sets Hosted Engine HA maintenance mode ('global' or 'local') to
+ enabled (True) or disabled (False).
+ """
+ if not haClient:
+ return errCode['unavail']
+
+ self.log.info("Setting Hosted Engine HA {0} maintenance to {1}"
+ .format(mode.lower(), enabled))
+ if mode.lower() == 'global':
+ mm = haClient.HAClient.MaintenanceMode.GLOBAL
+ elif mode.lower() == 'local':
+ mm = haClient.HAClient.MaintenanceMode.LOCAL
+ else:
+ return errCode['haErr']
+
+ try:
+ haClient.HAClient().set_maintenance_mode(mm, enabled)
+ except:
+ self.log.exception("error setting HA maintenance mode")
+ return errCode['haErr']
+ return {'status': doneCode}
+
# take a rough estimate on how much free mem is available for new vm
# memTotal = memFree + memCached + mem_used_by_non_qemu + resident .
# simply returning (memFree + memCached) is not good enough, as the
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index d0987e5..54cae06 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -427,6 +427,10 @@
api = API.Global()
return api.setMOMPolicyParameters(key_value_store)
+ def setHaMaintenanceMode(self, mode, enabled):
+ api = API.Global()
+ return api.setHaMaintenanceMode(mode, enabled)
+
def domainActivate(self, sdUUID, spUUID, options=None):
domain = API.StorageDomain(sdUUID)
return domain.activate(spUUID)
@@ -846,6 +850,7 @@
(self.setLogLevel, 'setLogLevel'),
(self.setMOMPolicy, 'setMOMPolicy'),
(self.setMOMPolicyParameters, 'setMOMPolicyParameters'),
+ (self.setHaMaintenanceMode, 'setHaMaintenanceMode'),
(self.vmHotplugDisk, 'hotplugDisk'),
(self.vmHotunplugDisk, 'hotunplugDisk'),
(self.vmHotplugNic, 'hotplugNic'),
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 12f0c98..cd7dd36 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -460,6 +460,35 @@
'data': {'key_value_store': 'dict'}}
##
+# @HaMaintenanceMode:
+#
+# An enumeration of recognized Hosted Engine maintenance modes.
+#
+# @GLOBAL: Suspend Hosted Engine agent actions on all hosts
+#
+# @LOCAL: Suspend Hosted Engine agent on this host, after migrating
+# engine VM, if necessary.
+#
+# Since: 4.14.0
+##
+{'enum': 'HaMaintenanceMode',
+ 'data': ['GLOBAL', 'LOCAL']}
+
+##
+# @Host.setHaMaintenanceMode:
+#
+# Configure maintenance for Hosted Engine subsystem.
+#
+# @mode: Type of maintenance to configure
+#
+# @enabled: Whether to enable or disable maintenance
+#
+# Since: 4.14.0
+##
+{'command': {'class': 'Host', 'name': 'setHaMaintenanceMode'},
+ 'data': {'mode': 'HaMaintenanceMode', 'enabled': 'bool'}}
+
+##
# @TaskDetails:
#
# A collection of information about a task.
--
To view, visit http://gerrit.ovirt.org/24091
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic08c5edb0e9b8cc11eb70ef6a66301335c42aad3
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.4
Gerrit-Owner: Greg Padgett <gpadgett(a)redhat.com>
10 years, 4 months
Change in vdsm[master]: vm: added missing GUID slot in Drive class
by derez@redhat.com
Daniel Erez has uploaded a new change for review.
Change subject: vm: added missing GUID slot in Drive class
......................................................................
vm: added missing GUID slot in Drive class
Following commit I6e8dadabdd02d3b44606f215c4bc7b7e306a591a,
added missing 'GUID' slot in VM -> Drive class
(needed for the functionality introduced in commit
Ia4988212f7f96078e774d2a4e7b5cd1681383cb0).
In addition, verified 'GUID' key existence on _getDiskStats.
Change-Id: I2c64375138061e4310188baddbe114251ac157cc
Related-To-Bug-Url: https://bugzilla.redhat.com/1026868
Signed-off-by: Daniel Erez <derez(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 2 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/24418/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 9371049..dfb4381 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -631,7 +631,7 @@
'apparentsize': str(vmDrive.apparentsize)}
if isVdsmImage(vmDrive):
dStats['imageID'] = vmDrive.imageID
- else:
+ elif "GUID" in vmDrive:
dStats['lunGUID'] = vmDrive.GUID
dStats['readRate'] = ((eInfo[dName][1] - sInfo[dName][1]) /
sampleInterval)
@@ -1453,7 +1453,7 @@
'propagateErrors', 'address', 'apparentsize', 'volumeInfo',
'index', 'name', 'optional', 'shared', 'truesize',
'volumeChain', 'baseVolumeID', 'serial', 'reqsize', 'cache',
- '_blockDev', 'extSharedState', 'drv', 'sgio')
+ '_blockDev', 'extSharedState', 'drv', 'sgio', 'GUID')
VOLWM_CHUNK_MB = config.getint('irs', 'volume_utilization_chunk_mb')
VOLWM_FREE_PCT = 100 - config.getint('irs', 'volume_utilization_percent')
VOLWM_CHUNK_REPLICATE_MULT = 2 # Chunk multiplier during replication
--
To view, visit http://gerrit.ovirt.org/24418
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2c64375138061e4310188baddbe114251ac157cc
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Daniel Erez <derez(a)redhat.com>
10 years, 4 months
Change in vdsm[master]: supervdsm: Enable multiprocessing module logging.
by lyarwood@redhat.com
Lee Yarwood has uploaded a new change for review.
Change subject: supervdsm: Enable multiprocessing module logging.
......................................................................
supervdsm: Enable multiprocessing module logging.
The multiprocessing module includes error logging using Python's logging
module, but it is not enabled by default. This patch enables the
logging and sets it to propagate to the supervdsmServer's root logger,
so it now defaults to producing logging and can be configured easily
from /etc/vdsm/svdsm.logger.conf.
Change-Id: Idbbe0f1eb294e99de997f78b964a062fdddbb6ea
Signed-off-by: Lee Yarwood <lyarwood(a)redhat.com>
Signed-off-by: David Gibson <dgibson(a)redhat.com>
---
M vdsm/supervdsmServer
1 file changed, 2 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/41/19741/1
diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer
index 40ec9df..006c35c 100755
--- a/vdsm/supervdsmServer
+++ b/vdsm/supervdsmServer
@@ -30,6 +30,7 @@
import signal
import logging
import logging.config
+import multiprocessing
LOG_CONF_PATH = "/etc/vdsm/svdsm.logger.conf"
@@ -356,6 +357,7 @@
def main(sockfile, pidfile=None):
log = logging.getLogger("SuperVdsm.Server")
+ multiprocessing.get_logger().propagate = 1
def bind(func):
def wrapper(_SuperVdsm, *args, **kwargs):
--
To view, visit http://gerrit.ovirt.org/19741
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idbbe0f1eb294e99de997f78b964a062fdddbb6ea
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Lee Yarwood <lyarwood(a)redhat.com>
10 years, 4 months
Change in vdsm[master]: lvm: Make the isActiveLV() method public.
by lyarwood@redhat.com
Lee Yarwood has uploaded a new change for review.
Change subject: lvm: Make the isActiveLV() method public.
......................................................................
lvm: Make the isActiveLV() method public.
This change makes the private isActiveLV() method public for
use in the blockSD layer.
Change-Id: I670fe3969b88819891c64ea3ac487b070618aaec
Signed-off-by: Lee Yarwood <lyarwood(a)redhat.com>
---
M vdsm/storage/lvm.py
1 file changed, 1 insertion(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/86/21386/1
diff --git a/vdsm/storage/lvm.py b/vdsm/storage/lvm.py
index 112f1c0..76184b8 100644
--- a/vdsm/storage/lvm.py
+++ b/vdsm/storage/lvm.py
@@ -1221,10 +1221,8 @@
return os.path.basename(os.readlink(lvp))
-def _isLVActive(vgName, lvName):
+def isLVActive(vgName, lvName):
"""Active volumes have a mp link.
-
- This function should not be used out of this module.
"""
return os.path.exists(lvPath(vgName, lvName))
--
To view, visit http://gerrit.ovirt.org/21386
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I670fe3969b88819891c64ea3ac487b070618aaec
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Lee Yarwood <lyarwood(a)redhat.com>
10 years, 4 months
Change in vdsm[master]: vdsm: Enable config of VM serial number
by mbetak@redhat.com
Martin Betak has uploaded a new change for review.
Change subject: vdsm: Enable config of VM serial number
......................................................................
vdsm: Enable config of VM serial number
Added support for passing explicit serial number
as a part of vmParams from the engine.
In case this new 'serial' param is not passed we fall back to the old
behavior when we use the host UUID.
Change-Id: I76309e833f0b00e69a187037a415642a8daf35f6
Signed-off-by: Martin Betak <mbetak(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 4 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/24274/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index aae8bd6..540834c 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -1014,7 +1014,7 @@
if self.arch == caps.Architecture.X86_64:
oselem.appendChildWithArgs('smbios', mode='sysinfo')
- def appendSysinfo(self, osname, osversion, hostUUID):
+ def appendSysinfo(self, osname, osversion, serial):
"""
Add <sysinfo> element to domain:
@@ -1045,7 +1045,7 @@
appendEntry('manufacturer', constants.SMBIOS_MANUFACTURER)
appendEntry('product', osname)
appendEntry('version', osversion)
- appendEntry('serial', hostUUID)
+ appendEntry('serial', serial)
appendEntry('uuid', self.conf['vmId'])
def appendFeatures(self):
@@ -2922,11 +2922,12 @@
osd = caps.osversion()
osVersion = osd.get('version', '') + '-' + osd.get('release', '')
+ serialNumber = self.conf.get('serial', utils.getHostUUID())
domxml.appendSysinfo(
osname=constants.SMBIOS_OSNAME,
osversion=osVersion,
- hostUUID=utils.getHostUUID())
+ serial=serialNumber)
domxml.appendClock()
--
To view, visit http://gerrit.ovirt.org/24274
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I76309e833f0b00e69a187037a415642a8daf35f6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Betak <mbetak(a)redhat.com>
10 years, 4 months
Change in vdsm[ovirt-3.3]: Removing vdsm-python-cpopen rpm creation from vdsm
by ybronhei@redhat.com
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Removing vdsm-python-cpopen rpm creation from vdsm
......................................................................
Removing vdsm-python-cpopen rpm creation from vdsm
In vdsm 4.13.2 we replaced the dependency of python-cpopen (commit
f3677ba1). Due to that change we are no longer required to provide
vdsm-python-cpopen as part of vdsm build. This patch removes all cpopen
related files from vdsm.
Change-Id: Ib21f293075a9d1464f7f6a08fd689c9fd76f33e8
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1063180
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M Makefile.am
M configure.ac
M debian/Makefile.am
M debian/control
D debian/vdsm-python-cpopen.install
M lib/Makefile.am
D lib/cpopen/.gitignore
D lib/cpopen/Makefile.am
D lib/cpopen/__init__.py
D lib/cpopen/cpopen.c
D lib/cpopen/setup.py
D lib/cpopen/tests.py
M vdsm.spec.in
13 files changed, 8 insertions(+), 755 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/60/24360/1
diff --git a/Makefile.am b/Makefile.am
index d71ee28..9b1a3c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -57,7 +57,6 @@
# checkd from now on
PEP8_WHITELIST = \
client \
- lib/cpopen/*.py \
lib/vdsm/*.py \
lib/vdsm/*.py.in \
tests \
diff --git a/configure.ac b/configure.ac
index 52105e9..aac15b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -181,6 +181,7 @@
AX_PYTHON_MODULE([ethtool], [fatal])
AX_PYTHON_MODULE([libvirt], [fatal])
AX_PYTHON_MODULE([pthreading], [fatal])
+AX_PYTHON_MODULE([cpopen], [fatal])
# External programs (sorted, please keep in order)
AC_PATH_PROG([BLKID_PATH], [blkid], [/sbin/blkid])
@@ -254,7 +255,6 @@
init/sysvinit/Makefile
init/upstart/Makefile
lib/Makefile
- lib/cpopen/Makefile
lib/vdsm/Makefile
lib/vdsm/tool/Makefile
lib/yajsonrpc/Makefile
diff --git a/debian/Makefile.am b/debian/Makefile.am
index 25e79c3..732529d 100644
--- a/debian/Makefile.am
+++ b/debian/Makefile.am
@@ -84,8 +84,6 @@
vdsm.postrm \
vdsm.preinst \
vdsm.prerm \
- vdsm-python-cpopen.docs \
- vdsm-python-cpopen.install \
vdsm-python.docs \
vdsm-python.install \
vdsm-tests.docs \
diff --git a/debian/control b/debian/control
index da030ad..820bc26 100644
--- a/debian/control
+++ b/debian/control
@@ -31,13 +31,6 @@
Vcs-Git: git://gerrit.ovirt.org/vdsm
Vcs-Browser: http://gerrit.ovirt.org/gitweb?p=vdsm.git
-Package: vdsm-python-cpopen
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python (>=2.7.3)
-Description: Creates a sub-process in simpler safer manner
- Python package for creating sub-process in simpler and safer manner by using
- C code.
-
Package: vdsm-yajsonrpc
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python (>=2.7.3),
@@ -54,7 +47,7 @@
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends},
python (>=2.7.3),
- vdsm-python-cpopen (>= ${source:Version}),
+ python-cpopen,
vdsm-python (= ${source:Version})
Description: VDSM command line interface
Call VDSM commands from the command line. Used for testing and debugging.
@@ -93,7 +86,7 @@
policycoreutils (>= 2.1.10),
psmisc (>= 22.6),
python (>= 2.7.3),
- vdsm-python-cpopen (= ${binary:Version}),
+ python-cpopen,
python-dmidecode,
python-ethtool (>= 0.8),
python-ethtool (>= 0.8),
diff --git a/debian/vdsm-python-cpopen.install b/debian/vdsm-python-cpopen.install
deleted file mode 100644
index d38a40e..0000000
--- a/debian/vdsm-python-cpopen.install
+++ /dev/null
@@ -1,2 +0,0 @@
-./usr/lib/python2.7/dist-packages/cpopen/__init__.py
-./usr/lib/python2.7/dist-packages/cpopen/cpopen.so
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b1a1a12..ff46328 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,4 +19,4 @@
#
include $(top_srcdir)/build-aux/Makefile.subs
-SUBDIRS = vdsm cpopen yajsonrpc
+SUBDIRS = vdsm yajsonrpc
diff --git a/lib/cpopen/.gitignore b/lib/cpopen/.gitignore
deleted file mode 100644
index d23b815..0000000
--- a/lib/cpopen/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-build
-*.so
diff --git a/lib/cpopen/Makefile.am b/lib/cpopen/Makefile.am
deleted file mode 100644
index c39ca24..0000000
--- a/lib/cpopen/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright 2012 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
-#
-
-cpopendir = $(pyexecdir)/cpopen
-
-dist_cpopen_PYTHON = \
- __init__.py \
- $(NULL)
-
-cpopen.so: cpopen.c setup.py
- (cd $(srcdir); $(PYTHON) setup.py build \
- --build-temp $(abs_builddir) --build-lib $(abs_builddir))
-
-all-local: cpopen.so
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(cpopendir)
- $(INSTALL_PROGRAM) cpopen.so \
- $(DESTDIR)$(cpopendir)/cpopen.so
-
-check-local: tests.py
- nosetests tests.py
-
-EXTRA_DIST = \
- cpopen.c \
- tests.py \
- setup.py
-
-CLEANFILES = \
- cpopen.o \
- cpopen.so
diff --git a/lib/cpopen/__init__.py b/lib/cpopen/__init__.py
deleted file mode 100644
index d671355..0000000
--- a/lib/cpopen/__init__.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Copyright 2012 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
-#
-
-"""
-Python's implementation of Popen forks back to python before execing.
-Forking a python proc is a very complex and volatile process.
-
-This is a simpler method of execing that doesn't go back to python after
-forking. This allows for faster safer exec.
-"""
-
-import os
-from subprocess import Popen, PIPE
-
-from cpopen import createProcess
-
-
-class CPopen(Popen):
- def __init__(self, args, close_fds=False, cwd=None, env=None,
- deathSignal=0):
- if not isinstance(args, list):
- args = list(args)
-
- if env is not None and not isinstance(env, list):
- env = list(("=".join(item) for item in env.iteritems()))
-
- self._deathSignal = int(deathSignal)
- Popen.__init__(self, args,
- close_fds=close_fds, cwd=cwd, env=env,
- stdin=PIPE, stdout=PIPE,
- stderr=PIPE)
-
- def _execute_child(self, args, executable, preexec_fn, close_fds,
- cwd, env, universal_newlines,
- startupinfo, creationflags, shell,
- p2cread, p2cwrite,
- c2pread, c2pwrite,
- errread, errwrite):
-
- try:
- pid, stdin, stdout, stderr = \
- createProcess(args, close_fds, p2cread, p2cwrite,
- c2pread, c2pwrite, errread, errwrite,
- cwd, env, self._deathSignal)
-
- self.pid = pid
- self._closed = False
- self._returncode = None
- except:
- os.close(p2cwrite)
- os.close(errread)
- os.close(c2pread)
- raise
- finally:
- os.close(p2cread)
- os.close(errwrite)
- os.close(c2pwrite)
diff --git a/lib/cpopen/cpopen.c b/lib/cpopen/cpopen.c
deleted file mode 100644
index 7b9ddce..0000000
--- a/lib/cpopen/cpopen.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
-* Copyright 2012 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
-*/
-
-#include <Python.h>
-
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/prctl.h>
-
-static PyObject *createProcess(PyObject *self, PyObject *args);
-static PyMethodDef CreateProcessMethods[];
-static void closeFDs(int errnofd);
-
-/* Python boilerplate */
-static PyMethodDef
-CreateProcessMethods[] = {
- {"createProcess", createProcess, METH_VARARGS,
- "Execute a command."},
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-PyMODINIT_FUNC
-initcpopen(void)
-{
- PyObject *m;
-
- m = Py_InitModule("cpopen", CreateProcessMethods);
-
- /* In the future put other init code after this condition. */
- if (m == NULL)
- return;
-}
-
-/* Just like close() but retries on interrupt */
-static int
-safeClose(int fd) {
- int rv;
-
-retry:
- rv = close(fd);
- if ((rv < 0) && (errno == EINTR)) {
- goto retry;
- }
-
- return rv;
-}
-
-/* Just like read() but retries on interrupt and tries to fill the buffer */
-static int
-safeRead(int fd, void *buff, size_t count) {
- size_t bread = 0;
- char* cbuff = buff;
- int rv = 0;
- while (bread < count) {
- rv = read(fd, cbuff + bread, count - bread);
- if (rv == 0) { /* EOF */
- return bread;
- } else if (rv < 0) { /* ERROR */
- switch (errno) {
- case EINTR:
- case EAGAIN:
- break;
- default:
- return rv;
- }
- } else { /* Success */
- bread += rv;
- }
- }
-
- return bread;
-}
-
-static int
-setCloseOnExec(int fd) {
- int flags;
-
- flags = fcntl(fd, F_GETFD);
- if (flags == -1) {
- return -1;
- }
-
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
- return -1;
- }
-
- return 0;
-}
-
-/* Closes all open FDs except for stdin, stdout and stderr */
-static void
-closeFDs(int errnofd) {
- DIR *dp;
- int dfd;
- struct dirent *ep;
- int fdNum = -1;
-
- dfd = open("/proc/self/fd/", O_RDONLY);
- dp = fdopendir(dfd);
- while ((ep = readdir(dp))) {
- if(sscanf(ep->d_name, "%d", &fdNum) < 1) {
- continue;
- }
-
- if (fdNum < 3) {
- continue;
- }
-
- if (fdNum == dfd) {
- continue;
- }
-
- if (fdNum == errnofd) {
- continue;
- }
-
- safeClose(fdNum);
- }
-
- closedir(dp);
- safeClose(dfd);
-}
-
-static void
-freeStringArray(char** arr) {
- char** item;
- for (item = arr; *item != NULL; item++) {
- PyMem_Free(*item);
- }
-
- free(arr);
-}
-
-/* Copies the strings from a python list to a null terminated array.
- * The strings are shallow copied and are owned by python.
- * Don't keep this array after the call.
- *
- * Returns a NULL terminated array of null strings. On error returns NULL and
- * sets the python error accordingly
- */
-static char**
-pyListToArray(PyObject* list, int checkIfEmpty) {
- int argn;
- int i;
- char** argv;
-
- if (!PyList_Check(list)) {
- PyErr_SetString(PyExc_TypeError, "Argument must be a python list");
- return NULL;
- }
-
- argn = PyList_Size(list);
- if ((checkIfEmpty) && (argn < 1)) {
- PyErr_SetString(PyExc_ValueError, "List must not be empty");
- return NULL;
- }
-
- argv = calloc(argn + 1, sizeof(char*));
- if (!argv) {
- PyErr_SetFromErrno(PyExc_OSError);
- return NULL;
- }
-
- for (i = 0; i < argn; i++) {
- if (!PyArg_Parse(PyList_GetItem(list, i),
- "et;",
- Py_FileSystemDefaultEncoding,
- &argv[i])) {
- PyErr_SetString(PyExc_TypeError,
- "createProcess() arg 2 must contain only strings");
- goto fail;
- }
- }
-
- return argv;
-
-fail:
- freeStringArray(argv);
- return NULL;
-}
-
-/* Python's implementation of Popen forks back to python before execing.
- * Forking a python proc is a very complex and volatile process.
- *
- * This is a simpler method of execing that doesn't go back to python after
- * forking. This allows for faster safer exec.
- *
- * return NULL on error and sets the python error accordingly.
- */
-static PyObject *
-createProcess(PyObject *self, PyObject *args)
-{
- int cpid;
- int deathSignal = 0;
- int rv;
-
- int outfd[2] = {-1, -1};
- int in1fd[2] = {-1, -1};
- int in2fd[2] = {-1, -1};
-
- int errnofd[2] = {-1, -1};
- int childErrno = 0;
-
- PyObject* pyArgList;
- PyObject* pyEnvList;
- const char* cwd;
- int close_fds = 0;
-
- char** argv = NULL;
- char** envp = NULL;
-
- if (!PyArg_ParseTuple(args, "O!iiiiiiizOi:createProcess;",
- &PyList_Type, &pyArgList, &close_fds,
- &outfd[0], &outfd[1],
- &in1fd[0], &in1fd[1],
- &in2fd[0], &in2fd[1],
- &cwd, &pyEnvList, &deathSignal)) {
- return NULL;
- }
-
- argv = pyListToArray(pyArgList, 1);
- if (!argv) {
- goto fail;
- }
-
- if (PyList_Check(pyEnvList)) {
- envp = pyListToArray(pyEnvList, 0);
- if (!envp) {
- goto fail;
- }
- }
-
- if(pipe(errnofd) < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto fail;
- }
-
-try_fork:
- cpid = fork();
- if (cpid < 0) {
- if (errno == EAGAIN ||
- errno == EINTR ) {
- goto try_fork;
- }
-
- PyErr_SetFromErrno(PyExc_OSError);
- goto fail;
- }
-
- if (!cpid) {
- safeClose(0);
- safeClose(1);
- safeClose(2);
-
- dup2(outfd[0], 0);
- dup2(in1fd[1], 1);
- dup2(in2fd[1], 2);
-
- safeClose(outfd[0]);
- safeClose(outfd[1]);
- safeClose(in1fd[0]);
- safeClose(in1fd[1]);
- safeClose(in2fd[0]);
- safeClose(in2fd[1]);
- safeClose(errnofd[0]);
-
- if (deathSignal) {
- childErrno = prctl(PR_SET_PDEATHSIG, deathSignal);
- if (childErrno < 0) {
- childErrno = errno;
- }
- /* Check that parent did not already die between fork and us
- * setting the death signal */
- if (write(errnofd[1], &childErrno, sizeof(int)) < sizeof(int)) {
- exit(-1);
- }
-
- if (childErrno != 0) {
- exit(-1);
- }
- }
-
- if (setCloseOnExec(errnofd[1]) < 0) {
- goto sendErrno;
- }
-
- if (close_fds) {
- closeFDs(errnofd[1]);
- }
-
- if (cwd) {
- if (chdir(cwd) < 0) {
- goto sendErrno;
- }
- setenv("PWD", cwd, 1);
- }
-exec:
- if (envp) {
- execvpe(argv[0], argv, envp);
- } else {
- execvp(argv[0], argv);
- }
-
- if (errno == EINTR ||
- errno == EAGAIN )
- {
- goto exec;
- }
-sendErrno:
- if (write(errnofd[1], &errno, sizeof(int)) < 0) {
- exit(errno);
- }
- exit(-1);
- }
-
- safeClose(errnofd[1]);
- errnofd[1] = -1;
-
- if (deathSignal) {
- /* death signal sync point */
- rv = safeRead(errnofd[0], &childErrno, sizeof(int));
- if (rv != sizeof(int)) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto fail;
- } else if (childErrno != 0) {
- PyErr_SetString(PyExc_OSError, strerror(childErrno));
- goto fail;
- }
- }
-
- /* error sync point */
- rv = safeRead(errnofd[0], &childErrno, sizeof(int));
- if (rv == sizeof(int)) {
- PyErr_SetString(PyExc_OSError, strerror(childErrno));
- goto fail;
- } else if (rv < 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto fail;
- }
-
- safeClose(errnofd[0]);
- errnofd[0] = -1;
-
- /* From this point errors shouldn't occur, if they do something is very
- * very very wrong */
-
- freeStringArray(argv);
-
- if (envp) {
- freeStringArray(envp);
- }
-
- return Py_BuildValue("(iiii)", cpid, outfd[1], in1fd[0], in2fd[0]);
-
-fail:
- if (argv) {
- freeStringArray(argv);
- }
-
- if (envp) {
- freeStringArray(envp);
- }
-
- if (errnofd[0] >= 0) {
- safeClose(errnofd[0]);
- }
-
- if (errnofd[1] >= 0) {
- safeClose(errnofd[1]);
- }
-
- return NULL;
-}
diff --git a/lib/cpopen/setup.py b/lib/cpopen/setup.py
deleted file mode 100644
index 66fc157..0000000
--- a/lib/cpopen/setup.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from distutils.core import setup, Extension
-
-module1 = Extension('cpopen',
- sources=['cpopen.c'])
-
-setup(name='cpopen',
- version='1.2.1',
- description='Creates a subprocess in simpler safer manner',
- py_modules=['__init__'],
- author='Yaniv Bronhaim',
- author_email='ybronhei(a)redhat.com',
- url='redhat.com',
- ext_modules=[module1])
diff --git a/lib/cpopen/tests.py b/lib/cpopen/tests.py
deleted file mode 100644
index 9dd1906..0000000
--- a/lib/cpopen/tests.py
+++ /dev/null
@@ -1,196 +0,0 @@
-#
-# Copyright 2012 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
-#
-import os
-import sys
-import subprocess
-from nose.plugins.skip import SkipTest
-import signal
-import threading
-import time
-
-from unittest import TestCase
-
-EXT_ECHO = "/bin/echo"
-
-if __name__ != "__main__":
- # This will not be available when we use this module as a subprocess
- import glob
- for p in glob.glob("build/*/"):
- sys.path.append(p)
-
- from . import CPopen
-
-
-class TestCPopen(TestCase):
- def testEcho(self):
- data = "Hello"
- p = CPopen([EXT_ECHO, "-n", data])
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
- self.assertEquals(p.stdout.read(), data)
-
- def testCat(self):
- path = "/etc/passwd"
- p = CPopen(["cat", path])
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
- with open(path, "r") as f:
- self.assertEquals(p.stdout.read(), f.read())
-
- def _subTest(self, name, params, *args, **kwargs):
- p = CPopen(["python", __file__, name] + params,
- *args, **kwargs)
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
- self.assertEquals(p.stdout.read().strip(), "True")
-
- def testCloseFDs(self):
- fds = os.pipe()
- try:
- self._subTest("fds", [str(fds[1])], close_fds=True)
- finally:
- os.close(fds[0])
- os.close(fds[1])
-
- def testNoCloseFds(self):
- fds = os.pipe()
- try:
- self._subTest("nofds", [str(fds[1])], close_fds=False)
- finally:
- os.close(fds[0])
- os.close(fds[1])
-
- def testEnv(self):
- env = os.environ.copy()
- env["TEST"] = "True"
- self._subTest("env", [], env=env)
-
- def testCwd(self):
- cwd = "/proc"
- p = CPopen(["python", "-c", "import os; print os.getcwd()"],
- cwd=cwd)
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
- self.assertEquals(p.stdout.read().strip(), cwd)
-
- def testRunNonExecutable(self):
- self.assertRaises(OSError, CPopen, ["/tmp"])
-
- def testBadCwd(self):
- self.assertRaises(OSError, CPopen, ["echo", "hello"],
- cwd="/~~~~~dasdas~~~~")
-
- def testUnicodeArg(self):
- data = u'hello'
- cmd = [EXT_ECHO, "-n", data]
-
- p = CPopen(cmd)
- p.wait()
- p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- p2.wait()
- self.assertEquals(p.stdout.read(), p2.stdout.read())
-
- def testNonASCIIUnicodeArg(self):
- data = u'\u05e9\u05dc\u05d5\u05dd'
- # If the default encoding is not utf-8 the test *should* fail as non
- # ascii conversion shouldn't work
- if sys.getfilesystemencoding() != "UTF-8":
- raise SkipTest("The default encoding isn't unicode")
-
- cmd = [EXT_ECHO, "-n", data]
-
- p = CPopen(cmd)
- p.wait()
- p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- p2.wait()
- self.assertEquals(p.stdout.read(), p2.stdout.read())
-
- def testStdin(self):
- data = "Hello World"
- p = CPopen(["cat"])
- p.stdin.write(data)
- p.stdin.flush()
- p.stdin.close()
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
-
- self.assertEquals(p.stdout.read(), data)
-
- def testStdinEpoll(self):
- import select
-
- data = "Hello World"
- p = CPopen(["cat"])
- ep = select.epoll()
- ep.register(p.stdin, select.EPOLLOUT)
- fd, ev = ep.poll(1)[0]
- ep.close()
- os.write(fd, data)
- p.stdin.close()
- p.wait()
- self.assertTrue(p.returncode == 0,
- "Process failed: %s" % os.strerror(p.returncode))
-
- self.assertEquals(p.stdout.read(), data)
-
- def testDeathSignal(self):
- # This is done because assignment in python doesn't cross scopes
- procPtr = [None]
-
- def spawn():
- procPtr[0] = CPopen(["sleep", "10"],
- deathSignal=signal.SIGKILL)
-
- t = threading.Thread(target=spawn)
- t.start()
- t.join()
- start = time.time()
- procPtr[0].wait()
- self.assertTrue(time.time() - start < 1)
-
-
-if __name__ == "__main__":
- cmd = sys.argv[1]
- if cmd == "fds":
- try:
- os.close(int(sys.argv[2]))
- print "False"
- except:
- print "True"
-
- elif cmd == "nofds":
- try:
- os.close(int(sys.argv[2]))
- print "True"
- except:
- print "False"
-
- elif cmd == "env":
- try:
- print os.environ.get("TEST", "False")
- except:
- print "False"
diff --git a/vdsm.spec.in b/vdsm.spec.in
index f5142a9..41a4e19 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -308,16 +308,6 @@
VDSM registration package. Used to register a Linux host to a Virtualization
Manager.
-%package python-cpopen
-Summary: Creates a sub-process in simpler safer manner.
-
-BuildRequires: python2-devel
-Conflicts: python-cpopen
-
-%description python-cpopen
-Python package for creating sub-process in simpler and safer manner by using C
-code.
-
%package python
Summary: VDSM python libraries
@@ -1332,11 +1322,11 @@
%{_datadir}/%{vdsm_name}/gluster/services.py*
%endif
-%files python-cpopen
-%{python_sitearch}/cpopen/__init__.py*
-%attr(755, root, root) %{python_sitearch}/cpopen/cpopen.so*
-
%changelog
+* Wed Feb 12 2014 Yaniv Bronhaim <ybronhei(a)redhat.com> - 4.13.2
+- Removing creation of vdsm-python-cpopen package and replace it by
+python-cpopen requirement.
+
* Sun Apr 07 2013 Yaniv Bronhaim <ybronhei(a)redhat.com> - 4.9.0-1
- Adding cpopen package
--
To view, visit http://gerrit.ovirt.org/24360
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib21f293075a9d1464f7f6a08fd689c9fd76f33e8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.3
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
10 years, 4 months
Change in vdsm[ovirt-3.4]: vm: discover volume path from xml definition
by Federico Simoncelli
Hello Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/24324
to review the following change.
Change subject: vm: discover volume path from xml definition
......................................................................
vm: discover volume path from xml definition
In a previous commit (c072945 One shot prepare) we involuntarily
changed the path used for virtual machine images from:
/rhev/data-center/<spUUID>/<sdUUID>/images/<imgUUID>/<volUUID>
to:
/rhev/data-center/mnt/blockSD/<sdUUID>/images/<imgUUID>/<volUUID>
This generated an issue during live migration between different
vdsm versions:
libvirtError: invalid argument: invalid path ... not assigned to
domain
In this patch we inspect libvirt xml during live migration and vdsm
restart to identify if it is necessary to update the path cached in
the drive object (provided by prepareImage).
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1059482
Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/24202
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 18 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/24324/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index ab32971..d3d47ab 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -4964,6 +4964,16 @@
self.log.debug('Looking for drive with attributes %s', deviceDict)
for d in self._devices[DISK_DEVICES]:
+ # When we analyze a disk device that was already discovered in
+ # the past (generally as soon as the VM is created) we should
+ # verify that the cached path is the one used in libvirt.
+ # We already hit few times the problem that after a live
+ # migration the paths were not in sync anymore (BZ#1059482).
+ if (hasattr(d, 'alias') and d.alias == alias
+ and d.path != devPath):
+ self.log.warning('updating drive %s path from %s to %s',
+ d.alias, d.path, devPath)
+ d.path = devPath
if d.path == devPath:
d.name = name
d.type = devType
@@ -4977,6 +4987,14 @@
# Update vm's conf with address for known disk devices
knownDev = False
for dev in self.conf['devices']:
+ # See comment in previous loop. This part is used to update
+ # the vm configuration as well.
+ if ('alias' in dev and dev['alias'] == alias
+ and dev['path'] != devPath):
+ self.log.warning('updating drive %s config path from %s '
+ 'to %s', dev['alias'], dev['path'],
+ devPath)
+ dev['path'] = devPath
if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
dev['name'] = name
dev['address'] = address
--
To view, visit http://gerrit.ovirt.org/24324
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.4
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
10 years, 4 months
Change in vdsm[ovirt-3.3]: vm: discover volume path from xml definition
by Federico Simoncelli
Hello Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/24329
to review the following change.
Change subject: vm: discover volume path from xml definition
......................................................................
vm: discover volume path from xml definition
In a previous commit (c072945 One shot prepare) we involuntarily
changed the path used for virtual machine images from:
/rhev/data-center/<spUUID>/<sdUUID>/images/<imgUUID>/<volUUID>
to:
/rhev/data-center/mnt/blockSD/<sdUUID>/images/<imgUUID>/<volUUID>
This generated an issue during live migration between different
vdsm versions:
libvirtError: invalid argument: invalid path ... not assigned to
domain
In this patch we inspect libvirt xml during live migration and vdsm
restart to identify if it is necessary to update the path cached in
the drive object (provided by prepareImage).
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1061621
Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/24202
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 18 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/29/24329/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index bb35f0e..fd295eb 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -4743,6 +4743,16 @@
address = self._getUnderlyingDeviceAddress(x)
for d in self._devices[DISK_DEVICES]:
+ # When we analyze a disk device that was already discovered in
+ # the past (generally as soon as the VM is created) we should
+ # verify that the cached path is the one used in libvirt.
+ # We already hit few times the problem that after a live
+ # migration the paths were not in sync anymore (BZ#1059482).
+ if (hasattr(d, 'alias') and d.alias == alias
+ and d.path != devPath):
+ self.log.warning('updating drive %s path from %s to %s',
+ d.alias, d.path, devPath)
+ d.path = devPath
if d.path == devPath:
d.name = name
d.type = devType
@@ -4755,6 +4765,14 @@
# Update vm's conf with address for known disk devices
knownDev = False
for dev in self.conf['devices']:
+ # See comment in previous loop. This part is used to update
+ # the vm configuration as well.
+ if ('alias' in dev and dev['alias'] == alias
+ and dev['path'] != devPath):
+ self.log.warning('updating drive %s config path from %s '
+ 'to %s', dev['alias'], dev['path'],
+ devPath)
+ dev['path'] = devPath
if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
dev['name'] = name
dev['address'] = address
--
To view, visit http://gerrit.ovirt.org/24329
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.3
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
10 years, 4 months
Change in vdsm[master]: caps: Collect numa information
by fromani@redhat.com
Francesco Romani has posted comments on this change.
Change subject: caps: Collect numa information
......................................................................
Patch Set 5: Code-Review+1
(2 comments)
http://gerrit.ovirt.org/#/c/23703/5//COMMIT_MSG
Commit Message:
Line 15: The items are separated by semicolon, the fields in each item
Line 16: are separated by colon.
Line 17: Take the first item above to explain the meaning of each field:
Line 18: 0 - The index of numa node
Line 19: 0,1 - The index of cpus(core) which belong to this numa node
ok, so is cpu,core right?
Line 20: 10240 - The total memory of this numa node
Line 21: 9500 - The free memory of this numa node
Line 22:
Line 23: Change-Id: I63eeb697ab986c3b9cad0dc44f41924f329e52cd
http://gerrit.ovirt.org/#/c/23703/5/vdsm/caps.py
File vdsm/caps.py:
Line 181: memInfo = _getMemoryStatsByNumaCell(int(cellInfo[0]), 0, memStats)
Line 182: cellInfo.append(str(memInfo['total']/1024))
Line 183: cellInfo.append(str(memInfo['free']/1024))
Line 184: cellsInfo.append(':'.join(cellInfo))
Line 185: return ';'.join(cellsInfo)
I feel this can be improved somehow but I don't have any suggestion here. On the other hand, we also have XML processing improvements in the pipeline and I don't see any obvious issue, in the nd I think it is good enough to go.
Line 186:
Line 187:
Line 188: def _getMemoryStatsByNumaCell(cell, flags=0, memStats=None):
Line 189: if memStats is None:
--
To view, visit http://gerrit.ovirt.org/23703
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I63eeb697ab986c3b9cad0dc44f41924f329e52cd
Gerrit-PatchSet: 5
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Xiaolei Shi <xiao-lei.shi(a)hp.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
10 years, 4 months
Change in vdsm[master]: xmlrpc: Use correct base class for parsing request
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: xmlrpc: Use correct base class for parsing request
......................................................................
xmlrpc: Use correct base class for parsing request
Previously we always used SecureXMLRPCServer.parse_request, even when
using SimpleXMLRPCServer. That happened to work since both inherit
parse_request from BaseHTTPServer. This patch use the correct base
class, so if one of them will override parse_request, we use the correct
method.
Change-Id: I4ef737c02afb97580179f381e0f227ee94e1383f
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M vdsm/BindingXMLRPC.py
1 file changed, 1 insertion(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/89/24289/1
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index b71dae5..7308c5c 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -109,8 +109,7 @@
return basehandler.setup(self)
def parse_request(self):
- r = (SecureXMLRPCServer.SecureXMLRPCRequestHandler.
- parse_request(self))
+ r = basehandler.parse_request(self)
threadLocal.flowID = self.headers.get(HTTP_HEADER_FLOWID)
return r
--
To view, visit http://gerrit.ovirt.org/24289
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4ef737c02afb97580179f381e0f227ee94e1383f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
10 years, 4 months