Systemd

編寫自己的守護程序。systemd 錯誤:無法從文件中讀取 PID:參數無效

  • June 22, 2014

我正在嘗試編寫自己的守護程序,一個非常簡單的 MPD(它是作業系統實驗室的工作)。我讓它工作:它開始像一個守護程序(ps的輸出):

1 14877 14877 14877 ?           -1 Ss       0   0:00 lab1_daemon

它播放,它得到信號。

問題是我無法使用 systemd 執行它。我寫了非常簡單的 .service 文件:

[Unit]
Description=Operating systems lab 1 daemon

[Service]
Type=forking
PIDFile=/run/lab1_daemon.pid
ExecStart=/path/lab1_daemon

[Install]
WantedBy=multi-user.target

但是當我執行守護程序時,systemctl start它會掛起 0.5 分鐘,然後在日誌中我看到:

Failed to read PID from file /run/lab1_daemon.pid: Invalid argument
lab1_daemon.service never wrote its PID file. Failing.

但它做到了!我檢查了它:

-rw-r--r-- 1 root root 13 Mar  5 00:13 /run/lab1_daemon.pid

我做錯了什麼?

PS:我什至嘗試daemon了功能來檢查,我確實正確地進行了守護程序。但我得到了同樣的結果。最小的原始碼(58 LOC,從 pastebin 移動):

#define _BSD_SOURCE
#define _GNU_SOURCE
#define _POSIX_C_SOURCE 199506L
#define _D_XOPEN_SOURCE 700

#define NAME "lab1_daemon"
#define PID_FILE_NAME "/run/" NAME ".pid"

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int lockfile(int fd)
{
       struct flock fl;
       fl.l_type = F_WRLCK;
       fl.l_start = 0;
       fl.l_whence = SEEK_SET;
       fl.l_len = 0;
       return fcntl(fd, F_SETLK, &fl);
}

bool is_already_running(char const *lock_file_name)
{
       int lock_file = open(lock_file_name, O_RDWR | O_CREAT,
                            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
       if (lock_file < 0)
               exit(1);

       if (lockfile(lock_file) < 0) {
               if (errno == EACCES || errno == EAGAIN) {
                       close(lock_file);
                       return true;
               }
               exit(1);
       }
       ftruncate(lock_file, 0);
       char buf[16];
       sprintf(buf, "PPID: %ld\n", (long)getpid());
       write(lock_file, buf, strlen(buf) + 1);
       return false;
}

int main(void)
{
       if (is_already_running(PID_FILE_NAME))
               exit(EXIT_FAILURE);
       daemon(0, 0);
       sleep(10);
       exit(EXIT_SUCCESS);
}

從 systemd 的文件中,我猜問題是您的 PID 文件格式不正確。而不是寫“PPID:yourpid ”。你應該只寫“ yourpid ”。順便說一下,PID 代表程序 ID,PPID 代表父程序 ID。您不能互換使用它們。

所以而不是

char buf[16];
sprintf(buf, "PPID: %ld\n", (long)getpid());
write(lock_file, buf, strlen(buf) + 1);

你應該做

fprintf(lock_file, "%ld\n", (long) getpid());

正如@samiam 在他的回答中所說,解鎖文件也是一個好習慣。

引用自:https://unix.stackexchange.com/questions/118132