From dba896b9a0ca7cbe4fb379017672bd44a0a77ef0 Mon Sep 17 00:00:00 2001
From: dimitri staessens <dimitri.staessens@intec.ugent.be>
Date: Fri, 17 Jun 2016 15:55:23 +0200
Subject: irmd, lib: use shm_du_map as lockfile.

Added the pid of the irmd to the shm_du_map. The IRMd will check for
an existing shm_du_map. If there is an existing file, it will exit if
the owner IRMd is running or remove it if the owner IRMd is not
running.

Also simplifies calculation of the shm_du_map pointers and corrects
exiting calls for the IRMd.

Fixes #8.
---
 include/ouroboros/shm_du_map.h |  2 ++
 src/irmd/main.c                | 30 +++++++++++++++++++-----------
 src/lib/shm_du_map.c           | 24 +++++++++++++++---------
 3 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/include/ouroboros/shm_du_map.h b/include/ouroboros/shm_du_map.h
index cc1e8869..081a6f62 100644
--- a/include/ouroboros/shm_du_map.h
+++ b/include/ouroboros/shm_du_map.h
@@ -37,6 +37,7 @@
 #endif
 
 #include "common.h"
+#include <sys/types.h>
 
 struct shm_du_buff;
 struct shm_du_map;
@@ -45,6 +46,7 @@ struct shm_du_map  * shm_du_map_create();
 struct shm_du_map  * shm_du_map_open();
 void                 shm_du_map_close(struct shm_du_map * dum);
 void                 shm_du_map_destroy(struct shm_du_map * dum);
+pid_t                shm_du_map_owner(struct shm_du_map * dum);
 
 /* returns the index of the buffer in the DU map */
 ssize_t  shm_create_du_buff(struct shm_du_map * dum,
diff --git a/src/irmd/main.c b/src/irmd/main.c
index c20d63db..87625205 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1555,11 +1555,20 @@ static struct irm * irm_create()
                 return NULL;
 
         if (access("/dev/shm/" SHM_DU_MAP_FILENAME, F_OK) != -1) {
-                LOG_ERR("IRM daemon is running in this system.");
-                LOG_ERR("If you think this message is in error,");
-                LOG_ERR("please remove /dev/shm/" SHM_DU_MAP_FILENAME);
-                LOG_ERR("(root privileges required) or reboot your system.");
-                return NULL;
+                struct shm_du_map * dum = shm_du_map_open();
+                if (dum == NULL) {
+                        LOG_ERR("Could not examine existing shm file.");
+                        exit(EXIT_FAILURE);
+                }
+                if (kill(shm_du_map_owner(dum), 0) < 0) {
+                        LOG_INFO("IRMd didn't properly shut down last time.");
+                        shm_du_map_destroy(dum);
+                        LOG_INFO("Stale shm file removed.");
+                } else {
+                        LOG_WARN("IRMd already running, exiting.");
+                        free(i);
+                        exit(EXIT_SUCCESS);
+                }
         }
 
         i->threadpool = malloc(sizeof(pthread_t) * IRMD_THREADPOOL_SIZE);
@@ -1621,19 +1630,18 @@ int main()
         sig_act.sa_flags     = SA_SIGINFO;
 
         if (sigaction(SIGINT,  &sig_act, NULL) < 0)
-                exit(1);
+                exit(EXIT_FAILURE);
         if (sigaction(SIGTERM, &sig_act, NULL) < 0)
-                exit(1);
+                exit(EXIT_FAILURE);
         if (sigaction(SIGHUP,  &sig_act, NULL) < 0)
-                exit(1);
+                exit(EXIT_FAILURE);
         if (sigaction(SIGPIPE, &sig_act, NULL) < 0)
-                exit(1);
+                exit(EXIT_FAILURE);
 
         instance = irm_create();
         if (instance == NULL)
                 return 1;
 
-
         pthread_create(&instance->cleanup_flows, NULL, irm_flow_cleaner, NULL);
 
         for (t = 0; t < IRMD_THREADPOOL_SIZE; ++t)
@@ -1647,5 +1655,5 @@ int main()
 
         irm_destroy(instance);
 
-        return 0;
+        exit(EXIT_SUCCESS);
 }
diff --git a/src/lib/shm_du_map.c b/src/lib/shm_du_map.c
index f63ce32d..0ce6bdcd 100644
--- a/src/lib/shm_du_map.c
+++ b/src/lib/shm_du_map.c
@@ -34,7 +34,7 @@
 
 #define SHM_BLOCKS_SIZE (SHM_BLOCKS_IN_MAP * SHM_DU_BUFF_BLOCK_SIZE)
 #define SHM_FILE_SIZE (SHM_BLOCKS_SIZE + 2 * sizeof (size_t)                   \
-                       + sizeof(pthread_mutex_t))
+                       + sizeof(pthread_mutex_t)) + sizeof(pid_t)
 
 #define get_head_ptr(dum)                                                      \
 ((struct shm_du_buff *)(dum->shm_base + (*dum->ptr_head *                      \
@@ -71,6 +71,7 @@ struct shm_du_map {
         size_t *          ptr_head;    /* start of ringbuffer head */
         size_t *          ptr_tail;    /* start of ringbuffer tail */
         pthread_mutex_t * shm_mutex;   /* lock all free space in shm */
+        pid_t *           pid;         /* pid of the irmd owner */
         int               fd;
 };
 
@@ -126,10 +127,9 @@ struct shm_du_map * shm_du_map_create()
         dum->shm_base = shm_base;
         dum->ptr_head = (size_t *)
                 ((uint8_t *) dum->shm_base + SHM_BLOCKS_SIZE);
-        dum->ptr_tail = (size_t *)
-                ((uint8_t *) dum->ptr_head + sizeof(size_t));
-        dum->shm_mutex = (pthread_mutex_t *)
-                ((uint8_t *) dum->ptr_tail + sizeof(size_t));
+        dum->ptr_tail = dum->ptr_head + 1;
+        dum->shm_mutex = (pthread_mutex_t *) (dum->ptr_tail + 1);
+        dum->pid = (pid_t *) (dum->shm_mutex + 1);
 
         pthread_mutexattr_init(&attr);
         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
@@ -138,6 +138,8 @@ struct shm_du_map * shm_du_map_create()
         *dum->ptr_head = 0;
         *dum->ptr_tail = 0;
 
+        *dum->pid = getpid();
+
         dum->fd = shm_fd;
 
         return dum;
@@ -181,16 +183,20 @@ struct shm_du_map * shm_du_map_open()
         dum->shm_base = shm_base;
         dum->ptr_head = (size_t *)
                 ((uint8_t *) dum->shm_base + SHM_BLOCKS_SIZE);
-        dum->ptr_tail = (size_t *)
-                ((uint8_t *) dum->ptr_head + sizeof(size_t));
-        dum->shm_mutex = (pthread_mutex_t *)
-                ((uint8_t *) dum->ptr_tail + sizeof(size_t));
+        dum->ptr_tail = dum->ptr_head + 1;
+        dum->shm_mutex = (pthread_mutex_t *) (dum->ptr_tail + 1);
+        dum->pid = (pid_t *) (dum->shm_mutex + 1);
 
         dum->fd = shm_fd;
 
         return dum;
 }
 
+pid_t shm_du_map_owner(struct shm_du_map * dum)
+{
+        return *dum->pid;
+}
+
 void shm_du_map_close(struct shm_du_map * dum)
 {
         if (dum == NULL) {
-- 
cgit v1.2.3