I'm learning about container technologies of Linux and wrote a minimal container implementation on my own. I'm currently confused about consoles / terminals for container processes, as I'm "reusing" the controlling terminal as
/dev/console (instead of
c 5 1) in the container.
I determine the current terminal from
/proc/self/fd/2, read its device node (major and minor), and
mknod(2) using the discovered device nodes to create
/dev/console node in the container.
This appears fine when running a regular application like
/bin/sh as PID 1 (in PID namespace), but not when through an init system (I used BusyBox for this).
/etc/inittab for the BusyBox rootfs:
However, the shell spawned by init always complains
can't access tty; job control turned off. I also tried using the same host TTY node for
/dev/tty (instead of
c 5 0) but this problem still persists.
I looked into the source code of
systemd-nspawn and found that it creates a "forwarded pty", where the container runs on a new PTY that's "forwarded" to the host side. The code is too complex for my educational project so it's not viable for me.
How can I use the host terminal for the container?
Details: My container program
clone(2) only one child with flags =
CLONE_NEWGROUP | CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD, and the child sets up capabilities (blacklisting) and seccomp (whitelisting, syscall list taken from Docker), before
pivot_root(2) to the container rootfs and
execve(2) into the target application.
I'm currently experimenting on Linux 5.3 (Ubuntu 18.04 HWE), but I don't expect this to be different on any recent Linux versions.