2
2
mirror of https://github.com/octoleo/restic.git synced 2024-05-28 14:40:49 +00:00
restic/internal/restic/node_xattr.go
Andrew Gunnerson 8c02ebb029
Add support for extended attributes on symlinks
Linux allows the use of non-`user.` extended attributes on symlinks. One
of the main users of this functionality is SELinux's `security.selinux`
xattr for storing a path's label. By storing symlink xattrs, restic is
now suitable for backing up the root filesystem on Linux distributions
that use SELinux.

This commit adds support for symlink xattrs when backing up data,
restoring data, and mounting snapshots via a fuse mount. All calls to
the xattr library have been updated to the use `L` variants of the
various functions, which always operate on the path given, without
following symlinks.

Fixes: #4375

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2023-06-19 14:37:31 -04:00

50 lines
1.1 KiB
Go

//go:build darwin || freebsd || linux || solaris
// +build darwin freebsd linux solaris
package restic
import (
"syscall"
"github.com/restic/restic/internal/errors"
"github.com/pkg/xattr"
)
// Getxattr retrieves extended attribute data associated with path.
func Getxattr(path, name string) ([]byte, error) {
b, err := xattr.LGet(path, name)
return b, handleXattrErr(err)
}
// Listxattr retrieves a list of names of extended attributes associated with the
// given path in the file system.
func Listxattr(path string) ([]string, error) {
l, err := xattr.LList(path)
return l, handleXattrErr(err)
}
// Setxattr associates name and data together as an attribute of path.
func Setxattr(path, name string, data []byte) error {
return handleXattrErr(xattr.LSet(path, name, data))
}
func handleXattrErr(err error) error {
switch e := err.(type) {
case nil:
return nil
case *xattr.Error:
// On Linux, xattr calls on files in an SMB/CIFS mount can return
// ENOATTR instead of ENOTSUP.
switch e.Err {
case syscall.ENOTSUP, xattr.ENOATTR:
return nil
}
return errors.WithStack(e)
default:
return errors.WithStack(e)
}
}