stopping a systemd service when starting another

2

1

I have written a simple zram.service file that will set up compressed swap space for me to avoid chewing too much om my disks. The zram have higher priority than the other swap devices.

The problem is that when I try to hibernate my system it will write the system state to swap which in this case is zram, and since the content of memory is lost when power disappears this of course don't work.

The solution is to stop my zram.service before executing systemctl hibernate, and start it again when the system is back up.

As far as I have found out systemctl hibernate starts the /lib/systemd/system/systemd-hibernate.service. I have copied this service to /etc/systemd/system/ to override it, and I can probably get this working by using the 'ExecStartPost=' stanza, but I think there must be a better way stopping a systemd service when another one is started and vice versa.

Edit: the working zram service on a Debian system for those interested

[Unit]
Description=ZRAM swap
Conflicts=hibernate.service

[Service]
Environment=ZRAM_MEM=1G
Environment=ZRAM_CMPALGO=lz4
Environment=ZRAM_CMPSTREAMS=2


Type=oneshot
User=root
ExecStartPre=/bin/sh -c "/sbin/modprobe zram num_devices=1"
ExecStartPre=/bin/sh -c "echo $ZRAM_CMPALGO >/sys/block/zram0/comp_algorithm"
ExecStartPre=/bin/sh -c "echo $ZRAM_CMPSTREAMS >/sys/block/zram0/max_comp_streams"
ExecStartPre=/bin/sh -c "echo $ZRAM_MEM > /sys/block/zram0/disksize"
ExecStartPre=/bin/sh -c "/sbin/mkswap /dev/zram0"
ExecStart=/sbin/swapon /dev/zram0 -p 10

ExecStop=/sbin/swapoff /dev/zram0
ExecStop=/bin/echo 1 > /sys/block/zram0/reset
ExecStop=/sbin/rmmod zram

RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Waxhead

Posted 2016-03-05T11:35:24.693

Reputation: 1 092

Answers

4

Define Conflicts= in the systemd unit file.

From the systemd.unit manpage:

Conflicts=

A space-separated list of unit names. Configures negative requirement dependencies. If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa. Note that this setting is independent of and orthogonal to the After= and Before= ordering dependencies.

If a unit A that conflicts with a unit B is scheduled to be started at the same time as B, the transaction will either fail (in case both are required part of the transaction) or be modified to be fixed (in case one or both jobs are not a required part of the transaction). In the latter case, the job that is not the required will be removed, or in case both are not required, the unit that conflicts will be started and the unit that is conflicted is stopped.

Shuangistan

Posted 2016-03-05T11:35:24.693

Reputation: 281