summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@ugent.be>2017-08-17 16:35:36 +0200
committerdimitri staessens <dimitri.staessens@ugent.be>2017-08-17 16:49:09 +0200
commitdb218bbe19b66a382df5f665981b7b16f1901bc9 (patch)
treedf6a08516b7215dddb024ab1e44f23121d616487
parent7ae3d85c7249b9e8846bc87fdf44e8621a370565 (diff)
downloadouroboros-db218bbe19b66a382df5f665981b7b16f1901bc9.tar.gz
ouroboros-db218bbe19b66a382df5f665981b7b16f1901bc9.zip
irmd: Handle IPCP creation fails gracefully
-rw-r--r--src/irmd/ipcp.c53
-rw-r--r--src/irmd/main.c34
2 files changed, 52 insertions, 35 deletions
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index ade09625..f3f97811 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -130,13 +130,34 @@ pid_t ipcp_create(const char * name,
enum ipcp_type ipcp_type)
{
pid_t api = -1;
- size_t len = 0;
char * ipcp_dir = "/sbin/";
- char * full_name = NULL;
char * exec_name = NULL;
char irmd_api[10];
+ char full_name[256];
char * argv[5];
+ switch(ipcp_type) {
+ case IPCP_NORMAL:
+ exec_name = IPCP_NORMAL_EXEC;
+ break;
+ case IPCP_SHIM_UDP:
+ exec_name = IPCP_SHIM_UDP_EXEC;
+ break;
+ case IPCP_SHIM_ETH_LLC:
+ exec_name = IPCP_SHIM_ETH_LLC_EXEC;
+ break;
+ case IPCP_LOCAL:
+ exec_name = IPCP_LOCAL_EXEC;
+ break;
+ default:
+ return -1;
+ }
+
+ if (strlen(exec_name) == 0) {
+ log_err("IPCP type not installed.");
+ return -1;
+ }
+
sprintf(irmd_api, "%u", getpid());
api = fork();
@@ -148,33 +169,9 @@ pid_t ipcp_create(const char * name,
if (api != 0)
return api;
- if (ipcp_type == IPCP_NORMAL)
- exec_name = IPCP_NORMAL_EXEC;
- else if (ipcp_type == IPCP_SHIM_UDP)
- exec_name = IPCP_SHIM_UDP_EXEC;
- else if (ipcp_type == IPCP_SHIM_ETH_LLC)
- exec_name = IPCP_SHIM_ETH_LLC_EXEC;
- else if (ipcp_type == IPCP_LOCAL)
- exec_name = IPCP_LOCAL_EXEC;
- else
- exit(EXIT_FAILURE);
-
- len += strlen(INSTALL_PREFIX);
- len += strlen(ipcp_dir);
- len += strlen(exec_name);
- len += 1;
-
- full_name = malloc(len + 1);
- if (full_name == NULL) {
- log_err("Failed to malloc");
- exit(EXIT_FAILURE);
- }
-
strcpy(full_name, INSTALL_PREFIX);
strcat(full_name, ipcp_dir);
strcat(full_name, exec_name);
- full_name[len] = '\0';
-
/* log_file to be placed at the end */
argv[0] = full_name;
@@ -190,9 +187,7 @@ pid_t ipcp_create(const char * name,
execv(argv[0], &argv[0]);
log_dbg("%s", strerror(errno));
- log_err("Failed to load IPCP daemon");
- log_err("Make sure to run the installed version");
- free(full_name);
+ log_err("Failed to load IPCP daemon.");
exit(EXIT_FAILURE);
}
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 61ce6a49..0c157fd4 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -275,6 +275,11 @@ static pid_t create_ipcp(char * name,
struct ipcp_entry * tmp = NULL;
struct list_head * p = NULL;
struct ipcp_entry * entry = NULL;
+ int ret = 0;
+ pthread_condattr_t cattr;
+ struct timespec dl;
+ struct timespec to = {SOCKET_TIMEOUT / 1000,
+ (SOCKET_TIMEOUT % 1000) * MILLION};
api = malloc(sizeof(*api));
if (api == NULL)
@@ -311,13 +316,20 @@ static pid_t create_ipcp(char * name,
pthread_rwlock_unlock(&irmd.reg_lock);
return -1;
}
+ pthread_condattr_init(&cattr);
+#ifndef __APPLE__
+ pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
+#endif
+
+ pthread_cond_init(&tmp->init_cond, &cattr);
+
+ pthread_condattr_destroy(&cattr);
- pthread_cond_init(&tmp->init_cond, NULL);
pthread_mutex_init(&tmp->init_lock, NULL);
- tmp->dif_name = NULL;
- tmp->type = ipcp_type;
- tmp->init = false;
+ tmp->dif_name = NULL;
+ tmp->type = ipcp_type;
+ tmp->init = false;
tmp->dir_hash_algo = -1;
list_for_each(p, &irmd.ipcps) {
@@ -334,11 +346,21 @@ static pid_t create_ipcp(char * name,
pthread_mutex_lock(&tmp->init_lock);
- while (tmp->init == false)
- pthread_cond_wait(&tmp->init_cond, &tmp->init_lock);
+ clock_gettime(PTHREAD_COND_CLOCK, &dl);
+ ts_add(&dl, &to, &dl);
+ while (tmp->init == false && ret != -ETIMEDOUT)
+ ret = -pthread_cond_timedwait(&tmp->init_cond,
+ &tmp->init_lock,
+ &dl);
pthread_mutex_unlock(&tmp->init_lock);
+ if (ret == -ETIMEDOUT) {
+ log_err("Process %d failed to respond.", api->pid);
+ kill(api->pid, SIGKILL);
+ return -1;
+ }
+
log_info("Created IPCP %d.", api->pid);
return api->pid;