From f437a4a122614a01a1f97713ddc6e45c1011b86f Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 6 Jul 2016 11:33:25 +0200 Subject: irmd: Rename registry functions Reflects that the functions (dis)associate an application instance from/with a name and not remove it from the registry entirely. --- src/irmd/main.c | 15 ++++++++------- src/irmd/registry.c | 12 ++++++------ src/irmd/registry.h | 12 ++++++------ 3 files changed, 20 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/irmd/main.c b/src/irmd/main.c index de100cf8..e59d3c2a 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -715,8 +715,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); @@ -800,7 +801,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); @@ -1392,12 +1393,12 @@ 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); } } } 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, -- cgit v1.2.3 From b3aa97084d0a9223b85ed81272d7d21c537a7d13 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 6 Jul 2016 15:23:46 +0200 Subject: irmd: Collect spawned processes The irmd will now collect terminated child processes (autostarted api's and ipcpd's). Upon exit, all autostarted api's will be killed. Fixes #19. --- src/irmd/main.c | 129 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 101 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/irmd/main.c b/src/irmd/main.c index e59d3c2a..ab6d5167 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -50,6 +50,7 @@ #include #include #include +#include #define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */ @@ -66,35 +67,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; @@ -102,8 +110,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() @@ -260,9 +268,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) { @@ -270,8 +282,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; @@ -285,7 +297,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); @@ -299,12 +311,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) @@ -320,6 +350,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); @@ -1035,9 +1066,8 @@ static pid_t auto_execute(char ** argv) return api; } - if (api != 0) { + if (api != 0) return api; - } execv(argv[0], argv); @@ -1056,6 +1086,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."); @@ -1091,17 +1123,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); @@ -1227,7 +1274,6 @@ static void irm_destroy() struct list_head * h; struct list_head * t; - pthread_rwlock_rdlock(&instance->state_lock); if (instance->state != IRMD_NULL) @@ -1242,6 +1288,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); } @@ -1251,6 +1298,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); @@ -1259,10 +1318,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) @@ -1321,6 +1378,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) @@ -1382,7 +1440,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); @@ -1403,6 +1461,20 @@ void * irm_flow_cleaner() } } + 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); @@ -1674,6 +1746,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); -- cgit v1.2.3