[Libguestfs] [PATCH] New API: part_get_disk_guid and part_set_disk_guid.

Maxim Perevedentsev mperevedentsev at virtuozzo.com
Mon Jan 18 16:29:58 UTC 2016


Some OSes (e.g. Windows Server 2012 R2) fail to boot if the disk
GPT GUID has changed. To preserve disk GUID e.g. during virt-resize,
we need a way to get/set disk GUIDs.
---
 daemon/parted.c      | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/actions.ml | 37 ++++++++++++++++++++++++++++++++
 src/MAX_PROC_NR      |  2 +-
 3 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/daemon/parted.c b/daemon/parted.c
index b073bd8..40f9676 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -928,3 +928,63 @@ do_part_get_mbr_part_type (const char *device, int partnum)
   reply_with_error ("strdup failed");
   return NULL;
 }
+
+char *
+do_part_get_disk_guid (const char *device)
+{
+  const char *pattern = "Disk identifier (GUID):";
+  size_t i;
+
+  CLEANUP_FREE char *err = NULL;
+  int r = commandf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
+                    str_sgdisk, device, "-p", NULL);
+  if (r == -1) {
+    reply_with_error ("%s %s -p: %s", str_sgdisk, device, err);
+    return NULL;
+  }
+
+  CLEANUP_FREE_STRING_LIST char **lines = split_lines (err);
+  if (lines == NULL) {
+    reply_with_error ("'%s %s -p' returned no output",
+                      str_sgdisk, device);
+    return NULL;
+  }
+
+  for (i = 0; lines[i] != NULL; ++i) {
+    if (STRPREFIX (lines[i], pattern)) {
+      char *value = lines[i] + strlen (pattern);
+
+      /* Skip any leading whitespace */
+      value += strspn (value, " \t");
+
+      /* Extract the actual information from the field. */
+      char *ret = extract_uuid (value);
+      if (ret == NULL) {
+        /* The extraction function already sends the error. */
+        return NULL;
+      }
+
+      return ret;
+    }
+  }
+
+  /* If we got here it means we didn't find the field */
+  reply_with_error ("sgdisk output did not contain disk GUID. "
+                    "See LIBGUESTFS_DEBUG output for more details");
+  return NULL;
+}
+
+int
+do_part_set_disk_guid (const char *device, const char *guid)
+{
+  CLEANUP_FREE char *err = NULL;
+  int r = commandf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
+                    str_sgdisk, device, "-U", guid, NULL);
+
+  if (r == -1) {
+    reply_with_error ("%s %s -U %s: %s", str_sgdisk, device, guid, err);
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 7f8e80b..62c4839 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12793,6 +12793,43 @@ See also L<ntfsresize(8)>, L<resize2fs(8)>, L<btrfs(8)>, L<xfs_info(8)>." };
     longdesc = "\
 This is the internal call which implements C<guestfs_feature_available>." };

+  { defaults with
+    name = "part_set_disk_guid"; added = (1, 33, 2);
+    style = RErr, [Device "device"; GUID "guid"], [];
+    proc_nr = Some 459;
+    optional = Some "gdisk";
+    tests = [
+      InitGPT, Always, TestLastFail (
+        [["part_set_disk_guid"; "/dev/sda"; "f"]]), [];
+      InitGPT, Always, TestResultString (
+        [["part_set_disk_guid"; "/dev/sda";
+          "01234567-89AB-CDEF-0123-456789ABCDEF"];
+         ["part_get_disk_guid"; "/dev/sda"]],
+        "01234567-89AB-CDEF-0123-456789ABCDEF"), [];
+    ];
+    shortdesc = "set the GUID of a GPT-partitioned disk";
+    longdesc = "\
+Set the disk identifier (GUID) of a GPT-partitioned C<device> to C<guid>.
+Return an error if the partition table of C<device> isn't GPT,
+or if C<guid> is not a valid GUID." };
+
+  { defaults with
+    name = "part_get_disk_guid"; added = (1, 33, 2);
+    style = RString "guid", [Device "device"], [];
+    proc_nr = Some 460;
+    optional = Some "gdisk";
+    tests = [
+      InitGPT, Always, TestResultString (
+        [["part_set_disk_guid"; "/dev/sda";
+          "01234567-89AB-CDEF-0123-456789ABCDEF"];
+         ["part_get_disk_guid"; "/dev/sda"]],
+        "01234567-89AB-CDEF-0123-456789ABCDEF"), [];
+    ];
+    shortdesc = "get the GUID of a GPT-partitioned disk";
+    longdesc = "\
+Return the disk identifier (GUID) of a GPT-partitioned C<device>.
+Behaviour is undefined for other partition types." };
+
 ]

 (* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index c92ddb6..ccbd68f 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-458
+460
--
1.8.3.1




More information about the Libguestfs mailing list