Merge pull request #3788 from greatroar/sftp-posix-rename

backend/sftp: Support atomic rename
This commit is contained in:
Alexander Neumann 2022-06-06 19:39:48 +02:00 committed by GitHub
commit 1dd4b9b60e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 4 deletions

View File

@ -31,6 +31,8 @@ type SFTP struct {
cmd *exec.Cmd
result <-chan error
posixRename bool
sem *backend.Semaphore
backend.Layout
Config
@ -96,7 +98,8 @@ func startClient(program string, args ...string) (*SFTP, error) {
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
@ -269,8 +272,7 @@ func (r *SFTP) Hasher() hash.Hash {
// HasAtomicReplace returns whether Save() can atomically replace files
func (r *SFTP) HasAtomicReplace() bool {
// we use sftp's 'Rename()' in 'Save()' which does not allow overwriting
return false
return r.posixRename
}
// 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")
}
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")
}