diff options
author | Venky Shankar <venky@gluster.com> | 2011-09-13 22:11:33 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-09-20 10:32:55 -0700 |
commit | b30f66e20d830daec057075d67f181e904984a27 (patch) | |
tree | bd65582f16521ab909b23dd52ed4366b74b526eb | |
parent | e8b81f72d7a45ce443e72c45ae68952911deac50 (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.py | 3 | ||||
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/master.py | 4 | ||||
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/syncdutils.py | 25 |
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 |