From a45d0183563fb3bb3b08d5d0a8ffcc5205d40a9b Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 26 Jan 2016 15:34:09 +0000 Subject: [PATCH] p2v: User can click on an interface name to identify the physical interface. When the user clicks on the second column of the list of network interfaces, run 'ethtool --identify 10', which (on supported cards) flashes a light on the physical interface for 10 seconds, allowing it to be identified by the operator. (cherry picked from commit 81ff8c5d23642667569833cd820e84814157580b) --- p2v/gui.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- p2v/virt-p2v.pod | 4 ++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/p2v/gui.c b/p2v/gui.c index c345e34..569a295 100644 --- a/p2v/gui.c +++ b/p2v/gui.c @@ -418,6 +418,7 @@ static void populate_removable (GtkTreeView *removable_list); static void populate_interfaces (GtkTreeView *interfaces_list); static void toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data); static void network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, gchar *new_text, gpointer data); +static gboolean maybe_identify_click (GtkWidget *interfaces_list, GdkEventButton *event, gpointer data); static void set_disks_from_ui (struct config *); static void set_removable_from_ui (struct config *); static void set_interfaces_from_ui (struct config *); @@ -653,6 +654,10 @@ create_conversion_dialog (struct config *config) gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (interfaces_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); interfaces_list = gtk_tree_view_new (); + /* See maybe_identify_click below for what we're doing. */ + g_signal_connect (interfaces_list, "button-press-event", + G_CALLBACK (maybe_identify_click), NULL); + gtk_widget_set_tooltip_markup (interfaces_list, _("Left click on an interface name to flash the light on the physical interface.")); populate_interfaces (GTK_TREE_VIEW (interfaces_list)); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (interfaces_sw), interfaces_list); @@ -944,7 +949,8 @@ populate_interfaces (GtkTreeView *interfaces_list) "" "%s\n" "%s" - "", + "\n" + "Identify interface", if_name, if_addr ? : _("Unknown"), if_vendor ? : _("Unknown")) == -1) { @@ -1034,6 +1040,68 @@ network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, gtk_tree_path_free (path); } +/* When the user clicks on the interface name on the list of + * interfaces, we want to run 'ethtool --identify', which usually + * makes some lights flash on the physical interface. We cannot catch + * clicks on the cell itself, so we have to go via a more obscure + * route. See http://stackoverflow.com/a/27207433 and + * https://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Events + */ +static gboolean +maybe_identify_click (GtkWidget *interfaces_list, GdkEventButton *event, + gpointer data) +{ + gboolean ret = FALSE; /* Did we handle this event? */ + + /* Single left click only. */ + if (event->type == GDK_BUTTON_PRESS && event->button == 1) { + GtkTreePath *path; + GtkTreeViewColumn *column; + + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (interfaces_list), + event->x, event->y, + &path, &column, NULL, NULL)) { + GList *cols; + gint column_index; + + /* Get column index. */ + cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (interfaces_list)); + column_index = g_list_index (cols, (gpointer) column); + g_list_free (cols); + + if (column_index == INTERFACES_COL_DEVICE) { + const gint *indices; + gint row_index; + const char *if_name; + char *cmd; + + /* Get the row index. */ + indices = gtk_tree_path_get_indices (path); + row_index = indices[0]; + + /* And the interface name. */ + if_name = all_interfaces[row_index]; + + /* Issue the ethtool command in the background. */ + if (asprintf (&cmd, "ethtool --identify '%s' 10 &", if_name) == -1) { + perror ("asprintf"); + exit (EXIT_FAILURE); + } + printf ("%s\n", cmd); + ignore_value (system (cmd)); + + free (cmd); + + ret = TRUE; /* We handled this event. */ + } + + gtk_tree_path_free (path); + } + } + + return ret; +} + static void set_from_ui_generic (char **all, char ***ret, GtkTreeView *list) { diff --git a/p2v/virt-p2v.pod b/p2v/virt-p2v.pod index a3987f4..3e4ef99 100644 --- a/p2v/virt-p2v.pod +++ b/p2v/virt-p2v.pod @@ -232,6 +232,10 @@ should be created in the guest after conversion. You can also connect these to target hypervisor networks (for further information about this feature, see L). +On supported hardware, left-clicking on the device name (eg. C) +causes a light to start flashing on the physical interface, allowing +the interface to be identified by the operator. + When you are ready to begin the conversion, press the C button: -- 1.8.3.1