diff options
Diffstat (limited to 'src/irmd')
| -rw-r--r-- | src/irmd/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/irmd/api_table.c | 115 | ||||
| -rw-r--r-- | src/irmd/api_table.h | 46 | ||||
| -rw-r--r-- | src/irmd/main.c | 75 | 
4 files changed, 233 insertions, 4 deletions
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 <dimitri.staessens@intec.ugent.be> + * + * 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 <ouroboros/config.h> +#include <ouroboros/list.h> +#include <ouroboros/errno.h> + +#include "api_table.h" + +#include <stdlib.h> + +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 <dimitri.staessens@intec.ugent.be> + * + * 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 <unistd.h> + +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 <sys/socket.h>  #include <sys/un.h> @@ -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);  | 
