From 11c6be30491ebe4e41380f48a271c57bcff4b043 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 10 Aug 2016 17:50:45 +0200 Subject: lib, irmd: Bind AP instances to AP_subsets This call will allow grouping AP instances of a certain AP together which are configured identically. Adds the bind operation to dev and updates the applications to make use of this call. Flow_alloc is now only called with the pid and doesn't send the apn anymore. --- src/irmd/CMakeLists.txt | 1 + src/irmd/api_table.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ src/irmd/api_table.h | 46 +++++++++++++++++++ src/irmd/main.c | 75 +++++++++++++++++++++++++++++-- 4 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 src/irmd/api_table.c create mode 100644 src/irmd/api_table.h (limited to 'src/irmd') diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index 89fbae08..ca068703 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES # Add source files here + api_table.c irm_flow.c main.c reg_api.c diff --git a/src/irmd/api_table.c b/src/irmd/api_table.c new file mode 100644 index 00000000..b62b2b55 --- /dev/null +++ b/src/irmd/api_table.c @@ -0,0 +1,115 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Application Instance Table + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "api_table.h" + +#include + +struct api_entry * api_entry_create(pid_t api, + char * apn, + char * ap_subset) +{ + struct api_entry * e = malloc(sizeof(*e)); + if (e == NULL) + return NULL; + + INIT_LIST_HEAD(&e->next); + + e->api = api; + e->apn = apn; + e->ap_subset = ap_subset; + + return e; +} + +void api_entry_destroy(struct api_entry * e) +{ + if (e->apn != NULL) + free(e->apn); + if (e->ap_subset != NULL) + free(e->ap_subset); + free(e); +} + +int api_table_add_api(struct list_head * api_table, + pid_t api, char * apn, char * ap_subset) +{ + if (apn == NULL) + return -EINVAL; + + struct api_entry * e = api_entry_create(api, apn, ap_subset); + if (e == NULL) + return -ENOMEM; + + list_add(&e->next, api_table); + + return 0; +} + +void api_table_del_api(struct list_head * api_table, pid_t api) +{ + struct list_head * p; + struct list_head * h; + + list_for_each_safe(p, h, api_table) { + struct api_entry * e = + list_entry(p, struct api_entry, next); + + if (api == e->api) { + list_del(&e->next); + api_entry_destroy(e); + } + } +} + +char * api_table_get_apn(struct list_head * api_table, pid_t api) +{ + struct list_head * h; + + list_for_each(h, api_table) { + struct api_entry * e = + list_entry(h, struct api_entry, next); + + if (api == e->api) + return e->apn; + } + + return NULL; +} +char * api_table_get_ap_subset(struct list_head * api_table, pid_t api) +{ + struct list_head * h; + + list_for_each(h, api_table) { + struct api_entry * e = + list_entry(h, struct api_entry, next); + + if (api == e->api) + return e->ap_subset; + } + + return NULL; +} diff --git a/src/irmd/api_table.h b/src/irmd/api_table.h new file mode 100644 index 00000000..694de6da --- /dev/null +++ b/src/irmd/api_table.h @@ -0,0 +1,46 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * The IPC Resource Manager - Application Instance Table + * + * Dimitri Staessens + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IRMD_API_TABLE_H +#define OUROBOROS_IRMD_API_TABLE_H + +#include + +struct api_entry { + struct list_head next; + pid_t api; + char * apn; + char * ap_subset; /* unique instance identifier */ +}; + +struct api_entry * api_entry_create(pid_t api, char * apn, char * ap_subset); +void api_entry_destroy(struct api_entry * e); + +int api_table_add_api(struct list_head * api_table, + pid_t api, + char * apn, + char * ap_subset); +void api_table_del_api(struct list_head * api_table, pid_t api); +char * api_table_get_apn(struct list_head * api_table, pid_t api); +char * api_table_get_ap_subset(struct list_head * api_table, pid_t api); + +#endif /* OUROBOROS_IRMD_API_TABLE_H */ diff --git a/src/irmd/main.c b/src/irmd/main.c index e36fb98e..55764941 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -43,6 +43,7 @@ #include "utils.h" #include "registry.h" #include "irm_flow.h" +#include "api_table.h" #include #include @@ -78,8 +79,6 @@ struct spawned_api { pid_t api; }; -/* keeps track of port_id's between N and N - 1 */ - struct irm { /* FIXME: list of ipcps could be merged into the registry */ struct list_head ipcps; @@ -87,6 +86,7 @@ struct irm { struct list_head registry; pthread_rwlock_t reg_lock; + struct list_head api_table; struct list_head spawned_apis; /* keep track of all flows in this processing system */ @@ -717,14 +717,59 @@ static int ap_unreg(char * name, return ret; } +static int api_bind(pid_t api, char * apn, char * ap_subset) +{ + int ret = 0; + char * apn_dup; + char * ap_s_dup = ap_subset; + if (apn == NULL) + return -EINVAL; + + pthread_rwlock_rdlock(&irmd->state_lock); + + if (irmd->state != IRMD_RUNNING) { + pthread_rwlock_unlock(&irmd->state_lock); + return -EPERM; + } + + pthread_rwlock_wrlock(&irmd->reg_lock); + + apn_dup = strdup(apn); + if (apn_dup == NULL) { + pthread_rwlock_unlock(&irmd->reg_lock); + pthread_rwlock_unlock(&irmd->state_lock); + return -ENOMEM; + } + + if (ap_subset != NULL) { + ap_s_dup = strdup(ap_subset); + if (ap_s_dup == NULL) { + pthread_rwlock_unlock(&irmd->reg_lock); + pthread_rwlock_unlock(&irmd->state_lock); + return -ENOMEM; + } + } + + ret = api_table_add_api(&irmd->api_table, + api, + apn_dup, + ap_s_dup); + + pthread_rwlock_unlock(&irmd->reg_lock); + pthread_rwlock_unlock(&irmd->state_lock); + + return ret; +} + static struct irm_flow * flow_accept(pid_t api, - char * srv_ap_name, char ** dst_ae_name) { struct irm_flow * f = NULL; struct reg_entry * rne = NULL; struct reg_api * rgi = NULL; + char * srv_ap_name; + pthread_rwlock_rdlock(&irmd->state_lock); if (irmd->state != IRMD_RUNNING) { @@ -734,6 +779,10 @@ static struct irm_flow * flow_accept(pid_t api, pthread_rwlock_wrlock(&irmd->reg_lock); + srv_ap_name = api_table_get_apn(&irmd->api_table, api); + if (srv_ap_name == NULL) + return NULL; + rne = registry_get_entry_by_apn(&irmd->registry, srv_ap_name); if (rne == NULL) { pthread_rwlock_unlock(&irmd->reg_lock); @@ -1458,6 +1507,18 @@ void * irm_flow_cleaner() } } + list_for_each_safe(pos, n, &irmd->api_table) { + struct api_entry * e = + list_entry(pos, struct api_entry, next); + + if (kill(e->api, 0) < 0) { + LOG_INFO("Instance %d removed from api table.", + e->api); + list_del(&e->next); + api_entry_destroy(e); + } + } + pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_unlock(&irmd->state_lock); @@ -1542,6 +1603,12 @@ void * mainloop() msg->ap_name, msg->opts); break; + case IRM_MSG_CODE__IRM_API_BIND: + ret_msg.has_result = true; + ret_msg.result = api_bind(msg->api, + msg->ap_name, + msg->ap_subset); + break; case IRM_MSG_CODE__IRM_LIST_IPCPS: ret_msg.n_apis = list_ipcps(msg->dst_name, &apis); @@ -1562,7 +1629,6 @@ void * mainloop() break; case IRM_MSG_CODE__IRM_FLOW_ACCEPT: e = flow_accept(msg->api, - msg->ap_name, &ret_msg.ae_name); if (e == NULL) { @@ -1700,6 +1766,7 @@ static struct irm * irm_create() } INIT_LIST_HEAD(&irmd->ipcps); + INIT_LIST_HEAD(&irmd->api_table); INIT_LIST_HEAD(&irmd->spawned_apis); INIT_LIST_HEAD(&irmd->registry); INIT_LIST_HEAD(&irmd->irm_flows); -- cgit v1.2.3