dumm: Remove the Dynamic UML Mesh Modeler framework
authorTobias Brunner <tobias@strongswan.org>
Wed, 12 Sep 2018 09:02:32 +0000 (11:02 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 12 Sep 2018 13:53:55 +0000 (15:53 +0200)
This has been pretty much defunct for several years (requires a
specially patched UML-enabled guest kernel).

31 files changed:
configure.ac
scripts/test.sh
src/Makefile.am
src/dumm/.gitignore [deleted file]
src/dumm/Makefile.am [deleted file]
src/dumm/bridge.c [deleted file]
src/dumm/bridge.h [deleted file]
src/dumm/cowfs.c [deleted file]
src/dumm/cowfs.h [deleted file]
src/dumm/dumm.c [deleted file]
src/dumm/dumm.h [deleted file]
src/dumm/ext/.gitignore [deleted file]
src/dumm/ext/README [deleted file]
src/dumm/ext/dumm.c [deleted file]
src/dumm/ext/extconf.rb.in [deleted file]
src/dumm/ext/lib/dumm.rb [deleted file]
src/dumm/ext/lib/dumm/guest.rb [deleted file]
src/dumm/guest.c [deleted file]
src/dumm/guest.h [deleted file]
src/dumm/iface.c [deleted file]
src/dumm/iface.h [deleted file]
src/dumm/irdumm.c [deleted file]
src/dumm/main.c [deleted file]
src/dumm/mconsole.c [deleted file]
src/dumm/mconsole.h [deleted file]
src/dumm/patches/mconsole-exec-2.6.26.patch [deleted file]
src/dumm/patches/mconsole-exec-2.6.27.patch [deleted file]
src/dumm/patches/mconsole-exec-2.6.28.patch [deleted file]
src/dumm/patches/mconsole-exec-2.6.29.patch [deleted file]
src/dumm/patches/mconsole-exec-2.6.30.patch [deleted file]
src/dumm/scripts/start_testing.rb [deleted file]

index ac9ca9b..26fd707 100644 (file)
@@ -280,7 +280,6 @@ ARG_ENABL_SET([aikgen],         [enable AIK generator for TPM 1.2.])
 ARG_DISBL_SET([charon],         [disable the IKEv1/IKEv2 keying daemon charon.])
 ARG_ENABL_SET([cmd],            [enable the command line IKE client charon-cmd.])
 ARG_ENABL_SET([conftest],       [enforce Suite B conformance test framework.])
-ARG_ENABL_SET([dumm],           [enable the DUMM UML test framework.])
 ARG_ENABL_SET([fast],           [enable libfast (FastCGI Application Server w/ templates.])
 ARG_ENABL_SET([fuzzing],        [enable fuzzing scripts (found in directory fuzz).])
 ARG_ENABL_SET([libipsec],       [enable user space IPsec implementation.])
@@ -1051,18 +1050,6 @@ if test x$imc_swima = xtrue -o $imv_swima = xtrue; then
        AC_SUBST(json_LIBS)
 fi
 
-if test x$dumm = xtrue; then
-       PKG_CHECK_MODULES(gtk, [gtk+-2.0 vte])
-       AC_SUBST(gtk_CFLAGS)
-       AC_SUBST(gtk_LIBS)
-       AC_CHECK_PROGS(RUBY, ruby)
-       PKG_CHECK_MODULES(ruby, [ruby])
-       saved_LIBS=$LIBS
-       LIBS=$ruby_LIBS
-       AC_CHECK_FUNCS(rb_errinfo)
-       LIBS=$saved_LIBS
-fi
-
 if test x$fast = xtrue; then
        AC_CHECK_LIB([neo_utl],[hdf_init],[LIBS="$LIBS"],[AC_MSG_ERROR([ClearSilver library neo_utl not found!])],[])
        AC_MSG_CHECKING([for -lneo_cgi and dependencies])
@@ -1691,7 +1678,6 @@ AM_CONDITIONAL(USE_COUNTERS, test x$counters = xtrue)
 # ---------------
 AM_CONDITIONAL(USE_LEAK_DETECTIVE, test x$leak_detective = xtrue)
 AM_CONDITIONAL(USE_LOCK_PROFILER, test x$lock_profiler = xtrue)
-AM_CONDITIONAL(USE_DUMM, test x$dumm = xtrue)
 AM_CONDITIONAL(USE_FAST, test x$fast = xtrue)
 AM_CONDITIONAL(USE_MANAGER, test x$manager = xtrue)
 AM_CONDITIONAL(USE_ME, test x$mediation = xtrue)
@@ -2001,8 +1987,6 @@ AC_CONFIG_FILES([
        src/pki/Makefile
        src/pki/man/Makefile
        src/pool/Makefile
-       src/dumm/Makefile
-       src/dumm/ext/extconf.rb
        src/libfast/Makefile
        src/manager/Makefile
        src/medsrv/Makefile
index 821275e..58dc730 100755 (executable)
@@ -31,7 +31,7 @@ printf-builtin)
        ;;
 all|coverage|sonarcloud)
        CONFIG="--enable-all --disable-android-dns --disable-android-log
-                       --disable-dumm --disable-kernel-pfroute --disable-keychain
+                       --disable-kernel-pfroute --disable-keychain
                        --disable-lock-profiler --disable-padlock --disable-fuzzing
                        --disable-osx-attr --disable-tkm --disable-uci
                        --disable-systemd --disable-soup --disable-unwind-backtraces
index e2747c3..6eacbe2 100644 (file)
@@ -88,10 +88,6 @@ if USE_CONFTEST
   SUBDIRS += conftest
 endif
 
-if USE_DUMM
-  SUBDIRS += dumm
-endif
-
 if USE_FAST
   SUBDIRS += libfast
 endif
diff --git a/src/dumm/.gitignore b/src/dumm/.gitignore
deleted file mode 100644 (file)
index 2b08867..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-dumm
-irdumm
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
deleted file mode 100644 (file)
index 0d1cfb7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-EXTRA_DIST = ext/dumm.c ext/README \
-  ext/lib/dumm.rb ext/lib/dumm/guest.rb
-
-ipseclib_LTLIBRARIES = libdumm.la
-ipsec_PROGRAMS = dumm irdumm
-
-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
-irdumm_SOURCES = irdumm.c
-
-libdumm_la_LIBADD = -lbridge -lfuse -lutil $(top_builddir)/src/libstrongswan/libstrongswan.la
-dumm_LDADD = libdumm.la ${gtk_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
-irdumm_LDADD = libdumm.la ${ruby_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
-
-AM_CPPFLAGS = \
-       -D_FILE_OFFSET_BITS=64 \
-       -I$(top_srcdir)/src/libstrongswan
-
-dumm_CFLAGS = ${gtk_CFLAGS}
-irdumm_CFLAGS = ${ruby_CFLAGS}
-
-all-local: ext
-
-clean-local:
-       (test -f ext/Makefile && cd ext && $(MAKE) clean && rm Makefile || true)
-
-install-data-local:
-       (test -f ext/Makefile && cd ext && $(MAKE) install)
-
-ext:   libdumm.la
-       (cd ext && $(RUBY) extconf.rb && $(MAKE))
-
-.PHONY: ext
diff --git a/src/dumm/bridge.c b/src/dumm/bridge.c
deleted file mode 100644 (file)
index 536e275..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <libbridge.h>
-
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-
-#include "bridge.h"
-
-typedef struct private_bridge_t private_bridge_t;
-
-struct private_bridge_t {
-       /** public interface */
-       bridge_t public;
-       /** device name */
-       char *name;
-       /** list of attached interfaces */
-       linked_list_t *ifaces;
-};
-
-/**
- * defined in iface.c
- */
-bool iface_control(char *name, bool up);
-
-METHOD(bridge_t, get_name, char*,
-       private_bridge_t *this)
-{
-       return this->name;
-}
-
-METHOD(bridge_t, create_iface_enumerator, enumerator_t*,
-       private_bridge_t *this)
-{
-       return this->ifaces->create_enumerator(this->ifaces);
-}
-
-METHOD(bridge_t, disconnect_iface, bool,
-       private_bridge_t *this, iface_t *iface)
-{
-       enumerator_t *enumerator;
-       iface_t *current = NULL;
-       bool good = FALSE;
-
-       enumerator = this->ifaces->create_enumerator(this->ifaces);
-       while (enumerator->enumerate(enumerator, (void**)&current))
-       {
-               if (current == iface)
-               {
-                       if (br_del_interface(this->name, iface->get_hostif(iface)) != 0)
-                       {
-                               DBG1(DBG_LIB, "removing iface '%s' from bridge '%s' in kernel"
-                                        " failed: %m", iface->get_hostif(iface), this->name);
-                       }
-                       else
-                       {
-                               iface->set_bridge(iface, NULL);
-                               this->ifaces->remove_at(this->ifaces, enumerator);
-                               good = TRUE;
-                       }
-                       break;
-               }
-       }
-       if (iface != current)
-       {
-               DBG1(DBG_LIB, "iface '%s' not found on bridge '%s'",
-                        iface->get_hostif(iface), this->name);
-       }
-       enumerator->destroy(enumerator);
-       return good;
-}
-
-METHOD(bridge_t, connect_iface, bool,
-       private_bridge_t *this, iface_t *iface)
-{
-       if (br_add_interface(this->name, iface->get_hostif(iface)) != 0)
-       {
-               DBG1(DBG_LIB, "adding iface '%s' to bridge '%s' failed: %m",
-                        iface->get_hostif(iface), this->name);
-               return FALSE;
-       }
-       iface->set_bridge(iface, &this->public);
-       this->ifaces->insert_last(this->ifaces, iface);
-       return TRUE;
-}
-
-/**
- * instance counter to (de-)initialize libbridge
- */
-static int instances = 0;
-
-METHOD(bridge_t, destroy, void,
-       private_bridge_t *this)
-{
-       enumerator_t *enumerator;
-       iface_t *iface;
-
-       enumerator = this->ifaces->create_enumerator(this->ifaces);
-       while (enumerator->enumerate(enumerator, (void**)&iface))
-       {
-               if (br_del_interface(this->name, iface->get_hostif(iface)) != 0)
-               {
-                       DBG1(DBG_LIB, "disconnecting iface '%s' failed: %m",
-                                iface->get_hostif(iface));
-               }
-               iface->set_bridge(iface, NULL);
-       }
-       enumerator->destroy(enumerator);
-       this->ifaces->destroy(this->ifaces);
-       iface_control(this->name, FALSE);
-       if (br_del_bridge(this->name) != 0)
-       {
-               DBG1(DBG_LIB, "deleting bridge '%s' from kernel failed: %m",
-                        this->name);
-       }
-       free(this->name);
-       free(this);
-       if (--instances == 0)
-       {
-               br_shutdown();
-       }
-}
-
-/**
- * create the bridge instance
- */
-bridge_t *bridge_create(char *name)
-{
-       private_bridge_t *this;
-
-       if (instances == 0)
-       {
-               if (br_init() != 0)
-               {
-                       DBG1(DBG_LIB, "libbridge initialization failed: %m");
-                       return NULL;
-               }
-       }
-
-       INIT(this,
-               .public = {
-                       .get_name = _get_name,
-                       .create_iface_enumerator = _create_iface_enumerator,
-                       .disconnect_iface = _disconnect_iface,
-                       .connect_iface = _connect_iface,
-                       .destroy = _destroy,
-               }
-       );
-
-       if (br_add_bridge(name) != 0)
-       {
-               DBG1(DBG_LIB, "creating bridge '%s' failed: %m", name);
-               free(this);
-               return NULL;
-       }
-       if (!iface_control(name, TRUE))
-       {
-               DBG1(DBG_LIB, "bringing bridge '%s' up failed: %m", name);
-       }
-
-       this->name = strdup(name);
-       this->ifaces = linked_list_create();
-
-       instances++;
-       return &this->public;
-}
diff --git a/src/dumm/bridge.h b/src/dumm/bridge.h
deleted file mode 100644 (file)
index 5069cfd..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef BRIDGE_H
-#define BRIDGE_H
-
-#include <library.h>
-#include <collections/enumerator.h>
-
-typedef struct bridge_t bridge_t;
-
-#include "iface.h"
-
-/**
- * Interface in a guest, connected to a tap device on the host.
- */
-struct bridge_t {
-
-       /**
-        * Get the name of the bridge.
-        *
-        * @return                      name of the bridge
-        */
-       char* (*get_name)(bridge_t *this);
-
-       /**
-        * Add an interface to a bridge.
-        *
-        * @param iface         interface to add
-        * @return                      TRUE if interface added
-        */
-       bool (*connect_iface)(bridge_t *this, iface_t *iface);
-
-       /**
-        * Remove an interface from a bridge.
-        *
-        * @param iface         interface to remove
-        * @return                      TRUE if interface removed
-        */
-       bool (*disconnect_iface)(bridge_t *this, iface_t *iface);
-
-       /**
-        * Create an enumerator over all interfaces.
-        *
-        * @return                      enumerator over iface_t's
-        */
-       enumerator_t* (*create_iface_enumerator)(bridge_t *this);
-
-       /**
-        * Destroy a bridge
-        */
-       void (*destroy) (bridge_t *this);
-};
-
-/**
- * Create a new bridge.
- *
- * @param name         name of the bridge to create
- * @return                     bridge, NULL if failed
- */
-bridge_t *bridge_create(char *name);
-
-#endif /* BRIDGE_H */
-
diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c
deleted file mode 100644 (file)
index ac581fe..0000000
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- * Copyright (C) 2001-2007 Miklos Szeredi
- *
- * Based on example shipped with FUSE.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-
-#define FUSE_USE_VERSION 26
-#define _GNU_SOURCE
-
-#include <fuse.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include "cowfs.h"
-
-#include <library.h>
-#include <utils/debug.h>
-#include <threading/thread.h>
-#include <threading/rwlock.h>
-#include <collections/linked_list.h>
-
-/** define _XOPEN_SOURCE 500 fails when using libstrongswan, define popen */
-extern ssize_t pread(int fd, void *buf, size_t count, off_t offset);
-extern ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
-
-typedef struct private_cowfs_t private_cowfs_t;
-
-struct private_cowfs_t {
-       /** public cowfs interface */
-       cowfs_t public;
-       /** fuse channel to mountpoint */
-       struct fuse_chan *chan;
-       /** fuse handle */
-       struct fuse *fuse;
-       /** mountpoint of cowfs FUSE */
-       char *mount;
-       /** master filesystem path */
-       char *master;
-       /** host filesystem path */
-       char *host;
-       /** overlay filesystems */
-       linked_list_t *overlays;
-       /** lock for overlays */
-       rwlock_t *lock;
-       /** fd of read only master filesystem */
-       int master_fd;
-       /** copy on write overlay to master */
-       int host_fd;
-       /** thread processing FUSE */
-       thread_t *thread;
-};
-
-typedef struct overlay_t overlay_t;
-
-/**
- * data for overlay filesystems
- */
-struct overlay_t {
-       /** path to overlay */
-       char *path;
-       /** overlay fd */
-       int fd;
-};
-
-/**
- * destroy an overlay
- */
-static void overlay_destroy(overlay_t *this)
-{
-       close(this->fd);
-       free(this->path);
-       free(this);
-}
-
-CALLBACK(overlay_equals, bool,
-       overlay_t *this, va_list args)
-{
-       overlay_t *other;
-
-       VA_ARGS_VGET(args, other);
-       return streq(this->path, other->path);
-}
-
-/**
- * remove and destroy the overlay with the given absolute path.
- * returns FALSE, if not found.
- */
-static bool overlay_remove(private_cowfs_t *this, char *path)
-{
-       overlay_t over, *current;
-       over.path = path;
-       if (!this->overlays->find_first(this->overlays, overlay_equals,
-                                                                       (void**)&current, &over))
-       {
-               return FALSE;
-       }
-       this->overlays->remove(this->overlays, current, NULL);
-       overlay_destroy(current);
-       return TRUE;
-}
-
-/**
- * get this pointer stored in fuse context
- */
-static private_cowfs_t *get_this()
-{
-       return (fuse_get_context())->private_data;
-}
-
-/**
- * make a path relative
- */
-static void rel(const char **path)
-{
-       if (**path == '/')
-       {
-               (*path)++;
-       }
-       if (**path == '\0')
-       {
-               *path = ".";
-       }
-}
-
-/**
- * get the highest overlay in which path exists
- */
-static int get_rd(const char *path)
-{
-       overlay_t *over;
-       enumerator_t *enumerator;
-       private_cowfs_t *this = get_this();
-
-       this->lock->read_lock(this->lock);
-       enumerator = this->overlays->create_enumerator(this->overlays);
-       while (enumerator->enumerate(enumerator, (void**)&over))
-       {
-               if (faccessat(over->fd, path, F_OK, 0) == 0)
-               {
-                       int fd = over->fd;
-                       enumerator->destroy(enumerator);
-                       this->lock->unlock(this->lock);
-                       return fd;
-               }
-       }
-       enumerator->destroy(enumerator);
-       this->lock->unlock(this->lock);
-
-       if (faccessat(this->host_fd, path, F_OK, 0) == 0)
-       {
-               return this->host_fd;
-       }
-       return this->master_fd;
-}
-
-/**
- * get the highest overlay available, to write something
- */
-static int get_wr(const char *path)
-{
-       overlay_t *over;
-       private_cowfs_t *this = get_this();
-       int fd = this->host_fd;
-       this->lock->read_lock(this->lock);
-       if (this->overlays->get_first(this->overlays, (void**)&over) == SUCCESS)
-       {
-               fd = over->fd;
-       }
-       this->lock->unlock(this->lock);
-       return fd;
-}
-
-/**
- * create full "path" at "wr" the same way they exist at "rd"
- */
-static bool clone_path(int rd, int wr, const char *path)
-{
-       char *pos, *full;
-       struct stat st;
-       full = strdupa(path);
-       pos = full;
-
-       while ((pos = strchr(pos, '/')))
-       {
-               *pos = '\0';
-               if (fstatat(wr, full, &st, 0) < 0)
-               {
-                       /* TODO: handle symlinks!? */
-                       if (fstatat(rd, full, &st, 0) < 0)
-                       {
-                               return FALSE;
-                       }
-                       if (mkdirat(wr, full, st.st_mode) < 0)
-                       {
-                               return FALSE;
-                       }
-               }
-               *pos = '/';
-               pos++;
-       }
-       return TRUE;
-}
-
-/**
- * copy a (special) file from a readonly to a read-write overlay
- */
-static int copy(const char *path)
-{
-       char *buf[4096];
-       int len;
-       int rd, wr;
-       int from, to;
-       struct stat st;
-
-       rd = get_rd(path);
-       wr = get_wr(path);
-
-       if (rd == wr)
-       {
-               /* already writeable */
-               return wr;
-       }
-       if (fstatat(rd, path, &st, 0) < 0)
-       {
-               return -1;
-       }
-       if (!clone_path(rd, wr, path))
-       {
-               return -1;
-       }
-       if (mknodat(wr, path, st.st_mode, st.st_rdev) < 0)
-       {
-               return -1;
-       }
-       /* copy if no special file */
-       if (st.st_size)
-       {
-               from = openat(rd, path, O_RDONLY, st.st_mode);
-               if (from < 0)
-               {
-                       return -1;
-               }
-               to = openat(wr, path, O_WRONLY , st.st_mode);
-               if (to < 0)
-               {
-                       close(from);
-                       return -1;
-               }
-               while ((len = read(from, buf, sizeof(buf))) > 0)
-               {
-                       if (write(to, buf, len) < len)
-                       {
-                               /* TODO: only on len < 0 ? */
-                               close(from);
-                               close(to);
-                               return -1;
-                       }
-               }
-               close(from);
-               close(to);
-               if (len < 0)
-               {
-                       return -1;
-               }
-       }
-       return wr;
-}
-
-/**
- * FUSE getattr method
- */
-static int cowfs_getattr(const char *path, struct stat *stbuf)
-{
-       rel(&path);
-
-       if (fstatat(get_rd(path), path, stbuf, AT_SYMLINK_NOFOLLOW) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE access method
- */
-static int cowfs_access(const char *path, int mask)
-{
-       rel(&path);
-
-       if (faccessat(get_rd(path), path, mask, 0) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE readlink method
- */
-static int cowfs_readlink(const char *path, char *buf, size_t size)
-{
-       int res;
-
-       rel(&path);
-
-       res = readlinkat(get_rd(path), path, buf, size - 1);
-       if (res < 0)
-       {
-               return -errno;
-       }
-       buf[res] = '\0';
-       return 0;
-}
-
-/**
- * get a directory stream of two concatenated paths
- */
-static DIR* get_dir(char *dir, const char *subdir)
-{
-       char *full;
-
-       if (dir == NULL)
-       {
-               return NULL;
-       }
-
-       full = alloca(strlen(dir) + strlen(subdir) + 1);
-       strcpy(full, dir);
-       strcat(full, subdir);
-
-       return opendir(full);
-}
-
-/**
- * check if a directory stream contains a directory
- */
-static bool contains_dir(DIR *d, char *dirname)
-{
-       struct dirent *ent;
-
-       rewinddir(d);
-       while ((ent = readdir(d)))
-       {
-               if (streq(ent->d_name, dirname))
-               {
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-/**
- * check if one of the higher overlays contains a directory
- */
-static bool overlays_contain_dir(DIR **d, char *dirname)
-{
-       for (; *d; ++d)
-       {
-               if (contains_dir(*d, dirname))
-               {
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-/**
- * FUSE readdir method
- */
-static int cowfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
-                                                off_t offset, struct fuse_file_info *fi)
-{
-#define ADD_DIR(overlay, base, path) ({\
-       DIR *dir = get_dir(base, path);\
-       if (dir) { *(--overlay) = dir; }\
-})
-       private_cowfs_t *this = get_this();
-       int count;
-       DIR **d, **overlays;
-       struct stat st;
-       struct dirent *ent;
-       overlay_t *over;
-       enumerator_t *enumerator;
-
-       memset(&st, 0, sizeof(st));
-
-       this->lock->read_lock(this->lock);
-       /* create a null-terminated array of DIR objects for all overlays (including
-        * the master and host layer). the order is from bottom to top */
-       count = this->overlays->get_count(this->overlays) + 2;
-       overlays = calloc(count + 1, sizeof(DIR*));
-       d = &overlays[count];
-
-       enumerator = this->overlays->create_enumerator(this->overlays);
-       while (enumerator->enumerate(enumerator, (void**)&over))
-       {
-               ADD_DIR(d, over->path, path);
-       }
-       enumerator->destroy(enumerator);
-       this->lock->unlock(this->lock);
-
-       ADD_DIR(d, this->host, path);
-       ADD_DIR(d, this->master, path);
-
-       for (; *d; ++d)
-       {
-               rewinddir(*d);
-               while((ent = readdir(*d)))
-               {
-                       if (!overlays_contain_dir(d + 1, ent->d_name))
-                       {
-                               st.st_ino = ent->d_ino;
-                               st.st_mode = ent->d_type << 12;
-                               filler(buf, ent->d_name, &st, 0);
-                       }
-               }
-               closedir(*d);
-       }
-
-       free(overlays);
-       return 0;
-}
-
-/**
- * FUSE mknod method
- */
-static int cowfs_mknod(const char *path, mode_t mode, dev_t rdev)
-{
-       int fd;
-       rel(&path);
-
-       fd = get_wr(path);
-       if (!clone_path(get_rd(path), fd, path))
-       {
-               return -errno;
-       }
-
-       if (mknodat(fd, path, mode, rdev) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE mkdir method
- */
-static int cowfs_mkdir(const char *path, mode_t mode)
-{
-       int fd;
-       rel(&path);
-
-       fd = get_wr(path);
-       if (!clone_path(get_rd(path), fd, path))
-       {
-               return -errno;
-       }
-       if (mkdirat(fd, path, mode) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE unlink method
- */
-static int cowfs_unlink(const char *path)
-{
-       rel(&path);
-
-       /* TODO: whiteout master */
-       if (unlinkat(get_wr(path), path, 0) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE rmdir method
- */
-static int cowfs_rmdir(const char *path)
-{
-       rel(&path);
-
-       /* TODO: whiteout master */
-       if (unlinkat(get_wr(path), path, AT_REMOVEDIR) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE symlink method
- */
-static int cowfs_symlink(const char *from, const char *to)
-{
-       int fd;
-       const char *fromrel = from;
-
-       rel(&to);
-       rel(&fromrel);
-
-       fd = get_wr(to);
-       if (!clone_path(get_rd(fromrel), fd, fromrel))
-       {
-               return -errno;
-       }
-       if (symlinkat(from, fd, to) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE rename method
- */
-static int cowfs_rename(const char *from, const char *to)
-{
-       int fd;
-
-       rel(&from);
-       rel(&to);
-
-       fd = copy(from);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       if (renameat(fd, from, get_wr(to), to) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE link method
- */
-static int cowfs_link(const char *from, const char *to)
-{
-       int rd, wr;
-
-       rel(&from);
-       rel(&to);
-
-       rd = get_rd(from);
-       wr = get_wr(to);
-
-       if (!clone_path(rd, wr, to))
-       {
-               DBG1(DBG_LIB, "cloning path '%s' failed", to);
-               return -errno;
-       }
-       if (linkat(rd, from, wr, to, 0) < 0)
-       {
-               DBG1(DBG_LIB, "linking '%s' to '%s' failed", from, to);
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE chmod method
- */
-static int cowfs_chmod(const char *path, mode_t mode)
-{
-       int fd;
-       struct stat st;
-
-       rel(&path);
-       fd = get_rd(path);
-       if (fstatat(fd, path, &st, 0) < 0)
-       {
-               return -errno;
-       }
-       if (st.st_mode == mode)
-       {
-               return 0;
-       }
-       fd = copy(path);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       if (fchmodat(fd, path, mode, 0) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE chown method
- */
-static int cowfs_chown(const char *path, uid_t uid, gid_t gid)
-{
-       int fd;
-       struct stat st;
-
-       rel(&path);
-       fd = get_rd(path);
-       if (fstatat(fd, path, &st, 0) < 0)
-       {
-               return -errno;
-       }
-       if (st.st_uid == uid && st.st_gid == gid)
-       {
-               return 0;
-       }
-       fd = copy(path);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       if (fchownat(fd, path, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE truncate method
- */
-static int cowfs_truncate(const char *path, off_t size)
-{
-       int fd;
-       struct stat st;
-
-       rel(&path);
-       fd = get_rd(path);
-       if (fstatat(fd, path, &st, 0) < 0)
-       {
-               return -errno;
-       }
-       if (st.st_size == size)
-       {
-               return 0;
-       }
-       fd = copy(path);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       fd = openat(fd, path, O_WRONLY);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       if (ftruncate(fd, size) < 0)
-       {
-               close(fd);
-               return -errno;
-       }
-       close(fd);
-       return 0;
-}
-
-/**
- * FUSE utimens method
- */
-static int cowfs_utimens(const char *path, const struct timespec ts[2])
-{
-       struct timeval tv[2];
-       int fd;
-
-       rel(&path);
-       fd = copy(path);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-
-       tv[0].tv_sec = ts[0].tv_sec;
-       tv[0].tv_usec = ts[0].tv_nsec / 1000;
-       tv[1].tv_sec = ts[1].tv_sec;
-       tv[1].tv_usec = ts[1].tv_nsec / 1000;
-
-       if (futimesat(fd, path, tv) < 0)
-       {
-               return -errno;
-       }
-       return 0;
-}
-
-/**
- * FUSE open method
- */
-static int cowfs_open(const char *path, struct fuse_file_info *fi)
-{
-       int fd;
-
-       rel(&path);
-       fd = get_rd(path);
-
-       fd = openat(fd, path, fi->flags);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       close(fd);
-       return 0;
-}
-
-/**
- * FUSE read method
- */
-static int cowfs_read(const char *path, char *buf, size_t size, off_t offset,
-                                         struct fuse_file_info *fi)
-{
-       int file, fd, res;
-
-       rel(&path);
-
-       fd = get_rd(path);
-
-       file = openat(fd, path, O_RDONLY);
-       if (file < 0)
-       {
-               return -errno;
-       }
-
-       res = pread(file, buf, size, offset);
-       if (res < 0)
-       {
-               res = -errno;
-       }
-       close(file);
-       return res;
-}
-
-/**
- * FUSE write method
- */
-static int cowfs_write(const char *path, const char *buf, size_t size,
-                                          off_t offset, struct fuse_file_info *fi)
-{
-       int file, fd, res;
-
-       rel(&path);
-
-       fd = copy(path);
-       if (fd < 0)
-       {
-               return -errno;
-       }
-       file = openat(fd, path, O_WRONLY);
-       if (file < 0)
-       {
-               return -errno;
-       }
-       res = pwrite(file, buf, size, offset);
-       if (res < 0)
-       {
-               res = -errno;
-       }
-       close(file);
-       return res;
-}
-
-/**
- * FUSE statfs method
- */
-static int cowfs_statfs(const char *path, struct statvfs *stbuf)
-{
-       int fd;
-
-       fd = get_rd(path);
-       if (fstatvfs(fd, stbuf) < 0)
-       {
-               return -errno;
-       }
-
-       return 0;
-}
-
-/**
- * FUSE init method
- */
-static void *cowfs_init(struct fuse_conn_info *conn)
-{
-       struct fuse_context *ctx;
-
-       ctx = fuse_get_context();
-
-       return ctx->private_data;
-}
-
-/**
- * FUSE method vectors
- */
-static struct fuse_operations cowfs_operations = {
-       .getattr        = cowfs_getattr,
-       .access         = cowfs_access,
-       .readlink       = cowfs_readlink,
-       .readdir        = cowfs_readdir,
-       .mknod          = cowfs_mknod,
-       .mkdir          = cowfs_mkdir,
-       .symlink        = cowfs_symlink,
-       .unlink         = cowfs_unlink,
-       .rmdir          = cowfs_rmdir,
-       .rename         = cowfs_rename,
-       .link           = cowfs_link,
-       .chmod          = cowfs_chmod,
-       .chown          = cowfs_chown,
-       .truncate       = cowfs_truncate,
-       .utimens        = cowfs_utimens,
-       .open           = cowfs_open,
-       .read           = cowfs_read,
-       .write          = cowfs_write,
-       .statfs         = cowfs_statfs,
-       .init           = cowfs_init,
-};
-
-METHOD(cowfs_t, add_overlay, bool,
-       private_cowfs_t *this, char *path)
-{
-       overlay_t *over = malloc_thing(overlay_t);
-       over->fd = open(path, O_RDONLY | O_DIRECTORY);
-       if (over->fd < 0)
-       {
-               DBG1(DBG_LIB, "failed to open overlay directory '%s': %m", path);
-               free(over);
-               return FALSE;
-       }
-       over->path = realpath(path, NULL);
-       this->lock->write_lock(this->lock);
-       overlay_remove(this, over->path);
-       this->overlays->insert_first(this->overlays, over);
-       this->lock->unlock(this->lock);
-       return TRUE;
-}
-
-METHOD(cowfs_t, del_overlay, bool,
-       private_cowfs_t *this, char *path)
-{
-       bool removed;
-       char real[PATH_MAX];
-       this->lock->write_lock(this->lock);
-       removed = overlay_remove(this, realpath(path, real));
-       this->lock->unlock(this->lock);
-       return removed;
-}
-
-METHOD(cowfs_t, pop_overlay, bool,
-       private_cowfs_t *this)
-{
-       overlay_t *over;
-       this->lock->write_lock(this->lock);
-       if (this->overlays->remove_first(this->overlays, (void**)&over) != SUCCESS)
-       {
-               this->lock->unlock(this->lock);
-               return FALSE;
-       }
-       this->lock->unlock(this->lock);
-       overlay_destroy(over);
-       return TRUE;
-}
-
-METHOD(cowfs_t, destroy, void,
-       private_cowfs_t *this)
-{
-       fuse_exit(this->fuse);
-       fuse_unmount(this->mount, this->chan);
-       this->thread->join(this->thread);
-       fuse_destroy(this->fuse);
-       this->lock->destroy(this->lock);
-       this->overlays->destroy_function(this->overlays, (void*)overlay_destroy);
-       free(this->mount);
-       free(this->master);
-       free(this->host);
-       close(this->master_fd);
-       close(this->host_fd);
-       free(this);
-}
-
-/**
- * creates a new cowfs fuse instance
- */
-cowfs_t *cowfs_create(char *master, char *host, char *mount)
-{
-       struct fuse_args args = {0, NULL, 0};
-       private_cowfs_t *this;
-
-       INIT(this,
-               .public = {
-                       .add_overlay = _add_overlay,
-                       .del_overlay = _del_overlay,
-                       .pop_overlay = _pop_overlay,
-                       .destroy = _destroy,
-               }
-       );
-
-       this->master_fd = open(master, O_RDONLY | O_DIRECTORY);
-       if (this->master_fd < 0)
-       {
-               DBG1(DBG_LIB, "failed to open master filesystem '%s'", master);
-               free(this);
-               return NULL;
-       }
-       this->host_fd = open(host, O_RDONLY | O_DIRECTORY);
-       if (this->host_fd < 0)
-       {
-               DBG1(DBG_LIB, "failed to open host filesystem '%s'", host);
-               close(this->master_fd);
-               free(this);
-               return NULL;
-       }
-
-       this->chan = fuse_mount(mount, &args);
-       if (this->chan == NULL)
-       {
-               DBG1(DBG_LIB, "mounting cowfs FUSE on '%s' failed", mount);
-               close(this->master_fd);
-               close(this->host_fd);
-               free(this);
-               return NULL;
-       }
-
-       this->fuse = fuse_new(this->chan, &args, &cowfs_operations,
-                                                 sizeof(cowfs_operations), this);
-       if (this->fuse == NULL)
-       {
-               DBG1(DBG_LIB, "creating cowfs FUSE handle failed");
-               close(this->master_fd);
-               close(this->host_fd);
-               fuse_unmount(mount, this->chan);
-               free(this);
-               return NULL;
-       }
-
-       this->mount = strdup(mount);
-       this->master = strdup(master);
-       this->host = strdup(host);
-       this->overlays = linked_list_create();
-       this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-
-       this->thread = thread_create((thread_main_t)fuse_loop, this->fuse);
-       if (!this->thread)
-       {
-               DBG1(DBG_LIB, "creating thread to handle FUSE failed");
-               fuse_unmount(mount, this->chan);
-               this->lock->destroy(this->lock);
-               this->overlays->destroy(this->overlays);
-               free(this->mount);
-               free(this->master);
-               free(this->host);
-               close(this->master_fd);
-               close(this->host_fd);
-               free(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
diff --git a/src/dumm/cowfs.h b/src/dumm/cowfs.h
deleted file mode 100644 (file)
index 9a596de..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef COWFS_H
-#define COWFS_H
-
-#include <library.h>
-
-typedef struct cowfs_t cowfs_t;
-
-/**
- * cowfs - Copy on write FUSE filesystem.
- *
- */
-struct cowfs_t {
-
-       /**
-        * Adds an additional copy on write overlay.
-        *
-        * If the path was already added as overlay, it is moved to the top.
-        *
-        * @param path          path of the overlay
-        * @return                      FALSE, if failed
-        */
-       bool (*add_overlay)(cowfs_t *this, char *path);
-
-       /**
-        * Remove the specified copy on write overlay.
-        *
-        * @param path          path of the overlay
-        * @return                      FALSE, if not found
-        */
-       bool (*del_overlay)(cowfs_t *this, char *path);
-
-       /**
-        * Remove the most recently added copy on write overlay.
-        *
-        * @return                      FALSE, if no overlay was found
-        */
-       bool (*pop_overlay)(cowfs_t *this);
-
-       /**
-        * Stop, umount and destroy a cowfs FUSE filesystem.
-        */
-       void (*destroy) (cowfs_t *this);
-};
-
-/**
- * Mount a cowfs FUSE filesystem.
- *
- * @param master               read only master file system directory
- * @param host                 copy on write host directory
- * @param mount                        mountpoint where union is mounted
- * @return                             instance, or NULL if FUSE initialization failed
- */
-cowfs_t *cowfs_create(char *master, char *host, char *mount);
-
-#endif /* COWFS_H */
-
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c
deleted file mode 100644 (file)
index e246713..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-
-#include "dumm.h"
-
-#define PERME (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
-#define GUEST_DIR "guests"
-#define TEMPLATE_DIR "templates"
-
-typedef struct private_dumm_t private_dumm_t;
-
-struct private_dumm_t {
-       /** public dumm interface */
-       dumm_t public;
-       /** working dir */
-       char *dir;
-       /** directory of guests */
-       char *guest_dir;
-       /** directory of loaded template */
-       char *template;
-       /** list of managed guests */
-       linked_list_t *guests;
-       /** list of managed bridges */
-       linked_list_t *bridges;
-};
-
-METHOD(dumm_t, create_guest, guest_t*,
-       private_dumm_t *this, char *name, char *kernel, char *master, char *args)
-{
-       guest_t *guest;
-
-       guest = guest_create(this->guest_dir, name, kernel, master, args);
-       if (guest)
-       {
-               this->guests->insert_last(this->guests, guest);
-       }
-       return guest;
-}
-
-METHOD(dumm_t, create_guest_enumerator, enumerator_t*,
-       private_dumm_t *this)
-{
-       return this->guests->create_enumerator(this->guests);
-}
-
-METHOD(dumm_t, delete_guest, void,
-       private_dumm_t *this, guest_t *guest)
-{
-       if (this->guests->remove(this->guests, guest, NULL))
-       {
-               char buf[512];
-               int len;
-
-               len = snprintf(buf, sizeof(buf), "rm -Rf %s/%s",
-                                          this->guest_dir, guest->get_name(guest));
-               guest->destroy(guest);
-               if (len > 8 && len < 512)
-               {
-                       ignore_result(system(buf));
-               }
-       }
-}
-
-METHOD(dumm_t, create_bridge, bridge_t*,
-       private_dumm_t *this, char *name)
-{
-       bridge_t *bridge;
-
-       bridge = bridge_create(name);
-       if (bridge)
-       {
-               this->bridges->insert_last(this->bridges, bridge);
-       }
-       return bridge;
-}
-
-METHOD(dumm_t, create_bridge_enumerator, enumerator_t*,
-       private_dumm_t *this)
-{
-       return this->bridges->create_enumerator(this->bridges);
-}
-
-METHOD(dumm_t, delete_bridge, void,
-       private_dumm_t *this, bridge_t *bridge)
-{
-       if (this->bridges->remove(this->bridges, bridge, NULL))
-       {
-               bridge->destroy(bridge);
-       }
-}
-
-METHOD(dumm_t, add_overlay, bool,
-       private_dumm_t *this, char *dir)
-{
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       if (dir == NULL)
-       {
-               return TRUE;
-       }
-       if (strlen(dir) > PATH_MAX)
-       {
-               DBG1(DBG_LIB, "overlay directory string '%s' is too long", dir);
-               return FALSE;
-       }
-       if (access(dir, F_OK) != 0)
-       {
-               if (!mkdir_p(dir, PERME))
-               {
-                       DBG1(DBG_LIB, "creating overlay directory '%s' failed: %m", dir);
-                       return FALSE;
-               }
-       }
-       enumerator = this->guests->create_enumerator(this->guests);
-       while (enumerator->enumerate(enumerator, (void**)&guest))
-       {
-               char guest_dir[PATH_MAX];
-               int len = snprintf(guest_dir, sizeof(guest_dir), "%s/%s", dir,
-                                                  guest->get_name(guest));
-               if (len < 0 || len >= sizeof(guest_dir))
-               {
-                       goto error;
-               }
-               if (access(guest_dir, F_OK) != 0)
-               {
-                       if (!mkdir_p(guest_dir, PERME))
-                       {
-                               DBG1(DBG_LIB, "creating overlay directory for guest '%s' failed: %m",
-                                        guest->get_name(guest));
-                               goto error;
-                       }
-               }
-               if (!guest->add_overlay(guest, guest_dir))
-               {
-                       goto error;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return TRUE;
-error:
-       enumerator->destroy(enumerator);
-       this->public.del_overlay(&this->public, dir);
-       return FALSE;
-}
-
-METHOD(dumm_t, del_overlay, bool,
-       private_dumm_t *this, char *dir)
-{
-       bool ret = FALSE;
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       enumerator = this->guests->create_enumerator(this->guests);
-       while (enumerator->enumerate(enumerator, (void**)&guest))
-       {
-               char guest_dir[PATH_MAX];
-               int len = snprintf(guest_dir, sizeof(guest_dir), "%s/%s", dir,
-                                                  guest->get_name(guest));
-               if (len < 0 || len >= sizeof(guest_dir))
-               {
-                       continue;
-               }
-               ret = guest->del_overlay(guest, guest_dir) || ret;
-       }
-       enumerator->destroy(enumerator);
-       return ret;
-}
-
-METHOD(dumm_t, pop_overlay, bool,
-       private_dumm_t *this)
-{
-       bool ret = FALSE;
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       enumerator = this->guests->create_enumerator(this->guests);
-       while (enumerator->enumerate(enumerator, (void**)&guest))
-       {
-               ret = guest->pop_overlay(guest) || ret;
-       }
-       enumerator->destroy(enumerator);
-       return ret;
-}
-
-/**
- * disable the currently enabled template
- */
-static void clear_template(private_dumm_t *this)
-{
-       if (this->template)
-       {
-               del_overlay(this, this->template);
-               free(this->template);
-               this->template = NULL;
-       }
-}
-
-METHOD(dumm_t, load_template, bool,
-       private_dumm_t *this, char *name)
-{
-       clear_template(this);
-       if (name == NULL)
-       {
-               return TRUE;
-       }
-       if (strlen(name) > PATH_MAX)
-       {
-               DBG1(DBG_LIB, "template name '%s' is too long", name);
-               return FALSE;
-       }
-       if (strchr(name, '/') != NULL)
-       {
-               DBG1(DBG_LIB, "template name '%s' must not contain '/' characters", name);
-               return FALSE;
-       }
-       if (asprintf(&this->template, "%s/%s", TEMPLATE_DIR, name) < 0)
-       {
-               this->template = NULL;
-               return FALSE;
-       }
-       if (access(this->template, F_OK) != 0)
-       {
-               if (!mkdir_p(this->template, PERME))
-               {
-                       DBG1(DBG_LIB, "creating template directory '%s' failed: %m",
-                                this->template);
-                       return FALSE;
-               }
-       }
-       return add_overlay(this, this->template);
-}
-
-/**
- * Template directory enumerator
- */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** directory enumerator */
-       enumerator_t *inner;
-} template_enumerator_t;
-
-METHOD(enumerator_t, template_enumerate, bool,
-       template_enumerator_t *this, va_list args)
-{
-       struct stat st;
-       char *rel, **template;
-
-       VA_ARGS_VGET(args, template);
-
-       while (this->inner->enumerate(this->inner, &rel, NULL, &st))
-       {
-               if (S_ISDIR(st.st_mode) && *rel != '.')
-               {
-                       *template = rel;
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-METHOD(enumerator_t, template_enumerator_destroy, void,
-       template_enumerator_t *this)
-{
-       this->inner->destroy(this->inner);
-       free(this);
-}
-
-METHOD(dumm_t, create_template_enumerator, enumerator_t*,
-       private_dumm_t *this)
-{
-       template_enumerator_t *enumerator;
-       INIT(enumerator,
-               .public = {
-                       .enumerate = enumerator_enumerate_default,
-                       .venumerate = _template_enumerate,
-                       .destroy = (void*)_template_enumerator_destroy,
-               },
-               .inner = enumerator_create_directory(TEMPLATE_DIR),
-       );
-       if (!enumerator->inner)
-       {
-               free(enumerator);
-               return enumerator_create_empty();
-       }
-       return &enumerator->public;
-}
-
-METHOD(dumm_t, destroy, void,
-       private_dumm_t *this)
-{
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       this->bridges->destroy_offset(this->bridges, offsetof(bridge_t, destroy));
-
-       enumerator = this->guests->create_enumerator(this->guests);
-       while (enumerator->enumerate(enumerator, (void**)&guest))
-       {
-               guest->stop(guest, NULL);
-       }
-       enumerator->destroy(enumerator);
-
-       while (this->guests->remove_last(this->guests, (void**)&guest) == SUCCESS)
-       {
-               guest->destroy(guest);
-       }
-       this->guests->destroy(this->guests);
-       free(this->guest_dir);
-       free(this->template);
-       free(this->dir);
-       free(this);
-}
-
-/**
- * load all guests in our working dir
- */
-static void load_guests(private_dumm_t *this)
-{
-       DIR *dir;
-       struct dirent *ent;
-       guest_t *guest;
-
-       dir = opendir(this->guest_dir);
-       if (dir == NULL)
-       {
-               return;
-       }
-
-       while ((ent = readdir(dir)))
-       {
-               if (*ent->d_name == '.')
-               {       /* skip ".", ".." and hidden files (such as ".svn") */
-                       continue;
-               }
-               guest = guest_load(this->guest_dir, ent->d_name);
-               if (guest)
-               {
-                       this->guests->insert_last(this->guests, guest);
-               }
-               else
-               {
-                       DBG1(DBG_LIB, "loading guest in directory '%s' failed, skipped",
-                                ent->d_name);
-               }
-       }
-       closedir(dir);
-}
-
-/**
- * create a dumm instance
- */
-dumm_t *dumm_create(char *dir)
-{
-       char cwd[PATH_MAX];
-       private_dumm_t *this;
-
-       INIT(this,
-               .public = {
-                       .create_guest = _create_guest,
-                       .create_guest_enumerator = _create_guest_enumerator,
-                       .delete_guest = _delete_guest,
-                       .create_bridge = _create_bridge,
-                       .create_bridge_enumerator = _create_bridge_enumerator,
-                       .delete_bridge = _delete_bridge,
-                       .add_overlay = _add_overlay,
-                       .del_overlay = _del_overlay,
-                       .pop_overlay = _pop_overlay,
-                       .load_template = _load_template,
-                       .create_template_enumerator = _create_template_enumerator,
-                       .destroy = _destroy,
-               },
-       );
-
-       if (dir && *dir == '/')
-       {
-               this->dir = strdup(dir);
-       }
-       else
-       {
-               if (getcwd(cwd, sizeof(cwd)) == NULL)
-               {
-                       free(this);
-                       return NULL;
-               }
-               if (dir)
-               {
-                       if (asprintf(&this->dir, "%s/%s", cwd, dir) < 0)
-                       {
-                               this->dir = NULL;
-                       }
-               }
-               else
-               {
-                       this->dir = strdup(cwd);
-               }
-       }
-       if (asprintf(&this->guest_dir, "%s/%s", this->dir, GUEST_DIR) < 0)
-       {
-               this->guest_dir = NULL;
-       }
-
-       this->guests = linked_list_create();
-       this->bridges = linked_list_create();
-
-       if (this->dir == NULL || this->guest_dir == NULL ||
-               (mkdir(this->guest_dir, PERME) < 0 && errno != EEXIST))
-       {
-               DBG1(DBG_LIB, "creating guest directory '%s' failed: %m",
-                        this->guest_dir);
-               destroy(this);
-               return NULL;
-       }
-
-       load_guests(this);
-       return &this->public;
-}
-
diff --git a/src/dumm/dumm.h b/src/dumm/dumm.h
deleted file mode 100644 (file)
index 921d215..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef DUMM_H
-#define DUMM_H
-
-#include <signal.h>
-
-#include <library.h>
-#include <collections/enumerator.h>
-
-#include "guest.h"
-#include "bridge.h"
-
-typedef struct dumm_t dumm_t;
-
-/**
- * dumm - Dynamic Uml Mesh Modeler
- *
- * Controls a group of UML guests and their networks.
- */
-struct dumm_t {
-
-       /**
-        * Starts a new UML guest
-        *
-        * @param name          name of the guest
-        * @param kernel        UML kernel to use for guest
-        * @param master        mounted read only master filesystem
-        * @param args          additional args to pass to kernel
-        * @return                      guest if started, NULL if failed
-        */
-       guest_t* (*create_guest) (dumm_t *this, char *name, char *kernel,
-                                                         char *master, char *args);
-
-       /**
-        * Create an enumerator over all guests.
-        *
-        * @return                      enumerator over guest_t's
-        */
-       enumerator_t* (*create_guest_enumerator) (dumm_t *this);
-
-       /**
-        * Delete a guest from disk.
-        *
-        * @param guest         guest to destroy
-        */
-       void (*delete_guest) (dumm_t *this, guest_t *guest);
-
-       /**
-        * Create a new bridge.
-        *
-        * @param name          name of the bridge to create
-        * @return                      created bridge
-        */
-       bridge_t* (*create_bridge)(dumm_t *this, char *name);
-
-       /**
-        * Create an enumerator over all bridges.
-        *
-        * @return                      enumerator over bridge_t's
-        */
-       enumerator_t* (*create_bridge_enumerator)(dumm_t *this);
-
-       /**
-        * Delete a bridge.
-        *
-        * @param bridge        bridge to destroy
-        */
-       void (*delete_bridge) (dumm_t *this, bridge_t *bridge);
-
-       /**
-        * Add an overlay to all guests.
-        *
-        * Directories named after the guests are created, if they do not exist
-        * in the given overlay directory.
-        *
-        * If adding the overlay on at lest one guest fails, FALSE is returned and
-        * the overlay is again removed from all guests.
-        *
-        * @param dir           dir to the overlay
-        * @return                      FALSE, on failure
-        */
-       bool (*add_overlay)(dumm_t *this, char *dir);
-
-       /**
-        * Removes an overlay from all guests.
-        *
-        * @param dir           dir to the overlay
-        * @return                      FALSE, if the overlay was not found on any guest
-        */
-       bool (*del_overlay)(dumm_t *this, char *dir);
-
-       /**
-        * Remove the latest overlay from all guests.
-        *
-        * @return                      FALSE, if no overlay was found on any guest
-        */
-       bool (*pop_overlay)(dumm_t *this);
-
-       /**
-        * Loads a template, create a new one if it does not exist.
-        *
-        * This is basically a wrapper around add/del_overlay to simplify working
-        * with overlays. Templates are located in a predefined directory, so that
-        * only a name for the template has to be specified here. Only one template
-        * can be loaded at any one time (but other overlays can be added on top or
-        * below a template).
-        *
-        * @param name          name of the template to load, NULL to unload
-        * @return                      FALSE if load/create failed
-        */
-       bool (*load_template)(dumm_t *this, char *name);
-
-       /**
-        * Create an enumerator over all available templates.
-        *
-        * @return                      enumerator over char*
-        */
-       enumerator_t* (*create_template_enumerator)(dumm_t *this);
-
-       /**
-        * stop all guests and destroy the modeler
-        */
-       void (*destroy) (dumm_t *this);
-};
-
-/**
- * Create a group of UML hosts and networks.
- *
- * @param dir                  directory to create guests/load from, NULL for cwd
- * @return                             created UML group, or NULL if failed.
- */
-dumm_t *dumm_create(char *dir);
-
-#endif /* DUMM_H */
-
diff --git a/src/dumm/ext/.gitignore b/src/dumm/ext/.gitignore
deleted file mode 100644 (file)
index 2780ad7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-dumm.so
-mkmf.log
-extconf.rb
diff --git a/src/dumm/ext/README b/src/dumm/ext/README
deleted file mode 100644 (file)
index 270d9d5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-DUMM Ruby Extension
-===================
-
-Build and Install
-
-  $ ruby extconf.rb
-  $ make
-  # make install
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
deleted file mode 100644 (file)
index 7df72eb..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (C) 2008-2010 Tobias Brunner
- * Copyright (C) 2008 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdio.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <library.h>
-#include <dumm.h>
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-
-#undef PACKAGE_NAME
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
-#undef PACKAGE_STRING
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_URL
-#undef HAVE_DLADDR
-#undef HAVE_QSORT_R
-/* avoid redefintiion of snprintf etc. */
-#define RUBY_DONT_SUBST
-/* undef our _GNU_SOURCE, as it gets redefined by <ruby.h> */
-#undef _GNU_SOURCE
-#include <ruby.h>
-
-static dumm_t *dumm;
-
-static VALUE rbm_dumm;
-static VALUE rbc_guest;
-static VALUE rbc_bridge;
-static VALUE rbc_iface;
-static VALUE rbc_template;
-
-/**
- * Guest invocation callback
- */
-static pid_t invoke(void *null, guest_t *guest, char *args[], int argc)
-{
-       pid_t pid;
-
-       pid = fork();
-       switch (pid)
-       {
-               case 0: /* child */
-                       /* create a new process group in order to prevent signals (e.g.
-                        * SIGINT) sent to the parent from terminating the child */
-                       setpgid(0, 0);
-                       dup2(open("/dev/null", 0), 1);
-                       dup2(open("/dev/null", 0), 2);
-                       execvp(args[0], args);
-                       /* FALL */
-               case -1:
-                       return 0;
-               default:
-                       return pid;
-       }
-}
-
-/**
- * SIGCHLD signal handler
- */
-static void sigchld_handler(int signal, siginfo_t *info, void* ptr)
-{
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       enumerator = dumm->create_guest_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &guest))
-       {
-               if (guest->get_pid(guest) == info->si_pid)
-               {
-                       guest->sigchild(guest);
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-
-/**
- * Global Dumm bindings
- */
-static VALUE dumm_add_overlay(VALUE class, VALUE dir)
-{
-       if (!dumm->add_overlay(dumm, StringValuePtr(dir)))
-       {
-               rb_raise(rb_eRuntimeError, "loading overlay failed");
-       }
-       return class;
-}
-
-static VALUE dumm_del_overlay(VALUE class, VALUE dir)
-{
-       return dumm->del_overlay(dumm, StringValuePtr(dir)) ? Qtrue : Qfalse;
-}
-
-static VALUE dumm_pop_overlay(VALUE class)
-{
-       return dumm->pop_overlay(dumm) ? Qtrue : Qfalse;
-}
-
-static void dumm_init()
-{
-       rbm_dumm = rb_define_module("Dumm");
-
-       rb_define_module_function(rbm_dumm, "add_overlay", dumm_add_overlay, 1);
-       rb_define_module_function(rbm_dumm, "del_overlay", dumm_del_overlay, 1);
-       rb_define_module_function(rbm_dumm, "pop_overlay", dumm_pop_overlay, 0);
-}
-
-/**
- * Guest bindings
- */
-static VALUE guest_hash_create(VALUE class)
-{
-       enumerator_t *enumerator;
-       guest_t *guest;
-       VALUE hash = rb_hash_new();
-       enumerator = dumm->create_guest_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &guest))
-       {
-               rb_hash_aset(hash, rb_str_new2(guest->get_name(guest)),
-                                        Data_Wrap_Struct(class, NULL, NULL, guest));
-       }
-       enumerator->destroy(enumerator);
-       return hash;
-}
-
-static VALUE guest_hash(VALUE class)
-{
-       ID id = rb_intern("@@guests");
-       if (!rb_cvar_defined(class, id))
-       {
-               VALUE hash = guest_hash_create(class);
-#ifdef RB_CVAR_SET_4_ARGS
-               rb_cvar_set(class, id, hash, 0);
-#else
-               rb_cvar_set(class, id, hash);
-#endif
-               return hash;
-       }
-       return rb_cvar_get(class, id);
-}
-
-static VALUE guest_find(VALUE class, VALUE key)
-{
-       if (TYPE(key) != T_STRING)
-       {
-               key = rb_convert_type(key, T_STRING, "String", "to_s");
-       }
-       return rb_hash_aref(guest_hash(class), key);
-}
-
-static VALUE guest_get(VALUE class, VALUE key)
-{
-       return guest_find(class, key);
-}
-
-static VALUE guest_each(int argc, VALUE *argv, VALUE class)
-{
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       rb_block_call(guest_hash(class), rb_intern("each_value"), 0, 0,
-                                 rb_yield, 0);
-       return class;
-}
-
-static VALUE guest_new(VALUE class, VALUE name, VALUE kernel,
-                                          VALUE master, VALUE args)
-{
-       VALUE self;
-       guest_t *guest;
-       guest = dumm->create_guest(dumm, StringValuePtr(name),
-                                                          StringValuePtr(kernel), StringValuePtr(master),
-                                                          StringValuePtr(args));
-       if (!guest)
-       {
-               rb_raise(rb_eRuntimeError, "creating guest failed");
-       }
-       self = Data_Wrap_Struct(class, NULL, NULL, guest);
-       rb_hash_aset(guest_hash(class), name, self);
-       return self;
-}
-
-static VALUE guest_to_s(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       return rb_str_new2(guest->get_name(guest));
-}
-
-static VALUE guest_start(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-
-       if (!guest->start(guest, invoke, NULL, NULL))
-       {
-               rb_raise(rb_eRuntimeError, "starting guest failed");
-       }
-       return self;
-}
-
-static VALUE guest_stop(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       guest->stop(guest, NULL);
-       return self;
-}
-
-static VALUE guest_running(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       return guest->get_pid(guest) ? Qtrue : Qfalse;
-}
-
-static void exec_cb(void *data, char *buf)
-{
-       rb_yield(rb_str_new2(buf));
-}
-
-static VALUE guest_exec(VALUE self, VALUE cmd)
-{
-       guest_t *guest;
-       bool block;
-       int ret;
-
-       block = rb_block_given_p();
-       Data_Get_Struct(self, guest_t, guest);
-       ret = guest->exec_str(guest, block ? (void*)exec_cb : NULL, TRUE, NULL,
-                                                 "exec %s", StringValuePtr(cmd));
-       rb_iv_set(self, "@execstatus", INT2NUM(ret));
-       return self;
-}
-
-static VALUE guest_mconsole(VALUE self, VALUE cmd)
-{
-       guest_t *guest;
-       bool block;
-       int ret;
-
-       block = rb_block_given_p();
-       Data_Get_Struct(self, guest_t, guest);
-       if ((ret = guest->exec_str(guest, block ? (void*)exec_cb : NULL, TRUE, NULL,
-                                       "%s", StringValuePtr(cmd))) != 0)
-       {
-               rb_raise(rb_eRuntimeError, "executing command failed (%d)", ret);
-       }
-       return self;
-}
-
-static VALUE guest_add_iface(VALUE self, VALUE name)
-{
-       guest_t *guest;
-       iface_t *iface;
-
-       Data_Get_Struct(self, guest_t, guest);
-       iface = guest->create_iface(guest, StringValuePtr(name));
-       if (!iface)
-       {
-               rb_raise(rb_eRuntimeError, "adding interface failed");
-       }
-       return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface);
-}
-
-static VALUE guest_find_iface(VALUE self, VALUE key)
-{
-       enumerator_t *enumerator;
-       iface_t *iface, *found = NULL;
-       guest_t *guest;
-
-       if (TYPE(key) == T_SYMBOL)
-       {
-               key = rb_convert_type(key, T_STRING, "String", "to_s");
-       }
-       Data_Get_Struct(self, guest_t, guest);
-       enumerator = guest->create_iface_enumerator(guest);
-       while (enumerator->enumerate(enumerator, &iface))
-       {
-               if (streq(iface->get_guestif(iface), StringValuePtr(key)))
-               {
-                       found = iface;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       if (!found)
-       {
-               return Qnil;
-       }
-       return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface);
-}
-
-static VALUE guest_get_iface(VALUE self, VALUE key)
-{
-       VALUE iface = guest_find_iface(self, key);
-       if (NIL_P(iface))
-       {
-               rb_raise(rb_eRuntimeError, "interface not found");
-       }
-       return iface;
-}
-
-static VALUE guest_each_iface(int argc, VALUE *argv, VALUE self)
-{
-       enumerator_t *enumerator;
-       linked_list_t *list;
-       guest_t *guest;
-       iface_t *iface;
-
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       Data_Get_Struct(self, guest_t, guest);
-       list = linked_list_create();
-       enumerator = guest->create_iface_enumerator(guest);
-       while (enumerator->enumerate(enumerator, &iface))
-       {
-               list->insert_last(list, iface);
-       }
-       enumerator->destroy(enumerator);
-       while (list->remove_first(list, (void**)&iface) == SUCCESS)
-       {
-               rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
-       }
-       list->destroy(list);
-       return self;
-}
-
-static VALUE guest_delete(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       if (guest->get_pid(guest))
-       {
-               rb_raise(rb_eRuntimeError, "guest is running");
-       }
-       dumm->delete_guest(dumm, guest);
-       return Qnil;
-}
-
-static VALUE guest_add_overlay(VALUE self, VALUE dir)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       if (!guest->add_overlay(guest, StringValuePtr(dir)))
-       {
-               rb_raise(rb_eRuntimeError, "loading overlay failed");
-       }
-       return self;
-}
-
-static VALUE guest_del_overlay(VALUE self, VALUE dir)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       return guest->del_overlay(guest, StringValuePtr(dir)) ? Qtrue : Qfalse;
-}
-
-static VALUE guest_pop_overlay(VALUE self)
-{
-       guest_t *guest;
-
-       Data_Get_Struct(self, guest_t, guest);
-       return guest->pop_overlay(guest) ? Qtrue : Qfalse;
-}
-
-static void guest_init()
-{
-       rbc_guest = rb_define_class_under(rbm_dumm , "Guest", rb_cObject);
-       rb_include_module(rb_class_of(rbc_guest), rb_mEnumerable);
-       rb_include_module(rbc_guest, rb_mEnumerable);
-
-       rb_define_singleton_method(rbc_guest, "[]", guest_get, 1);
-       rb_define_singleton_method(rbc_guest, "each", guest_each, -1);
-       rb_define_singleton_method(rbc_guest, "new", guest_new, 4);
-       rb_define_singleton_method(rbc_guest, "include?", guest_find, 1);
-       rb_define_singleton_method(rbc_guest, "guest?", guest_find, 1);
-
-       rb_define_method(rbc_guest, "to_s", guest_to_s, 0);
-       rb_define_method(rbc_guest, "start", guest_start, 0);
-       rb_define_method(rbc_guest, "stop", guest_stop, 0);
-       rb_define_method(rbc_guest, "running?", guest_running, 0);
-       rb_define_method(rbc_guest, "exec", guest_exec, 1);
-       rb_define_method(rbc_guest, "mconsole", guest_mconsole, 1);
-       rb_define_method(rbc_guest, "add", guest_add_iface, 1);
-       rb_define_method(rbc_guest, "[]", guest_get_iface, 1);
-       rb_define_method(rbc_guest, "each", guest_each_iface, -1);
-       rb_define_method(rbc_guest, "include?", guest_find_iface, 1);
-       rb_define_method(rbc_guest, "iface?", guest_find_iface, 1);
-       rb_define_method(rbc_guest, "delete", guest_delete, 0);
-       rb_define_method(rbc_guest, "add_overlay", guest_add_overlay, 1);
-       rb_define_method(rbc_guest, "del_overlay", guest_del_overlay, 1);
-       rb_define_method(rbc_guest, "pop_overlay", guest_pop_overlay, 0);
-
-       rb_define_attr(rbc_guest, "execstatus", 1, 0);
-}
-
-/**
- * Bridge binding
- */
-static VALUE bridge_find(VALUE class, VALUE key)
-{
-       enumerator_t *enumerator;
-       bridge_t *bridge, *found = NULL;
-
-       if (TYPE(key) == T_SYMBOL)
-       {
-               key = rb_convert_type(key, T_STRING, "String", "to_s");
-       }
-       enumerator = dumm->create_bridge_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &bridge))
-       {
-               if (streq(bridge->get_name(bridge), StringValuePtr(key)))
-               {
-                       found = bridge;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       if (!found)
-       {
-               return Qnil;
-       }
-       return Data_Wrap_Struct(class, NULL, NULL, found);
-}
-
-static VALUE bridge_get(VALUE class, VALUE key)
-{
-       VALUE bridge = bridge_find(class, key);
-       if (NIL_P(bridge))
-       {
-               rb_raise(rb_eRuntimeError, "bridge not found");
-       }
-       return bridge;
-}
-
-static VALUE bridge_each(int argc, VALUE *argv, VALUE class)
-{
-       enumerator_t *enumerator;
-       linked_list_t *list;
-       bridge_t *bridge;
-
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       list = linked_list_create();
-       enumerator = dumm->create_bridge_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &bridge))
-       {
-               list->insert_last(list, bridge);
-       }
-       enumerator->destroy(enumerator);
-       while (list->remove_first(list, (void**)&bridge) == SUCCESS)
-       {
-               rb_yield(Data_Wrap_Struct(class, NULL, NULL, bridge));
-       }
-       list->destroy(list);
-       return class;
-}
-
-static VALUE bridge_new(VALUE class, VALUE name)
-
-{
-       bridge_t *bridge;
-
-       bridge = dumm->create_bridge(dumm, StringValuePtr(name));
-       if (!bridge)
-       {
-               rb_raise(rb_eRuntimeError, "creating bridge failed");
-       }
-       return Data_Wrap_Struct(class, NULL, NULL, bridge);
-}
-
-static VALUE bridge_to_s(VALUE self)
-{
-       bridge_t *bridge;
-
-       Data_Get_Struct(self, bridge_t, bridge);
-       return rb_str_new2(bridge->get_name(bridge));
-}
-
-static VALUE bridge_each_iface(int argc, VALUE *argv, VALUE self)
-{
-       enumerator_t *enumerator;
-       linked_list_t *list;
-       bridge_t *bridge;
-       iface_t *iface;
-
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       Data_Get_Struct(self, bridge_t, bridge);
-       list = linked_list_create();
-       enumerator = bridge->create_iface_enumerator(bridge);
-       while (enumerator->enumerate(enumerator, &iface))
-       {
-               list->insert_last(list, iface);
-       }
-       enumerator->destroy(enumerator);
-       while (list->remove_first(list, (void**)&iface) == SUCCESS)
-       {
-               rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
-       }
-       list->destroy(list);
-       return self;
-}
-
-static VALUE bridge_delete(VALUE self)
-{
-       bridge_t *bridge;
-
-       Data_Get_Struct(self, bridge_t, bridge);
-       dumm->delete_bridge(dumm, bridge);
-       return Qnil;
-}
-
-static void bridge_init()
-{
-       rbc_bridge = rb_define_class_under(rbm_dumm , "Bridge", rb_cObject);
-       rb_include_module(rb_class_of(rbc_bridge), rb_mEnumerable);
-       rb_include_module(rbc_bridge, rb_mEnumerable);
-
-       rb_define_singleton_method(rbc_bridge, "[]", bridge_get, 1);
-       rb_define_singleton_method(rbc_bridge, "each", bridge_each, -1);
-       rb_define_singleton_method(rbc_bridge, "new", bridge_new, 1);
-       rb_define_singleton_method(rbc_bridge, "include?", bridge_find, 1);
-       rb_define_singleton_method(rbc_bridge, "bridge?", bridge_find, 1);
-
-       rb_define_method(rbc_bridge, "to_s", bridge_to_s, 0);
-       rb_define_method(rbc_bridge, "each", bridge_each_iface, -1);
-       rb_define_method(rbc_bridge, "delete", bridge_delete, 0);
-}
-
-/**
- * Iface wrapper
- */
-static VALUE iface_to_s(VALUE self)
-{
-       iface_t *iface;
-
-       Data_Get_Struct(self, iface_t, iface);
-       return rb_str_new2(iface->get_hostif(iface));
-}
-
-static VALUE iface_connect(VALUE self, VALUE vbridge)
-{
-       iface_t *iface;
-       bridge_t *bridge;
-
-       Data_Get_Struct(self, iface_t, iface);
-       Data_Get_Struct(vbridge, bridge_t, bridge);
-       if (!bridge->connect_iface(bridge, iface))
-       {
-               rb_raise(rb_eRuntimeError, "connecting iface failed");
-       }
-       return self;
-}
-
-static VALUE iface_disconnect(VALUE self)
-{
-       iface_t *iface;
-       bridge_t *bridge;
-
-       Data_Get_Struct(self, iface_t, iface);
-       bridge = iface->get_bridge(iface);
-       if (!bridge || !bridge->disconnect_iface(bridge, iface))
-       {
-               rb_raise(rb_eRuntimeError, "disconnecting iface failed");
-       }
-       return self;
-}
-
-static VALUE iface_add_addr(VALUE self, VALUE name)
-{
-       iface_t *iface;
-       host_t *addr;
-       int bits;
-
-       addr = host_create_from_subnet(StringValuePtr(name), &bits);
-       if (!addr)
-       {
-               rb_raise(rb_eArgError, "invalid IP address");
-       }
-       Data_Get_Struct(self, iface_t, iface);
-       if (!iface->add_address(iface, addr, bits))
-       {
-               addr->destroy(addr);
-               rb_raise(rb_eRuntimeError, "adding address failed");
-       }
-       if (rb_block_given_p()) {
-               rb_yield(self);
-               iface->delete_address(iface, addr, bits);
-       }
-       addr->destroy(addr);
-       return self;
-}
-
-static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
-{
-       enumerator_t *enumerator;
-       linked_list_t *list;
-       iface_t *iface;
-       host_t *addr;
-       char buf[64], *fmt = "%H";
-
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       list = linked_list_create();
-       Data_Get_Struct(self, iface_t, iface);
-       enumerator = iface->create_address_enumerator(iface);
-       while (enumerator->enumerate(enumerator, &addr))
-       {
-               list->insert_last(list, addr->clone(addr));
-       }
-       enumerator->destroy(enumerator);
-       while (list->remove_first(list, (void**)&addr) == SUCCESS)
-       {
-               snprintf(buf, sizeof(buf), fmt, addr);
-               addr->destroy(addr);
-               rb_yield(rb_str_new2(buf));
-       }
-       list->destroy(list);
-       return self;
-}
-
-static VALUE iface_del_addr(VALUE self, VALUE vaddr)
-{
-       iface_t *iface;
-       host_t *addr;
-       int bits;
-
-       addr = host_create_from_subnet(StringValuePtr(vaddr), &bits);
-       if (!addr)
-       {
-               rb_raise(rb_eArgError, "invalid IP address");
-       }
-       Data_Get_Struct(self, iface_t, iface);
-       if (!iface->delete_address(iface, addr, bits))
-       {
-               addr->destroy(addr);
-               rb_raise(rb_eRuntimeError, "address not found");
-       }
-       if (rb_block_given_p()) {
-               rb_yield(self);
-               iface->add_address(iface, addr, bits);
-       }
-       addr->destroy(addr);
-       return self;
-}
-
-static VALUE iface_delete(VALUE self)
-{
-       guest_t *guest;
-       iface_t *iface;
-
-       Data_Get_Struct(self, iface_t, iface);
-       guest = iface->get_guest(iface);
-       guest->destroy_iface(guest, iface);
-       return Qnil;
-}
-
-static void iface_init()
-{
-       rbc_iface = rb_define_class_under(rbm_dumm , "Iface", rb_cObject);
-       rb_include_module(rbc_iface, rb_mEnumerable);
-
-       rb_define_method(rbc_iface, "to_s", iface_to_s, 0);
-       rb_define_method(rbc_iface, "connect", iface_connect, 1);
-       rb_define_method(rbc_iface, "disconnect", iface_disconnect, 0);
-       rb_define_method(rbc_iface, "add", iface_add_addr, 1);
-       rb_define_method(rbc_iface, "del", iface_del_addr, 1);
-       rb_define_method(rbc_iface, "each", iface_each_addr, -1);
-       rb_define_method(rbc_iface, "delete", iface_delete, 0);
-}
-
-static VALUE template_load(VALUE class, VALUE dir)
-{
-       if (!dumm->load_template(dumm, StringValuePtr(dir)))
-       {
-               rb_raise(rb_eRuntimeError, "loading template failed");
-       }
-       return class;
-}
-
-static VALUE template_unload(VALUE class)
-{
-       if (!dumm->load_template(dumm, NULL))
-       {
-               rb_raise(rb_eRuntimeError, "unloading template failed");
-       }
-       return class;
-}
-
-static VALUE template_each(int argc, VALUE *argv, VALUE class)
-{
-       enumerator_t *enumerator;
-       char *template;
-
-       if (!rb_block_given_p())
-       {
-               rb_raise(rb_eArgError, "must be called with a block");
-       }
-       enumerator = dumm->create_template_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &template))
-       {
-               rb_yield(rb_str_new2(template));
-       }
-       enumerator->destroy(enumerator);
-       return class;
-}
-
-static void template_init()
-{
-       rbc_template = rb_define_class_under(rbm_dumm , "Template", rb_cObject);
-       rb_include_module(rb_class_of(rbc_template), rb_mEnumerable);
-
-       rb_define_singleton_method(rbc_template, "load", template_load, 1);
-       rb_define_singleton_method(rbc_template, "unload", template_unload, 0);
-       rb_define_singleton_method(rbc_template, "each", template_each, -1);
-}
-
-/**
- * extension finalization
- */
-void Final_dumm()
-{
-       struct sigaction action;
-
-       dumm->destroy(dumm);
-
-       sigemptyset(&action.sa_mask);
-       action.sa_handler = SIG_DFL;
-       action.sa_flags = 0;
-       sigaction(SIGCHLD, &action, NULL);
-
-       library_deinit();
-}
-
-/**
- * extension initialization
- */
-void Init_dumm()
-{
-       struct sigaction action;
-
-       /* there are too many to report, rubyruby... */
-       setenv("LEAK_DETECTIVE_DISABLE", "1", 1);
-
-       library_init(NULL, "dumm");
-
-       dumm = dumm_create(NULL);
-
-       dumm_init();
-       guest_init();
-       bridge_init();
-       iface_init();
-       template_init();
-
-       sigemptyset(&action.sa_mask);
-       action.sa_sigaction = sigchld_handler;
-       action.sa_flags = SA_SIGINFO;
-       sigaction(SIGCHLD, &action, NULL);
-
-       rb_set_end_proc(Final_dumm, 0);
-}
diff --git a/src/dumm/ext/extconf.rb.in b/src/dumm/ext/extconf.rb.in
deleted file mode 100644 (file)
index 29df65c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# DUMM for Ruby
-#
-
-require 'mkmf'
-
-$defs << " @DEFS@"
-$CFLAGS << " -Wno-format -include \"@top_builddir@/config.h\""
-
-dir_config('dumm', '@top_srcdir@/src/dumm', '../.libs')
-dir_config('strongswan', '@top_srcdir@/src/libstrongswan', '../../libstrongswan/.libs')
-
-unless find_library('dumm', 'dumm_create')
-  puts "... failed: 'libdumm' not found!"
-  exit
-end
-
-create_makefile('dumm', '@top_srcdir@/src/dumm/ext')
-
diff --git a/src/dumm/ext/lib/dumm.rb b/src/dumm/ext/lib/dumm.rb
deleted file mode 100644 (file)
index 0dd7ada..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-=begin
-  Copyright (C) 2008-2009 Tobias Brunner
-  HSR Hochschule fuer Technik Rapperswil
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the
-  Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
-
-  This program is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-  for more details.
-=end
-
-require 'dumm.so'
-require 'dumm/guest'
-
-module Dumm
-  
-  # use guest/bridge indentifiers directly
-  def method_missing(id, *args)
-    if Guest.guest? id
-      return Guest[id]
-    end
-    if Bridge.bridge? id
-      return Bridge[id]
-    end
-    super(id, *args)
-  end
-  
-  # shortcut for Template loading
-  def template(name = nil)
-    if name
-      Template.load name
-    else
-      Template.sort.each {|t| puts t }
-    end
-    return Dumm
-  end
-  
-  # unload template/overlays, reset all guests and delete bridges
-  def reset
-    Template.unload
-    Guest.each { |guest|
-      guest.reset
-    }
-    Bridge.each { |bridge|
-      bridge.delete
-    }
-    return Dumm
-  end
-  
-  # wait until all running guests have booted up
-  def boot
-    Guest.each {|g|
-      g.boot if g.running?
-    }
-    return Dumm
-  end
-end
-
-# vim:sw=2 ts=2 et
diff --git a/src/dumm/ext/lib/dumm/guest.rb b/src/dumm/ext/lib/dumm/guest.rb
deleted file mode 100644 (file)
index 6978edc..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-=begin
-  Copyright (C) 2008-2010 Tobias Brunner
-  HSR Hochschule fuer Technik Rapperswil
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by the
-  Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
-
-  This program is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-  for more details.
-=end
-
-module Dumm
-  class Guest
-    # accessor for guests
-    # e.g. Guest.sun instead of Guest["sun"]
-    def self.method_missing(id, *args)
-      unless guest? id
-        super(id, *args)
-      end
-      Guest[id]
-    end
-
-    # accessor for interfaces
-    # e.g. guest.eth0 instead of guest["eth0"]
-    def method_missing(id, *args)
-      unless iface? id
-        super(id, *args)
-      end
-      self[id]
-    end
-
-    # remove all overlays, delete all interfaces
-    def reset
-      while pop_overlay; end
-      each {|i|
-        i.delete
-      }
-    end
-
-    # has the guest booted up?
-    def booted?
-      exec("pgrep getty")
-      execstatus == 0
-    end
-
-    # wait until the guest has booted
-    def boot
-      while not booted?
-        sleep(1)
-      end
-    end
-  end
-end
-
-# vim:sw=2 ts=2 et
diff --git a/src/dumm/guest.c b/src/dumm/guest.c
deleted file mode 100644 (file)
index 327b86c..0000000
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <dirent.h>
-#include <termios.h>
-#include <stdarg.h>
-
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-
-#include "dumm.h"
-#include "guest.h"
-#include "mconsole.h"
-#include "cowfs.h"
-
-#define PERME (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
-#define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
-
-#define MASTER_DIR "master"
-#define DIFF_DIR "diff"
-#define UNION_DIR "union"
-#define ARGS_FILE "args"
-#define PID_FILE "pid"
-#define KERNEL_FILE "linux"
-#define LOG_FILE "boot.log"
-#define NOTIFY_FILE "notify"
-#define PTYS 0
-
-typedef struct private_guest_t private_guest_t;
-
-struct private_guest_t {
-       /** implemented public interface */
-       guest_t public;
-       /** name of the guest */
-       char *name;
-       /** directory of guest */
-       int dir;
-       /** directory name of guest */
-       char *dirname;
-       /** additional args to pass to guest */
-       char *args;
-       /** pid of guest child process */
-       int pid;
-       /** state of guest */
-       guest_state_t state;
-       /** FUSE cowfs instance */
-       cowfs_t *cowfs;
-       /** mconsole to control running UML */
-       mconsole_t *mconsole;
-       /** list of interfaces attached to the guest */
-       linked_list_t *ifaces;
-};
-
-ENUM(guest_state_names, GUEST_STOPPED, GUEST_STOPPING,
-       "STOPPED",
-       "STARTING",
-       "RUNNING",
-       "PAUSED",
-       "STOPPING",
-);
-
-METHOD(guest_t, get_name, char*,
-       private_guest_t *this)
-{
-       return this->name;
-}
-
-METHOD(guest_t, create_iface, iface_t*,
-       private_guest_t *this, char *name)
-{
-       enumerator_t *enumerator;
-       iface_t *iface;
-
-       if (this->state != GUEST_RUNNING)
-       {
-               DBG1(DBG_LIB, "guest '%s' not running, unable to add interface",
-                        this->name);
-               return NULL;
-       }
-
-       enumerator = this->ifaces->create_enumerator(this->ifaces);
-       while (enumerator->enumerate(enumerator, (void**)&iface))
-       {
-               if (streq(name, iface->get_guestif(iface)))
-               {
-                       DBG1(DBG_LIB, "guest '%s' already has an interface '%s'",
-                                this->name, name);
-                       enumerator->destroy(enumerator);
-                       return NULL;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       iface = iface_create(name, &this->public, this->mconsole);
-       if (iface)
-       {
-               this->ifaces->insert_last(this->ifaces, iface);
-       }
-       return iface;
-}
-
-METHOD(guest_t, destroy_iface, void,
-       private_guest_t *this, iface_t *iface)
-{
-       enumerator_t *enumerator;
-       iface_t *current;
-
-       enumerator = this->ifaces->create_enumerator(this->ifaces);
-       while (enumerator->enumerate(enumerator, (void**)&current))
-       {
-               if (current == iface)
-               {
-                       this->ifaces->remove_at(this->ifaces, enumerator);
-                       current->destroy(current);
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-METHOD(guest_t, create_iface_enumerator, enumerator_t*,
-       private_guest_t *this)
-{
-       return this->ifaces->create_enumerator(this->ifaces);
-}
-
-METHOD(guest_t, get_state, guest_state_t,
-       private_guest_t *this)
-{
-       return this->state;
-}
-
-METHOD(guest_t, get_pid, pid_t,
-       private_guest_t *this)
-{
-       return this->pid;
-}
-
-/**
- * write format string to a buffer, and advance buffer position
- */
-static char* write_arg(char **pos, size_t *left, char *format, ...)
-{
-       size_t len;
-       char *res = NULL;
-       va_list args;
-
-       va_start(args, format);
-       len = vsnprintf(*pos, *left, format, args);
-       va_end(args);
-       if (len < *left)
-       {
-               res = *pos;
-               len++;
-               *pos += len + 1;
-               *left -= len + 1;
-       }
-       return res;
-}
-
-METHOD(guest_t, stop, void,
-       private_guest_t *this, idle_function_t idle)
-{
-       if (this->state != GUEST_STOPPED)
-       {
-               this->state = GUEST_STOPPING;
-               this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy));
-               this->ifaces = linked_list_create();
-               kill(this->pid, SIGINT);
-               while (this->state != GUEST_STOPPED)
-               {
-                       if (idle)
-                       {
-                               idle();
-                       }
-                       else
-                       {
-                               usleep(50000);
-                       }
-               }
-               unlinkat(this->dir, PID_FILE, 0);
-               this->pid = 0;
-       }
-}
-
-/**
- * save pid in file
- */
-void savepid(private_guest_t *this)
-{
-       FILE *file;
-
-       file = fdopen(openat(this->dir, PID_FILE, O_RDWR | O_CREAT | O_TRUNC,
-                                                PERM), "w");
-       if (file)
-       {
-               fprintf(file, "%d", this->pid);
-               fclose(file);
-       }
-}
-
-METHOD(guest_t, start, bool,
-       private_guest_t *this, invoke_function_t invoke, void* data,
-       idle_function_t idle)
-{
-       char buf[2048];
-       char *notify;
-       char *pos = buf;
-       char *args[32];
-       int i = 0;
-       size_t left = sizeof(buf);
-
-       memset(args, 0, sizeof(args));
-
-       if (this->state != GUEST_STOPPED)
-       {
-               DBG1(DBG_LIB, "unable to start guest in state %N", guest_state_names,
-                        this->state);
-               return FALSE;
-       }
-       this->state = GUEST_STARTING;
-
-       notify = write_arg(&pos, &left, "%s/%s", this->dirname, NOTIFY_FILE);
-
-       args[i++] = write_arg(&pos, &left, "nice");
-       args[i++] = write_arg(&pos, &left, "%s/%s", this->dirname, KERNEL_FILE);
-       args[i++] = write_arg(&pos, &left, "root=/dev/root");
-       args[i++] = write_arg(&pos, &left, "rootfstype=hostfs");
-       args[i++] = write_arg(&pos, &left, "rootflags=%s/%s", this->dirname, UNION_DIR);
-       args[i++] = write_arg(&pos, &left, "uml_dir=%s", this->dirname);
-       args[i++] = write_arg(&pos, &left, "umid=%s", this->name);
-       args[i++] = write_arg(&pos, &left, "mconsole=notify:%s", notify);
-       args[i++] = write_arg(&pos, &left, "con=null");
-       if (this->args)
-       {
-               args[i++] = this->args;
-       }
-
-       this->pid = invoke(data, &this->public, args, i);
-       if (!this->pid)
-       {
-               this->state = GUEST_STOPPED;
-               return FALSE;
-       }
-       savepid(this);
-
-       /* open mconsole */
-       this->mconsole = mconsole_create(notify, idle);
-       if (this->mconsole == NULL)
-       {
-               DBG1(DBG_LIB, "opening mconsole at '%s' failed, stopping guest", buf);
-               stop(this, NULL);
-               return FALSE;
-       }
-
-       this->state = GUEST_RUNNING;
-       return TRUE;
-}
-
-METHOD(guest_t, add_overlay, bool,
-       private_guest_t *this, char *path)
-{
-       if (path == NULL)
-       {
-               return FALSE;
-       }
-
-       if (access(path, F_OK) != 0)
-       {
-               if (!mkdir_p(path, PERME))
-               {
-                       DBG1(DBG_LIB, "creating overlay for guest '%s' failed: %m",
-                                this->name);
-                       return FALSE;
-               }
-       }
-
-       return this->cowfs->add_overlay(this->cowfs, path);
-}
-
-METHOD(guest_t, del_overlay, bool,
-       private_guest_t *this, char *path)
-{
-       return this->cowfs->del_overlay(this->cowfs, path);
-}
-
-METHOD(guest_t, pop_overlay, bool,
-       private_guest_t *this)
-{
-       return this->cowfs->pop_overlay(this->cowfs);
-}
-
-/**
- * Variadic version of the exec function
- */
-static int vexec(private_guest_t *this, void(*cb)(void*,char*,size_t), void *data,
-                                char *cmd, va_list args)
-{
-       char buf[1024];
-       size_t len;
-
-       if (this->mconsole)
-       {
-               len = vsnprintf(buf, sizeof(buf), cmd, args);
-
-               if (len > 0 && len < sizeof(buf))
-               {
-                       return this->mconsole->exec(this->mconsole, cb, data, buf);
-               }
-       }
-       return -1;
-}
-
-METHOD(guest_t, exec, int,
-       private_guest_t *this, void(*cb)(void*,char*,size_t), void *data,
-       char *cmd, ...)
-{
-       int res;
-       va_list args;
-       va_start(args, cmd);
-       res = vexec(this, cb, data, cmd, args);
-       va_end(args);
-       return res;
-}
-
-typedef struct {
-       chunk_t buf;
-       void (*cb)(void*,char*);
-       void *data;
-} exec_str_t;
-
-/**
- * callback that combines chunks to a string. if a callback is given, the string
- * is split at newlines and the callback is called for each line.
- */
-static void exec_str_cb(exec_str_t *data, char *buf, size_t len)
-{
-       if (!data->buf.ptr)
-       {
-               data->buf = chunk_alloc(len + 1);
-               memcpy(data->buf.ptr, buf, len);
-               data->buf.ptr[len] = '\0';
-       }
-       else
-       {
-               size_t newlen = strlen(data->buf.ptr) + len + 1;
-               if (newlen > data->buf.len)
-               {
-                       data->buf.ptr = realloc(data->buf.ptr, newlen);
-                       data->buf.len = newlen;
-               }
-               strncat(data->buf.ptr, buf, len);
-       }
-
-       if (data->cb)
-       {
-               char *nl;
-               while ((nl = strchr(data->buf.ptr, '\n')) != NULL)
-               {
-                       *nl++ = '\0';
-                       data->cb(data->data, data->buf.ptr);
-                       memmove(data->buf.ptr, nl, strlen(nl) + 1);
-               }
-       }
-}
-
-METHOD(guest_t, exec_str, int,
-       private_guest_t *this, void(*cb)(void*,char*), bool lines, void *data,
-       char *cmd, ...)
-{
-       int res;
-       va_list args;
-       va_start(args, cmd);
-       if (cb)
-       {
-               exec_str_t exec = { chunk_empty, NULL, NULL };
-               if (lines)
-               {
-                       exec.cb = cb;
-                       exec.data = data;
-               }
-               res = vexec(this, (void(*)(void*,char*,size_t))exec_str_cb, &exec, cmd, args);
-               if (exec.buf.ptr)
-               {
-                       if (!lines || strlen(exec.buf.ptr) > 0)
-                       {
-                               /* return the complete string or the remaining stuff in the
-                                * buffer (i.e. when there was no newline at the end) */
-                               cb(data, exec.buf.ptr);
-                       }
-                       chunk_free(&exec.buf);
-               }
-       }
-       else
-       {
-               res = vexec(this, NULL, NULL, cmd, args);
-       }
-       va_end(args);
-       return res;
-}
-
-METHOD(guest_t, sigchild, void,
-       private_guest_t *this)
-{
-       DESTROY_IF(this->mconsole);
-       this->mconsole = NULL;
-       this->state = GUEST_STOPPED;
-}
-
-/**
- * umount the union filesystem
- */
-static bool umount_unionfs(private_guest_t *this)
-{
-       if (this->cowfs)
-       {
-               this->cowfs->destroy(this->cowfs);
-               this->cowfs = NULL;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * mount the union filesystem
- */
-static bool mount_unionfs(private_guest_t *this)
-{
-       char master[PATH_MAX];
-       char diff[PATH_MAX];
-       char mount[PATH_MAX];
-
-       if (this->cowfs == NULL)
-       {
-               snprintf(master, sizeof(master), "%s/%s", this->dirname, MASTER_DIR);
-               snprintf(diff, sizeof(diff), "%s/%s", this->dirname, DIFF_DIR);
-               snprintf(mount, sizeof(mount), "%s/%s", this->dirname, UNION_DIR);
-
-               this->cowfs = cowfs_create(master, diff, mount);
-               if (this->cowfs)
-               {
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-/**
- * load args configuration from file
- */
-char *loadargs(private_guest_t *this)
-{
-       FILE *file;
-       char buf[512], *args = NULL;
-
-       file = fdopen(openat(this->dir, ARGS_FILE, O_RDONLY, PERM), "r");
-       if (file)
-       {
-               if (fgets(buf, sizeof(buf), file))
-               {
-                       args = strdup(buf);
-               }
-               fclose(file);
-       }
-       return args;
-}
-
-/**
- * save args configuration to file
- */
-bool saveargs(private_guest_t *this, char *args)
-{
-       FILE *file;
-       bool retval = FALSE;
-
-       file = fdopen(openat(this->dir, ARGS_FILE, O_RDWR | O_CREAT | O_TRUNC,
-                                                PERM), "w");
-       if (file)
-       {
-               if (fprintf(file, "%s", args) > 0)
-               {
-                       retval = TRUE;
-               }
-               fclose(file);
-       }
-       return retval;
-}
-
-METHOD(guest_t, destroy, void,
-       private_guest_t *this)
-{
-       stop(this, NULL);
-       umount_unionfs(this);
-       if (this->dir > 0)
-       {
-               close(this->dir);
-       }
-       this->ifaces->destroy(this->ifaces);
-       free(this->dirname);
-       free(this->args);
-       free(this->name);
-       free(this);
-}
-
-/**
- * generic guest constructor
- */
-static private_guest_t *guest_create_generic(char *parent, char *name,
-                                                                                        bool create)
-{
-       char cwd[PATH_MAX];
-       private_guest_t *this;
-
-       INIT(this,
-               .public = {
-                       .get_name = _get_name,
-                       .get_pid = _get_pid,
-                       .get_state = _get_state,
-                       .create_iface = _create_iface,
-                       .destroy_iface = _destroy_iface,
-                       .create_iface_enumerator = _create_iface_enumerator,
-                       .start = _start,
-                       .stop = _stop,
-                       .add_overlay = _add_overlay,
-                       .del_overlay = _del_overlay,
-                       .pop_overlay = _pop_overlay,
-                       .exec = _exec,
-                       .exec_str = _exec_str,
-                       .sigchild = _sigchild,
-                       .destroy = _destroy,
-               }
-       );
-
-       if (*parent == '/' || getcwd(cwd, sizeof(cwd)) == NULL)
-       {
-               if (asprintf(&this->dirname, "%s/%s", parent, name) < 0)
-               {
-                       this->dirname = NULL;
-               }
-       }
-       else
-       {
-               if (asprintf(&this->dirname, "%s/%s/%s", cwd, parent, name) < 0)
-               {
-                       this->dirname = NULL;
-               }
-       }
-       if (this->dirname == NULL)
-       {
-               free(this);
-               return NULL;
-       }
-       if (create)
-       {
-               mkdir(this->dirname, PERME);
-       }
-       this->dir = open(this->dirname, O_DIRECTORY, PERME);
-       if (this->dir < 0)
-       {
-               DBG1(DBG_LIB, "opening guest directory '%s' failed: %m", this->dirname);
-               free(this->dirname);
-               free(this);
-               return NULL;
-       }
-       this->state = GUEST_STOPPED;
-       this->ifaces = linked_list_create();
-       this->name = strdup(name);
-
-       return this;
-}
-
-/**
- * create a symlink to old called new in our working dir
- */
-static bool make_symlink(private_guest_t *this, char *old, char *new)
-{
-       char cwd[PATH_MAX];
-       char buf[PATH_MAX];
-
-       if (*old == '/' || getcwd(cwd, sizeof(cwd)) == NULL)
-       {
-               snprintf(buf, sizeof(buf), "%s", old);
-       }
-       else
-       {
-               snprintf(buf, sizeof(buf), "%s/%s", cwd, old);
-       }
-       return symlinkat(buf, this->dir, new) == 0;
-}
-
-
-/**
- * create the guest instance, including required dirs and mounts
- */
-guest_t *guest_create(char *parent, char *name, char *kernel,
-                                         char *master, char *args)
-{
-       private_guest_t *this = guest_create_generic(parent, name, TRUE);
-
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       if (!make_symlink(this, master, MASTER_DIR) ||
-               !make_symlink(this, kernel, KERNEL_FILE))
-       {
-               DBG1(DBG_LIB, "creating master/kernel symlink failed: %m");
-               destroy(this);
-               return NULL;
-       }
-
-       if (mkdirat(this->dir, UNION_DIR, PERME) != 0 ||
-               mkdirat(this->dir, DIFF_DIR, PERME) != 0)
-       {
-               DBG1(DBG_LIB, "unable to create directories for '%s': %m", name);
-               destroy(this);
-               return NULL;
-       }
-
-       this->args = args;
-       if (args && !saveargs(this, args))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       if (!mount_unionfs(this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
-/**
- * load an already created guest
- */
-guest_t *guest_load(char *parent, char *name)
-{
-       private_guest_t *this = guest_create_generic(parent, name, FALSE);
-
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       this->args = loadargs(this);
-
-       if (!mount_unionfs(this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
diff --git a/src/dumm/guest.h b/src/dumm/guest.h
deleted file mode 100644 (file)
index 14c7272..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef GUEST_H
-#define GUEST_H
-
-#include <library.h>
-#include <collections/enumerator.h>
-
-typedef enum guest_state_t guest_state_t;
-typedef struct guest_t guest_t;
-
-#include "iface.h"
-
-/**
- * State of a guest (started, stopped, ...)
- */
-enum guest_state_t {
-       /** guest kernel not running at all */
-       GUEST_STOPPED,
-       /** kernel started, but not yet available */
-       GUEST_STARTING,
-       /** guest is up and running */
-       GUEST_RUNNING,
-       /** guest has been paused */
-       GUEST_PAUSED,
-       /** guest is stopping (shutting down) */
-       GUEST_STOPPING,
-};
-
-/**
- * string mappings for guest_state_t
- */
-extern enum_name_t *guest_state_names;
-
-/**
- * Invoke function which launches the UML guest.
- *
- * Consoles are all set to NULL, you may change them by adding additional UML
- * options to args before invocation.
- *
- * @param data         callback data
- * @param guest                guest to start
- * @param args         args to use for guest invocation, args[0] is kernel
- * @param argc         number of elements in args
- * @param idle
- * @return                     PID of child, 0 if failed
- */
-typedef pid_t (*invoke_function_t)(void *data, guest_t *guest,
-                                                                  char *args[], int argc);
-
-/**
- * Idle function to pass to start().
- */
-typedef void (*idle_function_t)(void);
-
-/**
- * A guest is a UML instance running on the host.
- **/
-struct guest_t {
-
-       /**
-        * Get the name of this guest.
-        *
-        * @return              name of the guest
-        */
-       char* (*get_name) (guest_t *this);
-
-       /**
-        * Get the process ID of the guest child process.
-        *
-        * @return              name of the guest
-        */
-       pid_t (*get_pid) (guest_t *this);
-
-       /**
-        * Get the state of the guest (stopped, started, etc.).
-        *
-        * @return              guests state
-        */
-       guest_state_t (*get_state)(guest_t *this);
-
-       /**
-        * Start the guest.
-        *
-        * @param invoke        UML guest invocation function
-        * @param data          data to pass back to invoke function
-        * @param idle          idle function to call while waiting on child
-        * @return                      TRUE if guest successfully started
-        */
-       bool (*start) (guest_t *this, invoke_function_t invoke, void *data,
-                                  idle_function_t idle);
-
-       /**
-        * Kill the guest.
-        *
-        * @param idle          idle function to call while waiting to termination
-        */
-       void (*stop) (guest_t *this, idle_function_t idle);
-
-       /**
-        * Create a new interface in the current scenario.
-        *
-        * @param name  name of the interface in the guest
-        * @return              created interface, or NULL if failed
-        */
-       iface_t* (*create_iface)(guest_t *this, char *name);
-
-       /**
-        * Destroy an interface on guest.
-        *
-        * @param iface interface to destroy
-        */
-       void (*destroy_iface)(guest_t *this, iface_t *iface);
-
-       /**
-        * Create an enumerator over all guest interfaces.
-        *
-        * @return              enumerator over iface_t's
-        */
-       enumerator_t* (*create_iface_enumerator)(guest_t *this);
-
-       /**
-        * Adds a COWFS overlay. The directory is created if it does not exist.
-        *
-        * @param dir           directory where overlay diff should point to
-        * @return                      FALSE, if failed
-        */
-       bool (*add_overlay)(guest_t *this, char *dir);
-
-       /**
-        * Removes the specified COWFS overlay.
-        *
-        * @param dir           directory where overlay diff points to
-        * @return                      FALSE, if no found
-        */
-       bool (*del_overlay)(guest_t *this, char *dir);
-
-       /**
-        * Removes the latest COWFS overlay.
-        *
-        * @return                      FALSE, if no overlay was found
-        */
-       bool (*pop_overlay)(guest_t *this);
-
-       /**
-        * Execute a command on the guests mconsole.
-        *
-        * @param cb            callback to call for each read block
-        * @param data          data to pass to callback
-        * @param cmd           command to execute
-        * @param ...           printf style argument list for cmd
-        * @return                      return value
-        */
-       int (*exec)(guest_t *this, void(*cb)(void*,char*,size_t), void *data,
-                               char *cmd, ...);
-
-       /**
-        * Execute a command on the guests mconsole, with output formatter.
-        *
-        * If lines is TRUE, callback is invoked for each output line. Otherwise
-        * the full result is returned in one callback invocation.
-        *
-        * @note This function does not work with binary output.
-        *
-        * @param cb            callback to call for each line or for the complete output
-        * @param lines         TRUE if the callback should be called for each line
-        * @param data          data to pass to callback
-        * @param cmd           command to execute
-        * @param ...           printf style argument list for cmd
-        * @return                      return value
-        */
-       int (*exec_str)(guest_t *this, void(*cb)(void*,char*), bool lines,
-                                       void *data, char *cmd, ...);
-
-       /**
-        * Called whenever a SIGCHILD for the guests PID is received.
-        */
-       void (*sigchild)(guest_t *this);
-
-       /**
-        * Close and destroy a guest with all interfaces
-        */
-       void (*destroy) (guest_t *this);
-};
-
-/**
- * Create a new, unstarted guest.
- *
- * @param parent       parent directory to create the guest in
- * @param name         name of the guest to create
- * @param kernel       kernel this guest uses
- * @param master       read-only master filesystem for guest
- * @param args         additional args to pass to kernel
- * @param mem          amount of memory to give the guest
- */
-guest_t *guest_create(char *parent, char *name, char *kernel,
-                                         char *master, char *args);
-
-/**
- * Load a guest created with guest_create().
- *
- * @param parent       parent directory to look for a guest
- * @param name         name of the guest directory
- */
-guest_t *guest_load(char *parent, char *name);
-
-#endif /* GUEST_H */
-
diff --git a/src/dumm/iface.c b/src/dumm/iface.c
deleted file mode 100644 (file)
index 3642ed8..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- * Copyright (C) 2002 Jeff Dike
- *
- * Based on the "tunctl" utility from Jeff Dike.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <linux/if_tun.h>
-
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-
-#include "iface.h"
-
-typedef struct private_iface_t private_iface_t;
-
-struct private_iface_t {
-       /** public interface */
-       iface_t public;
-       /** device name in guest (eth0) */
-       char *guestif;
-       /** device name at host (tap0) */
-       char *hostif;
-       /** bridge this interface is attached to */
-       bridge_t *bridge;
-       /** guest this interface is attached to */
-       guest_t *guest;
-       /** mconsole for guest */
-       mconsole_t *mconsole;
-};
-
-/**
- * bring an interface up or down (host side)
- */
-bool iface_control(char *name, bool up)
-{
-       int s;
-       bool good = FALSE;
-       struct ifreq ifr;
-
-       memset(&ifr, 0, sizeof(struct ifreq));
-       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
-
-       s = socket(AF_INET, SOCK_DGRAM, 0);
-       if (!s)
-       {
-               return FALSE;
-       }
-       if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0)
-       {
-               if (up)
-               {
-                       ifr.ifr_flags |= IFF_UP;
-               }
-               else
-               {
-                       ifr.ifr_flags &= ~IFF_UP;
-               }
-               if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
-               {
-                       good = TRUE;
-               }
-       }
-       close(s);
-       return good;
-}
-
-METHOD(iface_t, get_guestif, char*,
-       private_iface_t *this)
-{
-       return this->guestif;
-}
-
-METHOD(iface_t, get_hostif, char*,
-       private_iface_t *this)
-{
-       return this->hostif;
-}
-
-METHOD(iface_t, add_address, bool,
-       private_iface_t *this, host_t *addr, int bits)
-{
-       return (this->guest->exec(this->guest, NULL, NULL,
-                       "exec ip addr add %H/%d dev %s", addr, bits, this->guestif) == 0);
-}
-
-/**
- * compile a list of the addresses of an interface
- */
-static void compile_address_list(linked_list_t *list, char *address)
-{
-       host_t *host = host_create_from_string(address, 0);
-       if (host)
-       {
-               list->insert_last(list, host);
-       }
-}
-
-/**
- * delete the list of addresses
- */
-static void destroy_address_list(linked_list_t *list)
-{
-       list->destroy_offset(list, offsetof(host_t, destroy));
-}
-
-METHOD(iface_t, create_address_enumerator, enumerator_t*,
-       private_iface_t *this)
-{
-       linked_list_t *addresses = linked_list_create();
-       this->guest->exec_str(this->guest, (void(*)(void*,char*))compile_address_list,
-                       TRUE, addresses,
-                       "exec ip addr list dev %s scope global | "
-                       "grep '^ \\+\\(inet6\\? \\)' | "
-                       "awk -F '( +|/)' '{ print $3 }'", this->guestif);
-       return enumerator_create_cleaner(addresses->create_enumerator(addresses),
-                                       (void(*)(void*))destroy_address_list, addresses);
-}
-
-METHOD(iface_t, delete_address, bool,
-       private_iface_t *this, host_t *addr, int bits)
-{
-       return (this->guest->exec(this->guest, NULL, NULL,
-                       "exec ip addr del %H/%d dev %s", addr, bits, this->guestif) == 0);
-}
-
-METHOD(iface_t, set_bridge, void,
-       private_iface_t *this, bridge_t *bridge)
-{
-       if (this->bridge == NULL && bridge)
-       {
-               this->guest->exec(this->guest, NULL, NULL,
-                                                 "exec ip link set %s up", this->guestif);
-       }
-       else if (this->bridge && bridge == NULL)
-       {
-               this->guest->exec(this->guest, NULL, NULL,
-                                                 "exec ip link set %s down", this->guestif);
-       }
-       this->bridge = bridge;
-}
-
-METHOD(iface_t, get_bridge, bridge_t*,
-       private_iface_t *this)
-{
-       return this->bridge;
-}
-
-METHOD(iface_t, get_guest, guest_t*,
-       private_iface_t *this)
-{
-       return this->guest;
-}
-
-/**
- * destroy the tap device
- */
-static bool destroy_tap(private_iface_t *this)
-{
-       struct ifreq ifr;
-       int tap;
-
-       if (!iface_control(this->hostif, FALSE))
-       {
-               DBG1(DBG_LIB, "bringing iface down failed: %m");
-       }
-       memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       strncpy(ifr.ifr_name, this->hostif, sizeof(ifr.ifr_name) - 1);
-
-       tap = open(TAP_DEVICE, O_RDWR);
-       if (tap < 0)
-       {
-               DBG1(DBG_LIB, "unable to open tap device %s: %m", TAP_DEVICE);
-               return FALSE;
-       }
-       if (ioctl(tap, TUNSETIFF, &ifr) < 0 ||
-               ioctl(tap, TUNSETPERSIST, 0) < 0)
-       {
-               DBG1(DBG_LIB, "removing %s failed: %m", this->hostif);
-               close(tap);
-               return FALSE;
-       }
-       close(tap);
-       return TRUE;
-}
-
-/**
- * create the tap device
- */
-static char* create_tap(private_iface_t *this)
-{
-       struct ifreq ifr;
-       int tap;
-
-       memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-       snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s-%s",
-                        this->guest->get_name(this->guest), this->guestif);
-
-       tap = open(TAP_DEVICE, O_RDWR);
-       if (tap < 0)
-       {
-               DBG1(DBG_LIB, "unable to open tap device %s: %m", TAP_DEVICE);
-               return NULL;
-       }
-       if (ioctl(tap, TUNSETIFF, &ifr) < 0 ||
-               ioctl(tap, TUNSETPERSIST, 1) < 0 ||
-               ioctl(tap, TUNSETOWNER, 0))
-       {
-               DBG1(DBG_LIB, "creating new tap device failed: %m");
-               close(tap);
-               return NULL;
-       }
-       close(tap);
-       return strdup(ifr.ifr_name);
-}
-
-METHOD(iface_t, destroy, void,
-       private_iface_t *this)
-{
-       if (this->bridge)
-       {
-               this->bridge->disconnect_iface(this->bridge, &this->public);
-       }
-       /* TODO: iface mgmt is not blocking yet, so wait some ticks */
-       usleep(50000);
-       this->mconsole->del_iface(this->mconsole, this->guestif);
-       destroy_tap(this);
-       free(this->guestif);
-       free(this->hostif);
-       free(this);
-}
-
-/**
- * create the iface instance
- */
-iface_t *iface_create(char *name, guest_t *guest, mconsole_t *mconsole)
-{
-       private_iface_t *this;
-
-       INIT(this,
-               .public = {
-                       .get_hostif = _get_hostif,
-                       .get_guestif = _get_guestif,
-                       .add_address = _add_address,
-                       .create_address_enumerator = _create_address_enumerator,
-                       .delete_address = _delete_address,
-                       .set_bridge = _set_bridge,
-                       .get_bridge = _get_bridge,
-                       .get_guest = _get_guest,
-                       .destroy = _destroy,
-               },
-               .mconsole = mconsole,
-               .guestif = strdup(name),
-               .guest = guest,
-       );
-       this->hostif = create_tap(this);
-       if (this->hostif == NULL)
-       {
-               destroy_tap(this);
-               free(this->guestif);
-               free(this);
-               return NULL;
-       }
-       if (!this->mconsole->add_iface(this->mconsole, this->guestif, this->hostif))
-       {
-               DBG1(DBG_LIB, "creating interface '%s' in guest failed", this->guestif);
-               destroy_tap(this);
-               free(this->guestif);
-               free(this->hostif);
-               free(this);
-               return NULL;
-       }
-       if (!iface_control(this->hostif, TRUE))
-       {
-               DBG1(DBG_LIB, "bringing iface '%s' up failed: %m", this->hostif);
-       }
-       return &this->public;
-}
-
diff --git a/src/dumm/iface.h b/src/dumm/iface.h
deleted file mode 100644 (file)
index e6e8775..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef IFACE_H
-#define IFACE_H
-
-#include <library.h>
-#include <collections/enumerator.h>
-#include <networking/host.h>
-
-#define TAP_DEVICE "/dev/net/tun"
-
-typedef struct iface_t iface_t;
-
-#include "mconsole.h"
-#include "bridge.h"
-#include "guest.h"
-
-/**
- * Interface in a guest, connected to a tap device on the host.
- */
-struct iface_t {
-
-       /**
-        * Get the interface name in the guest (e.g. eth0).
-        *
-        * @return                      guest interface name
-        */
-       char* (*get_guestif)(iface_t *this);
-
-       /**
-        * Get the interface name at the host (e.g. tap0).
-        *
-        * @return                      host interface (tap device) name
-        */
-       char* (*get_hostif)(iface_t *this);
-
-       /**
-        * Add an address to the interface.
-        *
-        * @param addr          address to add to the interface
-        * @param bits          network prefix length in bits
-        * @return                      TRUE if address added
-        */
-       bool (*add_address)(iface_t *this, host_t *addr, int bits);
-
-       /**
-        * Create an enumerator over all installed addresses.
-        *
-        * @return                      enumerator over host_t*
-        */
-       enumerator_t* (*create_address_enumerator)(iface_t *this);
-
-       /**
-        * Remove an address from an interface.
-        *
-        * @note The network prefix length has to be the same as used in add_address
-        *
-        * @param addr          address to remove
-        * @param bits          network prefix length in bits
-        * @return                      TRUE if address removed
-        */
-       bool (*delete_address)(iface_t *this, host_t *addr, int bits);
-
-       /**
-        * Set the bridge this interface is attached to.
-        *
-        * @param bridge        assigned bridge, or NULL for none
-        */
-       void (*set_bridge)(iface_t *this, bridge_t *bridge);
-
-       /**
-        * Get the bridge this iface is connected, or NULL.
-        *
-        * @return                      connected bridge, or NULL
-        */
-       bridge_t* (*get_bridge)(iface_t *this);
-
-       /**
-        * Get the guest this iface belongs to.
-        *
-        * @return                      guest of this iface
-        */
-       guest_t* (*get_guest)(iface_t *this);
-
-       /**
-        * Destroy an interface
-        */
-       void (*destroy) (iface_t *this);
-};
-
-/**
- * Create a new interface for a guest
- *
- * @param name         name of the interface in the guest
- * @param guest                guest this iface is connecting
- * @param mconsole     mconsole of guest
- * @return                     interface descriptor, or NULL if failed
- */
-iface_t *iface_create(char *name, guest_t *guest, mconsole_t *mconsole);
-
-#endif /* IFACE_H */
-
diff --git a/src/dumm/irdumm.c b/src/dumm/irdumm.c
deleted file mode 100644 (file)
index eb61da2..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#undef PACKAGE_NAME
-#undef PACKAGE_TARNAME
-#undef PACKAGE_VERSION
-#undef PACKAGE_STRING
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_URL
-#undef HAVE_DLADDR
-#undef HAVE_QSORT_R
-#include <ruby.h>
-
-#ifdef HAVE_RB_ERRINFO
-#define ruby_errinfo rb_errinfo()
-#endif
-
-/**
- * main routine, parses args and reads from console
- */
-int main(int argc, char *argv[])
-{
-       int state, i;
-       char buf[512];
-
-       ruby_init();
-       ruby_init_loadpath();
-
-       rb_eval_string_protect("require 'dumm' and include Dumm", &state);
-       if (state)
-       {
-               rb_p(ruby_errinfo);
-               printf("Please install the ruby extension first!\n");
-       }
-       for (i = 1; i < argc; i++)
-       {
-               snprintf(buf, sizeof(buf), "load \"%s\"", argv[i]);
-               printf("%s\n", buf);
-               rb_eval_string_protect(buf, &state);
-               if (state)
-               {
-                       rb_p(ruby_errinfo);
-               }
-       }
-       rb_require("irb");
-       rb_require("irb/completion");
-       rb_eval_string_protect("IRB.start", &state);
-       if (state)
-       {
-               rb_p(ruby_errinfo);
-       }
-
-       ruby_finalize();
-       return 0;
-}
-
diff --git a/src/dumm/main.c b/src/dumm/main.c
deleted file mode 100644 (file)
index 1b5bef7..0000000
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "dumm.h"
-
-#include <collections/linked_list.h>
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <sched.h>
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <vte/vte.h>
-#include <vte/reaper.h>
-
-/**
- * notebook page with vte and guest
- */
-typedef struct {
-       gint num;
-       GtkWidget *vte;
-       guest_t *guest;
-} page_t;
-
-/**
- * Main window
- */
-GtkWidget *window;
-
-/**
- * notebook with guests, vtes
- */
-GtkWidget *notebook;
-
-/**
- * dumm context
- */
-dumm_t *dumm;
-
-/**
- * pages in notebook, page_t
- */
-linked_list_t *pages;
-
-/**
- * handle guest termination, SIGCHILD
- */
-static void child_exited(VteReaper *vtereaper, gint pid, gint status)
-{
-       enumerator_t *enumerator;
-       page_t *page;
-
-       enumerator = pages->create_enumerator(pages);
-       while (enumerator->enumerate(enumerator, (void**)&page))
-       {
-               if (page->guest->get_pid(page->guest) == pid)
-               {
-                       page->guest->sigchild(page->guest);
-                       vte_terminal_feed(VTE_TERMINAL(page->vte),
-                                                         "\n\r--- guest terminated ---\n\r", -1);
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-static page_t* get_page(int num)
-{
-       enumerator_t *enumerator;
-       page_t *page, *found = NULL;
-
-       enumerator = pages->create_enumerator(pages);
-       while (enumerator->enumerate(enumerator, (void**)&page))
-       {
-               if (page->num == num)
-               {
-                       found = page;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * Guest invocation callback
- */
-static pid_t invoke(void *vte, guest_t *guest,
-                                       char *args[], int argc)
-{
-       GPid pid;
-
-       if (vte_terminal_fork_command_full(VTE_TERMINAL(vte),
-                                               VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP,
-                                               NULL, args, NULL,
-                                               G_SPAWN_CHILD_INHERITS_STDIN | G_SPAWN_SEARCH_PATH,
-                                               NULL, NULL, &pid, NULL))
-       {
-               return pid;
-       }
-       return 0;
-}
-
-void idle(void)
-{
-       gtk_main_iteration_do(FALSE);
-       sched_yield();
-}
-
-static void start_guest()
-{
-       page_t *page;
-
-       page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
-       if (page && page->guest->get_state(page->guest) == GUEST_STOPPED)
-       {
-               vte_terminal_feed(VTE_TERMINAL(page->vte),
-                                                 "--- starting guest ---\n\r", -1);
-               page->guest->start(page->guest, invoke, VTE_TERMINAL(page->vte), idle);
-       }
-}
-
-static void start_all_guests()
-{
-       enumerator_t *enumerator;
-       page_t *page;
-
-       enumerator = pages->create_enumerator(pages);
-       while (enumerator->enumerate(enumerator, (void**)&page))
-       {
-               if (page->guest->get_state(page->guest) == GUEST_STOPPED)
-               {
-                       vte_terminal_feed(VTE_TERMINAL(page->vte),
-                                                 "--- starting all guests ---\n\r", -1);
-                       page->guest->start(page->guest, invoke,
-                                                          VTE_TERMINAL(page->vte), idle);
-               }
-       }
-       enumerator->destroy(enumerator);
-}
-
-static void stop_guest()
-{
-       page_t *page;
-
-       page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
-       if (page && page->guest->get_state(page->guest) == GUEST_RUNNING)
-       {
-               page->guest->stop(page->guest, idle);
-       }
-}
-
-/**
- * quit signal handler
- */
-static void quit()
-{
-       enumerator_t *enumerator;
-       page_t *page;
-
-       dumm->load_template(dumm, NULL);
-
-       enumerator = pages->create_enumerator(pages);
-       while (enumerator->enumerate(enumerator, &page))
-       {
-               if (page->guest->get_state(page->guest) != GUEST_STOPPED)
-               {
-                       page->guest->stop(page->guest, idle);
-               }
-       }
-       enumerator->destroy(enumerator);
-       gtk_main_quit();
-}
-
-static void error_dialog(char *msg)
-{
-       GtkWidget *error;
-
-       error = gtk_message_dialog_new(GTK_WINDOW(window),
-                                                         GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
-                                                         GTK_BUTTONS_CLOSE, msg);
-       gtk_dialog_run(GTK_DIALOG(error));
-       gtk_widget_destroy(error);
-}
-
-static void create_switch()
-{
-       GtkWidget *dialog, *table, *label, *name;
-       bridge_t *bridge;
-
-       dialog = gtk_dialog_new_with_buttons("Create new switch", GTK_WINDOW(window),
-                                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                                                       GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
-
-       table = gtk_table_new(1, 2, TRUE);
-       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
-
-       label = gtk_label_new("Switch name");
-       gtk_table_attach(GTK_TABLE(table), label,  0, 1, 0, 1, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       name = gtk_entry_new();
-       gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(name);
-
-       gtk_widget_show(table);
-
-       while (TRUE)
-       {
-               switch (gtk_dialog_run(GTK_DIALOG(dialog)))
-               {
-                       case GTK_RESPONSE_ACCEPT:
-                       {
-                               if (streq(gtk_entry_get_text(GTK_ENTRY(name)), ""))
-                               {
-                                       continue;
-                               }
-                               bridge = dumm->create_bridge(dumm,
-                                                                       (char*)gtk_entry_get_text(GTK_ENTRY(name)));
-                               if (!bridge)
-                               {
-                                       error_dialog("creating bridge failed!");
-                                       continue;
-                               }
-                               break;
-                       }
-                       default:
-                               break;
-               }
-               break;
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static void delete_switch()
-{
-
-}
-
-static void connect_guest()
-{
-       page_t *page;
-       GtkWidget *dialog, *table, *label, *name, *box;
-       bridge_t *bridge;
-       iface_t *iface;
-       enumerator_t *enumerator;
-
-       page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
-       if (!page || page->guest->get_state(page->guest) != GUEST_RUNNING)
-       {
-               return;
-       }
-
-       dialog = gtk_dialog_new_with_buttons("Connect guest", GTK_WINDOW(window),
-                                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                                                       GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
-
-       table = gtk_table_new(2, 2, TRUE);
-       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
-
-       label = gtk_label_new("Interface name");
-       gtk_table_attach(GTK_TABLE(table), label,  0, 1, 0, 1, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       name = gtk_entry_new();
-       gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(name);
-
-       label = gtk_label_new("Connected switch");
-       gtk_table_attach(GTK_TABLE(table), label,  0, 1, 1, 2, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       box = gtk_combo_box_new_text();
-       gtk_table_attach(GTK_TABLE(table), box, 1, 2, 1, 2,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       enumerator = dumm->create_bridge_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, &bridge))
-       {
-               gtk_combo_box_append_text(GTK_COMBO_BOX(box), bridge->get_name(bridge));
-       }
-       enumerator->destroy(enumerator);
-       gtk_widget_show(box);
-
-       gtk_widget_show(table);
-
-       while (TRUE)
-       {
-               switch (gtk_dialog_run(GTK_DIALOG(dialog)))
-               {
-                       case GTK_RESPONSE_ACCEPT:
-                       {
-                               if (streq(gtk_entry_get_text(GTK_ENTRY(name)), ""))
-                               {
-                                       continue;
-                               }
-
-                               iface = page->guest->create_iface(page->guest,
-                                                                       (char*)gtk_entry_get_text(GTK_ENTRY(name)));
-                               if (!iface)
-                               {
-                                       error_dialog("creating interface failed!");
-                                       continue;
-                               }
-                               enumerator = dumm->create_bridge_enumerator(dumm);
-                               while (enumerator->enumerate(enumerator, &bridge))
-                               {
-                                       if (!bridge->connect_iface(bridge, iface))
-                                       {
-                                               error_dialog("connecting interface failed!");
-                                       }
-                                       break;
-                               }
-                               enumerator->destroy(enumerator);
-                               break;
-                       }
-                       default:
-                               break;
-               }
-               break;
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static void disconnect_guest()
-{
-
-}
-
-static void delete_guest()
-{
-       page_t *page;
-
-       page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
-       if (page)
-       {
-               page->guest->stop(page->guest, idle);
-               dumm->delete_guest(dumm, page->guest);
-               gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page->num);
-               pages->remove(pages, page, NULL);
-               g_free(page);
-       }
-}
-
-/**
- * create a new page for a guest
- */
-static page_t* create_page(guest_t *guest)
-{
-       GtkWidget *label;
-       page_t *page;
-
-       page = g_new(page_t, 1);
-       page->guest = guest;
-       page->vte = vte_terminal_new();
-       label = gtk_label_new(guest->get_name(guest));
-       page->num = gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
-                                                                                page->vte, label);
-       gtk_widget_show(page->vte);
-       pages->insert_last(pages, page);
-       return page;
-}
-
-/**
- * create a new guest
- */
-static void create_guest()
-{
-       guest_t *guest;
-       GtkWidget *dialog, *table, *label, *name, *kernel, *master, *args;
-
-       dialog = gtk_dialog_new_with_buttons("Create new guest", GTK_WINDOW(window),
-                                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-                                                       GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL);
-
-       table = gtk_table_new(4, 2, TRUE);
-       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
-
-       label = gtk_label_new("Guest name");
-       gtk_table_attach(GTK_TABLE(table), label,  0, 1, 0, 1, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       label = gtk_label_new("UML kernel");
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       label = gtk_label_new("Master filesystem");
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       label = gtk_label_new("Kernel arguments");
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 0, 0, 0, 0);
-       gtk_widget_show(label);
-
-       name = gtk_entry_new();
-       gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(name);
-
-       kernel = gtk_file_chooser_button_new("Select UML kernel image",
-                                                                                GTK_FILE_CHOOSER_ACTION_OPEN);
-       gtk_table_attach(GTK_TABLE(table), kernel, 1, 2, 1, 2,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(kernel);
-
-       master = gtk_file_chooser_button_new("Select master filesystem",
-                                                                                GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-       gtk_table_attach(GTK_TABLE(table), master, 1, 2, 2, 3,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(master);
-
-       args = gtk_entry_new();
-       gtk_table_attach(GTK_TABLE(table), args, 1, 2, 3, 4,
-                                        GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0);
-       gtk_widget_show(args);
-
-       gtk_widget_show(table);
-
-       while (TRUE)
-       {
-               switch (gtk_dialog_run(GTK_DIALOG(dialog)))
-               {
-                       case GTK_RESPONSE_ACCEPT:
-                       {
-                               char *sname, *skernel, *smaster, *sargs;
-                               page_t *page;
-
-                               sname = (char*)gtk_entry_get_text(GTK_ENTRY(name));
-                               skernel = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(kernel));
-                               smaster = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(master));
-                               sargs = (char*)gtk_entry_get_text(GTK_ENTRY(args));
-
-                               if (!sname[0] || !skernel || !smaster)
-                               {
-                                       continue;
-                               }
-                               guest = dumm->create_guest(dumm, sname, skernel, smaster, sargs);
-                               if (!guest)
-                               {
-                                       error_dialog("creating guest failed!");
-                                       continue;
-                               }
-                               page = create_page(guest);
-                               gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), page->num);
-                               break;
-                       }
-                       default:
-                               break;
-               }
-               break;
-       }
-       gtk_widget_destroy(dialog);
-}
-
-/**
- * main routine, parses args and reads from console
- */
-int main(int argc, char *argv[])
-{
-       GtkWidget *menubar, *menu, *menuitem, *vbox;
-       GtkWidget *dummMenu, *guestMenu, *switchMenu;
-       enumerator_t *enumerator;
-       guest_t *guest;
-
-       library_init(NULL, "dumm");
-       gtk_init(&argc, &argv);
-
-       pages = linked_list_create();
-       dumm = dumm_create(NULL);
-
-       /* setup window */
-       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-       g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(quit), NULL);
-       gtk_window_set_title(GTK_WINDOW (window), "Dumm");
-       gtk_window_set_default_size(GTK_WINDOW (window), 1000, 500);
-       g_signal_connect(G_OBJECT(vte_reaper_get()), "child-exited",
-                                        G_CALLBACK(child_exited), NULL);
-
-       /* add vbox with menubar, notebook */
-       vbox = gtk_vbox_new(FALSE, 0);
-       gtk_container_add(GTK_CONTAINER(window), vbox);
-       menubar = gtk_menu_bar_new();
-       gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
-       notebook = gtk_notebook_new();
-       g_object_set(G_OBJECT(notebook), "homogeneous", TRUE, NULL);
-       gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
-       gtk_container_add(GTK_CONTAINER(vbox), notebook);
-
-       /* Dumm menu */
-       menu = gtk_menu_new();
-       dummMenu = gtk_menu_item_new_with_mnemonic("_Dumm");
-       gtk_menu_bar_append(GTK_MENU_BAR(menubar), dummMenu);
-       gtk_widget_show(dummMenu);
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(dummMenu), menu);
-
-       /* Dumm -> exit */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(quit), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest menu */
-       menu = gtk_menu_new();
-       guestMenu = gtk_menu_item_new_with_mnemonic("_Guest");
-       gtk_menu_bar_append(GTK_MENU_BAR(menubar), guestMenu);
-       gtk_widget_show(guestMenu);
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(guestMenu), menu);
-
-       /* Guest -> new */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(create_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> delete */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(delete_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       menuitem = gtk_separator_menu_item_new();
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> start */
-       menuitem = gtk_menu_item_new_with_mnemonic("_Start");
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(start_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> startall */
-       menuitem = gtk_menu_item_new_with_mnemonic("Start _all");
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(start_all_guests), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> stop */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_STOP, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(stop_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       menuitem = gtk_separator_menu_item_new();
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> connect */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CONNECT, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(connect_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Guest -> disconnect */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DISCONNECT, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(disconnect_guest), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_set_sensitive(menuitem, FALSE);
-       gtk_widget_show(menuitem);
-
-       /* Switch menu */
-       menu = gtk_menu_new();
-       switchMenu = gtk_menu_item_new_with_mnemonic("_Switch");
-       gtk_menu_bar_append(GTK_MENU_BAR(menubar), switchMenu);
-       gtk_widget_show(switchMenu);
-       gtk_menu_item_set_submenu(GTK_MENU_ITEM(switchMenu), menu);
-
-       /* Switch -> new */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(create_switch), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_show(menuitem);
-
-       /* Switch -> delete */
-       menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL);
-       g_signal_connect(G_OBJECT(menuitem), "activate",
-                                        G_CALLBACK(delete_switch), NULL);
-       gtk_menu_append(GTK_MENU(menu), menuitem);
-       gtk_widget_set_sensitive(menuitem, FALSE);
-       gtk_widget_show(menuitem);
-
-       /* show widgets */
-       gtk_widget_show(menubar);
-       gtk_widget_show(notebook);
-       gtk_widget_show(vbox);
-       gtk_widget_show(window);
-
-       /* fill notebook with guests */
-       enumerator = dumm->create_guest_enumerator(dumm);
-       while (enumerator->enumerate(enumerator, (void**)&guest))
-       {
-               create_page(guest);
-       }
-       enumerator->destroy(enumerator);
-
-       gtk_main();
-
-       dumm->destroy(dumm);
-       pages->destroy_function(pages, g_free);
-
-       library_deinit();
-       return 0;
-}
-
diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c
deleted file mode 100644 (file)
index 3e31bc6..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- * Copyright (C) 2001-2004 Jeff Dike
- *
- * Based on the "uml_mconsole" utility from Jeff Dike.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <sys/un.h>
-
-#include <utils/debug.h>
-
-#include "mconsole.h"
-
-#define MCONSOLE_MAGIC 0xcafebabe
-#define MCONSOLE_VERSION 2
-#define MCONSOLE_MAX_DATA 512
-
-typedef struct private_mconsole_t private_mconsole_t;
-
-struct private_mconsole_t {
-       /** public interface */
-       mconsole_t public;
-       /** mconsole socket */
-       int console;
-       /** notify socket */
-       int notify;
-       /** address of uml socket */
-       struct sockaddr_un uml;
-       /** idle function */
-       void (*idle)(void);
-};
-
-/**
- * mconsole message format from "arch/um/include/mconsole.h"
- */
-typedef struct mconsole_request mconsole_request;
-/** mconsole request message */
-struct mconsole_request {
-       uint32_t magic;
-       uint32_t version;
-       uint32_t len;
-       char data[MCONSOLE_MAX_DATA];
-};
-
-
-typedef struct mconsole_reply mconsole_reply;
-/** mconsole reply message */
-struct mconsole_reply {
-       uint32_t err;
-       uint32_t more;
-       uint32_t len;
-       char data[MCONSOLE_MAX_DATA];
-};
-
-typedef struct mconsole_notify mconsole_notify;
-/** mconsole notify message */
-struct mconsole_notify {
-       uint32_t magic;
-       uint32_t version;
-       enum {
-               MCONSOLE_SOCKET,
-               MCONSOLE_PANIC,
-               MCONSOLE_HANG,
-               MCONSOLE_USER_NOTIFY,
-       } type;
-       uint32_t len;
-       char data[MCONSOLE_MAX_DATA];
-};
-
-/**
- * send a request to UML using mconsole
- */
-static int request(private_mconsole_t *this, void(*cb)(void*,char*,size_t),
-                                  void *data, char *command, ...)
-{
-       mconsole_request request;
-       mconsole_reply reply;
-       int len, flags = 0;
-       va_list args;
-
-       memset(&request, 0, sizeof(request));
-       request.magic = MCONSOLE_MAGIC;
-       request.version = MCONSOLE_VERSION;
-       va_start(args, command);
-       request.len = vsnprintf(request.data, sizeof(request.data), command, args);
-       va_end(args);
-
-       if (this->idle)
-       {
-               flags = MSG_DONTWAIT;
-       }
-       do
-       {
-               if (this->idle)
-               {
-                       this->idle();
-               }
-               len = sendto(this->console, &request, sizeof(request), flags,
-                                        (struct sockaddr*)&this->uml, sizeof(this->uml));
-       }
-       while (len < 0 && (errno == EINTR || errno == EAGAIN));
-
-       if (len < 0)
-       {
-               DBG1(DBG_LIB, "sending mconsole command to UML failed: %m");
-               return -1;
-       }
-       do
-       {
-               len = recv(this->console, &reply, sizeof(reply), flags);
-               if (len < 0 && (errno == EINTR || errno == EAGAIN))
-               {
-                       if (this->idle)
-                       {
-                               this->idle();
-                       }
-                       continue;
-               }
-               if (len < 0)
-               {
-                       DBG1(DBG_LIB, "receiving from mconsole failed: %m");
-                       return -1;
-               }
-               if (len > 0)
-               {
-                       if (cb)
-                       {
-                               cb(data, reply.data, reply.len);
-                       }
-                       else if (reply.err)
-                       {
-                               if (reply.len && *reply.data)
-                               {
-                                       DBG1(DBG_LIB, "received mconsole error %d: %.*s",
-                                                reply.err, (int)reply.len, reply.data);
-                               }
-                               break;
-                       }
-               }
-       }
-       while (reply.more);
-
-       return reply.err;
-}
-
-/**
- * ignore error message
- */
-static void ignore(void *data, char *buf, size_t len)
-{
-}
-
-METHOD(mconsole_t, add_iface, bool,
-       private_mconsole_t *this, char *guest, char *host)
-{
-       int tries = 0;
-
-       while (tries++ < 5)
-       {
-               if (request(this, ignore, NULL, "config %s=tuntap,%s", guest, host) == 0)
-               {
-                       return TRUE;
-               }
-               usleep(10000 * tries * tries);
-       }
-       return FALSE;
-}
-
-METHOD(mconsole_t, del_iface, bool,
-       private_mconsole_t *this, char *guest)
-{
-       if (request(this, NULL, NULL, "remove %s", guest) != 0)
-       {
-               return FALSE;
-       }
-       return TRUE;
-}
-
-METHOD(mconsole_t, exec, int,
-       private_mconsole_t *this, void(*cb)(void*,char*,size_t), void *data,
-       char *cmd)
-{
-       return request(this, cb, data, "%s", cmd);
-}
-
-/**
- * Poll until guest is ready
- */
-static void wait_bootup(private_mconsole_t *this)
-{
-       /* wait for init process to appear */
-       while (request(this, ignore, NULL, "exec ps -p 1 > /dev/null"))
-       {
-               if (this->idle)
-               {
-                       this->idle();
-               }
-               usleep(100000);
-       }
-}
-
-METHOD(mconsole_t, destroy, void,
-       private_mconsole_t *this)
-{
-       close(this->console);
-       close(this->notify);
-       free(this);
-}
-
-/**
- * setup the mconsole notify connection and wait for its readiness
- */
-static bool wait_for_notify(private_mconsole_t *this, char *nsock)
-{
-       struct sockaddr_un addr;
-       mconsole_notify notify;
-       int len, flags = 0;
-
-       this->notify = socket(AF_UNIX, SOCK_DGRAM, 0);
-       if (this->notify < 0)
-       {
-               DBG1(DBG_LIB, "opening mconsole notify socket failed: %m");
-               return FALSE;
-       }
-       memset(&addr, 0, sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       strncpy(addr.sun_path, nsock, sizeof(addr.sun_path));
-       if (bind(this->notify, (struct sockaddr*)&addr, sizeof(addr)) < 0)
-       {
-               DBG1(DBG_LIB, "binding mconsole notify socket to '%s' failed: %m",
-                        nsock);
-               close(this->notify);
-               return FALSE;
-       }
-       if (this->idle)
-       {
-               flags = MSG_DONTWAIT;
-       }
-       do
-       {
-               if (this->idle)
-               {
-                       this->idle();
-               }
-               len = recvfrom(this->notify, &notify, sizeof(notify), flags, NULL, 0);
-       }
-       while (len < 0 && (errno == EINTR || errno == EAGAIN));
-
-       if (len < 0 || len >= sizeof(notify))
-       {
-               DBG1(DBG_LIB, "reading from mconsole notify socket failed: %m");
-               close(this->notify);
-               unlink(nsock);
-               return FALSE;
-       }
-       if (notify.magic != MCONSOLE_MAGIC ||
-               notify.version != MCONSOLE_VERSION ||
-               notify.type != MCONSOLE_SOCKET)
-       {
-               DBG1(DBG_LIB, "received unexpected message from mconsole notify"
-                        " socket: %b", &notify, sizeof(notify));
-               close(this->notify);
-               unlink(nsock);
-               return FALSE;
-       }
-       memset(&this->uml, 0, sizeof(this->uml));
-       this->uml.sun_family = AF_UNIX;
-       strncpy(this->uml.sun_path, (char*)&notify.data, sizeof(this->uml.sun_path));
-       return TRUE;
-}
-
-/**
- * setup the mconsole console connection
- */
-static bool setup_console(private_mconsole_t *this)
-{
-       struct sockaddr_un addr;
-
-       this->console = socket(AF_UNIX, SOCK_DGRAM, 0);
-       if (this->console < 0)
-       {
-               DBG1(DBG_LIB, "opening mconsole socket failed: %m");
-               return FALSE;
-       }
-       memset(&addr, 0, sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       snprintf(&addr.sun_path[1], sizeof(addr.sun_path)-1, "%5d-%d",
-                        getpid(), this->console);
-       if (bind(this->console, (struct sockaddr*)&addr, sizeof(addr)) < 0)
-       {
-               DBG1(DBG_LIB, "binding mconsole socket to '%s' failed: %m",
-                        &addr.sun_path[1]);
-               close(this->console);
-               return FALSE;
-       }
-       return TRUE;
-}
-
-/**
- * create the mconsole instance
- */
-mconsole_t *mconsole_create(char *notify, void(*idle)(void))
-{
-       private_mconsole_t *this;
-
-       INIT(this,
-               .public = {
-                       .add_iface = _add_iface,
-                       .del_iface = _del_iface,
-                       .exec = _exec,
-                       .destroy = _destroy,
-               },
-               .idle = idle,
-       );
-
-       if (!wait_for_notify(this, notify))
-       {
-               free(this);
-               return NULL;
-       }
-
-       if (!setup_console(this))
-       {
-               close(this->notify);
-               unlink(notify);
-               free(this);
-               return NULL;
-       }
-       unlink(notify);
-
-       wait_bootup(this);
-
-       return &this->public;
-}
-
diff --git a/src/dumm/mconsole.h b/src/dumm/mconsole.h
deleted file mode 100644 (file)
index 2b8a1cd..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef MCONSOLE_H
-#define MCONSOLE_H
-
-#include <library.h>
-
-typedef struct mconsole_t mconsole_t;
-
-/**
- * UML mconsole, change running UML configuration using mconsole.
- */
-struct mconsole_t {
-
-       /**
-        * Create a guest interface and connect it to tap host interface.
-        *
-        * @param guest                 name of the interface to create in the guest
-        * @param host                  name of the tap device to connect guest to
-        * @return                              TRUE if interface created
-        */
-       bool (*add_iface)(mconsole_t *this, char *guest, char *host);
-
-       /**
-        * Delete a guest interface.
-        *
-        * @param guest                 name of the interface to delete on the guest
-        * @return                              TRUE if interface deleted
-        */
-       bool (*del_iface)(mconsole_t *this, char *guest);
-
-       /**
-        * Execute a command on the mconsole.
-        *
-        * @param cb                    callback function to invoke for each line
-        * @param data                  data to pass to callback
-        * @param cmd                   command to invoke
-        * @return                              return value of command
-        */
-       int (*exec)(mconsole_t *this, void(*cb)(void*,char*,size_t), void *data,
-                               char *cmd);
-
-       /**
-        * Destroy the mconsole instance
-        */
-       void (*destroy) (mconsole_t *this);
-};
-
-/**
- * Create a new mconsole connection to a guest.
- *
- * Waits for a notification from the guest through the notify socket and tries
- * to connect to the mconsole socket supplied in the received notification.
- *
- * @param notify                       unix notify socket path
- * @param idle                         idle function to call while waiting for responses
- * @return                                     mconsole instance, or NULL if failed
- */
-mconsole_t *mconsole_create(char *notify, void(*idle)(void));
-
-#endif /* MCONSOLE_H */
-
diff --git a/src/dumm/patches/mconsole-exec-2.6.26.patch b/src/dumm/patches/mconsole-exec-2.6.26.patch
deleted file mode 100644 (file)
index 454c4d3..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
---- a/arch/um/drivers/mconsole_kern.c  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/drivers/mconsole_kern.c  2008-08-06 09:32:52.000000000 +0200
-@@ -4,6 +4,7 @@
-  * Licensed under the GPL
-  */
-+#include "linux/kmod.h"
- #include <linux/console.h>
- #include <linux/ctype.h>
- #include <linux/interrupt.h>
-@@ -18,6 +19,8 @@
- #include <linux/utsname.h>
- #include <linux/workqueue.h>
- #include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/file.h>
- #include <asm/uaccess.h>
- #include "init.h"
-@@ -199,6 +202,65 @@
- }
- #endif
-+void mconsole_exec(struct mc_request *req)
-+{
-+      DECLARE_COMPLETION_ONSTACK(done);
-+      struct subprocess_info *sub_info;
-+      int res, len;
-+      struct file *out;
-+      char buf[MCONSOLE_MAX_DATA];
-+
-+      char *envp[] = {
-+              "HOME=/", "TERM=linux",
-+              "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
-+              NULL
-+      };
-+      char *argv[] = {
-+              "/bin/sh", "-c",
-+              req->request.data + strlen("exec "),
-+              NULL
-+      };
-+      
-+      sub_info = call_usermodehelper_setup("/bin/sh", argv, envp);
-+      if (sub_info == NULL) {
-+              mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
-+              return;
-+      }
-+      res = call_usermodehelper_stdoutpipe(sub_info, &out);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
-+              return;
-+      }
-+
-+      call_usermodehelper_setcomplete(sub_info, &done);
-+      
-+      res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT); 
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
-+              return;
-+      }
-+      
-+      for (;;) {
-+              len = out->f_op->read(out, buf, sizeof(buf), 0);
-+              if (len < 0) {
-+                      mconsole_reply(req, "reading output failed", 1, 0);
-+                      break;
-+              }
-+              if (len == 0)
-+                      break;
-+              mconsole_reply_len(req, buf, len, 0, 1);
-+      }
-+      fput(out);
-+      
-+      wait_for_completion(&done);
-+      res = call_usermodehelper_getretval(sub_info) >> 8;
-+      call_usermodehelper_freeinfo(sub_info);
-+      
-+      mconsole_reply_len(req, buf, len, res, 0);
-+}
-+
- void mconsole_proc(struct mc_request *req)
- {
-       char path[64];
-@@ -270,6 +332,7 @@
-     stop - pause the UML; it will do nothing until it receives a 'go' \n\
-     go - continue the UML after a 'stop' \n\
-     log <string> - make UML enter <string> into the kernel log\n\
-+    exec <string> - pass <string> to /bin/sh -c synchronously\n\
-     proc <file> - returns the contents of the UML's /proc/<file>\n\
-     stack <pid> - returns the stack of the specified pid\n\
- "
---- a/arch/um/drivers/mconsole_user.c  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/drivers/mconsole_user.c  2008-07-15 15:41:54.000000000 +0200
-@@ -32,6 +32,7 @@
-       { "stop", mconsole_stop, MCONSOLE_PROC },
-       { "go", mconsole_go, MCONSOLE_INTR },
-       { "log", mconsole_log, MCONSOLE_INTR },
-+      { "exec", mconsole_exec, MCONSOLE_PROC },
-       { "proc", mconsole_proc, MCONSOLE_PROC },
-       { "stack", mconsole_stack, MCONSOLE_INTR },
- };
---- a/arch/um/include/mconsole.h       2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/include/mconsole.h       2008-07-15 15:41:54.000000000 +0200
-@@ -85,6 +85,7 @@
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
- extern void mconsole_log(struct mc_request *req);
-+extern void mconsole_exec(struct mc_request *req);
- extern void mconsole_proc(struct mc_request *req);
- extern void mconsole_stack(struct mc_request *req);
---- a/kernel/kmod.c    2008-07-13 23:51:29.000000000 +0200
-+++ b/kernel/kmod.c    2008-07-31 14:46:31.000000000 +0200
-@@ -118,6 +118,7 @@
- struct subprocess_info {
-       struct work_struct work;
-       struct completion *complete;
-+      struct completion *executed;
-       char *path;
-       char **argv;
-       char **envp;
-@@ -125,6 +126,7 @@
-       enum umh_wait wait;
-       int retval;
-       struct file *stdin;
-+      struct file *stdout;
-       void (*cleanup)(char **argv, char **envp);
- };
-@@ -160,8 +162,26 @@
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
--
--              /* and disallow core files too */
-+      }
-+      if (sub_info->stdout) {
-+              struct files_struct *f = current->files;
-+              struct fdtable *fdt;
-+              
-+              sys_close(1);
-+              sys_close(2);
-+              get_file(sub_info->stdout);
-+              fd_install(1, sub_info->stdout);
-+              fd_install(2, sub_info->stdout);
-+              spin_lock(&f->file_lock);
-+              fdt = files_fdtable(f);
-+              FD_SET(1, fdt->open_fds);
-+              FD_CLR(1, fdt->close_on_exec);
-+              FD_SET(2, fdt->open_fds);
-+              FD_CLR(2, fdt->close_on_exec);
-+              spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdin || sub_info->stdout) {
-+              /* disallow core files */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-@@ -243,7 +263,7 @@
-       /* CLONE_VFORK: wait until the usermode helper has execve'd
-        * successfully We need the data structures to stay around
-        * until that is done.  */
--      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
-+      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
-               pid = kernel_thread(wait_for_helper, sub_info,
-                                   CLONE_FS | CLONE_FILES | SIGCHLD);
-       else
-@@ -254,6 +274,16 @@
-       case UMH_NO_WAIT:
-               break;
-+      case UMH_WAIT_EXT:
-+              if (pid > 0) {
-+                      complete(sub_info->executed);
-+                      break;
-+              }
-+              sub_info->retval = pid;
-+              complete(sub_info->executed);
-+              complete(sub_info->complete);
-+              break;
-+
-       case UMH_WAIT_PROC:
-               if (pid > 0)
-                       break;
-@@ -404,6 +434,19 @@
- }
- EXPORT_SYMBOL(call_usermodehelper_setcleanup);
-+void call_usermodehelper_setcomplete(struct subprocess_info *info,
-+                                  struct completion* complete)
-+{
-+      info->complete = complete;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_setcomplete);
-+
-+int call_usermodehelper_getretval(struct subprocess_info *info)
-+{
-+      return info->retval;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_getretval);
-+
- /**
-  * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
-  * @sub_info: a subprocess_info returned by call_usermodehelper_setup
-@@ -433,6 +476,29 @@
- }
- EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                struct file **filp)
-+{
-+      struct file *f;
-+
-+      f = create_write_pipe();
-+      if (IS_ERR(f))
-+              return PTR_ERR(f);
-+      sub_info->stdout = f;
-+
-+      f = create_read_pipe(f);
-+      if (IS_ERR(f)) {
-+              free_write_pipe(sub_info->stdout);
-+              sub_info->stdout = NULL;
-+              return PTR_ERR(f);
-+      }
-+      *filp = f;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
-+
-+
- /**
-  * call_usermodehelper_exec - start a usermode application
-  * @sub_info: information about the subprocessa
-@@ -460,15 +526,22 @@
-               goto out;
-       }
--      sub_info->complete = &done;
-+      if (wait == UMH_WAIT_EXT)
-+              sub_info->executed = &done;
-+      else
-+              sub_info->complete = &done;
-+
-       sub_info->wait = wait;
-       queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
-               goto unlock;
-+
-       wait_for_completion(&done);
--      retval = sub_info->retval;
-+      retval = sub_info->retval;
-+      if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
-+              goto unlock;
- out:
-       call_usermodehelper_freeinfo(sub_info);
- unlock:
---- a/include/linux/kmod.h     2008-07-13 23:51:29.000000000 +0200
-+++ b/include/linux/kmod.h     2008-07-31 14:43:33.000000000 +0200
-@@ -38,6 +38,7 @@
- struct key;
- struct file;
- struct subprocess_info;
-+struct completion;
- /* Allocate a subprocess_info structure */
- struct subprocess_info *call_usermodehelper_setup(char *path,
-@@ -48,13 +49,20 @@
-                                struct key *session_keyring);
- int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                 struct file **filp);
-+void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
-+                                   struct completion *complete);
- void call_usermodehelper_setcleanup(struct subprocess_info *info,
-                                   void (*cleanup)(char **argv, char **envp));
-+int call_usermodehelper_getretval(struct subprocess_info *sub_info);
- enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-+      UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal 
-+                                 when the process is complete */
- };
- /* Actually execute the sub-process */
---- a/arch/um/Makefile 2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile 2008-07-15 16:27:02.000000000 +0200
-@@ -77,6 +77,7 @@
- KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-                        -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
- KBUILD_CFLAGS += $(KERNEL_DEFINES)
-+KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
- PHONY += linux
---- a/arch/um/Makefile-i386    2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile-i386    2008-07-15 16:23:57.000000000 +0200
-@@ -32,11 +32,4 @@
- # an unresolved reference.
- cflags-y += -ffreestanding
--# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
--# a lot more stack due to the lack of sharing of stacklots.  Also, gcc
--# 4.3.0 needs -funit-at-a-time for extern inline functions.
--KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
--                      echo $(call cc-option,-fno-unit-at-a-time); \
--                      else echo $(call cc-option,-funit-at-a-time); fi ;)
--
- KBUILD_CFLAGS += $(cflags-y)
---- a/arch/um/Makefile-x86_64  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile-x86_64  2008-07-15 16:24:20.000000000 +0200
-@@ -21,6 +21,3 @@
- LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
- LINK-y += -m64
--
--# Do unit-at-a-time unconditionally on x86_64, following the host
--KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
---- a/arch/um/drivers/line.c   2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/drivers/line.c   2008-07-28 15:13:19.000000000 +0200
-@@ -876,6 +876,6 @@
-               return base;
-       }
--      snprintf(title, len, "%s (%s)", base, umid);
-+      snprintf(title, len, "%s (%s)", umid, base);
-       return title;
- }
diff --git a/src/dumm/patches/mconsole-exec-2.6.27.patch b/src/dumm/patches/mconsole-exec-2.6.27.patch
deleted file mode 100644 (file)
index b0405ee..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
---- a/arch/um/drivers/mconsole_kern.c  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/drivers/mconsole_kern.c  2008-10-07 11:03:31.000000000 +0200
-@@ -4,6 +4,7 @@
-  * Licensed under the GPL
-  */
-+#include "linux/kmod.h"
- #include <linux/console.h>
- #include <linux/ctype.h>
- #include <linux/interrupt.h>
-@@ -18,6 +19,8 @@
- #include <linux/utsname.h>
- #include <linux/workqueue.h>
- #include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/file.h>
- #include <asm/uaccess.h>
- #include "init.h"
-@@ -199,6 +202,65 @@
- }
- #endif
-+void mconsole_exec(struct mc_request *req)
-+{
-+      DECLARE_COMPLETION_ONSTACK(done);
-+      struct subprocess_info *sub_info;
-+      int res, len;
-+      struct file *out;
-+      char buf[MCONSOLE_MAX_DATA];
-+
-+      char *envp[] = {
-+              "HOME=/", "TERM=linux",
-+              "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
-+              NULL
-+      };
-+      char *argv[] = {
-+              "/bin/sh", "-c",
-+              req->request.data + strlen("exec "),
-+              NULL
-+      };
-+      
-+      sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC);
-+      if (sub_info == NULL) {
-+              mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
-+              return;
-+      }
-+      res = call_usermodehelper_stdoutpipe(sub_info, &out);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
-+              return;
-+      }
-+
-+      call_usermodehelper_setcomplete(sub_info, &done);
-+      
-+      res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT); 
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
-+              return;
-+      }
-+      
-+      for (;;) {
-+              len = out->f_op->read(out, buf, sizeof(buf), 0);
-+              if (len < 0) {
-+                      mconsole_reply(req, "reading output failed", 1, 0);
-+                      break;
-+              }
-+              if (len == 0)
-+                      break;
-+              mconsole_reply_len(req, buf, len, 0, 1);
-+      }
-+      fput(out);
-+      
-+      wait_for_completion(&done);
-+      res = call_usermodehelper_getretval(sub_info) >> 8;
-+      call_usermodehelper_freeinfo(sub_info);
-+      
-+      mconsole_reply_len(req, buf, len, res, 0);
-+}
-+
- void mconsole_proc(struct mc_request *req)
- {
-       char path[64];
-@@ -270,6 +332,7 @@
-     stop - pause the UML; it will do nothing until it receives a 'go' \n\
-     go - continue the UML after a 'stop' \n\
-     log <string> - make UML enter <string> into the kernel log\n\
-+    exec <string> - pass <string> to /bin/sh -c synchronously\n\
-     proc <file> - returns the contents of the UML's /proc/<file>\n\
-     stack <pid> - returns the stack of the specified pid\n\
- "
---- a/arch/um/drivers/mconsole_user.c  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/drivers/mconsole_user.c  2008-10-07 11:00:55.000000000 +0200
-@@ -32,6 +32,7 @@
-       { "stop", mconsole_stop, MCONSOLE_PROC },
-       { "go", mconsole_go, MCONSOLE_INTR },
-       { "log", mconsole_log, MCONSOLE_INTR },
-+      { "exec", mconsole_exec, MCONSOLE_PROC },
-       { "proc", mconsole_proc, MCONSOLE_PROC },
-       { "stack", mconsole_stack, MCONSOLE_INTR },
- };
---- a/arch/um/include/mconsole.h       2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/include/mconsole.h       2008-10-07 11:00:55.000000000 +0200
-@@ -85,6 +85,7 @@
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
- extern void mconsole_log(struct mc_request *req);
-+extern void mconsole_exec(struct mc_request *req);
- extern void mconsole_proc(struct mc_request *req);
- extern void mconsole_stack(struct mc_request *req);
---- a/kernel/kmod.c    2008-10-07 10:31:12.000000000 +0200
-+++ b/kernel/kmod.c    2008-10-07 11:07:37.000000000 +0200
-@@ -118,6 +118,7 @@
- struct subprocess_info {
-       struct work_struct work;
-       struct completion *complete;
-+      struct completion *executed;
-       char *path;
-       char **argv;
-       char **envp;
-@@ -125,6 +126,7 @@
-       enum umh_wait wait;
-       int retval;
-       struct file *stdin;
-+      struct file *stdout;
-       void (*cleanup)(char **argv, char **envp);
- };
-@@ -160,8 +162,26 @@
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
--
--              /* and disallow core files too */
-+      }
-+      if (sub_info->stdout) {
-+              struct files_struct *f = current->files;
-+              struct fdtable *fdt;
-+              
-+              sys_close(1);
-+              sys_close(2);
-+              get_file(sub_info->stdout);
-+              fd_install(1, sub_info->stdout);
-+              fd_install(2, sub_info->stdout);
-+              spin_lock(&f->file_lock);
-+              fdt = files_fdtable(f);
-+              FD_SET(1, fdt->open_fds);
-+              FD_CLR(1, fdt->close_on_exec);
-+              FD_SET(2, fdt->open_fds);
-+              FD_CLR(2, fdt->close_on_exec);
-+              spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdin || sub_info->stdout) {
-+              /* disallow core files */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-@@ -243,7 +263,7 @@
-       /* CLONE_VFORK: wait until the usermode helper has execve'd
-        * successfully We need the data structures to stay around
-        * until that is done.  */
--      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
-+      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
-               pid = kernel_thread(wait_for_helper, sub_info,
-                                   CLONE_FS | CLONE_FILES | SIGCHLD);
-       else
-@@ -254,6 +274,16 @@
-       case UMH_NO_WAIT:
-               break;
-+      case UMH_WAIT_EXT:
-+              if (pid > 0) {
-+                      complete(sub_info->executed);
-+                      break;
-+              }
-+              sub_info->retval = pid;
-+              complete(sub_info->executed);
-+              complete(sub_info->complete);
-+              break;
-+
-       case UMH_WAIT_PROC:
-               if (pid > 0)
-                       break;
-@@ -405,6 +435,19 @@
- }
- EXPORT_SYMBOL(call_usermodehelper_setcleanup);
-+void call_usermodehelper_setcomplete(struct subprocess_info *info,
-+                                  struct completion* complete)
-+{
-+      info->complete = complete;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_setcomplete);
-+
-+int call_usermodehelper_getretval(struct subprocess_info *info)
-+{
-+      return info->retval;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_getretval);
-+
- /**
-  * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
-  * @sub_info: a subprocess_info returned by call_usermodehelper_setup
-@@ -434,6 +477,29 @@
- }
- EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                struct file **filp)
-+{
-+      struct file *f;
-+
-+      f = create_write_pipe(0);
-+      if (IS_ERR(f))
-+              return PTR_ERR(f);
-+      sub_info->stdout = f;
-+
-+      f = create_read_pipe(f, 0);
-+      if (IS_ERR(f)) {
-+              free_write_pipe(sub_info->stdout);
-+              sub_info->stdout = NULL;
-+              return PTR_ERR(f);
-+      }
-+      *filp = f;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
-+
-+
- /**
-  * call_usermodehelper_exec - start a usermode application
-  * @sub_info: information about the subprocessa
-@@ -461,15 +527,22 @@
-               goto out;
-       }
--      sub_info->complete = &done;
-+      if (wait == UMH_WAIT_EXT)
-+              sub_info->executed = &done;
-+      else
-+              sub_info->complete = &done;
-+
-       sub_info->wait = wait;
-       queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
-               goto unlock;
-+
-       wait_for_completion(&done);
--      retval = sub_info->retval;
-+      retval = sub_info->retval;
-+      if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
-+              goto unlock;
- out:
-       call_usermodehelper_freeinfo(sub_info);
- unlock:
---- a/include/linux/kmod.h     2008-10-07 10:31:11.000000000 +0200
-+++ b/include/linux/kmod.h     2008-10-07 11:00:55.000000000 +0200
-@@ -40,6 +40,7 @@
- struct key;
- struct file;
- struct subprocess_info;
-+struct completion;
- /* Allocate a subprocess_info structure */
- struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
-@@ -50,13 +51,20 @@
-                                struct key *session_keyring);
- int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                 struct file **filp);
-+void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
-+                                   struct completion *complete);
- void call_usermodehelper_setcleanup(struct subprocess_info *info,
-                                   void (*cleanup)(char **argv, char **envp));
-+int call_usermodehelper_getretval(struct subprocess_info *sub_info);
- enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-+      UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal 
-+                                 when the process is complete */
- };
- /* Actually execute the sub-process */
---- a/arch/um/Makefile 2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile 2008-10-07 11:00:55.000000000 +0200
-@@ -77,6 +77,7 @@
- KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-                        -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
- KBUILD_CFLAGS += $(KERNEL_DEFINES)
-+KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
- PHONY += linux
---- a/arch/um/Makefile-i386    2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile-i386    2008-10-07 11:00:55.000000000 +0200
-@@ -32,11 +32,4 @@
- # an unresolved reference.
- cflags-y += -ffreestanding
--# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
--# a lot more stack due to the lack of sharing of stacklots.  Also, gcc
--# 4.3.0 needs -funit-at-a-time for extern inline functions.
--KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
--                      echo $(call cc-option,-fno-unit-at-a-time); \
--                      else echo $(call cc-option,-funit-at-a-time); fi ;)
--
- KBUILD_CFLAGS += $(cflags-y)
---- a/arch/um/Makefile-x86_64  2008-07-13 23:51:29.000000000 +0200
-+++ b/arch/um/Makefile-x86_64  2008-10-07 11:00:55.000000000 +0200
-@@ -21,6 +21,3 @@
- LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
- LINK-y += -m64
--
--# Do unit-at-a-time unconditionally on x86_64, following the host
--KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
---- a/arch/um/drivers/line.c   2008-10-07 10:31:00.000000000 +0200
-+++ b/arch/um/drivers/line.c   2008-10-07 11:00:55.000000000 +0200
-@@ -864,6 +864,6 @@
-               return base;
-       }
--      snprintf(title, len, "%s (%s)", base, umid);
-+      snprintf(title, len, "%s (%s)", umid, base);
-       return title;
- }
diff --git a/src/dumm/patches/mconsole-exec-2.6.28.patch b/src/dumm/patches/mconsole-exec-2.6.28.patch
deleted file mode 100644 (file)
index 2f400b3..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
---- a/arch/um/drivers/line.c
-+++ b/arch/um/drivers/line.c
-@@ -866,6 +866,6 @@ char *add_xterm_umid(char *base)
-               return base;
-       }
--      snprintf(title, len, "%s (%s)", base, umid);
-+      snprintf(title, len, "%s (%s)", umid, base);
-       return title;
- }
---- a/arch/um/drivers/mconsole_kern.c
-+++ b/arch/um/drivers/mconsole_kern.c
-@@ -4,6 +4,7 @@
-  * Licensed under the GPL
-  */
-+#include "linux/kmod.h"
- #include <linux/console.h>
- #include <linux/ctype.h>
- #include <linux/interrupt.h>
-@@ -20,6 +21,8 @@
- #include <linux/un.h>
- #include <linux/workqueue.h>
- #include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/file.h>
- #include <asm/uaccess.h>
- #include "init.h"
-@@ -201,6 +204,65 @@ void mconsole_proc(struct mc_request *req)
- }
- #endif
-+void mconsole_exec(struct mc_request *req)
-+{
-+      DECLARE_COMPLETION_ONSTACK(done);
-+      struct subprocess_info *sub_info;
-+      int res, len;
-+      struct file *out;
-+      char buf[MCONSOLE_MAX_DATA];
-+
-+      char *envp[] = {
-+              "HOME=/", "TERM=linux",
-+              "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
-+              NULL
-+      };
-+      char *argv[] = {
-+              "/bin/sh", "-c",
-+              req->request.data + strlen("exec "),
-+              NULL
-+      };
-+      
-+      sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC);
-+      if (sub_info == NULL) {
-+              mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
-+              return;
-+      }
-+      res = call_usermodehelper_stdoutpipe(sub_info, &out);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
-+              return;
-+      }
-+
-+      call_usermodehelper_setcomplete(sub_info, &done);
-+      
-+      res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT); 
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
-+              return;
-+      }
-+      
-+      for (;;) {
-+              len = out->f_op->read(out, buf, sizeof(buf), 0);
-+              if (len < 0) {
-+                      mconsole_reply(req, "reading output failed", 1, 0);
-+                      break;
-+              }
-+              if (len == 0)
-+                      break;
-+              mconsole_reply_len(req, buf, len, 0, 1);
-+      }
-+      fput(out);
-+      
-+      wait_for_completion(&done);
-+      res = call_usermodehelper_getretval(sub_info) >> 8;
-+      call_usermodehelper_freeinfo(sub_info);
-+      
-+      mconsole_reply_len(req, buf, len, res, 0);
-+}
-+
- void mconsole_proc(struct mc_request *req)
- {
-       char path[64];
-@@ -272,6 +334,7 @@ void mconsole_proc(struct mc_request *req)
-     stop - pause the UML; it will do nothing until it receives a 'go' \n\
-     go - continue the UML after a 'stop' \n\
-     log <string> - make UML enter <string> into the kernel log\n\
-+    exec <string> - pass <string> to /bin/sh -c synchronously\n\
-     proc <file> - returns the contents of the UML's /proc/<file>\n\
-     stack <pid> - returns the stack of the specified pid\n\
- "
---- a/arch/um/drivers/mconsole_user.c
-+++ b/arch/um/drivers/mconsole_user.c
-@@ -32,6 +32,7 @@ static struct mconsole_command commands[] = {
-       { "stop", mconsole_stop, MCONSOLE_PROC },
-       { "go", mconsole_go, MCONSOLE_INTR },
-       { "log", mconsole_log, MCONSOLE_INTR },
-+      { "exec", mconsole_exec, MCONSOLE_PROC },
-       { "proc", mconsole_proc, MCONSOLE_PROC },
-       { "stack", mconsole_stack, MCONSOLE_INTR },
- };
---- a/arch/um/include/shared/mconsole.h
-+++ b/arch/um/include/shared/mconsole.h
-@@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_request *req);
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
- extern void mconsole_log(struct mc_request *req);
-+extern void mconsole_exec(struct mc_request *req);
- extern void mconsole_proc(struct mc_request *req);
- extern void mconsole_stack(struct mc_request *req);
---- a/include/linux/kmod.h
-+++ b/include/linux/kmod.h
-@@ -40,6 +40,7 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; }
- struct key;
- struct file;
- struct subprocess_info;
-+struct completion;
- /* Allocate a subprocess_info structure */
- struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
-@@ -50,13 +51,20 @@ void call_usermodehelper_setkeys(struct subprocess_info *info,
-                                struct key *session_keyring);
- int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                 struct file **filp);
-+void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
-+                                   struct completion *complete);
- void call_usermodehelper_setcleanup(struct subprocess_info *info,
-                                   void (*cleanup)(char **argv, char **envp));
-+int call_usermodehelper_getretval(struct subprocess_info *sub_info);
- enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-+      UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal 
-+                                 when the process is complete */
- };
- /* Actually execute the sub-process */
---- a/kernel/kmod.c
-+++ b/kernel/kmod.c
-@@ -118,6 +118,7 @@ EXPORT_SYMBOL(request_module);
- struct subprocess_info {
-       struct work_struct work;
-       struct completion *complete;
-+      struct completion *executed;
-       char *path;
-       char **argv;
-       char **envp;
-@@ -125,6 +126,7 @@ struct subprocess_info {
-       enum umh_wait wait;
-       int retval;
-       struct file *stdin;
-+      struct file *stdout;
-       void (*cleanup)(char **argv, char **envp);
- };
-@@ -160,8 +162,26 @@ static int ____call_usermodehelper(void *data)
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
--
--              /* and disallow core files too */
-+      }
-+      if (sub_info->stdout) {
-+              struct files_struct *f = current->files;
-+              struct fdtable *fdt;
-+              
-+              sys_close(1);
-+              sys_close(2);
-+              get_file(sub_info->stdout);
-+              fd_install(1, sub_info->stdout);
-+              fd_install(2, sub_info->stdout);
-+              spin_lock(&f->file_lock);
-+              fdt = files_fdtable(f);
-+              FD_SET(1, fdt->open_fds);
-+              FD_CLR(1, fdt->close_on_exec);
-+              FD_SET(2, fdt->open_fds);
-+              FD_CLR(2, fdt->close_on_exec);
-+              spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdin || sub_info->stdout) {
-+              /* disallow core files */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-@@ -243,7 +263,7 @@ static void __call_usermodehelper(struct work_struct *work)
-       /* CLONE_VFORK: wait until the usermode helper has execve'd
-        * successfully We need the data structures to stay around
-        * until that is done.  */
--      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
-+      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
-               pid = kernel_thread(wait_for_helper, sub_info,
-                                   CLONE_FS | CLONE_FILES | SIGCHLD);
-       else
-@@ -254,6 +274,16 @@ static void __call_usermodehelper(struct work_struct *work)
-       case UMH_NO_WAIT:
-               break;
-+      case UMH_WAIT_EXT:
-+              if (pid > 0) {
-+                      complete(sub_info->executed);
-+                      break;
-+              }
-+              sub_info->retval = pid;
-+              complete(sub_info->executed);
-+              complete(sub_info->complete);
-+              break;
-+
-       case UMH_WAIT_PROC:
-               if (pid > 0)
-                       break;
-@@ -397,6 +427,19 @@ void call_usermodehelper_setcleanup(struct subprocess_info *info,
- }
- EXPORT_SYMBOL(call_usermodehelper_setcleanup);
-+void call_usermodehelper_setcomplete(struct subprocess_info *info,
-+                                  struct completion* complete)
-+{
-+      info->complete = complete;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_setcomplete);
-+
-+int call_usermodehelper_getretval(struct subprocess_info *info)
-+{
-+      return info->retval;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_getretval);
-+
- /**
-  * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
-  * @sub_info: a subprocess_info returned by call_usermodehelper_setup
-@@ -426,6 +469,29 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
- }
- EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                struct file **filp)
-+{
-+      struct file *f;
-+
-+      f = create_write_pipe(0);
-+      if (IS_ERR(f))
-+              return PTR_ERR(f);
-+      sub_info->stdout = f;
-+
-+      f = create_read_pipe(f, 0);
-+      if (IS_ERR(f)) {
-+              free_write_pipe(sub_info->stdout);
-+              sub_info->stdout = NULL;
-+              return PTR_ERR(f);
-+      }
-+      *filp = f;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
-+
-+
- /**
-  * call_usermodehelper_exec - start a usermode application
-  * @sub_info: information about the subprocessa
-@@ -453,15 +519,22 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
-               goto out;
-       }
--      sub_info->complete = &done;
-+      if (wait == UMH_WAIT_EXT)
-+              sub_info->executed = &done;
-+      else
-+              sub_info->complete = &done;
-+
-       sub_info->wait = wait;
-       queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
-               goto unlock;
-+
-       wait_for_completion(&done);
--      retval = sub_info->retval;
-+      retval = sub_info->retval;
-+      if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
-+              goto unlock;
- out:
-       call_usermodehelper_freeinfo(sub_info);
- unlock:
diff --git a/src/dumm/patches/mconsole-exec-2.6.29.patch b/src/dumm/patches/mconsole-exec-2.6.29.patch
deleted file mode 100644 (file)
index a28d3fe..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-index 869e1a3..978e430 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -32,6 +32,7 @@
- tags
- TAGS
- vmlinux
-+linux
- System.map
- Module.markers
- Module.symvers
-diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
-index 14a102e..0acfaeb 100644
---- a/arch/um/drivers/line.c
-+++ b/arch/um/drivers/line.c
-@@ -866,6 +866,6 @@ char *add_xterm_umid(char *base)
-               return base;
-       }
--      snprintf(title, len, "%s (%s)", base, umid);
-+      snprintf(title, len, "%s (%s)", umid, base);
-       return title;
- }
-diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
-index e14629c..c488930 100644
---- a/arch/um/drivers/mconsole_kern.c
-+++ b/arch/um/drivers/mconsole_kern.c
-@@ -4,6 +4,7 @@
-  * Licensed under the GPL
-  */
-+#include "linux/kmod.h"
- #include <linux/console.h>
- #include <linux/ctype.h>
- #include <linux/interrupt.h>
-@@ -20,6 +21,8 @@
- #include <linux/un.h>
- #include <linux/workqueue.h>
- #include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/file.h>
- #include <asm/uaccess.h>
- #include "init.h"
-@@ -202,6 +205,65 @@ void mconsole_proc(struct mc_request *req)
- }
- #endif
-+void mconsole_exec(struct mc_request *req)
-+{
-+      DECLARE_COMPLETION_ONSTACK(done);
-+      struct subprocess_info *sub_info;
-+      int res, len;
-+      struct file *out;
-+      char buf[MCONSOLE_MAX_DATA];
-+
-+      char *envp[] = {
-+              "HOME=/", "TERM=linux",
-+              "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
-+              NULL
-+      };
-+      char *argv[] = {
-+              "/bin/sh", "-c",
-+              req->request.data + strlen("exec "),
-+              NULL
-+      };
-+
-+      sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC);
-+      if (sub_info == NULL) {
-+              mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
-+              return;
-+      }
-+      res = call_usermodehelper_stdoutpipe(sub_info, &out);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
-+              return;
-+      }
-+
-+      call_usermodehelper_setcomplete(sub_info, &done);
-+
-+      res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
-+              return;
-+      }
-+
-+      for (;;) {
-+              len = out->f_op->read(out, buf, sizeof(buf), &out->f_pos);
-+              if (len < 0) {
-+                      mconsole_reply(req, "reading output failed", 1, 0);
-+                      break;
-+              }
-+              if (len == 0)
-+                      break;
-+              mconsole_reply_len(req, buf, len, 0, 1);
-+      }
-+      fput(out);
-+
-+      wait_for_completion(&done);
-+      res = call_usermodehelper_getretval(sub_info) >> 8;
-+      call_usermodehelper_freeinfo(sub_info);
-+
-+      mconsole_reply_len(req, buf, len, res, 0);
-+}
-+
- void mconsole_proc(struct mc_request *req)
- {
-       char path[64];
-@@ -273,6 +335,7 @@ void mconsole_proc(struct mc_request *req)
-     stop - pause the UML; it will do nothing until it receives a 'go' \n\
-     go - continue the UML after a 'stop' \n\
-     log <string> - make UML enter <string> into the kernel log\n\
-+    exec <string> - pass <string> to /bin/sh -c synchronously\n\
-     proc <file> - returns the contents of the UML's /proc/<file>\n\
-     stack <pid> - returns the stack of the specified pid\n\
- "
-diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
-index f8cf4c8..019d89f 100644
---- a/arch/um/drivers/mconsole_user.c
-+++ b/arch/um/drivers/mconsole_user.c
-@@ -32,6 +32,7 @@ static struct mconsole_command commands[] = {
-       { "stop", mconsole_stop, MCONSOLE_PROC },
-       { "go", mconsole_go, MCONSOLE_INTR },
-       { "log", mconsole_log, MCONSOLE_INTR },
-+      { "exec", mconsole_exec, MCONSOLE_PROC },
-       { "proc", mconsole_proc, MCONSOLE_PROC },
-       { "stack", mconsole_stack, MCONSOLE_INTR },
- };
-diff --git a/arch/um/include/.gitignore b/arch/um/include/.gitignore
-new file mode 100644
-index 0000000..4c14eba
---- /dev/null
-+++ b/arch/um/include/.gitignore
-@@ -0,0 +1,2 @@
-+shared/kern_constants.h
-+shared/user_constants.h
-diff --git a/arch/um/include/shared/mconsole.h b/arch/um/include/shared/mconsole.h
-index c139ae1..dfb83b1 100644
---- a/arch/um/include/shared/mconsole.h
-+++ b/arch/um/include/shared/mconsole.h
-@@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_request *req);
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
- extern void mconsole_log(struct mc_request *req);
-+extern void mconsole_exec(struct mc_request *req);
- extern void mconsole_proc(struct mc_request *req);
- extern void mconsole_stack(struct mc_request *req);
-diff --git a/arch/um/kernel/.gitignore b/arch/um/kernel/.gitignore
-new file mode 100644
-index 0000000..803397e
---- /dev/null
-+++ b/arch/um/kernel/.gitignore
-@@ -0,0 +1,3 @@
-+config.c
-+config.tmp
-+vmlinux.lds
-diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
-index b5afcfd..b598128 100644
---- a/arch/um/os-Linux/file.c
-+++ b/arch/um/os-Linux/file.c
-@@ -521,6 +521,8 @@ int os_create_unix_socket(const char *file, int len, int close_on_exec)
-       addr.sun_family = AF_UNIX;
-+      if (len > sizeof(addr.sun_path))
-+              len = sizeof(addr.sun_path);
-       snprintf(addr.sun_path, len, "%s", file);
-       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-diff --git a/include/linux/kmod.h b/include/linux/kmod.h
-index 92213a9..db07018 100644
---- a/include/linux/kmod.h
-+++ b/include/linux/kmod.h
-@@ -40,6 +40,7 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; }
- struct key;
- struct file;
- struct subprocess_info;
-+struct completion;
- /* Allocate a subprocess_info structure */
- struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
-@@ -50,13 +51,20 @@ void call_usermodehelper_setkeys(struct subprocess_info *info,
-                                struct key *session_keyring);
- int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                 struct file **filp);
-+void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
-+                                   struct completion *complete);
- void call_usermodehelper_setcleanup(struct subprocess_info *info,
-                                   void (*cleanup)(char **argv, char **envp));
-+int call_usermodehelper_getretval(struct subprocess_info *sub_info);
- enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-+      UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal
-+                                 when the process is complete */
- };
- /* Actually execute the sub-process */
-diff --git a/kernel/kmod.c b/kernel/kmod.c
-index a27a5f6..61479bf 100644
---- a/kernel/kmod.c
-+++ b/kernel/kmod.c
-@@ -119,12 +119,14 @@ struct subprocess_info {
-       struct work_struct work;
-       struct completion *complete;
-       struct cred *cred;
-+      struct completion *executed;
-       char *path;
-       char **argv;
-       char **envp;
-       enum umh_wait wait;
-       int retval;
-       struct file *stdin;
-+      struct file *stdout;
-       void (*cleanup)(char **argv, char **envp);
- };
-@@ -161,8 +163,26 @@ static int ____call_usermodehelper(void *data)
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdout) {
-+              struct files_struct *f = current->files;
-+              struct fdtable *fdt;
--              /* and disallow core files too */
-+              sys_close(1);
-+              sys_close(2);
-+              get_file(sub_info->stdout);
-+              fd_install(1, sub_info->stdout);
-+              fd_install(2, sub_info->stdout);
-+              spin_lock(&f->file_lock);
-+              fdt = files_fdtable(f);
-+              FD_SET(1, fdt->open_fds);
-+              FD_CLR(1, fdt->close_on_exec);
-+              FD_SET(2, fdt->open_fds);
-+              FD_CLR(2, fdt->close_on_exec);
-+              spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdin || sub_info->stdout) {
-+              /* disallow core files */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-@@ -248,7 +268,7 @@ static void __call_usermodehelper(struct work_struct *work)
-       /* CLONE_VFORK: wait until the usermode helper has execve'd
-        * successfully We need the data structures to stay around
-        * until that is done.  */
--      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
-+      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
-               pid = kernel_thread(wait_for_helper, sub_info,
-                                   CLONE_FS | CLONE_FILES | SIGCHLD);
-       else
-@@ -259,6 +279,16 @@ static void __call_usermodehelper(struct work_struct *work)
-       case UMH_NO_WAIT:
-               break;
-+      case UMH_WAIT_EXT:
-+              if (pid > 0) {
-+                      complete(sub_info->executed);
-+                      break;
-+              }
-+              sub_info->retval = pid;
-+              complete(sub_info->executed);
-+              complete(sub_info->complete);
-+              break;
-+
-       case UMH_WAIT_PROC:
-               if (pid > 0)
-                       break;
-@@ -411,6 +441,19 @@ void call_usermodehelper_setcleanup(struct subprocess_info *info,
- }
- EXPORT_SYMBOL(call_usermodehelper_setcleanup);
-+void call_usermodehelper_setcomplete(struct subprocess_info *info,
-+                                  struct completion* complete)
-+{
-+      info->complete = complete;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_setcomplete);
-+
-+int call_usermodehelper_getretval(struct subprocess_info *info)
-+{
-+      return info->retval;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_getretval);
-+
- /**
-  * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
-  * @sub_info: a subprocess_info returned by call_usermodehelper_setup
-@@ -440,6 +483,29 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
- }
- EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                struct file **filp)
-+{
-+      struct file *f;
-+
-+      f = create_write_pipe(0);
-+      if (IS_ERR(f))
-+              return PTR_ERR(f);
-+      sub_info->stdout = f;
-+
-+      f = create_read_pipe(f, 0);
-+      if (IS_ERR(f)) {
-+              free_write_pipe(sub_info->stdout);
-+              sub_info->stdout = NULL;
-+              return PTR_ERR(f);
-+      }
-+      *filp = f;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
-+
-+
- /**
-  * call_usermodehelper_exec - start a usermode application
-  * @sub_info: information about the subprocessa
-@@ -469,15 +535,22 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
-               goto out;
-       }
--      sub_info->complete = &done;
-+      if (wait == UMH_WAIT_EXT)
-+              sub_info->executed = &done;
-+      else
-+              sub_info->complete = &done;
-+
-       sub_info->wait = wait;
-       queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
-               goto unlock;
-+
-       wait_for_completion(&done);
--      retval = sub_info->retval;
-+      retval = sub_info->retval;
-+      if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
-+              goto unlock;
- out:
-       call_usermodehelper_freeinfo(sub_info);
- unlock:
diff --git a/src/dumm/patches/mconsole-exec-2.6.30.patch b/src/dumm/patches/mconsole-exec-2.6.30.patch
deleted file mode 100644 (file)
index b675ab4..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-index 51bd99d..7ac27b0 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -32,6 +32,7 @@
- tags
- TAGS
- vmlinux
-+linux
- System.map
- Module.markers
- Module.symvers
-diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
-index 14a102e..0acfaeb 100644
---- a/arch/um/drivers/line.c
-+++ b/arch/um/drivers/line.c
-@@ -866,6 +866,6 @@ char *add_xterm_umid(char *base)
-               return base;
-       }
--      snprintf(title, len, "%s (%s)", base, umid);
-+      snprintf(title, len, "%s (%s)", umid, base);
-       return title;
- }
-diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
-index e14629c..c488930 100644
---- a/arch/um/drivers/mconsole_kern.c
-+++ b/arch/um/drivers/mconsole_kern.c
-@@ -4,6 +4,7 @@
-  * Licensed under the GPL
-  */
-+#include "linux/kmod.h"
- #include <linux/console.h>
- #include <linux/ctype.h>
- #include <linux/interrupt.h>
-@@ -20,6 +21,8 @@
- #include <linux/un.h>
- #include <linux/workqueue.h>
- #include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/file.h>
- #include <asm/uaccess.h>
- #include "init.h"
-@@ -202,6 +205,65 @@ void mconsole_proc(struct mc_request *req)
- }
- #endif
-+void mconsole_exec(struct mc_request *req)
-+{
-+      DECLARE_COMPLETION_ONSTACK(done);
-+      struct subprocess_info *sub_info;
-+      int res, len;
-+      struct file *out;
-+      char buf[MCONSOLE_MAX_DATA];
-+
-+      char *envp[] = {
-+              "HOME=/", "TERM=linux",
-+              "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
-+              NULL
-+      };
-+      char *argv[] = {
-+              "/bin/sh", "-c",
-+              req->request.data + strlen("exec "),
-+              NULL
-+      };
-+
-+      sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC);
-+      if (sub_info == NULL) {
-+              mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
-+              return;
-+      }
-+      res = call_usermodehelper_stdoutpipe(sub_info, &out);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
-+              return;
-+      }
-+
-+      call_usermodehelper_setcomplete(sub_info, &done);
-+
-+      res = call_usermodehelper_exec(sub_info, UMH_WAIT_EXT);
-+      if (res < 0) {
-+              call_usermodehelper_freeinfo(sub_info);
-+              mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
-+              return;
-+      }
-+
-+      for (;;) {
-+              len = out->f_op->read(out, buf, sizeof(buf), &out->f_pos);
-+              if (len < 0) {
-+                      mconsole_reply(req, "reading output failed", 1, 0);
-+                      break;
-+              }
-+              if (len == 0)
-+                      break;
-+              mconsole_reply_len(req, buf, len, 0, 1);
-+      }
-+      fput(out);
-+
-+      wait_for_completion(&done);
-+      res = call_usermodehelper_getretval(sub_info) >> 8;
-+      call_usermodehelper_freeinfo(sub_info);
-+
-+      mconsole_reply_len(req, buf, len, res, 0);
-+}
-+
- void mconsole_proc(struct mc_request *req)
- {
-       char path[64];
-@@ -273,6 +335,7 @@ void mconsole_proc(struct mc_request *req)
-     stop - pause the UML; it will do nothing until it receives a 'go' \n\
-     go - continue the UML after a 'stop' \n\
-     log <string> - make UML enter <string> into the kernel log\n\
-+    exec <string> - pass <string> to /bin/sh -c synchronously\n\
-     proc <file> - returns the contents of the UML's /proc/<file>\n\
-     stack <pid> - returns the stack of the specified pid\n\
- "
-diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
-index f8cf4c8..019d89f 100644
---- a/arch/um/drivers/mconsole_user.c
-+++ b/arch/um/drivers/mconsole_user.c
-@@ -32,6 +32,7 @@ static struct mconsole_command commands[] = {
-       { "stop", mconsole_stop, MCONSOLE_PROC },
-       { "go", mconsole_go, MCONSOLE_INTR },
-       { "log", mconsole_log, MCONSOLE_INTR },
-+      { "exec", mconsole_exec, MCONSOLE_PROC },
-       { "proc", mconsole_proc, MCONSOLE_PROC },
-       { "stack", mconsole_stack, MCONSOLE_INTR },
- };
-diff --git a/arch/um/include/.gitignore b/arch/um/include/.gitignore
-new file mode 100644
-index 0000000..4c14eba
---- /dev/null
-+++ b/arch/um/include/.gitignore
-@@ -0,0 +1,2 @@
-+shared/kern_constants.h
-+shared/user_constants.h
-diff --git a/arch/um/include/shared/mconsole.h b/arch/um/include/shared/mconsole.h
-index c139ae1..dfb83b1 100644
---- a/arch/um/include/shared/mconsole.h
-+++ b/arch/um/include/shared/mconsole.h
-@@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_request *req);
- extern void mconsole_stop(struct mc_request *req);
- extern void mconsole_go(struct mc_request *req);
- extern void mconsole_log(struct mc_request *req);
-+extern void mconsole_exec(struct mc_request *req);
- extern void mconsole_proc(struct mc_request *req);
- extern void mconsole_stack(struct mc_request *req);
-diff --git a/arch/um/kernel/.gitignore b/arch/um/kernel/.gitignore
-new file mode 100644
-index 0000000..803397e
---- /dev/null
-+++ b/arch/um/kernel/.gitignore
-@@ -0,0 +1,3 @@
-+config.c
-+config.tmp
-+vmlinux.lds
-diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
-index b5afcfd..b598128 100644
---- a/arch/um/os-Linux/file.c
-+++ b/arch/um/os-Linux/file.c
-@@ -521,6 +521,8 @@ int os_create_unix_socket(const char *file, int len, int close_on_exec)
-       addr.sun_family = AF_UNIX;
-+      if (len > sizeof(addr.sun_path))
-+              len = sizeof(addr.sun_path);
-       snprintf(addr.sun_path, len, "%s", file);
-       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-diff --git a/include/linux/kmod.h b/include/linux/kmod.h
-index 384ca8b..b59c12e 100644
---- a/include/linux/kmod.h
-+++ b/include/linux/kmod.h
-@@ -45,6 +45,7 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS;
- struct key;
- struct file;
- struct subprocess_info;
-+struct completion;
- /* Allocate a subprocess_info structure */
- struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
-@@ -55,13 +56,20 @@ void call_usermodehelper_setkeys(struct subprocess_info *info,
-                                struct key *session_keyring);
- int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                 struct file **filp);
-+void call_usermodehelper_setcomplete(struct subprocess_info *sub_info,
-+                                   struct completion *complete);
- void call_usermodehelper_setcleanup(struct subprocess_info *info,
-                                   void (*cleanup)(char **argv, char **envp));
-+int call_usermodehelper_getretval(struct subprocess_info *sub_info);
- enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-+      UMH_WAIT_EXT = 2,       /* wait for the exec then return and signal
-+                                 when the process is complete */
- };
- /* Actually execute the sub-process */
-diff --git a/kernel/kmod.c b/kernel/kmod.c
-index 7e95bed..3f86902 100644
---- a/kernel/kmod.c
-+++ b/kernel/kmod.c
-@@ -121,12 +121,14 @@ struct subprocess_info {
-       struct work_struct work;
-       struct completion *complete;
-       struct cred *cred;
-+      struct completion *executed;
-       char *path;
-       char **argv;
-       char **envp;
-       enum umh_wait wait;
-       int retval;
-       struct file *stdin;
-+      struct file *stdout;
-       void (*cleanup)(char **argv, char **envp);
- };
-@@ -163,8 +165,26 @@ static int ____call_usermodehelper(void *data)
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdout) {
-+              struct files_struct *f = current->files;
-+              struct fdtable *fdt;
--              /* and disallow core files too */
-+              sys_close(1);
-+              sys_close(2);
-+              get_file(sub_info->stdout);
-+              fd_install(1, sub_info->stdout);
-+              fd_install(2, sub_info->stdout);
-+              spin_lock(&f->file_lock);
-+              fdt = files_fdtable(f);
-+              FD_SET(1, fdt->open_fds);
-+              FD_CLR(1, fdt->close_on_exec);
-+              FD_SET(2, fdt->open_fds);
-+              FD_CLR(2, fdt->close_on_exec);
-+              spin_unlock(&f->file_lock);
-+      }
-+      if (sub_info->stdin || sub_info->stdout) {
-+              /* disallow core files */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-@@ -250,7 +270,7 @@ static void __call_usermodehelper(struct work_struct *work)
-       /* CLONE_VFORK: wait until the usermode helper has execve'd
-        * successfully We need the data structures to stay around
-        * until that is done.  */
--      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
-+      if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT || wait == UMH_WAIT_EXT)
-               pid = kernel_thread(wait_for_helper, sub_info,
-                                   CLONE_FS | CLONE_FILES | SIGCHLD);
-       else
-@@ -261,6 +281,16 @@ static void __call_usermodehelper(struct work_struct *work)
-       case UMH_NO_WAIT:
-               break;
-+      case UMH_WAIT_EXT:
-+              if (pid > 0) {
-+                      complete(sub_info->executed);
-+                      break;
-+              }
-+              sub_info->retval = pid;
-+              complete(sub_info->executed);
-+              complete(sub_info->complete);
-+              break;
-+
-       case UMH_WAIT_PROC:
-               if (pid > 0)
-                       break;
-@@ -415,6 +445,19 @@ void call_usermodehelper_setcleanup(struct subprocess_info *info,
- }
- EXPORT_SYMBOL(call_usermodehelper_setcleanup);
-+void call_usermodehelper_setcomplete(struct subprocess_info *info,
-+                                  struct completion* complete)
-+{
-+      info->complete = complete;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_setcomplete);
-+
-+int call_usermodehelper_getretval(struct subprocess_info *info)
-+{
-+      return info->retval;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_getretval);
-+
- /**
-  * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
-  * @sub_info: a subprocess_info returned by call_usermodehelper_setup
-@@ -444,6 +487,29 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
- }
- EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
-+                                struct file **filp)
-+{
-+      struct file *f;
-+
-+      f = create_write_pipe(0);
-+      if (IS_ERR(f))
-+              return PTR_ERR(f);
-+      sub_info->stdout = f;
-+
-+      f = create_read_pipe(f, 0);
-+      if (IS_ERR(f)) {
-+              free_write_pipe(sub_info->stdout);
-+              sub_info->stdout = NULL;
-+              return PTR_ERR(f);
-+      }
-+      *filp = f;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
-+
-+
- /**
-  * call_usermodehelper_exec - start a usermode application
-  * @sub_info: information about the subprocessa
-@@ -473,15 +539,22 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
-               goto out;
-       }
--      sub_info->complete = &done;
-+      if (wait == UMH_WAIT_EXT)
-+              sub_info->executed = &done;
-+      else
-+              sub_info->complete = &done;
-+
-       sub_info->wait = wait;
-       queue_work(khelper_wq, &sub_info->work);
-       if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
-               goto unlock;
-+
-       wait_for_completion(&done);
--      retval = sub_info->retval;
-+      retval = sub_info->retval;
-+      if (wait == UMH_WAIT_EXT)       /* caller will free sub_info */
-+              goto unlock;
- out:
-       call_usermodehelper_freeinfo(sub_info);
- unlock:
diff --git a/src/dumm/scripts/start_testing.rb b/src/dumm/scripts/start_testing.rb
deleted file mode 100644 (file)
index c92e805..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-br0 = Bridge.new("br0")
-br1 = Bridge.new("br1")
-br2 = Bridge.new("br2")
-
-alice    = Guest["alice"]
-venus    = Guest["venus"]
-moon     = Guest["moon"]
-carol    = Guest["carol"]
-winnetou = Guest["winnetou"]
-dave     = Guest["dave"]
-sun      = Guest["sun"]
-bob      = Guest["bob"]
-
-alice.start
-venus.start
-moon.start
-carol.start
-winnetou.start
-dave.start
-sun.start
-bob.start
-
-alice.add("eth0").connect(br1).add("10.1.0.10")
-venus.add("eth0").connect(br1).add("10.1.0.20")
-moon.add("eth1").connect(br1).add("10.1.0.1")
-moon.add("eth0").connect(br0).add("192.168.0.1")
-carol.add("eth0").connect(br0).add("192.168.0.100")
-winnetou.add("eth0").connect(br0).add("192.168.0.150")
-dave.add("eth0").connect(br0).add("192.168.0.200")
-sun.add("eth0").connect(br0).add("192.168.0.2")
-sun.add("eth1").connect(br2).add("10.2.0.1")
-bob.add("eth0").connect(br2).add("10.2.0.10")
-
-alice.exec("ip route add dev eth0 10.1.0.0/16 src 10.1.0.10")
-venus.exec("ip route add dev eth0 10.1.0.0/16 src 10.1.0.20")
-moon.exec("ip route add dev eth1 10.1.0.0/16 src 10.1.0.1")
-moon.exec("ip route add dev eth0 192.168.0.0/24 src 192.168.0.1")
-carol.exec("ip route add dev eth0 192.168.0.0/24 src 192.168.0.100")
-winnetou.exec("ip route add dev eth0 192.168.0.0/24 src 192.168.0.150")
-dave.exec("ip route add dev eth0 192.168.0.0/24 src 192.168.0.200")
-sun.exec("ip route add dev eth0 192.168.0.0/24 src 192.168.0.2")
-sun.exec("ip route add dev eth1 10.2.0.0/16 src 10.2.0.1")
-bob.exec("ip route add dev eth0 10.2.0.0/16 src 10.2.0.10")
-
-alice.exec("ip route add default via 10.1.0.1")
-venus.exec("ip route add default via 10.1.0.1")
-moon.exec("ip route add default via 192.168.0.254")
-carol.exec("ip route add default via 192.168.0.254")
-winnetou.exec("ip route add default via 192.168.0.254")
-dave.exec("ip route add default via 192.168.0.254")
-sun.exec("ip route add default via 192.168.0.254")
-bob.exec("ip route add default via 10.2.0.1")
-
-moon.exec("echo 1 > /proc/sys/net/ipv4/ip_forward")
-sun.exec("echo 1 > /proc/sys/net/ipv4/ip_forward")
-