NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.07k stars 14.12k forks source link

Systemd user timers will not start #22807

Closed joelmo closed 7 years ago

joelmo commented 7 years ago

Issue description

I have used systemds user times for a long time, now they are failing to start. I get this message: backup.timer: Failed to enter waiting state: Operation not permitted

This is the code from my config and there is an accompanying systemd.user.services.backup unit to this:

      systemd.user.timers.backup = {
        wantedBy = [ "default.target" ];
        timerConfig = {
          OnCalendar = "*-*-* 22:00:00";
          Persistent = "true";
          WakeSystem = "true";
        };
      };

Technical details

peterhoeg commented 7 years ago

You need to do wantedBy = [ "timers.target" ]; instead.

joelmo commented 7 years ago

I did the change but I get same error. Here is the generated unit:

~ $ systemctl --user cat backup.timer 
# /nix/store/qawfr7isradba1vxii7nn6n1a2fp24hf-unit-backup.timer/backup.timer
[Unit]

[Timer]
OnCalendar=*-*-* 22:00:00
Persistent=true
WakeSystem=true
peterhoeg commented 7 years ago

What does this give you: systemctl --user list-timers

joelmo commented 7 years ago

I have this test case. Looking at the log, seems like startAt used to be availible too, but now the option is not recognized.

    systemd.user.services.huhu = {
       description = "meh";
       wantedBy = [ "default.target" ];
       serviceConfig.ExecStart = "/bin/sh -c 'printf HUHU!'";
       # startAt = [ "*:*:0/30" "*:0/1:15" ];
    };

    systemd.user.timers.huhu = {
       wantedBy = [ "timers.target" ];
       timerConfig = {
          OnCalendar = "*-*-* 22:00:00";
          Persistent = "true";
          WakeSystem = "true";
       };
    };
~ $ systemctl --user list-timers --all
NEXT LEFT LAST PASSED UNIT       ACTIVATES
n/a  n/a  n/a  n/a    huhu.timer huhu.service
peterhoeg commented 7 years ago

That's super odd - I have a whole bunch of user timers running here although they all use OnBootSec and OnBootInactiveSec instead of OnCalendar:

systemd.user.timers."mbsync@" = {
  description = "Run mbsync every 5 minutes - %i";
  timerConfig = {
    OnBootSec = "10m";
    OnUnitInactiveSec = "5m";
    Unit = "mbsync@%i.service";
  };
};

Could you try that and see if you can get something running that way?

You do not need wantedBy = [ "default.target" ]; from the service definition. Not sure if that causes problems (like it refuses to activate a unit that is run unconditionally or something like that).

joelmo commented 7 years ago

After removing Persistent, WakeSystem it now works. I suspect that WakeSystem need special permission..

lucasew commented 1 year ago

I had this problem today and there is another detail that the timers you create at the moment are only enabled at the next login. Without relogging the timer will not appear in systemctl list-timers --user but if you pass --all too it will appear.

It's an easy fix though, just systemctl start the timer. Maybe it should be started automatically in activaction time.

cx405 commented 1 year ago

@joelmo @lucasew Your original code is perfectly ok. The reason for this timer to fail is because at some point you did this: systemctl --user enable backup.timer . This installs a COPY of the timer into ~/.config/systemd/user as a hook. This is the way of other OSes, but not NixOS. Because, the moment you do this, the old copy will persist in said directory and will permanently override any changes you do from configuration.nix. Regardless of changes you do to in configuration.nix, the old version of timer will override and spill same errors (if it had errors at the time of running enable command).

The solution is:

After reboot, your timer should work. No need to remove Persistent or WakeSystem.

To get which timers are run by the user do this: $ systemctl --user list-timers --all To get a list of all user-space timers/services on the machine, do this: $ ls -1 /nix/store/*-user-units/*.{timer,service} | less. This is where NixOS stores user timers/services, they are never invoked from within user directory (unless user makes his own, outside of configuration.nix).