sftp: use vendor-specific VFS statistics extension for about if available

See #5763
This commit is contained in:
albertony 2021-10-31 14:04:36 +01:00
parent b4091f282a
commit 5db9a2f831
2 changed files with 48 additions and 10 deletions

View File

@ -1324,6 +1324,42 @@ func (f *Fs) Hashes() hash.Set {
// About gets usage stats
func (f *Fs) About(ctx context.Context) (*fs.Usage, error) {
// If server implements the vendor-specific VFS statistics extension prefer that
// (OpenSSH implements it on using syscall.Statfs on Linux and API function GetDiskFreeSpace on Windows)
c, err := f.getSftpConnection(ctx)
if err != nil {
return nil, err
}
var vfsStats *sftp.StatVFS
if _, found := c.sftpClient.HasExtension("statvfs@openssh.com"); found {
fs.Debugf(f, "Server has VFS statistics extension")
aboutPath := f.absRoot
if aboutPath == "" {
aboutPath = "/"
}
fs.Debugf(f, "About path %q", aboutPath)
vfsStats, err = c.sftpClient.StatVFS(aboutPath)
}
f.putSftpConnection(&c, err) // Return to pool asap, if running shell command below it will be re-used
if vfsStats != nil {
total := vfsStats.TotalSpace()
free := vfsStats.FreeSpace()
used := total - free
return &fs.Usage{
Total: fs.NewUsageValue(int64(total)),
Used: fs.NewUsageValue(int64(used)),
Free: fs.NewUsageValue(int64(free)),
}, nil
} else if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, err
}
fs.Debugf(f, "Failed to retrieve VFS statistics, trying shell command instead: %v", err)
} else {
fs.Debugf(f, "Server does not have the VFS statistics extension, trying shell command instead")
}
// Fall back to shell command method if possible
if f.shellType == shellTypeNotSupported || f.shellType == "cmd" {
fs.Debugf(f, "About shell command is not available for shell type %q (set option shell_type to override)", f.shellType)
return nil, fmt.Errorf("not supported with shell type %q", f.shellType)

View File

@ -370,17 +370,19 @@ your RClone backend configuration to disable this behaviour.
### About command
SFTP supports the [about](/commands/rclone_about/) command if the
same login has access to a Unix shell, where the `df` command is
available (e.g. in the remote's PATH). `about` will return the
total space, free space, and used space on the remote for the disk
of the specified path on the remote or, if not set, the disk of
the root on the remote. `about` will fail if it does not have
shell access or if `df` is not found.
The `about` command returns the total space, free space, and used
space on the remote for the disk of the specified path on the remote or,
if not set, the disk of the root on the remote.
If the server shell is PowerShell, probably with a Windows OpenSSH
server, rclone supports `about` using a built-in shell command
(see [shell access](#shell-access)).
SFTP usually supports the [about](/commands/rclone_about/) command, but
it depends on the server. If the server implements the vendor-specific
VFS statistics extension, which is normally the case with OpenSSH instances,
it will be used. If not, but the same login has access to a Unix shell,
where the `df` command is available (e.g. in the remote's PATH), then
this will be used instead. If the server shell is PowerShell, probably
with a Windows OpenSSH server, rclone will use a built-in shell command
(see [shell access](#shell-access)). If none of the above is applicable,
`about` will fail.
{{< rem autogenerated options start" - DO NOT EDIT - instead edit fs.RegInfo in backend/sftp/sftp.go then run make backenddocs" >}}
### Standard options