From 0018bb7854b4dc605f334d92e833b436142e212c Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 6 Jan 2024 18:43:16 +0100 Subject: [PATCH 1/4] restic: cleanup node type determination os.ModeCharDevice is already included in os.ModeType --- internal/restic/node.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/restic/node.go b/internal/restic/node.go index edb49bfca..1b940b0d0 100644 --- a/internal/restic/node.go +++ b/internal/restic/node.go @@ -109,7 +109,7 @@ func NodeFromFileInfo(path string, fi os.FileInfo) (*Node, error) { } func nodeTypeFromFileInfo(fi os.FileInfo) string { - switch fi.Mode() & (os.ModeType | os.ModeCharDevice) { + switch fi.Mode() & os.ModeType { case 0: return "file" case os.ModeDir: From 6b79834cc8f1d77102db7d2e6a8890da2998cd68 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 6 Jan 2024 19:03:11 +0100 Subject: [PATCH 2/4] archiver: improve error message for irregular files Since Go 1.21, most reparse points are considered as irregular files. Depending on the underlying driver these can exhibit nearly arbitrary behavior. When encountering such a file, restic returned an indecipherable error message: `error: invalid node type ""`. Add the filepath to the error message and state that the file type is not supported. --- internal/archiver/archiver.go | 6 +++++- internal/restic/node.go | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go index e2f22ebea..8f9c8d8e8 100644 --- a/internal/archiver/archiver.go +++ b/internal/archiver/archiver.go @@ -2,6 +2,7 @@ package archiver import ( "context" + "fmt" "os" "path" "runtime" @@ -183,7 +184,10 @@ func (arch *Archiver) nodeFromFileInfo(snPath, filename string, fi os.FileInfo) } // overwrite name to match that within the snapshot node.Name = path.Base(snPath) - return node, errors.WithStack(err) + if err != nil { + return node, fmt.Errorf("nodeFromFileInfo %v: %w", filename, err) + } + return node, err } // loadSubtree tries to load the subtree referenced by node. In case of an error, nil is returned. diff --git a/internal/restic/node.go b/internal/restic/node.go index 1b940b0d0..7edc41ce8 100644 --- a/internal/restic/node.go +++ b/internal/restic/node.go @@ -124,6 +124,8 @@ func nodeTypeFromFileInfo(fi os.FileInfo) string { return "fifo" case os.ModeSocket: return "socket" + case os.ModeIrregular: + return "irregular" } return "" @@ -622,7 +624,7 @@ func (node *Node) fillExtra(path string, fi os.FileInfo) error { case "fifo": case "socket": default: - return errors.Errorf("invalid node type %q", node.Type) + return errors.Errorf("unsupported file type %q", node.Type) } return node.fillExtendedAttributes(path) From 51419c51d3cae9137e428acac9fb346220701b81 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 6 Jan 2024 19:08:24 +0100 Subject: [PATCH 3/4] archiver: Add filepath to error message if it is not included yet --- internal/archiver/archiver.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go index 8f9c8d8e8..f2c481b32 100644 --- a/internal/archiver/archiver.go +++ b/internal/archiver/archiver.go @@ -7,6 +7,7 @@ import ( "path" "runtime" "sort" + "strings" "time" "github.com/restic/restic/internal/debug" @@ -169,6 +170,11 @@ func (arch *Archiver) error(item string, err error) error { return err } + // not all errors include the filepath, thus add it if it is missing + if !strings.Contains(err.Error(), item) { + err = fmt.Errorf("%v: %w", item, err) + } + errf := arch.Error(item, err) if err != errf { debug.Log("item %v: error was filtered by handler, before: %q, after: %v", item, err, errf) From 3e29f8dddfb5a568c2feffad99cf8c840835acf5 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 6 Jan 2024 19:17:54 +0100 Subject: [PATCH 4/4] add changelog for irregular files on windows --- changelog/unreleased/issue-4560 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 changelog/unreleased/issue-4560 diff --git a/changelog/unreleased/issue-4560 b/changelog/unreleased/issue-4560 new file mode 100644 index 000000000..c421f6e69 --- /dev/null +++ b/changelog/unreleased/issue-4560 @@ -0,0 +1,14 @@ +Bugfix: Improve errors for irregular files on Windows + +Since Go 1.21, most filesystem reparse points on Windows are considered to be +irregular files. This caused restic to show an `error: invalid node type ""` +error message for those files. + +We have improved the error message to include the file path for those files: +`error: nodeFromFileInfo path/to/file: unsupported file type "irregular"`. +As irregular files are not required to behave like regular files, it is not +possible to provide a generic way to back up those files. + +https://github.com/restic/restic/issues/4560 +https://github.com/restic/restic/pull/4620 +https://forum.restic.net/t/windows-backup-error-invalid-node-type/6875