aboutsummaryrefslogtreecommitdiffstats
path: root/qemu-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu-gtk.c')
-rw-r--r--qemu-gtk.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/qemu-gtk.c b/qemu-gtk.c
index 0281b58..e1c7a9a 100644
--- a/qemu-gtk.c
+++ b/qemu-gtk.c
@@ -379,6 +379,20 @@ static void menu_cb_monitor_cont(GtkAction *action, gpointer userdata)
monitor_append(win, "cont");
}
+static void menu_cb_monitor_save_to_disk(GtkAction *action, gpointer userdata)
+{
+ struct qemu_window *win = userdata;
+ char line[256];
+
+ if (!win->image_save) {
+ /* TODO: error message */
+ return;
+ }
+ snprintf(line, sizeof(line), "migrate \"exec:cat>%s\"", win->image_save);
+ monitor_append(win, line);
+ monitor_append(win, "quit");
+}
+
static void menu_cb_monitor_sys_reset(GtkAction *action, gpointer userdata)
{
struct qemu_window *win = userdata;
@@ -532,6 +546,8 @@ void vnc_connect(struct qemu_window *win)
if (2 == sscanf(win->vnc_display, "%127[^:]:%d", win->vnc_hostname, &nr)) {
sprintf(win->vnc_tcpport, "%d", nr + 5900);
+ if (strcmp("0.0.0.0",win->vnc_hostname) == 0)
+ sprintf(win->vnc_hostname, "%s", win->monitor.hostname);
} else if (1 == sscanf(win->vnc_display, ":%d", &nr)) {
sprintf(win->vnc_hostname, "%s", win->monitor.hostname);
sprintf(win->vnc_tcpport, "%d", nr + 5900);
@@ -547,7 +563,8 @@ void vnc_connect(struct qemu_window *win)
/* ------------------------------------------------------------------ */
-int conn_init(struct qemu_conn *conn, char *name, char *dest)
+int conn_init(struct qemu_conn *conn, char *name, char *dest,
+ const char *monitor_hostname)
{
struct addrinfo ask;
char path[256];
@@ -560,9 +577,13 @@ int conn_init(struct qemu_conn *conn, char *name, char *dest)
snprintf(conn->name, sizeof(conn->name), "%s", name);
strcpy(conn->hostname, "localhost");
- if (2 == sscanf(dest, "tcp:%64[^:]:%32s", conn->hostname, serv)) {
+ if (monitor_hostname)
+ strcpy(conn->hostname, monitor_hostname);
+ if (2 == sscanf(dest, "tcp:%64[^:]:%32[^,]", conn->hostname, serv)) {
+ if (strcmp("0.0.0.0", conn->hostname) == 0)
+ sprintf(conn->hostname, "%s", monitor_hostname);
conn->handle = tcp_connect(&ask, NULL, NULL, conn->hostname, serv);
- } else if (1 == sscanf(dest, "tcp:%32s", serv)) {
+ } else if (1 == sscanf(dest, "tcp:%32[^,]", serv)) {
conn->handle = tcp_connect(&ask, NULL, NULL, conn->hostname, serv);
} else if (1 == sscanf(dest, "unix:%255s", path)) {
conn->handle = unix_connect(path);
@@ -588,6 +609,12 @@ static void conn_user_input(VteTerminal *vte, gchar *buf, guint len,
write(conn->handle, buf, len);
}
+static void conn_vte_destroy(GtkObject *object, gpointer data)
+{
+ struct qemu_conn *conn = data;
+ conn->vte = NULL;
+}
+
static gboolean conn_watch(GIOChannel *source, GIOCondition condition,
gpointer data)
{
@@ -615,6 +642,9 @@ static gboolean conn_watch(GIOChannel *source, GIOCondition condition,
close:
if (conn->vte)
vte_terminal_feed(VTE_TERMINAL(conn->vte), "\r\n=== CLOSED ===", 16);
+ g_source_destroy(g_main_context_find_source_by_id
+ (g_main_context_default(), conn->id));
+ conn->id = 0;
close(conn->handle);
conn->handle = -1;
return FALSE;
@@ -637,7 +667,7 @@ int conn_open_term(struct qemu_window *win, char *name, char *dest, int pos)
return -1;
memset(conn,0,sizeof(*conn));
- fd = conn_init(conn, name, dest);
+ fd = conn_init(conn, name, dest, win->monitor.hostname);
if (fd == -1) {
free(conn);
return -1;
@@ -733,6 +763,10 @@ static const GtkActionEntry entries[] = {
.label = "_Unpause",
.callback = G_CALLBACK(menu_cb_monitor_cont),
},{
+ .name = "MonitorSaveToDisk",
+ .label = "_Save to disk",
+ .callback = G_CALLBACK(menu_cb_monitor_save_to_disk),
+ },{
.name = "MonitorSysReset",
.label = "_Reset",
.callback = G_CALLBACK(menu_cb_monitor_sys_reset),
@@ -814,6 +848,7 @@ static char ui_xml[] =
" <menu action='VMMenu'>"
" <menuitem action='MonitorStop'/>"
" <menuitem action='MonitorCont'/>"
+" <menuitem action='MonitorSaveToDisk'/>"
" <menuitem action='MonitorSysPowerdown'/>"
" <separator/>"
" <menuitem action='MonitorSysReset'/>"
@@ -982,6 +1017,8 @@ void qemu_conn_tab(struct qemu_window *win, struct qemu_conn *conn, int pos)
conn->vte = vte_terminal_new();
g_signal_connect(conn->vte, "commit",
G_CALLBACK(conn_user_input), conn);
+ g_signal_connect(conn->vte, "destroy",
+ G_CALLBACK(conn_vte_destroy), conn);
tabs_add(win, conn->vte, conn->name, pos);
vte_configure(win, conn->vte);
}
@@ -1003,6 +1040,7 @@ static void usage(FILE *fp)
" -m Enable monitor logging and access.\n"
" -s Enable serial console.\n"
" -t Disable VNC, enable serial console.\n"
+ " -i <file> Image file for \"vm save\".\n"
"\n"
"-- \n"
"(c) 2008 Gerd Hoffmann <kraxel@redhat.com>\n",
@@ -1039,6 +1077,7 @@ int
main(int argc, char *argv[])
{
struct qemu_window *win;
+ char *image = NULL;
char mon[256];
int monitor_tab = 0;
int sercon_tab = 0;
@@ -1048,7 +1087,7 @@ main(int argc, char *argv[])
gtk_init(&argc, &argv);
for (;;) {
- if (-1 == (c = getopt(argc, argv, "hdkmst")))
+ if (-1 == (c = getopt(argc, argv, "hdkmsti:")))
break;
switch (c) {
case 'd':
@@ -1067,6 +1106,9 @@ main(int argc, char *argv[])
vnc_tab = 0;
sercon_tab = 1;
break;
+ case 'i':
+ image = optarg;
+ break;
case 'h':
usage(stdout);
exit(0);
@@ -1093,6 +1135,7 @@ main(int argc, char *argv[])
win->quit_on_shutdown = quit_on_shutdown;
win->sercon_tab = sercon_tab;
win->vnc_tab = vnc_tab;
+ win->image_save = image;
gtk_widget_show_all(win->toplevel);
/* tabs */