Change in vdsm[master]: spec: update sanlock dependencies
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: spec: update sanlock dependencies
......................................................................
spec: update sanlock dependencies
Forcing some old fedora installations to update sanlock to the latest
version. This is mostly to address:
- wdmd: dynamically select working watchdog device
which makes it possible to run sanlock on hardware (generally laptops)
with multiple watchdogs.
Change-Id: Ia9a28d7bf23ab93781bdf3d8cf5769fe149fdeb4
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 3 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/92/12292/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 38838ea..89da7af 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -107,7 +107,7 @@
Requires: device-mapper-multipath >= 0.4.9-52
Requires: e2fsprogs >= 1.41.12-11
Requires: kernel >= 2.6.32-279.9.1
-Requires: sanlock >= 2.3-4, sanlock-python
+Requires: sanlock >= 2.3-4
Requires: initscripts >= 9.03.31-2.el6_3.1
Requires: mom >= 0.3.0
Requires: selinux-policy-targeted >= 3.7.19-155
@@ -125,7 +125,7 @@
Requires: e2fsprogs >= 1.41.14
Requires: kernel >= 3.6
Requires: mom >= 0.3.0
-Requires: sanlock >= 2.4-2, sanlock-python
+Requires: sanlock >= 2.6-4
Requires: sed >= 4.2.1-10
Requires: selinux-policy-targeted >= 3.10.0-149
Requires: lvm2 >= 2.02.95
@@ -151,6 +151,7 @@
Requires: libselinux-python
Requires: %{name}-python = %{version}-%{release}
Requires: pyparted
+Requires: sanlock-python
Requires(post): /usr/sbin/saslpasswd2
Requires(post): /bin/hostname
--
To view, visit http://gerrit.ovirt.org/12292
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9a28d7bf23ab93781bdf3d8cf5769fe149fdeb4
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: core: introducing retrieveImage
by laravot@redhat.com
Liron Ar has uploaded a new change for review.
Change subject: core: introducing retrieveImage
......................................................................
core: introducing retrieveImage
Adding retrieveImage verb which allows to "upload" image data from vdsm
to the requester over HTTP.
Change-Id: If2df4d3a16f39bf80281d7669ed31fd8369bada5
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/storage/hsm.py
M vdsm/storage/image.py
M vdsm/storage/imageSharing.py
M vdsm/storage/sp.py
6 files changed, 91 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/41/26741/1
diff --git a/vdsm/API.py b/vdsm/API.py
index d075271..3403b8c 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -864,6 +864,11 @@
return self._irs.downloadImage(
methodArgs, self._spUUID, self._sdUUID, self._UUID, volUUID)
+ def retrieve(self, methodArgs, callback, startEvent, volUUID=None):
+ return self._irs.retrieveImage(methodArgs, callback, startEvent,
+ self._spUUID, self._sdUUID, self._UUID,
+ volUUID)
+
def downloadFromStream(self, methodArgs, callback, volUUID=None):
return self._irs.downloadImageFromStream(
methodArgs, callback, self._spUUID, self._sdUUID, self._UUID,
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 10146d5..abdba97 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -117,6 +117,8 @@
HEADER_DOMAIN = 'Storage-Domain-Id'
HEADER_IMAGE = 'Image-Id'
HEADER_VOLUME = 'Volume-Id'
+ HEADER_SIZE = 'Size'
+ HEADER_RESULT = 'Result'
HEADER_CONTENT_LENGTH = 'content-length'
HEADER_CONTENT_TYPE = 'content-type'
@@ -125,6 +127,33 @@
threadLocal.server = self.request.getsockname()[0]
return basehandler.setup(self)
+ def do_GET(self):
+ length = self._getIntHeader(self.HEADER_SIZE,
+ httplib.BAD_REQUEST)
+ image = self._constructImageFromRequestInfo()
+ startEvent = threading.Event()
+ methodArgs = {'fileObj': self.wfile,
+ 'length': length}
+
+ # Optional header
+ volUUID = self.headers.getheader(self.HEADER_VOLUME)
+
+ def operation():
+ opEndEvent, opEndCallback = self._createEventAndSetCallback()
+ response = image.retrieve(methodArgs, opEndCallback,
+ startEvent, volUUID)
+ json_response = self._convertToJson(response)
+ headers = {self.HEADER_CONTENT_TYPE:
+ 'application/octet-stream',
+ self.HEADER_CONTENT_LENGTH:
+ length,
+ self.HEADER_RESULT: json_response}
+ self.handle_response(headers)
+ startEvent.set()
+ self._waitForEvent(opEndEvent)
+
+ self._performSocketOp(operation)
+
def do_PUT(self):
contentLength = self._getIntHeader(self.HEADER_CONTENT_LENGTH,
httplib.LENGTH_REQUIRED)
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 0ebe129..c24cdb0 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1660,6 +1660,21 @@
methodArgs, sdUUID, imgUUID, volUUID)
@public
+ def retrieveImage(self, methodArgs, callback, startEvent, spUUID, sdUUID,
+ imgUUID, volUUID=None):
+ """
+ Retrieve an image.
+
+ Warning: Internal use only.
+ """
+ sdCache.produce(sdUUID)
+ pool = self.getPool(spUUID)
+ # NOTE: this could become an hsm task
+ self._spmSchedule(spUUID, "retrieveImage", pool.retrieveImage,
+ methodArgs, callback, startEvent, sdUUID, imgUUID,
+ volUUID)
+
+ @public
def downloadImageFromStream(self, methodArgs, callback, spUUID, sdUUID,
imgUUID, volUUID=None):
"""
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 7d5f78d..fe04720 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -1174,6 +1174,15 @@
finally:
domain.deactivateImage(imgUUID)
+ def retrieve(self, methodArgs, sdUUID, imgUUID, volUUID):
+ domain = sdCache.produce(sdUUID)
+
+ vol = self._activateVolumeForImportExport(domain, imgUUID, volUUID)
+ try:
+ imageSharing.retrieveImage(vol.getVolumePath(), methodArgs)
+ finally:
+ domain.deactivateImage(imgUUID)
+
def copyToImage(self, methodArgs, sdUUID, imgUUID, volUUID=None):
domain = sdCache.produce(sdUUID)
diff --git a/vdsm/storage/imageSharing.py b/vdsm/storage/imageSharing.py
index 305cedb..789b541 100644
--- a/vdsm/storage/imageSharing.py
+++ b/vdsm/storage/imageSharing.py
@@ -89,6 +89,19 @@
p.kill()
raise
+
+def retrieveImage(dstImgPath, methodArgs):
+ fileObj = methodArgs['fileObj']
+ bytes_left = total_size = methodArgs['length']
+ cmd = [constants.EXT_DD, "if=%s" % dstImgPath, "bs=%s" % constants.MEGAB,
+ "count=%s" % (total_size / constants.MEGAB + 1)]
+
+ p = utils.execCmd(cmd, sync=False,
+ deathSignal=signal.SIGKILL)
+ p.blocking = True
+ try:
+ _copyData(p.stdout, fileObj, bytes_left)
+ _ensureProcessSucceded(p, constants.EXT_DD)
except Exception:
if p.returncode is None:
p.kill()
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index acc3838..7909fc5 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1629,6 +1629,26 @@
return image.Image(self.poolPath) \
.download(methodArgs, sdUUID, imgUUID, volUUID)
+ def retrieveImage(self, methodArgs, callback, startEvent, sdUUID, imgUUID,
+ volUUID=None):
+ """
+ Retrieves an image from to a given file the specified method
+ and methodArgs.
+ """
+ while not startEvent.is_set():
+ startEvent.wait()
+
+ imgResourceLock = rmanager.acquireResource(
+ sd.getNamespace(sdUUID, IMAGE_NAMESPACE), imgUUID,
+ rm.LockType.shared)
+
+ with imgResourceLock:
+ try:
+ return image.Image(self.poolPath) \
+ .retrieve(methodArgs, sdUUID, imgUUID, volUUID)
+ finally:
+ callback()
+
def downloadImageFromStream(self, methodArgs, callback, sdUUID, imgUUID,
volUUID=None):
"""
--
To view, visit http://gerrit.ovirt.org/26741
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If2df4d3a16f39bf80281d7669ed31fd8369bada5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
10 years
Change in vdsm[master]: core: refactor in BindingXMLRPC
by laravot@redhat.com
Liron Ar has uploaded a new change for review.
Change subject: core: refactor in BindingXMLRPC
......................................................................
core: refactor in BindingXMLRPC
moved logic from do_PUT to methods.
Change-Id: I64bb1b0a4cb85ce822929f1907847dd63eb69fc2
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/BindingXMLRPC.py
1 file changed, 83 insertions(+), 49 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/40/26740/1
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 76251f5..10146d5 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -126,59 +126,32 @@
return basehandler.setup(self)
def do_PUT(self):
- try:
- contentLength = self.headers.getheader(
- self.HEADER_CONTENT_LENGTH)
- if not contentLength:
- self.send_error(httplib.LENGTH_REQUIRED,
- "missing content length")
- return
+ contentLength = self._getIntHeader(self.HEADER_CONTENT_LENGTH,
+ httplib.LENGTH_REQUIRED)
+ image = self._constructImageFromRequestInfo()
+ methodArgs = {'fileObj': self.rfile,
+ 'length': contentLength}
+ # Optional header
+ volUUID = self.headers.getheader(self.HEADER_VOLUME)
- try:
- contentLength = int(contentLength)
- except ValueError:
- self.send_error(httplib.BAD_REQUEST,
- "invalid content length %r" %
- contentLength)
- return
-
- # Required headers
- spUUID = self.headers.getheader(self.HEADER_POOL)
- sdUUID = self.headers.getheader(self.HEADER_DOMAIN)
- imgUUID = self.headers.getheader(self.HEADER_IMAGE)
- if not all((spUUID, sdUUID, imgUUID)):
- self.send_error(httplib.BAD_REQUEST,
- "missing or empty required header(s):"
- " spUUID=%s sdUUID=%s imgUUID=%s"
- % (spUUID, sdUUID, imgUUID))
- return
-
- # Optional headers
- volUUID = self.headers.getheader(self.HEADER_VOLUME)
-
- uploadFinishedEvent = threading.Event()
-
- def upload_finished():
- uploadFinishedEvent.set()
-
- methodArgs = {'fileObj': self.rfile,
- 'contentLength': contentLength}
- image = API.Image(imgUUID, spUUID, sdUUID)
+ def operation():
+ opEndEvent, opEndCallback = self._createEventAndSetCallback()
response = image.downloadFromStream(methodArgs,
- upload_finished,
- volUUID)
+ opEndCallback, volUUID)
+ json_response = self._convertToJson(response)
+ self._waitForEvent(opEndEvent)
+ headers = {self.HEADER_CONTENT_TYPE:
+ 'application/json',
+ self.HEADER_CONTENT_LENGTH:
+ len(json_response)}
+ self.handle_response(headers,
+ json_response)
- while not uploadFinishedEvent.is_set():
- uploadFinishedEvent.wait()
+ self._performSocketOp(operation)
- json_response = json.dumps(response)
- self.send_response(httplib.OK)
- self.send_header(self.HEADER_CONTENT_TYPE,
- 'application/json')
- self.send_header(self.HEADER_CONTENT_LENGTH,
- len(json_response))
- self.end_headers()
- self.wfile.write(json_response)
+ def _performSocketOp(self, execFunc):
+ try:
+ execFunc()
except socket.timeout:
self.send_error(httplib.REQUEST_TIMEOUT,
@@ -188,6 +161,67 @@
self.send_error(httplib.INTERNAL_SERVER_ERROR,
"error during execution", exc_info=True)
+ def _constructImageFromRequestInfo(self):
+ # Required headers
+ spUUID = self.headers.getheader(self.HEADER_POOL)
+ sdUUID = self.headers.getheader(self.HEADER_DOMAIN)
+ imgUUID = self.headers.getheader(self.HEADER_IMAGE)
+ if not all((spUUID, sdUUID, imgUUID)):
+ self.send_error(httplib.BAD_REQUEST,
+ "missing or empty required header(s):"
+ " spUUID=%s sdUUID=%s imgUUID=%s"
+ % (spUUID, sdUUID, imgUUID))
+ return
+
+ return API.Image(imgUUID, spUUID, sdUUID)
+
+ @staticmethod
+ def _createEventAndSetCallback(self):
+ opFinishedEvent = threading.Event()
+
+ def setCallback():
+ opFinishedEvent.set()
+
+ return opFinishedEvent, setCallback
+
+ @staticmethod
+ def _waitForEvent(event):
+ while not event.is_set():
+ event.wait()
+
+ @staticmethod
+ def _convertToJson(data):
+ return json.dumps(data)
+
+ def _getIntHeader(self, headerName, missingError):
+ value = self.headers.getheader(
+ headerName)
+ if not value:
+ self.send_error(missingError,
+ "missing header %s" % headerName)
+ return
+
+ try:
+ value = int(value)
+ except ValueError:
+ self.send_error(httplib.BAD_REQUEST,
+ "invalid header value %r" %
+ value)
+ return
+
+ return value
+
+ def handle_response(self, headers, body=None):
+ self.send_response(httplib.OK)
+
+ for k, v in headers.iteritems():
+ self.send_header(k, v)
+
+ self.end_headers()
+
+ if body is not None:
+ self.wfile.write(body)
+
def send_error(self, error, message, exc_info=False):
try:
self.log.error(message, exc_info=exc_info)
--
To view, visit http://gerrit.ovirt.org/26740
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I64bb1b0a4cb85ce822929f1907847dd63eb69fc2
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
10 years
Change in vdsm[master]: core: generify "streamDownloadImage" related methods
by laravot@redhat.com
Liron Ar has uploaded a new change for review.
Change subject: core: generify "streamDownloadImage" related methods
......................................................................
core: generify "streamDownloadImage" related methods
This patch generifies the related "streamDownloadImage" methods in
image/imageSharing to be have more generic name as they could be used
with any passed fileObj.
Change-Id: I1c73374681b5a5fc9fd0cb81020138fb5c8bfe69
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/storage/image.py
M vdsm/storage/imageSharing.py
M vdsm/storage/sp.py
3 files changed, 9 insertions(+), 14 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/61/26761/1
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 63dc56a..7d5f78d 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -1174,14 +1174,14 @@
finally:
domain.deactivateImage(imgUUID)
- def downloadFromStream(self, methodArgs, sdUUID, imgUUID, volUUID=None):
+ def copyToImage(self, methodArgs, sdUUID, imgUUID, volUUID=None):
domain = sdCache.produce(sdUUID)
vol = self._activateVolumeForImportExport(domain, imgUUID, volUUID)
try:
# Extend the volume (if relevant) to the image size
vol.extend(imageSharing.
- streamGetSize(methodArgs) / volume.BLOCK_SIZE)
- imageSharing.streamDownloadImage(vol.getVolumePath(), methodArgs)
+ getLengthFromArgs(methodArgs) / volume.BLOCK_SIZE)
+ imageSharing.copyToImage(vol.getVolumePath(), methodArgs)
finally:
domain.deactivateImage(imgUUID)
diff --git a/vdsm/storage/imageSharing.py b/vdsm/storage/imageSharing.py
index 8f150f3..47d2bb1 100644
--- a/vdsm/storage/imageSharing.py
+++ b/vdsm/storage/imageSharing.py
@@ -60,7 +60,7 @@
return size
-def streamGetSize(methodArgs):
+def getLengthFromArgs(methodArgs):
return methodArgs['contentLength']
@@ -74,21 +74,16 @@
methodArgs.get("headers", {}))
-def streamDownloadImage(dstImgPath, methodArgs):
- bytes_left = streamGetSize(methodArgs)
- stream = methodArgs['fileObj']
+def copyToImage(dstImgPath, methodArgs):
+ bytes_left = getLengthFromArgs(methodArgs)
+ fileObj = methodArgs['fileObj']
cmd = [constants.EXT_DD, "of=%s" % dstImgPath, "bs=%s" % constants.MEGAB]
p = utils.execCmd(cmd, sudo=False, sync=False,
deathSignal=signal.SIGKILL)
try:
- _copyData(stream, p.stdin, bytes_left)
+ _copyData(fileObj, p.stdin, bytes_left)
_ensureProcessSucceded(p, constants.EXT_DD, se.StorageException)
- except Exception:
- if p.returncode is None:
- p.kill()
- raise
-
except Exception:
if p.returncode is None:
p.kill()
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 4de27d9..40feda3 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1641,7 +1641,7 @@
with imgResourceLock:
try:
return image.Image(self.poolPath) \
- .downloadFromStream(methodArgs, sdUUID, imgUUID, volUUID)
+ .copyToImage(methodArgs, sdUUID, imgUUID, volUUID)
finally:
callback()
--
To view, visit http://gerrit.ovirt.org/26761
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1c73374681b5a5fc9fd0cb81020138fb5c8bfe69
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
10 years
Change in vdsm[master]: core: removal of unneeded callback passing
by laravot@redhat.com
Liron Ar has uploaded a new change for review.
Change subject: core: removal of unneeded callback passing
......................................................................
core: removal of unneeded callback passing
The callback can be executed from sp.py after completing the operation,
eliminating the need to pass it to imageSharing.
Change-Id: I5a6e455dc3824f695fab241197ac628713f683a9
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/storage/image.py
M vdsm/storage/sp.py
2 files changed, 6 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/60/26760/1
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 44ba822..63dc56a 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -1174,14 +1174,7 @@
finally:
domain.deactivateImage(imgUUID)
- def downloadFromStream(self, methodArgs, callback, sdUUID, imgUUID,
- volUUID=None):
- try:
- self._downloadFromStream(methodArgs, sdUUID, imgUUID, volUUID)
- finally:
- callback()
-
- def _downloadFromStream(self, methodArgs, sdUUID, imgUUID, volUUID=None):
+ def downloadFromStream(self, methodArgs, sdUUID, imgUUID, volUUID=None):
domain = sdCache.produce(sdUUID)
vol = self._activateVolumeForImportExport(domain, imgUUID, volUUID)
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 338232f..4de27d9 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1639,9 +1639,11 @@
rm.LockType.exclusive)
with imgResourceLock:
- return image.Image(self.poolPath) \
- .downloadFromStream(methodArgs, callback, sdUUID, imgUUID,
- volUUID)
+ try:
+ return image.Image(self.poolPath) \
+ .downloadFromStream(methodArgs, sdUUID, imgUUID, volUUID)
+ finally:
+ callback()
def moveMultipleImages(self, srcDomUUID, dstDomUUID, imgDict, vmUUID,
force):
--
To view, visit http://gerrit.ovirt.org/26760
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5a6e455dc3824f695fab241197ac628713f683a9
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
10 years
Change in vdsm[master]: core: imageSharing - export logic to functions
by laravot@redhat.com
Liron Ar has uploaded a new change for review.
Change subject: core: imageSharing - export logic to functions
......................................................................
core: imageSharing - export logic to functions
Most of the logic within imageSharing.streamDownloadImage() can be
exported out to be used by any operation.
The logic that was contained in this function is being exported into two
functions in this patch:
1. copyData - which can be used to copy data between two file objects.
2. ensureProcessSucceded - which is used to ensure that a process was
ended succesfully.
Change-Id: I861b40cc62c3332b887b64c2525fc512cdc6a22a
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/storage/imageSharing.py
1 file changed, 47 insertions(+), 34 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/59/26759/1
diff --git a/vdsm/storage/imageSharing.py b/vdsm/storage/imageSharing.py
index 7166293..8f150f3 100644
--- a/vdsm/storage/imageSharing.py
+++ b/vdsm/storage/imageSharing.py
@@ -19,7 +19,6 @@
import logging
import signal
-import socket
import curlImgWrap
from vdsm import constants
@@ -83,39 +82,12 @@
p = utils.execCmd(cmd, sudo=False, sync=False,
deathSignal=signal.SIGKILL)
try:
- while bytes_left > 0:
- to_read = min(BUFFER_SIZE, bytes_left)
-
- try:
- data = stream.read(to_read)
- except socket.timeout:
- log.error("socket timeout")
- raise se.MiscFileReadException()
-
- if not data:
- total_size = streamGetSize(methodArgs)
- log.error("partial data %s from %s",
- total_size - bytes_left, total_size)
- raise se.MiscFileReadException()
-
- p.stdin.write(data)
- # Process stdin is not a real file object but a wrapper using
- # StringIO buffer. To ensure that we don't use more memory if we
- # get data faster then dd read it from the pipe, we flush on every
- # write. We can remove flush() we can limit the buffer size used
- # by this stdin wrapper.
- p.stdin.flush()
- bytes_left = bytes_left - len(data)
-
- p.stdin.close()
- if not p.wait(WAIT_TIMEOUT):
- log.error("timeout waiting for dd process")
- raise se.StorageException()
-
- if p.returncode != 0:
- log.error("dd error - code %s, stderr %s",
- p.returncode, p.stderr.read(1000))
- raise se.MiscFileWriteException()
+ _copyData(stream, p.stdin, bytes_left)
+ _ensureProcessSucceded(p, constants.EXT_DD, se.StorageException)
+ except Exception:
+ if p.returncode is None:
+ p.kill()
+ raise
except Exception:
if p.returncode is None:
@@ -123,6 +95,47 @@
raise
+def _ensureProcessSucceded(p, command, failureException):
+ if not p.wait(WAIT_TIMEOUT):
+ log.error("timeout waiting for %s ", str(command))
+ raise failureException()
+
+ if p.returncode != 0:
+ log.error("%s error - code %s, stderr %s",
+ str(command), p.returncode, p.stderr.read(1000))
+ raise failureException()
+
+
+def _copyData(inBuffer, outBuffer, bytes_left):
+ total_size = bytes_left
+ while bytes_left > 0:
+ to_read = min(BUFFER_SIZE, bytes_left)
+
+ try:
+ data = inBuffer.read(to_read)
+ except Exception:
+ log.error("error while attempting to read input data")
+ raise se.MiscFileReadException()
+
+ if not data:
+ log.error("partial data %s from %s",
+ total_size - bytes_left, total_size)
+ raise se.MiscFileReadException()
+
+ try:
+ outBuffer.write(data)
+ # outBuffer may not be a real file object but a wrapper.
+ # To ensure that we don't use more memory as the input buffer size
+ # we flush on every write.
+ outBuffer.flush()
+ except Exception:
+ log.exception("Error while writing data", exc_info=True)
+ raise se.MiscFileWriteException()
+
+ bytes_left = bytes_left - len(data)
+
+ outBuffer.close()
+
_METHOD_IMPLEMENTATIONS = {
'http': (httpGetSize, httpDownloadImage, httpUploadImage),
}
--
To view, visit http://gerrit.ovirt.org/26759
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I861b40cc62c3332b887b64c2525fc512cdc6a22a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
10 years
Change in vdsm[master]: caps: Collect kdump status
by mperina@redhat.com
Martin Peřina has uploaded a new change for review.
Change subject: caps: Collect kdump status
......................................................................
caps: Collect kdump status
Adds kdump configuration status to caps module. The status will be
reported to engine in xml response of getCapabilities using boolean
key 'kdumpStatus'.
Change-Id: I68d7a2a24fdaad74255004af0f327197eaee65f2
BugUrl: https://bugzilla.redhat.com/970259
Signed-off-by: Martin Perina <mperina(a)redhat.com>
---
M vdsm/caps.py
M vdsm_api/vdsmapi-schema.json
2 files changed, 7 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/26/25926/1
diff --git a/vdsm/caps.py b/vdsm/caps.py
index b260d29..5b4c0cc 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -274,6 +274,10 @@
if os.path.exists(path)]
+def _getKdumpStatus():
+ return file('/sys/kernel/kexec_crash_loaded').read() == '1\n'
+
+
@utils.memoized
def getos():
if os.path.exists('/etc/rhev-hypervisor-release'):
@@ -386,6 +390,7 @@
config.getint('vars', 'extra_mem_reserve'))
caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')
caps['rngSources'] = _getRngSources()
+ caps['kdumpStatus'] = _getKdumpStatus()
return caps
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 1275ddb..ce71fb4 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -1032,7 +1032,8 @@
'HBAInventory': 'HbaInventory', 'vmTypes': ['VmType'],
'memSize': 'uint', 'reservedMem': 'uint',
'guestOverhead': 'uint', 'netConfigDirty': 'bool',
- 'rngSources': ['VmRngDeviceSource']}}
+ 'rngSources': ['VmRngDeviceSource'],
+ 'kdumpStatus': 'bool'}}
##
# @Host.getCapabilities:
--
To view, visit http://gerrit.ovirt.org/25926
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I68d7a2a24fdaad74255004af0f327197eaee65f2
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Peřina <mperina(a)redhat.com>
10 years
Change in vdsm[master]: [WIP] api: Define the VmJobs API
by alitke@redhat.com
Adam Litke has uploaded a new change for review.
Change subject: [WIP] api: Define the VmJobs API
......................................................................
[WIP] api: Define the VmJobs API
As part of the work being done to enable live merge usecases (deleting
snapshots while a VM is running), we need an API for ovirt-engine to
monitor the state of ongoing libvirt Block Jobs. In the future we would
also like to extend this API to support other use cases (eg. migration).
The libvirt API only reports about block jobs while they are active.
Once finished (whether successfully or in error) the job ceases to
exist. We will mirror the same behavior in vdsm to avoid issues related
to persisting information and needing to clean it later.
Here is an example of how this API would be used by ovirt-engine:
1. The user initiates the removal of a VM snapshot.
2. ovirt-engine starts a blockCommit operation using an as yet
unimplemented vdsm API.
3. ovirt-engine monitors the VmStats that are already being collected
to gather progress information on the running live merge.
4. At some point the job will stop appearing in VmStats.
5. ovirt-engine will call an as yet unimplemented API to list the volume
chain for the affected VM Disk. This information will tell
ovirt-engine whether the operation succeeded or failed.
What's missing? This API does not provide a reliable way to report
detailed error messages about the operation. This is because block jobs
disappear as soon as they succeed or fail. To solve this problem on a
best errort basis, vdsm can subscribe to libvirt events to receive block
job error messages which can be relayed to engine in the same way that
other errors are relayed. This would not be fool proof because if
libvirt or vdsm is restarted, some events may be missed. In any case,
the detailed error reporting is a separate issue that can be implemented
by another patch.
Change-Id: I92d8afc2526ba0d2fe930a4227adc2b91f87ba8a
Signed-off-by: Adam Litke <alitke(a)redhat.com>
---
M vdsm/vm.py
M vdsm_api/vdsmapi-schema.json
2 files changed, 102 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/33/24133/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 77f9683..c4220fd 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -2734,6 +2734,9 @@
stats["watchdogEvent"] = self._watchdogEvent
return stats
+ def _getVmJobs(self):
+ return []
+
def _getStatsInternal(self):
# used by API.Vm.getStats
@@ -2818,6 +2821,7 @@
stats['clientIp'] = self.conf.get('clientIp', '')
if 'pauseCode' in self.conf:
stats['pauseCode'] = self.conf['pauseCode']
+ stats['jobs'] = self._getVmJobs()
try:
stats.update(self.guestAgent.getGuestInfo())
except Exception:
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 6d8c333..037b8be 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -5589,6 +5589,100 @@
'data': {'time': 'float', 'action': 'WatchdogEventAction'}}
##
+# @VmJobState:
+#
+# An enumeration of VmJob states.
+#
+# @unknown: The state is not known
+#
+# @normal: The job is running normally
+#
+# Since: 4.14.2
+##
+{'enum': 'VmJobState', 'data': ['unknown', 'normal']}
+
+##
+# @VmJobType:
+#
+# An enumeration of VmJob Types.
+#
+# @unknown: The job type is not known
+#
+# @block: A job related to a Vm block device
+#
+# Since: 4.14.2
+##
+{'enum': 'VmJobType', 'data': ['unknown', 'block']}
+
+##
+# @BlockJobType:
+#
+# An enumeration of VM Block Job Types.
+#
+# @copy: A block rebase operation in copy mode
+#
+# @rebase: A block rebase operation
+#
+# @commit: A block commit operation
+#
+# Since: 4.14.2
+##
+{'enum': 'BlockJobType', 'data': ['copy', 'rebase', 'commit']}
+
+##
+# @VmJobInfoBlock:
+#
+# Detailed information about a block job.
+#
+# @jobType: The VmJobType (always @block)
+#
+# @opType: The specific type of operation being performed
+#
+# @bandwidth: Indicates a bandwidth limit in MB/s
+#
+# @cur: A cursor value indicating the job's current position
+#
+# @end: A cursor value indicating the the end of the job
+#
+# @imgUUID: The UUID of the image that this job is working with
+#
+# Since: 4.14.2
+##
+{'type': 'VmJobInfoBlock',
+ 'data': {'jobType': 'VmJobType', 'opType': 'BlockJobType',
+ 'bandwidth': 'uint', 'cur': 'uint', 'end': 'uint',
+ 'imgUUID': 'UUID'}}
+
+##
+# @VmJobInfo:
+#
+# A discriminated record of job type-specific metadata.
+#
+# @jobType: The type of VmJob this metadata describes
+#
+# Since: 4.14.2
+##
+{'type': 'VmJobInfo',
+ 'data': {'jobType': 'VmJobType'},
+ 'union': ['VmJobInfoBlock']}
+
+##
+# @VmJob:
+#
+# Information about an ongoing operation related to a VM.
+#
+# @state: The current state of the job. Note that as soon as jobs finish they
+# will no longer be reported. This field is designed to report any
+# conditions which may require further intervention.
+#
+# @info: Type-specific such as progress information
+#
+# Since: 4.14.2
+##
+{'type': 'VmJob',
+ 'data': {'state': 'VmJobState', 'info': 'VmJobInfo'}}
+
+##
# @RunningVmStats:
#
# Statistics for a running virtual machine.
@@ -5656,6 +5750,8 @@
# @guestFQDN: Fully qualified domain name of the guest OS. (Reported
# by the guest agent)
#
+# @jobs: #optional A list of active Vm Jobs
+#
# Since: 4.10.0
##
{'type': 'RunningVmStats',
@@ -5674,7 +5770,8 @@
'memoryStats': 'GuestMemoryStats', 'balloonInfo': 'BalloonInfo',
'disksUsage': ['GuestMountInfo'],
'netIfaces': ['GuestNetworkDeviceInfo'],
- '*watchdogEvent': 'WatchdogEvent', 'guestFQDN': 'str'}}
+ '*watchdogEvent': 'WatchdogEvent', 'guestFQDN': 'str',
+ '*jobs': ['VmJob']}}
##
# @VmStats:
--
To view, visit http://gerrit.ovirt.org/24133
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I92d8afc2526ba0d2fe930a4227adc2b91f87ba8a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke(a)redhat.com>
10 years
Change in vdsm[master]: Unknown dmidecode value is set to None which cannot be parse...
by ybronhei@redhat.com
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Unknown dmidecode value is set to None which cannot be parsed by xmlrpc
......................................................................
Unknown dmidecode value is set to None which cannot be parsed by xmlrpc
Instead of keeping key with value None if dmidecode does not return its
value, fill it with empty string.
Change-Id: I979518e1d0c0c882fe98fd5aee43c0d50ab17e14
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1089393
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M vdsm/dmidecodeUtil.py
1 file changed, 4 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/42/26942/1
diff --git a/vdsm/dmidecodeUtil.py b/vdsm/dmidecodeUtil.py
index eb8d834..6ba8dcb 100644
--- a/vdsm/dmidecodeUtil.py
+++ b/vdsm/dmidecodeUtil.py
@@ -32,7 +32,10 @@
if isinstance(v, dict):
ret.update(__leafDict(v))
else:
- ret[k] = v
+ if v is None:
+ ret[k] = ''
+ else:
+ ret[k] = v
return ret
--
To view, visit http://gerrit.ovirt.org/26942
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I979518e1d0c0c882fe98fd5aee43c0d50ab17e14
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
10 years
Change in vdsm[master]: vdsm_config: move download certificate
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: vdsm_config: move download certificate
......................................................................
vdsm_config: move download certificate
Exist a case where dhcp server may delay to deliver
the ip address and we can't download the engine certificate
from vdsm-config stage. This patch is moving the download
certificate to vdsm-reg-setup.
Change-Id: Ia2c025eedd2be92b9418ddbe01efc02c913af2a7
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M vdsm_reg/vdsm-config
M vdsm_reg/vdsm-reg-setup.in
2 files changed, 33 insertions(+), 8 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/26718/1
diff --git a/vdsm_reg/vdsm-config b/vdsm_reg/vdsm-config
index 5e4d16c..3ff81fe 100755
--- a/vdsm_reg/vdsm-config
+++ b/vdsm_reg/vdsm-config
@@ -90,22 +90,22 @@
sed --copy -i "s/\(^vdc_host_name=\)\(..*$\)/\1${vdc_managment_server}/" \
/etc/vdsm-reg/vdsm-reg.conf
- res=`python "$DEPLOY_UTIL" --node-cleanup`
- ret_val=$?
- echo "$res" >> $LOG 2>&1
- if [ ! $ret_val -eq 0 ];then
- echo "Node cleanup failed" >> $LOG 2>&1
- fi
-
if [ "$vdc_managment_server" != "$vdc_managment_port" ]; then
sed --copy -i "s/\(^vdc_host_port=\)\(..*$\)/\1${vdc_managment_port}/" \
/etc/vdsm-reg/vdsm-reg.conf
fi
- res=`python "$DEPLOY_UTIL" --download-rhevm-cert --server-address="$vdc_managment_server" --server-port="$vdc_managment_port" --fingerprint="$management_server_fingerprint"`
+ if [ "$management_server_fingerprint" != "" ]; then
+ echo "# Fingerprint of oVirt Engine CA" >> /etc/vdsm-reg/vdsm-reg.conf
+ echo "fingerprint = \"$management_server_fingerprint\"" >> /etc/vdsm-reg/vdsm-reg.conf
+ persist /etc/vdsm-reg/vdsm-reg.conf
+ fi
+
+ res=`python "$DEPLOY_UTIL" --node-cleanup`
ret_val=$?
echo "$res" >> $LOG 2>&1
if [ ! $ret_val -eq 0 ];then
+ echo "Node cleanup failed" >> $LOG 2>&1
mv "$tmp_vdsm_reg_conf" /etc/vdsm-reg/vdsm-reg.conf
echo "Rebooting ... " >> $LOG 2>&1
/sbin/reboot
diff --git a/vdsm_reg/vdsm-reg-setup.in b/vdsm_reg/vdsm-reg-setup.in
index 07963cc..d144ec9 100644
--- a/vdsm_reg/vdsm-reg-setup.in
+++ b/vdsm_reg/vdsm-reg-setup.in
@@ -24,6 +24,12 @@
import createDaemon
from deployUtil import MGT_BRIDGE_NAME
+try:
+ from ovirtnode import ovirtfunctions
+except ImportError:
+ # Continue if it's not a ovirt-node based distro
+ pass
+
TICKET_RETRIES=3
DEFAULT_CONFIG_FILE="/etc/vdsm-reg/vdsm-reg.conf"
VDSM_CONF="/etc/vdsm/vdsm.conf"
@@ -300,6 +306,25 @@
if __name__ == "__main__":
config_file = DEFAULT_CONFIG_FILE
daemonize = True
+
+ _, _, engineWebCACert = deployUtil.certPaths('')
+ config.read([config_file])
+ cfg_fingerprint = config.get('vars', 'fingerprint')
+
+ if cfg_fingerprint and not os.path.exists(engineWebCACert):
+ cfg_port = config.get('vars', 'vdc_host_port')
+ cfg_host = config.get('vars', 'vdc_host_name')
+ if deployUtil.getRhevmCert(cfg_host, cfg_port):
+ engine_fingerprint = deployUtil.generateFingerPrint(engineWebCACert)
+ if cfg_fingerprint != engine_fingerprint:
+ print "Failed: Fingerprint provided in vdsm-reg" \
+ " differs from Engine"
+ else:
+ if deployUtil.isOvirt():
+ ovirtfunctions.ovirt_store_config(engineWebCACert)
+ else:
+ print "Failed downloading the Engine certificate file"
+
try:
opts,args = getopt.getopt(sys.argv[1:], "hc:l",["help"])
for o,v in opts:
--
To view, visit http://gerrit.ovirt.org/26718
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia2c025eedd2be92b9418ddbe01efc02c913af2a7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
10 years