1

I wanted to set up an anacron task to run a backintime backup once a day (Ubuntu 20.04.3 LTS). If you schedule this using the backintime GUI, the normal crontab is being used, but for my use case this is not suitable: I usually have my computer on standby when I'm not using it, so the cronjob would just be discarded if I don't have the computer running at that exact scheduled time. What I did instead was create a script in the cron.daily directory, so that anacron takes care of it, which also supports delayed execution in case of standby or the computer being shut down for some time. I added the following command:

sudo -i -u samuel /usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 /usr/bin/backintime backup-job >/dev/null

This is exactly what backintime adds to the crontab, so I was sure it would work just fine when using anacron. But that's not the case: The job is started just fine, but the backup never finishes. The syslog output is the following:

backintime (samuel/1): INFO: Lock
backintime (samuel/1): WARNING: Inhibit Suspend failed.
backintime (samuel/1): INFO: mount ssh: [...]
backintime (samuel/1): INFO: Take a new snapshot. Profile: 1 Main profile
backintime (samuel/1): INFO: Call rsync to take the snapshot

[... around 10 seconds later ...]

anacron[1082]: Job `cron.daily' terminated (mailing output)
anacron[1082]: anacron: Can't find sendmail at /usr/sbin/sendmail, not mailing output
anacron[1082]: Can't find sendmail at /usr/sbin/sendmail, not mailing output
systemd[1]: anacron.service: Killing process 7920 (python3) with signal SIGKILL.
anacron[1082]: Normal exit (1 job run)
systemd[1]: anacron.service: Killing process 7958 (ssh-agent) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8107 (ssh) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8109 (sshfs) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8112 (python3) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8126 (rsync) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8127 (ssh) with signal SIGKILL.
systemd[1]: anacron.service: Killing process 8123 (QXcbEventQueue) with signal SIGKILL.
systemd[1]: anacron.service: Succeeded.

I find this situation rather weird, because why would anacron deliberately kill my processes? So what happens, as far as I interpret it, is that the command I'm executing in my backup script exits rather quickly, as its only task is to spin off some worker processes like python, ssh, rsync etc, and once they're running in the background, the launcher quits. So far so good, but anacron apparently thinks it's its duty to kill off all descendants of the original backup script once the script is done. But how can I prevent it from doing so? Do I really need to manually find out the descendant PIDs and wait for all of them to be done, before exiting the backup script?

I haven't found any info on this behavior online, so I would be glad if someone had any advice on how to proceed here.

2 Answers 2

2

Edit: The workaround below didn't work 100% of the time, so I went digging again and identified that the root cause is not anacron itself but rather its systemd configuration: Apparently systemd units can specify a kill mode that is used to clean up any spawned subprocesses once the main process is done. Anacron had this set to "mixed", and changing it to "none" successfully allows my backup task to run in the background. Be aware that for other kinds of anacron tasks disabling the killing of subprocesses might not be ideal, but for my use case it's exactly what I need.

Changing the kill mode can be done via sudo systemctl edit anacron.service and then entering the following configuration:

[Service]
KillMode=none

--

I'll leave the previous workaround for reference:

I found a more or less robust workaround for this situation: In my specific case, backintime does a remote backup via SSH. This is done by launching an sshfs process that takes care of mounting the backup location and exits once the backup is done. As such, the script can just wait for that process to start and finish again, in order to know when the backup is done:

sudo -i -u samuel /usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 /usr/bin/backintime backup-job >/dev/null

echo "Waiting for SSHFS to start"
until pids=$(pidof sshfs)
do
    sleep 1
done

echo "Waiting for backup to finish (SSHFS [$pids] to exit)"
while ps -p "$pids" >/dev/null 2>&1
do
    sleep 5
done

echo "SSHFS process gone, exiting"

This might not be the most elegant solution but at least it works nicely.

0

The way to leave processes running in the background and not to modify anacron or another service units is to use systemd-run utility. By default, it runs a program in new .service unit in clean and detached execution environment with ppid=1 and service type simple.

In your case, backintime creates child processes and then exits, so you should specify --service-type=forking or use --scope or -r option. More details about difference between the methods is in systemd-run and systemd.service manuals.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .