Change in vdsm[master]: gluster: adds a verb to check if a gluster volume is empty

dnarayan at redhat.com dnarayan at redhat.com
Tue Mar 31 12:43:04 UTC 2015


Darshan N has uploaded a new change for review.

Change subject: gluster: adds a verb to check if a gluster volume is empty
......................................................................

gluster: adds a verb to check if a gluster volume is empty

This patch adds a verb isVolumeEmpty which checks if a
gluster volume is empty or not. This verb takes gluster
volume name as an argument and returns a flag
isVolumeEmpty. This check is needed during geo-replication
create, as it is recomemded to have the remote volume
to be empty. So while creating a geo-rep session engine
has to check if slave volume is empty.

Change-Id: I278d326faad6798e6e3404a94813d6145b1d8c4b
Signed-off-by: Darshan N <dnarayan at redhat.com>
---
M client/vdsClientGluster.py
M vdsm/gluster/api.py
M vdsm/gluster/apiwrapper.py
M vdsm/gluster/exception.py
M vdsm/rpc/vdsmapi-gluster-schema.json
5 files changed, 130 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/93/39393/1

diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index b7aac8c..d67bc47 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -749,6 +749,15 @@
         pp.pprint(status)
         return status['status']['code'], status['status']['message']
 
+    def do_glusterIsVolumeEmpty(self, args):
+        params = self._eqSplit(args)
+        volumeName = params.get('volumeName', '')
+
+        status = self.s.glusterIsVolumeEmpty(volumeName)
+
+        pp.pprint(status)
+        return status['status']['code'], status['status']['message']
+
 
 def getGlusterCmdDict(serv):
     return \
@@ -1274,5 +1283,10 @@
               '<slave_host_name>is remote slave host name or ip\n\t'
               '<slave_volume_name>existing volume name in the slave node',
               'Delete the geo-replication session'
+              )),
+         'glusterIsVolumeEmpty': (
+             serv.do_glusterIsVolumeEmpty,
+             ('volumeName=<volume name>',
+              'Check if the given volume is empty or not'
               ))
          }
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 6a9f53e..8926225 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -20,14 +20,18 @@
 
 import errno
 import os
+import tempfile
 from functools import wraps
 from vdsm.define import doneCode
 from pwd import getpwnam
+from vdsm import utils
 
+import storage.mount
 import supervdsm as svdsm
 import exception as ge
 from . import makePublic
 from . import safeWrite
+from . import cli
 
 _SUCCESS = {'status': doneCode}
 GEOREP_PUB_KEY_PATH = "/var/lib/glusterd/geo-replication/common_secret.pem.pub"
@@ -68,6 +72,63 @@
 
     wrapper.exportAsVerb = True
     return wrapper
+
+
+def _removeMountPoint(path):
+    try:
+        os.rmdir(path)
+    except OSError:
+        msg = "Failed to remove glusterfs mount dir - %s" % path
+        raise ge.GlusterMountDirRemoveFailedException(err=[msg])
+
+
+ at makePublic
+def isVolumeEmpty(volumeName, volumeServer="localhost"):
+    volume_data = cli.volumeInfo(volumeName=volumeName,
+                                 remoteServer=volumeServer)
+    if volumeName not in volume_data:
+        msg = "Volume \"%s\" does not exists" % volumeName
+        raise ge.GlusterVolumeNameErrorException(err=[msg])
+
+    if volume_data[volumeName]['volumeStatus'] == cli.VolumeStatus.OFFLINE:
+        msg = "Volume \"%s\" is not Online" % volumeName
+        raise ge.GlusterVolumeIsNotOnlineException(err=[msg])
+
+    mountPoint = tempfile.mkdtemp(prefix="vdsm_gluster_")
+    fs = "%s:/%s" % (volumeServer, volumeName)
+    glusterfsMount = storage.mount.Mount(fs, mountPoint)
+    try:
+        glusterfsMount.mount(mntOpts='ro', vfstype="glusterfs")
+    except storage.mount.MountError:
+        _removeMountPoint(mountPoint)
+        errMsg = "Failed to mount glusterfs volume %s" % volumeName
+        raise ge.GlusterVolumeEmptyCheckFailedException(err=[errMsg])
+
+    if glusterfsMount.isMounted():
+        rc, out, err = utils.execCmd(['find', mountPoint,
+                                      '-maxdepth', '1', '-path',
+                                      mountPoint + "/.trashcan", '-prune',
+                                      '-o', '-path', mountPoint,
+                                      '-o', '-print0', '-quit'])
+        if rc:
+            raise ge.GlusterVolumeEmptyCheckFailedException(rc, out, err)
+    else:
+        _removeMountPoint(mountPoint)
+        errMsg = "Failed to mount glusterfs volume %s" % volumeName
+        raise ge.GlusterVolumeEmptyCheckFailedException(err=[errMsg])
+
+    try:
+        glusterfsMount.umount(lazy=True)
+    except storage.mount.MountError:
+        errMsg = "Failed to unmount temp glusterfs mount - %s" % mountPoint
+        raise ge.GlusterVolumeUnmountFailedException(err=[errMsg])
+
+    _removeMountPoint(mountPoint)
+
+    if out:
+        return False
+    else:
+        return True
 
 
 @makePublic
@@ -640,6 +701,10 @@
             remoteUserName
         )
 
+    @exportAsVerb
+    def isVolumeEmpty(self, volumeName, options=None):
+        status = self.svdsmProxy.glusterIsVolumeEmpty(volumeName)
+        return {'isVolumeEmpty': status}
 
 def getGlusterMethods(gluster):
     l = []
diff --git a/vdsm/gluster/apiwrapper.py b/vdsm/gluster/apiwrapper.py
index 37b7588..d6f2974 100644
--- a/vdsm/gluster/apiwrapper.py
+++ b/vdsm/gluster/apiwrapper.py
@@ -306,6 +306,9 @@
             remoteUserName
         )
 
+    def isVolumeEmpty(self, volumeName):
+        return self._gluster.isVolumeEmpty(volumeName)
+
 
 class GlusterSnapshot(GlusterApiBase):
     def __init__(self):
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index 339fe92..9c94aae 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -576,6 +576,26 @@
     message = "glfs fini failed"
 
 
+class GlusterVolumeIsNotOnlineException(GlusterVolumeException):
+    code = 4574
+    message = "Failed to get Gluster volume stats"
+
+
+class GlusterMountDirRemoveFailedException(GlusterVolumeException):
+    code = 4575
+    message = "Failed to remove temp mount directory"
+
+
+class GlusterVolumeEmptyCheckFailedException(GlusterVolumeException):
+    code = 4576
+    message = "Failed to Check if gluster volume is empty"
+
+
+class GlusterVolumeUnmountFailedException(GlusterVolumeException):
+    code = 4577
+    message = "Failed to Unmount temporary glusterfs mount"
+
+
 # geo-replication
 class GlusterGeoRepException(GlusterException):
     code = 4200
diff --git a/vdsm/rpc/vdsmapi-gluster-schema.json b/vdsm/rpc/vdsmapi-gluster-schema.json
index 97ad3bf..6b8e807 100644
--- a/vdsm/rpc/vdsmapi-gluster-schema.json
+++ b/vdsm/rpc/vdsmapi-gluster-schema.json
@@ -2117,3 +2117,31 @@
 {'command': {'class': 'GlusterVolume', 'name': 'geoRepMountBrokerSetup'},
  'data': {'remoteUserName': 'str', 'remoteGroupName': 'str',
           'remoteVolumeName': 'str'}}
+
+##
+# @IsVolumeEmpty:
+#
+# Flag which tells if a given volume is empty
+#
+# @geoRepPubKeys: A flag which tells if a gluster volume is empty
+#
+# Since: 4.17.0
+##
+{'type': 'IsVolumeEmpty',
+ 'data': {'isVolumeEmpty': 'bool'}}
+
+##
+# @GlusterVolume.isVolumeEmpty:
+#
+# check if a gluster volume is empty
+#
+# @volumeName: Gluster volume name
+#
+# Returns:
+# success/failure
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'GlusterVolume', 'name': 'isVolumeEmpty'},
+ 'data': {'volumeName': 'str'},
+ 'returns': 'IsVolumeEmpty'}


-- 
To view, visit https://gerrit.ovirt.org/39393
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I278d326faad6798e6e3404a94813d6145b1d8c4b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Darshan N <dnarayan at redhat.com>


More information about the vdsm-patches mailing list