func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) { base := filepath.Base(path) dir := filepath.Dir(path) // if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay if base == WhiteoutOpaqueDir { if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil { return false, err } // don't write the file itself return false, nil } // if a file was deleted and we are using overlay, we need to create a character device if strings.HasPrefix(base, WhiteoutPrefix) { originalBase := base[len(WhiteoutPrefix):] originalPath := filepath.Join(dir, originalBase) if err := syscall.Mknod(originalPath, syscall.S_IFCHR, 0); err != nil { return false, err } if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil { return false, err } // don't write the file itself return false, nil } return true, nil }
// SetXAttr add an extended attribute to path with a write polciy specified // in the flags parameter. // The flags argument can be used to refine the semantics of the operation. // XATTR_CREATE specifies a pure create, which fails if the named attribute // exists already. // XATTR_REPLACE specifies a pure replace operation, which fails if the named // attribute does not already exist. // By default (no flags), the extended attribute will be created if need be, // or will simply replace the value if the attribute exists. func SetXAttr(path, name string, val []byte, flags int) error { err := syscall.Setxattr(path, name, val, flags) if err != nil { return err } return nil }
// Associates name and data together as an attribute of path. func Setxattr(path, name string, data []byte) error { name = userPrefix + name if err := syscall.Setxattr(path, name, data, 0); err != nil { return &XAttrError{"setxattr", path, name, err} } return nil }
func (constor *Constor) setdeleted(pathl string) error { stat := syscall.Stat_t{} err := syscall.Stat(pathl, &stat) if err != nil { fd, err := syscall.Creat(pathl, 0) if err != nil { return err } syscall.Close(fd) } return syscall.Setxattr(pathl, DELXATTR, []byte{49}, 0) }
func (a *FileAttr) WriteXAttr(p string) { if a.Attr == nil { return } var e EncodedAttr e.FromAttr(a.Attr) b := e.Encode(a.Hash) errno := syscall.Setxattr(p, _TERM_XATTR, b, 0) if errno != nil { log.Printf("Setxattr %s: code %v", p, errno) } }
func isXattrSupported() (result bool, err error) { result = true setXattrErr := syscall.Setxattr("/proc/self/exe", "user.test xattr", []byte("test xattr data"), 0) if setXattrErr != nil { errno := setXattrErr.(syscall.Errno) // syscall.Setxattr will return 'read-only filesystem' errors on a live-disc in live mode if errno == syscall.EOPNOTSUPP || errno == syscall.EROFS { result = false } else { err = setXattrErr } } return }
func (constor *Constor) createPath(dirpath string) error { dirs := strings.Split(dirpath, "/") if len(dirs) == 0 { return syscall.EIO } subdir := "" for _, dir := range dirs { if dir == "" { continue } subdir = Path.Join(subdir, "/", dir) li := constor.getLayer(subdir) if li == 0 { continue } if li == -1 { return syscall.EIO } stat := syscall.Stat_t{} if err := constor.Lstat(subdir, &stat); err != nil { return err } subdirl := Path.Join(constor.layers[0], subdir) if err := syscall.Mkdir(subdirl, stat.Mode); err != nil { return err } if err := syscall.Chown(subdirl, int(stat.Uid), int(stat.Gid)); err != nil { return err } if err := syscall.UtimesNano(subdirl, []syscall.Timespec{stat.Atim, stat.Mtim}); err != nil { return err } inoitoa := strconv.Itoa(int(stat.Ino)) inobyte := []byte(inoitoa) if err := syscall.Setxattr(subdirl, INOXATTR, inobyte, 0); err != nil { return err } inode, err := constor.inodemap.findInode(stat.Ino) if err != nil { return err } inode.Lock() inode.layer = 0 inode.Unlock() } return nil }
func setOrHasXattr(path, n, v string) error { if err := syscall.Setxattr(path, n, []byte(v), 1); err == nil { return nil } else if !os.IsExist(err) { return err } tab := make([]byte, 256) sz, err := syscall.Getxattr(path, n, tab) if err != nil { return err } if bytes.Equal([]byte(v), tab[:sz]) { return nil } else { return errors.New("XATTR mismatch") } }
func TestXAttrRead(t *testing.T) { nm := xattrFilename mountPoint, clean := xattrTestCase(t, nm) defer clean() mounted := filepath.Join(mountPoint, nm) attrs, err := listXAttr(mounted) readback := make(map[string][]byte) if err != nil { t.Error("Unexpected ListXAttr error", err) } else { for _, a := range attrs { val, err := readXAttr(mounted, a) if err != nil { t.Errorf("GetXAttr(%q) failed: %v", a, err) } readback[a] = val } } if len(readback) != len(xattrGolden) { t.Error("length mismatch", xattrGolden, readback) } else { for k, v := range readback { if bytes.Compare(xattrGolden[k], v) != 0 { t.Error("val mismatch", k, v, xattrGolden[k]) } } } err = syscall.Setxattr(mounted, "third", []byte("value"), 0) if err != nil { t.Error("Setxattr error", err) } val, err := readXAttr(mounted, "third") if err != nil || string(val) != "value" { t.Error("Read back set xattr:", err, string(val)) } syscall.Removexattr(mounted, "third") val, err = readXAttr(mounted, "third") if err != syscall.ENODATA { t.Error("Data not removed?", err, val) } }
func NewUidShiftingFilePermEditor(uidRange *user.UidRange) (FilePermissionsEditor, error) { if os.Geteuid() != 0 { return func(_ string, _, _ int, _ byte, _ os.FileInfo, _ map[string]string) error { // The files are owned by the current user on creation. // If we do nothing, they will remain so. return nil }, nil } return func(path string, uid, gid int, typ byte, fi os.FileInfo, xattr map[string]string) error { shiftedUid, shiftedGid, err := uidRange.ShiftRange(uint32(uid), uint32(gid)) if err != nil { return err } if err := os.Lchown(path, int(shiftedUid), int(shiftedGid)); err != nil { return err } // lchown(2) says that, depending on the linux kernel version, it // can change the file's mode also if executed as root. So call // os.Chmod after it. if typ != tar.TypeSymlink { if err := os.Chmod(path, fi.Mode()); err != nil { return err } } if typ == tar.TypeReg || typ == tar.TypeRegA { for k, v := range xattr { if !isXattrAllowed(k) { continue } err := syscall.Setxattr(path, k, []byte(v), 0) if err != nil { return err } } } return nil }, nil }
func isXattrSupported() (bool, error) { var err error if xattrvar { LogWriter.Debug("Running forced xattr mode") return true, err } result := true setXattrErr := syscall.Setxattr("/proc/self/exe", "user.test xattr", []byte("test xattr data"), 0) if setXattrErr != nil { errno := setXattrErr.(syscall.Errno) // syscall.Setxattr will return 'read-only filesystem' errors on a live-disc in live mode if errno == syscall.EOPNOTSUPP || errno == syscall.EROFS { result = false } else { err = setXattrErr } } return result, err }
// based on libacl's acl_set_file func setType(path, attr string, acl ACL) error { if attr == aclEADefault { fi, err := os.Stat(path) if err != nil { return err } // non-directories can't have default ACLs if !fi.IsDir() { return syscall.EACCES } } xattr, err := xattrFromACL(acl) if err != nil { return err } return syscall.Setxattr(path, attr, xattr, 0) }
func TestGetAllXattr(t *testing.T) { var ( err error testxattr = map[string]string{ "user.checksum": "asdfsf13434qwf1324", "user.random": "This is a test", } ) xattrFile, err := ioutil.TempFile("", "") if err != nil { t.Error(err) return } defer os.Remove(xattrFile.Name()) xattrFile.Close() xattrDir, err := ioutil.TempDir("", "") if err != nil { t.Error(err) return } defer os.Remove(xattrDir) for k, v := range testxattr { err = syscall.Setxattr(xattrFile.Name(), k, []byte(v), 0) if err == syscall.ENOTSUP { t.Log(err) return } if err != nil { t.Error(err) return } err = syscall.Setxattr(xattrDir, k, []byte(v), 0) if err == syscall.ENOTSUP { t.Log(err) return } if err != nil { t.Error(err) return } } // Test retrieval of extended attributes for regular files. h, err := GetAllXattr(xattrFile.Name()) if err != nil { t.Error(err) return } if h == nil { t.Errorf("Expected to find extended attributes but did not find any.") return } for k, v := range h { found, ok := h[k] if !ok || found != testxattr[k] { t.Errorf("Expected to find extended attribute %s with a value of %s on regular file but did not find it.", k, v) return } } // Test retrieval of extended attributes for directories. h, err = GetAllXattr(xattrDir) if err != nil { t.Error(err) return } if h == nil { t.Errorf("Expected to find extended attributes but did not find any.") return } for k, v := range h { found, ok := h[k] if !ok || found != testxattr[k] { t.Errorf("Expected to find extended attribute %s with a value of %s on directory but did not find it.", k, v) return } } }
func setWithXattr(path string, flags string) (err error) { err = syscall.Setxattr(path, "user.pax.flags", []byte(flags), 0) return }
// sets an attribute's value from bytes. func (this *FileXattribsNS) Set(tag string, data []byte) error { return syscall.Setxattr(this.File.Name(), this.namespace+ssep+tag, data, 0) }
// Setxattr calls syscall setxattr func Setxattr(path string, attr string, data []byte, flags int) (err error) { return syscall.Setxattr(path, attr, data, flags) }
func sysSetxattr(path string, attr string, val []byte, flag int) error { return syscall.Setxattr(path, attr, val, flag) }
func (fs *loopbackFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status { err := syscall.Setxattr(fs.GetPath(name), attr, data, flags) return fuse.ToStatus(err) }
func (b *Builder) createLayer(ids []string) (*ct.ImageLayer, error) { imageID := ids[len(ids)-1] layer, err := b.Store.Load(imageID) if err != nil { return nil, err } else if layer != nil { return layer, nil } // apply the docker layer diffs to a temporary directory dir, err := ioutil.TempDir("", "docker-layer-") if err != nil { return nil, err } defer os.RemoveAll(dir) for _, id := range ids { diff, err := b.Context.Diff(id, "") if err != nil { return nil, err } if err := archive.Untar(diff, dir, &archive.TarOptions{}); err != nil { return nil, err } // convert Docker AUFS whiteouts to overlay whiteouts. // // See the "whiteouts and opaque directories" section of the // OverlayFS documentation for a description of the whiteout // file formats: // https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.Mode().IsRegular() { return nil } base := filepath.Base(path) dir := filepath.Dir(path) if base == archive.WhiteoutOpaqueDir { if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil { return err } return os.Remove(path) } if !strings.HasPrefix(base, archive.WhiteoutPrefix) { return nil } // replace the file which the AUFS whiteout is hiding // with an overlay whiteout file, and remove the AUFS // whiteout name := filepath.Join(dir, strings.TrimPrefix(base, archive.WhiteoutPrefix)) if err := os.RemoveAll(name); err != nil { return err } if err := syscall.Mknod(name, syscall.S_IFCHR, 0); err != nil { return err } stat := info.Sys().(*syscall.Stat_t) if err := os.Chown(name, int(stat.Uid), int(stat.Gid)); err != nil { return err } return os.Remove(path) }) if err != nil { return nil, err } } // create the squashfs layer, with the root dir having 755 permissions if err := os.Chmod(dir, 0755); err != nil { return nil, err } path, layer, err := b.mksquashfs(dir) if err != nil { return nil, err } return layer, b.Store.Save(imageID, path, layer) }
func (w *RealFileWriter) SetAttr(n string, v []byte) error { err := syscall.Setxattr(w.path, n, v, 0) return err }
func setWithXattr(path string, flags string) error { flags = checkEmulTramp(flags) err := syscall.Setxattr(path, "user.pax.flags", []byte(flags), 0) return err }
func setxattr(path, key string, value []byte, flags int) error { return syscall.Setxattr(path, key, value, flags) }