summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2015-12-16 20:26:04 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2015-12-16 20:26:04 +0100
commitb1d0b438473ed95bdac30f1cc70752a9c117068a (patch)
treee73c4000b1e0e0f60f64ebf1b40e03bad7081a39
parentd98ed87299e26531f5a71ad053cbe412f8252799 (diff)
launchers basis work
Change-Id: Idf243308d2c0320f02cab732ccf65181d1843e88
-rw-r--r--src/Makefile.am3
-rw-r--r--src/af-run.c159
-rw-r--r--src/af-usrd.c3
3 files changed, 137 insertions, 28 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b1c95bc..94e06df 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,6 +31,7 @@ SECWRP = \
APPFWK = \
af-db.c \
+ af-launch.c \
af-run.c
@@ -87,6 +88,6 @@ wgtpkg_installer_SOURCES = wgtpkg-installer.c ${WGTPKGSRCS} ${WGTSRCS} ${SECWRP}
wgtpkg_info_SOURCES = wgtpkg-info.c ${WGTPKGSRCS} ${WGTSRCS} ${OTHERSRCS}
-af_usrd_SOURCES = af-usrd.c ${APPFWK} ${WGTSRCS} ${OTHERSRCS}
+af_usrd_SOURCES = af-usrd.c ${APPFWK} ${WGTSRCS} ${OTHERSRCS} ${SECWRP}
diff --git a/src/af-run.c b/src/af-run.c
index 0fd533c..82a3ed2 100644
--- a/src/af-run.c
+++ b/src/af-run.c
@@ -29,7 +29,7 @@
#include "verbose.h"
#include "utils-dir.h"
-#include "wgt-info.h"
+#include "af-launch.h"
enum appstate {
as_starting,
@@ -43,7 +43,7 @@ struct apprun {
struct apprun *next_by_runid;
struct apprun *next_by_pgid;
int runid;
- pid_t pgid;
+ pid_t pids[2]; /* 0: group leader, 1: slave (appli) */
enum appstate state;
json_object *appli;
};
@@ -65,7 +65,7 @@ static char *homeappdir;
static struct apprun *runner_of_pgid(pid_t pgid)
{
struct apprun *result = runners_by_pgid[(int)(pgid & (ROOT_RUNNERS_COUNT - 1))];
- while (result && result->pgid != pgid)
+ while (result && result->pids[0] != pgid)
result = result->next_by_pgid;
return result;
}
@@ -73,7 +73,7 @@ static struct apprun *runner_of_pgid(pid_t pgid)
/* insert a runner for its pgid */
static void pgid_insert(struct apprun *runner)
{
- struct apprun **prev = &runners_by_runid[(int)(runner->pgid & (ROOT_RUNNERS_COUNT - 1))];
+ struct apprun **prev = &runners_by_runid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
runner->next_by_pgid = *prev;
*prev = runner;
}
@@ -81,7 +81,7 @@ static void pgid_insert(struct apprun *runner)
/* remove a runner for its pgid */
static void pgid_remove(struct apprun *runner)
{
- struct apprun **prev = &runners_by_runid[(int)(runner->pgid & (ROOT_RUNNERS_COUNT - 1))];
+ struct apprun **prev = &runners_by_runid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
runner->next_by_pgid = *prev;
*prev = runner;
}
@@ -93,8 +93,11 @@ static struct apprun *runner_of_pid(pid_t pid)
{
/* try avoiding system call */
struct apprun *result = runner_of_pgid(pid);
- if (result == NULL)
+ if (result == NULL) {
result = runner_of_pgid(getpgid(pid));
+ if (result && result->pids[1] != pid)
+ result = NULL;
+ }
return result;
}
@@ -130,20 +133,24 @@ static struct apprun *createrunner(json_object *appli)
struct apprun *result;
struct apprun **prev;
- if (runnercount >= MAX_RUNNER_COUNT)
+ if (runnercount >= MAX_RUNNER_COUNT) {
+ errno = EAGAIN;
return NULL;
+ }
do {
runnerid++;
if (runnerid > MAX_RUNNER_COUNT)
runnerid = 1;
} while(getrunner(runnerid));
result = calloc(1, sizeof * result);
- if (result) {
+ if (result == NULL)
+ errno = ENOMEM;
+ else {
prev = &runners_by_runid[runnerid & (ROOT_RUNNERS_COUNT - 1)];
result->next_by_runid = *prev;
result->next_by_pgid = NULL;
result->runid = runnerid;
- result->pgid = 0;
+ result->pids[0] = result->pids[1] = 0;
result->state = as_starting;
result->appli = json_object_get(appli);
*prev = result;
@@ -153,7 +160,7 @@ static struct apprun *createrunner(json_object *appli)
}
/**************** signaling ************************/
-
+#if 0
static void started(int runid)
{
}
@@ -173,7 +180,7 @@ static void terminated(int runid)
static void removed(int runid)
{
}
-
+#endif
/**************** running ************************/
static int killrunner(int runid, int sig, enum appstate tostate)
@@ -192,33 +199,126 @@ static int killrunner(int runid, int sig, enum appstate tostate)
rc = 0;
}
else {
- rc = killpg(runner->pgid, sig);
+ rc = killpg(runner->pids[0], sig);
if (!rc)
runner->state = tostate;
}
return rc;
}
-/**************** summarizing the application *********************/
-
-struct applisum {
- const char *path;
- const char *tag;
- const char *appid;
- const char *content;
- const char *type;
- const char *name;
- int width;
- int height;
+static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
+{
+ struct apprun *runner;
+
+ runner = runner_of_pgid(info->si_pid);
+ if (!runner)
+ return;
+
+ switch(info->si_code) {
+ case CLD_EXITED:
+ case CLD_KILLED:
+ case CLD_DUMPED:
+ case CLD_TRAPPED:
+ runner->state = as_terminated;
+ pgid_remove(runner);
+ break;
+
+ case CLD_STOPPED:
+ runner->state = as_stopped;
+ break;
+
+ case CLD_CONTINUED:
+ runner->state = as_running;
+ break;
+ }
+}
+
+/**************** handle af_launch_desc *********************/
+
+static int get_jstr(struct json_object *obj, const char *key, const char **value)
+{
+ json_object *data;
+ return json_object_object_get_ex(obj, key, &data)
+ && json_object_get_type(data) == json_type_string
+ && (*value = json_object_get_string(data)) != NULL;
+}
+
+static int get_jint(struct json_object *obj, const char *key, int *value)
+{
+ json_object *data;
+ return json_object_object_get_ex(obj, key, &data)
+ && json_object_get_type(data) == json_type_int
+ && ((*value = (int)json_object_get_int(data)), 1);
+}
+
+static int fill_launch_desc(struct json_object *appli, struct af_launch_desc *desc)
+{
+ json_object *pub;
+
+ /* main items */
+ if(!json_object_object_get_ex(appli, "public", &pub)
+ || !get_jstr(appli, "path", &desc->path)
+ || !get_jstr(appli, "id", &desc->tag)
+ || !get_jstr(appli, "content", &desc->content)
+ || !get_jstr(appli, "type", &desc->type)
+ || !get_jstr(pub, "name", &desc->name)
+ || !get_jint(pub, "width", &desc->width)
+ || !get_jint(pub, "height", &desc->height)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* plugins */
+ {
+ /* TODO */
+ static const char *null = NULL;
+ desc->plugins = &null;
+ }
+
+ /* finaly */
+ desc->home = homeappdir;
+ return 0;
};
/**************** API handling ************************/
int af_run_start(struct json_object *appli)
{
- const char *path;
- const char *id;
- return -1;
+ static struct apprun *runner;
+ struct af_launch_desc desc;
+ int rc;
+ sigset_t saved, blocked;
+
+ /* prepare to launch */
+ rc = fill_launch_desc(appli, &desc);
+ if (rc)
+ return rc;
+ runner = createrunner(appli);
+ if (!runner)
+ return -1;
+
+ /* block children signals until launched */
+ sigemptyset(&blocked);
+ sigaddset(&blocked, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &blocked, &saved);
+
+ /* launch now */
+ rc = af_launch(&desc, runner->pids);
+ if (rc < 0) {
+ /* fork failed */
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ ERROR("can't start, af_launch failed: %m");
+ freerunner(runner);
+ return -1;
+ }
+
+ /* insert the pid */
+ runner->state = as_running;
+ pgid_insert(runner);
+
+ /* unblock children signal now */
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return 0;
}
int af_run_terminate(int runid)
@@ -340,6 +440,7 @@ int af_run_init()
int rc;
uid_t me;
struct passwd passwd, *pw;
+ struct sigaction siga;
/* computes the 'homeappdir' */
me = geteuid();
@@ -367,7 +468,11 @@ int af_run_init()
}
/* install signal handlers */
-
+ siga.sa_flags = SA_SIGINFO | SA_NOCLDWAIT;
+ sigemptyset(&siga.sa_mask);
+ sigaddset(&siga.sa_mask, SIGCHLD);
+ siga.sa_sigaction = on_sigchld;
+ sigaction(SIGCHLD, &siga, NULL);
return 0;
}
diff --git a/src/af-usrd.c b/src/af-usrd.c
index 89e1c57..7697b96 100644
--- a/src/af-usrd.c
+++ b/src/af-usrd.c
@@ -148,6 +148,9 @@ int main(int ac, char **av)
{
LOGAUTH("afdb-usrd");
+ /* init random generator */
+ srandom((unsigned int)time(NULL));
+
/* init runners */
if (af_run_init()) {
ERROR("af_run_init failed");