bridging using libbridge

rewrite of guest, does not change cwd anymore
loading of created scenarios
This commit is contained in:
Martin Willi
2007-07-30 13:20:35 +00:00
parent 70c5c34da7
commit 725e263ff3
8 changed files with 640 additions and 144 deletions
+99 -22
View File
@@ -13,7 +13,12 @@
* for more details.
*/
#include <sys/stat.h>
#define _GNU_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <debug.h>
@@ -22,16 +27,27 @@
typedef struct private_dumm_t private_dumm_t;
struct private_dumm_t {
/** public dumm interface */
dumm_t public;
/** working dir */
char *dir;
/** list of managed guests */
linked_list_t *guests;
/** list of managed bridges */
linked_list_t *bridges;
/** do not catch signals if we are destroying */
bool destroying;
};
static guest_t* create_guest(private_dumm_t *this, char *name, char *master, int mem)
/**
* Implementation of dumm_t.create_guest.
*/
static guest_t* create_guest(private_dumm_t *this, char *name, char *kernel,
char *master, int mem)
{
guest_t *guest;
guest = guest_create(name, master, mem);
guest = guest_create(this->dir, name, kernel, master, mem);
if (guest)
{
this->guests->insert_last(this->guests, guest);
@@ -39,11 +55,37 @@ static guest_t* create_guest(private_dumm_t *this, char *name, char *master, int
return guest;
}
/**
* Implementation of dumm_t.create_guest_iterator.
*/
static iterator_t* create_guest_iterator(private_dumm_t *this)
{
return this->guests->create_iterator(this->guests, TRUE);
}
}
/**
* Implementation of dumm_t.create_bridge.
*/
static bridge_t* create_bridge(private_dumm_t *this, char *name)
{
bridge_t *bridge;
bridge = bridge_create(name);
if (bridge)
{
this->bridges->insert_last(this->bridges, bridge);
}
return bridge;
}
/**
* Implementation of dumm_t.create_bridge_iterator.
*/
static iterator_t* create_bridge_iterator(private_dumm_t *this)
{
return this->bridges->create_iterator(this->bridges, TRUE);
}
/**
* Implementation of dumm_t.sigchild_handler.
*/
@@ -53,13 +95,11 @@ static void sigchild_handler(private_dumm_t *this, siginfo_t *info)
{
return;
}
switch (info->si_code)
{
case CLD_EXITED:
case CLD_KILLED:
case CLD_DUMPED:
case CLD_STOPPED:
{
iterator_t *iterator;
guest_t *guest;
@@ -81,11 +121,16 @@ static void sigchild_handler(private_dumm_t *this, siginfo_t *info)
}
}
/**
* Implementation of dumm_t.destroy
*/
static void destroy(private_dumm_t *this)
{
iterator_t *iterator;
guest_t *guest;
this->bridges->destroy_offset(this->bridges, offsetof(bridge_t, destroy));
iterator = this->guests->create_iterator(this->guests, TRUE);
while (iterator->iterate(iterator, (void**)&guest))
{
@@ -95,40 +140,72 @@ static void destroy(private_dumm_t *this)
this->destroying = TRUE;
this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy));
free(this->dir);
free(this);
}
/**
* check for a directory, create if it does not exist
* load all guests in our working dir
*/
static bool makedir(char *dir)
static void load_guests(private_dumm_t *this)
{
struct stat st;
DIR *dir;
struct dirent *ent;
guest_t *guest;
if (stat(dir, &st) != 0)
dir = opendir(this->dir);
if (dir == NULL)
{
return mkdir(dir, S_IRWXU) == 0;
return;
}
return S_ISDIR(st.st_mode);
while ((ent = readdir(dir)))
{
if (streq(ent->d_name, ".") || streq(ent->d_name, ".."))
{
continue;
}
guest = guest_load(this->dir, ent->d_name);
if (guest)
{
this->guests->insert_last(this->guests, guest);
}
else
{
DBG1("loading guest in directory '%s' failed, skipped", ent->d_name);
}
}
closedir(dir);
}
dumm_t *dumm_create()
/**
* create a dumm instance
*/
dumm_t *dumm_create(char *dir)
{
char cwd[PATH_MAX];
private_dumm_t *this = malloc_thing(private_dumm_t);
this->public.create_guest = (guest_t*(*)(dumm_t*,char*,char*,char*,int))create_guest;
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.sigchild_handler = (void(*)(dumm_t*, siginfo_t *info))sigchild_handler;
this->public.create_guest = (void*)create_guest;
this->public.create_guest_iterator = (void*)create_guest_iterator;
this->public.destroy = (void*)destroy;
if (!makedir(HOST_DIR) || !makedir(MOUNT_DIR) || !makedir(RUN_DIR))
{
free(this);
return NULL;
}
this->public.destroy = (void(*)(dumm_t*))destroy;
this->destroying = FALSE;
if (*dir == '/' || getcwd(cwd, sizeof(cwd)) == 0)
{
this->dir = strdup(dir);
}
else
{
asprintf(&this->dir, "%s/%s", cwd, dir);
}
this->guests = linked_list_create();
this->bridges = linked_list_create();
load_guests(this);
return &this->public;
}