[systemd-devel] How to get systemd to leave a USB serial console session alone when hadware is pulled?

Kaz Kylheku kaz at kylheku.com
Tue May 21 15:17:23 PDT 2013


On Thu, 16 May 2013 19:58:35 +0400, Andrey Borzenkov
<arvidjaar at gmail.com> wrote:
> В Wed, 15 May 2013 21:19:38 -0700
> Kaz Kylheku <kaz at kylheku.com> пишет:
> 
>>
>> Can you at least tell me how to get agetty to start on a system
>> that does not have my patch, when a USB-Serial converter is
>> inserted which is marked as a console?
>>
> 
> The usual stanza is to use in your udev rules
> 
> TAG+="systemd", ENV{SYSTEMD_WANTS}+="getty at ttyUSB0.service"
> 
> You probably can also check whether device is marked as console
> (whatever it means) in the same rule.
> 
> TAG is likely to be already present for serial devices.

Hi Andrey,

Thank you very much for this hint in the right direction,
it was helfpul. I have made a lot of progress with this, 
including additional kernel work, and only one more issue
remains (to my knowledge so far, pending more testing).
In all other respects, it works ideally, as I envisioned
it.

One thing which was causing a problem that I had the USB
serial console declared on the kernel command line as the
rightmost console entry. If it is the rightmost console, then
it gets special treatment from systemd (which is entirely
justified, since the rightmost console device which is present
also gets special treament from the system: for instance
the /dev/console tty device always binds to the rightmost
console that is up.)  In this case, if we have an additional
udev rule to do the getty service, it conflicts with built in
systemd behavior.  The solution is not to have the USB serial
as the rightmost console (which means it cannot be the only
console: but that makes sense: we should not have a device that
can be removed as the only console!)

Now then, I have added two sysfs attributes to USB serial
devices which make it easier to write accurate udev rules.

My udev rule looks like this:

SUBSYSTEM=="tty", KERNEL=="ttyUSB[0-9]", ATTRS{is_console}=="1",
ATTRS{reinserted}=="0", TAG+="systemd",
ENV{SYSTEMD_WANTS}+="getty@%k.service"

We only launch agetty when a ttyUSB device appears which is
a console, and is not a re-insertion.

The "reinserted" property is only set when the device is
reinserted and a TTY session is recovered.  If there is
completely a fresh start, then this property goes back
to zero.

The agetty killing behavior is prevented by setting
KillMode = none in the getty service, so when the device
is pulled and re-inserted, the shell session is intact.

***

So now only one issue remains.   If I have s shell session
open and during that session I pull the tty serial device
and plug it back in, and then log out of that session,
systemd does not serve up agetty. The shell logs out and
then the console goes unresponsive with no program monitoring
it.

The workaround is, at that point, to unplug the device
and plug it back in. This will trigger a udev event (with
the "reinserted"  attribute equal to "0": since no TTY session is
being recovered: nothing has the TTY open). The custom udev
rule fires, and systemd serves up an agetty.

systemd seems to be reacting to the device removal event,
and basically goes into a state in which it thinks the device is
gone, which is correct.  Moreover, since KillMode = none
is in effect, it does not turf the associated session. However,
it does not notice that the device is reinserted.
When that session exits spontaneously due to a logout,
systemd still thinks the device is not there any more,
and so does not re-start the agetty.

I suspect that this cannot be "configured away", but will
require a patch to systemd. Though it's only a minor issue now.
The users can just be trained to do a pull and re-insert as
a workaround when a login prompt does not appear.

Compared to the great convenience of how everything works now,
it's nothing.

Thanks again for the tip ...


More information about the systemd-devel mailing list