|
|
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 |
|