WORKSPACE: bump Linux to 5.15.2
This involves ripping out fsinfo because there now is quotactl_fd which
handles what we originally used fsinfo for. I also enabled a few new
interesting kernel features in the config like the Landlock LSM and
KFENCE.
Change-Id: Ic0a113893a437b2c8068d06984fdc386f34e6adb
Reviewed-on: https://review.monogon.dev/c/monogon/+/444
Reviewed-by: Sergiusz Bazanski <serge@monogon.tech>
diff --git a/metropolis/pkg/fsquota/BUILD.bazel b/metropolis/pkg/fsquota/BUILD.bazel
index dbeb19b..b25d812 100644
--- a/metropolis/pkg/fsquota/BUILD.bazel
+++ b/metropolis/pkg/fsquota/BUILD.bazel
@@ -3,10 +3,7 @@
go_library(
name = "go_default_library",
- srcs = [
- "fsinfo.go",
- "fsquota.go",
- ],
+ srcs = ["fsquota.go"],
importpath = "source.monogon.dev/metropolis/pkg/fsquota",
visibility = ["//metropolis:__subpackages__"],
deps = [
diff --git a/metropolis/pkg/fsquota/fsinfo.go b/metropolis/pkg/fsquota/fsinfo.go
deleted file mode 100644
index ecbaecf..0000000
--- a/metropolis/pkg/fsquota/fsinfo.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2020 The Monogon Project Authors.
-//
-// SPDX-License-Identifier: Apache-2.0
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package fsquota
-
-import (
- "fmt"
- "os"
- "unsafe"
-
- "golang.org/x/sys/unix"
-)
-
-// This requires fsinfo() support, which is not yet in any stable kernel. Our
-// kernel has that syscall backported. This would otherwise be an extremely
-// expensive operation and also involve lots of logic from our side.
-
-// From syscall_64.tbl
-const sys_fsinfo = 441
-
-// From uapi/linux/fsinfo.h
-const fsinfo_attr_source = 0x09
-const fsinfo_flags_query_path = 0x0000
-const fsinfo_flags_query_fd = 0x0001
-
-type fsinfoParams struct {
- resolveFlags uint64
- atFlags uint32
- flags uint32
- request uint32
- nth uint32
- mth uint32
-}
-
-func fsinfoGetSource(dir *os.File) (string, error) {
- buf := make([]byte, 256)
- params := fsinfoParams{
- flags: fsinfo_flags_query_fd,
- request: fsinfo_attr_source,
- }
- n, _, err := unix.Syscall6(sys_fsinfo, dir.Fd(), 0, uintptr(unsafe.Pointer(¶ms)), unsafe.Sizeof(params), uintptr(unsafe.Pointer(&buf[0])), 256)
- if err != unix.Errno(0) {
- return "", fmt.Errorf("failed to call fsinfo: %w", err)
- }
- return string(buf[:n-1]), nil
-}
diff --git a/metropolis/pkg/fsquota/fsquota.go b/metropolis/pkg/fsquota/fsquota.go
index 263dd48..0d49592 100644
--- a/metropolis/pkg/fsquota/fsquota.go
+++ b/metropolis/pkg/fsquota/fsquota.go
@@ -43,10 +43,6 @@
return err
}
defer dir.Close()
- source, err := fsinfoGetSource(dir)
- if err != nil {
- return err
- }
var valid uint32
if maxBytes > 0 {
valid |= quotactl.FlagBLimitsValid
@@ -69,7 +65,7 @@
// kernels setquota interface. Due to the short time window and
// infrequent calls this should not be an immediate issue.
for {
- quota, err := quotactl.GetNextQuota(source, quotactl.QuotaTypeProject, lastID)
+ quota, err := quotactl.GetNextQuota(dir, quotactl.QuotaTypeProject, lastID)
if err == unix.ENOENT || err == unix.ESRCH {
// We have enumerated all quotas, nothing exists here
break
@@ -102,7 +98,7 @@
// Always round up to the nearest block size
bytesLimitBlocks := uint64(math.Ceil(float64(maxBytes) / float64(1024)))
- return quotactl.SetQuota(source, quotactl.QuotaTypeProject, lastID, "actl.Quota{
+ return quotactl.SetQuota(dir, quotactl.QuotaTypeProject, lastID, "actl.Quota{
BHardLimit: bytesLimitBlocks,
BSoftLimit: bytesLimitBlocks,
IHardLimit: maxInodes,
@@ -126,10 +122,6 @@
return nil, err
}
defer dir.Close()
- source, err := fsinfoGetSource(dir)
- if err != nil {
- return nil, err
- }
attrs, err := fsxattrs.Get(dir)
if err != nil {
return nil, err
@@ -137,7 +129,7 @@
if attrs.ProjectID == 0 {
return nil, os.ErrNotExist
}
- quota, err := quotactl.GetQuota(source, quotactl.QuotaTypeProject, attrs.ProjectID)
+ quota, err := quotactl.GetQuota(dir, quotactl.QuotaTypeProject, attrs.ProjectID)
if err != nil {
return nil, err
}
diff --git a/metropolis/pkg/fsquota/quotactl/quotactl.go b/metropolis/pkg/fsquota/quotactl/quotactl.go
index 337daaa..08be6e0 100644
--- a/metropolis/pkg/fsquota/quotactl/quotactl.go
+++ b/metropolis/pkg/fsquota/quotactl/quotactl.go
@@ -21,6 +21,7 @@
import (
"fmt"
+ "os"
"unsafe"
"golang.org/x/sys/unix"
@@ -101,16 +102,12 @@
)
// QuotaOn turns quota accounting and enforcement on
-func QuotaOn(device string, qtype QuotaType, quotaFormat QuotaFormat, quotaFilePath string) error {
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return err
- }
+func QuotaOn(fd *os.File, qtype QuotaType, quotaFormat QuotaFormat, quotaFilePath string) error {
pathArg, err := unix.BytePtrFromString(quotaFilePath)
if err != nil {
return err
}
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_QUOTAON|uint(qtype)), uintptr(unsafe.Pointer(devArg)), uintptr(quotaFormat), uintptr(unsafe.Pointer(pathArg)), 0, 0)
+ _, _, err = unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_QUOTAON|uint(qtype)), uintptr(quotaFormat), uintptr(unsafe.Pointer(pathArg)), 0, 0)
if err != unix.Errno(0) {
return err
}
@@ -118,12 +115,8 @@
}
// QuotaOff turns quotas off
-func QuotaOff(device string, qtype QuotaType) error {
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_QUOTAOFF|uint(qtype)), uintptr(unsafe.Pointer(devArg)), 0, 0, 0, 0)
+func QuotaOff(fd *os.File, qtype QuotaType) error {
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_QUOTAOFF|uint(qtype)), 0, 0, 0, 0)
if err != unix.Errno(0) {
return err
}
@@ -131,13 +124,9 @@
}
// GetFmt gets the quota format used on given filesystem
-func GetFmt(device string, qtype QuotaType) (QuotaFormat, error) {
+func GetFmt(fd *os.File, qtype QuotaType) (QuotaFormat, error) {
var fmt uint32
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return 0, err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_GETFMT|uint(qtype)), uintptr(unsafe.Pointer(devArg)), 0, uintptr(unsafe.Pointer(&fmt)), 0, 0)
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETFMT|uint(qtype)), 0, uintptr(unsafe.Pointer(&fmt)), 0, 0)
if err != unix.Errno(0) {
return 0, err
}
@@ -145,13 +134,9 @@
}
// GetInfo gets information about quota files
-func GetInfo(device string, qtype QuotaType) (*DQInfo, error) {
+func GetInfo(fd *os.File, qtype QuotaType) (*DQInfo, error) {
var info DQInfo
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return nil, err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_GETINFO|uint(qtype)), uintptr(unsafe.Pointer(devArg)), 0, uintptr(unsafe.Pointer(&info)), 0, 0)
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETINFO|uint(qtype)), 0, uintptr(unsafe.Pointer(&info)), 0, 0)
if err != unix.Errno(0) {
return nil, err
}
@@ -159,12 +144,8 @@
}
// SetInfo sets information about quota files
-func SetInfo(device string, qtype QuotaType, info *DQInfo) error {
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_SETINFO|uint(qtype)), uintptr(unsafe.Pointer(devArg)), 0, uintptr(unsafe.Pointer(info)), 0, 0)
+func SetInfo(fd *os.File, qtype QuotaType, info *DQInfo) error {
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SETINFO|uint(qtype)), 0, uintptr(unsafe.Pointer(info)), 0, 0)
if err != unix.Errno(0) {
return err
}
@@ -172,13 +153,9 @@
}
// GetQuota gets user quota structure
-func GetQuota(device string, qtype QuotaType, id uint32) (*Quota, error) {
+func GetQuota(fd *os.File, qtype QuotaType, id uint32) (*Quota, error) {
var info Quota
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return nil, err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_GETQUOTA|uint(qtype)), uintptr(unsafe.Pointer(devArg)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
if err != unix.Errno(0) {
return nil, err
}
@@ -186,13 +163,9 @@
}
// GetNextQuota gets disk limits and usage > ID
-func GetNextQuota(device string, qtype QuotaType, id uint32) (*NextDQBlk, error) {
+func GetNextQuota(fd *os.File, qtype QuotaType, id uint32) (*NextDQBlk, error) {
var info NextDQBlk
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return nil, err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_GETNEXTQUOTA|uint(qtype)), uintptr(unsafe.Pointer(devArg)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETNEXTQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
if err != unix.Errno(0) {
return nil, err
}
@@ -200,12 +173,8 @@
}
// SetQuota sets the given quota
-func SetQuota(device string, qtype QuotaType, id uint32, quota *Quota) error {
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_SETQUOTA|uint(qtype)), uintptr(unsafe.Pointer(devArg)), uintptr(id), uintptr(unsafe.Pointer(quota)), 0, 0)
+func SetQuota(fd *os.File, qtype QuotaType, id uint32, quota *Quota) error {
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SETQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(quota)), 0, 0)
if err != unix.Errno(0) {
return fmt.Errorf("failed to set quota: %w", err)
}
@@ -214,13 +183,9 @@
// Sync syncs disk copy of filesystems quotas. If device is empty it syncs all
// filesystems.
-func Sync(device string) error {
- if device != "" {
- devArg, err := unix.BytePtrFromString(device)
- if err != nil {
- return err
- }
- _, _, err = unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_SYNC), uintptr(unsafe.Pointer(devArg)), 0, 0, 0, 0)
+func Sync(fd *os.File) error {
+ if fd != nil {
+ _, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SYNC), 0, 0, 0, 0)
if err != unix.Errno(0) {
return err
}