Blame SOURCES/0133-p2v-Refactor-into-get_blockdev_size-and-get_blockdev.patch

e76f14
From a9d9b7d3cf9fa9928498273974830e9ba2002e5f Mon Sep 17 00:00:00 2001
e76f14
From: "Richard W.M. Jones" <rjones@redhat.com>
e76f14
Date: Fri, 24 Jun 2016 14:45:05 +0100
e76f14
Subject: [PATCH] p2v: Refactor into get_blockdev_size and get_blockdev_model
e76f14
 functions.
e76f14
e76f14
This is just refactoring, but it reveals and fixes a bug too.  The
e76f14
size_gb field was left as NULL when the --test-disk option was used.
e76f14
Apparently passing NULL to gtk_list_store_set is fine, but just in
e76f14
case I replaced it with "".
e76f14
e76f14
(cherry picked from commit 68ff3ffd1de7b72255ee5098c0bfef90e6236cb5)
e76f14
---
e76f14
 p2v/gui.c   | 40 ++++++++-----------------------------
e76f14
 p2v/p2v.h   |  2 ++
e76f14
 p2v/utils.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
e76f14
 3 files changed, 75 insertions(+), 32 deletions(-)
e76f14
e76f14
diff --git a/p2v/gui.c b/p2v/gui.c
e76f14
index 7414037..1bae4d8 100644
e76f14
--- a/p2v/gui.c
e76f14
+++ b/p2v/gui.c
e76f14
@@ -869,47 +869,23 @@ populate_disks (GtkTreeView *disks_list)
e76f14
                                     G_TYPE_STRING, G_TYPE_STRING);
e76f14
   if (all_disks != NULL) {
e76f14
     for (i = 0; all_disks[i] != NULL; ++i) {
e76f14
-      CLEANUP_FREE char *size_filename = NULL;
e76f14
-      CLEANUP_FREE char *model_filename = NULL;
e76f14
-      CLEANUP_FREE char *size_str = NULL;
e76f14
+      uint64_t size;
e76f14
       CLEANUP_FREE char *size_gb = NULL;
e76f14
       CLEANUP_FREE char *model = NULL;
e76f14
-      uint64_t size;
e76f14
 
e76f14
-      if (asprintf (&size_filename, "/sys/block/%s/size",
e76f14
-                    all_disks[i]) == -1) {
e76f14
-        perror ("asprintf");
e76f14
-        exit (EXIT_FAILURE);
e76f14
-      }
e76f14
-      if (g_file_get_contents (size_filename, &size_str, NULL, NULL) &&
e76f14
-          sscanf (size_str, "%" SCNu64, &size) == 1) {
e76f14
-        size /= 2*1024*1024; /* size from kernel is given in sectors? */
e76f14
-        if (asprintf (&size_gb, "%" PRIu64, size) == -1) {
e76f14
-          perror ("asprintf");
e76f14
-          exit (EXIT_FAILURE);
e76f14
-        }
e76f14
-      }
e76f14
-
e76f14
-      if (asprintf (&model_filename, "/sys/block/%s/device/model",
e76f14
-                    all_disks[i]) == -1) {
e76f14
-        perror ("asprintf");
e76f14
-        exit (EXIT_FAILURE);
e76f14
-      }
e76f14
-      if (g_file_get_contents (model_filename, &model, NULL, NULL)) {
e76f14
-        /* Need to chomp trailing \n from the content. */
e76f14
-        size_t len = strlen (model);
e76f14
-        if (len > 0 && model[len-1] == '\n')
e76f14
-          model[len-1] = '\0';
e76f14
-      } else {
e76f14
-        model = strdup ("");
e76f14
+      if (all_disks[i][0] != '/') { /* not using --test-disk */
e76f14
+        size = get_blockdev_size (all_disks[i]);
e76f14
+        if (asprintf (&size_gb, "%" PRIu64, size) == -1)
e76f14
+          error (EXIT_FAILURE, errno, "asprintf");
e76f14
+        model = get_blockdev_model (all_disks[i]);
e76f14
       }
e76f14
 
e76f14
       gtk_list_store_append (disks_store, &iter);
e76f14
       gtk_list_store_set (disks_store, &iter,
e76f14
                           DISKS_COL_CONVERT, TRUE,
e76f14
                           DISKS_COL_DEVICE, all_disks[i],
e76f14
-                          DISKS_COL_SIZE, size_gb,
e76f14
-                          DISKS_COL_MODEL, model,
e76f14
+                          DISKS_COL_SIZE, size_gb ? size_gb : "",
e76f14
+                          DISKS_COL_MODEL, model ? model : "",
e76f14
                           -1);
e76f14
     }
e76f14
   }
e76f14
diff --git a/p2v/p2v.h b/p2v/p2v.h
e76f14
index 49c97b6..40b05b8 100644
e76f14
--- a/p2v/p2v.h
e76f14
+++ b/p2v/p2v.h
e76f14
@@ -131,6 +131,8 @@ extern mexp_h *start_remote_connection (struct config *, const char *remote_dir,
e76f14
 extern const char *get_ssh_error (void);
e76f14
 
e76f14
 /* utils.c */
e76f14
+extern uint64_t get_blockdev_size (const char *dev);
e76f14
+extern char *get_blockdev_model (const char *dev);
e76f14
 extern char *get_if_addr (const char *if_name);
e76f14
 extern char *get_if_vendor (const char *if_name, int truncate);
e76f14
 extern void wait_network_online (const struct config *);
e76f14
diff --git a/p2v/utils.c b/p2v/utils.c
e76f14
index 3781a8d..18c2b7c 100644
e76f14
--- a/p2v/utils.c
e76f14
+++ b/p2v/utils.c
e76f14
@@ -20,9 +20,12 @@
e76f14
 
e76f14
 #include <stdio.h>
e76f14
 #include <stdlib.h>
e76f14
+#include <inttypes.h>
e76f14
 #include <string.h>
e76f14
 #include <ctype.h>
e76f14
 #include <unistd.h>
e76f14
+#include <errno.h>
e76f14
+#include <error.h>
e76f14
 #include <locale.h>
e76f14
 #include <libintl.h>
e76f14
 
e76f14
@@ -38,6 +41,68 @@
e76f14
     }                                           \
e76f14
   } while (0)
e76f14
 
e76f14
+/**
e76f14
+ * Return size of a block device, from F</sys/block/I<dev>/size>.
e76f14
+ *
e76f14
+ * This function always succeeds, or else exits (since we expect
e76f14
+ * C<dev> to always be valid and the C<size> file to always exist).
e76f14
+ */
e76f14
+uint64_t
e76f14
+get_blockdev_size (const char *dev)
e76f14
+{
e76f14
+  CLEANUP_FCLOSE FILE *fp = NULL;
e76f14
+  CLEANUP_FREE char *path = NULL;
e76f14
+  CLEANUP_FREE char *size_str = NULL;
e76f14
+  size_t len;
e76f14
+  uint64_t size;
e76f14
+
e76f14
+  if (asprintf (&path, "/sys/block/%s/size", dev) == -1)
e76f14
+    error (EXIT_FAILURE, errno, "asprintf");
e76f14
+
e76f14
+  fp = fopen (path, "r");
e76f14
+  if (fp == NULL)
e76f14
+    error (EXIT_FAILURE, errno, "fopen: %s", path);
e76f14
+  if (getline (&size_str, &len, fp) == -1)
e76f14
+    error (EXIT_FAILURE, errno, "getline: %s", path);
e76f14
+
e76f14
+  if (sscanf (size_str, "%" SCNu64, &size) != 1)
e76f14
+    error (EXIT_FAILURE, 0, "cannot parse %s: %s", path, size_str);
e76f14
+
e76f14
+  size /= 2*1024*1024;     /* size from kernel is given in sectors? */
e76f14
+  return size;
e76f14
+}
e76f14
+
e76f14
+/**
e76f14
+ * Return model of a block device, from F</sys/block/I<dev>/device/model>.
e76f14
+ *
e76f14
+ * Returns C<NULL> if the file was not found.  The caller must
e76f14
+ * free the returned string.
e76f14
+ */
e76f14
+char *
e76f14
+get_blockdev_model (const char *dev)
e76f14
+{
e76f14
+  CLEANUP_FCLOSE FILE *fp = NULL;
e76f14
+  CLEANUP_FREE char *path = NULL;
e76f14
+  char *model = NULL;
e76f14
+  size_t len = 0;
e76f14
+  ssize_t n;
e76f14
+
e76f14
+  if (asprintf (&path, "/sys/block/%s/device/model", dev) == -1)
e76f14
+    error (EXIT_FAILURE, errno, "asprintf");
e76f14
+  fp = fopen (path, "r");
e76f14
+  if (fp == NULL) {
e76f14
+    perror (path);
e76f14
+    return NULL;
e76f14
+  }
e76f14
+  if ((n = getline (&model, &len, fp)) == -1) {
e76f14
+    perror (path);
e76f14
+    free (model);
e76f14
+    return NULL;
e76f14
+  }
e76f14
+  CHOMP (model, n);
e76f14
+  return model;
e76f14
+}
e76f14
+
e76f14
 /* Return contents of /sys/class/net/<if_name>/address (if found). */
e76f14
 char *
e76f14
 get_if_addr (const char *if_name)
e76f14
-- 
e76f14
1.8.3.1
e76f14