forked from TrueCloudLab/restic
Merge pull request #3788 from greatroar/sftp-posix-rename
backend/sftp: Support atomic rename
This commit is contained in:
commit
1dd4b9b60e
1 changed files with 11 additions and 4 deletions
|
@ -31,6 +31,8 @@ type SFTP struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
result <-chan error
|
result <-chan error
|
||||||
|
|
||||||
|
posixRename bool
|
||||||
|
|
||||||
sem *backend.Semaphore
|
sem *backend.Semaphore
|
||||||
backend.Layout
|
backend.Layout
|
||||||
Config
|
Config
|
||||||
|
@ -96,7 +98,8 @@ func startClient(program string, args ...string) (*SFTP, error) {
|
||||||
return nil, errors.Wrap(err, "bg")
|
return nil, errors.Wrap(err, "bg")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SFTP{c: client, cmd: cmd, result: ch}, nil
|
_, posixRename := client.HasExtension("posix-rename@openssh.com")
|
||||||
|
return &SFTP{c: client, cmd: cmd, result: ch, posixRename: posixRename}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// clientError returns an error if the client has exited. Otherwise, nil is
|
// clientError returns an error if the client has exited. Otherwise, nil is
|
||||||
|
@ -269,8 +272,7 @@ func (r *SFTP) Hasher() hash.Hash {
|
||||||
|
|
||||||
// HasAtomicReplace returns whether Save() can atomically replace files
|
// HasAtomicReplace returns whether Save() can atomically replace files
|
||||||
func (r *SFTP) HasAtomicReplace() bool {
|
func (r *SFTP) HasAtomicReplace() bool {
|
||||||
// we use sftp's 'Rename()' in 'Save()' which does not allow overwriting
|
return r.posixRename
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join joins the given paths and cleans them afterwards. This always uses
|
// Join joins the given paths and cleans them afterwards. This always uses
|
||||||
|
@ -364,7 +366,12 @@ func (r *SFTP) Save(ctx context.Context, h restic.Handle, rd restic.RewindReader
|
||||||
return errors.Wrap(err, "Close")
|
return errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.c.Rename(tmpFilename, filename)
|
// Prefer POSIX atomic rename if available.
|
||||||
|
if r.posixRename {
|
||||||
|
err = r.c.PosixRename(tmpFilename, filename)
|
||||||
|
} else {
|
||||||
|
err = r.c.Rename(tmpFilename, filename)
|
||||||
|
}
|
||||||
return errors.Wrap(err, "Rename")
|
return errors.Wrap(err, "Rename")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue