container/op: merge mqueue and dev Ops
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m5s
Test / Hakurei (push) Successful in 2m54s
Test / Sandbox (race detector) (push) Successful in 3m58s
Test / Hpkg (push) Successful in 3m59s
Test / Hakurei (race detector) (push) Successful in 4m33s
Test / Flake checks (push) Successful in 1m19s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m5s
Test / Hakurei (push) Successful in 2m54s
Test / Sandbox (race detector) (push) Successful in 3m58s
Test / Hpkg (push) Successful in 3m59s
Test / Hakurei (race detector) (push) Successful in 4m33s
Test / Flake checks (push) Successful in 1m19s
There is no reason to mount mqueue anywhere else, and these Ops usually follow each other. This change merges them. This helps decrease IPC overhead and also enables mounting dev readonly. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
15170735ba
commit
14824b8a9b
@ -72,8 +72,7 @@ var containerTestCases = []struct {
|
|||||||
|
|
||||||
{"dev", true, true /* go test output is not a tty */, false, false,
|
{"dev", true, true /* go test output is not a tty */, false, false,
|
||||||
new(container.Ops).
|
new(container.Ops).
|
||||||
Dev("/dev").
|
Dev("/dev", true),
|
||||||
Mqueue("/dev/mqueue"),
|
|
||||||
[]*vfs.MountInfoEntry{
|
[]*vfs.MountInfoEntry{
|
||||||
ent("/", "/dev", "rw,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
ent("/", "/dev", "rw,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||||
ent("/null", "/dev/null", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
ent("/null", "/dev/null", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
@ -86,6 +85,21 @@ var containerTestCases = []struct {
|
|||||||
ent("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
|
ent("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
|
||||||
},
|
},
|
||||||
1971, 100, nil, 0, seccomp.PresetStrict},
|
1971, 100, nil, 0, seccomp.PresetStrict},
|
||||||
|
|
||||||
|
{"dev no mqueue", true, true /* go test output is not a tty */, false, false,
|
||||||
|
new(container.Ops).
|
||||||
|
Dev("/dev", false),
|
||||||
|
[]*vfs.MountInfoEntry{
|
||||||
|
ent("/", "/dev", "rw,nosuid,nodev,relatime", "tmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/null", "/dev/null", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/zero", "/dev/zero", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/full", "/dev/full", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/random", "/dev/random", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/urandom", "/dev/urandom", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/tty", "/dev/tty", "rw,nosuid", "devtmpfs", "devtmpfs", ignore),
|
||||||
|
ent("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,mode=620,ptmxmode=666"),
|
||||||
|
},
|
||||||
|
1971, 100, nil, 0, seccomp.PresetStrict},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContainer(t *testing.T) {
|
func TestContainer(t *testing.T) {
|
||||||
|
@ -180,27 +180,29 @@ func (p MountProcOp) String() string { return fmt.Sprintf("proc on %q", string(p
|
|||||||
func init() { gob.Register(new(MountDevOp)) }
|
func init() { gob.Register(new(MountDevOp)) }
|
||||||
|
|
||||||
// Dev appends an [Op] that mounts a subset of host /dev.
|
// Dev appends an [Op] that mounts a subset of host /dev.
|
||||||
func (f *Ops) Dev(dest string) *Ops {
|
func (f *Ops) Dev(dest string, mqueue bool) *Ops {
|
||||||
*f = append(*f, MountDevOp(dest))
|
*f = append(*f, &MountDevOp{dest, mqueue})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
type MountDevOp string
|
type MountDevOp struct {
|
||||||
|
Target string
|
||||||
|
Mqueue bool
|
||||||
|
}
|
||||||
|
|
||||||
func (d MountDevOp) early(*Params) error { return nil }
|
func (d *MountDevOp) early(*Params) error { return nil }
|
||||||
func (d MountDevOp) apply(params *Params) error {
|
func (d *MountDevOp) apply(params *Params) error {
|
||||||
v := string(d)
|
if !path.IsAbs(d.Target) {
|
||||||
if !path.IsAbs(v) {
|
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", d.Target))
|
||||||
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", v))
|
|
||||||
}
|
}
|
||||||
target := toSysroot(v)
|
target := toSysroot(d.Target)
|
||||||
|
|
||||||
if err := mountTmpfs(SourceTmpfsDevtmpfs, target, MS_NOSUID|MS_NODEV, 0, params.ParentPerm); err != nil {
|
if err := mountTmpfs(SourceTmpfsDevtmpfs, target, MS_NOSUID|MS_NODEV, 0, params.ParentPerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range []string{"null", "zero", "full", "random", "urandom", "tty"} {
|
for _, name := range []string{"null", "zero", "full", "random", "urandom", "tty"} {
|
||||||
targetPath := toSysroot(path.Join(v, name))
|
targetPath := path.Join(target, name)
|
||||||
if err := ensureFile(targetPath, 0444, params.ParentPerm); err != nil {
|
if err := ensureFile(targetPath, 0444, params.ParentPerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -247,7 +249,7 @@ func (d MountDevOp) apply(params *Params) error {
|
|||||||
if params.RetainSession {
|
if params.RetainSession {
|
||||||
var buf [8]byte
|
var buf [8]byte
|
||||||
if _, _, errno := Syscall(SYS_IOCTL, 1, TIOCGWINSZ, uintptr(unsafe.Pointer(&buf[0]))); errno == 0 {
|
if _, _, errno := Syscall(SYS_IOCTL, 1, TIOCGWINSZ, uintptr(unsafe.Pointer(&buf[0]))); errno == 0 {
|
||||||
consolePath := toSysroot(path.Join(v, "console"))
|
consolePath := path.Join(target, "console")
|
||||||
if err := ensureFile(consolePath, 0444, params.ParentPerm); err != nil {
|
if err := ensureFile(consolePath, 0444, params.ParentPerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -264,43 +266,27 @@ func (d MountDevOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.Mqueue {
|
||||||
|
mqueueTarget := path.Join(target, "mqueue")
|
||||||
|
if err := os.Mkdir(mqueueTarget, params.ParentPerm); err != nil {
|
||||||
|
return wrapErrSelf(err)
|
||||||
|
}
|
||||||
|
return wrapErrSuffix(Mount(SourceMqueue, mqueueTarget, FstypeMqueue, MS_NOSUID|MS_NOEXEC|MS_NODEV, zeroString),
|
||||||
|
"cannot mount mqueue:")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d MountDevOp) Is(op Op) bool { vd, ok := op.(MountDevOp); return ok && d == vd }
|
func (d *MountDevOp) Is(op Op) bool { vd, ok := op.(*MountDevOp); return ok && *d == *vd }
|
||||||
func (MountDevOp) prefix() string { return "mounting" }
|
func (*MountDevOp) prefix() string { return "mounting" }
|
||||||
func (d MountDevOp) String() string { return fmt.Sprintf("dev on %q", string(d)) }
|
func (d *MountDevOp) String() string {
|
||||||
|
if d.Mqueue {
|
||||||
func init() { gob.Register(new(MountMqueueOp)) }
|
return fmt.Sprintf("dev on %q with mqueue", d.Target)
|
||||||
|
|
||||||
// Mqueue appends an [Op] that mounts a private instance of mqueue.
|
|
||||||
func (f *Ops) Mqueue(dest string) *Ops {
|
|
||||||
*f = append(*f, MountMqueueOp(dest))
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
type MountMqueueOp string
|
|
||||||
|
|
||||||
func (m MountMqueueOp) early(*Params) error { return nil }
|
|
||||||
func (m MountMqueueOp) apply(params *Params) error {
|
|
||||||
v := string(m)
|
|
||||||
|
|
||||||
if !path.IsAbs(v) {
|
|
||||||
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", v))
|
|
||||||
}
|
}
|
||||||
|
return fmt.Sprintf("dev on %q", d.Target)
|
||||||
target := toSysroot(v)
|
|
||||||
if err := os.MkdirAll(target, params.ParentPerm); err != nil {
|
|
||||||
return wrapErrSelf(err)
|
|
||||||
}
|
|
||||||
return wrapErrSuffix(Mount(SourceMqueue, target, FstypeMqueue, MS_NOSUID|MS_NOEXEC|MS_NODEV, zeroString),
|
|
||||||
fmt.Sprintf("cannot mount mqueue on %q:", v))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MountMqueueOp) Is(op Op) bool { vm, ok := op.(MountMqueueOp); return ok && m == vm }
|
|
||||||
func (MountMqueueOp) prefix() string { return "mounting" }
|
|
||||||
func (m MountMqueueOp) String() string { return fmt.Sprintf("mqueue on %q", string(m)) }
|
|
||||||
|
|
||||||
func init() { gob.Register(new(MountTmpfsOp)) }
|
func init() { gob.Register(new(MountTmpfsOp)) }
|
||||||
|
|
||||||
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
||||||
|
@ -33,7 +33,7 @@ func TestContainer(t *testing.T) {
|
|||||||
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
|
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
|
||||||
return helper.New(ctx, os.Args[0], argsWt, stat, argF, func(z *container.Container) {
|
return helper.New(ctx, os.Args[0], argsWt, stat, argF, func(z *container.Container) {
|
||||||
setOutput(&z.Stdout, &z.Stderr)
|
setOutput(&z.Stdout, &z.Stderr)
|
||||||
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
|
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev", true)
|
||||||
}, nil)
|
}, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -118,7 +118,7 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev", true).
|
||||||
Bind("/bin", "/bin", 0).
|
Bind("/bin", "/bin", 0).
|
||||||
Bind("/usr/bin", "/usr/bin", 0).
|
Bind("/usr/bin", "/usr/bin", 0).
|
||||||
Bind("/nix/store", "/nix/store", 0).
|
Bind("/nix/store", "/nix/store", 0).
|
||||||
|
@ -46,7 +46,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Root("/", "4a450b6596d7bc15bd01780eb9a607ac", container.BindWritable).
|
Root("/", "4a450b6596d7bc15bd01780eb9a607ac", container.BindWritable).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev", true).
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Readonly("/var/run/nscd", 0755).
|
Readonly("/var/run/nscd", 0755).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
@ -180,7 +180,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Root("/", "ebf083d1b175911782d413369b64ce7c", container.BindWritable).
|
Root("/", "ebf083d1b175911782d413369b64ce7c", container.BindWritable).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev", true).
|
||||||
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Readonly("/var/run/nscd", 0755).
|
Readonly("/var/run/nscd", 0755).
|
||||||
|
@ -85,7 +85,7 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid
|
|||||||
Tmpfs(hst.Tmp, 1<<12, 0755)
|
Tmpfs(hst.Tmp, 1<<12, 0755)
|
||||||
|
|
||||||
if !s.Device {
|
if !s.Device {
|
||||||
params.Dev("/dev").Mqueue("/dev/mqueue")
|
params.Dev("/dev", true)
|
||||||
} else {
|
} else {
|
||||||
params.Bind("/dev", "/dev", container.BindWritable|container.BindDevice)
|
params.Bind("/dev", "/dev", container.BindWritable|container.BindDevice)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func Exec(ctx context.Context, p string) ([]*Entry, error) {
|
|||||||
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
||||||
z.Stdout = stdout
|
z.Stdout = stdout
|
||||||
z.Stderr = stderr
|
z.Stderr = stderr
|
||||||
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
|
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev", false)
|
||||||
|
|
||||||
if err := z.Start(); err != nil {
|
if err := z.Start(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user