Blame SOURCES/0174-p2v-Display-network-card-MAC-address-and-vendor-in-c.patch

ffd6ed
From 41880930360b38de1390b9ff5b36a459ff153c27 Mon Sep 17 00:00:00 2001
ffd6ed
From: "Richard W.M. Jones" <rjones@redhat.com>
ffd6ed
Date: Thu, 14 May 2015 13:57:41 +0100
ffd6ed
Subject: [PATCH] p2v: Display network card MAC address and vendor in
ffd6ed
 conversion dialog (RHBZ#855059).
ffd6ed
ffd6ed
This displays the MAC address and vendor next to each network
ffd6ed
interface, aiding users in determining which network cards they want
ffd6ed
to transfer to the virtualized machine.
ffd6ed
ffd6ed
(cherry picked from commit 0833c192b68e87bb10fecf8352a355474c3915bf)
ffd6ed
---
ffd6ed
 p2v/Makefile.am           |   3 +-
ffd6ed
 p2v/gui.c                 |  27 ++++++++-
ffd6ed
 p2v/p2v.h                 |   4 ++
ffd6ed
 p2v/p2v.ks.in             |   1 +
ffd6ed
 p2v/utils.c               | 136 ++++++++++++++++++++++++++++++++++++++++++++++
ffd6ed
 p2v/virt-p2v-make-disk.in |   8 +--
ffd6ed
 po/POTFILES               |   1 +
ffd6ed
 7 files changed, 172 insertions(+), 8 deletions(-)
ffd6ed
 create mode 100644 p2v/utils.c
ffd6ed
ffd6ed
diff --git a/p2v/Makefile.am b/p2v/Makefile.am
ffd6ed
index cafad0b..c9d6b6f 100644
ffd6ed
--- a/p2v/Makefile.am
ffd6ed
+++ b/p2v/Makefile.am
ffd6ed
@@ -53,7 +53,8 @@ virt_p2v_SOURCES = \
ffd6ed
 	miniexpect.c \
ffd6ed
 	miniexpect.h \
ffd6ed
 	p2v.h \
ffd6ed
-	ssh.c
ffd6ed
+	ssh.c \
ffd6ed
+	utils.c
ffd6ed
 
ffd6ed
 virt_p2v_CPPFLAGS = \
ffd6ed
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
ffd6ed
diff --git a/p2v/gui.c b/p2v/gui.c
ffd6ed
index 43d6165..c0079aa 100644
ffd6ed
--- a/p2v/gui.c
ffd6ed
+++ b/p2v/gui.c
ffd6ed
@@ -436,7 +436,7 @@ create_conversion_dialog (struct config *config)
ffd6ed
   /* XXX It would be nice not to have to set this explicitly, but
ffd6ed
    * if we don't then Gtk chooses a very small window.
ffd6ed
    */
ffd6ed
-  gtk_widget_set_size_request (conv_dlg, 800, 560);
ffd6ed
+  gtk_widget_set_size_request (conv_dlg, 900, 560);
ffd6ed
 
ffd6ed
   /* The main dialog area. */
ffd6ed
   hbox = gtk_hbox_new (TRUE, 1);
ffd6ed
@@ -891,6 +891,24 @@ populate_interfaces (GtkTreeView *interfaces_list)
ffd6ed
                                          G_TYPE_STRING);
ffd6ed
   if (all_interfaces) {
ffd6ed
     for (i = 0; all_interfaces[i] != NULL; ++i) {
ffd6ed
+      const char *if_name = all_interfaces[i];
ffd6ed
+      CLEANUP_FREE char *device_descr = NULL;
ffd6ed
+      CLEANUP_FREE char *if_addr = get_if_addr (if_name);
ffd6ed
+      CLEANUP_FREE char *if_vendor = get_if_vendor (if_name, 40);
ffd6ed
+
ffd6ed
+      if (asprintf (&device_descr,
ffd6ed
+                    "%s\n"
ffd6ed
+                    "<small>"
ffd6ed
+                    "%s\n"
ffd6ed
+                    "%s"
ffd6ed
+                    "</small>",
ffd6ed
+                    if_name,
ffd6ed
+                    if_addr ? : _("Unknown"),
ffd6ed
+                    if_vendor ? : _("Unknown")) == -1) {
ffd6ed
+        perror ("asprintf");
ffd6ed
+        exit (EXIT_FAILURE);
ffd6ed
+      }
ffd6ed
+
ffd6ed
       gtk_list_store_append (interfaces_store, &iter);
ffd6ed
       gtk_list_store_set (interfaces_store, &iter,
ffd6ed
                           /* Only convert the first interface.  As
ffd6ed
@@ -898,7 +916,7 @@ populate_interfaces (GtkTreeView *interfaces_list)
ffd6ed
                            * physical interface.
ffd6ed
                            */
ffd6ed
                           INTERFACES_COL_CONVERT, i == 0,
ffd6ed
-                          INTERFACES_COL_DEVICE, all_interfaces[i],
ffd6ed
+                          INTERFACES_COL_DEVICE, device_descr,
ffd6ed
                           INTERFACES_COL_NETWORK, "default",
ffd6ed
                           -1);
ffd6ed
     }
ffd6ed
@@ -913,13 +931,15 @@ populate_interfaces (GtkTreeView *interfaces_list)
ffd6ed
                                                interfaces_col_convert,
ffd6ed
                                                "active", INTERFACES_COL_CONVERT,
ffd6ed
                                                NULL);
ffd6ed
+  gtk_cell_renderer_set_alignment (interfaces_col_convert, 0.5, 0.0);
ffd6ed
   interfaces_col_device = gtk_cell_renderer_text_new ();
ffd6ed
   gtk_tree_view_insert_column_with_attributes (interfaces_list,
ffd6ed
                                                -1,
ffd6ed
                                                _("Device"),
ffd6ed
                                                interfaces_col_device,
ffd6ed
-                                               "text", INTERFACES_COL_DEVICE,
ffd6ed
+                                               "markup", INTERFACES_COL_DEVICE,
ffd6ed
                                                NULL);
ffd6ed
+  gtk_cell_renderer_set_alignment (interfaces_col_device, 0.5, 0.0);
ffd6ed
   interfaces_col_network = gtk_cell_renderer_text_new ();
ffd6ed
   gtk_tree_view_insert_column_with_attributes (interfaces_list,
ffd6ed
                                                -1,
ffd6ed
@@ -927,6 +947,7 @@ populate_interfaces (GtkTreeView *interfaces_list)
ffd6ed
                                                interfaces_col_network,
ffd6ed
                                                "text", INTERFACES_COL_NETWORK,
ffd6ed
                                                NULL);
ffd6ed
+  gtk_cell_renderer_set_alignment (interfaces_col_network, 0.5, 0.0);
ffd6ed
 
ffd6ed
   g_signal_connect (interfaces_col_convert, "toggled",
ffd6ed
                     G_CALLBACK (toggled), interfaces_store);
ffd6ed
diff --git a/p2v/p2v.h b/p2v/p2v.h
ffd6ed
index c3ca0f6..c5427a7 100644
ffd6ed
--- a/p2v/p2v.h
ffd6ed
+++ b/p2v/p2v.h
ffd6ed
@@ -105,6 +105,10 @@ extern mexp_h *open_data_connection (struct config *, int *local_port, int *remo
ffd6ed
 extern mexp_h *start_remote_connection (struct config *, const char *remote_dir, const char *libvirt_xml);
ffd6ed
 extern const char *get_ssh_error (void);
ffd6ed
 
ffd6ed
+/* utils.c */
ffd6ed
+extern char *get_if_addr (const char *if_name);
ffd6ed
+extern char *get_if_vendor (const char *if_name, int truncate);
ffd6ed
+
ffd6ed
 /* virt-v2v version and features (read from remote). */
ffd6ed
 extern int v2v_major;
ffd6ed
 extern int v2v_minor;
ffd6ed
diff --git a/p2v/p2v.ks.in b/p2v/p2v.ks.in
ffd6ed
index 3ff6784..2319781 100644
ffd6ed
--- a/p2v/p2v.ks.in
ffd6ed
+++ b/p2v/p2v.ks.in
ffd6ed
@@ -72,6 +72,7 @@ libxml2
ffd6ed
 gtk2
ffd6ed
 network-manager-applet
ffd6ed
 dbus-x11
ffd6ed
+hwdata
ffd6ed
 @hardware-support --optional
ffd6ed
 
ffd6ed
 %end
ffd6ed
diff --git a/p2v/utils.c b/p2v/utils.c
ffd6ed
new file mode 100644
ffd6ed
index 0000000..0b30be3
ffd6ed
--- /dev/null
ffd6ed
+++ b/p2v/utils.c
ffd6ed
@@ -0,0 +1,136 @@
ffd6ed
+/* virt-p2v
ffd6ed
+ * Copyright (C) 2015 Red Hat Inc.
ffd6ed
+ *
ffd6ed
+ * This program is free software; you can redistribute it and/or modify
ffd6ed
+ * it under the terms of the GNU General Public License as published by
ffd6ed
+ * the Free Software Foundation; either version 2 of the License, or
ffd6ed
+ * (at your option) any later version.
ffd6ed
+ *
ffd6ed
+ * This program is distributed in the hope that it will be useful,
ffd6ed
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
ffd6ed
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ffd6ed
+ * GNU General Public License for more details.
ffd6ed
+ *
ffd6ed
+ * You should have received a copy of the GNU General Public License
ffd6ed
+ * along with this program; if not, write to the Free Software
ffd6ed
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ffd6ed
+ */
ffd6ed
+
ffd6ed
+#include <config.h>
ffd6ed
+
ffd6ed
+#include <stdio.h>
ffd6ed
+#include <stdlib.h>
ffd6ed
+#include <string.h>
ffd6ed
+#include <ctype.h>
ffd6ed
+#include <unistd.h>
ffd6ed
+#include <locale.h>
ffd6ed
+#include <libintl.h>
ffd6ed
+
ffd6ed
+#include "p2v.h"
ffd6ed
+
ffd6ed
+#define CHOMP(line,len)                         \
ffd6ed
+  do {                                          \
ffd6ed
+    if ((len) > 0 && (line)[(len)-1] == '\n') { \
ffd6ed
+      (line)[(len)-1] = '\0';                   \
ffd6ed
+      len--;                                    \
ffd6ed
+    }                                           \
ffd6ed
+  } while (0)
ffd6ed
+
ffd6ed
+/* Return contents of /sys/class/net/<if_name>/address (if found). */
ffd6ed
+char *
ffd6ed
+get_if_addr (const char *if_name)
ffd6ed
+{
ffd6ed
+  CLEANUP_FCLOSE FILE *fp = NULL;
ffd6ed
+  CLEANUP_FREE char *path = NULL;
ffd6ed
+  char *content = NULL;
ffd6ed
+  size_t len = 0;
ffd6ed
+  ssize_t n;
ffd6ed
+
ffd6ed
+  if (asprintf (&path, "/sys/class/net/%s/address", if_name) == -1) {
ffd6ed
+    perror ("asprintf");
ffd6ed
+    exit (EXIT_FAILURE);
ffd6ed
+  }
ffd6ed
+  fp = fopen (path, "r");
ffd6ed
+  if (fp == NULL)
ffd6ed
+    return NULL;
ffd6ed
+  if ((n = getline (&content, &len, fp)) == -1) {
ffd6ed
+    perror (path);
ffd6ed
+    free (content);
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+  CHOMP (content, n);
ffd6ed
+  return content;
ffd6ed
+}
ffd6ed
+
ffd6ed
+/* Return contents of /sys/class/net/<if_name>/device/vendor (if found),
ffd6ed
+ * mapped to the PCI vendor.  See:
ffd6ed
+ * http://pjwelsh.blogspot.co.uk/2011/11/howto-get-network-card-vendor-device-or.html
ffd6ed
+ */
ffd6ed
+char *
ffd6ed
+get_if_vendor (const char *if_name, int truncate)
ffd6ed
+{
ffd6ed
+  CLEANUP_FCLOSE FILE *fp = NULL;
ffd6ed
+  CLEANUP_FREE char *path = NULL;
ffd6ed
+  char *line = NULL;
ffd6ed
+  size_t len = 0;
ffd6ed
+  ssize_t n;
ffd6ed
+  char vendor[5];
ffd6ed
+
ffd6ed
+  if (asprintf (&path, "/sys/class/net/%s/device/vendor", if_name) == -1) {
ffd6ed
+    perror ("asprintf");
ffd6ed
+    exit (EXIT_FAILURE);
ffd6ed
+  }
ffd6ed
+  fp = fopen (path, "r");
ffd6ed
+  if (fp == NULL) {
ffd6ed
+    perror (path);
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+  if ((n = getline (&line, &len, fp)) == -1) {
ffd6ed
+    perror (path);
ffd6ed
+    free (line);
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  /* Vendor is (always?) a 16 bit quantity (as defined by PCI),
ffd6ed
+   * something like "0x8086" (for Intel Corp).
ffd6ed
+   */
ffd6ed
+  CHOMP (line, n);
ffd6ed
+  if (line[0] != '0' || line[1] != 'x' || strlen (&line[2]) != 4) {
ffd6ed
+    free (line);
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  strcpy (vendor, &line[2]);
ffd6ed
+
ffd6ed
+  fclose (fp);
ffd6ed
+  fp = fopen ("/usr/share/hwdata/pci.ids", "r");
ffd6ed
+  if (fp == NULL) {
ffd6ed
+    perror ("/usr/share/hwdata/pci.ids");
ffd6ed
+    free (line);
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+  while ((n = getline (&line, &len, fp)) != -1) {
ffd6ed
+    CHOMP (line, n);
ffd6ed
+    if (STRPREFIX (line, vendor)) {
ffd6ed
+      /* Find the start of the name after the vendor ID and whitespace. */
ffd6ed
+      size_t i = 4;
ffd6ed
+      n -= 4;
ffd6ed
+
ffd6ed
+      while (n > 0 && isspace (line[i])) {
ffd6ed
+        i++;
ffd6ed
+        n--;
ffd6ed
+      }
ffd6ed
+
ffd6ed
+      memmove (&line[0], &line[i], n+1 /* copy trailing \0 */);
ffd6ed
+
ffd6ed
+      /* Truncate? */
ffd6ed
+      if (truncate > 0 && n > truncate)
ffd6ed
+        line[n] = '\0';
ffd6ed
+
ffd6ed
+      return line;
ffd6ed
+    }
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  free (line);
ffd6ed
+  return NULL;
ffd6ed
+}
ffd6ed
diff --git a/p2v/virt-p2v-make-disk.in b/p2v/virt-p2v-make-disk.in
ffd6ed
index e2ea7f5..6d7dcb2 100644
ffd6ed
--- a/p2v/virt-p2v-make-disk.in
ffd6ed
+++ b/p2v/virt-p2v-make-disk.in
ffd6ed
@@ -102,7 +102,7 @@ trap cleanup INT QUIT TERM EXIT ERR
ffd6ed
 # Note that libguestfs is NOT a dependency.
ffd6ed
 case "$osversion" in
ffd6ed
     centos-*|fedora-*|rhel-*|scientificlinux-*)
ffd6ed
-        deps=pcre,libxml2,gtk2,/usr/bin/xinit,/usr/bin/ssh,/usr/bin/qemu-nbd,/usr/bin/Xorg,xorg-x11-drivers,xorg-x11-fonts-Type1,metacity,NetworkManager,network-manager-applet,dbus-x11,@hardware-support
ffd6ed
+        deps=pcre,libxml2,gtk2,/usr/bin/xinit,/usr/bin/ssh,/usr/bin/qemu-nbd,/usr/bin/Xorg,xorg-x11-drivers,xorg-x11-fonts-Type1,metacity,NetworkManager,network-manager-applet,dbus-x11,hwdata,@hardware-support
ffd6ed
         cat > $tmpdir/p2v.conf <<'EOF'
ffd6ed
 add_drivers+=" usb-storage "
ffd6ed
 EOF
ffd6ed
@@ -120,13 +120,13 @@ EOF
ffd6ed
         "
ffd6ed
         ;;
ffd6ed
     debian-*|ubuntu-*)
ffd6ed
-        deps=libpcre3,libxml2,libgtk2.0-0,openssh-client,qemu-utils,xorg,xserver-xorg-video-all,metacity,network-manager,network-manager-applet,dbus-x11
ffd6ed
+        deps=libpcre3,libxml2,libgtk2.0-0,openssh-client,qemu-utils,xorg,xserver-xorg-video-all,metacity,network-manager,network-manager-applet,dbus-x11,hwdata
ffd6ed
         ;;
ffd6ed
     archlinux-*)
ffd6ed
-        deps=pcre,libxml2,gtk2,openssh,qemu,xorg-xinit,xorg-server,xf86-video-*,metacity,NetworkManager,network-manager-applet,dbus-x11
ffd6ed
+        deps=pcre,libxml2,gtk2,openssh,qemu,xorg-xinit,xorg-server,xf86-video-*,metacity,NetworkManager,network-manager-applet,dbus-x11,hwdata
ffd6ed
         ;;
ffd6ed
     opensuse-*|suse-*)
ffd6ed
-        deps=pcre,libxml2,gtk2,/usr/bin/ssh,/usr/bin/qemu-nbd,/usr/bin/xinit,/usr/bin/Xorg,xf86-video-*,metacity,NetworkManager,network-manager-applet,dbus-x11
ffd6ed
+        deps=pcre,libxml2,gtk2,/usr/bin/ssh,/usr/bin/qemu-nbd,/usr/bin/xinit,/usr/bin/Xorg,xf86-video-*,metacity,NetworkManager,network-manager-applet,dbus-x11,hwdata
ffd6ed
         ;;
ffd6ed
     *)
ffd6ed
         echo "$program: internal error: could not work out the Linux distro from '$osversion'"
ffd6ed
diff --git a/po/POTFILES b/po/POTFILES
ffd6ed
index 7f3365c..c64afda 100644
ffd6ed
--- a/po/POTFILES
ffd6ed
+++ b/po/POTFILES
ffd6ed
@@ -263,6 +263,7 @@ p2v/kernel.c
ffd6ed
 p2v/main.c
ffd6ed
 p2v/miniexpect.c
ffd6ed
 p2v/ssh.c
ffd6ed
+p2v/utils.c
ffd6ed
 perl/Guestfs.c
ffd6ed
 perl/bindtests.pl
ffd6ed
 perl/lib/Sys/Guestfs.pm
ffd6ed
-- 
ffd6ed
1.8.3.1
ffd6ed