container/fhs: move pathname constants
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m6s
Test / Hpkg (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 4m29s
Test / Hakurei (race detector) (push) Successful in 3m5s
Test / Hakurei (push) Successful in 2m10s
Test / Flake checks (push) Successful in 1m21s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m6s
Test / Hpkg (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 4m29s
Test / Hakurei (race detector) (push) Successful in 3m5s
Test / Hakurei (push) Successful in 2m10s
Test / Flake checks (push) Successful in 1m21s
This allows referencing FHS pathnames without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(AutoEtcOp)) }
|
||||
@@ -13,7 +14,7 @@ func init() { gob.Register(new(AutoEtcOp)) }
|
||||
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||
func (f *Ops) Etc(host *check.Absolute, prefix string) *Ops {
|
||||
e := &AutoEtcOp{prefix}
|
||||
f.Mkdir(AbsFHSEtc, 0755)
|
||||
f.Mkdir(fhs.AbsEtc, 0755)
|
||||
f.Bind(host, e.hostPath(), 0)
|
||||
*f = append(*f, e)
|
||||
return f
|
||||
@@ -29,7 +30,7 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
}
|
||||
state.nonrepeatable |= nrAutoEtc
|
||||
|
||||
const target = sysrootPath + FHSEtc
|
||||
const target = sysrootPath + fhs.Etc
|
||||
rel := e.hostRel() + "/"
|
||||
|
||||
if err := k.mkdirAll(target, 0755); err != nil {
|
||||
@@ -44,7 +45,7 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
case ".host", "passwd", "group":
|
||||
|
||||
case "mtab":
|
||||
if err = k.symlink(FHSProc+"mounts", target+n); err != nil {
|
||||
if err = k.symlink(fhs.Proc+"mounts", target+n); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ func (e *AutoEtcOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *AutoEtcOp) hostPath() *check.Absolute { return AbsFHSEtc.Append(e.hostRel()) }
|
||||
func (e *AutoEtcOp) hostPath() *check.Absolute { return fhs.AbsEtc.Append(e.hostRel()) }
|
||||
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
||||
|
||||
func (e *AutoEtcOp) Is(op Op) bool {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(AutoRootOp)) }
|
||||
@@ -40,7 +41,7 @@ func (r *AutoRootOp) early(state *setupState, k syscallDispatcher) error {
|
||||
// careful: the Valid method is skipped, make sure this is always valid
|
||||
op := &BindMountOp{
|
||||
Source: r.Host.Append(name),
|
||||
Target: AbsFHSRoot.Append(name),
|
||||
Target: fhs.AbsRoot.Append(name),
|
||||
Flags: r.Flags,
|
||||
}
|
||||
if err = op.early(state, k); err != nil {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
"hakurei.app/container/seccomp"
|
||||
)
|
||||
|
||||
@@ -200,7 +201,7 @@ func (p *Container) Start() error {
|
||||
} else {
|
||||
p.cmd.Cancel = func() error { return p.cmd.Process.Signal(CancelSignal) }
|
||||
}
|
||||
p.cmd.Dir = FHSRoot
|
||||
p.cmd.Dir = fhs.Root
|
||||
p.cmd.SysProcAttr = &SysProcAttr{
|
||||
Setsid: !p.RetainSession,
|
||||
Pdeathsig: SIGKILL,
|
||||
@@ -316,7 +317,7 @@ func (p *Container) Serve() error {
|
||||
|
||||
// do not transmit nil
|
||||
if p.Dir == nil {
|
||||
p.Dir = AbsFHSRoot
|
||||
p.Dir = fhs.AbsRoot
|
||||
}
|
||||
if p.SeccompRules == nil {
|
||||
p.SeccompRules = make([]seccomp.NativeRule, 0)
|
||||
|
||||
41
container/fhs/abs.go
Normal file
41
container/fhs/abs.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package fhs
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *check.Absolute
|
||||
|
||||
var (
|
||||
// AbsRoot is [Root] as [check.Absolute].
|
||||
AbsRoot = unsafeAbs(Root)
|
||||
// AbsEtc is [Etc] as [check.Absolute].
|
||||
AbsEtc = unsafeAbs(Etc)
|
||||
// AbsTmp is [Tmp] as [check.Absolute].
|
||||
AbsTmp = unsafeAbs(Tmp)
|
||||
|
||||
// AbsRun is [Run] as [check.Absolute].
|
||||
AbsRun = unsafeAbs(Run)
|
||||
// AbsRunUser is [RunUser] as [check.Absolute].
|
||||
AbsRunUser = unsafeAbs(RunUser)
|
||||
|
||||
// AbsUsrBin is [UsrBin] as [check.Absolute].
|
||||
AbsUsrBin = unsafeAbs(UsrBin)
|
||||
|
||||
// AbsVar is [Var] as [check.Absolute].
|
||||
AbsVar = unsafeAbs(Var)
|
||||
// AbsVarLib is [VarLib] as [check.Absolute].
|
||||
AbsVarLib = unsafeAbs(VarLib)
|
||||
|
||||
// AbsDev is [Dev] as [check.Absolute].
|
||||
AbsDev = unsafeAbs(Dev)
|
||||
// AbsProc is [Proc] as [check.Absolute].
|
||||
AbsProc = unsafeAbs(Proc)
|
||||
// AbsSys is [Sys] as [check.Absolute].
|
||||
AbsSys = unsafeAbs(Sys)
|
||||
)
|
||||
38
container/fhs/fhs.go
Normal file
38
container/fhs/fhs.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// Package fhs provides constant and checked pathname values for common FHS paths.
|
||||
package fhs
|
||||
|
||||
const (
|
||||
// Root points to the file system root.
|
||||
Root = "/"
|
||||
// Etc points to the directory for system-specific configuration.
|
||||
Etc = "/etc/"
|
||||
// Tmp points to the place for small temporary files.
|
||||
Tmp = "/tmp/"
|
||||
|
||||
// Run points to a "tmpfs" file system for system packages to place runtime data, socket files, and similar.
|
||||
Run = "/run/"
|
||||
// RunUser points to a directory containing per-user runtime directories,
|
||||
// each usually individually mounted "tmpfs" instances.
|
||||
RunUser = Run + "user/"
|
||||
|
||||
// Usr points to vendor-supplied operating system resources.
|
||||
Usr = "/usr/"
|
||||
// UsrBin points to binaries and executables for user commands that shall appear in the $PATH search path.
|
||||
UsrBin = Usr + "bin/"
|
||||
|
||||
// Var points to persistent, variable system data. Writable during normal system operation.
|
||||
Var = "/var/"
|
||||
// VarLib points to persistent system data.
|
||||
VarLib = Var + "lib/"
|
||||
// VarEmpty points to a nonstandard directory that is usually empty.
|
||||
VarEmpty = Var + "empty/"
|
||||
|
||||
// Dev points to the root directory for device nodes.
|
||||
Dev = "/dev/"
|
||||
// Proc points to a virtual kernel file system exposing the process list and other functionality.
|
||||
Proc = "/proc/"
|
||||
// ProcSys points to a hierarchy below /proc/ that exposes a number of kernel tunables.
|
||||
ProcSys = Proc + "sys/"
|
||||
// Sys points to a virtual kernel file system exposing discovered devices and other functionality.
|
||||
Sys = "/sys/"
|
||||
)
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
. "syscall"
|
||||
"time"
|
||||
|
||||
"hakurei.app/container/fhs"
|
||||
"hakurei.app/container/seccomp"
|
||||
)
|
||||
|
||||
@@ -30,7 +31,7 @@ const (
|
||||
|
||||
it should be noted that none of this should become relevant at any point since the resulting
|
||||
intermediate root tmpfs should be effectively anonymous */
|
||||
intermediateHostPath = FHSProc + "self/fd"
|
||||
intermediateHostPath = fhs.Proc + "self/fd"
|
||||
|
||||
// setup params file descriptor
|
||||
setupEnv = "HAKUREI_SETUP"
|
||||
@@ -146,17 +147,17 @@ func initEntrypoint(k syscallDispatcher, msg Msg) {
|
||||
if err := k.setDumpable(SUID_DUMP_USER); err != nil {
|
||||
k.fatalf(msg, "cannot set SUID_DUMP_USER: %v", err)
|
||||
}
|
||||
if err := k.writeFile(FHSProc+"self/uid_map",
|
||||
if err := k.writeFile(fhs.Proc+"self/uid_map",
|
||||
append([]byte{}, strconv.Itoa(params.Uid)+" "+strconv.Itoa(params.HostUid)+" 1\n"...),
|
||||
0); err != nil {
|
||||
k.fatalf(msg, "%v", err)
|
||||
}
|
||||
if err := k.writeFile(FHSProc+"self/setgroups",
|
||||
if err := k.writeFile(fhs.Proc+"self/setgroups",
|
||||
[]byte("deny\n"),
|
||||
0); err != nil && !os.IsNotExist(err) {
|
||||
k.fatalf(msg, "%v", err)
|
||||
}
|
||||
if err := k.writeFile(FHSProc+"self/gid_map",
|
||||
if err := k.writeFile(fhs.Proc+"self/gid_map",
|
||||
append([]byte{}, strconv.Itoa(params.Gid)+" "+strconv.Itoa(params.HostGid)+" 1\n"...),
|
||||
0); err != nil {
|
||||
k.fatalf(msg, "%v", err)
|
||||
@@ -175,7 +176,7 @@ func initEntrypoint(k syscallDispatcher, msg Msg) {
|
||||
// cache sysctl before pivot_root
|
||||
lastcap := k.lastcap(msg)
|
||||
|
||||
if err := k.mount(zeroString, FHSRoot, zeroString, MS_SILENT|MS_SLAVE|MS_REC, zeroString); err != nil {
|
||||
if err := k.mount(zeroString, fhs.Root, zeroString, MS_SILENT|MS_SLAVE|MS_REC, zeroString); err != nil {
|
||||
k.fatalf(msg, "cannot make / rslave: %v", err)
|
||||
}
|
||||
|
||||
@@ -220,7 +221,7 @@ func initEntrypoint(k syscallDispatcher, msg Msg) {
|
||||
if err := k.pivotRoot(intermediateHostPath, hostDir); err != nil {
|
||||
k.fatalf(msg, "cannot pivot into intermediate root: %v", err)
|
||||
}
|
||||
if err := k.chdir(FHSRoot); err != nil {
|
||||
if err := k.chdir(fhs.Root); err != nil {
|
||||
k.fatalf(msg, "cannot enter intermediate root: %v", err)
|
||||
}
|
||||
|
||||
@@ -253,7 +254,7 @@ func initEntrypoint(k syscallDispatcher, msg Msg) {
|
||||
{
|
||||
var fd int
|
||||
if err := IgnoringEINTR(func() (err error) {
|
||||
fd, err = k.open(FHSRoot, O_DIRECTORY|O_RDONLY, 0)
|
||||
fd, err = k.open(fhs.Root, O_DIRECTORY|O_RDONLY, 0)
|
||||
return
|
||||
}); err != nil {
|
||||
k.fatalf(msg, "cannot open intermediate root: %v", err)
|
||||
@@ -271,7 +272,7 @@ func initEntrypoint(k syscallDispatcher, msg Msg) {
|
||||
if err := k.unmount(".", MNT_DETACH); err != nil {
|
||||
k.fatalf(msg, "cannot unmount intermediate root: %v", err)
|
||||
}
|
||||
if err := k.chdir(FHSRoot); err != nil {
|
||||
if err := k.chdir(fhs.Root); err != nil {
|
||||
k.fatalf(msg, "cannot enter root: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
. "syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
func init() { gob.Register(new(MountDevOp)) }
|
||||
@@ -49,7 +50,7 @@ func (d *MountDevOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
}
|
||||
if err := k.bindMount(
|
||||
state,
|
||||
toHost(FHSDev+name),
|
||||
toHost(fhs.Dev+name),
|
||||
targetPath,
|
||||
0,
|
||||
); err != nil {
|
||||
@@ -58,15 +59,15 @@ func (d *MountDevOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
}
|
||||
for i, name := range []string{"stdin", "stdout", "stderr"} {
|
||||
if err := k.symlink(
|
||||
FHSProc+"self/fd/"+string(rune(i+'0')),
|
||||
fhs.Proc+"self/fd/"+string(rune(i+'0')),
|
||||
path.Join(target, name),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, pair := range [][2]string{
|
||||
{FHSProc + "self/fd", "fd"},
|
||||
{FHSProc + "kcore", "core"},
|
||||
{fhs.Proc + "self/fd", "fd"},
|
||||
{fhs.Proc + "kcore", "core"},
|
||||
{"pts/ptmx", "ptmx"},
|
||||
} {
|
||||
if err := k.symlink(pair[0], path.Join(target, pair[1])); err != nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -67,7 +68,7 @@ func (f *Ops) Overlay(target, state, work *check.Absolute, layers ...*check.Abso
|
||||
// OverlayEphemeral appends an [Op] that mounts the overlay pseudo filesystem on [MountOverlayOp.Target]
|
||||
// with an ephemeral upperdir and workdir.
|
||||
func (f *Ops) OverlayEphemeral(target *check.Absolute, layers ...*check.Absolute) *Ops {
|
||||
return f.Overlay(target, AbsFHSRoot, nil, layers...)
|
||||
return f.Overlay(target, fhs.AbsRoot, nil, layers...)
|
||||
}
|
||||
|
||||
// OverlayReadonly appends an [Op] that mounts the overlay pseudo filesystem readonly on [MountOverlayOp.Target]
|
||||
@@ -85,7 +86,7 @@ type MountOverlayOp struct {
|
||||
lower []string
|
||||
// The upperdir is normally on a writable filesystem.
|
||||
//
|
||||
// If Work is nil and Upper holds the special value [AbsFHSRoot],
|
||||
// If Work is nil and Upper holds the special value [fhs.AbsRoot],
|
||||
// an ephemeral upperdir and workdir will be set up.
|
||||
//
|
||||
// If both Work and Upper are nil, upperdir and workdir is omitted and the overlay is mounted readonly.
|
||||
@@ -119,7 +120,7 @@ func (o *MountOverlayOp) Valid() bool {
|
||||
func (o *MountOverlayOp) early(_ *setupState, k syscallDispatcher) error {
|
||||
if o.Work == nil && o.Upper != nil {
|
||||
switch o.Upper.String() {
|
||||
case FHSRoot: // ephemeral
|
||||
case fhs.Root: // ephemeral
|
||||
o.ephemeral = true // intermediate root not yet available
|
||||
|
||||
default:
|
||||
@@ -174,10 +175,10 @@ func (o *MountOverlayOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
if o.ephemeral {
|
||||
var err error
|
||||
// these directories are created internally, therefore early (absolute, symlink, prefix, escape) is bypassed
|
||||
if o.upper, err = k.mkdirTemp(FHSRoot, intermediatePatternOverlayUpper); err != nil {
|
||||
if o.upper, err = k.mkdirTemp(fhs.Root, intermediatePatternOverlayUpper); err != nil {
|
||||
return err
|
||||
}
|
||||
if o.work, err = k.mkdirTemp(FHSRoot, intermediatePatternOverlayWork); err != nil {
|
||||
if o.work, err = k.mkdirTemp(fhs.Root, intermediatePatternOverlayWork); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -40,7 +41,7 @@ func (t *TmpfileOp) Valid() bool { return t != ni
|
||||
func (t *TmpfileOp) early(*setupState, syscallDispatcher) error { return nil }
|
||||
func (t *TmpfileOp) apply(state *setupState, k syscallDispatcher) error {
|
||||
var tmpPath string
|
||||
if f, err := k.createTemp(FHSRoot, intermediatePatternTmpfile); err != nil {
|
||||
if f, err := k.createTemp(fhs.Root, intermediatePatternTmpfile); err != nil {
|
||||
return err
|
||||
} else if _, err = f.Write(t.Data); err != nil {
|
||||
return err
|
||||
|
||||
@@ -59,7 +59,6 @@ const (
|
||||
FstypeNULL = zeroString
|
||||
// FstypeProc represents the proc pseudo-filesystem.
|
||||
// A fully visible instance of proc must be available in the mount namespace for proc to be mounted.
|
||||
// This filesystem type is usually mounted on [FHSProc].
|
||||
FstypeProc = "proc"
|
||||
// FstypeDevpts represents the devpts pseudo-filesystem.
|
||||
// This type of filesystem is usually mounted on /dev/pts.
|
||||
|
||||
@@ -8,90 +8,19 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/fhs"
|
||||
"hakurei.app/container/vfs"
|
||||
)
|
||||
|
||||
/* constants in this file bypass abs check, be extremely careful when changing them! */
|
||||
|
||||
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
|
||||
func unsafeAbs(_ string) *check.Absolute
|
||||
|
||||
const (
|
||||
// FHSRoot points to the file system root.
|
||||
FHSRoot = "/"
|
||||
// FHSEtc points to the directory for system-specific configuration.
|
||||
FHSEtc = "/etc/"
|
||||
// FHSTmp points to the place for small temporary files.
|
||||
FHSTmp = "/tmp/"
|
||||
|
||||
// FHSRun points to a "tmpfs" file system for system packages to place runtime data, socket files, and similar.
|
||||
FHSRun = "/run/"
|
||||
// FHSRunUser points to a directory containing per-user runtime directories,
|
||||
// each usually individually mounted "tmpfs" instances.
|
||||
FHSRunUser = FHSRun + "user/"
|
||||
|
||||
// FHSUsr points to vendor-supplied operating system resources.
|
||||
FHSUsr = "/usr/"
|
||||
// FHSUsrBin points to binaries and executables for user commands that shall appear in the $PATH search path.
|
||||
FHSUsrBin = FHSUsr + "bin/"
|
||||
|
||||
// FHSVar points to persistent, variable system data. Writable during normal system operation.
|
||||
FHSVar = "/var/"
|
||||
// FHSVarLib points to persistent system data.
|
||||
FHSVarLib = FHSVar + "lib/"
|
||||
// FHSVarEmpty points to a nonstandard directory that is usually empty.
|
||||
FHSVarEmpty = FHSVar + "empty/"
|
||||
|
||||
// FHSDev points to the root directory for device nodes.
|
||||
FHSDev = "/dev/"
|
||||
// FHSProc points to a virtual kernel file system exposing the process list and other functionality.
|
||||
FHSProc = "/proc/"
|
||||
// FHSProcSys points to a hierarchy below /proc/ that exposes a number of kernel tunables.
|
||||
FHSProcSys = FHSProc + "sys/"
|
||||
// FHSSys points to a virtual kernel file system exposing discovered devices and other functionality.
|
||||
FHSSys = "/sys/"
|
||||
)
|
||||
|
||||
var (
|
||||
// AbsFHSRoot is [FHSRoot] as [Absolute].
|
||||
AbsFHSRoot = unsafeAbs(FHSRoot)
|
||||
// AbsFHSEtc is [FHSEtc] as [Absolute].
|
||||
AbsFHSEtc = unsafeAbs(FHSEtc)
|
||||
// AbsFHSTmp is [FHSTmp] as [Absolute].
|
||||
AbsFHSTmp = unsafeAbs(FHSTmp)
|
||||
|
||||
// AbsFHSRun is [FHSRun] as [Absolute].
|
||||
AbsFHSRun = unsafeAbs(FHSRun)
|
||||
// AbsFHSRunUser is [FHSRunUser] as [Absolute].
|
||||
AbsFHSRunUser = unsafeAbs(FHSRunUser)
|
||||
|
||||
// AbsFHSUsrBin is [FHSUsrBin] as [Absolute].
|
||||
AbsFHSUsrBin = unsafeAbs(FHSUsrBin)
|
||||
|
||||
// AbsFHSVar is [FHSVar] as [Absolute].
|
||||
AbsFHSVar = unsafeAbs(FHSVar)
|
||||
// AbsFHSVarLib is [FHSVarLib] as [Absolute].
|
||||
AbsFHSVarLib = unsafeAbs(FHSVarLib)
|
||||
|
||||
// AbsFHSDev is [FHSDev] as [Absolute].
|
||||
AbsFHSDev = unsafeAbs(FHSDev)
|
||||
// AbsFHSProc is [FHSProc] as [Absolute].
|
||||
AbsFHSProc = unsafeAbs(FHSProc)
|
||||
// AbsFHSSys is [FHSSys] as [Absolute].
|
||||
AbsFHSSys = unsafeAbs(FHSSys)
|
||||
)
|
||||
|
||||
const (
|
||||
// Nonexistent is a path that cannot exist.
|
||||
// /proc is chosen because a system with covered /proc is unsupported by this package.
|
||||
Nonexistent = FHSProc + "nonexistent"
|
||||
Nonexistent = fhs.Proc + "nonexistent"
|
||||
|
||||
hostPath = FHSRoot + hostDir
|
||||
hostPath = fhs.Root + hostDir
|
||||
hostDir = "host"
|
||||
sysrootPath = FHSRoot + sysrootDir
|
||||
sysrootPath = fhs.Root + sysrootDir
|
||||
sysrootDir = "sysroot"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"hakurei.app/container/fhs"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -16,9 +18,9 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
kernelOverflowuidPath = FHSProcSys + "kernel/overflowuid"
|
||||
kernelOverflowgidPath = FHSProcSys + "kernel/overflowgid"
|
||||
kernelCapLastCapPath = FHSProcSys + "kernel/cap_last_cap"
|
||||
kernelOverflowuidPath = fhs.ProcSys + "kernel/overflowuid"
|
||||
kernelOverflowgidPath = fhs.ProcSys + "kernel/overflowgid"
|
||||
kernelCapLastCapPath = fhs.ProcSys + "kernel/cap_last_cap"
|
||||
)
|
||||
|
||||
func mustReadSysctl(msg Msg) {
|
||||
|
||||
Reference in New Issue
Block a user