pkg/system: return rich errors from L(g|s)etxattr

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider 2023-05-08 18:15:43 -04:00
parent ccd834ea25
commit 0cdfd5f275
2 changed files with 21 additions and 9 deletions

View file

@ -757,26 +757,26 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
}
}
var errors []string
var xattrErrs []string
for key, value := range hdr.Xattrs {
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
if err == syscall.ENOTSUP || err == syscall.EPERM {
if errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.EPERM) {
// We ignore errors here because not all graphdrivers support
// xattrs *cough* old versions of AUFS *cough*. However only
// ENOTSUP should be emitted in that case, otherwise we still
// bail.
// EPERM occurs if modifying xattrs is not allowed. This can
// happen when running in userns with restrictions (ChromeOS).
errors = append(errors, err.Error())
xattrErrs = append(xattrErrs, err.Error())
continue
}
return err
}
}
if len(errors) > 0 {
if len(xattrErrs) > 0 {
logrus.WithFields(logrus.Fields{
"errors": errors,
"errors": xattrErrs,
}).Warn("ignored xattrs in archive: underlying filesystem doesn't support them")
}

View file

@ -1,11 +1,19 @@
package system // import "github.com/docker/docker/pkg/system"
import "golang.org/x/sys/unix"
import (
"io/fs"
"golang.org/x/sys/unix"
)
// Lgetxattr retrieves the value of the extended attribute identified by attr
// and associated with the given path in the file system.
// It will returns a nil slice and nil error if the xattr is not set.
func Lgetxattr(path string, attr string) ([]byte, error) {
pathErr := func(err error) ([]byte, error) {
return nil, &fs.PathError{Op: "lgetxattr", Path: path, Err: err}
}
// Start with a 128 length byte array
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
@ -14,7 +22,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
// Buffer too small, use zero-sized buffer to get the actual size
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
return pathErr(errno)
}
dest = make([]byte, sz)
sz, errno = unix.Lgetxattr(path, attr, dest)
@ -24,7 +32,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
case errno == unix.ENODATA:
return nil, nil
case errno != nil:
return nil, errno
return pathErr(errno)
}
return dest[:sz], nil
@ -33,5 +41,9 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
// Lsetxattr sets the value of the extended attribute identified by attr
// and associated with the given path in the file system.
func Lsetxattr(path string, attr string, data []byte, flags int) error {
return unix.Lsetxattr(path, attr, data, flags)
err := unix.Lsetxattr(path, attr, data, flags)
if err != nil {
return &fs.PathError{Op: "lsetxattr", Path: path, Err: err}
}
return nil
}