diff options
| author | Csaba Henk <csaba@redhat.com> | 2012-07-18 03:59:00 +0200 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2012-07-19 10:15:57 -0700 | 
| commit | de22a7760db69b82de8959d238fe444af8b387d0 (patch) | |
| tree | fc53a54971f6f5443fdf8d1b70f413ca626f4a1c | |
| parent | 9f5b8911b484230304fa52c0fcd92f696a4af74a (diff) | |
geo-rep / gsyncd: add support for sending xtimes through rsync
Note that in said mode metadata synchronization is best effort:
rsync syncs metadata at last so if rsync is interrupted in between
xattr sync and metadata sync stages, then file will be considered
in sync
Change-Id: I1c75eab33b0a1000abf3ad36b2d484a89eeda1bd
BUG: 841062
Signed-off-by: Csaba Henk <csaba@redhat.com>
Reviewed-on: http://review.gluster.com/3683
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
| -rw-r--r-- | xlators/features/marker/utils/syncdaemon/gsyncd.py | 3 | ||||
| -rw-r--r-- | xlators/features/marker/utils/syncdaemon/master.py | 28 | ||||
| -rw-r--r-- | xlators/features/marker/utils/syncdaemon/resource.py | 18 | 
3 files changed, 35 insertions, 14 deletions
diff --git a/xlators/features/marker/utils/syncdaemon/gsyncd.py b/xlators/features/marker/utils/syncdaemon/gsyncd.py index 17b10e5a..9e946946 100644 --- a/xlators/features/marker/utils/syncdaemon/gsyncd.py +++ b/xlators/features/marker/utils/syncdaemon/gsyncd.py @@ -159,6 +159,7 @@ def main_i():      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('--use-rsync-xattrs',    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') @@ -213,7 +214,7 @@ def main_i():      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, 'store_true', None) and o.get_opt_string() not in ('--version', '--help') ] -    remote_tunables = [ 'listen', 'go_daemon', 'timeout', 'session_owner', 'config_file' ] +    remote_tunables = [ 'listen', 'go_daemon', 'timeout', 'session_owner', 'config_file', 'use_rsync_xattrs' ]      rq_remote_tunables = { 'listen': True }      # precedence for sources of values: 1) commandline, 2) cfg file, 3) defaults diff --git a/xlators/features/marker/utils/syncdaemon/master.py b/xlators/features/marker/utils/syncdaemon/master.py index 945ebb75..a6aeb53d 100644 --- a/xlators/features/marker/utils/syncdaemon/master.py +++ b/xlators/features/marker/utils/syncdaemon/master.py @@ -54,12 +54,13 @@ def gmaster_builder():      """produce the GMaster class variant corresponding         to sync mode"""      this = sys.modules[__name__] -    mixin = gconf.special_sync_mode -    if not mixin: -        mixin = 'normal' -    logging.info('setting up master for %s sync mode' % mixin) -    mixin = getattr(this, mixin.capitalize() + 'Mixin') -    class _GMaster(GMasterBase, mixin): +    modemixin = gconf.special_sync_mode +    if not modemixin: +        modemixin = 'normal' +    logging.info('setting up master for %s sync mode' % modemixin) +    modemixin = getattr(this, modemixin.capitalize() + 'Mixin') +    sendmarkmixin = boolify(gconf.use_rsync_xattrs) and SendmarkNormalMixin or SendmarkRsyncMixin +    class _GMaster(GMasterBase, modemixin, sendmarkmixin):          pass      return _GMaster @@ -295,6 +296,19 @@ class BlindMixin(object):          self.slave.server.set_xtime_vec(path, xtd) +# Further mixins for certain tunable behaviors + +class SendmarkNormalMixin(object): + +    def sendmark_regular(self, *a, **kw): +        return self.sendmark(self, *a, **kw) + +class SendmarkRsyncMixin(object): + +    def sendmark_regular(self, *a, **kw): +        pass + +  class GMasterBase(object):      """abstract class impementling master role""" @@ -753,7 +767,7 @@ class GMasterBase(object):                  def regjob(e, xte, pb):                      if pb.wait():                          logging.debug("synced " + e) -                        self.sendmark(e, xte) +                        self.sendmark_regular(e, xte)                          return True                      else:                          logging.warn("failed to sync " + e) diff --git a/xlators/features/marker/utils/syncdaemon/resource.py b/xlators/features/marker/utils/syncdaemon/resource.py index 9ca226f9..47e4748d 100644 --- a/xlators/features/marker/utils/syncdaemon/resource.py +++ b/xlators/features/marker/utils/syncdaemon/resource.py @@ -19,7 +19,7 @@ import repce  from repce import RepceServer, RepceClient  from  master import gmaster_builder  import syncdutils -from syncdutils import GsyncdError, select, privileged +from syncdutils import GsyncdError, select, privileged, boolify  UrlRX  = re.compile('\A(\w+)://([^ *?[]*)\Z')  HostRX = re.compile('[a-z\d](?:[a-z\d.-]*[a-z\d])?', re.I) @@ -472,6 +472,10 @@ class SlaveLocal(object):          stop servicing if a timeout is configured and got no          keep-alime in that inteval          """ + +        if boolify(gconf.use_rsync_xattrs) and not privileged(): +            raise GsyncdError("using rsync for extended attributes is not supported") +          repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs))          t = syncdutils.Thread(target=lambda: (repce.service_loop(),                                                syncdutils.finalize())) @@ -498,12 +502,13 @@ class SlaveRemote(object):          communicate throuh its stdio.          """          slave = opts.get('slave', self.url) +        extra_opts = []          so = getattr(gconf, 'session_owner', None)          if so: -            so_args = ['--session-owner', so] -        else: -            so_args = [] -        po = Popen(rargs + gconf.remote_gsyncd.split() + so_args + \ +            extra_opts += ['--session-owner', so] +        if boolify(gconf.use_rsync_xattrs): +            extra_opts.append('--use-rsync-xattrs') +        po = Popen(rargs + gconf.remote_gsyncd.split() + extra_opts + \                     ['-N', '--listen', '--timeout', str(gconf.timeout), slave],                     stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)          gconf.transport = po @@ -532,7 +537,8 @@ class SlaveRemote(object):              raise GsyncdError("no files to sync")          logging.debug("files: " + ", ".join(files))          argv = gconf.rsync_command.split() + ['-aR', '--super', '--numeric-ids', '--no-implied-dirs'] + \ -               gconf.rsync_options.split() +  files + list(args) +               gconf.rsync_options.split() + (boolify(gconf.use_rsync_xattrs) and ['--xattrs'] or []) + \ +               files + list(args)          po = Popen(argv, stderr=subprocess.PIPE)          po.wait()          po.terminate_geterr(fail_on_err = False)  | 
