/[rdiff-backup]/rdiff-backup/rdiff_backup/backup.py
ViewVC logotype

Diff of /rdiff-backup/rdiff_backup/backup.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.35 by bescoto, Sat Nov 5 02:54:03 2005 UTC revision 1.36 by bescoto, Wed Nov 23 23:16:32 2005 UTC
# Line 23  from __future__ import generators Line 23  from __future__ import generators
23  import errno  import errno
24  import Globals, metadata, rorpiter, TempFile, Hardlink, robust, increment, \  import Globals, metadata, rorpiter, TempFile, Hardlink, robust, increment, \
25             rpath, static, log, selection, Time, Rdiff, statistics, iterfile, \             rpath, static, log, selection, Time, Rdiff, statistics, iterfile, \
26             hash             hash, longname
27    
28  def Mirror(src_rpath, dest_rpath):  def Mirror(src_rpath, dest_rpath):
29          """Turn dest_rpath into a copy of src_rpath"""          """Turn dest_rpath into a copy of src_rpath"""
# Line 189  class DestinationStruct: Line 189  class DestinationStruct:
189                  elif dest_rorp:                  elif dest_rorp:
190                          dest_sig = dest_rorp.getRORPath()                          dest_sig = dest_rorp.getRORPath()
191                          if dest_rorp.isreg():                          if dest_rorp.isreg():
192                                  sig_fp = cls.get_one_sig_fp(dest_base_rpath.new_index(index))                                  dest_rp = longname.get_mirror_rp(dest_base_rpath, dest_rorp)
193                                    sig_fp = cls.get_one_sig_fp(dest_rp)
194                                  if sig_fp is None: return None                                  if sig_fp is None: return None
195                                  dest_sig.setfile(sig_fp)                                  dest_sig.setfile(sig_fp)
196                  else: dest_sig = rpath.RORPath(index)                  else: dest_sig = rpath.RORPath(index)
197                  return dest_sig                                  return dest_sig
198    
199          def get_one_sig_fp(cls, dest_rp):          def get_one_sig_fp(cls, dest_rp):
200                  """Return a signature fp of given index, corresponding to reg file"""                  """Return a signature fp of given index, corresponding to reg file"""
# Line 467  class PatchITRB(rorpiter.ITRBranch): Line 468  class PatchITRB(rorpiter.ITRBranch):
468                  self.statfileobj = (statistics.get_active_statfileobj() or                  self.statfileobj = (statistics.get_active_statfileobj() or
469                                                          statistics.StatFileObj())                                                          statistics.StatFileObj())
470                  self.dir_replacement, self.dir_update = None, None                  self.dir_replacement, self.dir_update = None, None
                 self.cached_rp = None  
471                  self.CCPP = CCPP                  self.CCPP = CCPP
472                  self.error_handler = robust.get_error_handler("UpdateError")                  self.error_handler = robust.get_error_handler("UpdateError")
473    
         def get_rp_from_root(self, index):  
                 """Return RPath by adding index to self.basis_root_rp"""  
                 if not self.cached_rp or self.cached_rp.index != index:  
                         self.cached_rp = self.basis_root_rp.new_index(index)  
                 return self.cached_rp  
   
         def check_long_name(self, func, *args):  
                 """Execute function, checking for ENAMETOOLONG error"""  
                 try: result = func(*args)  
                 except OSError, exc:  
                         if (errno.errorcode.has_key(exc[0]) and  
                                 errno.errorcode[exc[0]] == 'ENAMETOOLONG'):  
                                 self.error_handler(exc, args[0])  
                                 return None  
                         else: raise  
                 return result  
   
474          def can_fast_process(self, index, diff_rorp):          def can_fast_process(self, index, diff_rorp):
475                  """True if diff_rorp and mirror are not directories"""                  """True if diff_rorp and mirror are not directories"""
476                  rp = self.check_long_name(self.get_rp_from_root, index)                  mirror_rorp = self.CCPP.get_mirror_rorp(index)
477                  # filename too long error qualifies (hack)                  return not (diff_rorp.isdir() or (mirror_rorp and mirror_rorp.isdir()))
                 return not rp or (not diff_rorp.isdir() and not rp.isdir())  
478    
479          def fast_process(self, index, diff_rorp):          def fast_process(self, index, diff_rorp):
480                  """Patch base_rp with diff_rorp (case where neither is directory)"""                  """Patch base_rp with diff_rorp (case where neither is directory)"""
481                  rp = self.check_long_name(self.get_rp_from_root, index)                  mirror_rp, discard = longname.get_mirror_inc_rps(
482                  if not rp: return                          self.CCPP.get_rorps(index), self.basis_root_rp)
483                  tf = TempFile.new(rp)                  assert not mirror_rp.isdir(), mirror_rp
484                  if self.patch_to_temp(rp, diff_rorp, tf):                  tf = TempFile.new(mirror_rp)
485                    if self.patch_to_temp(mirror_rp, diff_rorp, tf):
486                          if tf.lstat():                          if tf.lstat():
487                                  rpath.rename(tf, rp)                                  rpath.rename(tf, mirror_rp)
488                                  self.CCPP.flag_success(index)                                  self.CCPP.flag_success(index)
489                          elif rp.lstat():                          elif mirror_rp and mirror_rp.lstat():
490                                  rp.delete()                                  mirror_rp.delete()
491                                  self.CCPP.flag_deleted(index)                                  self.CCPP.flag_deleted(index)
492                  else:                  else:
493                          tf.setdata()                          tf.setdata()
# Line 583  class PatchITRB(rorpiter.ITRBranch): Line 566  class PatchITRB(rorpiter.ITRBranch):
566    
567          def start_process(self, index, diff_rorp):          def start_process(self, index, diff_rorp):
568                  """Start processing directory - record information for later"""                  """Start processing directory - record information for later"""
569                  base_rp = self.base_rp = self.get_rp_from_root(index)                  self.base_rp, discard = longname.get_mirror_inc_rps(
570                  assert diff_rorp.isdir() or base_rp.isdir() or not base_rp.index                          self.CCPP.get_rorps(index), self.basis_root_rp)
571                  if diff_rorp.isdir(): self.prepare_dir(diff_rorp, base_rp)                  if diff_rorp.isdir(): self.prepare_dir(diff_rorp, self.base_rp)
572                  elif self.set_dir_replacement(diff_rorp, base_rp):                  elif self.set_dir_replacement(diff_rorp, self.base_rp):
573                          self.CCPP.flag_success(index)                          if diff_rorp.lstat(): self.CCPP.flag_success(index)
574                            else: self.CCPP.flag_deleted(index)
575    
576          def set_dir_replacement(self, diff_rorp, base_rp):          def set_dir_replacement(self, diff_rorp, base_rp):
577                  """Set self.dir_replacement, which holds data until done with dir                  """Set self.dir_replacement, which holds data until done with dir
# Line 607  class PatchITRB(rorpiter.ITRBranch): Line 591  class PatchITRB(rorpiter.ITRBranch):
591                  else: return 1                  else: return 1
592    
593          def prepare_dir(self, diff_rorp, base_rp):          def prepare_dir(self, diff_rorp, base_rp):
594                  """Prepare base_rp to turn into a directory"""                  """Prepare base_rp to be a directory"""
595                  self.dir_update = diff_rorp.getRORPath() # make copy in case changes                  self.dir_update = diff_rorp.getRORPath() # make copy in case changes
596                  if not base_rp.isdir():                  if not base_rp.isdir():
597                          if base_rp.lstat(): base_rp.delete()                          if base_rp.lstat(): self.base_rp.delete()
598                            base_rp.setdata()
599                          base_rp.mkdir()                          base_rp.mkdir()
600                          self.CCPP.flag_success(diff_rorp.index)                          self.CCPP.flag_success(diff_rorp.index)
601                  else: # maybe no change, so query CCPP before tagging success                  else: # maybe no change, so query CCPP before tagging success
# Line 622  class PatchITRB(rorpiter.ITRBranch): Line 607  class PatchITRB(rorpiter.ITRBranch):
607                  if self.dir_update:                  if self.dir_update:
608                          assert self.base_rp.isdir()                          assert self.base_rp.isdir()
609                          rpath.copy_attribs(self.dir_update, self.base_rp)                          rpath.copy_attribs(self.dir_update, self.base_rp)
610                  else:                  elif self.dir_replacement:
                         assert self.dir_replacement  
611                          self.base_rp.rmdir()                          self.base_rp.rmdir()
612                          if self.dir_replacement.lstat():                          if self.dir_replacement.lstat():
613                                  rpath.rename(self.dir_replacement, self.base_rp)                                  rpath.rename(self.dir_replacement, self.base_rp)
# Line 637  class IncrementITRB(PatchITRB): Line 621  class IncrementITRB(PatchITRB):
621          """          """
622          def __init__(self, basis_root_rp, inc_root_rp, rorp_cache):          def __init__(self, basis_root_rp, inc_root_rp, rorp_cache):
623                  self.inc_root_rp = inc_root_rp                  self.inc_root_rp = inc_root_rp
                 self.cached_incrp = None  
624                  PatchITRB.__init__(self, basis_root_rp, rorp_cache)                  PatchITRB.__init__(self, basis_root_rp, rorp_cache)
625    
         def get_incrp(self, index):  
                 """Return inc RPath by adding index to self.basis_root_rp"""  
                 if not self.cached_incrp or self.cached_incrp.index != index:  
                         self.cached_incrp = self.inc_root_rp.new_index(index)  
                 return self.cached_incrp  
   
626          def fast_process(self, index, diff_rorp):          def fast_process(self, index, diff_rorp):
627                  """Patch base_rp with diff_rorp and write increment (neither is dir)"""                  """Patch base_rp with diff_rorp and write increment (neither is dir)"""
628                  rp = self.check_long_name(self.get_rp_from_root, index)                  mirror_rp, inc_prefix = longname.get_mirror_inc_rps(
629                  if not rp: return                          self.CCPP.get_rorps(index), self.basis_root_rp, self.inc_root_rp)
630                  tf = TempFile.new(rp)                  tf = TempFile.new(mirror_rp)
631                  if self.patch_to_temp(rp, diff_rorp, tf):                  if self.patch_to_temp(mirror_rp, diff_rorp, tf):
632                          inc = self.check_long_name(increment.Increment,                          inc = increment.Increment(tf, mirror_rp, inc_prefix)
                                                                            tf, rp, self.get_incrp(index))  
633                          if inc is not None:                          if inc is not None:
634                                  self.CCPP.set_inc(index, inc)                                  self.CCPP.set_inc(index, inc)
635                                  if inc.isreg():                                  if inc.isreg():
636                                          inc.fsync_with_dir() # Write inc before rp changed                                          inc.fsync_with_dir() # Write inc before rp changed
637                                  if tf.lstat():                                  if tf.lstat():
638                                          rpath.rename(tf, rp)                                          rpath.rename(tf, mirror_rp)
639                                          self.CCPP.flag_success(index)                                          self.CCPP.flag_success(index)
640                                  elif rp.lstat():                                  elif mirror_rp.lstat():
641                                          rp.delete()                                          mirror_rp.delete()
642                                          self.CCPP.flag_deleted(index)                                          self.CCPP.flag_deleted(index)
643                                  return # normal return, otherwise error occurred                                  return # normal return, otherwise error occurred
644                  tf.setdata()                  tf.setdata()
# Line 670  class IncrementITRB(PatchITRB): Line 646  class IncrementITRB(PatchITRB):
646    
647          def start_process(self, index, diff_rorp):          def start_process(self, index, diff_rorp):
648                  """Start processing directory"""                  """Start processing directory"""
649                  base_rp = self.base_rp = self.get_rp_from_root(index)                  self.base_rp, inc_prefix = longname.get_mirror_inc_rps(
650                  assert diff_rorp.isdir() or base_rp.isdir()                          self.CCPP.get_rorps(index), self.basis_root_rp, self.inc_root_rp)
651                    self.base_rp.setdata()
652                    assert diff_rorp.isdir() or self.base_rp.isdir()
653                  if diff_rorp.isdir():                  if diff_rorp.isdir():
654                          inc = self.check_long_name(increment.Increment,                          inc = increment.Increment(diff_rorp, self.base_rp, inc_prefix)
                                                                  diff_rorp, base_rp, self.get_incrp(index))  
655                          if inc and inc.isreg():                          if inc and inc.isreg():
656                                  inc.fsync_with_dir() # must write inc before rp changed                                  inc.fsync_with_dir() # must write inc before rp changed
657                          self.prepare_dir(diff_rorp, base_rp)                          self.base_rp.setdata() # in case written by increment above
658                  elif self.set_dir_replacement(diff_rorp, base_rp):                          self.prepare_dir(diff_rorp, self.base_rp)
659                          inc = self.check_long_name(increment.Increment,                  elif self.set_dir_replacement(diff_rorp, self.base_rp):
660                                                  self.dir_replacement, base_rp, self.get_incrp(index))                          inc = increment.Increment(self.dir_replacement, self.base_rp,
661                                                                              inc_prefix)
662                          if inc:                          if inc:
663                                  self.CCPP.set_inc(index, inc)                                  self.CCPP.set_inc(index, inc)
664                                  self.CCPP.flag_success(index)                                  self.CCPP.flag_success(index)

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.36

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26