63 |
assert mirror_rp.index == () and inc_rpath.index == () |
assert mirror_rp.index == () and inc_rpath.index == () |
64 |
assert mirror_rp.isdir() and inc_rpath.isdir() |
assert mirror_rp.isdir() and inc_rpath.isdir() |
65 |
assert mirror_rp.conn is inc_rpath.conn is Globals.local_connection |
assert mirror_rp.conn is inc_rpath.conn is Globals.local_connection |
66 |
set_regress_time() |
manager, former_current_mirror_rp = set_regress_time() |
67 |
set_restore_times() |
set_restore_times() |
68 |
former_current_mirror_rp = remove_rbdir_increments() |
regress_rbdir(manager) |
69 |
ITR = rorpiter.IterTreeReducer(RegressITRB, []) |
ITR = rorpiter.IterTreeReducer(RegressITRB, []) |
70 |
for rf in iterate_meta_rfs(mirror_rp, inc_rpath): ITR(rf.index, rf) |
for rf in iterate_meta_rfs(mirror_rp, inc_rpath): ITR(rf.index, rf) |
71 |
ITR.Finish() |
ITR.Finish() |
81 |
|
|
82 |
""" |
""" |
83 |
global regress_time, unsuccessful_backup_time |
global regress_time, unsuccessful_backup_time |
84 |
curmir_incs = restore.get_inclist(Globals.rbdir.append("current_mirror")) |
manager = metadata.SetManager() |
85 |
|
curmir_incs = manager.sorted_prefix_inclist('current_mirror') |
86 |
assert len(curmir_incs) == 2, \ |
assert len(curmir_incs) == 2, \ |
87 |
"Found %s current_mirror flags, expected 2" % len(curmir_incs) |
"Found %s current_mirror flags, expected 2" % len(curmir_incs) |
88 |
inctimes = [inc.getinctime() for inc in curmir_incs] |
mirror_rp_to_delete = curmir_incs[0] |
89 |
inctimes.sort() |
regress_time = curmir_incs[1].getinctime() |
90 |
regress_time = inctimes[0] |
unsuccessful_backup_time = mirror_rp_to_delete.getinctime() |
|
unsuccessful_backup_time = inctimes[-1] |
|
91 |
log.Log("Regressing to " + Time.timetopretty(regress_time), 4) |
log.Log("Regressing to " + Time.timetopretty(regress_time), 4) |
92 |
|
return manager, mirror_rp_to_delete |
93 |
|
|
94 |
def set_restore_times(): |
def set_restore_times(): |
95 |
"""Set _rest_time and _mirror_time in the restore module |
"""Set _rest_time and _mirror_time in the restore module |
101 |
restore.MirrorStruct._mirror_time = unsuccessful_backup_time |
restore.MirrorStruct._mirror_time = unsuccessful_backup_time |
102 |
restore.MirrorStruct._rest_time = regress_time |
restore.MirrorStruct._rest_time = regress_time |
103 |
|
|
104 |
def remove_rbdir_increments(): |
def regress_rbdir(meta_manager): |
105 |
"""Delete the increments in the rdiff-backup-data directory |
"""Delete the increments in the rdiff-backup-data directory |
106 |
|
|
107 |
Returns the former current mirror rp so we can delete it later. |
Returns the former current mirror rp so we can delete it later. |
108 |
All of the other rp's should be deleted before the actual regress, |
All of the other rp's should be deleted before the actual regress, |
109 |
to clear up disk space the rest of the procedure may need. |
to clear up disk space the rest of the procedure may need. |
110 |
|
|
111 |
|
Also, in case the previous session failed while diffing the |
112 |
|
metadata file, either recreate the mirror_metadata snapshot, or |
113 |
|
delete the extra regress_time diff. |
114 |
|
|
115 |
""" |
""" |
116 |
former_current_mirror = None |
has_meta_diff, has_meta_snap = 0, 0 |
117 |
for filename in Globals.rbdir.listdir(): |
for old_rp in meta_manager.timerpmap[regress_time]: |
118 |
rp = Globals.rbdir.append(filename) |
if old_rp.getincbase_str() == 'mirror_metadata': |
119 |
if rp.isincfile() and rp.getinctime() == unsuccessful_backup_time: |
if old_rp.getinctype() == 'snapshot': has_meta_snap = 1 |
|
if rp.getincbase_str() == "current_mirror": |
|
|
former_current_mirror = rp |
|
120 |
else: |
else: |
121 |
log.Log("Removing rdiff-backup-data increment " + rp.path, 5) |
assert old_rp.getinctype() == 'diff', old_rp |
122 |
rp.delete() |
has_meta_diff = 1 |
123 |
return former_current_mirror |
if has_meta_diff and not has_meta_snap: recreate_meta(meta_manager) |
124 |
|
|
125 |
|
for new_rp in meta_manager.timerpmap[unsuccessful_backup_time]: |
126 |
|
if new_rp.getincbase_str() != 'current_mirror': |
127 |
|
log.Log("Deleting old diff at " + new_rp.path, 5) |
128 |
|
new_rp.delete() |
129 |
|
|
130 |
|
def recreate_meta(meta_manager): |
131 |
|
"""Make regress_time mirror_metadata snapshot by patching |
132 |
|
|
133 |
|
We write to a tempfile first. Otherwise, in case of a crash, it |
134 |
|
would seem we would have an intact snapshot and partial diff, not |
135 |
|
the reverse. |
136 |
|
|
137 |
|
""" |
138 |
|
temprp = TempFile.new_in_dir(Globals.rbdir) |
139 |
|
writer = metadata.MetadataFile(temprp, 'w', check_path = 0) |
140 |
|
for rorp in meta_manager.get_meta_at_time(regress_time, None): |
141 |
|
writer.write_object(rorp) |
142 |
|
writer.close() |
143 |
|
|
144 |
|
finalrp = Globals.rbdir.append("mirror_metadata.%s.snapshot.gz" % |
145 |
|
Time.timetostring(regress_time)) |
146 |
|
assert not finalrp.lstat(), finalrp |
147 |
|
rpath.rename(temprp, finalrp) |
148 |
|
if Globals.fsync_directories: Globals.rbdir.fsync() |
149 |
|
|
150 |
def iterate_raw_rfs(mirror_rp, inc_rp): |
def iterate_raw_rfs(mirror_rp, inc_rp): |
151 |
"""Iterate all RegressFile objects in mirror/inc directory |
"""Iterate all RegressFile objects in mirror/inc directory |
174 |
metadata.SetManager() |
metadata.SetManager() |
175 |
metadata_iter = metadata.ManagerObj.GetAtTime(regress_time) |
metadata_iter = metadata.ManagerObj.GetAtTime(regress_time) |
176 |
if metadata_iter: return metadata_iter |
if metadata_iter: return metadata_iter |
177 |
log.Log.FatalError("No metadata for time %s found, cannot regress" |
log.Log.FatalError("No metadata for time %s (%s) found,\ncannot regress" |
178 |
% Time.timetopretty(regress_time)) |
% (Time.timetopretty(regress_time), regress_time)) |
179 |
|
|
180 |
def iterate_meta_rfs(mirror_rp, inc_rp): |
def iterate_meta_rfs(mirror_rp, inc_rp): |
181 |
"""Yield RegressFile objects with extra metadata information added |
"""Yield RegressFile objects with extra metadata information added |