Add a locker to run only one service
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 17 Oct 2019 16:06:44 +0000 (18:06 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 17 Oct 2019 16:07:24 +0000 (18:07 +0200)
Change-Id: Iedec0340cb08f9eaa81967fb28a8b0e7f2c44603
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/main-cynagorad.c

index db5408d..4a90cc0 100644 (file)
@@ -35,6 +35,7 @@
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/file.h>
 #include <sys/capability.h>
 
 #if defined(WITH_SYSTEMD_ACTIVATION)
@@ -61,6 +62,9 @@
 #if !defined(DEFAULT_CYNAGORA_GROUP)
 #    define  DEFAULT_CYNAGORA_GROUP  NULL
 #endif
+#if !defined(DEFAULT_LOCKFILE)
+#    define  DEFAULT_LOCKFILE      ".cynagora-lock"
+#endif
 
 #define _DBDIR_       'd'
 #define _GROUP_       'g'
@@ -143,6 +147,7 @@ versiontxt[] =
 
 static int isid(const char *text);
 static void ensure_directory(const char *path, int uid, int gid);
+static int lockdir(const char *dir);
 
 int main(int ac, char **av)
 {
@@ -316,6 +321,13 @@ int main(int ac, char **av)
        cap_clear(caps);
        rc = cap_set_proc(caps);
 
+       /* get lock for the database */
+       rc = lockdir(dbdir);
+       if (rc < 0) {
+               fprintf(stderr, "can not lock database of directory %s: %m\n", dbdir);
+               return 1;
+       }
+
        /* connection to the database */
        rc = db_open(dbdir);
        if (rc < 0) {
@@ -457,3 +469,22 @@ static void ensure_directory(const char *path, int uid, int gid)
        ensuredir(p, (int)l, uid, gid);
 }
 
+static int lockdir(const char *dir)
+{
+       char path[PATH_MAX];
+       int fd, rc;
+
+       rc = snprintf(path, sizeof path, "%s/%s", dir, DEFAULT_LOCKFILE);
+       if (rc >= (int)sizeof path) {
+               rc = -1;
+               errno = ENAMETOOLONG;
+       } else if (rc >= 0) {
+               rc = open(path, O_RDWR|O_CREAT, 0600);
+               if (rc >= 0) {
+                       fd = rc;
+                       rc = flock(fd, LOCK_EX|LOCK_NB);
+               }
+       }
+       return rc;
+}
+