Change in vdsm[master]: hsm: Add refresh device command
frolland at redhat.com
frolland at redhat.com
Sun Mar 15 15:24:36 UTC 2015
Hello Fred Rolland,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/38754
to review the following change.
Change subject: hsm: Add refresh device command
......................................................................
hsm: Add refresh device command
This command calls the multipath-resize and the returns
the device size.
multipath-resize resizes online multipath device after a LUN
was resized on the storage server.
Change-Id: I6fbeec7920a7943a9b1ea9dbd93477fa9b642f5b
Bug-Url: https://bugzilla.redhat.com/609689
Signed-off-by: Fred Rolland <frolland at redhat.com>
---
M client/vdsClient.py
M lib/vdsm/config.py.in
M lib/vdsm/constants.py.in
M vdsm/API.py
M vdsm/rpc/BindingXMLRPC.py
M vdsm/rpc/Bridge.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/storage/hsm.py
M vdsm/storage/multipath-resize
M vdsm/storage/multipath.py
M vdsm/sudoers.vdsm.in
11 files changed, 95 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/38754/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 07dbaa2..5c0d0e8 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -722,6 +722,13 @@
pp.pprint(devices['devList'])
return 0, ''
+ def refreshDevice(self, args):
+ if len(args) == 1:
+ guid = args[0]
+ size = self.s.refreshDevice(guid)
+ print '%s size= %s' % (guid, size)
+ return 0, ''
+
def getDevicesVisibility(self, args):
devList = args[0].split(',')
res = self.s.getDevicesVisibility(devList, {})
diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in
index cf8cadd..4b57c4f 100644
--- a/lib/vdsm/config.py.in
+++ b/lib/vdsm/config.py.in
@@ -251,6 +251,10 @@
('scsi_rescan_maximal_timeout', '30',
'The maximal number of seconds to wait for scsi scan to return.'),
+ ('multipath_resize_maximal_timeout', '30',
+ 'The maximal number of seconds to wait '
+ 'for multipath resize to return.'),
+
('sd_health_check_delay', '10',
'Storage domain health check delay, the amount of seconds to '
'wait between two successive run of the domain health check.'),
diff --git a/lib/vdsm/constants.py.in b/lib/vdsm/constants.py.in
index 89bdebd..02d66d8 100644
--- a/lib/vdsm/constants.py.in
+++ b/lib/vdsm/constants.py.in
@@ -164,3 +164,4 @@
EXT_CURL_IMG_WRAP = '@LIBEXECDIR@/curl-img-wrap'
EXT_FC_SCAN = '@LIBEXECDIR@/fc-scan'
+EXT_MP_RESIZE = '@LIBEXECDIR@/multipath-resize'
diff --git a/vdsm/API.py b/vdsm/API.py
index ba99911..a53d42c 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -1612,6 +1612,9 @@
def getDeviceList(self, storageType=None):
return self._irs.getDeviceList(storageType)
+ def refreshDevice(self, guid):
+ return self._irs.refreshDevice(guid)
+
def getDevicesVisibility(self, guidList):
return self._irs.getDevicesVisibility(guidList)
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index b92fbb0..1483736 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -965,6 +965,10 @@
api = API.Global()
return api.getDeviceList(storageType)
+ def refreshDevice(self, guid, options=None):
+ api = API.Global()
+ return api.refreshDevice(guid)
+
def devicesGetVisibility(self, guids, options=None):
api = API.Global()
return api.getDevicesVisibility(guids)
@@ -1119,6 +1123,7 @@
(self.stopMonitoringDomain, 'stopMonitoringDomain'),
(self.vgsGetList, 'getVGList'),
(self.devicesGetList, 'getDeviceList'),
+ (self.refreshDevice, 'refreshDevice'),
(self.devicesGetVisibility, 'getDevicesVisibility'),
(self.storageServerConnectionRefsAcquire,
'storageServer_ConnectionRefs_acquire'),
diff --git a/vdsm/rpc/Bridge.py b/vdsm/rpc/Bridge.py
index 8dc4a21..15a2b1e 100644
--- a/vdsm/rpc/Bridge.py
+++ b/vdsm/rpc/Bridge.py
@@ -401,6 +401,7 @@
'Host_getCapabilities': {'ret': Host_getCapabilities_Ret},
'Host_getConnectedStoragePools': {'ret': 'poollist'},
'Host_getDeviceList': {'ret': 'devList'},
+ 'Host_refreshDevice': {'ret': 'size'},
'Host_getDevicesVisibility': {'ret': 'visible'},
'Host_getExternalVMs': {'ret': 'vmList'},
'Host_getHardwareInfo': {'ret': 'info'},
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 47440a4..fe37fb5 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -1476,6 +1476,34 @@
'returns': ['BlockDeviceInfo']}
##
+# @DeviceSize:
+#
+# Device size.
+#
+# @size: Device size.
+#
+# Since: 4.16.8
+##
+{'type': 'DeviceSize',
+ 'data': {'size': 'str'}}
+
+##
+# @Host.refreshDevice:
+#
+# Refresh multipath device and return the size after refresh.
+#
+# @guid: A block device GUID
+#
+# Returns:
+# Device size
+#
+# Since: 4.10.0
+##
+{'command': {'class': 'Host', 'name': 'refreshDevice'},
+ 'data': {'guid': ['UUID']},
+ 'returns': 'DeviceSize'}
+
+##
# @DeviceVisibilityMap:
#
# A mapping of boolean values indexed by block device GUID.
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index c0ac3a1..d7b7e74 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -734,6 +734,24 @@
return dict(size=str(roundedSizeBytes))
@public
+ def refreshDevice(self, guid, options=None):
+ """
+ Call multipath-resize with specified device guid
+
+ :param guid: Device UUID to refresh size.
+ :type guid: UUID
+ :param options: ?
+ :returns: dictionary of size and respective size in bytes
+ :rtype: dict
+ """
+ multipath.resize(guid)
+
+ st = os.stat("/dev/mapper/%s" % guid)
+ minor = os.minor(st.st_rdev)
+ devicesize = multipath.getDeviceSize("dm-%d" % minor)
+ return dict(size=devicesize)
+
+ @public
def extendStorageDomain(self, sdUUID, spUUID, guids,
force=False, options=None):
"""
diff --git a/vdsm/storage/multipath-resize b/vdsm/storage/multipath-resize
index 90a6d15..72086dd 100755
--- a/vdsm/storage/multipath-resize
+++ b/vdsm/storage/multipath-resize
@@ -55,7 +55,6 @@
import logging
import os
-import subprocess
import sys
from vdsm import concurrent
diff --git a/vdsm/storage/multipath.py b/vdsm/storage/multipath.py
index f12f798..6dbba9c 100644
--- a/vdsm/storage/multipath.py
+++ b/vdsm/storage/multipath.py
@@ -28,6 +28,8 @@
import logging
import re
from collections import namedtuple
+from vdsm.config import config
+from vdsm.infra import zombiereaper
from vdsm import constants
from vdsm import utils
@@ -305,3 +307,27 @@
def devIsFCP(type):
return type in [DEV_FCP, DEV_MIXED]
+
+
+def resize(uuid):
+ """
+ Calls script multipath-resize
+ """
+ timeout = config.getint('irs', 'multipath_resize_maximal_timeout')
+
+ proc = utils.execCmd([constants.EXT_MP_RESIZE], sync=False,
+ execCmdLogger=log, sudo=True)
+ try:
+ proc.wait(timeout)
+ finally:
+ if proc.returncode is None:
+ zombiereaper.autoReapPID(proc.pid)
+ raise Error("Timeout scanning (pid=%s)" % proc.pid)
+ elif proc.returncode != 0:
+ stderr = proc.stderr.read(512)
+ raise Error("Scan failed: %r" % stderr)
+ return ""
+
+
+class Error(Exception):
+ """ multipath operation failed """
diff --git a/vdsm/sudoers.vdsm.in b/vdsm/sudoers.vdsm.in
index da88ff2..716d153 100644
--- a/vdsm/sudoers.vdsm.in
+++ b/vdsm/sudoers.vdsm.in
@@ -27,7 +27,8 @@
@MULTIPATH_PATH@, \
@SETSID_PATH@ @IONICE_PATH@ -c ? -n ? @SU_PATH@ vdsm -s /bin/sh -c /usr/libexec/vdsm/spmprotect.sh*, \
@SERVICE_PATH@ vdsmd *, \
- @REBOOT_PATH@ -f
+ @REBOOT_PATH@ -f, \
+ @LIBEXECDIR@/multipath-resize
vdsm ALL=(ALL) NOPASSWD: VDSM_LIFECYCLE, VDSM_STORAGE
Defaults:vdsm !requiretty
--
To view, visit https://gerrit.ovirt.org/38754
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6fbeec7920a7943a9b1ea9dbd93477fa9b642f5b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Freddy Rolland <frolland at redhat.com>
Gerrit-Reviewer: Fred Rolland <frolland at redhat.com>
More information about the vdsm-patches
mailing list