diff options
author | Martin Willi <martin@strongswan.org> | 2007-09-13 08:10:36 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-09-13 08:10:36 +0000 |
commit | acc4aa8637c2e3c7e3de4f0bdf42e944b518ae61 (patch) | |
tree | 7da540fac49489f41ebf441d81be18a3a811f45f /src | |
parent | d8c15900ad377d884412fef6e2d8c64447d377db (diff) | |
download | strongswan-acc4aa8637c2e3c7e3de4f0bdf42e944b518ae61.tar.bz2 strongswan-acc4aa8637c2e3c7e3de4f0bdf42e944b518ae61.tar.xz |
fixed scenario loading
Diffstat (limited to 'src')
-rw-r--r-- | src/dumm/Makefile.am | 4 | ||||
-rw-r--r-- | src/dumm/cowfs.c | 58 | ||||
-rw-r--r-- | src/dumm/cowfs.h | 4 | ||||
-rw-r--r-- | src/dumm/dumm.c | 92 | ||||
-rw-r--r-- | src/dumm/dumm.h | 15 | ||||
-rw-r--r-- | src/dumm/guest.c | 35 | ||||
-rw-r--r-- | src/dumm/guest.h | 10 | ||||
-rw-r--r-- | src/dumm/main.c | 75 | ||||
-rw-r--r-- | src/dumm/mconsole.c | 31 |
9 files changed, 195 insertions, 129 deletions
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am index 5f93fab04..3356e7a57 100644 --- a/src/dumm/Makefile.am +++ b/src/dumm/Makefile.am @@ -4,9 +4,9 @@ ipsec_PROGRAMS = dumm libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c dumm_SOURCES = main.c -libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lbridge -lfuse -lutil +libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lbridge -lfuse -lutil ${xml_LIBS} dumm_LDADD = -ldumm -lreadline -INCLUDES = -I$(top_srcdir)/src/libstrongswan +INCLUDES = -I$(top_srcdir)/src/libstrongswan ${xml_CFLAGS} AM_CFLAGS = -D_FILE_OFFSET_BITS=64 diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c index 2c5dd380b..4c16c7c5d 100644 --- a/src/dumm/cowfs.c +++ b/src/dumm/cowfs.c @@ -55,14 +55,14 @@ struct private_cowfs_t { char *master; /** host filesystem path */ char *host; - /** scenario filesystem path */ - char *scen; + /** overlay filesystem path */ + char *over; /** fd of read only master filesystem */ int master_fd; /** copy on write overlay to master */ int host_fd; - /** optional scenario COW overlay */ - int scen_fd; + /** optional COW overlay */ + int over_fd; /** thread processing FUSE */ pthread_t thread; }; @@ -97,9 +97,9 @@ static int get_rd(const char *path) { private_cowfs_t *this = get_this(); - if (this->scen_fd > 0 && faccessat(this->scen_fd, path, F_OK, 0) == 0) + if (this->over_fd > 0 && faccessat(this->over_fd, path, F_OK, 0) == 0) { - return this->scen_fd; + return this->over_fd; } if (faccessat(this->host_fd, path, F_OK, 0) == 0) { @@ -114,9 +114,9 @@ static int get_rd(const char *path) static int get_wr(const char *path) { private_cowfs_t *this = get_this(); - if (this->scen_fd > 0) + if (this->over_fd > 0) { - return this->scen_fd; + return this->over_fd; } return this->host_fd; } @@ -318,7 +318,7 @@ static int cowfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, d1 = get_dir(this->master, path); d2 = get_dir(this->host, path); - d3 = get_dir(this->scen, path); + d3 = get_dir(this->over, path); if (d1) { @@ -741,9 +741,9 @@ static int cowfs_statfs(const char *path, struct statvfs *stbuf) int fd; fd = this->host_fd; - if (this->scen_fd > 0) + if (this->over_fd > 0) { - fd = this->scen_fd; + fd = this->over_fd; } if (fstatvfs(fd, stbuf) < 0) @@ -793,29 +793,29 @@ static struct fuse_operations cowfs_operations = { }; /** - * Implementation of cowfs_t.set_scenario. + * Implementation of cowfs_t.set_overlay. */ -static bool set_scenario(private_cowfs_t *this, char *path) +static bool set_overlay(private_cowfs_t *this, char *path) { - if (this->scen) + if (this->over) { - free(this->scen); - this->scen = NULL; + free(this->over); + this->over = NULL; } - if (this->scen_fd > 0) + if (this->over_fd > 0) { - close(this->scen_fd); - this->scen_fd = -1; + close(this->over_fd); + this->over_fd = -1; } if (path) { - this->scen_fd = open(path, O_RDONLY | O_DIRECTORY); - if (this->scen_fd < 0) + this->over_fd = open(path, O_RDONLY | O_DIRECTORY); + if (this->over_fd < 0) { - DBG1("failed to open scenario overlay directory '%s': %m", path); + DBG1("failed to open overlay directory '%s': %m", path); return FALSE; } - this->scen = strdup(path); + this->over = strdup(path); } return TRUE; } @@ -832,12 +832,12 @@ static void destroy(private_cowfs_t *this) free(this->mount); free(this->master); free(this->host); - free(this->scen); + free(this->over); close(this->master_fd); close(this->host_fd); - if (this->scen_fd > 0) + if (this->over_fd > 0) { - close(this->scen_fd); + close(this->over_fd); } free(this); } @@ -850,7 +850,7 @@ cowfs_t *cowfs_create(char *master, char *host, char *mount) struct fuse_args args = {0, NULL, 0}; private_cowfs_t *this = malloc_thing(private_cowfs_t); - this->public.set_scenario = (bool(*)(cowfs_t*, char *path))set_scenario; + this->public.set_overlay = (bool(*)(cowfs_t*, char *path))set_overlay; this->public.destroy = (void(*)(cowfs_t*))destroy; this->master_fd = open(master, O_RDONLY | O_DIRECTORY); @@ -866,7 +866,7 @@ cowfs_t *cowfs_create(char *master, char *host, char *mount) close(this->master_fd); free(this); } - this->scen_fd = -1; + this->over_fd = -1; this->chan = fuse_mount(mount, &args); if (this->chan == NULL) @@ -893,7 +893,7 @@ cowfs_t *cowfs_create(char *master, char *host, char *mount) this->mount = strdup(mount); this->master = strdup(master); this->host = strdup(host); - this->scen = NULL; + this->over = NULL; if (pthread_create(&this->thread, NULL, (void*)fuse_loop, this->fuse) != 0) { diff --git a/src/dumm/cowfs.h b/src/dumm/cowfs.h index fb1fc35a7..419197dd6 100644 --- a/src/dumm/cowfs.h +++ b/src/dumm/cowfs.h @@ -27,12 +27,12 @@ typedef struct cowfs_t cowfs_t; struct cowfs_t { /** - * @brief Set the scenario copy on write overlay. + * @brief Set an additional copy on write overlay. * * @param path path of the overlay * @return FALSE if failed */ - bool (*set_scenario)(cowfs_t *this, char *path); + bool (*set_overlay)(cowfs_t *this, char *path); /** * @brief Stop, umount and destroy a cowfs FUSE filesystem. diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c index cfe403f7e..560ab8d19 100644 --- a/src/dumm/dumm.c +++ b/src/dumm/dumm.c @@ -21,6 +21,8 @@ #include <stdio.h> #include <dirent.h> #include <errno.h> +#include <libxml/xmlreader.h> +#include <libxml/xmlwriter.h> #include <debug.h> @@ -28,8 +30,8 @@ #define PERME (S_IRWXU | S_IRWXG) #define GUEST_DIR "guests" -#define SCENARIO_DIR "scenarios" -#define SCENARIO_DIFF_DIR "diff" +#define TEMPLATE_DIR "templates" +#define TEMPLATE_DIR_DIR "diff" /** * instances of dumm, used to deliver signals @@ -45,10 +47,10 @@ struct private_dumm_t { char *dir; /** directory of guests */ char *guest_dir; - /** directory of scenarios */ - char *scenario_dir; - /** directory of loaded scenario */ - char *scenario; + /** directory of templates */ + char *template_dir; + /** directory of loaded template */ + char *template; /** list of managed guests */ linked_list_t *guests; /** list of managed bridges */ @@ -105,73 +107,77 @@ static iterator_t* create_bridge_iterator(private_dumm_t *this) } /** - * disable the currently enabled scenario + * disable the currently enabled template */ -static void clear_scenario(private_dumm_t *this) +static void clear_template(private_dumm_t *this) { - iterator_t *iterator; + iterator_t *iterator, *ifaces; guest_t *guest; + iface_t *iface; - free(this->scenario); - this->scenario = NULL; + free(this->template); + this->template = NULL; iterator = this->guests->create_iterator(this->guests, TRUE); while (iterator->iterate(iterator, (void**)&guest)) { - guest->set_scenario(guest, NULL); + guest->load_template(guest, NULL); + ifaces = guest->create_iface_iterator(guest); + while (ifaces->iterate(ifaces, (void**)&iface)) + { + ifaces->remove(ifaces); + iface->destroy(iface); + } + ifaces->destroy(ifaces); } iterator->destroy(iterator); } /** - * Implementation of dumm_t.load_scenario. + * Implementation of dumm_t.load_template. */ -static bool load_scenario(private_dumm_t *this, char *name) +static bool load_template(private_dumm_t *this, char *name) { iterator_t *iterator; guest_t *guest; char dir[PATH_MAX]; size_t len; + clear_template(this); + if (name == NULL) { - clear_scenario(this); return TRUE; } - free(this->scenario); - asprintf(&this->scenario, "%s/%s", this->scenario_dir, name); - mkdir(this->scenario_dir, PERME); - - len = snprintf(dir, sizeof(dir), "%s/%s", this->scenario, SCENARIO_DIFF_DIR); + free(this->template); + asprintf(&this->template, "%s/%s", this->template_dir, name); + len = snprintf(dir, sizeof(dir), "%s/%s", this->template, TEMPLATE_DIR_DIR); if (len < 0 || len >= sizeof(dir)) { - clear_scenario(this); return FALSE; } - if (access(this->scenario, F_OK) != 0) - { /* does not exist, create scenario */ - if (mkdir(this->scenario, PERME) != 0) + if (access(this->template, F_OK) != 0) + { /* does not exist, create template */ + if (mkdir(this->template, PERME) != 0) { - DBG1("creating scenario directory '%s' failed: %m", this->scenario); - clear_scenario(this); + DBG1("creating template directory '%s' failed: %m", this->template); return FALSE; } if (mkdir(dir, PERME) != 0) { - DBG1("creating scenario overlay directory '%s' failed: %m", dir); - clear_scenario(this); + DBG1("creating template overlay directory '%s' failed: %m", dir); return FALSE; } } iterator = this->guests->create_iterator(this->guests, TRUE); while (iterator->iterate(iterator, (void**)&guest)) { - if (!guest->set_scenario(guest, dir)) + if (!guest->load_template(guest, dir)) { iterator->destroy(iterator); - clear_scenario(this); + clear_template(this); return FALSE; } } @@ -180,15 +186,6 @@ static bool load_scenario(private_dumm_t *this, char *name) } /** - * Implementation of dumm_t.save_scenario. - */ -static bool save_scenario(private_dumm_t *this) -{ - DBG1("scenario loading unimplemented."); - return FALSE; -} - -/** * signal handler */ void signal_handler(int sig, siginfo_t *info, void *ucontext) @@ -303,8 +300,8 @@ static void destroy(private_dumm_t *this) this->destroying = TRUE; this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy)); free(this->guest_dir); - free(this->scenario_dir); - free(this->scenario); + free(this->template_dir); + free(this->template); free(this->dir); remove_instance(this); free(this); @@ -357,8 +354,7 @@ dumm_t *dumm_create(char *dir) this->public.create_guest_iterator = (iterator_t*(*)(dumm_t*))create_guest_iterator; this->public.create_bridge = (bridge_t*(*)(dumm_t*, char *name))create_bridge; this->public.create_bridge_iterator = (iterator_t*(*)(dumm_t*))create_bridge_iterator; - this->public.load_scenario = (bool(*)(dumm_t*, char *name))load_scenario; - this->public.save_scenario = (bool(*)(dumm_t*))save_scenario; + this->public.load_template = (bool(*)(dumm_t*, char *name))load_template; this->public.destroy = (void(*)(dumm_t*))destroy; this->destroying = FALSE; @@ -370,9 +366,9 @@ dumm_t *dumm_create(char *dir) { asprintf(&this->dir, "%s/%s", cwd, dir); } - this->scenario = NULL; + this->template = NULL; asprintf(&this->guest_dir, "%s/%s", this->dir, GUEST_DIR); - asprintf(&this->scenario_dir, "%s/%s", this->dir, SCENARIO_DIR); + asprintf(&this->template_dir, "%s/%s", this->dir, TEMPLATE_DIR); this->guests = linked_list_create(); this->bridges = linked_list_create(); @@ -384,6 +380,12 @@ dumm_t *dumm_create(char *dir) destroy(this); return NULL; } + if (mkdir(this->template_dir, PERME) < 0 && errno != EEXIST) + { + DBG1("creating template directory '%s' failed: %m", this->template_dir); + destroy(this); + return NULL; + } load_guests(this); return &this->public; diff --git a/src/dumm/dumm.h b/src/dumm/dumm.h index 6fc32799b..349e6f11b 100644 --- a/src/dumm/dumm.h +++ b/src/dumm/dumm.h @@ -70,19 +70,12 @@ struct dumm_t { iterator_t* (*create_bridge_iterator)(dumm_t *this); /** - * @brief Loads a scenario, create a new one if it does not exist. + * @brief Loads a template, create a new one if it does not exist. * - * @param name name of the scenario to load/create - * @return FALSE if load/crate failed + * @param name name of the template, NULL to clonse + * @return FALSE if load/create failed */ - bool (*load_scenario)(dumm_t *this, char *name); - - /** - * @brief Saves the current loaded scenario. - * - * @return FALSE if saving scenario failed - */ - bool (*save_scenario)(dumm_t *this); + bool (*load_template)(dumm_t *this, char *name); /** * @brief stop all guests and destroy the modeler diff --git a/src/dumm/guest.c b/src/dumm/guest.c index b74449cb3..bbb59f431 100644 --- a/src/dumm/guest.c +++ b/src/dumm/guest.c @@ -69,19 +69,6 @@ struct private_guest_t { cowfs_t *cowfs; /** mconsole to control running UML */ mconsole_t *mconsole; - /** pty consoles */ - struct { - /** pty master fd */ - int master; - /** pty slave fd */ - int slave; - /** name of the pty */ - char name[16]; - /** currently in use */ - bool occupied; - /** is valid */ - bool valid; - } pty[PTYS]; /** list of interfaces attached to the guest */ linked_list_t *ifaces; }; @@ -273,16 +260,16 @@ static bool start(private_guest_t *this) } /** - * Implementation of guest_t.set_scenario. + * Implementation of guest_t.load_template. */ -static bool set_scenario(private_guest_t *this, char *path) +static bool load_template(private_guest_t *this, char *path) { char dir[PATH_MAX]; size_t len; if (path == NULL) { - return this->cowfs->set_scenario(this->cowfs, NULL); + return this->cowfs->set_overlay(this->cowfs, NULL); } len = snprintf(dir, sizeof(dir), "%s/%s", path, this->name); @@ -294,11 +281,11 @@ static bool set_scenario(private_guest_t *this, char *path) { if (mkdir(dir, PERME) != 0) { - DBG1("creating scenario overlay for guest '%s' failed: %m", this->name); + DBG1("creating overlay for guest '%s' failed: %m", this->name); return FALSE; } } - return this->cowfs->set_scenario(this->cowfs, dir); + return this->cowfs->set_overlay(this->cowfs, dir); } /** @@ -306,22 +293,12 @@ static bool set_scenario(private_guest_t *this, char *path) */ static void sigchild(private_guest_t *this) { - int i; - if (this->state != GUEST_STOPPING) { /* collect zombie if uml crashed */ waitpid(this->pid, NULL, WNOHANG); } DESTROY_IF(this->mconsole); this->mconsole = NULL; - for (i = 0; i < PTYS; i++) - { - if (this->pty[i].valid) - { - close(this->pty[i].master); - close(this->pty[i].slave); - } - } this->state = GUEST_STOPPED; } @@ -457,7 +434,7 @@ static private_guest_t *guest_create_generic(char *parent, char *name, this->public.start = (void*)start; this->public.stop = (void*)stop; this->public.get_console = (char*(*)(guest_t*,int))get_console; - this->public.set_scenario = (bool(*)(guest_t*, char *path))set_scenario; + this->public.load_template = (bool(*)(guest_t*, char *path))load_template; this->public.sigchild = (void(*)(guest_t*))sigchild; this->public.destroy = (void*)destroy; diff --git a/src/dumm/guest.h b/src/dumm/guest.h index 10d42cb92..10b37aaa7 100644 --- a/src/dumm/guest.h +++ b/src/dumm/guest.h @@ -89,10 +89,10 @@ struct guest_t { /** * @brief Get a console pts device. * - * Every guest has 6 consoles, numbered from 1 to 6. These are associated + * Every guest has 5 consoles, numbered from 1 to 5. These are associated * to a unique pts device on the host. * - * @param console console number to get (1-6) + * @param console console number to get (1-5) * @return pts device file name, NULL if failed */ char* (*get_console) (guest_t *this, int console); @@ -113,12 +113,12 @@ struct guest_t { iterator_t* (*create_iface_iterator)(guest_t *this); /** - * @brief Set the scenario COWFS overlay to use. + * @brief Set the template COWFS overlay to use. * - * @param parent parent directory where scenario diff should point to + * @param parent parent directory where template diff should point to * @return FALSE if failed */ - bool (*set_scenario)(guest_t *this, char *parent); + bool (*load_template)(guest_t *this, char *parent); /** * @brief Called whenever a SIGCHILD for the guests PID is received. diff --git a/src/dumm/main.c b/src/dumm/main.c index b4c435256..d6e142e24 100644 --- a/src/dumm/main.c +++ b/src/dumm/main.c @@ -21,6 +21,8 @@ #include <library.h> #include <readline/readline.h> #include <readline/history.h> +#include <dlfcn.h> +#include <dirent.h> #include "dumm.h" @@ -469,17 +471,73 @@ static void bridge_list_menu() } } -static void scenario_menu() +static void template_menu() { char *name; - name = get_line("scenario name (or 'none'): "); + name = get_line("template name (or 'none'): "); - dumm->load_scenario(dumm, streq(name, "none") ? NULL : name); + dumm->load_template(dumm, streq(name, "none") ? NULL : name); free(name); } +typedef bool (*uml_test_t)(dumm_t *dumm); + +static void test_menu() +{ + char *name; + void *handle; + struct dirent *ent; + DIR *dir; + uml_test_t test; + + name = get_line("test name: "); + + dir = opendir("tests"); + if (dir) + { + while ((ent = readdir(dir))) + { + char buf[PATH_MAX]; + size_t len; + + len = strlen(ent->d_name); + if (strlen(ent->d_name) < 4 || !streq(ent->d_name + len - 3, ".so")) + { + continue; + } + + snprintf(buf, sizeof(buf), "%s/%s", "tests", ent->d_name); + handle = dlopen(buf, RTLD_LAZY); + if (!handle) + { + printf("failed to open test %s\n", ent->d_name); + continue; + } + test = dlsym(handle, "test"); + if (test && dumm->load_template(dumm, ent->d_name)) + { + printf("running test %s: ", ent->d_name); + if (test(dumm)) + { + printf("success\n"); + } + else + { + printf("failed\n"); + } + } + else + { + printf("failed to open test %s\n", ent->d_name); + } + dlclose(handle); + } + } + free(name); +} + /** * Signal handler */ @@ -552,16 +610,21 @@ int main(int argc, char *argv[]) { bridge_list_menu(); } - else if (streq(line, "scenario")) + else if (streq(line, "template")) + { + template_menu(); + } + else if (streq(line, "test")) { - scenario_menu(); + test_menu(); } else { - printf("quit|guest|bridge|scenario\n"); + printf("quit|guest|bridge|template|test\n"); } free(line); } + dumm->load_template(dumm, NULL); dumm->destroy(dumm); clear_history(); return 0; diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c index 77578238b..25cb84621 100644 --- a/src/dumm/mconsole.c +++ b/src/dumm/mconsole.c @@ -200,6 +200,31 @@ static char* get_console_pts(private_mconsole_t *this, int con) } /** + * Poll until guest is ready + */ +static bool wait_bootup(private_mconsole_t *this) +{ + char *cmd, buf[128]; + int len, res; + + cmd = "config con0"; + while (TRUE) + { + len = sizeof(buf); + res = request(this, cmd, buf, &len); + if (res < 0) + { + return FALSE; + } + if (res == 0) + { + return TRUE; + } + usleep(50000); + } +} + +/** * Implementation of mconsole_t.destroy. */ static void destroy(private_mconsole_t *this) @@ -313,6 +338,12 @@ mconsole_t *mconsole_create(char *notify) } unlink(notify); + if (!wait_bootup(this)) + { + destroy(this); + return NULL; + } + return &this->public; } |