From 7834e92b218da69cd934679dec9c2d714d89d15e Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Mon, 13 Jun 2016 13:48:17 +0200 Subject: lib, irmd, tools, ipcpd: updates to dev API. The registration function has been moved to the irm tool, applications now need to be registered by an administrator. Currently only supports one instance per registered name, and an AP can be registered under only one name. The irmd can now start a registered server application on demand. For the full functionality of the tool, execute "irm register". AP name removed from flow allocation. Flow allocation does not send the source ap name as it is quite useless. The accept() call now only returns the AE name. --- src/irmd/main.c | 251 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 135 insertions(+), 116 deletions(-) (limited to 'src/irmd') 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; -- cgit v1.2.3