Commit 31c32ead authored by Joan Piles's avatar Joan Piles

First tentative patch for resuse of incomplete backups

parent a16ba656
......@@ -58,7 +58,15 @@ func runRsyncCommand(cmd *exec.Cmd) (error, chan error) {
// error was presumably volatile.
func CreateSnapshot(base *Snapshot) (*Snapshot, error) {
cl := new(realClock)
newSn := newIncompleteSnapshot(cl)
partial := LastReusableFromDisk(cl)
var newSn *Snapshot
if partial == nil {
newSn = newIncompleteSnapshot(cl)
} else {
newSn = ReusePartial(partial, cl)
}
cmd := createRsyncCommand(newSn, base)
err, done := runRsyncCommand(cmd)
if err != nil {
......@@ -77,7 +85,7 @@ func CreateSnapshot(base *Snapshot) (*Snapshot, error) {
}
return nil, errors.New("rsync killed by request")
case err := <-done:
Debugf("received something on done channel:", nil)
Debugf("received something on done channel: ", err)
if err != nil {
// At this stage rsync ran, but with errors.
// Restart in case of
......@@ -90,6 +98,7 @@ func CreateSnapshot(base *Snapshot) (*Snapshot, error) {
// First, get the error code
if exiterr, ok := err.(*exec.ExitError); ok { // The return code != 0)
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { // Finally get the actual status code
Debugf("The error code we got is: ", err)
// status now holds the actual return code
if status == 24 { // Magic number: means some files couldn't be copied because they vanished, so nothing critical. See man rsync
Debugf("Some files failed to copy because they were deleted in the meantime, but nothing critical... going on...")
......
......@@ -187,6 +187,23 @@ func (sl SnapshotList) lastGood() *Snapshot {
return sl[ix]
}
// Find the last snapshot in a given list.
func (sl SnapshotList) last() *Snapshot {
var t time.Time
var ix int = -1
for i, sn := range sl {
if (sn.startTime.After(t)) {
t = sn.startTime
ix = i
}
}
if ix == -1 {
return nil
}
return sl[ix]
}
// parseSnapshotName split the given string up into the various values needed
// for creating a Snapshot struct.
func parseSnapshotName(s string) (time.Time, time.Time, SnapshotState, error) {
......@@ -322,3 +339,26 @@ func LastGoodFromDisk(cl Clock) *Snapshot {
}
return sn
}
// LastIncompleteFromDisk lists the snapshots in the repository and returns a pointer
// to the youngest incomplete snapshot, for possible reuse.
func LastReusableFromDisk(cl Clock) *Snapshot {
snapshots, err := FindSnapshots(cl)
if err != nil {
log.Println(err)
}
sn := snapshots.state(STATE_INCOMPLETE, NONE).last()
return sn
}
// ReusePartial generates a new incomplete snapshot based on a previous one.
// Can be used to try to use previous incomplete snapshots, or even to reuse
// obsolete ones.
func ReusePartial(orig *Snapshot, cl Clock) *Snapshot {
s := newIncompleteSnapshot(cl)
err := os.Rename(orig.FullName(), s.FullName())
if err != nil {
log.Fatal(err)
}
return s;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment