diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipcpd/normal/main.c | 5 | ||||
| -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 | ||||
| -rw-r--r-- | src/lib/dev.c | 37 | ||||
| -rw-r--r-- | src/lib/irmd_messages.proto | 48 | ||||
| -rw-r--r-- | src/tools/cbr/cbr_server.c | 9 | ||||
| -rw-r--r-- | src/tools/echo/echo_server.c | 5 | ||||
| -rw-r--r-- | src/tools/oping/oping_server.c | 5 | 
10 files changed, 316 insertions, 30 deletions
| diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 38789ddd..1599166d 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -175,6 +175,11 @@ static int normal_ipcp_bootstrap(struct dif_config * conf)                  return -1;          } +        if (api_bind(conf->dif_name) < 0) { +                printf("Failed to bind the server api."); +                return -1; +        } +          _ipcp->state = IPCP_ENROLLED;          pthread_rwlock_unlock(&_ipcp->state_lock); 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); diff --git a/src/lib/dev.c b/src/lib/dev.c index cc332233..765c493e 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -134,6 +134,42 @@ void ap_fini(void)          free(_ap_instance);  } +int api_bind(char * ap_subset) +{ +        irm_msg_t msg = IRM_MSG__INIT; +        irm_msg_t * recv_msg = NULL; +        int ret = -1; + +        msg.code    = IRM_MSG_CODE__IRM_API_BIND; +        msg.has_api = true; + +        if (_ap_instance->ap_name == NULL) +                return -EPERM; /* call init first */ + +        pthread_rwlock_rdlock(&_ap_instance->data_lock); + +        msg.api = _ap_instance->api; +        msg.ap_name = _ap_instance->ap_name; + +        pthread_rwlock_unlock(&_ap_instance->data_lock); + +        msg.ap_subset = ap_subset; + +        recv_msg = send_recv_irm_msg(&msg); +        if (recv_msg == NULL) { +                return -1; +        } + +        if (!recv_msg->has_result || (ret = recv_msg->result)) { +                irm_msg__free_unpacked(recv_msg, NULL); +                return ret; +        } + +        irm_msg__free_unpacked(recv_msg, NULL); + +        return ret; +} +  static int port_id_to_fd(int port_id)  {          int i; @@ -154,7 +190,6 @@ int flow_accept(char ** ae_name)          pthread_rwlock_rdlock(&_ap_instance->data_lock); -        msg.ap_name = _ap_instance->ap_name;          msg.api     = _ap_instance->api;          pthread_rwlock_unlock(&_ap_instance->data_lock); diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index 730f842c..5c320a17 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -31,32 +31,34 @@ enum irm_msg_code {          IRM_ENROLL_IPCP       =  6;          IRM_BIND              =  7;          IRM_UNBIND            =  8; -        IRM_REG               =  9; -        IRM_UNREG             = 10; -        IRM_FLOW_ACCEPT       = 11; -        IRM_FLOW_ALLOC_RESP   = 12; -        IRM_FLOW_ALLOC        = 13; -        IRM_FLOW_ALLOC_RES    = 14; -        IRM_FLOW_DEALLOC      = 15; -        IPCP_FLOW_REQ_ARR     = 16; -        IPCP_FLOW_ALLOC_REPLY = 17; -        IPCP_FLOW_DEALLOC     = 18; -        IRM_REPLY             = 19; +        IRM_API_BIND          =  9; +        IRM_REG               = 10; +        IRM_UNREG             = 11; +        IRM_FLOW_ACCEPT       = 12; +        IRM_FLOW_ALLOC_RESP   = 13; +        IRM_FLOW_ALLOC        = 14; +        IRM_FLOW_ALLOC_RES    = 15; +        IRM_FLOW_DEALLOC      = 16; +        IPCP_FLOW_REQ_ARR     = 17; +        IPCP_FLOW_ALLOC_REPLY = 18; +        IPCP_FLOW_DEALLOC     = 19; +        IRM_REPLY             = 20;  };  message irm_msg {          required irm_msg_code code   =  1;          optional string ap_name      =  2; -        optional string ae_name      =  3; -        optional sint32 api          =  4; -        optional uint32 ipcp_type    =  5; -        repeated string dif_name     =  6; -        repeated string args         =  7; -        optional sint32 response     =  8; -        optional string dst_name     =  9; -        optional sint32 port_id      = 10; -        optional dif_config_msg conf = 11; -        optional uint32 opts         = 12; -        repeated sint32 apis         = 13; -        optional sint32 result       = 14; +        optional string ap_subset    =  3; +        optional string ae_name      =  4; +        optional sint32 api          =  5; +        optional uint32 ipcp_type    =  6; +        repeated string dif_name     =  7; +        repeated string args         =  8; +        optional sint32 response     =  9; +        optional string dst_name     = 10; +        optional sint32 port_id      = 11; +        optional dif_config_msg conf = 12; +        optional uint32 opts         = 13; +        repeated sint32 apis         = 14; +        optional sint32 result       = 15;  }; diff --git a/src/tools/cbr/cbr_server.c b/src/tools/cbr/cbr_server.c index fc23363f..d0666551 100644 --- a/src/tools/cbr/cbr_server.c +++ b/src/tools/cbr/cbr_server.c @@ -206,7 +206,7 @@ int server_main()              sigaction(SIGHUP,  &sig_act, NULL) ||              sigaction(SIGPIPE, &sig_act, NULL)) {                  printf("Failed to install sighandler.\n"); -                exit(EXIT_FAILURE); +                return -1;          }          if (pthread_mutex_init(&fds_lock, NULL)) { @@ -216,7 +216,12 @@ int server_main()          if (pthread_cond_init(&fds_signal, NULL)) {                  printf("Failed to init cond.\n"); -                exit(EXIT_FAILURE); +                return -1; +        } + +        if (api_bind(NULL) < 0) { +                printf("Failed to bind the server api."); +                return -1;          }          for (i = 0; i < THREADS_SIZE; i++) diff --git a/src/tools/echo/echo_server.c b/src/tools/echo/echo_server.c index e6ab9cfd..3106ee35 100644 --- a/src/tools/echo/echo_server.c +++ b/src/tools/echo/echo_server.c @@ -39,6 +39,11 @@ int server_main()          char   buf[BUF_SIZE];          ssize_t count = 0; +        if (api_bind(NULL) < 0) { +                printf("Failed to bind the server api."); +                return -1; +        } +          printf("Starting the server.\n");          /* Manual cleanup is required for now */ diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index a5021cba..9e2fa12f 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -148,6 +148,11 @@ int server_main()                  return -1;          } +        if (api_bind(NULL) < 0) { +                printf("Failed to bind the server instance."); +                return -1; +        } +          pthread_create(&server.cleaner_pt, NULL, cleaner_thread, NULL);          pthread_create(&server.accept_pt, NULL, accept_thread, NULL);          pthread_create(&server.server_pt, NULL, server_thread, NULL); | 
