lib/versioner: Clean the versions dir of symlinks, not the full folder

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4289
This commit is contained in:
Jakob Borg
2017-08-08 13:13:08 +00:00
parent a3c17f8f81
commit fa5c890ff6
9 changed files with 207 additions and 36 deletions

View File

@@ -17,6 +17,8 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
@@ -29,7 +31,7 @@ import (
const (
OldestHandledVersion = 10
CurrentVersion = 20
CurrentVersion = 21
MaxRescanIntervalS = 365 * 24 * 60 * 60
)
@@ -314,6 +316,9 @@ func (cfg *Configuration) clean() error {
if cfg.Version == 19 {
convertV19V20(cfg)
}
if cfg.Version == 20 {
convertV20V21(cfg)
}
// Build a list of available devices
existingDevices := make(map[protocol.DeviceID]bool)
@@ -363,6 +368,32 @@ func (cfg *Configuration) clean() error {
return nil
}
func convertV20V21(cfg *Configuration) {
for _, folder := range cfg.Folders {
switch folder.Versioning.Type {
case "simple", "trashcan":
// Clean out symlinks in the known place
cleanSymlinks(filepath.Join(folder.Path(), ".stversions"))
case "staggered":
versionDir := folder.Versioning.Params["versionsPath"]
if versionDir == "" {
// default place
cleanSymlinks(filepath.Join(folder.Path(), ".stversions"))
} else if filepath.IsAbs(versionDir) {
// absolute
cleanSymlinks(versionDir)
} else {
// relative to folder
cleanSymlinks(filepath.Join(folder.Path(), versionDir))
}
}
}
// there is also a symlink recovery step in Model.StartFolder()
cfg.Version = 21
}
func convertV19V20(cfg *Configuration) {
cfg.Options.MinHomeDiskFree = Size{Value: cfg.Options.DeprecatedMinHomeDiskFreePct, Unit: "%"}
cfg.Options.DeprecatedMinHomeDiskFreePct = 0
@@ -640,3 +671,23 @@ loop:
}
return devices[0:count]
}
func cleanSymlinks(dir string) {
if runtime.GOOS == "windows" {
// We don't do symlinks on Windows. Additionally, there may
// be things that look like symlinks that are not, which we
// should leave alone. Deduplicated files, for example.
return
}
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Mode()&os.ModeSymlink != 0 {
l.Infoln("Removing incorrectly versioned symlink", path)
os.Remove(path)
return filepath.SkipDir
}
return nil
})
}