diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-04-10 18:54:25 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-04-10 18:54:25 +0900 |
| commit | c806f43881223a85ad888f434e078dcc68de028d (patch) | |
| tree | 29e84efa3bc6466ad4f395d2f931d2d2e2468c28 /sandbox | |
| parent | 584405f7ccd4c8c0e63762e113f4650f2abd469e (diff) | |
sandbox: implement autoetc as setup op
This significantly reduces setup op count and the readdir call now happens in the context of the init process.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'sandbox')
| -rw-r--r-- | sandbox/ops.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/sandbox/ops.go b/sandbox/ops.go index 1f1d5a9a..fd56f617 100644 --- a/sandbox/ops.go +++ b/sandbox/ops.go @@ -440,3 +440,57 @@ func (f *Ops) PlaceP(name string, dataP **[]byte) *Ops { *f = append(*f, t) return f } + +func init() { gob.Register(new(AutoEtc)) } + +// AutoEtc creates a toplevel symlink mirror of a directory in sysroot with /etc semantics. +// This is not a generic setup op. It is implemented here to reduce ipc overhead. +type AutoEtc struct { + // this is an absolute path within sysroot + HostEtc string +} + +func (e *AutoEtc) early(*Params) error { return nil } +func (e *AutoEtc) apply(*Params) error { + if !path.IsAbs(e.HostEtc) { + return msg.WrapErr(syscall.EBADE, + fmt.Sprintf("path %q is not absolute", e.HostEtc)) + } + + const target = sysrootPath + "/etc/" + if err := os.MkdirAll(target, 0755); err != nil { + return wrapErrSelf(err) + } + + if d, err := os.ReadDir(toSysroot(e.HostEtc)); err != nil { + return wrapErrSelf(err) + } else { + for _, ent := range d { + n := ent.Name() + switch n { + case "passwd": + case "group": + + case "mtab": + if err = os.Symlink("/proc/mounts", target+n); err != nil { + return wrapErrSelf(err) + } + + default: + if err = os.Symlink(path.Join(e.HostEtc, n), target+n); err != nil { + return wrapErrSelf(err) + } + } + } + } + + return nil +} + +func (e *AutoEtc) Is(op Op) bool { + ve, ok := op.(*AutoEtc) + return ok && ((e == nil && ve == nil) || (e != nil && ve != nil && *e == *ve)) +} +func (*AutoEtc) prefix() string { return "setting up" } +func (e *AutoEtc) String() string { return fmt.Sprintf("auto etc via %s", e.HostEtc) } +func (f *Ops) Etc(host string) *Ops { *f = append(*f, &AutoEtc{host}); return f } |
