Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save and restore extended attributes #25

Closed
fd0 opened this issue Nov 15, 2014 · 13 comments
Closed

Save and restore extended attributes #25

fd0 opened this issue Nov 15, 2014 · 13 comments

Comments

@fd0
Copy link
Member

fd0 commented Nov 15, 2014

This issue tracks saving and restoring extended attributes like POSIX ACL.

@jgfrm
Copy link

jgfrm commented Jan 27, 2017

I start working on this.

@jgfrm
Copy link

jgfrm commented Jan 30, 2017

I have xattrs for files working.
There are however two problems.

  1. I need a full path to the file (in case the node is for a file which is there) and a full path to the directory (in case the node is for a dir).
    What happens is that fileWorker uses a full path:
    node, err := restic.NodeFromFileInfo(e.Fullpath(), e.Info())
    where dirWorker uses a relative path
    n, err := restic.NodeFromFileInfo(dir.Path(), dir.Info())

My question:

  • how can I obtain the full path of a dir, specifically in node.fillExtra
  1. I also tried to implement xattr for fuse.
    To call the proper syscall of the fuse package (syscallx.Setxattr), I need also the full path of the file or dir.
    Again here: how can I obtain the full path?

Thanks

@fd0
Copy link
Member Author

fd0 commented Jan 30, 2017

Why do you need a full path for reading the extended attributes?

@fd0
Copy link
Member Author

fd0 commented Jan 30, 2017

It works very well with relative paths, sample program here:

$ touch foo
$ ./xattr ./foo
extended attributes for ./foo:
$ setfacl -m user:nobody:r foo
$ ./xattr ./foo
extended attributes for ./foo:
system.posix_acl_access: "\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x02\x00\x04\x00c\x00\x00\x00\x04\x00\x04\x00\xff\xff\xff\xff\x10\x00\x04\x00\xff\xff\xff\xff \x00\x04\x00\xff\xff\xff\xff"

@jgfrm
Copy link

jgfrm commented Feb 1, 2017

The problem is that in
node.fillExtra
for a file, the full path is passed (that's ok) whereas for a directory a relative path is passed.

This relative path is evaluated in the context of the restic process, and does not coincide with the place in the backup.
Therefore, looking up the acl for a directory fails.

I either need the full path, or the path relative to the context of the restic process.

@fd0
Copy link
Member Author

fd0 commented Feb 2, 2017

Ah, so it's inconsistent. I understand now. Then just change the invocation of NodeFromFileInfo() for directories so that the full path is passed on:

diff --git a/src/restic/archiver/archiver.go b/src/restic/archiver/archiver.go
index b579524..d95423c 100644
--- a/src/restic/archiver/archiver.go
+++ b/src/restic/archiver/archiver.go
@@ -385,7 +385,7 @@ func (arch *Archiver) dirWorker(wg *sync.WaitGroup, p *restic.Progress, done <-c
            node := &restic.Node{}
 
            if dir.Path() != "" && dir.Info() != nil {
-               n, err := restic.NodeFromFileInfo(dir.Path(), dir.Info())
+               n, err := restic.NodeFromFileInfo(dir.Fullpath(), dir.Info())
                if err != nil {
                    n.Error = err.Error()
                    dir.Result() <- n

I have verified this change locally.

@jgfrm
Copy link

jgfrm commented Feb 2, 2017

For fuse support, I need the same thing.
The full path (node.Path) is not set.
I see that the JSON field is not included in the marshalling.
Is there a way to get the full path for a file/dir (incl mount dir) in fuse/dir.go and file.go?

@fd0
Copy link
Member Author

fd0 commented Feb 3, 2017

I'm sorry, but I don't understand. Why do you need the path of the (original) file/dir in the fuse code? The extended attributes are available after unmarshalling the Node from the repo, so why is the path needed?

The Path attribute of the Node struct is used during backup to store the path to the node. After the backup is done, there's no need for this path any more (the file may even have been removed).

@jgfrm
Copy link

jgfrm commented Feb 3, 2017

I do not need the path of the original file, but the path of the file that is accessed via the fuse mount.
So say there is a file /user/bla/bla.txt and I mount the backup on e.g. /mnt/restic, I need the path /mnt/restic/user/bla/bla.txt to set the proper acl for that file. A relative path only works, if it is relative path to the context of the restic process.

I have added in the fuse code support for obtaining the full path name of the mounted file by adding for each file/directory a pointer to its parent, so that I can recursively traverse the tree until I reach the root.

The remaining problem is that I also need the path for the selected snapshot, including the mount point. I have developed also code for this, but I am not really satisfied with it. I discovered that the snapshot dir is the first dir, (in terms of struct Dir). If I store the name of that snapshot directory, plus a pointer to the snapshots (which contains a reference to the mount point), I can obtain the full path.

However, I would prefer to have a struct for the set of snapshots, and a separate one for the snapshot itself. What do you think?

@fd0
Copy link
Member Author

fd0 commented Feb 3, 2017

Thanks for the explanation. It's a bit hard to follow, could you push the code you already have somewhere so I can have a look?

@jgfrm
Copy link

jgfrm commented Feb 6, 2017

Sometimes things are simpler than you originally thought. Extended attribute support works now for fuse, with only a few additions to the code.
Let's first process the extended attribute support for the restore command, then I will submit support for fuse.

@fd0
Copy link
Member Author

fd0 commented Feb 6, 2017

Ok, cool! thanks for your work so far!

@fd0
Copy link
Member Author

fd0 commented Feb 16, 2017

This was just merged in 0674f32, thanks @jgfrm for the hard work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants