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