Monday, November 8, 2021

Systemd Failed to Enable Unit?

When I attempt to enable the service using sytemd, I encounter an error where systemd complains that the server does not exists. For example, this is what I observe when I try to enable the OpenVPN service.


$ systemctl enable openvpn@server
Failed to enable unit: Unit file openvpn@server does not exist

This means that I miss the service configuration file. But which one and where should the file be? Although I don't know much about systemd, I resolve this issue by using strace. Using the OpenVPN service as an example, I do the following,

  1. Run strace on the systemd process, i.e.,
    
        sudo sh -c 'strace -p 1 2>&1 | tee strace_systemd.log'
        
  2. Next, run systemctl enable for the OpenVPN service,
    
    	sudo systemctl enable openvpn@server
    	
  3. Examine strace_systemd.log. For this, we search the service name, e.g., openvpn, in it. In this example, we see,
    
    ......
    recvmsg(25, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="/org/freedesktop/systemd1\0\0\0\0\0\0\0"..., iov_len=200}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) = 200 
    getuid()                                = 0   
    openat(AT_FDCWD, "/etc/systemd/system.control/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/system.control/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/transient/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/generator.early/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/etc/systemd/system/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/system/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/generator/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/local/lib/systemd/system/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/systemd/system/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/generator.late/openvpn@server.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/etc/systemd/system.control/openvpn@.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/system.control/openvpn@.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/transient/openvpn@.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/run/systemd/generator.early/openvpn@.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/etc/systemd/system/openvpn@.service", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    ...
    
    sendmsg(25, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\3\1\0015\0\0\0\1\0\0\0g\0\0\0\5\1u\0\1\0\0\0\4\1s\0#\0\0\0"..., iov_len=120}, {iov_base="0\0\0\0Unit file openvpn@server.ser"..., iov_len=53}], msg_iovlen=2, msg_controllen=0, msg_flags=0}, MSG_DONTWAIT|MSG_NOSIGNAL) = 173
        
    where systemd complains that it cannot find the configuration file of the service at these locations.
  4. Luckily, I do locate a configuration file in the system, e.g.,
    $ sudo find /etc -name openvpn\* /etc/systemd/system/multi-user.target.wants/openvpn@server.service /etc/openvpn $
  5. Thus, to fix this issue is to create a link to the OpenVPN service configuration file in the /etc/systemd/system/ directory where systemd is searching for the file based on the output of the strace command,
    sudo ln -s /usr/lib/systemd/system/openvpn-server\@.service /etc/systemd/system/openvpn@server.service

The systemctl enable is successful after the above.

No comments:

Post a Comment