summaryrefslogtreecommitdiff
path: root/src/dumm/mconsole.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dumm/mconsole.c')
-rw-r--r--src/dumm/mconsole.c110
1 files changed, 51 insertions, 59 deletions
diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c
index d9864f676..c6e0c2f08 100644
--- a/src/dumm/mconsole.c
+++ b/src/dumm/mconsole.c
@@ -88,21 +88,21 @@ struct mconsole_notify {
/**
* send a request to UML using mconsole
*/
-static int request(private_mconsole_t *this, char *command,
- char buf[], size_t *size)
+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, total = 0, flags = 0;
+ int len, flags = 0;
+ va_list args;
memset(&request, 0, sizeof(request));
request.magic = MCONSOLE_MAGIC;
request.version = MCONSOLE_VERSION;
- request.len = min(strlen(command), sizeof(reply.data) - 1);
- strncpy(request.data, command, request.len);
- *buf = '\0';
- (*size)--;
-
+ va_start(args, command);
+ request.len = vsnprintf(request.data, sizeof(request.data), command, args);
+ va_end(args);
+
if (this->idle)
{
flags = MSG_DONTWAIT;
@@ -120,7 +120,7 @@ static int request(private_mconsole_t *this, char *command,
if (len < 0)
{
- snprintf(buf, *size, "sending mconsole command to UML failed: %m");
+ DBG1("sending mconsole command to UML failed: %m");
return -1;
}
do
@@ -136,96 +136,87 @@ static int request(private_mconsole_t *this, char *command,
}
if (len < 0)
{
- snprintf(buf, *size, "receiving from mconsole failed: %m");
+ DBG1("receiving from mconsole failed: %m");
return -1;
}
if (len > 0)
{
- strncat(buf, reply.data, min(reply.len, *size - total));
- total += reply.len;
+ if (cb)
+ {
+ cb(data, reply.data, reply.len);
+ }
+ else if (reply.err)
+ {
+ DBG1("received mconsole error %d: %*.s",
+ reply.err, reply.len, reply.data);
+ break;
+ }
}
}
while (reply.more);
- *size = total;
return reply.err;
}
/**
+ * ignore error message
+ */
+static void ignore(void *data, char *buf, size_t len)
+{
+}
+
+/**
* Implementation of mconsole_t.add_iface.
*/
static bool add_iface(private_mconsole_t *this, char *guest, char *host)
{
- char buf[128];
- int len;
+ int tries = 0;
- len = snprintf(buf, sizeof(buf), "config %s=tuntap,%s", guest, host);
- if (len < 0 || len >= sizeof(buf))
- {
- return FALSE;
- }
- len = sizeof(buf);
- if (request(this, buf, buf, &len) != 0)
+ while (tries++ < 5)
{
- DBG1("adding interface failed: %.*s", len, buf);
- return FALSE;
+ if (request(this, ignore, NULL, "config %s=tuntap,%s", guest, host) == 0)
+ {
+ return TRUE;
+ }
+ usleep(10000 * tries * tries);
}
- return TRUE;
+ return FALSE;
}
/**
* Implementation of mconsole_t.del_iface.
*/
static bool del_iface(private_mconsole_t *this, char *guest)
-{
- char buf[128];
- int len;
-
- len = snprintf(buf, sizeof(buf), "remove %s", guest);
- if (len < 0 || len >= sizeof(buf))
- {
- return FALSE;
- }
- if (request(this, buf, buf, &len) != 0)
+{
+ if (request(this, NULL, NULL, "remove %s", guest) != 0)
{
- DBG1("removing interface failed: %.*s", len, buf);
return FALSE;
}
return TRUE;
}
/**
+ * Implementation of mconsole_t.exec
+ */
+static int exec(private_mconsole_t *this, void(*cb)(void*,char*,size_t),
+ void *data, char *cmd)
+{
+ return request(this, cb, data, "exec %s", cmd);
+}
+
+/**
* Poll until guest is ready
*/
static bool wait_bootup(private_mconsole_t *this)
{
- char buf[128];
- int len, res;
-
- while (TRUE)
+ /* wait for init process to appear */
+ while (request(this, ignore, NULL, "exec ps -p 1 > /dev/null"))
{
- len = sizeof(buf);
- res = request(this, "config eth9=mcast", buf, &len);
- if (res < 0)
- {
- return FALSE;
- }
- if (res == 0)
- {
- while (request(this, "remove eth9", buf, &len) != 0)
- {
- usleep(50000);
- }
- return TRUE;
- }
if (this->idle)
{
this->idle();
}
- else
- {
- usleep(50000);
- }
+ usleep(100000);
}
}
@@ -240,7 +231,7 @@ static void destroy(private_mconsole_t *this)
}
/**
- * setup the mconsole notify connection and wait for its readyness
+ * setup the mconsole notify connection and wait for its readiness
*/
static bool wait_for_notify(private_mconsole_t *this, char *nsock)
{
@@ -335,6 +326,7 @@ mconsole_t *mconsole_create(char *notify, void(*idle)(void))
this->public.add_iface = (bool(*)(mconsole_t*, char *guest, char *host))add_iface;
this->public.del_iface = (bool(*)(mconsole_t*, char *guest))del_iface;
+ this->public.exec = (int(*)(mconsole_t*, void(*cb)(void*,char*,size_t), void *data, char *cmd))exec;
this->public.destroy = (void*)destroy;
this->idle = idle;