summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/dev.h3
-rw-r--r--src/ipcpd/normal/main.c5
-rw-r--r--src/irmd/CMakeLists.txt1
-rw-r--r--src/irmd/api_table.c115
-rw-r--r--src/irmd/api_table.h46
-rw-r--r--src/irmd/main.c75
-rw-r--r--src/lib/dev.c37
-rw-r--r--src/lib/irmd_messages.proto48
-rw-r--r--src/tools/cbr/cbr_server.c9
-rw-r--r--src/tools/echo/echo_server.c5
-rw-r--r--src/tools/oping/oping_server.c5
11 files changed, 319 insertions, 30 deletions
diff --git a/include/ouroboros/dev.h b/include/ouroboros/dev.h
index d5fb744b..a0885b70 100644
--- a/include/ouroboros/dev.h
+++ b/include/ouroboros/dev.h
@@ -36,6 +36,9 @@
int ap_init(char * ap_name);
void ap_fini(void);
+/* This call binds an instance to a specific subset of applications */
+int api_bind(char * ap_subset);
+
/* Returns file descriptor (> 0) and client AE name. */
int flow_accept(char ** ae_name);
int flow_alloc_resp(int fd, int result);
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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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);