aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2007-09-13 08:10:36 +0000
committerMartin Willi <martin@strongswan.org>2007-09-13 08:10:36 +0000
commitacc4aa8637c2e3c7e3de4f0bdf42e944b518ae61 (patch)
tree7da540fac49489f41ebf441d81be18a3a811f45f /src
parentd8c15900ad377d884412fef6e2d8c64447d377db (diff)
downloadstrongswan-acc4aa8637c2e3c7e3de4f0bdf42e944b518ae61.tar.bz2
strongswan-acc4aa8637c2e3c7e3de4f0bdf42e944b518ae61.tar.xz
fixed scenario loading
Diffstat (limited to 'src')
-rw-r--r--src/dumm/Makefile.am4
-rw-r--r--src/dumm/cowfs.c58
-rw-r--r--src/dumm/cowfs.h4
-rw-r--r--src/dumm/dumm.c92
-rw-r--r--src/dumm/dumm.h15
-rw-r--r--src/dumm/guest.c35
-rw-r--r--src/dumm/guest.h10
-rw-r--r--src/dumm/main.c75
-rw-r--r--src/dumm/mconsole.c31
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;
}