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