예제 #1
0
    def _restore_orig_regfile(self, rf):
        """Restore original regular file

        This is the trickiest case for avoiding information loss,
        because we don't want to delete the increment before the
        mirror is fully written.

        """
        assert rf.metadata_rorp.isreg(), (
            "Metadata path '{mp}' can only be regular file.".format(
                mp=rf.metadata_rorp))
        if rf.mirror_rp.isreg():
            tf = rf.mirror_rp.get_temp_rpath(sibling=True)
            tf.write_from_fileobj(rf.get_restore_fp())
            tf.fsync_with_dir()  # make sure tf fully written before move
            rpath.copy_attribs(rf.metadata_rorp, tf)
            rpath.rename(tf, rf.mirror_rp)  # move is atomic
        else:
            if rf.mirror_rp.lstat():
                rf.mirror_rp.delete()
            rf.mirror_rp.write_from_fileobj(rf.get_restore_fp())
            rpath.copy_attribs(rf.metadata_rorp, rf.mirror_rp)
        if Globals.fsync_directories:
            rf.mirror_rp.get_parent_rp().fsync(
            )  # force move before inc delete
예제 #2
0
 def end_process_directory(self):
     """Finish processing a directory"""
     rf = self.rf
     if rf.metadata_rorp.isdir():
         if rf.mirror_rp.isdir():
             rf.mirror_rp.setdata()
             if not rf.metadata_rorp.equal_loose(rf.mirror_rp):
                 log.Log("Regressing attributes of path {pa}".format(pa=rf),
                         log.INFO)
                 rpath.copy_attribs(rf.metadata_rorp, rf.mirror_rp)
         else:
             rf.mirror_rp.delete()
             log.Log("Regressing file {fi}".format(fi=rf.mirror_rp),
                     log.INFO)
             rpath.copy_with_attribs(rf.metadata_rorp, rf.mirror_rp)
     else:  # replacing a dir with some other kind of file
         assert rf.mirror_rp.isdir(), (
             "Mirror '{mrp!r}' can only be a directory.".format(
                 mrp=rf.mirror_rp))
         log.Log("Replacing directory {di}".format(di=rf), log.INFO)
         if rf.metadata_rorp.isreg():
             self._restore_orig_regfile(rf)
         else:
             rf.mirror_rp.delete()
             rpath.copy_with_attribs(rf.metadata_rorp, rf.mirror_rp)
     if rf.regress_inc:
         log.Log("Deleting increment {ic}".format(ic=rf), log.INFO)
         rf.regress_inc.delete()
예제 #3
0
 def testCopyAttribs(self):
     """Test copying attributes"""
     t = RPath(self.lc, self.mainprefix, ("testattribs",))
     if t.lstat():
         t.delete()
     for rp in [self.noperms, self.nowrite, self.rf, self.exec1, self.exec2, self.hl1, self.dir]:
         copy(rp, t)
         rpath.copy_attribs(rp, t)
         # assert rpath.cmp_attribs(t, rp), \
         assert t.equal_loose(rp), "Attributes for file %s not copied successfully" % rp.path
         t.delete()
예제 #4
0
	def testCopyAttribs(self):
		"""Test copying attributes"""
		t = RPath(self.lc, self.mainprefix, ("testattribs",))
		if t.lstat(): t.delete()
		for rp in [self.noperms, self.nowrite, self.rf, self.exec1,
				   self.exec2, self.hl1, self.dir]:
			copy(rp, t)
			rpath.copy_attribs(rp, t)
			#assert rpath.cmp_attribs(t, rp), \
			assert t.equal_loose(rp), \
				   "Attributes for file %s not copied successfully" % rp.path
			t.delete()
예제 #5
0
 def testCopyAttribs(self):
     """Test copying attributes"""
     t = rpath.RPath(self.lc, self.write_dir, ("testattribs", ))
     if t.lstat():
         t.delete()
     for rp in [
             self.noperms, self.nowrite, self.rf, self.exec1, self.exec2,
             self.hl1, self.dir
     ]:
         rpath.copy(rp, t)
         rpath.copy_attribs(rp, t)
         self.assertTrue(t.equal_loose(rp))
         t.delete()
예제 #6
0
 def end_process_directory(self):
     """Finish processing directory"""
     if self.dir_update:
         assert self.base_rp.isdir(), (
             "Base path '{brp}' must be a directory.".format(
                 brp=self.base_rp))
         rpath.copy_attribs(self.dir_update, self.base_rp)
     else:
         assert self.dir_replacement, (
             "Replacement directory must be defined.")
         self.base_rp.rmdir()
         if self.dir_replacement.lstat():
             rpath.rename(self.dir_replacement, self.base_rp)
예제 #7
0
 def _patch_to_temp(self, basis_rp, diff_rorp, new):
     """Patch basis_rp, writing output in new, which doesn't exist yet"""
     if diff_rorp.isflaglinked():
         map_hardlinks.link_rp(diff_rorp, new, self.basis_root_rp)
         return
     if diff_rorp.get_attached_filetype() == 'snapshot':
         copy_report = rpath.copy(diff_rorp, new)
     else:
         assert diff_rorp.get_attached_filetype() == 'diff', (
             "File '{drp}' must be of type '{dtype}'.".format(
                 drp=diff_rorp, dtype='diff'))
         copy_report = Rdiff.patch_local(basis_rp, diff_rorp, new)
     self._check_hash(copy_report, diff_rorp)
     if new.lstat():
         rpath.copy_attribs(diff_rorp, new)
예제 #8
0
def InternalMirror(source_local, dest_local, src_dir, dest_dir, force=False):
    """
    Mirror src to dest internally

    like InternalBackup, but only mirror.  Do this through
    InternalBackup, but then delete rdiff-backup-data directory.
    """
    # Save attributes of root to restore later
    src_root = rpath.RPath(Globals.local_connection, src_dir)
    dest_root = rpath.RPath(Globals.local_connection, dest_dir)
    dest_rbdir = dest_root.append("rdiff-backup-data")

    InternalBackup(source_local, dest_local, src_dir, dest_dir, force=force)
    dest_root.setdata()
    Myrm(dest_rbdir.path)
    # Restore old attributes
    rpath.copy_attribs(src_root, dest_root)
예제 #9
0
def InternalMirror(source_local, dest_local, src_dir, dest_dir):
	"""Mirror src to dest internally

	like InternalBackup, but only mirror.  Do this through
	InternalBackup, but then delete rdiff-backup-data directory.

	"""
	# Save attributes of root to restore later
	src_root = rpath.RPath(Globals.local_connection, src_dir)
	dest_root = rpath.RPath(Globals.local_connection, dest_dir)
	dest_rbdir = dest_root.append("rdiff-backup-data")

	InternalBackup(source_local, dest_local, src_dir, dest_dir)
	dest_root.setdata()
	Myrm(dest_rbdir.path)
	# Restore old attributes
	rpath.copy_attribs(src_root, dest_root)
예제 #10
0
    def end_process_directory(self):
        """Finish processing directory"""
        if self.dir_update:
            assert self.base_rp.isdir(), (
                "Base directory '{rp}' isn't a directory.".format(
                    rp=self.base_rp))
            rpath.copy_attribs(self.dir_update, self.base_rp)

            if (Globals.process_uid != 0
                    and self.dir_update.getperms() % 0o1000 < 0o700):
                # Directory was unreadable at start -- keep it readable
                # until the end of the backup process.
                self.base_rp.chmod(0o700 | self.dir_update.getperms())
        elif self.dir_replacement:
            self.base_rp.rmdir()
            if self.dir_replacement.lstat():
                rpath.rename(self.dir_replacement, self.base_rp)
예제 #11
0
    def _patch_snapshot_to_temp(self, diff_rorp, new):
        """Write diff_rorp to new, return true if successful

        Returns 1 if normal success, 2 if special file is written,
        whether or not it is successful.  This is because special
        files either fail with a SpecialFileError, or don't need to be
        compared.

        """
        if diff_rorp.isspecial():
            self._write_special(diff_rorp, new)
            rpath.copy_attribs(diff_rorp, new)
            return 2

        report = robust.check_common_error(self.error_handler, rpath.copy,
                                           (diff_rorp, new))
        if isinstance(report, hash.Report):
            self.CCPP.update_hash(diff_rorp.index, report.sha1_digest)
            return 1
        return report != 0  # if == 0, error_handler caught something
예제 #12
0
    def _patch_to_temp(self, basis_rp, diff_rorp, new):
        """Patch basis_rp, writing output in new, which doesn't exist yet

        Returns true if able to write new as desired, false if
        UpdateError or similar gets in the way.

        """
        if diff_rorp.isflaglinked():
            self._patch_hardlink_to_temp(diff_rorp, new)
        elif diff_rorp.get_attached_filetype() == 'snapshot':
            result = self._patch_snapshot_to_temp(diff_rorp, new)
            if not result:
                return 0
            elif result == 2:
                return 1  # SpecialFile
        elif not self._patch_diff_to_temp(basis_rp, diff_rorp, new):
            return 0
        if new.lstat():
            if diff_rorp.isflaglinked():
                if Globals.eas_write:
                    """ `isflaglinked() == True` implies that we are processing
                    the 2nd (or later) file in a group of files linked to an
                    inode.  As such, we don't need to perform the usual
                    `copy_attribs(diff_rorp, new)` for the inode because that
                    was already done when the 1st file in the group was
                    processed.  Nonetheless, we still must perform the following
                    task (which would have normally been performed by
                    `copy_attribs()`).  Otherwise, the subsequent call to
                    `_matches_cached_rorp(diff_rorp, new)` will fail because the
                    new rorp's metadata would be missing the extended attribute
                    data.
                    """
                    new.data['ea'] = diff_rorp.get_ea()
            else:
                rpath.copy_attribs(diff_rorp, new)
        return self._matches_cached_rorp(diff_rorp, new)
예제 #13
0
    def testInnerRestore(self):
        """Restore part of a dir, see if hard links preserved"""
        MakeOutputDir()
        output = rpath.RPath(Globals.local_connection, abs_output_dir)
        hlout1_dir = os.path.join(abs_test_dir, b"out_hardlink1")
        hlout2_dir = os.path.join(abs_test_dir, b"out_hardlink2")

        # Now set up directories out_hardlink1 and out_hardlink2
        hlout1 = rpath.RPath(Globals.local_connection, hlout1_dir)
        if hlout1.lstat():
            hlout1.delete()
        hlout1.mkdir()
        hlout1_sub = hlout1.append("subdir")
        hlout1_sub.mkdir()
        hl1_1 = hlout1_sub.append("hardlink1")
        hl1_2 = hlout1_sub.append("hardlink2")
        hl1_3 = hlout1_sub.append("hardlink3")
        hl1_4 = hlout1_sub.append("hardlink4")
        # 1 and 2 are hard linked, as are 3 and 4
        hl1_1.touch()
        hl1_2.hardlink(hl1_1.path)
        hl1_3.touch()
        hl1_4.hardlink(hl1_3.path)

        hlout2 = rpath.RPath(Globals.local_connection, hlout2_dir)
        if hlout2.lstat():
            hlout2.delete()
        xcopytree(hlout1_dir, hlout2_dir)
        hlout2_sub = hlout2.append("subdir")
        hl2_1 = hlout2_sub.append("hardlink1")
        hl2_2 = hlout2_sub.append("hardlink2")
        hl2_3 = hlout2_sub.append("hardlink3")
        hl2_4 = hlout2_sub.append("hardlink4")
        # Now 2 and 3 are hard linked, also 1 and 4
        rpath.copy_with_attribs(hl1_1, hl2_1)
        rpath.copy_with_attribs(hl1_2, hl2_2)
        hl2_3.delete()
        hl2_3.hardlink(hl2_2.path)
        hl2_4.delete()
        hl2_4.hardlink(hl2_1.path)
        rpath.copy_attribs(hlout1_sub, hlout2_sub)

        # Now try backing up twice, making sure hard links are preserved
        InternalBackup(1, 1, hlout1.path, output.path)
        out_subdir = output.append("subdir")
        self.assertEqual(
            out_subdir.append("hardlink1").getinode(),
            out_subdir.append("hardlink2").getinode())
        self.assertEqual(
            out_subdir.append("hardlink3").getinode(),
            out_subdir.append("hardlink4").getinode())
        self.assertNotEqual(
            out_subdir.append("hardlink1").getinode(),
            out_subdir.append("hardlink3").getinode())

        time.sleep(1)
        InternalBackup(1, 1, hlout2.path, output.path)
        out_subdir.setdata()
        self.assertEqual(
            out_subdir.append("hardlink1").getinode(),
            out_subdir.append("hardlink4").getinode())
        self.assertEqual(
            out_subdir.append("hardlink2").getinode(),
            out_subdir.append("hardlink3").getinode())
        self.assertNotEqual(
            out_subdir.append("hardlink1").getinode(),
            out_subdir.append("hardlink2").getinode())

        # Now try restoring, still checking hard links.
        sub_dir = os.path.join(abs_output_dir, b"subdir")
        out2_dir = os.path.join(abs_test_dir, b"out2")
        out2 = rpath.RPath(Globals.local_connection, out2_dir)
        hlout1 = out2.append("hardlink1")
        hlout2 = out2.append("hardlink2")
        hlout3 = out2.append("hardlink3")
        hlout4 = out2.append("hardlink4")

        if out2.lstat():
            out2.delete()
        InternalRestore(1, 1, sub_dir, out2_dir, 1)
        out2.setdata()
        for rp in [hlout1, hlout2, hlout3, hlout4]:
            rp.setdata()
        self.assertEqual(hlout1.getinode(), hlout2.getinode())
        self.assertEqual(hlout3.getinode(), hlout4.getinode())
        self.assertNotEqual(hlout1.getinode(), hlout3.getinode())

        if out2.lstat():
            out2.delete()
        InternalRestore(1, 1, sub_dir, out2_dir, int(time.time()))
        out2.setdata()
        for rp in [hlout1, hlout2, hlout3, hlout4]:
            rp.setdata()
        self.assertEqual(hlout1.getinode(), hlout4.getinode())
        self.assertEqual(hlout2.getinode(), hlout3.getinode())
        self.assertNotEqual(hlout1.getinode(), hlout2.getinode())
예제 #14
0
	def testInnerRestore(self):
		"""Restore part of a dir, see if hard links preserved"""
		MakeOutputDir()
		output = rpath.RPath(Globals.local_connection,
							 "testfiles/output")
		
		# Now set up directories out_hardlink1 and out_hardlink2
		hlout1 = rpath.RPath(Globals.local_connection,
							 "testfiles/out_hardlink1")
		if hlout1.lstat(): hlout1.delete()
		hlout1.mkdir()
		hlout1_sub = hlout1.append("subdir")
		hlout1_sub.mkdir()
		hl1_1 = hlout1_sub.append("hardlink1")
		hl1_2 = hlout1_sub.append("hardlink2")
		hl1_3 = hlout1_sub.append("hardlink3")
		hl1_4 = hlout1_sub.append("hardlink4")
		# 1 and 2 are hard linked, as are 3 and 4
		hl1_1.touch()
		hl1_2.hardlink(hl1_1.path)
		hl1_3.touch()
		hl1_4.hardlink(hl1_3.path)
		
		hlout2 = rpath.RPath(Globals.local_connection,
							 "testfiles/out_hardlink2")
		if hlout2.lstat(): hlout2.delete()
		assert not os.system("cp -a testfiles/out_hardlink1 "
							 "testfiles/out_hardlink2")
		hlout2_sub = hlout2.append("subdir")
		hl2_1 = hlout2_sub.append("hardlink1")
		hl2_2 = hlout2_sub.append("hardlink2")
		hl2_3 = hlout2_sub.append("hardlink3")
		hl2_4 = hlout2_sub.append("hardlink4")
		# Now 2 and 3 are hard linked, also 1 and 4
		rpath.copy_with_attribs(hl1_1, hl2_1)
		rpath.copy_with_attribs(hl1_2, hl2_2)
		hl2_3.delete()
		hl2_3.hardlink(hl2_2.path)
		hl2_4.delete()
		hl2_4.hardlink(hl2_1.path)
		rpath.copy_attribs(hlout1_sub, hlout2_sub)

		# Now try backing up twice, making sure hard links are preserved
		InternalBackup(1, 1, hlout1.path, output.path)
		out_subdir = output.append("subdir")
		assert out_subdir.append("hardlink1").getinode() == \
			   out_subdir.append("hardlink2").getinode()
		assert out_subdir.append("hardlink3").getinode() == \
			   out_subdir.append("hardlink4").getinode()
		assert out_subdir.append("hardlink1").getinode() != \
			   out_subdir.append("hardlink3").getinode()

		time.sleep(1)
		InternalBackup(1, 1, hlout2.path, output.path)
		out_subdir.setdata()
		assert out_subdir.append("hardlink1").getinode() == \
			   out_subdir.append("hardlink4").getinode()
		assert out_subdir.append("hardlink2").getinode() == \
			   out_subdir.append("hardlink3").getinode()
		assert out_subdir.append("hardlink1").getinode() != \
			   out_subdir.append("hardlink2").getinode()

		# Now try restoring, still checking hard links.
		out2 = rpath.RPath(Globals.local_connection, "testfiles/out2")
		hlout1 = out2.append("hardlink1")
		hlout2 = out2.append("hardlink2")
		hlout3 = out2.append("hardlink3")
		hlout4 = out2.append("hardlink4")

		if out2.lstat(): out2.delete()
		InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2", 1)
		out2.setdata()
		for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata()
		assert hlout1.getinode() == hlout2.getinode()
		assert hlout3.getinode() == hlout4.getinode()
		assert hlout1.getinode() != hlout3.getinode()
		
		if out2.lstat(): out2.delete()
		InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2",
						int(time.time()))
		out2.setdata()
		for rp in [hlout1, hlout2, hlout3, hlout4]: rp.setdata()
		assert hlout1.getinode() == hlout4.getinode(), \
			   "%s %s" % (hlout1.path, hlout4.path)
		assert hlout2.getinode() == hlout3.getinode()
		assert hlout1.getinode() != hlout2.getinode()
예제 #15
0
    def testInnerRestore(self):
        """Restore part of a dir, see if hard links preserved"""
        MakeOutputDir()
        output = rpath.RPath(Globals.local_connection, "testfiles/output")

        # Now set up directories out_hardlink1 and out_hardlink2
        hlout1 = rpath.RPath(Globals.local_connection,
                             "testfiles/out_hardlink1")
        if hlout1.lstat(): hlout1.delete()
        hlout1.mkdir()
        hlout1_sub = hlout1.append("subdir")
        hlout1_sub.mkdir()
        hl1_1 = hlout1_sub.append("hardlink1")
        hl1_2 = hlout1_sub.append("hardlink2")
        hl1_3 = hlout1_sub.append("hardlink3")
        hl1_4 = hlout1_sub.append("hardlink4")
        # 1 and 2 are hard linked, as are 3 and 4
        hl1_1.touch()
        hl1_2.hardlink(hl1_1.path)
        hl1_3.touch()
        hl1_4.hardlink(hl1_3.path)

        hlout2 = rpath.RPath(Globals.local_connection,
                             "testfiles/out_hardlink2")
        if hlout2.lstat(): hlout2.delete()
        assert not os.system("cp -a testfiles/out_hardlink1 "
                             "testfiles/out_hardlink2")
        hlout2_sub = hlout2.append("subdir")
        hl2_1 = hlout2_sub.append("hardlink1")
        hl2_2 = hlout2_sub.append("hardlink2")
        hl2_3 = hlout2_sub.append("hardlink3")
        hl2_4 = hlout2_sub.append("hardlink4")
        # Now 2 and 3 are hard linked, also 1 and 4
        rpath.copy_with_attribs(hl1_1, hl2_1)
        rpath.copy_with_attribs(hl1_2, hl2_2)
        hl2_3.delete()
        hl2_3.hardlink(hl2_2.path)
        hl2_4.delete()
        hl2_4.hardlink(hl2_1.path)
        rpath.copy_attribs(hlout1_sub, hlout2_sub)

        # Now try backing up twice, making sure hard links are preserved
        InternalBackup(1, 1, hlout1.path, output.path)
        out_subdir = output.append("subdir")
        assert out_subdir.append("hardlink1").getinode() == \
            out_subdir.append("hardlink2").getinode()
        assert out_subdir.append("hardlink3").getinode() == \
            out_subdir.append("hardlink4").getinode()
        assert out_subdir.append("hardlink1").getinode() != \
            out_subdir.append("hardlink3").getinode()

        time.sleep(1)
        InternalBackup(1, 1, hlout2.path, output.path)
        out_subdir.setdata()
        assert out_subdir.append("hardlink1").getinode() == \
            out_subdir.append("hardlink4").getinode()
        assert out_subdir.append("hardlink2").getinode() == \
            out_subdir.append("hardlink3").getinode()
        assert out_subdir.append("hardlink1").getinode() != \
            out_subdir.append("hardlink2").getinode()

        # Now try restoring, still checking hard links.
        out2 = rpath.RPath(Globals.local_connection, "testfiles/out2")
        hlout1 = out2.append("hardlink1")
        hlout2 = out2.append("hardlink2")
        hlout3 = out2.append("hardlink3")
        hlout4 = out2.append("hardlink4")

        if out2.lstat(): out2.delete()
        InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2", 1)
        out2.setdata()
        for rp in [hlout1, hlout2, hlout3, hlout4]:
            rp.setdata()
        assert hlout1.getinode() == hlout2.getinode()
        assert hlout3.getinode() == hlout4.getinode()
        assert hlout1.getinode() != hlout3.getinode()

        if out2.lstat(): out2.delete()
        InternalRestore(1, 1, "testfiles/output/subdir", "testfiles/out2",
                        int(time.time()))
        out2.setdata()
        for rp in [hlout1, hlout2, hlout3, hlout4]:
            rp.setdata()
        assert hlout1.getinode() == hlout4.getinode(), \
            "%s %s" % (hlout1.path, hlout4.path)
        assert hlout2.getinode() == hlout3.getinode()
        assert hlout1.getinode() != hlout2.getinode()