From 4df2e33568426da1fe5991d4bb14949146a9a8d1 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Fri, 18 Oct 2024 22:26:18 +0200 Subject: [PATCH] archiver: properly create node for vss backups Previously, NodeFromFileInfo used the original file path to create the node, which also meant that extended metadata was read from there instead of within the vss snapshot. This change is a temporary solution for restic 0.17.2 and will be replaced with a clean fix in restic 0.18.0. --- internal/archiver/archiver.go | 3 ++- internal/fs/fs_local.go | 6 ++++++ internal/fs/fs_local_vss.go | 6 ++++++ internal/fs/fs_reader.go | 6 ++++++ internal/fs/interface.go | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go index 839320816..03b3b9986 100644 --- a/internal/archiver/archiver.go +++ b/internal/archiver/archiver.go @@ -248,7 +248,8 @@ func (arch *Archiver) trackItem(item string, previous, current *restic.Node, s I // nodeFromFileInfo returns the restic node from an os.FileInfo. func (arch *Archiver) nodeFromFileInfo(snPath, filename string, fi os.FileInfo, ignoreXattrListError bool) (*restic.Node, error) { - node, err := restic.NodeFromFileInfo(filename, fi, ignoreXattrListError) + mappedFilename := arch.FS.MapFilename(filename) + node, err := restic.NodeFromFileInfo(mappedFilename, fi, ignoreXattrListError) if !arch.WithAtime { node.AccessTime = node.ModTime } diff --git a/internal/fs/fs_local.go b/internal/fs/fs_local.go index 48c40dc90..06dbae9a0 100644 --- a/internal/fs/fs_local.go +++ b/internal/fs/fs_local.go @@ -18,6 +18,12 @@ func (fs Local) VolumeName(path string) string { return filepath.VolumeName(path) } +// MapFilename is a temporary hack to prepare a filename for usage with +// NodeFromFileInfo. This is only relevant for LocalVss. +func (fs Local) MapFilename(filename string) string { + return filename +} + // Open opens a file for reading. func (fs Local) Open(name string) (File, error) { f, err := os.Open(fixpath(name)) diff --git a/internal/fs/fs_local_vss.go b/internal/fs/fs_local_vss.go index 718dfc46d..db6c95155 100644 --- a/internal/fs/fs_local_vss.go +++ b/internal/fs/fs_local_vss.go @@ -145,6 +145,12 @@ func (fs *LocalVss) Lstat(name string) (os.FileInfo, error) { return os.Lstat(fs.snapshotPath(name)) } +// MapFilename is a temporary hack to prepare a filename for usage with +// NodeFromFileInfo. This is only relevant for LocalVss. +func (fs *LocalVss) MapFilename(filename string) string { + return fs.snapshotPath(filename) +} + // isMountPointIncluded is true if given mountpoint included by user. func (fs *LocalVss) isMountPointIncluded(mountPoint string) bool { if fs.excludeVolumes == nil { diff --git a/internal/fs/fs_reader.go b/internal/fs/fs_reader.go index 47af74245..a39b4dad2 100644 --- a/internal/fs/fs_reader.go +++ b/internal/fs/fs_reader.go @@ -39,6 +39,12 @@ func (fs *Reader) VolumeName(_ string) string { return "" } +// MapFilename is a temporary hack to prepare a filename for usage with +// NodeFromFileInfo. This is only relevant for LocalVss. +func (fs *Reader) MapFilename(filename string) string { + return filename +} + // Open opens a file for reading. func (fs *Reader) Open(name string) (f File, err error) { switch name { diff --git a/internal/fs/interface.go b/internal/fs/interface.go index b26c56944..0fd84715d 100644 --- a/internal/fs/interface.go +++ b/internal/fs/interface.go @@ -11,6 +11,7 @@ type FS interface { OpenFile(name string, flag int, perm os.FileMode) (File, error) Stat(name string) (os.FileInfo, error) Lstat(name string) (os.FileInfo, error) + MapFilename(filename string) string Join(elem ...string) string Separator() string