Bug 79497 - RFE: Add StopUnit= support to timers
Summary: RFE: Add StopUnit= support to timers
Status: RESOLVED WONTFIX
Alias: None
Product: systemd
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: systemd-bugs
QA Contact: systemd-bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-01 05:57 UTC by Jim Carter
Modified: 2014-06-04 13:18 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description Jim Carter 2014-06-01 05:57:58 UTC
This is with systemd-208 from OpenSuSE-13.1 package systemd-208-19.1.x86_64
Systemd units are all in /etc/systemd/system .
They are appended at the end of this report.  

baobei.automount starts at boot. If you do "ls /baobei", baobei.mount runs.
baobei.mount does mount the filesystem.  Also starts baobei-umount.timer
The timer triggers immediately but fails to unmount because /baobei is busy.
5 minutes later (more or less), baobei-umount.service ran and unmounted it.
And baobei-umount.timer was stopped.  

10 mins later, "ls /baobei", it gets mounted, baobei-umount.timer started.
The timer triggers immediately but fails to unmount because it's busy.
30 secs later, "umount /baobei", it was unmounted, baobei-umount.timer stopped.
90 secs later, "ls /baobei", it gets mounted,
    baobei-umount.timer was started, baobei-umount.service was NOT executed.
180 secs later,  baobei-umount.service was started and
    successfully unmounted /baobei.  baobei-umount.timer was stopped.

The 180 secs is 300 secs after baobei-umount.service was previously 
started (and didn't unmount /baobei because it was busy).  

The man page for systemd.timer says:
If a timer configured with OnBootSec= or OnStartupSec= is already
in the past when the timer unit is activated, it will immediately
elapse and the configured unit is started. This is not the case for
timers defined in the other directives.

Evidently the last statement is not presently operative. 

What I would like the developers to do: Once again prevent the timer 
from triggering if one of its contingencies is true at startup.  

The following is actually a feature request, to get the developers
thinking about how some people want to use timers.  
A common use-case for the timer is to stop a unit, rather than to 
start it.  If the timer had a StopUnit option, baobei-umount.service
would not be needed.  But if you stop baobei.mount and the mount point
is busy, I assume something reasonable happens.  

I tried hard to set up socket activation for cups (printing), but failed. 
I wanted cups to be stopped a certain time after being started, but the 
timer triggered immediately and the killer service killed cups which had
just been started.  It seems bizarre for the killer service to exec
"systemd stop cups.service".  I tried a Conflicts contingency, but was
not able to get it to work right.  If the timer could do the StopUnit
thing, life would be a lot simpler.  

The real autofs daemon unmounts unused filesystems after a configured
time.  If systemd's automount unit had an auto-unmount timer, a lot of
this complication could be avoided.  In fact, the same is true for 
socket units, for which you can assume that the underlying service is
unused if no packets go through its socket.  A race condition needs to 
be worked around, if systemd declares a unit unused and stops it, but
after committing to stop, the automount reports access or the socket
receives a packet.  

James F. Carter          Voice 310 825 2897    FAX 310 206 6673
UCLA-Mathnet;  6115 MSA; 520 Portola Plaza; Los Angeles, CA, USA  90095-1555
Email: jimc@math.ucla.edu    http://www.math.ucla.edu/~jimc (q.v. for PGP key)


Systemd units:
=-=-= baobei.automount -- Starts baobei.mount when the mount point 
	is referred to.

[Unit]
Description=Automount Baobei's virtual disc

[Automount]
Where=/baobei

[Install]
WantedBy=local-fs.target

=-=-= baobei.mount -- Actually mounts the filesystem.

[Unit]
Description=Mount Baobei's virtual disc

[Mount]
What=/dev/sda7
Where=/baobei
Type=ntfs
Options=ro,loop,offset=103424K,umask=222,uid=alice

=-=-= baobei-umount.timer -- Try to unmount the filesystem after 5 minutes.

[Unit]
Description=Delays before auto-unmounting Baobei's virtual disc

# When baobei.mount is started or stopped by systemd operations, this unit 
# is started/stopped too.  
PartOf=baobei.mount

# If baobei.mount stops for any reason, this one stops too, e.g. if you
# manually umount /baobei.  If this unit is started explicitly, baobei.mount
# will be too (same as Requires).
BindsTo=baobei.mount

After=baobei.mount

[Timer]
OnActiveSec=300
OnUnitActiveSec=300

# Unit=baobei-umount.service (is the default and is recommended)

[Install]
WantedBy=baobei.mount

=-=-= baobei-umount.service -- Actually unmounts the disc.

[Unit]
Description=Unmounts Baobei's virtual disc

[Service]
Type=oneshot

ExecStart=/usr/bin/umount /baobei

# This is the return code of umount if the mtpt is not mounted or is busy.
SuccessExitStatus=32
Comment 1 David Strauss 2014-06-04 13:18:39 UTC
> If the timer had a StopUnit option, baobei-umount.service
would not be needed.

Please don't use timers to shut down units after a guess a how long it takes for them to go idle. It's not safe and never will be.

> I tried hard to set up socket activation for cups (printing), but failed. 
I wanted cups to be stopped a certain time after being started, but the 
timer triggered immediately and the killer service killed cups which had
just been started.

Fedora ships with CUPS using socket activation, so it definitely works. If CUPS should shut down on idle, that needs to be taken up with the CUPS project, not systemd.

> If systemd's automount unit had an auto-unmount timer, a lot of
this complication could be avoided.

There is already a TODO ("automount: implement expire") for automount units to support unmount-on-idle, which is already implemented in the underlying autofs layer, as you note.

> In fact, the same is true for socket units, for which you can assume that the underlying service is unused if no packets go through its socket.

No, you cannot assume that. Your example service, CUPS, is a counterexample given that a brief connection requesting a huge print job could occupy the daemon for hours.

> A race condition needs to be worked around, if systemd declares a unit unused and stops it, but after committing to stop, the automount reports access or the socket receives a packet.

This should already be handled for socket activation. systemd resumes watching for incoming data when stopping the service, allowing for immediate reactivation after shutdown completes.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.