summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2016-07-06 19:04:04 +0200
committerSander Vrijders <sander.vrijders@intec.ugent.be>2016-07-06 19:04:04 +0200
commitb7696a17688bc338ac150f8d5ffd0b59c3206f77 (patch)
treeec2f2b03efcecf2946286ebb3b6f4580f0865dea /src/irmd
parent4a3e3f1b9eef457f3f216d2b2a4ccf0a32eb9599 (diff)
parent90c3c96b5c9b1e4db6bb6d1894a21aec54a965b1 (diff)
downloadouroboros-b7696a17688bc338ac150f8d5ffd0b59c3206f77.tar.gz
ouroboros-b7696a17688bc338ac150f8d5ffd0b59c3206f77.zip
Merge remote-tracking branch 'upstream/be' into be
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/main.c145
-rw-r--r--src/irmd/registry.c12
-rw-r--r--src/irmd/registry.h12
3 files changed, 121 insertions, 48 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index ddce2d61..ff129b71 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -51,7 +51,7 @@
#include <pthread.h>
#include <sys/stat.h>
#include <dirent.h>
-#include <getopt.h>
+#include <sys/wait.h>
#define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */
@@ -68,35 +68,42 @@ enum irm_state {
IRMD_SHUTDOWN
};
+struct spawned_api {
+ struct list_head next;
+ pid_t api;
+};
+
/* keeps track of port_id's between N and N - 1 */
struct port_map_entry {
struct list_head next;
- int port_id;
+ int port_id;
- pid_t n_api;
- pid_t n_1_api;
+ pid_t n_api;
+ pid_t n_1_api;
- pthread_cond_t res_signal;
- pthread_mutex_t res_lock;
+ pthread_cond_t res_signal;
+ pthread_mutex_t res_lock;
- enum flow_state state;
+ enum flow_state state;
- struct timespec t0;
+ struct timespec t0;
};
struct irm {
/* FIXME: list of ipcps could be merged into the registry */
- struct list_head ipcps;
+ struct list_head ipcps;
+
+ struct list_head registry;
+ pthread_rwlock_t reg_lock;
- struct list_head registry;
- pthread_rwlock_t reg_lock;
+ struct list_head spawned_apis;
/* keep track of all flows in this processing system */
- struct bmp * port_ids;
+ struct bmp * port_ids;
/* maps port_ids to api pair */
- struct list_head port_map;
- pthread_rwlock_t flows_lock;
+ struct list_head port_map;
+ pthread_rwlock_t flows_lock;
enum irm_state state;
struct shm_du_map * dum;
@@ -104,8 +111,8 @@ struct irm {
int sockfd;
pthread_rwlock_t state_lock;
- pthread_t cleanup_flows;
- pthread_t shm_sanitize;
+ pthread_t cleanup_flows;
+ pthread_t shm_sanitize;
} * instance = NULL;
static struct port_map_entry * port_map_entry_create()
@@ -262,9 +269,13 @@ static pid_t get_ipcp_by_dst_name(char * dst_name,
static pid_t create_ipcp(char * name,
enum ipcp_type ipcp_type)
{
- pid_t api;
+ struct spawned_api * api;
struct ipcp_entry * tmp = NULL;
+ api = malloc(sizeof(*api));
+ if (api == NULL)
+ return -ENOMEM;
+
pthread_rwlock_rdlock(&instance->state_lock);
if (instance->state != IRMD_RUNNING) {
@@ -272,8 +283,8 @@ static pid_t create_ipcp(char * name,
return -1;
}
- api = ipcp_create(ipcp_type);
- if (api == -1) {
+ api->api = ipcp_create(ipcp_type);
+ if (api->api == -1) {
pthread_rwlock_unlock(&instance->state_lock);
LOG_ERR("Failed to create IPCP.");
return -1;
@@ -287,7 +298,7 @@ static pid_t create_ipcp(char * name,
INIT_LIST_HEAD(&tmp->next);
- tmp->api = api;
+ tmp->api = api->api;
tmp->name = strdup(name);
if (tmp->name == NULL) {
ipcp_entry_destroy(tmp);
@@ -301,12 +312,30 @@ static pid_t create_ipcp(char * name,
list_add(&tmp->next, &instance->ipcps);
+ list_add(&api->next, &instance->spawned_apis);
+
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
- LOG_INFO("Created IPCP %d.", api);
+ LOG_INFO("Created IPCP %d.", api->api);
- return api;
+ return api->api;
+}
+
+static void clear_spawned_api(pid_t api)
+{
+ struct list_head * pos = NULL;
+ struct list_head * n = NULL;
+
+ list_for_each_safe(pos, n, &(instance->spawned_apis)) {
+ struct spawned_api * a =
+ list_entry(pos, struct spawned_api, next);
+
+ if (api == a->api) {
+ list_del(&a->next);
+ free(a);
+ }
+ }
}
static int destroy_ipcp(pid_t api)
@@ -322,6 +351,7 @@ static int destroy_ipcp(pid_t api)
list_entry(pos, struct ipcp_entry, next);
if (api == tmp->api) {
+ clear_spawned_api(api);
if (ipcp_destroy(api))
LOG_ERR("Could not destroy IPCP.");
list_del(&tmp->next);
@@ -717,8 +747,9 @@ static struct port_map_entry * flow_accept(pid_t api,
}
if (!reg_entry_has_api(rne, api)) {
- rgi = registry_add_ap_instance(&instance->registry,
- rne->name, api);
+ rgi = registry_add_api_name(&instance->registry,
+ api,
+ rne->name);
if (rgi == NULL) {
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
@@ -802,7 +833,7 @@ static int flow_alloc_resp(pid_t n_api,
pthread_mutex_lock(&rne->state_lock);
- registry_remove_ap_instance(&instance->registry, rne->name, n_api);
+ registry_remove_api_name(&instance->registry, n_api, rne->name);
pthread_mutex_unlock(&rne->state_lock);
@@ -1036,9 +1067,8 @@ static pid_t auto_execute(char ** argv)
return api;
}
- if (api != 0) {
+ if (api != 0)
return api;
- }
execv(argv[0], argv);
@@ -1057,6 +1087,8 @@ static struct port_map_entry * flow_req_arr(pid_t api,
bool acc_wait = true;
enum reg_name_state state;
+ struct spawned_api * c_api;
+
pme = port_map_entry_create();
if (pme == NULL) {
LOG_ERR("Failed to create port_map_entry.");
@@ -1092,17 +1124,32 @@ static struct port_map_entry * flow_req_arr(pid_t api,
free(pme);
return NULL;
case REG_NAME_AUTO_ACCEPT:
+ c_api = malloc(sizeof(*c_api));
+ if (c_api == NULL) {
+ pthread_rwlock_unlock(&instance->reg_lock);
+ pthread_rwlock_unlock(&instance->state_lock);
+ free(pme);
+ return NULL;
+ }
+
pthread_mutex_lock(&rne->state_lock);
rne->state = REG_NAME_AUTO_EXEC;
pthread_mutex_unlock(&rne->state_lock);
- if (auto_execute(reg_entry_resolve_auto(rne)) < 0) {
+ if ((c_api->api = auto_execute(reg_entry_resolve_auto(rne)))
+ < 0) {
+ pthread_mutex_lock(&rne->state_lock);
+ rne->state = REG_NAME_AUTO_ACCEPT;
+ pthread_mutex_unlock(&rne->state_lock);
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
free(pme);
+ free(c_api);
return NULL;
}
+ list_add(&c_api->next, &instance->spawned_apis);
+
pthread_rwlock_unlock(&instance->reg_lock);
pthread_mutex_lock(&rne->state_lock);
@@ -1228,7 +1275,6 @@ static void irm_destroy()
struct list_head * h;
struct list_head * t;
-
pthread_rwlock_rdlock(&instance->state_lock);
if (instance->state != IRMD_NULL)
@@ -1243,6 +1289,7 @@ static void irm_destroy()
struct ipcp_entry * e = list_entry(h, struct ipcp_entry, next);
list_del(&e->next);
ipcp_destroy(e->api);
+ clear_spawned_api(e->api);
ipcp_entry_destroy(e);
}
@@ -1252,6 +1299,18 @@ static void irm_destroy()
reg_entry_destroy(e);
}
+ list_for_each_safe(h, t, &instance->spawned_apis) {
+ struct spawned_api * api =
+ list_entry(h, struct spawned_api, next);
+ int status;
+ if (kill(api->api, SIGTERM))
+ LOG_DBGF("Could not send kill signal to %d.", api->api);
+ else if (waitpid(api->api, &status, 0) < 0)
+ LOG_DBGF("Error waiting for %d to exit.", api->api);
+ list_del(&api->next);
+ free(api);
+ }
+
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_wrlock(&instance->flows_lock);
@@ -1260,10 +1319,8 @@ static void irm_destroy()
struct port_map_entry * e = list_entry(h,
struct port_map_entry,
next);
-
list_del(&e->next);
port_map_entry_destroy(e);
-
}
if (instance->port_ids != NULL)
@@ -1322,6 +1379,7 @@ void * irm_flow_cleaner()
struct timespec timeout = {IRMD_CLEANUP_TIMER / BILLION,
IRMD_CLEANUP_TIMER % BILLION};
+ int status;
while (true) {
if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
@@ -1383,7 +1441,7 @@ void * irm_flow_cleaner()
pthread_rwlock_unlock(&instance->flows_lock);
pthread_rwlock_wrlock(&instance->reg_lock);
- list_for_each_safe(pos, n, &(instance->registry)) {
+ list_for_each_safe(pos, n, &instance->registry) {
struct reg_entry * e =
list_entry(pos, struct reg_entry, next);
@@ -1394,16 +1452,30 @@ void * irm_flow_cleaner()
next);
if (kill(r->api, 0) < 0) {
LOG_INFO("Process %d gone, "
- "instance deleted.",
+ "registry binding removed.",
r->api);
- registry_remove_ap_instance(
+ registry_remove_api_name(
&instance->registry,
- e->name,
- r->api);
+ r->api,
+ e->name);
}
}
}
+ list_for_each_safe(pos, n, &instance->spawned_apis) {
+ struct spawned_api * api =
+ list_entry(pos, struct spawned_api, next);
+ waitpid(api->api, &status, WNOHANG);
+
+ if (kill(api->api, 0) < 0) {
+ LOG_INFO("Spawned process %d terminated "
+ "with exit status %d.",
+ api->api, status);
+ list_del(&api->next);
+ free(api);
+ }
+ }
+
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
@@ -1675,6 +1747,7 @@ static struct irm * irm_create()
}
INIT_LIST_HEAD(&instance->ipcps);
+ INIT_LIST_HEAD(&instance->spawned_apis);
INIT_LIST_HEAD(&instance->registry);
INIT_LIST_HEAD(&instance->port_map);
diff --git a/src/irmd/registry.c b/src/irmd/registry.c
index a4e2fcfa..ae532d5a 100644
--- a/src/irmd/registry.c
+++ b/src/irmd/registry.c
@@ -491,9 +491,9 @@ int registry_remove_ap_auto(struct list_head * registry,
}
-struct reg_instance * registry_add_ap_instance(struct list_head * registry,
- char * name,
- pid_t api)
+struct reg_instance * registry_add_api_name(struct list_head * registry,
+ pid_t api,
+ char * name)
{
struct reg_entry * e = NULL;
struct reg_instance * i = NULL;
@@ -534,9 +534,9 @@ struct reg_instance * registry_add_ap_instance(struct list_head * registry,
return i;
}
-int registry_remove_ap_instance(struct list_head * registry,
- char * name,
- pid_t api)
+int registry_remove_api_name(struct list_head * registry,
+ pid_t api,
+ char * name)
{
struct reg_entry * e = NULL;
struct reg_instance * i = NULL;
diff --git a/src/irmd/registry.h b/src/irmd/registry.h
index 36b68dcd..83b9d393 100644
--- a/src/irmd/registry.h
+++ b/src/irmd/registry.h
@@ -130,12 +130,12 @@ int registry_add_ap_auto(struct list_head * registry,
int registry_remove_ap_auto(struct list_head * registry,
char * name,
char * ap_name);
-struct reg_instance * registry_add_ap_instance(struct list_head * registry,
- char * name,
- pid_t api);
-int registry_remove_ap_instance(struct list_head * registry,
- char * name,
- pid_t api);
+struct reg_instance * registry_add_api_name(struct list_head * registry,
+ pid_t api,
+ char * name);
+int registry_remove_api_name(struct list_head * registry,
+ pid_t api,
+ char * name);
struct reg_entry * registry_get_entry_by_name(struct list_head * registry,
char * name);
struct reg_entry * registry_get_entry_by_ap_name(struct list_head * registry,