Commit 84a95ec9 authored by Daniel P. Berrange's avatar Daniel P. Berrange

Move interactive console to a separate console device

To avoid mixing the interactive console I/O with the machine
boot/error messages, use a dedicated console device for
interactive apps. Run a XDR based RPC protocol over the
console device to allow proper separation of stdout and
stderr, and passing back of command exit status
parent 15fb0b7e
......@@ -38,6 +38,8 @@ libvirt-sandbox/libvirt-sandbox-init-common
libvirt-sandbox/libvirt-sandbox-init-qemu
libvirt-sandbox/libvirt-sandbox-enum-types.h
libvirt-sandbox/libvirt-sandbox-enum-types.c
libvirt-sandbox/libvirt-sandbox-protocol.c
libvirt-sandbox/libvirt-sandbox-protocol.h
libvirt-sandbox/tests/*.cfg
libvirt-sandbox/tests/test-config
bin/virt-sandbox
......
......@@ -34,6 +34,15 @@ static gboolean do_close(GVirSandboxConsole *con G_GNUC_UNUSED,
return FALSE;
}
static gboolean do_exited(GVirSandboxConsole *con G_GNUC_UNUSED,
int status,
gpointer opaque)
{
int *ret = opaque;
*ret = WEXITSTATUS(status);
return FALSE;
}
static void libvirt_sandbox_version(void)
{
g_print(_("%s version %s\n"), PACKAGE, VERSION);
......@@ -49,6 +58,7 @@ int main(int argc, char **argv) {
GVirSandboxConfigInteractive *icfg = NULL;
GVirSandboxContext *ctx = NULL;
GVirSandboxContextInteractive *ictx = NULL;
GVirSandboxConsole *log = NULL;
GVirSandboxConsole *con = NULL;
GMainLoop *loop = NULL;
GError *error = NULL;
......@@ -209,12 +219,26 @@ int main(int argc, char **argv) {
goto cleanup;
}
if (!(con = gvir_sandbox_context_get_log_console(ctx, &error))) {
if (!(log = gvir_sandbox_context_get_log_console(ctx, &error))) {
g_printerr(_("Unable to get log console: %s\n"),
error && error->message ? error->message : "unknown");
goto cleanup;
}
g_signal_connect(log, "closed", (GCallback)do_close, loop);
if (!(gvir_sandbox_console_attach_stderr(log, &error))) {
g_printerr(_("Unable to attach sandbox console: %s\n"),
error && error->message ? error->message : "unknown");
goto cleanup;
}
if (!(con = gvir_sandbox_context_interactive_get_app_console(ictx, &error))) {
g_printerr(_("Unable to get app console: %s\n"),
error && error->message ? error->message : "unknown");
goto cleanup;
}
g_signal_connect(con, "closed", (GCallback)do_close, loop);
g_signal_connect(con, "exited", (GCallback)do_exited, &ret);
if (!(gvir_sandbox_console_attach_stdio(con, &error))) {
g_printerr(_("Unable to attach sandbox console: %s\n"),
......@@ -224,8 +248,6 @@ int main(int argc, char **argv) {
g_main_loop_run(loop);
ret = EXIT_SUCCESS;
cleanup:
if (error)
g_error_free(error);
......@@ -241,6 +263,7 @@ cleanup:
g_main_loop_unref(loop);
if (hv)
g_object_unref(hv);
return ret;
}
......
......@@ -51,6 +51,7 @@ LIBVIRT_SANDBOX_GTK_MISC
LIBVIRT_SANDBOX_WIN32
LIBVIRT_SANDBOX_COVERAGE
LIBVIRT_SANDBOX_INTROSPECTION
LIBVIRT_SANDBOX_RPCGEN
AC_OUTPUT(Makefile
......
......@@ -10,78 +10,42 @@ libexec_PROGRAMS = \
libvirt-sandbox-init-lxc \
$(NULL)
PROTOCOL_GENERATOR = libvirt-sandbox-protocol-generator.pl
EXTRA_DIST += $(PROTOCOL_GENERATOR)
sandboxconfigdir = $(sysconfdir)/$(PACKAGE)/scratch
sandboxconfig_DATA = README
lib_LTLIBRARIES = libvirt-sandbox-1.0.la
libvirt_sandbox_init_common_SOURCES = libvirt-sandbox-init-common.c
libvirt_sandbox_init_common_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
$(COVERAGE_CFLAGS) \
-I$(top_srcdir) \
$(GIO_UNIX_CFLAGS) \
$(LIBVIRT_GLIB_CFLAGS) \
$(LIBVIRT_GOBJECT_CFLAGS) \
$(CAPNG_CFLAGS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_common_LDFLAGS = \
-lutil \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(GIO_UNIX_LIBS) \
$(LIBVIRT_GLIB_LIBS) \
$(LIBVIRT_GOBJECT_LIBS) \
$(CAPNG_LIBS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_common_LDADD = \
libvirt-sandbox-1.0.la \
SANDBOX_TEMPLATE_FILES = \
libvirt-sandbox-enum-types.h.template \
libvirt-sandbox-enum-types.c.template \
$(NULL)
libvirt_sandbox_init_lxc_SOURCES = libvirt-sandbox-init-lxc.c
libvirt_sandbox_init_lxc_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
-I$(top_srcdir) \
$(GIO_UNIX_CFLAGS) \
$(LIBVIRT_GLIB_CFLAGS) \
$(LIBVIRT_GOBJECT_CFLAGS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_lxc_LDFLAGS = \
libvirt-sandbox-1.0.la \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(GIO_UNIX_LIBS) \
$(LIBVIRT_GLIB_LIBS) \
$(LIBVIRT_GOBJECT_LIBS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_lxc_LDADD = \
libvirt-sandbox-1.0.la \
SANDBOX_GENERATED_ENUM_FILES = \
libvirt-sandbox-enum-types.h \
libvirt-sandbox-enum-types.c \
$(NULL)
libvirt_sandbox_init_qemu_SOURCES = libvirt-sandbox-init-qemu.c
libvirt_sandbox_init_qemu_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_qemu_LDFLAGS = \
-all-static \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(WARN_CFLAGS) \
SANDBOX_GENERATED_RPC_FILES = \
libvirt-sandbox-protocol.h \
libvirt-sandbox-protocol.c \
$(NULL)
SANDBOX_TEMPLATE_FILES = \
libvirt-sandbox-enum-types.h.template \
libvirt-sandbox-enum-types.c.template \
SANDBOX_PROTOCOL_FILES = \
libvirt-sandbox-protocol.x \
$(NULL)
SANDBOX_GENERATED_FILES = \
libvirt-sandbox-enum-types.h \
libvirt-sandbox-enum-types.c \
$(SANDBOX_GENERATED_ENUM_FILES) \
$(SANDBOX_GENERATED_RPC_FILES) \
$(NULL)
SANDBOX_RPC_FILES = \
libvirt-sandbox-rpcpacket.c \
libvirt-sandbox-rpcpacket.h \
$(NULL)
SANDBOX_HEADER_FILES = \
......@@ -103,6 +67,7 @@ SANDBOX_HEADER_FILES = \
libvirt-sandbox-builder-container.h \
libvirt-sandbox-console.h \
libvirt-sandbox-console-raw.h \
libvirt-sandbox-console-rpc.h \
libvirt-sandbox-context.h \
libvirt-sandbox-context-graphical.h \
libvirt-sandbox-context-interactive.h \
......@@ -126,6 +91,7 @@ SANDBOX_SOURCE_FILES = \
libvirt-sandbox-builder-container.c \
libvirt-sandbox-console.c \
libvirt-sandbox-console-raw.c \
libvirt-sandbox-console-rpc.c \
libvirt-sandbox-context.c \
libvirt-sandbox-context-graphical.c \
libvirt-sandbox-context-interactive.c \
......@@ -136,11 +102,16 @@ libvirt_sandbox_1_0_ladir = $(includedir)/libvirt-sandbox-1.0/libvirt-sandbox
libvirt_sandbox_1_0_la_HEADERS = \
$(SANDBOX_HEADER_FILES)
libvirt_sandbox_1_0_la_SOURCES = \
$(SANDBOX_SOURCE_FILES)
$(SANDBOX_SOURCE_FILES) \
$(SANDBOX_RPC_FILES)
nodist_libvirt_sandbox_1_0_la_HEADERS = \
libvirt-sandbox-enum-types.h
$(NULL)
nodist_libvirt_sandbox_1_0_la_SOURCES = \
libvirt-sandbox-enum-types.c
libvirt-sandbox-enum-types.c \
libvirt-sandbox-protocol.h \
libvirt-sandbox-protocol.c \
$(NULL)
libvirt_sandbox_1_0_la_CFLAGS = \
-DBINDIR="\"$(bindir)\"" \
-DDATADIR="\"$(datadir)\"" \
......@@ -170,7 +141,70 @@ libvirt_sandbox_1_0_la_LDFLAGS = \
-Wl,--version-script=$(srcdir)/libvirt-sandbox.sym \
-version-info $(LIBVIRT_SANDBOX_VERSION_INFO)
EXTRA_DIST += $(SANDBOX_TEMPLATE_FILES)
libvirt_sandbox_init_common_SOURCES = libvirt-sandbox-init-common.c \
$(SANDBOX_GENERATED_RPC_FILES) \
$(SANDBOX_RPC_FILES) \
$(NULL)
libvirt_sandbox_init_common_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
$(COVERAGE_CFLAGS) \
-I$(top_srcdir) \
$(GIO_UNIX_CFLAGS) \
$(LIBVIRT_GLIB_CFLAGS) \
$(LIBVIRT_GOBJECT_CFLAGS) \
$(CAPNG_CFLAGS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_common_LDFLAGS = \
-lutil \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(GIO_UNIX_LIBS) \
$(LIBVIRT_GLIB_LIBS) \
$(LIBVIRT_GOBJECT_LIBS) \
$(CAPNG_LIBS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_common_LDADD = \
libvirt-sandbox-1.0.la \
$(NULL)
libvirt_sandbox_init_lxc_SOURCES = libvirt-sandbox-init-lxc.c
libvirt_sandbox_init_lxc_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
-I$(top_srcdir) \
$(GIO_UNIX_CFLAGS) \
$(LIBVIRT_GLIB_CFLAGS) \
$(LIBVIRT_GOBJECT_CFLAGS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_lxc_LDFLAGS = \
libvirt-sandbox-1.0.la \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(GIO_UNIX_LIBS) \
$(LIBVIRT_GLIB_LIBS) \
$(LIBVIRT_GOBJECT_LIBS) \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_lxc_LDADD = \
libvirt-sandbox-1.0.la \
$(NULL)
libvirt_sandbox_init_qemu_SOURCES = libvirt-sandbox-init-qemu.c
libvirt_sandbox_init_qemu_CFLAGS = \
-DLIBEXECDIR="\"$(libexecdir)\"" \
-DSANDBOXCONFIGDIR="\"$(sandboxconfigdir)\"" \
$(WARN_CFLAGS) \
$(NULL)
libvirt_sandbox_init_qemu_LDFLAGS = \
-all-static \
$(COVERAGE_CFLAGS:-f%=-Wc,f%) \
$(WARN_CFLAGS) \
$(NULL)
EXTRA_DIST += $(SANDBOX_TEMPLATE_FILES) $(SANDBOX_PROTOCOL_FILES)
BUILT_SOURCES = $(SANDBOX_GENERATED_FILES)
CLEANFILES += $(SANDBOX_GENERATED_FILES)
......@@ -184,6 +218,13 @@ libvirt-sandbox-enum-types.c: $(SANDBOX_HEADER_FILES) libvirt-sandbox-enum-types
sed -e "s/G_TYPE_VIR_CONFIG/GVIR_CONFIG_TYPE/" -e "s/g_vir/gvir/" > libvirt-sandbox-enum-types.c
libvirt-sandbox-protocol.c: $(srcdir)/$(PROTOCOL_GENERATOR) $(SANDBOX_PROTOCOL_FILES)
$(AM_V_GEN)$(PERL) -w $(srcdir)/$(PROTOCOL_GENERATOR) $(RPCGEN) -c $(SANDBOX_PROTOCOL_FILES:%=$(srcdir)/%) $@
libvirt-sandbox-protocol.h: $(srcdir)/$(PROTOCOL_GENERATOR) $(SANDBOX_PROTOCOL_FILES)
$(AM_V_GEN)$(PERL) -w $(srcdir)/$(PROTOCOL_GENERATOR) $(RPCGEN) -h $(SANDBOX_PROTOCOL_FILES:%=$(srcdir)/%) $@
if WITH_INTROSPECTION
LibvirtSandbox-1.0.gir: libvirt-sandbox-1.0.la $(G_IR_SCANNER) Makefile.am
......@@ -206,7 +247,7 @@ LibvirtSandbox-1.0.gir: libvirt-sandbox-1.0.la $(G_IR_SCANNER) Makefile.am
$(srcdir)/libvirt-sandbox.h \
$(SANDBOX_SOURCE_FILES:%=$(srcdir)/%) \
$(SANDBOX_HEADER_FILES:%=$(srcdir)/%) \
$(SANDBOX_GENERATED_FILES:%=%) \
$(SANDBOX_GENERATED_ENUM_FILES:%=%) \
$(NULL)
girdir = $(datadir)/gir-1.0
......
......@@ -302,7 +302,7 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
g_list_free(networks);
/* The first console is for stdio of the sandboxed app */
/* The first console is for debug messages from stdout/err of the guest init/kernel */
src = gvir_config_domain_chardev_source_pty_new();
con = gvir_config_domain_console_new();
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(con),
......@@ -324,6 +324,18 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
g_object_unref(con);
}
if (GVIR_SANDBOX_IS_CONFIG_INTERACTIVE(config)) {
/* The third console is for stdio of the sandboxed app */
src = gvir_config_domain_chardev_source_pty_new();
con = gvir_config_domain_console_new();
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(con),
GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(src));
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(con));
g_object_unref(con);
}
if (GVIR_SANDBOX_IS_CONFIG_GRAPHICAL(config)) {
g_set_error(error, GVIR_SANDBOX_BUILDER_CONTAINER_ERROR, 0,
"%s", "Graphical sandboxes are not supported for containers");
......
......@@ -410,7 +410,8 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
GVirConfigDomainInterfaceUser *iface;
GVirConfigDomainMemballoon *ball;
GVirConfigDomainGraphicsSpice *graph;
GVirConfigDomainSerial *con;
GVirConfigDomainConsole *con;
GVirConfigDomainSerial *ser;
GVirConfigDomainChardevSourcePty *src;
GList *tmp = NULL, *mounts = NULL, *networks = NULL;
int i;
......@@ -521,19 +522,41 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
/* The first serial is for stdio of the sandboxed app */
src = gvir_config_domain_chardev_source_pty_new();
con = gvir_config_domain_serial_new();
con = gvir_config_domain_console_new();
gvir_config_domain_console_set_target_type(GVIR_CONFIG_DOMAIN_CONSOLE(con),
GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_SERIAL);
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(con),
GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(src));
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(con));
g_object_unref(con);
src = gvir_config_domain_chardev_source_pty_new();
ser = gvir_config_domain_serial_new();
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(ser),
GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(src));
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(ser));
g_object_unref(ser);
/* Optional second serial is for a interactive shell (useful for
* troubleshooting stuff */
if (gvir_sandbox_config_get_shell(config)) {
src = gvir_config_domain_chardev_source_pty_new();
con = gvir_config_domain_serial_new();
ser = gvir_config_domain_serial_new();
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(ser),
GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(src));
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(ser));
g_object_unref(ser);
}
if (GVIR_SANDBOX_IS_CONFIG_INTERACTIVE(config)) {
src = gvir_config_domain_chardev_source_pty_new();
con = gvir_config_domain_console_new();
gvir_config_domain_console_set_target_type(GVIR_CONFIG_DOMAIN_CONSOLE(con),
GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_VIRTIO);
gvir_config_domain_chardev_set_source(GVIR_CONFIG_DOMAIN_CHARDEV(con),
GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE(src));
gvir_config_domain_add_device(domain,
......@@ -541,7 +564,6 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
g_object_unref(con);
}
if (GVIR_SANDBOX_IS_CONFIG_GRAPHICAL(config)) {
graph = gvir_config_domain_graphics_spice_new();
gvir_config_domain_graphics_spice_set_port(graph, -1);
......
This diff is collapsed.
/*
* libvirt-sandbox-console-rpc.h: libvirt sandbox rpc console
*
* Copyright (C) 2011-2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
#if !defined(__LIBVIRT_SANDBOX_H__) && !defined(LIBVIRT_SANDBOX_BUILD)
#error "Only <libvirt-sandbox/libvirt-sandbox.h> can be included directly."
#endif
#ifndef __LIBVIRT_SANDBOX_CONSOLE_RPC_H__
#define __LIBVIRT_SANDBOX_CONSOLE_RPC_H__
G_BEGIN_DECLS
#define GVIR_SANDBOX_TYPE_CONSOLE_RPC (gvir_sandbox_console_rpc_get_type ())
#define GVIR_SANDBOX_CONSOLE_RPC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_SANDBOX_TYPE_CONSOLE_RPC, GVirSandboxConsoleRpc))
#define GVIR_SANDBOX_CONSOLE_RPC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_SANDBOX_TYPE_CONSOLE_RPC, GVirSandboxConsoleRpcClass))
#define GVIR_SANDBOX_IS_CONSOLE_RPC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_SANDBOX_TYPE_CONSOLE_RPC))
#define GVIR_SANDBOX_IS_CONSOLE_RPC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_SANDBOX_TYPE_CONSOLE_RPC))
#define GVIR_SANDBOX_CONSOLE_RPC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_SANDBOX_TYPE_CONSOLE_RPC, GVirSandboxConsoleRpcClass))
typedef struct _GVirSandboxConsoleRpc GVirSandboxConsoleRpc;
typedef struct _GVirSandboxConsoleRpcPrivate GVirSandboxConsoleRpcPrivate;
typedef struct _GVirSandboxConsoleRpcClass GVirSandboxConsoleRpcClass;
struct _GVirSandboxConsoleRpc
{
GObject parent;
GVirSandboxConsoleRpcPrivate *priv;
/* Do not add fields to this struct */
};
struct _GVirSandboxConsoleRpcClass
{
GObjectClass parent_class;
void (*exited)(GVirSandboxConsoleRpc *console, int status);
void (*closed)(GVirSandboxConsoleRpc *console, gboolean err);
};
GType gvir_sandbox_console_rpc_get_type(void);
GVirSandboxConsoleRpc *gvir_sandbox_console_rpc_new(GVirConnection *connection,
GVirDomain *domain,
const char *devname);
G_END_DECLS
#endif /* __LIBVIRT_SANDBOX_CONSOLE_H__ */
......@@ -142,3 +142,41 @@ GVirSandboxContextInteractive *gvir_sandbox_context_interactive_new(GVirConnecti
"config", config,
NULL));
}
/**
* gvir_sandbox_context_interactive_get_app_console:
* @ctxt: (transfer none): the sandbox context
*
* Returns: (transfer full)(allow-none): the sandbox console (or NULL)
*/
GVirSandboxConsole *gvir_sandbox_context_interactive_get_app_console(GVirSandboxContextInteractive *ctxt,
GError **error)
{
GVirSandboxConsole *console;
const char *devname = NULL;
GVirDomain *domain;
GVirConnection *conn;
if (!(domain = gvir_sandbox_context_get_domain(GVIR_SANDBOX_CONTEXT(ctxt), error)))
return NULL;
conn = gvir_sandbox_context_get_connection(GVIR_SANDBOX_CONTEXT(ctxt));
/* XXX get from config + shell */
if (strstr(gvir_connection_get_uri(conn), "lxc")) {
GVirSandboxConfig *config = gvir_sandbox_context_get_config(GVIR_SANDBOX_CONTEXT(ctxt));
if (gvir_sandbox_config_get_shell(config))
devname = "console2";
else
devname = "console1";
} else {
devname = "console1";
}
console = GVIR_SANDBOX_CONSOLE(gvir_sandbox_console_rpc_new(conn,
domain,
devname));
g_object_unref(domain);
return console;
}
......@@ -60,6 +60,9 @@ GType gvir_sandbox_context_interactive_get_type(void);
GVirSandboxContextInteractive *gvir_sandbox_context_interactive_new(GVirConnection *connection,
GVirSandboxConfigInteractive *config);
GVirSandboxConsole *gvir_sandbox_context_interactive_get_app_console(GVirSandboxContextInteractive *ctxt,
GError **error);
G_END_DECLS
#endif /* __LIBVIRT_SANDBOX_CONTEXT_INTERACTIVE_H__ */
......@@ -333,6 +333,7 @@ gboolean gvir_sandbox_context_start(GVirSandboxContext *ctxt, GError **error)
gchar *tmpdir;
gchar *configdir;
gboolean ret = FALSE;
const gchar *devname;
if (priv->domain) {
*error = g_error_new(GVIR_SANDBOX_CONTEXT_ERROR, 0,
......@@ -378,9 +379,15 @@ gboolean gvir_sandbox_context_start(GVirSandboxContext *ctxt, GError **error)
if (!(gvir_sandbox_cleaner_run_post_start(priv->cleaner, NULL)))
goto error;
/* XXX get from config */
if (strstr(gvir_connection_get_uri(priv->connection), "lxc"))
devname = "console0";
else
devname = "serial0";
priv->console = GVIR_SANDBOX_CONSOLE(gvir_sandbox_console_raw_new(priv->connection,
priv->domain,
NULL));
devname));
priv->active = TRUE;
ret = TRUE;
......@@ -515,9 +522,9 @@ GVirSandboxConsole *gvir_sandbox_context_get_shell_console(GVirSandboxContext *c
/* XXX get from config */
if (strstr(gvir_connection_get_uri(priv->connection), "lxc"))
devname = "console0";
devname = "console1";
else
devname = "serial0";
devname = "serial1";
console = GVIR_SANDBOX_CONSOLE(gvir_sandbox_console_raw_new(priv->connection, priv->domain,
devname));
......
#
# Generate code for an XDR protocol, optionally applying
# fixups to the glibc rpcgen code so that it compiles
# with warnings turned on.
#
# This code is evil. Arguably better would be just to compile
# without -Werror. Update: The IXDR_PUT_LONG replacements are
# actually fixes for 64 bit, so this file is necessary. Arguably
# so is the type-punning fix.
#
# Copyright (C) 2007, 2011-2012 Red Hat, Inc.
#
# See COPYING for the license of this software.
#
# Richard Jones <rjones@redhat.com>
use strict;
my $in_function = 0;
my @function = ();
my $rpcgen = shift;
my $mode = shift;
my $xdrdef = shift;
my $target = shift;
unlink $target;
open RPCGEN, "-|", $rpcgen, $mode, $xdrdef
or die "cannot run $rpcgen $mode $xdrdef: $!";
open TARGET, ">$target"
or die "cannot create $target: $!";
my $fixup = $^O eq "linux" || $^O eq "cygwin";
if ($mode eq "-c") {
print TARGET "#include <config.h>\n";
}
while (<RPCGEN>) {
# We only want to fixup the GLibc rpcgen output
# So just print data unchanged, if non-Linux
unless ($fixup) {
print TARGET;
next;
}
if (m/^{/) {
$in_function = 1;
print TARGET;
next;
}
s/\t/ /g;
# Fix VPATH builds
s,#include ".*/([^/]+)protocol\.h",#include "${1}protocol.h",;
if (m,#(ifdef|ifndef|define|endif)\s+,) {
s/-/_/g;
}
# Portability for Solaris RPC
s/u_quad_t/uint64_t/g;
s/quad_t/int64_t/g;
s/xdr_u_quad_t/xdr_uint64_t/g;
s/xdr_quad_t/xdr_int64_t/g;
s/(?<!IXDR_GET_INT32 )IXDR_GET_LONG/IXDR_GET_INT32/g;
if (m/^}/) {
$in_function = 0;
# Note: The body of the function is in @function.
# Remove decl of buf, if buf isn't used in the function.
my @uses = grep /[^.>]\bbuf\b/, @function;
@function = grep !/[^.>]\bbuf\b/, @function if @uses == 1;
# Remove decl of i, if i isn't used in the function.
@uses = grep /[^.>]\bi\b/, @function;
@function = grep !/[^.>]\bi\b/, @function if @uses == 1;
# (char **)&objp->... gives:
# warning: dereferencing type-punned pointer will break
# strict-aliasing rules
# so rewrite it.
my %uses = ();
my $i = 0;
foreach (@function) {
$uses{$1} = $i++ if m/\(char \*\*\)\&(objp->[a-z_.]+_val)/i;
}
if (keys %uses >= 1) {
my $i = 1;
foreach (keys %uses) {
$i = $uses{$_};
unshift @function,
(" char **objp_cpp$i = (char **) (void *) &$_;\n");
$i++;
}
@function =
map { s{\(char \*\*\)\&(objp->[a-z_.]+_val)}
{objp_cpp$uses{$1}}gi; $_ } @function;
}
# The code uses 'IXDR_PUT_{U_,}LONG' but it's wrong in two
# ways: Firstly these functions are deprecated and don't
# work on 64 bit platforms. Secondly the return value should
# be ignored. Correct both these mistakes.
@function =
map { s/\bIXDR_PUT_((U_)?)LONG\b/(void)IXDR_PUT_$1INT32/; $_ }
map { s/\bXDR_INLINE\b/(int32_t*)XDR_INLINE/; $_ }
@function;
print TARGET (join ("", @function));
@function = ();
}
unless ($in_function) {
print TARGET;
} else {
push @function, $_;
}
}
close TARGET
or die "cannot save $target: $!";
close RPCGEN
or die "cannot shutdown $rpcgen: $!";
chmod 0444, $target
or die "cannot set $target readonly: $!";
const GVIR_SANDBOX_PROTOCOL_PACKET_MAX = 262144;
const GVIR_SANDBOX_PROTOCOL_LEN_MAX = 4;
const GVIR_SANDBOX_PROTOCOL_HEADER_MAX = 16;
const GVIR_SANDBOX_PROTOCOL_PAYLOAD_MAX = 262128;
const GVIR_SANDBOX_PROTOCOL_HANDSHAKE_WAIT = 033;
const GVIR_SANDBOX_PROTOCOL_HANDSHAKE_SYNC = 034;
enum GVirSandboxProtocolProc {
GVIR_SANDBOX_PROTOCOL_PROC_STDIN = 1,
GVIR_SANDBOX_PROTOCOL_PROC_STDOUT = 2,
GVIR_SANDBOX_PROTOCOL_PROC_STDERR = 3,
GVIR_SANDBOX_PROTOCOL_PROC_EXIT = 4,
GVIR_SANDBOX_PROTOCOL_PROC_QUIT = 5
};
enum GVirSandboxProtocolType {
/* Async message */
GVIR_SANDBOX_PROTOCOL_TYPE_MESSAGE = 0,
/* Async data packet */
GVIR_SANDBOX_PROTOCOL_TYPE_DATA = 1
};
enum GVirSandboxProtocolStatus {
/* Status is always GVIR_SANDBOX_PROTO_OK for calls.
* For replies, indicates no error.
*/
GVIR_SANDBOX_PROTOCOL_STATUS_OK = 0
};