Skip to content

Commit

Permalink
Call enterDir/leaveDir if a directory's child may be selected
Browse files Browse the repository at this point in the history
This allows leaveDir to set metadata properly for directories
with descendants that are selected by an include filter, even
if the directory in question isn't selected by that filter.

For example, let's say you have the following file in your repo:

    /home/user/nested/data/values.txt

...and / and /home are owned by root, but /home/user and below are owned
by user.

If you run "restic restore -i /home/user/nested/data -t /tmp/restore $SNAPSHOT" as root,
/home/user/nested/ will currently be restored with root as the owner,
even though it's supposed to be owned by user.

This change makes sure that leaveDir is called to restore metadata to
nodes like /home/user/nested - enterDir is also called under the same
circumstances for purposes of symmetry.

This fixes GH restic#1402 and (I think) GH restic#2563
  • Loading branch information
hoelzro committed Oct 8, 2020
1 parent 88cc444 commit deeff9b
Showing 1 changed file with 3 additions and 7 deletions.
10 changes: 3 additions & 7 deletions internal/restorer/restorer.go
Expand Up @@ -104,7 +104,7 @@ func (res *Restorer) traverseTree(ctx context.Context, target, location string,
return errors.Errorf("Dir without subtree in tree %v", treeID.Str())
}

if selectedForRestore {
if selectedForRestore || childMayBeSelected {
err = sanitizeError(visitor.enterDir(node, nodeTarget, nodeLocation))
if err != nil {
return err
Expand All @@ -118,7 +118,7 @@ func (res *Restorer) traverseTree(ctx context.Context, target, location string,
}
}

if selectedForRestore {
if selectedForRestore || childMayBeSelected {
err = sanitizeError(visitor.leaveDir(node, nodeTarget, nodeLocation))
if err != nil {
return err
Expand Down Expand Up @@ -209,11 +209,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) error {

// first tree pass: create directories and collect all files to restore
err = res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
enterDir: func(node *restic.Node, target, location string) error {
// create dir with default permissions
// #leaveDir restores dir metadata after visiting all children
return fs.MkdirAll(target, 0700)
},
enterDir: noop,

visitNode: func(node *restic.Node, target, location string) error {
// create parent dir with default permissions
Expand Down

0 comments on commit deeff9b

Please sign in to comment.