diff options
Diffstat (limited to 'src/irmd/main.c')
| -rw-r--r-- | src/irmd/main.c | 251 | 
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;  | 
