summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/main.c251
1 files changed, 135 insertions, 116 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 03f9a3c2..ea52d67f 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -72,9 +72,10 @@ struct reg_name_entry {
/* FIXME: make a list resolve to AP-I instead */
instance_name_t * api;
+ char ** argv;
+ bool autoexec;
bool accept;
- char * req_ap_name;
char * req_ae_name;
int response;
int flow_arrived;
@@ -264,8 +265,9 @@ static struct reg_name_entry * reg_name_entry_create()
e->name = NULL;
e->api = NULL;
+ e->argv = NULL;
+ e->autoexec = false;
e->accept = false;
- e->req_ap_name = NULL;
e->req_ae_name = NULL;
e->flow_arrived = -1;
@@ -286,13 +288,17 @@ static struct reg_name_entry * reg_name_entry_create()
static struct reg_name_entry * reg_name_entry_init(struct reg_name_entry * e,
char * name,
- instance_name_t * api)
+ instance_name_t * api,
+ char ** argv,
+ bool ae)
{
if (e == NULL || name == NULL || api == NULL)
return NULL;
- e->name = name;
- e->api = api;
+ e->name = name;
+ e->api = api;
+ e->argv = argv;
+ e->autoexec = ae;
return e;
}
@@ -335,6 +341,21 @@ static struct reg_name_entry * get_reg_name_entry_by_name(char * name)
return NULL;
}
+static struct reg_name_entry * get_reg_name_entry_by_ap_name(char * ap_name)
+{
+ struct list_head * pos = NULL;
+
+ list_for_each(pos, &instance->reg_names) {
+ struct reg_name_entry * e =
+ list_entry(pos, struct reg_name_entry, next);
+
+ if (strcmp(ap_name, e->api->name) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
static struct reg_name_entry * get_reg_name_entry_by_id(pid_t pid)
{
struct list_head * pos = NULL;
@@ -351,7 +372,10 @@ static struct reg_name_entry * get_reg_name_entry_by_id(pid_t pid)
}
/* FIXME: add only name when we have NSM solved */
-static int reg_name_entry_add_name_instance(char * name, instance_name_t * api)
+static int reg_name_entry_add_name_instance(char * name,
+ instance_name_t * api,
+ char ** argv,
+ bool autoexec)
{
struct reg_name_entry * e = get_reg_name_entry_by_name(name);
if (e == NULL) {
@@ -359,7 +383,8 @@ static int reg_name_entry_add_name_instance(char * name, instance_name_t * api)
if (e == NULL)
return -1;
- if (reg_name_entry_init(e, name, api) == NULL) {
+ if (reg_name_entry_init(e, name, api, argv, autoexec)
+ == NULL) {
reg_name_entry_destroy(e);
return -1;
}
@@ -595,46 +620,12 @@ static int enroll_ipcp(instance_name_t * api,
return 0;
}
-static int reg_ipcp(instance_name_t * api,
- char ** difs,
- size_t difs_size)
-{
- rw_lock_rdlock(&instance->state_lock);
- rw_lock_wrlock(&instance->reg_lock);
-
- if (ipcp_reg(api->id, difs, difs_size)) {
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
- LOG_ERR("Could not register IPCP to N-1 DIF(s).");
- return -1;
- }
-
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
-
- return 0;
-}
-
-static int unreg_ipcp(instance_name_t * api,
- char ** difs,
- size_t difs_size)
-{
- rw_lock_rdlock(&instance->state_lock);
- rw_lock_wrlock(&instance->reg_lock);
- if (ipcp_unreg(api->id, difs, difs_size)) {
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
- LOG_ERR("Could not unregister IPCP from N-1 DIF(s).");
- return -1;
- }
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
-
- return 0;
-}
-
-static int ap_reg(char * ap_name,
+static int ap_reg(char * name,
+ char * ap_name,
pid_t ap_id,
+ int argc,
+ char ** argv,
+ bool autoexec,
char ** difs,
size_t len)
{
@@ -644,6 +635,7 @@ static int ap_reg(char * ap_name,
struct reg_name_entry * rne = NULL;
instance_name_t * api = NULL;
+ char ** argv_dup = NULL;
rw_lock_rdlock(&instance->state_lock);
rw_lock_wrlock(&instance->reg_lock);
@@ -661,16 +653,15 @@ static int ap_reg(char * ap_name,
return -1;
}
- if (instance_name_init_from(api, ap_name, ap_id) == NULL) {
+ if (instance_name_init_from(api, path_strip(ap_name), ap_id) == NULL) {
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
instance_name_destroy(api);
return -1;
}
- /* check if this ap_name is already registered */
-
- rne = get_reg_name_entry_by_name(ap_name);
+ /* check if this name is already registered */
+ rne = get_reg_name_entry_by_name(name);
if (rne != NULL) {
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
@@ -678,11 +669,6 @@ static int ap_reg(char * ap_name,
return -1; /* can only register one instance for now */
}
- /*
- * for now, the whatevercast name is the same as the ap_name and
- * contains a single instance only
- */
-
list_for_each(pos, &instance->ipcps) {
struct ipcp_entry * e =
list_entry(pos, struct ipcp_entry, next);
@@ -692,26 +678,42 @@ static int ap_reg(char * ap_name,
for (i = 0; i < len; ++i) {
if (wildcard_match(difs[i], e->dif_name) == 0) {
- if (ipcp_name_reg(e->api->id, ap_name)) {
+ if (ipcp_name_reg(e->api->id, name)) {
LOG_ERR("Could not register "
- "%s in DIF %s.",
- api->name, e->dif_name);
+ "%s in DIF %s as %s.",
+ api->name, e->dif_name, name);
} else {
+ LOG_INFO("Registered %s as %s in %s",
+ api->name, name, e->dif_name);
++ret;
}
}
}
}
-
if (ret == 0) {
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
instance_name_destroy(api);
return -1;
}
+
+ /* we need to duplicate argv */
+ if (argc != 0) {
+ argv_dup = malloc ((argc + 2) * sizeof(*argv_dup));
+ argv_dup[0] = strdup(api->name);
+ for (i = 1; i <= argc; ++i)
+ argv_dup[i] = strdup(argv[i - 1]);
+ argv_dup[argc + 1] = NULL;
+ }
+
+
/* for now, we register single instances */
- ret = reg_name_entry_add_name_instance(strdup(ap_name),
- api);
+ if ((ret = reg_name_entry_add_name_instance(strdup(name),
+ api,
+ argv_dup,
+ autoexec))
+ < 0)
+ LOG_DBGF("Failed to add application %s.", api->name);
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
@@ -719,38 +721,28 @@ static int ap_reg(char * ap_name,
return ret;
}
-static int ap_unreg(char * ap_name,
+static int ap_unreg(char * name,
+ char * ap_name,
pid_t ap_id,
char ** difs,
- size_t len)
+ size_t len,
+ bool hard)
{
int i;
int ret = 0;
struct reg_name_entry * rne = NULL;
struct list_head * pos = NULL;
+ if (name == NULL || len == 0 || difs == NULL || difs[0] == NULL)
+ return -1;
+
rw_lock_rdlock(&instance->state_lock);
rw_lock_wrlock(&instance->reg_lock);
- /* check if ap_name is registered */
- rne = get_reg_name_entry_by_id(ap_id);
- if (rne == NULL) {
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
- return 0; /* no such id */
- }
-
- if (strcmp(ap_name, rne->api->name)) {
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
- return 0;
- }
-
- if (instance->ipcps.next == NULL) {
- rw_lock_unlock(&instance->reg_lock);
- rw_lock_unlock(&instance->state_lock);
- LOG_ERR("No IPCPs in this system.");
- return 0;
+ if (!hard && strcmp(difs[0], "*") != 0) {
+ LOG_INFO("Unregistration not complete yet.");
+ LOG_MISSING;
+ return -1;
}
list_for_each(pos, &instance->ipcps) {
@@ -762,7 +754,8 @@ static int ap_unreg(char * ap_name,
for (i = 0; i < len; ++i) {
if (wildcard_match(difs[i], e->dif_name) == 0) {
- if (ipcp_name_unreg(e->api->id, rne->name)) {
+ if (ipcp_name_unreg(e->api->id,
+ rne->name)) {
LOG_ERR("Could not unregister "
"%s in DIF %s.",
rne->name, e->dif_name);
@@ -772,7 +765,6 @@ static int ap_unreg(char * ap_name,
}
}
- /* FIXME: check if name is not registered in any DIF before removing */
reg_name_entry_del_name(rne->name);
rw_lock_unlock(&instance->reg_lock);
@@ -782,8 +774,8 @@ static int ap_unreg(char * ap_name,
}
static struct port_map_entry * flow_accept(pid_t pid,
- char ** ap_name,
- char ** ae_name)
+ char * srv_ap_name,
+ char ** dst_ae_name)
{
struct port_map_entry * pme;
struct reg_name_entry * rne = NULL;
@@ -791,11 +783,21 @@ static struct port_map_entry * flow_accept(pid_t pid,
rw_lock_rdlock(&instance->state_lock);
rw_lock_rdlock(&instance->reg_lock);
- rne = get_reg_name_entry_by_id(pid);
+ rne = get_reg_name_entry_by_ap_name(srv_ap_name);
if (rne == NULL) {
rw_lock_unlock(&instance->reg_lock);
rw_lock_unlock(&instance->state_lock);
- LOG_DBGF("Unregistered AP calling accept().");
+ LOG_DBGF("AP %s is unknown.", srv_ap_name);
+ return NULL;
+ }
+
+ if (rne->api->id == 0) {
+ rne->api->id = pid;
+ } else if (rne->api->id != pid) {
+ rw_lock_unlock(&instance->reg_lock);
+ rw_lock_unlock(&instance->state_lock);
+ LOG_DBGF("Can only register one instance.");
+ LOG_MISSING;
return NULL;
}
@@ -843,9 +845,8 @@ static struct port_map_entry * flow_accept(pid_t pid,
return NULL;
}
- *ap_name = rne->req_ap_name;
- if (ae_name != NULL)
- *ae_name = rne->req_ae_name;
+ if (dst_ae_name != NULL)
+ *dst_ae_name = rne->req_ae_name;
rw_lock_unlock(&instance->flows_lock);
rw_lock_unlock(&instance->state_lock);
@@ -919,7 +920,6 @@ static int flow_alloc_resp(pid_t n_pid,
static struct port_map_entry * flow_alloc(pid_t pid,
char * dst_name,
- char * src_ap_name,
char * src_ae_name,
struct qos_spec * qos)
{
@@ -967,7 +967,6 @@ static struct port_map_entry * flow_alloc(pid_t pid,
pme->port_id,
pme->n_pid,
dst_name,
- src_ap_name,
src_ae_name,
QOS_CUBE_BE) < 0) {
rw_lock_rdlock(&instance->state_lock);
@@ -1085,9 +1084,30 @@ static int flow_dealloc(int port_id)
return ret;
}
+static int auto_execute(char * ap, char ** argv)
+{
+ pid_t pid;
+ LOG_INFO("Executing %s.", ap);
+ pid = fork();
+ if (pid == -1) {
+ LOG_ERR("Failed to fork");
+ return pid;
+ }
+
+ if (pid != 0) {
+ return pid;
+ }
+
+ execv(ap, argv);
+
+ LOG_DBG("Failed to execute.");
+
+ exit(EXIT_FAILURE);
+ return 0;
+}
+
static struct port_map_entry * flow_req_arr(pid_t pid,
char * dst_name,
- char * ap_name,
char * ae_name)
{
struct reg_name_entry * rne;
@@ -1125,13 +1145,20 @@ static struct port_map_entry * flow_req_arr(pid_t pid,
pthread_mutex_lock(&rne->acc_lock);
- rne->req_ap_name = ap_name;
rne->req_ae_name = ae_name;
if (rne->accept == false) {
- pthread_mutex_unlock(&rne->acc_lock);
- LOG_WARN("This AP is not accepting flow allocations.");
- return NULL;
+ if (rne->autoexec) {
+ pme->n_pid = auto_execute(rne->api->name, rne->argv);
+ while (rne->accept == false)
+ sched_yield();
+ }
+ else {
+ pthread_mutex_unlock(&rne->acc_lock);
+ LOG_WARN("%s is not accepting flow allocations.",
+ rne->name);
+ return NULL;
+ }
}
rne->flow_arrived = 0;
@@ -1345,35 +1372,29 @@ void * mainloop()
ret_msg.result = enroll_ipcp(&api,
msg->dif_name[0]);
break;
- case IRM_MSG_CODE__IRM_REG_IPCP:
- ret_msg.has_result = true;
- ret_msg.result = reg_ipcp(&api,
- msg->dif_name,
- msg->n_dif_name);
- break;
- case IRM_MSG_CODE__IRM_UNREG_IPCP:
- ret_msg.has_result = true;
- ret_msg.result = unreg_ipcp(&api,
- msg->dif_name,
- msg->n_dif_name);
- break;
case IRM_MSG_CODE__IRM_AP_REG:
ret_msg.has_result = true;
- ret_msg.result = ap_reg(msg->ap_name,
+ ret_msg.result = ap_reg(msg->dst_name,
+ msg->ap_name,
msg->pid,
+ msg->n_args,
+ msg->args,
+ msg->autoexec,
msg->dif_name,
msg->n_dif_name);
break;
case IRM_MSG_CODE__IRM_AP_UNREG:
ret_msg.has_result = true;
- ret_msg.result = ap_unreg(msg->ap_name,
+ ret_msg.result = ap_unreg(msg->dst_name,
+ msg->ap_name,
msg->pid,
msg->dif_name,
- msg->n_dif_name);
+ msg->n_dif_name,
+ msg->hard);
break;
case IRM_MSG_CODE__IRM_FLOW_ACCEPT:
e = flow_accept(msg->pid,
- &ret_msg.ap_name,
+ msg->ap_name,
&ret_msg.ae_name);
if (e == NULL)
@@ -1393,7 +1414,6 @@ void * mainloop()
case IRM_MSG_CODE__IRM_FLOW_ALLOC:
e = flow_alloc(msg->pid,
msg->dst_name,
- msg->ap_name,
msg->ae_name,
NULL);
if (e == NULL)
@@ -1415,7 +1435,6 @@ void * mainloop()
case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:
e = flow_req_arr(msg->pid,
msg->dst_name,
- msg->ap_name,
msg->ae_name);
if (e == NULL)
break;