forked from TrueCloudLab/restic
Merge pull request #2584 from greatroar/mount-cache-uid-gid
Cache uid and gid for top directories in internal/fuse
This commit is contained in:
commit
f77477129f
5 changed files with 64 additions and 32 deletions
|
@ -98,8 +98,6 @@ func newDirFromSnapshot(ctx context.Context, root *Root, inode uint64, snapshot
|
||||||
return &dir{
|
return &dir{
|
||||||
root: root,
|
root: root,
|
||||||
node: &restic.Node{
|
node: &restic.Node{
|
||||||
UID: uint32(os.Getuid()),
|
|
||||||
GID: uint32(os.Getgid()),
|
|
||||||
AccessTime: snapshot.Time,
|
AccessTime: snapshot.Time,
|
||||||
ModTime: snapshot.Time,
|
ModTime: snapshot.Time,
|
||||||
ChangeTime: snapshot.Time,
|
ChangeTime: snapshot.Time,
|
||||||
|
@ -114,11 +112,8 @@ func (d *dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
debug.Log("called")
|
debug.Log("called")
|
||||||
a.Inode = d.inode
|
a.Inode = d.inode
|
||||||
a.Mode = os.ModeDir | d.node.Mode
|
a.Mode = os.ModeDir | d.node.Mode
|
||||||
|
a.Uid = d.root.uid
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
a.Gid = d.root.gid
|
||||||
a.Uid = d.node.UID
|
|
||||||
a.Gid = d.node.GID
|
|
||||||
}
|
|
||||||
a.Atime = d.node.AccessTime
|
a.Atime = d.node.AccessTime
|
||||||
a.Ctime = d.node.ChangeTime
|
a.Ctime = d.node.ChangeTime
|
||||||
a.Mtime = d.node.ModTime
|
a.Mtime = d.node.ModTime
|
||||||
|
|
|
@ -8,6 +8,7 @@ package fuse
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -152,3 +153,44 @@ func TestFuseFile(t *testing.T) {
|
||||||
|
|
||||||
rtest.OK(t, f.Release(ctx, nil))
|
rtest.OK(t, f.Release(ctx, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test top-level directories for their UID and GID.
|
||||||
|
func TestTopUidGid(t *testing.T) {
|
||||||
|
repo, cleanup := repository.TestRepository(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
restic.TestCreateSnapshot(t, repo, time.Unix(1460289341, 207401672), 0, 0)
|
||||||
|
|
||||||
|
testTopUidGid(t, Config{}, repo, uint32(os.Getuid()), uint32(os.Getgid()))
|
||||||
|
testTopUidGid(t, Config{OwnerIsRoot: true}, repo, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTopUidGid(t *testing.T, cfg Config, repo restic.Repository, uid, gid uint32) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
root, err := NewRoot(ctx, repo, cfg)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
|
||||||
|
var attr fuse.Attr
|
||||||
|
err = root.Attr(ctx, &attr)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.Equals(t, uid, attr.Uid)
|
||||||
|
rtest.Equals(t, gid, attr.Gid)
|
||||||
|
|
||||||
|
idsdir, err := root.Lookup(ctx, "ids")
|
||||||
|
rtest.OK(t, err)
|
||||||
|
|
||||||
|
err = idsdir.Attr(ctx, &attr)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.Equals(t, uid, attr.Uid)
|
||||||
|
rtest.Equals(t, gid, attr.Gid)
|
||||||
|
|
||||||
|
snapID := loadFirstSnapshot(t, repo).ID().Str()
|
||||||
|
snapshotdir, err := idsdir.(fs.NodeStringLookuper).Lookup(ctx, snapID)
|
||||||
|
|
||||||
|
err = snapshotdir.Attr(ctx, &attr)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.Equals(t, uid, attr.Uid)
|
||||||
|
rtest.Equals(t, gid, attr.Gid)
|
||||||
|
}
|
|
@ -42,11 +42,9 @@ func NewMetaDir(root *Root, inode uint64, entries map[string]fs.Node) *MetaDir {
|
||||||
func (d *MetaDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
func (d *MetaDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr.Inode = d.inode
|
attr.Inode = d.inode
|
||||||
attr.Mode = os.ModeDir | 0555
|
attr.Mode = os.ModeDir | 0555
|
||||||
|
attr.Uid = d.root.uid
|
||||||
|
attr.Gid = d.root.gid
|
||||||
|
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
|
||||||
attr.Uid = uint32(os.Getuid())
|
|
||||||
attr.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
debug.Log("attr: %v", attr)
|
debug.Log("attr: %v", attr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package fuse
|
package fuse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/debug"
|
"github.com/restic/restic/internal/debug"
|
||||||
|
@ -37,6 +38,8 @@ type Root struct {
|
||||||
lastCheck time.Time
|
lastCheck time.Time
|
||||||
|
|
||||||
*MetaDir
|
*MetaDir
|
||||||
|
|
||||||
|
uid, gid uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that *Root implements these interfaces
|
// ensure that *Root implements these interfaces
|
||||||
|
@ -56,6 +59,11 @@ func NewRoot(ctx context.Context, repo restic.Repository, cfg Config) (*Root, er
|
||||||
blobSizeCache: NewBlobSizeCache(ctx, repo.Index()),
|
blobSizeCache: NewBlobSizeCache(ctx, repo.Index()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cfg.OwnerIsRoot {
|
||||||
|
root.uid = uint32(os.Getuid())
|
||||||
|
root.gid = uint32(os.Getgid())
|
||||||
|
}
|
||||||
|
|
||||||
entries := map[string]fs.Node{
|
entries := map[string]fs.Node{
|
||||||
"snapshots": NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), "", ""),
|
"snapshots": NewSnapshotsDir(root, fs.GenerateDynamicInode(root.inode, "snapshots"), "", ""),
|
||||||
"tags": NewTagsDir(root, fs.GenerateDynamicInode(root.inode, "tags")),
|
"tags": NewTagsDir(root, fs.GenerateDynamicInode(root.inode, "tags")),
|
||||||
|
|
|
@ -168,11 +168,9 @@ func NewTagsDir(root *Root, inode uint64) *TagsDir {
|
||||||
func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr.Inode = d.inode
|
attr.Inode = d.inode
|
||||||
attr.Mode = os.ModeDir | 0555
|
attr.Mode = os.ModeDir | 0555
|
||||||
|
attr.Uid = d.root.uid
|
||||||
|
attr.Gid = d.root.gid
|
||||||
|
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
|
||||||
attr.Uid = uint32(os.Getuid())
|
|
||||||
attr.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
debug.Log("attr: %v", attr)
|
debug.Log("attr: %v", attr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -181,11 +179,9 @@ func (d *SnapshotsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr.Inode = d.inode
|
attr.Inode = d.inode
|
||||||
attr.Mode = os.ModeDir | 0555
|
attr.Mode = os.ModeDir | 0555
|
||||||
|
attr.Uid = d.root.uid
|
||||||
|
attr.Gid = d.root.gid
|
||||||
|
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
|
||||||
attr.Uid = uint32(os.Getuid())
|
|
||||||
attr.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
debug.Log("attr: %v", attr)
|
debug.Log("attr: %v", attr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -194,11 +190,9 @@ func (d *SnapshotsIDSDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr.Inode = d.inode
|
attr.Inode = d.inode
|
||||||
attr.Mode = os.ModeDir | 0555
|
attr.Mode = os.ModeDir | 0555
|
||||||
|
attr.Uid = d.root.uid
|
||||||
|
attr.Gid = d.root.gid
|
||||||
|
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
|
||||||
attr.Uid = uint32(os.Getuid())
|
|
||||||
attr.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
debug.Log("attr: %v", attr)
|
debug.Log("attr: %v", attr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -207,11 +201,9 @@ func (d *HostsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
func (d *TagsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
func (d *TagsDir) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
attr.Inode = d.inode
|
attr.Inode = d.inode
|
||||||
attr.Mode = os.ModeDir | 0555
|
attr.Mode = os.ModeDir | 0555
|
||||||
|
attr.Uid = d.root.uid
|
||||||
|
attr.Gid = d.root.gid
|
||||||
|
|
||||||
if !d.root.cfg.OwnerIsRoot {
|
|
||||||
attr.Uid = uint32(os.Getuid())
|
|
||||||
attr.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
debug.Log("attr: %v", attr)
|
debug.Log("attr: %v", attr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -437,11 +429,8 @@ func (l *snapshotLink) Readlink(ctx context.Context, req *fuse.ReadlinkRequest)
|
||||||
func (l *snapshotLink) Attr(ctx context.Context, a *fuse.Attr) error {
|
func (l *snapshotLink) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
a.Inode = l.inode
|
a.Inode = l.inode
|
||||||
a.Mode = os.ModeSymlink | 0777
|
a.Mode = os.ModeSymlink | 0777
|
||||||
|
a.Uid = l.root.uid
|
||||||
if !l.root.cfg.OwnerIsRoot {
|
a.Gid = l.root.gid
|
||||||
a.Uid = uint32(os.Getuid())
|
|
||||||
a.Gid = uint32(os.Getgid())
|
|
||||||
}
|
|
||||||
a.Atime = l.snapshot.Time
|
a.Atime = l.snapshot.Time
|
||||||
a.Ctime = l.snapshot.Time
|
a.Ctime = l.snapshot.Time
|
||||||
a.Mtime = l.snapshot.Time
|
a.Mtime = l.snapshot.Time
|
||||||
|
|
Loading…
Reference in a new issue