3 ms·
I don't understand. How is using ForkExec, Wait4 forcing you to use threads? What do you mean with "You basically can't do anything with file descriptors or con
by sebcat 11y ago
I don't understand. How is using ForkExec, Wait4 forcing you to use threads? What do you mean with "You basically can't do anything with file descriptors or containers at all with this model."? It is possible to pass a ProcAddr containing a SysProcAddr to ForkExec with fds, chroot, namespaces, &c.
Attached simple demo code of what I mean with ForkExec, Wait4.
EDIT: to clarify, the demo code is not intended to work like init, just to spawn a couple of processes and wait for them to terminate.
package main
import (
"log"
"syscall"
)
func main() {
cmds := [][]string{
{"/usr/bin/sleep", "4"},
{"/usr/bin/sleep", "5"},
{"/usr/bin/sleep", "1"},
{"/usr/bin/sleep", "2"},
}
for _, cmd := range cmds {
if len(cmd) > 0 {
if _, err := syscall.ForkExec(cmd[0], cmd, nil); err != nil {
log.Fatal(err)
}
}
}
for nwaited := 0; nwaited < len(cmds); nwaited++ {
var w syscall.WaitStatus
pid, err := syscall.Wait4(-1, &w, 0, nil)
if err != nil {
log.Println(err)
} else {
log.Println("pid", pid, "exited", w.Exited(), "exit status", w.ExitStatus())
}
}
}
- chubot 11y agoOK, I see that there is a lot of stuff like chroot and UIDs in SysProcAttr [1]. I think they have added a bunch since I last tried this. But the point still stands... you get a subset of the OS API. Everything has to be "canned" into that struct and you can't execute arbitrary code between fork and exec. Especially with containers, this is a never-ending target... They apparently have user namespaces, but what about network namespaces or IPC namespaces? [1] https://golang.org/src/syscall/exec_linux.go https://golang.org/src/syscall/exec_linux.go Now, it might be good enough for your application, and it probably IS good enough for everything except a full-fledged production quality init system. For that case I would be worried about running into limitations.
- sebcat 11y ago> Especially with containers, this is a never-ending target... They apparently have user namespaces, but what about network namespaces or IPC namespaces? There's no reason calls to e.g. unshare(2) and setns(2) can't be added to forkAndExecInChild in exec_linux.go like they have been added for the other syscalls needed to set up a child. I guess if anyone is reading this thread and wants that they can follow the guidelines for contributions and look at https://github.com/golang/go/issues/5968 https://github.com/golang/go/issues/5968 EDIT: It's also possible to supply CloneFlags though the SysProcAttr struct, e.g., CLONE_NEWIPC, CLONE_NEWNET.
- heavenlyhash 11y agoYou're free to argue that, but it's still fair for everyone to concede that there's a difference in friction between "I can do what I need, now" and "I have to wait for the language core to add features trailing discovering of these niche needs". Also, the subject's been raised before, and regrettably (IMO) the proposal rejected. As a result, you'll find a nontrivial amount of C appearing in e.g. the runc project. (Which is a crying shame, because it invoking cgo means runc ceased to be trivially reproducibly buildable, last time I checked...)