diff options
Diffstat (limited to 'qemu-gtk.c')
-rw-r--r-- | qemu-gtk.c | 53 |
1 files changed, 48 insertions, 5 deletions
@@ -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 */ |