diff options
author | Martin Willi <martin@strongswan.org> | 2008-04-28 16:43:30 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-04-28 16:43:30 +0000 |
commit | a47486b5e4386b85c0a01424ba83930af8593ccc (patch) | |
tree | 154ab6a41116c1acb054a39ace0b6863ea8ab692 /src/dumm/guest.c | |
parent | e8a680d94a541bba152a45422580930fbdcee8eb (diff) | |
download | strongswan-a47486b5e4386b85c0a01424ba83930af8593ccc.tar.bz2 strongswan-a47486b5e4386b85c0a01424ba83930af8593ccc.tar.xz |
prototype of dumm GUI
Diffstat (limited to 'src/dumm/guest.c')
-rw-r--r-- | src/dumm/guest.c | 143 |
1 files changed, 67 insertions, 76 deletions
diff --git a/src/dumm/guest.c b/src/dumm/guest.c index bbb59f431..58539b751 100644 --- a/src/dumm/guest.c +++ b/src/dumm/guest.c @@ -63,8 +63,6 @@ struct private_guest_t { int pid; /** state of guest */ guest_state_t state; - /** log file for console 0 */ - int bootlog; /** FUSE cowfs instance */ cowfs_t *cowfs; /** mconsole to control running UML */ @@ -94,7 +92,7 @@ static char* get_name(private_guest_t *this) */ static iface_t* create_iface(private_guest_t *this, char *name) { - iterator_t *iterator; + enumerator_t *enumerator; iface_t *iface; if (this->state != GUEST_RUNNING) @@ -103,17 +101,17 @@ static iface_t* create_iface(private_guest_t *this, char *name) return NULL; } - iterator = this->ifaces->create_iterator(this->ifaces, TRUE); - while (iterator->iterate(iterator, (void**)&iface)) + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, (void**)&iface)) { if (streq(name, iface->get_guestif(iface))) { DBG1("guest '%s' already has an interface '%s'", this->name, name); - iterator->destroy(iterator); + enumerator->destroy(enumerator); return NULL; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); iface = iface_create(this->name, name, this->mconsole); if (iface) @@ -124,11 +122,32 @@ static iface_t* create_iface(private_guest_t *this, char *name) } /** - * Implementation of guest_t.create_iface_iterator. + * Implementation of guest_t.destroy_iface. */ -static iterator_t* create_iface_iterator(private_guest_t *this) +static void destroy_iface(private_guest_t *this, iface_t *iface) { - return this->ifaces->create_iterator(this->ifaces, TRUE); + enumerator_t *enumerator; + iface_t *current; + + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, (void**)¤t)) + { + if (current == iface) + { + this->ifaces->remove_at(this->ifaces, enumerator); + current->destroy(current); + break; + } + } + enumerator->destroy(enumerator); +} + +/** + * Implementation of guest_t.create_iface_enumerator. + */ +static enumerator_t* create_iface_enumerator(private_guest_t *this) +{ + return this->ifaces->create_enumerator(this->ifaces); } /** @@ -170,21 +189,9 @@ static char* write_arg(char **pos, size_t *left, char *format, ...) } /** - * Implementation of get_t.close_console. - */ -static char* get_console(private_guest_t *this, int console) -{ - if (this->state == GUEST_RUNNING) - { - return this->mconsole->get_console_pts(this->mconsole, console); - } - return NULL; -} - -/** * Implementation of guest_t.stop. */ -static void stop(private_guest_t *this) +static void stop(private_guest_t *this, idle_function_t idle) { if (this->state != GUEST_STOPPED) { @@ -192,23 +199,35 @@ static void stop(private_guest_t *this) this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy)); this->ifaces = linked_list_create(); kill(this->pid, SIGINT); - waitpid(this->pid, NULL, 0); - this->state = GUEST_STOPPED; + while (this->state != GUEST_STOPPED) + { + if (idle) + { + idle(); + } + else + { + usleep(50000); + } + } } } /** * Implementation of guest_t.start. */ -static bool start(private_guest_t *this) +static bool start(private_guest_t *this, invoke_function_t invoke, void* data, + idle_function_t idle) { char buf[2048]; char *notify; char *pos = buf; - char *args[16]; + char *args[32]; int i = 0; size_t left = sizeof(buf); + memset(args, 0, sizeof(args)); + if (this->state != GUEST_STOPPED) { DBG1("unable to start guest in state %N", guest_state_names, this->state); @@ -226,32 +245,20 @@ static bool start(private_guest_t *this) args[i++] = write_arg(&pos, &left, "umid=%s", this->name); args[i++] = write_arg(&pos, &left, "mem=%dM", this->mem); args[i++] = write_arg(&pos, &left, "mconsole=notify:%s", notify); - args[i++] = write_arg(&pos, &left, "con=pts"); - args[i++] = write_arg(&pos, &left, "con0=none,fd:%d", this->bootlog); - args[i++] = NULL; + args[i++] = write_arg(&pos, &left, "con=null"); - this->pid = fork(); - switch (this->pid) - { - case 0: /* child, */ - dup2(open("/dev/null", 0), 0); - dup2(this->bootlog, 1); - dup2(this->bootlog, 2); - execvp(args[0], args); - DBG1("starting UML kernel '%s' failed: %m", args[0]); - exit(1); - case -1: - this->state = GUEST_STOPPED; - return FALSE; - default: - break; + this->pid = invoke(data, &this->public, args, i); + if (!this->pid) + { + this->state = GUEST_STOPPED; + return FALSE; } /* open mconsole */ - this->mconsole = mconsole_create(notify); + this->mconsole = mconsole_create(notify, idle); if (this->mconsole == NULL) { DBG1("opening mconsole at '%s' failed, stopping guest", buf); - stop(this); + stop(this, NULL); return FALSE; } @@ -266,6 +273,7 @@ static bool load_template(private_guest_t *this, char *path) { char dir[PATH_MAX]; size_t len; + iface_t *iface; if (path == NULL) { @@ -285,7 +293,15 @@ static bool load_template(private_guest_t *this, char *path) return FALSE; } } - return this->cowfs->set_overlay(this->cowfs, dir); + if (!this->cowfs->set_overlay(this->cowfs, dir)) + { + return FALSE; + } + while (this->ifaces->remove_last(this->ifaces, (void**)&iface) == SUCCESS) + { + iface->destroy(iface); + } + return TRUE; } /** @@ -293,10 +309,6 @@ static bool load_template(private_guest_t *this, char *path) */ static void sigchild(private_guest_t *this) { - if (this->state != GUEST_STOPPING) - { /* collect zombie if uml crashed */ - waitpid(this->pid, NULL, WNOHANG); - } DESTROY_IF(this->mconsole); this->mconsole = NULL; this->state = GUEST_STOPPED; @@ -341,22 +353,6 @@ static bool mount_unionfs(private_guest_t *this) } /** - * open logfile for boot messages - */ -static int open_bootlog(private_guest_t *this) -{ - int fd; - - fd = openat(this->dir, LOG_FILE, O_WRONLY | O_CREAT, PERM); - if (fd == -1) - { - DBG1("opening bootlog failed, using stdout"); - return 1; - } - return fd; -} - -/** * load memory configuration from file */ int loadmem(private_guest_t *this) @@ -402,12 +398,8 @@ bool savemem(private_guest_t *this, int mem) */ static void destroy(private_guest_t *this) { - stop(this); + stop(this, NULL); umount_unionfs(this); - if (this->bootlog > 1) - { - close(this->bootlog); - } if (this->dir > 0) { close(this->dir); @@ -430,10 +422,10 @@ static private_guest_t *guest_create_generic(char *parent, char *name, this->public.get_pid = (pid_t(*)(guest_t*))get_pid; this->public.get_state = (guest_state_t(*)(guest_t*))get_state; this->public.create_iface = (iface_t*(*)(guest_t*,char*))create_iface; - this->public.create_iface_iterator = (iterator_t*(*)(guest_t*))create_iface_iterator; + this->public.destroy_iface = (void(*)(guest_t*,iface_t*))destroy_iface; + this->public.create_iface_enumerator = (enumerator_t*(*)(guest_t*))create_iface_enumerator; this->public.start = (void*)start; this->public.stop = (void*)stop; - this->public.get_console = (char*(*)(guest_t*,int))get_console; this->public.load_template = (bool(*)(guest_t*, char *path))load_template; this->public.sigchild = (void(*)(guest_t*))sigchild; this->public.destroy = (void*)destroy; @@ -464,7 +456,6 @@ static private_guest_t *guest_create_generic(char *parent, char *name, this->mconsole = NULL; this->ifaces = linked_list_create(); this->mem = 0; - this->bootlog = open_bootlog(this); this->name = strdup(name); this->cowfs = NULL; |