Systemd Drop-In Configuration: Why PIDFile Directive Fails to Create /var/run/machined.pid


4 views

When working with systemd drop-in configurations, a common pitfall occurs when trying to create PID files through the PIDFile directive. Let's examine why your 10-machined-pid-file.conf might not be behaving as expected.

First, let's verify your current setup. The configuration you shared contains a typo - [Serivce] should be [Service]:

[Service]
PIDFile=/var/run/machined.pid
ExecReload=/bin/kill -HUP $MAINPID

Contrary to what many believe, the PIDFile directive doesn't automatically create the PID file. It merely tells systemd where to look for it and where to write it when the service properly terminates. The actual creation should be handled by:

  • The service itself (systemd-machined in this case)
  • A custom ExecStartPre script
  • Proper directory permissions

Here's how to diagnose and fix the issue:

# Check if the service actually uses the PID file
sudo strace -p $(pgrep systemd-machi) -e trace=file

# Verify directory permissions
ls -ld /var/run/
sudo chmod 755 /var/run

# Alternative approach using tmpfiles.d
echo "d /var/run/machined 0755 root root" | sudo tee /etc/tmpfiles.d/machined.conf
sudo systemd-tmpfiles --create

If systemd-machined doesn't natively support PID file creation, consider these workarounds:

[Service]
# Solution 1: Pre-create the file
ExecStartPre=/bin/bash -c 'echo $$ > /var/run/machined.pid'

# Solution 2: Use RuntimeDirectory
RuntimeDirectory=machined
PIDFile=/run/machined/machined.pid

After making changes, always:

sudo systemctl daemon-reload
sudo systemctl restart systemd-machined
journalctl -u systemd-machined --no-pager -n 30

When configuring systemd services, the PIDFile directive serves a specific purpose that's often misunderstood. It doesn't automatically create the PID file - rather, it tells systemd where to look for the process ID file that the service itself should create.

[Service]
Type=simple
PIDFile=/var/run/machined.pid
ExecStart=/usr/lib/systemd/systemd-machined

First, let's ensure your drop-in file is properly formatted and recognized:

# Check merged unit configuration
systemd-analyze cat-config systemd/systemd-machined.service

# Verify the drop-in is loaded
systemd-detect-virt --container || systemctl show -p DropInPaths systemd-machined.service

The service executable (systemd-machined in this case) must actually create the PID file. Many services implement this through:

// Example of C code that creates PID file
FILE *pidfile = fopen("/var/run/machined.pid", "w");
if (pidfile) {
    fprintf(pidfile, "%d\n", getpid());
    fclose(pidfile);
}

If modifying the service isn't an option, consider these workarounds:

# Method 1: Use ExecStartPost
[Service]
ExecStartPost=/bin/sh -c 'echo $MAINPID > /var/run/machined.pid'

# Method 2: Create a wrapper script
#!/bin/bash
echo $$ > /var/run/machined.pid
exec /usr/lib/systemd/systemd-machined "$@"

Ensure proper permissions exist for the PID file location:

# Modern systems may use /run instead of /var/run
ls -ld /run /var/run
stat -c "%a %U:%G" /var/run

# Set up tmpfiles.d configuration if needed
echo "d /var/run/machined 0755 root root -" > /etc/tmpfiles.d/machined.conf
systemd-tmpfiles --create

To verify what's actually happening during service startup:

# Increase logging level
systemctl set-environment SYSTEMD_LOG_LEVEL=debug
journalctl -fu systemd-machined

# Check if the service actually attempts to create the file
strace -f -e trace=file -o /tmp/machined.strace systemctl start systemd-machined