summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenky Shankar <venky@gluster.com>2011-09-13 22:11:33 +0530
committerVijay Bellur <vijay@gluster.com>2011-09-20 10:32:55 -0700
commitb30f66e20d830daec057075d67f181e904984a27 (patch)
treebd65582f16521ab909b23dd52ed4366b74b526eb
parente8b81f72d7a45ce443e72c45ae68952911deac50 (diff)
geo-rep: gsyncd: add --ignore-deletes option
When this option is set, a file deleted on master will not trigger a delete operation on the slave. Hence, the slave will remain as a superset of the master and can be used to recover the master in case of crash and/or accidental deletes. This options is not enabled by default. Change-Id: I9244d9dfa4f38f19436036f36bec0d9c3a1f7993 BUG: 3552 Reviewed-on: http://review.gluster.com/426 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Csaba Henk <csaba@gluster.com>
-rw-r--r--xlators/features/marker/utils/syncdaemon/gsyncd.py3
-rw-r--r--xlators/features/marker/utils/syncdaemon/master.py4
-rw-r--r--xlators/features/marker/utils/syncdaemon/syncdutils.py25
3 files changed, 29 insertions, 3 deletions
diff --git a/xlators/features/marker/utils/syncdaemon/gsyncd.py b/xlators/features/marker/utils/syncdaemon/gsyncd.py
index 797000970a5..9cae4d407f4 100644
--- a/xlators/features/marker/utils/syncdaemon/gsyncd.py
+++ b/xlators/features/marker/utils/syncdaemon/gsyncd.py
@@ -148,6 +148,7 @@ def main_i():
op.add_option('-p', '--pid-file', metavar='PIDF', type=str, action='callback', callback=store_abs)
op.add_option('-l', '--log-file', metavar='LOGF', type=str, action='callback', callback=store_abs)
op.add_option('--state-file', metavar='STATF', type=str, action='callback', callback=store_abs)
+ op.add_option('--ignore-deletes', default=False, action='store_true')
op.add_option('-L', '--log-level', metavar='LVL')
op.add_option('-r', '--remote-gsyncd', metavar='CMD', default=os.path.abspath(sys.argv[0]))
op.add_option('--volume-id', metavar='UUID')
@@ -188,7 +189,7 @@ def main_i():
op.add_option('--canonicalize-url', dest='url_print', action='callback', callback=store_local_curry('canon'))
op.add_option('--canonicalize-escape-url', dest='url_print', action='callback', callback=store_local_curry('canon_esc'))
- tunables = [ norm(o.get_opt_string()[2:]) for o in op.option_list if o.callback in (store_abs, None) and o.get_opt_string() not in ('--version', '--help') ]
+ tunables = [ norm(o.get_opt_string()[2:]) for o in op.option_list if o.callback in (store_abs, 'store_true', None) and o.get_opt_string() not in ('--version', '--help') ]
# precedence for sources of values: 1) commandline, 2) cfg file, 3) defaults
# -- for this to work out we need to tell apart defaults from explicitly set
diff --git a/xlators/features/marker/utils/syncdaemon/master.py b/xlators/features/marker/utils/syncdaemon/master.py
index de4b324214e..9e54dc4faf2 100644
--- a/xlators/features/marker/utils/syncdaemon/master.py
+++ b/xlators/features/marker/utils/syncdaemon/master.py
@@ -9,7 +9,7 @@ from errno import ENOENT, ENODATA
from threading import currentThread, Condition, Lock
from gconf import gconf
-from syncdutils import FreeObject, Thread, GsyncdError
+from syncdutils import FreeObject, Thread, GsyncdError, boolify
URXTIME = (-1, 0)
@@ -346,7 +346,7 @@ class GMaster(object):
self.add_failjob(path, 'remote-entries-fail')
return
dd = set(des) - set(dem)
- if dd:
+ if dd and not boolify(gconf.ignore_deletes):
self.slave.server.purge(path, dd)
chld = []
for e in dem:
diff --git a/xlators/features/marker/utils/syncdaemon/syncdutils.py b/xlators/features/marker/utils/syncdaemon/syncdutils.py
index f82f412a014..e3098d5f4ea 100644
--- a/xlators/features/marker/utils/syncdaemon/syncdutils.py
+++ b/xlators/features/marker/utils/syncdaemon/syncdutils.py
@@ -222,3 +222,28 @@ def getusername(uid = None):
if uid == None:
uid = os.geteuid()
return pwd.getpwuid(uid).pw_name
+
+def boolify(s):
+ """
+ Generic string to boolean converter
+
+ return
+ - Quick return if string 's' is of type bool
+ - True if it's in true_list
+ - False if it's in false_list
+ - Warn if it's not present in either and return False
+ """
+ true_list = ['true', 'yes', '1', 'on']
+ false_list = ['false', 'no', '0', 'off']
+
+ if isinstance(s, bool):
+ return s
+
+ rv = False
+ lstr = s.lower()
+ if lstr in true_list:
+ rv = True
+ elif not lstr in false_list:
+ logging.warn("Unknown string (%s) in string to boolean conversion defaulting to False\n" % (s))
+
+ return rv