ipartola / hawkeye

An simple and fast USB webcam MJPEG streaming server.
Other
205 stars 28 forks source link

Lockfile problem #17

Open hyppoCom opened 5 years ago

hyppoCom commented 5 years ago

When the daemon dies not gracefully, and the pid_file remains, the daemon cannot run again, as it founds the old pid_file. I solved this problem changing the write_pid function in daemon.c. Not it tries to lock the pid_file (in case it exists), and if it's not locked, it removes the old pid_file.

Attached you can find the patch to daemon.c hawkeye_lockfile_fix.patch.txt

--- daemon-2017.09.28.c 2017-09-28 21:55:03.000000000 +0200
+++ daemon.c    2018-09-27 23:27:49.416185223 +0200
@@ -10,6 +10,7 @@
 #include <pwd.h>
 #include <grp.h>
 #include <libgen.h>
+#include <sys/file.h>

 #include "memory.h"
 #include "daemon.h"
@@ -68,6 +69,17 @@
     nchown(pid_dir, user, group);
     free(pid_dir);

+       // before check if pidfile exists: if it's NOT locked the process is dead
+       if ((f = open(pid_file, O_RDONLY)) >= 0) {
+               // lockfile exists: check lock
+               if (flock(f, LOCK_EX|LOCK_NB) != 0) {
+                       panic("PID file existing and locked");
+               }
+               // Lock successful: the owner is dead, remove lockfile
+               close(f);
+               unlink(pid_file);
+       }
+
     if ((f = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 00644)) < 0) {
         if (errno == EEXIST) {
             panic("PID file already exists");
@@ -83,7 +95,10 @@
         panic("Could not write to PID file");
     }

-       close(f);
+       if (flock(f, LOCK_EX|LOCK_NB) != 0) {
+               panic("Can't lock PID file");
+       }
+       // DON'T close(f) to retain the lock till the program is running
 }

 void drop_privileges(const char *user, const char *group) {
kylethedeveloper commented 4 years ago

This must be applied definitely. Nice patch.