|  | 
|  | 1 | +// Package syscallutil provdes addenda to golang.org/x/sys/unix | 
|  | 2 | +package syscallutil | 
|  | 3 | + | 
|  | 4 | +import ( | 
|  | 5 | +	"unsafe" | 
|  | 6 | + | 
|  | 7 | +	"golang.org/x/sys/unix" | 
|  | 8 | +) | 
|  | 9 | + | 
|  | 10 | +// nolint | 
|  | 11 | +const ( | 
|  | 12 | +	AT_EMPTY_PATH          = unix.AT_EMPTY_PATH | 
|  | 13 | +	AT_RECURSIVE           = 0x8000 // https://github.com/torvalds/linux/blob/v5.12/include/uapi/linux/fcntl.h#L112 | 
|  | 14 | +	AT_SYMLINK_NOFOLLOW    = unix.AT_SYMLINK_NOFOLLOW | 
|  | 15 | +	AT_NO_AUTOMOUNT        = unix.AT_NO_AUTOMOUNT | 
|  | 16 | +	MOUNT_ATTR_RDONLY      = 0x00000001 // https://github.com/torvalds/linux/blob/v5.12/include/uapi/linux/mount.h#L113 | 
|  | 17 | +	MOUNT_ATTR_NOSUID      = 0x00000002 | 
|  | 18 | +	MOUNT_ATTR_NODEV       = 0x00000004 | 
|  | 19 | +	MOUNT_ATTR_NOEXEC      = 0x00000008 | 
|  | 20 | +	MOUNT_ATTR__ATIME      = 0x00000070 | 
|  | 21 | +	MOUNT_ATTR_RELATIME    = 0x00000000 | 
|  | 22 | +	MOUNT_ATTR_NOATIME     = 0x00000010 | 
|  | 23 | +	MOUNT_ATTR_STRICTATIME = 0x00000020 | 
|  | 24 | +	MOUNT_ATTR_NODIRATIME  = 0x00000080 | 
|  | 25 | +	MOUNT_ATTR_IDMAP       = 0x00100000 | 
|  | 26 | +	MOUNT_ATTR_SIZE_VER0   = 32 // https://github.com/torvalds/linux/blob/v5.12/include/uapi/linux/mount.h#L135 | 
|  | 27 | +) | 
|  | 28 | + | 
|  | 29 | +// MountAttr corresponds to struct mount_attr, version 0, appeared in kernel 5.12. | 
|  | 30 | +// https://github.com/torvalds/linux/blob/v5.12/include/uapi/linux/mount.h#L124-L132 | 
|  | 31 | +type MountAttr struct { | 
|  | 32 | +	AttrSet     uint64 // __u64 attr_set | 
|  | 33 | +	AttrClr     uint64 // __u64 attr_clr | 
|  | 34 | +	Propagation uint64 // __u64 propagation | 
|  | 35 | +	UsernsFd    uint64 // __u64 userns_fd | 
|  | 36 | +} | 
|  | 37 | + | 
|  | 38 | +// MountSetattr is a wrapper for mount_setattr(2). | 
|  | 39 | +// | 
|  | 40 | +// int syscall(SYS_mount_setattr, int dirfd, const char *pathname, unsigned int flags, struct mount_attr *attr, size_t size); | 
|  | 41 | +// | 
|  | 42 | +// Requires kernel >= 5.12. | 
|  | 43 | +// https://man7.org/linux/man-pages/man2/mount_setattr.2.html | 
|  | 44 | +func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error { | 
|  | 45 | +	pathnamePtr, err := unix.BytePtrFromString(pathname) | 
|  | 46 | +	if err != nil { | 
|  | 47 | +		return err | 
|  | 48 | +	} | 
|  | 49 | +	_, _, errno := unix.Syscall6(unix.SYS_MOUNT_SETATTR, | 
|  | 50 | +		uintptr(dirfd), uintptr(unsafe.Pointer(pathnamePtr)), uintptr(flags), | 
|  | 51 | +		uintptr(unsafe.Pointer(attr)), unsafe.Sizeof(*attr), 0) | 
|  | 52 | +	if errno != 0 { | 
|  | 53 | +		return errno | 
|  | 54 | +	} | 
|  | 55 | +	return nil | 
|  | 56 | +} | 
0 commit comments