Systemd
編寫自己的守護程序。systemd 錯誤:無法從文件中讀取 PID:參數無效
我正在嘗試編寫自己的守護程序,一個非常簡單的 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 在他的回答中所說,解鎖文件也是一個好習慣。