There are several ways a process might be killed because of a dying terminal.
The first way is that the terminal driver in the kernel sends a SIGHUP signal to the controlling process for which the terminal is the controlling terminal. In most cases, the controlling process is the shell that is initially started in the terminal, and its controlling terminal is the one that its stdin, stdout and stderr are connected to. A process becomes disconnected from the controlling terminal if it calls setsid
.
The second way is that the shell, when it receives SIGHUP, re-sends that signal to its subprocesses — more precisely, to its background jobs. Some shells (ksh, bash, zsh) have a disown
builtin to tell the shell not to send a SIGHUP to a particular job.
If the terminal goes away and a program tries to read from it, it is notified of an end-of-file condition (or possibly EIO for a background job). If the terminal goes away and a program tries to write to it, the write returns with an EIO error. These might cause the program to exit.
So what su
changes here is that (2) would normally cause the initial shell to kill the background job, but since that background process is running as a different user, the signal cannot be delivered, and the background process lives on.
systemd-nspawn
handles permissions for devices through cgroups. By default, any container is granted with permissions only for common devices like /dev/null
, /dev/zero
, etc, and additionally to any device passed directly to --bind
argument like --bind=/dev/vcs
. This won't work with USB because /dev/bus/usb
is a directory.
To grant permission for currently running container named my_container
(supposedly you started it with systemd-nspawn
directly from command line) execute as root:
$ echo 'c 189:* rwm' > \
/sys/fs/cgroup/devices/machine.slice/machine-my_container/devices.allow
c 189:* rwm
means read write modify permissions for any character device with type (identificator) 189 and any subtype. You can find type and subtype of device with file
:
$ file /dev/bus/usb/002/002
This permission will only last while container is running.
If you are using systemd-nspawn@.service
or want to persist permissions with it, create
/etc/systemd/system/systemd-nspawn@.service.d/override.conf
or
/etc/systemd/system/systemd-nspawn@my_container.service.d/override.conf
(depending on whether you want access to USB from any systemd-nspawn
container or only from my_container
correspondingly) with the following content:
[Service]
DeviceAllow=char-usb_device rwm
usb_device
is an alias. You can find other in /proc/devices
.
Best Answer
Ok, so, for what it's worth, the following was successful for me:
Practically identical to yours, except I don't give the
machine
a name and I get an-x
ephemeral btrfs snapshot of my/
for the container's root.That brought up the container's
getty
on my terminal's pty and I logged in tologin
and all.I confess I was a bit stumped for a little while, but after a little poking at
systemctl
in the container w/zsh
<tab> completion I came up with (run from within the container):Which got the machine to surrender its terminal control. The only thing is, I started that with
sudo
- which also gets its own layer of terminal control to authenticate in the first place. This left me with a blank terminal, and no amount ofkill -CONT "$(pgrep ksh)"
was doing me any good. And so I was again stumped for a moment or two, but (in another terminal)...Gave me the above list, and so I thought - what the hell?
And - lo and behold - I had
ksh
back in the original terminal. To wrap it up, I needed to verify I could still access themachine
, though, of course, else it would be useless:Ok...
And I got another
getty
on another terminal!