summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemon/lvm.c88
-rw-r--r--generator/generator_actions.ml10
-rw-r--r--src/MAX_PROC_NR2
3 files changed, 99 insertions, 1 deletions
diff --git a/daemon/lvm.c b/daemon/lvm.c
index 9103a33d..06fdbff0 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -23,6 +23,7 @@
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -872,3 +873,90 @@ do_list_dm_devices (void)
return ret.argv;
}
+
+char *
+do_vgmeta (const char *vg, size_t *size_r)
+{
+ char *err;
+ int fd, r;
+ char tmp[] = "/tmp/vgmetaXXXXXX";
+ size_t alloc, size, max;
+ ssize_t rs;
+ char *buf, *buf2;
+
+ /* Make a temporary file. */
+ fd = mkstemp (tmp);
+ if (fd == -1) {
+ reply_with_perror ("mkstemp");
+ return NULL;
+ }
+
+ close (fd);
+
+ r = command (NULL, &err, "lvm", "vgcfgbackup", "-f", tmp, vg, NULL);
+ if (r == -1) {
+ reply_with_error ("vgcfgbackup: %s", err);
+ free (err);
+ return NULL;
+ }
+ free (err);
+
+ /* Now read back the temporary file. */
+ fd = open (tmp, O_RDONLY|O_CLOEXEC);
+ if (fd == -1) {
+ reply_with_error ("%s", tmp);
+ return NULL;
+ }
+
+ /* Read up to GUESTFS_MESSAGE_MAX - <overhead> bytes. If it's
+ * larger than that, we need to return an error instead (for
+ * correctness).
+ */
+ max = GUESTFS_MESSAGE_MAX - 1000;
+ buf = NULL;
+ size = alloc = 0;
+
+ for (;;) {
+ if (size >= alloc) {
+ alloc += 8192;
+ if (alloc > max) {
+ reply_with_error ("metadata is too large for message buffer");
+ free (buf);
+ close (fd);
+ return NULL;
+ }
+ buf2 = realloc (buf, alloc);
+ if (buf2 == NULL) {
+ reply_with_perror ("realloc");
+ free (buf);
+ close (fd);
+ return NULL;
+ }
+ buf = buf2;
+ }
+
+ rs = read (fd, buf + size, alloc - size);
+ if (rs == -1) {
+ reply_with_perror ("read: %s", tmp);
+ free (buf);
+ close (fd);
+ return NULL;
+ }
+ if (rs == 0)
+ break;
+ if (rs > 0)
+ size += rs;
+ }
+
+ if (close (fd) == -1) {
+ reply_with_perror ("close: %s", tmp);
+ free (buf);
+ return NULL;
+ }
+
+ unlink (tmp);
+
+ *size_r = size;
+
+ return buf; /* caller will free */
+}
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index a2710080..8c074ca9 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -6812,6 +6812,16 @@ Note that in the common case where you have added an ISO file
as a libguestfs device, you would I<not> call this. Instead
you would call C<guestfs_isoinfo_device>.");
+ ("vgmeta", (RBufferOut "metadata", [String "vgname"], []), 315, [Optional "lvm2"],
+ [],
+ "get volume group metadata",
+ "\
+C<vgname> is an LVM volume group. This command examines the
+volume group and returns its metadata.
+
+Note that the metadata is an internal structure used by LVM,
+subject to change at any time, and is provided for information only.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 9346fabb..66953656 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-314
+315