summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2011-10-21 13:57:11 +0100
committerDaniel P. Berrange <berrange@redhat.com>2012-01-31 14:27:17 +0000
commit5bc4c0b342f0ebe330f0db61a0a40cf009d2b1ba (patch)
tree4e048cf87b6edff107b25904c6bd47eb5c2a3e06 /src
parenta94100eaebd9ac23a164640e270a7ffaea98943e (diff)
downloadvirt-viewer-5bc4c0b342f0ebe330f0db61a0a40cf009d2b1ba.tar.gz
virt-viewer-5bc4c0b342f0ebe330f0db61a0a40cf009d2b1ba.tar.xz
virt-viewer-5bc4c0b342f0ebe330f0db61a0a40cf009d2b1ba.zip
Support for virDomainOpenGraphics API
Add a new flag --attach, which instructs virt-viewer to attach to the target display using virDomainOpenGraphics, instead of initiating a VNC/SPICE connection directly.
Diffstat (limited to 'src')
-rw-r--r--src/virt-viewer-app.c57
-rw-r--r--src/virt-viewer-app.h3
-rw-r--r--src/virt-viewer-main.c5
-rw-r--r--src/virt-viewer.c61
-rw-r--r--src/virt-viewer.h1
5 files changed, 121 insertions, 6 deletions
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index f340917..1126ddf 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -111,6 +111,7 @@ struct _VirtViewerAppPrivate {
gboolean authretry;
gboolean started;
gboolean fullscreen;
+ gboolean attach;
VirtViewerSession *session;
gboolean active;
@@ -650,6 +651,26 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
return 0;
}
+static gboolean
+virt_viewer_app_default_open_connection(VirtViewerApp *self G_GNUC_UNUSED, int *fd)
+{
+ *fd = -1;
+ return TRUE;
+}
+
+
+static int
+virt_viewer_app_open_connection(VirtViewerApp *self, int *fd)
+{
+ VirtViewerAppClass *klass;
+
+ g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), -1);
+ klass = VIRT_VIEWER_APP_GET_CLASS(self);
+
+ return klass->open_connection(self, fd);
+}
+
+
#if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK)
static void
virt_viewer_app_channel_open(VirtViewerSession *session,
@@ -661,13 +682,18 @@ virt_viewer_app_channel_open(VirtViewerSession *session,
g_return_if_fail(self != NULL);
+ if (!virt_viewer_app_open_connection(self, &fd))
+ return;
+
+ DEBUG_LOG("After open connection callback fd=%d", fd);
+
priv = self->priv;
if (priv->transport && g_ascii_strcasecmp(priv->transport, "ssh") == 0 &&
- !priv->direct) {
+ !priv->direct && fd == -1) {
if ((fd = virt_viewer_app_open_tunnel_ssh(priv->host, priv->port, priv->user,
priv->ghost, priv->gport, NULL)) < 0)
virt_viewer_app_simple_message_dialog(self, _("Connect to ssh failed."));
- } else {
+ } else if (fd == -1) {
virt_viewer_app_simple_message_dialog(self, _("Can't connect to channel, SSH only supported."));
}
@@ -690,10 +716,16 @@ virt_viewer_app_default_activate(VirtViewerApp *self)
VirtViewerAppPrivate *priv = self->priv;
int fd = -1;
+ if (!virt_viewer_app_open_connection(self, &fd))
+ return -1;
+
+ DEBUG_LOG("After open connection callback fd=%d", fd);
+
#if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK)
if (priv->transport &&
g_ascii_strcasecmp(priv->transport, "ssh") == 0 &&
- !priv->direct) {
+ !priv->direct &&
+ fd == -1) {
gchar *p = NULL;
if (priv->gport) {
@@ -716,7 +748,7 @@ virt_viewer_app_default_activate(VirtViewerApp *self)
priv->user, priv->ghost,
priv->gport, priv->unixsock)) < 0)
return -1;
- } else if (priv->unixsock) {
+ } else if (priv->unixsock && fd == -1) {
virt_viewer_app_trace(self, "Opening direct UNIX connection to display at %s",
priv->unixsock);
if ((fd = virt_viewer_app_open_unix_sock(priv->unixsock)) < 0)
@@ -1190,6 +1222,7 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
klass->initial_connect = virt_viewer_app_default_initial_connect;
klass->activate = virt_viewer_app_default_activate;
klass->deactivated = virt_viewer_app_default_deactivated;
+ klass->open_connection = virt_viewer_app_default_open_connection;
g_object_class_install_property(object_class,
PROP_VERBOSE,
@@ -1292,6 +1325,22 @@ virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct)
self->priv->direct = direct;
}
+void
+virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach)
+{
+ g_return_if_fail(VIRT_VIEWER_IS_APP(self));
+
+ self->priv->attach = attach;
+}
+
+gboolean
+virt_viewer_app_get_attach(VirtViewerApp *self)
+{
+ g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE);
+
+ return self->priv->attach;
+}
+
gboolean
virt_viewer_app_is_active(VirtViewerApp *self)
{
diff --git a/src/virt-viewer-app.h b/src/virt-viewer-app.h
index 320e75c..7280873 100644
--- a/src/virt-viewer-app.h
+++ b/src/virt-viewer-app.h
@@ -55,6 +55,7 @@ typedef struct {
int (*initial_connect) (VirtViewerApp *self);
int (*activate) (VirtViewerApp *self);
void (*deactivated) (VirtViewerApp *self);
+ gboolean (*open_connection)(VirtViewerApp *self, int *fd);
} VirtViewerAppClass;
GType virt_viewer_app_get_type (void);
@@ -73,6 +74,8 @@ int virt_viewer_app_initial_connect(VirtViewerApp *self);
void virt_viewer_app_start_reconnect_poll(VirtViewerApp *self);
void virt_viewer_app_set_zoom_level(VirtViewerApp *self, gint zoom_level);
void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
+void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
+gboolean virt_viewer_app_get_attach(VirtViewerApp *self);
gboolean virt_viewer_app_has_session(VirtViewerApp *self);
void virt_viewer_app_set_connect_info(VirtViewerApp *self,
const gchar *host,
diff --git a/src/virt-viewer-main.c b/src/virt-viewer-main.c
index c8e1082..bb967bb 100644
--- a/src/virt-viewer-main.c
+++ b/src/virt-viewer-main.c
@@ -52,6 +52,7 @@ int main(int argc, char **argv)
gboolean verbose = FALSE;
gboolean debug = FALSE;
gboolean direct = FALSE;
+ gboolean attach = FALSE;
gboolean waitvm = FALSE;
gboolean reconnect = FALSE;
gboolean fullscreen = FALSE;
@@ -64,6 +65,8 @@ int main(int argc, char **argv)
N_("Display verbose information"), NULL },
{ "direct", 'd', 0, G_OPTION_ARG_NONE, &direct,
N_("Direct connection with no automatic tunnels"), NULL },
+ { "attach", 'a', 0, G_OPTION_ARG_NONE, &attach,
+ N_("Attach to the local display using libvirt"), NULL },
{ "connect", 'c', 0, G_OPTION_ARG_STRING, &uri,
N_("Connect to hypervisor"), "URI"},
{ "wait", 'w', 0, G_OPTION_ARG_NONE, &waitvm,
@@ -121,7 +124,7 @@ int main(int argc, char **argv)
virt_viewer_app_set_debug(debug);
- viewer = virt_viewer_new(uri, args[0], zoom, direct, waitvm, reconnect, verbose, NULL);
+ viewer = virt_viewer_new(uri, args[0], zoom, direct, attach, waitvm, reconnect, verbose, NULL);
if (viewer == NULL)
goto cleanup;
diff --git a/src/virt-viewer.c b/src/virt-viewer.c
index 10865ec..9dc0ad8 100644
--- a/src/virt-viewer.c
+++ b/src/virt-viewer.c
@@ -40,6 +40,10 @@
#include <libxml/xpath.h>
#include <libxml/uri.h>
+#if defined(HAVE_SOCKETPAIR)
+#include <sys/socket.h>
+#endif
+
#include "virt-viewer.h"
#include "virt-viewer-app.h"
#include "virt-viewer-events.h"
@@ -48,6 +52,7 @@
struct _VirtViewerPrivate {
char *uri;
virConnectPtr conn;
+ virDomainPtr dom;
char *domkey;
gboolean withEvents;
gboolean waitvm;
@@ -59,6 +64,7 @@ G_DEFINE_TYPE (VirtViewer, virt_viewer, VIRT_VIEWER_TYPE_APP)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE, VirtViewerPrivate))
static int virt_viewer_initial_connect(VirtViewerApp *self);
+static gboolean virt_viewer_open_connection(VirtViewerApp *self, int *fd);
static void virt_viewer_deactivated(VirtViewerApp *self);
static gboolean virt_viewer_start(VirtViewerApp *self);
@@ -85,6 +91,12 @@ virt_viewer_set_property (GObject *object, guint property_id,
static void
virt_viewer_dispose (GObject *object)
{
+ VirtViewer *self = VIRT_VIEWER(object);
+ VirtViewerPrivate *priv = self->priv;
+ if (priv->dom)
+ virDomainFree(priv->dom);
+ if (priv->conn)
+ virConnectClose(priv->conn);
G_OBJECT_CLASS(virt_viewer_parent_class)->dispose (object);
}
@@ -102,6 +114,7 @@ virt_viewer_class_init (VirtViewerClass *klass)
app_class->initial_connect = virt_viewer_initial_connect;
app_class->deactivated = virt_viewer_deactivated;
+ app_class->open_connection = virt_viewer_open_connection;
app_class->start = virt_viewer_start;
}
@@ -117,6 +130,11 @@ virt_viewer_deactivated(VirtViewerApp *app)
VirtViewer *self = VIRT_VIEWER(app);
VirtViewerPrivate *priv = self->priv;
+ if (priv->dom) {
+ virDomainFree(priv->dom);
+ priv->dom = NULL;
+ }
+
if (priv->reconnect) {
if (!priv->withEvents) {
DEBUG_LOG("No domain events, falling back to polling");
@@ -365,6 +383,11 @@ virt_viewer_update_display(VirtViewer *self, virDomainPtr dom)
VirtViewerPrivate *priv = self->priv;
VirtViewerApp *app = VIRT_VIEWER_APP(self);
+ if (priv->dom)
+ virDomainFree(priv->dom);
+ priv->dom = dom;
+ virDomainRef(priv->dom);
+
virt_viewer_app_trace(app, "Guest %s is running, determining display\n",
priv->domkey);
@@ -378,6 +401,36 @@ virt_viewer_update_display(VirtViewer *self, virDomainPtr dom)
return 0;
}
+static gboolean
+virt_viewer_open_connection(VirtViewerApp *self G_GNUC_UNUSED, int *fd)
+{
+#if defined(HAVE_SOCKETPAIR)
+ VirtViewer *viewer = VIRT_VIEWER(self);
+ VirtViewerPrivate *priv = viewer->priv;
+ int pair[2];
+#endif
+ *fd = -1;
+#if defined(HAVE_SOCKETPAIR)
+ if (!priv->dom)
+ return TRUE;
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) < 0)
+ return FALSE;
+
+ if (virDomainOpenGraphics(priv->dom, 0, pair[0],
+ VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) < 0) {
+ virErrorPtr err = virGetLastError();
+ DEBUG_LOG("Error %s", err && err->message ? err->message : "Unknown");
+ close(pair[0]);
+ close(pair[1]);
+ return TRUE;
+ }
+ close(pair[0]);
+ *fd = pair[1];
+#endif
+ return TRUE;
+}
+
static int
virt_viewer_domain_event(virConnectPtr conn G_GNUC_UNUSED,
virDomainPtr dom,
@@ -488,6 +541,10 @@ virt_viewer_start(VirtViewerApp *app)
.cb = virt_viewer_auth_libvirt_credentials,
.cbdata = (void *)priv->uri,
};
+ int oflags = 0;
+
+ if (!virt_viewer_app_get_attach(app))
+ oflags |= VIR_CONNECT_RO;
virt_viewer_events_register();
@@ -498,7 +555,7 @@ virt_viewer_start(VirtViewerApp *app)
priv->conn = virConnectOpenAuth(priv->uri,
//virConnectAuthPtrDefault,
&auth_libvirt,
- VIR_CONNECT_RO);
+ oflags);
if (!priv->conn) {
virt_viewer_app_simple_message_dialog(app, _("Unable to connect to libvirt with URI %s"),
priv->uri ? priv->uri : _("[none]"));
@@ -530,6 +587,7 @@ virt_viewer_new(const char *uri,
const char *name,
gint zoom,
gboolean direct,
+ gboolean attach,
gboolean waitvm,
gboolean reconnect,
gboolean verbose,
@@ -553,6 +611,7 @@ virt_viewer_new(const char *uri,
g_object_set(app, "title", name, NULL);
virt_viewer_window_set_zoom_level(virt_viewer_app_get_main_window(app), zoom);
virt_viewer_app_set_direct(app, direct);
+ virt_viewer_app_set_attach(app, attach);
/* should probably be properties instead */
priv->uri = g_strdup(uri);
diff --git a/src/virt-viewer.h b/src/virt-viewer.h
index 886a0f3..02512ca 100644
--- a/src/virt-viewer.h
+++ b/src/virt-viewer.h
@@ -53,6 +53,7 @@ virt_viewer_new(const char *uri,
const char *name,
gint zoom,
gboolean direct,
+ gboolean attach,
gboolean waitvm,
gboolean reconnect,
gboolean verbose,