summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2009-05-15 14:01:28 +0100
committerRichard W.M. Jones <rjones@redhat.com>2009-05-15 14:52:34 +0100
commit5cd39c83e23eb300d1bdfa806902a31b409ff420 (patch)
treea47e2bf9afc16cb9404ae996f512a9d3f22e553b
parentb8e5f51c79f539a740827506cc9da3ffcb6c87f8 (diff)
downloadlibguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.tar.gz
libguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.tar.xz
libguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.zip
Add: pvresize, sfdisk-N, sfdisk-l, sfdisk-kernel-geomtry, sfdisk-disk-geometry commands. Pass --no-reread flag to sfdisk.
-rw-r--r--daemon/Makefile.am1
-rw-r--r--daemon/actions.h5
-rw-r--r--daemon/devsparts.c43
-rw-r--r--daemon/lvm.c18
-rw-r--r--daemon/sfdisk.c130
-rw-r--r--daemon/stubs.c154
-rw-r--r--fish/cmds.c126
-rw-r--r--fish/completion.c5
-rw-r--r--guestfish-actions.pod51
-rw-r--r--guestfs-actions.pod74
-rw-r--r--haskell/Guestfs.hs15
-rw-r--r--java/com/redhat/et/libguestfs/GuestFS.java109
-rw-r--r--java/com_redhat_et_libguestfs_GuestFS.c108
-rw-r--r--ocaml/guestfs.ml5
-rw-r--r--ocaml/guestfs.mli15
-rw-r--r--ocaml/guestfs_c_actions.c130
-rw-r--r--perl/Guestfs.xs72
-rw-r--r--perl/lib/Sys/Guestfs.pm41
-rw-r--r--python/guestfs-py.c135
-rw-r--r--python/guestfs.py49
-rw-r--r--ruby/ext/guestfs/_guestfs.c129
-rwxr-xr-xsrc/generator.ml58
-rw-r--r--src/guestfs-actions.c460
-rw-r--r--src/guestfs-actions.h5
-rw-r--r--src/guestfs_protocol.c139
-rw-r--r--src/guestfs_protocol.h68
-rw-r--r--src/guestfs_protocol.x42
-rw-r--r--tests.c5
28 files changed, 2143 insertions, 49 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index d6ae6c38..ac1f8c58 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -43,6 +43,7 @@ guestfsd_SOURCES = \
mount.c \
pingdaemon.c \
proto.c \
+ sfdisk.c \
stat.c \
strings.c \
stubs.c \
diff --git a/daemon/actions.h b/daemon/actions.h
index 37ec1253..3e6589e2 100644
--- a/daemon/actions.h
+++ b/daemon/actions.h
@@ -118,3 +118,8 @@ extern char **do_strings (const char *path);
extern char **do_strings_e (const char *encoding, const char *path);
extern char *do_hexdump (const char *path);
extern int do_zerofree (const char *device);
+extern int do_pvresize (const char *device);
+extern int do_sfdisk_N (const char *device, int n, int cyls, int heads, int sectors, const char *line);
+extern char *do_sfdisk_l (const char *device);
+extern char *do_sfdisk_kernel_geometry (const char *device);
+extern char *do_sfdisk_disk_geometry (const char *device);
diff --git a/daemon/devsparts.c b/daemon/devsparts.c
index 0a4d5e46..21854b5c 100644
--- a/daemon/devsparts.c
+++ b/daemon/devsparts.c
@@ -152,46 +152,3 @@ do_mkfs (const char *fstype, const char *device)
free (err);
return 0;
}
-
-int
-do_sfdisk (const char *device, int cyls, int heads, int sectors,
- char * const* const lines)
-{
- FILE *fp;
- char buf[256];
- int i;
-
- IS_DEVICE (device, -1);
-
- /* Safe because of IS_DEVICE above. */
- strcpy (buf, "/sbin/sfdisk");
- if (cyls)
- sprintf (buf + strlen (buf), " -C %d", cyls);
- if (heads)
- sprintf (buf + strlen (buf), " -H %d", heads);
- if (sectors)
- sprintf (buf + strlen (buf), " -S %d", sectors);
- sprintf (buf + strlen (buf), " %s", device);
-
- fp = popen (buf, "w");
- if (fp == NULL) {
- reply_with_perror (buf);
- return -1;
- }
-
- for (i = 0; lines[i] != NULL; ++i) {
- if (fprintf (fp, "%s\n", lines[i]) < 0) {
- reply_with_perror (buf);
- fclose (fp);
- return -1;
- }
- }
-
- if (fclose (fp) == EOF) {
- reply_with_perror (buf);
- fclose (fp);
- return -1;
- }
-
- return 0;
-}
diff --git a/daemon/lvm.c b/daemon/lvm.c
index 326b5830..d1a6cd60 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -358,3 +358,21 @@ do_pvremove (const char *device)
free (err);
return 0;
}
+
+int
+do_pvresize (const char *device)
+{
+ char *err;
+ int r;
+
+ r = command (NULL, &err,
+ "/sbin/lvm", "pvresize", device, NULL);
+ if (r == -1) {
+ reply_with_error ("pvresize: %s: %s", device, err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
diff --git a/daemon/sfdisk.c b/daemon/sfdisk.c
new file mode 100644
index 00000000..9d7a220f
--- /dev/null
+++ b/daemon/sfdisk.c
@@ -0,0 +1,130 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "daemon.h"
+#include "actions.h"
+
+static int
+sfdisk (const char *device, int n, int cyls, int heads, int sectors,
+ char * const* const lines)
+{
+ FILE *fp;
+ char buf[256];
+ int i;
+
+ IS_DEVICE (device, -1);
+
+ strcpy (buf, "/sbin/sfdisk --no-reread");
+ if (n > 0)
+ sprintf (buf + strlen (buf), " -N %d", n);
+ if (cyls)
+ sprintf (buf + strlen (buf), " -C %d", cyls);
+ if (heads)
+ sprintf (buf + strlen (buf), " -H %d", heads);
+ if (sectors)
+ sprintf (buf + strlen (buf), " -S %d", sectors);
+ /* Safe because of IS_DEVICE above: */
+ sprintf (buf + strlen (buf), " %s", device);
+
+ fp = popen (buf, "w");
+ if (fp == NULL) {
+ reply_with_perror (buf);
+ return -1;
+ }
+
+ for (i = 0; lines[i] != NULL; ++i) {
+ if (fprintf (fp, "%s\n", lines[i]) < 0) {
+ reply_with_perror (buf);
+ fclose (fp);
+ return -1;
+ }
+ }
+
+ if (fclose (fp) == EOF) {
+ reply_with_perror (buf);
+ fclose (fp);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+do_sfdisk (const char *device, int cyls, int heads, int sectors,
+ char * const* const lines)
+{
+ return sfdisk (device, 0, cyls, heads, sectors, lines);
+}
+
+int
+do_sfdisk_N (const char *device, int n, int cyls, int heads, int sectors,
+ const char *line)
+{
+ const char *lines[2] = { line, NULL };
+
+ return sfdisk (device, n, cyls, heads, sectors, lines);
+}
+
+static char *
+sfdisk_flag (const char *device, const char *flag)
+{
+ char *out, *err;
+ int r;
+
+ IS_DEVICE (device, NULL);
+
+ r = command (&out, &err, "/sbin/sfdisk", flag, device, NULL);
+ if (r == -1) {
+ reply_with_error ("sfdisk: %s: %s", device, err);
+ free (out);
+ free (err);
+ return NULL;
+ }
+
+ free (err);
+
+ return out; /* caller frees */
+}
+
+char *
+do_sfdisk_l (const char *device)
+{
+ return sfdisk_flag (device, "-l");
+}
+
+char *
+do_sfdisk_kernel_geometry (const char *device)
+{
+ return sfdisk_flag (device, "-g");
+}
+
+char *
+do_sfdisk_disk_geometry (const char *device)
+{
+ return sfdisk_flag (device, "-G");
+}
diff --git a/daemon/stubs.c b/daemon/stubs.c
index 212634fd..e80ba9be 100644
--- a/daemon/stubs.c
+++ b/daemon/stubs.c
@@ -2421,6 +2421,145 @@ done:
xdr_free ((xdrproc_t) xdr_guestfs_zerofree_args, (char *) &args);
}
+static void pvresize_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_pvresize_args args;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_pvresize_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "pvresize");
+ return;
+ }
+ device = args.device;
+
+ r = do_pvresize (device);
+ if (r == -1)
+ /* do_pvresize has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_pvresize_args, (char *) &args);
+}
+
+static void sfdisk_N_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_sfdisk_N_args args;
+ const char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ const char *line;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_sfdisk_N_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "sfdisk_N");
+ return;
+ }
+ device = args.device;
+ n = args.n;
+ cyls = args.cyls;
+ heads = args.heads;
+ sectors = args.sectors;
+ line = args.line;
+
+ r = do_sfdisk_N (device, n, cyls, heads, sectors, line);
+ if (r == -1)
+ /* do_sfdisk_N has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_N_args, (char *) &args);
+}
+
+static void sfdisk_l_stub (XDR *xdr_in)
+{
+ char *r;
+ struct guestfs_sfdisk_l_args args;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_sfdisk_l_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "sfdisk_l");
+ return;
+ }
+ device = args.device;
+
+ r = do_sfdisk_l (device);
+ if (r == NULL)
+ /* do_sfdisk_l has already called reply_with_error */
+ goto done;
+
+ struct guestfs_sfdisk_l_ret ret;
+ ret.partitions = r;
+ reply ((xdrproc_t) &xdr_guestfs_sfdisk_l_ret, (char *) &ret);
+ free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_l_args, (char *) &args);
+}
+
+static void sfdisk_kernel_geometry_stub (XDR *xdr_in)
+{
+ char *r;
+ struct guestfs_sfdisk_kernel_geometry_args args;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_sfdisk_kernel_geometry_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "sfdisk_kernel_geometry");
+ return;
+ }
+ device = args.device;
+
+ r = do_sfdisk_kernel_geometry (device);
+ if (r == NULL)
+ /* do_sfdisk_kernel_geometry has already called reply_with_error */
+ goto done;
+
+ struct guestfs_sfdisk_kernel_geometry_ret ret;
+ ret.partitions = r;
+ reply ((xdrproc_t) &xdr_guestfs_sfdisk_kernel_geometry_ret, (char *) &ret);
+ free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_kernel_geometry_args, (char *) &args);
+}
+
+static void sfdisk_disk_geometry_stub (XDR *xdr_in)
+{
+ char *r;
+ struct guestfs_sfdisk_disk_geometry_args args;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_sfdisk_disk_geometry_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "sfdisk_disk_geometry");
+ return;
+ }
+ device = args.device;
+
+ r = do_sfdisk_disk_geometry (device);
+ if (r == NULL)
+ /* do_sfdisk_disk_geometry has already called reply_with_error */
+ goto done;
+
+ struct guestfs_sfdisk_disk_geometry_ret ret;
+ ret.partitions = r;
+ reply ((xdrproc_t) &xdr_guestfs_sfdisk_disk_geometry_ret, (char *) &ret);
+ free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_disk_geometry_args, (char *) &args);
+}
+
void dispatch_incoming_message (XDR *xdr_in)
{
switch (proc_nr) {
@@ -2715,6 +2854,21 @@ void dispatch_incoming_message (XDR *xdr_in)
case GUESTFS_PROC_ZEROFREE:
zerofree_stub (xdr_in);
break;
+ case GUESTFS_PROC_PVRESIZE:
+ pvresize_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_SFDISK_N:
+ sfdisk_N_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_SFDISK_L:
+ sfdisk_l_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY:
+ sfdisk_kernel_geometry_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_SFDISK_DISK_GEOMETRY:
+ sfdisk_disk_geometry_stub (xdr_in);
+ break;
default:
reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr);
}
diff --git a/fish/cmds.c b/fish/cmds.c
index 1f3d9cee..5680bfa3 100644
--- a/fish/cmds.c
+++ b/fish/cmds.c
@@ -113,6 +113,7 @@ void list_commands (void)
printf ("%-20s %s\n", "ping-daemon", "ping the guest daemon");
printf ("%-20s %s\n", "pvcreate", "create an LVM physical volume");
printf ("%-20s %s\n", "pvremove", "remove an LVM physical volume");
+ printf ("%-20s %s\n", "pvresize", "resize an LVM physical volume");
printf ("%-20s %s\n", "pvs", "list the LVM physical volumes (PVs)");
printf ("%-20s %s\n", "pvs-full", "list the LVM physical volumes (PVs)");
printf ("%-20s %s\n", "read-lines", "read file as lines");
@@ -127,6 +128,10 @@ void list_commands (void)
printf ("%-20s %s\n", "set-qemu", "set the qemu binary");
printf ("%-20s %s\n", "set-verbose", "set verbose mode");
printf ("%-20s %s\n", "sfdisk", "create partitions on a block device");
+ printf ("%-20s %s\n", "sfdisk-N", "modify a single partition on a block device");
+ printf ("%-20s %s\n", "sfdisk-disk-geometry", "display the disk geometry from the partition table");
+ printf ("%-20s %s\n", "sfdisk-kernel-geometry", "display the kernel geometry");
+ printf ("%-20s %s\n", "sfdisk-l", "display the partition table");
printf ("%-20s %s\n", "stat", "get file information");
printf ("%-20s %s\n", "statvfs", "get file system statistics");
printf ("%-20s %s\n", "strings", "print the printable strings in a file");
@@ -340,7 +345,7 @@ void display_command (const char *cmd)
pod2text ("mkfs - make a filesystem", " mkfs <fstype> <device>\n\nThis creates a filesystem on C<device> (usually a partition\nor LVM logical volume). The filesystem type is C<fstype>, for\nexample C<ext3>.");
else
if (strcasecmp (cmd, "sfdisk") == 0)
- pod2text ("sfdisk - create partitions on a block device", " sfdisk <device> <cyls> <heads> <sectors> <lines>\n\nThis is a direct interface to the L<sfdisk(8)> program for creating\npartitions on block devices.\n\nC<device> should be a block device, for example C</dev/sda>.\n\nC<cyls>, C<heads> and C<sectors> are the number of cylinders, heads\nand sectors on the device, which are passed directly to sfdisk as\nthe I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any\nof these, then the corresponding parameter is omitted. Usually for\n'large' disks, you can just pass C<0> for these, but for small\n(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work\nout the right geometry and you will need to tell it.\n\nC<lines> is a list of lines that we feed to C<sfdisk>. For more\ninformation refer to the L<sfdisk(8)> manpage.\n\nTo create a single partition occupying the whole disk, you would\npass C<lines> as a single element list, when the single element being\nthe string C<,> (comma).\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
+ pod2text ("sfdisk - create partitions on a block device", " sfdisk <device> <cyls> <heads> <sectors> <lines>\n\nThis is a direct interface to the L<sfdisk(8)> program for creating\npartitions on block devices.\n\nC<device> should be a block device, for example C</dev/sda>.\n\nC<cyls>, C<heads> and C<sectors> are the number of cylinders, heads\nand sectors on the device, which are passed directly to sfdisk as\nthe I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any\nof these, then the corresponding parameter is omitted. Usually for\n'large' disks, you can just pass C<0> for these, but for small\n(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work\nout the right geometry and you will need to tell it.\n\nC<lines> is a list of lines that we feed to C<sfdisk>. For more\ninformation refer to the L<sfdisk(8)> manpage.\n\nTo create a single partition occupying the whole disk, you would\npass C<lines> as a single element list, when the single element being\nthe string C<,> (comma).\n\nSee also: C<sfdisk_l>, C<sfdisk_N>\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
else
if (strcasecmp (cmd, "write_file") == 0 || strcasecmp (cmd, "write-file") == 0)
pod2text ("write-file - create a file", " write-file <path> <content> <size>\n\nThis call creates a file called C<path>. The contents of the\nfile is the string C<content> (which can contain any 8 bit data),\nwith length C<size>.\n\nAs a special case, if C<size> is C<0>\nthen the length is calculated using C<strlen> (so in this case\nthe content cannot contain embedded ASCII NULs).\n\nI<NB.> Owing to a bug, writing content containing ASCII NUL\ncharacters does I<not> work, even if the length is specified.\nWe hope to resolve this bug in a future version. In the meantime\nuse C<upload>.\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
@@ -504,6 +509,21 @@ void display_command (const char *cmd)
if (strcasecmp (cmd, "zerofree") == 0)
pod2text ("zerofree - zero unused inodes and disk blocks on ext2/3 filesystem", " zerofree <device>\n\nThis runs the I<zerofree> program on C<device>. This program\nclaims to zero unused inodes and disk blocks on an ext2/3\nfilesystem, thus making it possible to compress the filesystem\nmore effectively.\n\nYou should B<not> run this program if the filesystem is\nmounted.\n\nIt is possible that using this program can damage the filesystem\nor data on the filesystem.");
else
+ if (strcasecmp (cmd, "pvresize") == 0)
+ pod2text ("pvresize - resize an LVM physical volume", " pvresize <device>\n\nThis resizes (expands or shrinks) an existing LVM physical\nvolume to match the new size of the underlying device.");
+ else
+ if (strcasecmp (cmd, "sfdisk_N") == 0 || strcasecmp (cmd, "sfdisk-N") == 0)
+ pod2text ("sfdisk-N - modify a single partition on a block device", " sfdisk-N <device> <n> <cyls> <heads> <sectors> <line>\n\nThis runs L<sfdisk(8)> option to modify just the single\npartition C<n> (note: C<n> counts from 1).\n\nFor other parameters, see C<sfdisk>. You should usually\npass C<0> for the cyls/heads/sectors parameters.\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
+ else
+ if (strcasecmp (cmd, "sfdisk_l") == 0 || strcasecmp (cmd, "sfdisk-l") == 0)
+ pod2text ("sfdisk-l - display the partition table", " sfdisk-l <device>\n\nThis displays the partition table on C<device>, in the\nhuman-readable output of the L<sfdisk(8)> command. It is\nnot intended to be parsed.");
+ else
+ if (strcasecmp (cmd, "sfdisk_kernel_geometry") == 0 || strcasecmp (cmd, "sfdisk-kernel-geometry") == 0)
+ pod2text ("sfdisk-kernel-geometry - display the kernel geometry", " sfdisk-kernel-geometry <device>\n\nThis displays the kernel's idea of the geometry of C<device>.\n\nThe result is in human-readable format, and not designed to\nbe parsed.");
+ else
+ if (strcasecmp (cmd, "sfdisk_disk_geometry") == 0 || strcasecmp (cmd, "sfdisk-disk-geometry") == 0)
+ pod2text ("sfdisk-disk-geometry - display the disk geometry from the partition table", " sfdisk-disk-geometry <device>\n\nThis displays the disk geometry of C<device> read from the\npartition table. Especially in the case where the underlying\nblock device has been resized, this can be different from the\nkernel's idea of the geometry (see C<sfdisk_kernel_geometry>).\n\nThe result is in human-readable format, and not designed to\nbe parsed.");
+ else
display_builtin_command (cmd);
}
@@ -2456,6 +2476,95 @@ static int run_zerofree (const char *cmd, int argc, char *argv[])
return r;
}
+static int run_pvresize (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *device;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ r = guestfs_pvresize (g, device);
+ return r;
+}
+
+static int run_sfdisk_N (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ const char *line;
+ if (argc != 6) {
+ fprintf (stderr, "%s should have 6 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ n = atoi (argv[1]);
+ cyls = atoi (argv[2]);
+ heads = atoi (argv[3]);
+ sectors = atoi (argv[4]);
+ line = argv[5];
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ return r;
+}
+
+static int run_sfdisk_l (const char *cmd, int argc, char *argv[])
+{
+ char *r;
+ const char *device;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ r = guestfs_sfdisk_l (g, device);
+ if (r == NULL) return -1;
+ printf ("%s\n", r);
+ free (r);
+ return 0;
+}
+
+static int run_sfdisk_kernel_geometry (const char *cmd, int argc, char *argv[])
+{
+ char *r;
+ const char *device;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ r = guestfs_sfdisk_kernel_geometry (g, device);
+ if (r == NULL) return -1;
+ printf ("%s\n", r);
+ free (r);
+ return 0;
+}
+
+static int run_sfdisk_disk_geometry (const char *cmd, int argc, char *argv[])
+{
+ char *r;
+ const char *device;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ r = guestfs_sfdisk_disk_geometry (g, device);
+ if (r == NULL) return -1;
+ printf ("%s\n", r);
+ free (r);
+ return 0;
+}
+
int run_action (const char *cmd, int argc, char *argv[])
{
if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
@@ -2809,6 +2918,21 @@ int run_action (const char *cmd, int argc, char *argv[])
if (strcasecmp (cmd, "zerofree") == 0)
return run_zerofree (cmd, argc, argv);
else
+ if (strcasecmp (cmd, "pvresize") == 0)
+ return run_pvresize (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "sfdisk_N") == 0 || strcasecmp (cmd, "sfdisk-N") == 0)
+ return run_sfdisk_N (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "sfdisk_l") == 0 || strcasecmp (cmd, "sfdisk-l") == 0)
+ return run_sfdisk_l (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "sfdisk_kernel_geometry") == 0 || strcasecmp (cmd, "sfdisk-kernel-geometry") == 0)
+ return run_sfdisk_kernel_geometry (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "sfdisk_disk_geometry") == 0 || strcasecmp (cmd, "sfdisk-disk-geometry") == 0)
+ return run_sfdisk_disk_geometry (cmd, argc, argv);
+ else
{
fprintf (stderr, "%s: unknown command\n", cmd);
return -1;
diff --git a/fish/completion.c b/fish/completion.c
index 5c7f5e01..03760ad6 100644
--- a/fish/completion.c
+++ b/fish/completion.c
@@ -121,6 +121,7 @@ static const char *const commands[] = {
"ping-daemon",
"pvcreate",
"pvremove",
+ "pvresize",
"pvs",
"pvs-full",
"qemu",
@@ -137,6 +138,10 @@ static const char *const commands[] = {
"set-qemu",
"set-verbose",
"sfdisk",
+ "sfdisk-N",
+ "sfdisk-disk-geometry",
+ "sfdisk-kernel-geometry",
+ "sfdisk-l",
"stat",
"statvfs",
"strings",
diff --git a/guestfish-actions.pod b/guestfish-actions.pod
index 7b5a4bed..213fa66e 100644
--- a/guestfish-actions.pod
+++ b/guestfish-actions.pod
@@ -905,6 +905,13 @@ The implementation uses the C<pvremove> command which refuses to
wipe physical volumes that contain any volume groups, so you have
to remove those first.
+=head2 pvresize
+
+ pvresize device
+
+This resizes (expands or shrinks) an existing LVM physical
+volume to match the new size of the underlying device.
+
=head2 pvs
pvs
@@ -1064,9 +1071,53 @@ To create a single partition occupying the whole disk, you would
pass C<lines> as a single element list, when the single element being
the string C<,> (comma).
+See also: C<sfdisk-l>, C<sfdisk-N>
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
+=head2 sfdisk-N
+
+ sfdisk-N device n cyls heads sectors line
+
+This runs L<sfdisk(8)> option to modify just the single
+partition C<n> (note: C<n> counts from 1).
+
+For other parameters, see C<sfdisk>. You should usually
+pass C<0> for the cyls/heads/sectors parameters.
+
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=head2 sfdisk-disk-geometry
+
+ sfdisk-disk-geometry device
+
+This displays the disk geometry of C<device> read from the
+partition table. Especially in the case where the underlying
+block device has been resized, this can be different from the
+kernel's idea of the geometry (see C<sfdisk-kernel-geometry>).
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+=head2 sfdisk-kernel-geometry
+
+ sfdisk-kernel-geometry device
+
+This displays the kernel's idea of the geometry of C<device>.
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+=head2 sfdisk-l
+
+ sfdisk-l device
+
+This displays the partition table on C<device>, in the
+human-readable output of the L<sfdisk(8)> command. It is
+not intended to be parsed.
+
=head2 stat
stat path
diff --git a/guestfs-actions.pod b/guestfs-actions.pod
index 109c73ea..abeed8ff 100644
--- a/guestfs-actions.pod
+++ b/guestfs-actions.pod
@@ -1208,6 +1208,16 @@ to remove those first.
This function returns 0 on success or -1 on error.
+=head2 guestfs_pvresize
+
+ int guestfs_pvresize (guestfs_h *handle,
+ const char *device);
+
+This resizes (expands or shrinks) an existing LVM physical
+volume to match the new size of the underlying device.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_pvs
char **guestfs_pvs (guestfs_h *handle);
@@ -1440,11 +1450,75 @@ To create a single partition occupying the whole disk, you would
pass C<lines> as a single element list, when the single element being
the string C<,> (comma).
+See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>
+
+This function returns 0 on success or -1 on error.
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
+=head2 guestfs_sfdisk_N
+
+ int guestfs_sfdisk_N (guestfs_h *handle,
+ const char *device,
+ int n,
+ int cyls,
+ int heads,
+ int sectors,
+ const char *line);
+
+This runs L<sfdisk(8)> option to modify just the single
+partition C<n> (note: C<n> counts from 1).
+
+For other parameters, see C<guestfs_sfdisk>. You should usually
+pass C<0> for the cyls/heads/sectors parameters.
+
This function returns 0 on success or -1 on error.
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=head2 guestfs_sfdisk_disk_geometry
+
+ char *guestfs_sfdisk_disk_geometry (guestfs_h *handle,
+ const char *device);
+
+This displays the disk geometry of C<device> read from the
+partition table. Especially in the case where the underlying
+block device has been resized, this can be different from the
+kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+This function returns a string, or NULL on error.
+I<The caller must free the returned string after use>.
+
+=head2 guestfs_sfdisk_kernel_geometry
+
+ char *guestfs_sfdisk_kernel_geometry (guestfs_h *handle,
+ const char *device);
+
+This displays the kernel's idea of the geometry of C<device>.
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+This function returns a string, or NULL on error.
+I<The caller must free the returned string after use>.
+
+=head2 guestfs_sfdisk_l
+
+ char *guestfs_sfdisk_l (guestfs_h *handle,
+ const char *device);
+
+This displays the partition table on C<device>, in the
+human-readable output of the L<sfdisk(8)> command. It is
+not intended to be parsed.
+
+This function returns a string, or NULL on error.
+I<The caller must free the returned string after use>.
+
=head2 guestfs_stat
struct guestfs_stat *guestfs_stat (guestfs_h *handle,
diff --git a/haskell/Guestfs.hs b/haskell/Guestfs.hs
index c061a7a6..170f0403 100644
--- a/haskell/Guestfs.hs
+++ b/haskell/Guestfs.hs
@@ -79,7 +79,8 @@ module Guestfs (
cp_a,
mv,
ping_daemon,
- zerofree
+ zerofree,
+ pvresize
) where
import Foreign
import Foreign.C
@@ -801,3 +802,15 @@ zerofree h device = do
fail err
else return ()
+foreign import ccall unsafe "guestfs_pvresize" c_pvresize
+ :: GuestfsP -> CString -> IO (CInt)
+
+pvresize :: GuestfsH -> String -> IO ()
+pvresize h device = do
+ r <- withCString device $ \device -> withForeignPtr h (\p -> c_pvresize p device)
+ if (r == -1)
+ then do
+ err <- last_error h
+ fail err
+ else return ()
+
diff --git a/java/com/redhat/et/libguestfs/GuestFS.java b/java/com/redhat/et/libguestfs/GuestFS.java
index 76ada908..7eafce0f 100644
--- a/java/com/redhat/et/libguestfs/GuestFS.java
+++ b/java/com/redhat/et/libguestfs/GuestFS.java
@@ -1518,6 +1518,8 @@ public class GuestFS {
* you would pass "lines" as a single element list, when
* the single element being the string "," (comma).
*
+ * See also: "g.sfdisk_l", "g.sfdisk_N"
+ *
* This command is dangerous. Without careful use you can
* easily destroy all your data.
*
@@ -2755,4 +2757,111 @@ public class GuestFS {
private native void _zerofree (long g, String device)
throws LibGuestFSException;
+ /**
+ * resize an LVM physical volume
+ *
+ * This resizes (expands or shrinks) an existing LVM
+ * physical volume to match the new size of the underlying
+ * device.
+ *
+ * @throws LibGuestFSException
+ */
+ public void pvresize (String device)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("pvresize: handle is closed");
+ _pvresize (g, device);
+ }
+ private native void _pvresize (long g, String device)
+ throws LibGuestFSException;
+
+ /**
+ * modify a single partition on a block device
+ *
+ * This runs sfdisk(8) option to modify just the single
+ * partition "n" (note: "n" counts from 1).
+ *
+ * For other parameters, see "g.sfdisk". You should usually
+ * pass 0 for the cyls/heads/sectors parameters.
+ *
+ * This command is dangerous. Without careful use you can
+ * easily destroy all your data.
+ *
+ * @throws LibGuestFSException
+ */
+ public void sfdisk_N (String device, int n, int cyls, int heads, int sectors, String line)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("sfdisk_N: handle is closed");
+ _sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ }
+ private native void _sfdisk_N (long g, String device, int n, int cyls, int heads, int sectors, String line)
+ throws LibGuestFSException;
+
+ /**
+ * display the partition table
+ *
+ * This displays the partition table on "device", in the
+ * human-readable output of the sfdisk(8) command. It is
+ * not intended to be parsed.
+ *
+ * @throws LibGuestFSException
+ */
+ public String sfdisk_l (String device)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("sfdisk_l: handle is closed");
+ return _sfdisk_l (g, device);
+ }
+ private native String _sfdisk_l (long g, String device)
+ throws LibGuestFSException;
+
+ /**
+ * display the kernel geometry
+ *
+ * This displays the kernel's idea of the geometry of
+ * "device".
+ *
+ * The result is in human-readable format, and not designed
+ * to be parsed.
+ *
+ * @throws LibGuestFSException
+ */
+ public String sfdisk_kernel_geometry (String device)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("sfdisk_kernel_geometry: handle is closed");
+ return _sfdisk_kernel_geometry (g, device);
+ }
+ private native String _sfdisk_kernel_geometry (long g, String device)
+ throws LibGuestFSException;
+
+ /**
+ * display the disk geometry from the partition table
+ *
+ * This displays the disk geometry of "device" read from
+ * the partition table. Especially in the case where the
+ * underlying block device has been resized, this can be
+ * different from the kernel's idea of the geometry (see
+ * "g.sfdisk_kernel_geometry").
+ *
+ * The result is in human-readable format, and not designed
+ * to be parsed.
+ *
+ * @throws LibGuestFSException
+ */
+ public String sfdisk_disk_geometry (String device)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("sfdisk_disk_geometry: handle is closed");
+ return _sfdisk_disk_geometry (g, device);
+ }
+ private native String _sfdisk_disk_geometry (long g, String device)
+ throws LibGuestFSException;
+
}
diff --git a/java/com_redhat_et_libguestfs_GuestFS.c b/java/com_redhat_et_libguestfs_GuestFS.c
index a823d84e..be7ea9f2 100644
--- a/java/com_redhat_et_libguestfs_GuestFS.c
+++ b/java/com_redhat_et_libguestfs_GuestFS.c
@@ -2739,3 +2739,111 @@ Java_com_redhat_et_libguestfs_GuestFS__1zerofree
}
}
+JNIEXPORT void JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1pvresize
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ int r;
+ const char *device;
+
+ device = (*env)->GetStringUTFChars (env, jdevice, NULL);
+ r = guestfs_pvresize (g, device);
+ (*env)->ReleaseStringUTFChars (env, jdevice, device);
+ if (r == -1) {
+ throw_exception (env, guestfs_last_error (g));
+ return ;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1N
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice, jint jn, jint jcyls, jint jheads, jint jsectors, jstring jline)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ int r;
+ const char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ const char *line;
+
+ device = (*env)->GetStringUTFChars (env, jdevice, NULL);
+ n = jn;
+ cyls = jcyls;
+ heads = jheads;
+ sectors = jsectors;
+ line = (*env)->GetStringUTFChars (env, jline, NULL);
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ (*env)->ReleaseStringUTFChars (env, jdevice, device);
+ (*env)->ReleaseStringUTFChars (env, jline, line);
+ if (r == -1) {
+ throw_exception (env, guestfs_last_error (g));
+ return ;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1l
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jstring jr;
+ char *r;
+ const char *device;
+
+ device = (*env)->GetStringUTFChars (env, jdevice, NULL);
+ r = guestfs_sfdisk_l (g, device);
+ (*env)->ReleaseStringUTFChars (env, jdevice, device);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ jr = (*env)->NewStringUTF (env, r);
+ free (r);
+ return jr;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1kernel_1geometry
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jstring jr;
+ char *r;
+ const char *device;
+
+ device = (*env)->GetStringUTFChars (env, jdevice, NULL);
+ r = guestfs_sfdisk_kernel_geometry (g, device);
+ (*env)->ReleaseStringUTFChars (env, jdevice, device);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ jr = (*env)->NewStringUTF (env, r);
+ free (r);
+ return jr;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1disk_1geometry
+ (JNIEnv *env, jobject obj, jlong jg, jstring jdevice)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ jstring jr;
+ char *r;
+ const char *device;
+
+ device = (*env)->GetStringUTFChars (env, jdevice, NULL);
+ r = guestfs_sfdisk_disk_geometry (g, device);
+ (*env)->ReleaseStringUTFChars (env, jdevice, device);
+ if (r == NULL) {
+ throw_exception (env, guestfs_last_error (g));
+ return NULL;
+ }
+ jr = (*env)->NewStringUTF (env, r);
+ free (r);
+ return jr;
+}
+
diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml
index 3886022d..d50b2d8c 100644
--- a/ocaml/guestfs.ml
+++ b/ocaml/guestfs.ml
@@ -236,3 +236,8 @@ external strings : t -> string -> string array = "ocaml_guestfs_strings"
external strings_e : t -> string -> string -> string array = "ocaml_guestfs_strings_e"
external hexdump : t -> string -> string = "ocaml_guestfs_hexdump"
external zerofree : t -> string -> unit = "ocaml_guestfs_zerofree"
+external pvresize : t -> string -> unit = "ocaml_guestfs_pvresize"
+external sfdisk_N : t -> string -> int -> int -> int -> int -> string -> unit = "ocaml_guestfs_sfdisk_N_byte" "ocaml_guestfs_sfdisk_N"
+external sfdisk_l : t -> string -> string = "ocaml_guestfs_sfdisk_l"
+external sfdisk_kernel_geometry : t -> string -> string = "ocaml_guestfs_sfdisk_kernel_geometry"
+external sfdisk_disk_geometry : t -> string -> string = "ocaml_guestfs_sfdisk_disk_geometry"
diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli
index 3776abe7..358a6d30 100644
--- a/ocaml/guestfs.mli
+++ b/ocaml/guestfs.mli
@@ -487,3 +487,18 @@ val hexdump : t -> string -> string
val zerofree : t -> string -> unit
(** zero unused inodes and disk blocks on ext2/3 filesystem *)
+val pvresize : t -> string -> unit
+(** resize an LVM physical volume *)
+
+val sfdisk_N : t -> string -> int -> int -> int -> int -> string -> unit
+(** modify a single partition on a block device *)
+
+val sfdisk_l : t -> string -> string
+(** display the partition table *)
+
+val sfdisk_kernel_geometry : t -> string -> string
+(** display the kernel geometry *)
+
+val sfdisk_disk_geometry : t -> string -> string
+(** display the disk geometry from the partition table *)
+
diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c
index 79a5c16f..f2d13b03 100644
--- a/ocaml/guestfs_c_actions.c
+++ b/ocaml/guestfs_c_actions.c
@@ -3201,3 +3201,133 @@ ocaml_guestfs_zerofree (value gv, value devicev)
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_guestfs_pvresize (value gv, value devicev)
+{
+ CAMLparam2 (gv, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("pvresize: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_pvresize (g, device);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "pvresize");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_N (value gv, value devicev, value nv, value cylsv, value headsv, value sectorsv, value linev)
+{
+ CAMLparam5 (gv, devicev, nv, cylsv, headsv);
+ CAMLxparam2 (sectorsv, linev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("sfdisk_N: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ int n = Int_val (nv);
+ int cyls = Int_val (cylsv);
+ int heads = Int_val (headsv);
+ int sectors = Int_val (sectorsv);
+ const char *line = String_val (linev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "sfdisk_N");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_N_byte (value *argv, int argn)
+{
+ return ocaml_guestfs_sfdisk_N (argv[0], argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_l (value gv, value devicev)
+{
+ CAMLparam2 (gv, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("sfdisk_l: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ char *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_sfdisk_l (g, device);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "sfdisk_l");
+
+ rv = caml_copy_string (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_kernel_geometry (value gv, value devicev)
+{
+ CAMLparam2 (gv, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("sfdisk_kernel_geometry: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ char *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_sfdisk_kernel_geometry (g, device);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "sfdisk_kernel_geometry");
+
+ rv = caml_copy_string (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_disk_geometry (value gv, value devicev)
+{
+ CAMLparam2 (gv, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("sfdisk_disk_geometry: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ char *r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_sfdisk_disk_geometry (g, device);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "sfdisk_disk_geometry");
+
+ rv = caml_copy_string (r);
+ free (r);
+ CAMLreturn (rv);
+}
+
diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs
index e87131bd..ff7ca9e1 100644
--- a/perl/Guestfs.xs
+++ b/perl/Guestfs.xs
@@ -1798,3 +1798,75 @@ PREINIT:
if (r == -1)
croak ("zerofree: %s", guestfs_last_error (g));
+void
+pvresize (g, device)
+ guestfs_h *g;
+ char *device;
+PREINIT:
+ int r;
+ PPCODE:
+ r = guestfs_pvresize (g, device);
+ if (r == -1)
+ croak ("pvresize: %s", guestfs_last_error (g));
+
+void
+sfdisk_N (g, device, n, cyls, heads, sectors, line)
+ guestfs_h *g;
+ char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ char *line;
+PREINIT:
+ int r;
+ PPCODE:
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ if (r == -1)
+ croak ("sfdisk_N: %s", guestfs_last_error (g));
+
+SV *
+sfdisk_l (g, device)
+ guestfs_h *g;
+ char *device;
+PREINIT:
+ char *partitions;
+ CODE:
+ partitions = guestfs_sfdisk_l (g, device);
+ if (partitions == NULL)
+ croak ("sfdisk_l: %s", guestfs_last_error (g));
+ RETVAL = newSVpv (partitions, 0);
+ free (partitions);
+ OUTPUT:
+ RETVAL
+
+SV *
+sfdisk_kernel_geometry (g, device)
+ guestfs_h *g;
+ char *device;
+PREINIT:
+ char *partitions;
+ CODE:
+ partitions = guestfs_sfdisk_kernel_geometry (g, device);
+ if (partitions == NULL)
+ croak ("sfdisk_kernel_geometry: %s", guestfs_last_error (g));
+ RETVAL = newSVpv (partitions, 0);
+ free (partitions);
+ OUTPUT:
+ RETVAL
+
+SV *
+sfdisk_disk_geometry (g, device)
+ guestfs_h *g;
+ char *device;
+PREINIT:
+ char *partitions;
+ CODE:
+ partitions = guestfs_sfdisk_disk_geometry (g, device);
+ if (partitions == NULL)
+ croak ("sfdisk_disk_geometry: %s", guestfs_last_error (g));
+ RETVAL = newSVpv (partitions, 0);
+ free (partitions);
+ OUTPUT:
+ RETVAL
+
diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm
index b11594f2..0249a412 100644
--- a/perl/lib/Sys/Guestfs.pm
+++ b/perl/lib/Sys/Guestfs.pm
@@ -840,6 +840,11 @@ The implementation uses the C<pvremove> command which refuses to
wipe physical volumes that contain any volume groups, so you have
to remove those first.
+=item $h->pvresize ($device);
+
+This resizes (expands or shrinks) an existing LVM physical
+volume to match the new size of the underlying device.
+
=item @physvols = $h->pvs ();
List all the physical volumes detected. This is the equivalent
@@ -985,9 +990,45 @@ To create a single partition occupying the whole disk, you would
pass C<lines> as a single element list, when the single element being
the string C<,> (comma).
+See also: C<$h-E<gt>sfdisk_l>, C<$h-E<gt>sfdisk_N>
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
+=item $h->sfdisk_N ($device, $n, $cyls, $heads, $sectors, $line);
+
+This runs L<sfdisk(8)> option to modify just the single
+partition C<n> (note: C<n> counts from 1).
+
+For other parameters, see C<$h-E<gt>sfdisk>. You should usually
+pass C<0> for the cyls/heads/sectors parameters.
+
B<This command is dangerous. Without careful use you
can easily destroy all your data>.
+=item $partitions = $h->sfdisk_disk_geometry ($device);
+
+This displays the disk geometry of C<device> read from the
+partition table. Especially in the case where the underlying
+block device has been resized, this can be different from the
+kernel's idea of the geometry (see C<$h-E<gt>sfdisk_kernel_geometry>).
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+=item $partitions = $h->sfdisk_kernel_geometry ($device);
+
+This displays the kernel's idea of the geometry of C<device>.
+
+The result is in human-readable format, and not designed to
+be parsed.
+
+=item $partitions = $h->sfdisk_l ($device);
+
+This displays the partition table on C<device>, in the
+human-readable output of the L<sfdisk(8)> command. It is
+not intended to be parsed.
+
=item %statbuf = $h->stat ($path);
Returns file information for the given C<path>.
diff --git a/python/guestfs-py.c b/python/guestfs-py.c
index 8301c703..140594d2 100644
--- a/python/guestfs-py.c
+++ b/python/guestfs-py.c
@@ -3427,6 +3427,136 @@ py_guestfs_zerofree (PyObject *self, PyObject *args)
return py_r;
}
+static PyObject *
+py_guestfs_pvresize (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ int r;
+ const char *device;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_pvresize",
+ &py_g, &device))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_pvresize (g, device);
+ if (r == -1) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ Py_INCREF (Py_None);
+ py_r = Py_None;
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_sfdisk_N (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ int r;
+ const char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ const char *line;
+
+ if (!PyArg_ParseTuple (args, (char *) "Osiiiis:guestfs_sfdisk_N",
+ &py_g, &device, &n, &cyls, &heads, &sectors, &line))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ if (r == -1) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ Py_INCREF (Py_None);
+ py_r = Py_None;
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_sfdisk_l (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char *r;
+ const char *device;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_sfdisk_l",
+ &py_g, &device))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_sfdisk_l (g, device);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = PyString_FromString (r);
+ free (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_sfdisk_kernel_geometry (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char *r;
+ const char *device;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_sfdisk_kernel_geometry",
+ &py_g, &device))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_sfdisk_kernel_geometry (g, device);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = PyString_FromString (r);
+ free (r);
+ return py_r;
+}
+
+static PyObject *
+py_guestfs_sfdisk_disk_geometry (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ char *r;
+ const char *device;
+
+ if (!PyArg_ParseTuple (args, (char *) "Os:guestfs_sfdisk_disk_geometry",
+ &py_g, &device))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_sfdisk_disk_geometry (g, device);
+ if (r == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));
+ return NULL;
+ }
+
+ py_r = PyString_FromString (r);
+ free (r);
+ return py_r;
+}
+
static PyMethodDef methods[] = {
{ (char *) "create", py_guestfs_create, METH_VARARGS, NULL },
{ (char *) "close", py_guestfs_close, METH_VARARGS, NULL },
@@ -3551,6 +3681,11 @@ static PyMethodDef methods[] = {
{ (char *) "strings_e", py_guestfs_strings_e, METH_VARARGS, NULL },
{ (char *) "hexdump", py_guestfs_hexdump, METH_VARARGS, NULL },
{ (char *) "zerofree", py_guestfs_zerofree, METH_VARARGS, NULL },
+ { (char *) "pvresize", py_guestfs_pvresize, METH_VARARGS, NULL },
+ { (char *) "sfdisk_N", py_guestfs_sfdisk_N, METH_VARARGS, NULL },
+ { (char *) "sfdisk_l", py_guestfs_sfdisk_l, METH_VARARGS, NULL },
+ { (char *) "sfdisk_kernel_geometry", py_guestfs_sfdisk_kernel_geometry, METH_VARARGS, NULL },
+ { (char *) "sfdisk_disk_geometry", py_guestfs_sfdisk_disk_geometry, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
diff --git a/python/guestfs.py b/python/guestfs.py
index 044e1fac..8ac4037c 100644
--- a/python/guestfs.py
+++ b/python/guestfs.py
@@ -750,6 +750,8 @@ class GuestFS:
you would pass "lines" as a single element list, when
the single element being the string "," (comma).
+ See also: "g.sfdisk_l", "g.sfdisk_N"
+
This command is dangerous. Without careful use you can
easily destroy all your data.
"""
@@ -1348,3 +1350,50 @@ class GuestFS:
"""
return libguestfsmod.zerofree (self._o, device)
+ def pvresize (self, device):
+ u"""This resizes (expands or shrinks) an existing LVM
+ physical volume to match the new size of the underlying
+ device.
+ """
+ return libguestfsmod.pvresize (self._o, device)
+
+ def sfdisk_N (self, device, n, cyls, heads, sectors, line):
+ u"""This runs sfdisk(8) option to modify just the single
+ partition "n" (note: "n" counts from 1).
+
+ For other parameters, see "g.sfdisk". You should usually
+ pass 0 for the cyls/heads/sectors parameters.
+
+ This command is dangerous. Without careful use you can
+ easily destroy all your data.
+ """
+ return libguestfsmod.sfdisk_N (self._o, device, n, cyls, heads, sectors, line)
+
+ def sfdisk_l (self, device):
+ u"""This displays the partition table on "device", in the
+ human-readable output of the sfdisk(8) command. It is
+ not intended to be parsed.
+ """
+ return libguestfsmod.sfdisk_l (self._o, device)
+
+ def sfdisk_kernel_geometry (self, device):
+ u"""This displays the kernel's idea of the geometry of
+ "device".
+
+ The result is in human-readable format, and not designed
+ to be parsed.
+ """
+ return libguestfsmod.sfdisk_kernel_geometry (self._o, device)
+
+ def sfdisk_disk_geometry (self, device):
+ u"""This displays the disk geometry of "device" read from
+ the partition table. Especially in the case where the
+ underlying block device has been resized, this can be
+ different from the kernel's idea of the geometry (see
+ "g.sfdisk_kernel_geometry").
+
+ The result is in human-readable format, and not designed
+ to be parsed.
+ """
+ return libguestfsmod.sfdisk_disk_geometry (self._o, device)
+
diff --git a/ruby/ext/guestfs/_guestfs.c b/ruby/ext/guestfs/_guestfs.c
index 4fb6ce71..b5c9b53a 100644
--- a/ruby/ext/guestfs/_guestfs.c
+++ b/ruby/ext/guestfs/_guestfs.c
@@ -2906,6 +2906,125 @@ static VALUE ruby_guestfs_zerofree (VALUE gv, VALUE devicev)
return Qnil;
}
+static VALUE ruby_guestfs_pvresize (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "pvresize");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "pvresize");
+
+ int r;
+
+ r = guestfs_pvresize (g, device);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_sfdisk_N (VALUE gv, VALUE devicev, VALUE nv, VALUE cylsv, VALUE headsv, VALUE sectorsv, VALUE linev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sfdisk_N");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "sfdisk_N");
+ int n = NUM2INT (nv);
+ int cyls = NUM2INT (cylsv);
+ int heads = NUM2INT (headsv);
+ int sectors = NUM2INT (sectorsv);
+ const char *line = StringValueCStr (linev);
+ if (!line)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "line", "sfdisk_N");
+
+ int r;
+
+ r = guestfs_sfdisk_N (g, device, n, cyls, heads, sectors, line);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_sfdisk_l (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sfdisk_l");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "sfdisk_l");
+
+ char *r;
+
+ r = guestfs_sfdisk_l (g, device);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_sfdisk_kernel_geometry (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sfdisk_kernel_geometry");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "sfdisk_kernel_geometry");
+
+ char *r;
+
+ r = guestfs_sfdisk_kernel_geometry (g, device);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
+static VALUE ruby_guestfs_sfdisk_disk_geometry (VALUE gv, VALUE devicev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "sfdisk_disk_geometry");
+
+ const char *device = StringValueCStr (devicev);
+ if (!device)
+ rb_raise (rb_eTypeError, "expected string for parameter %s of %s",
+ "device", "sfdisk_disk_geometry");
+
+ char *r;
+
+ r = guestfs_sfdisk_disk_geometry (g, device);
+ if (r == NULL)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ VALUE rv = rb_str_new2 (r);
+ free (r);
+ return rv;
+}
+
/* Initialize the module. */
void Init__guestfs ()
{
@@ -3158,4 +3277,14 @@ void Init__guestfs ()
ruby_guestfs_hexdump, 1);
rb_define_method (c_guestfs, "zerofree",
ruby_guestfs_zerofree, 1);
+ rb_define_method (c_guestfs, "pvresize",
+ ruby_guestfs_pvresize, 1);
+ rb_define_method (c_guestfs, "sfdisk_N",
+ ruby_guestfs_sfdisk_N, 6);
+ rb_define_method (c_guestfs, "sfdisk_l",
+ ruby_guestfs_sfdisk_l, 1);
+ rb_define_method (c_guestfs, "sfdisk_kernel_geometry",
+ ruby_guestfs_sfdisk_kernel_geometry, 1);
+ rb_define_method (c_guestfs, "sfdisk_disk_geometry",
+ ruby_guestfs_sfdisk_disk_geometry, 1);
}
diff --git a/src/generator.ml b/src/generator.ml
index 652564d8..19dc20d5 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -1076,7 +1076,9 @@ information refer to the L<sfdisk(8)> manpage.
To create a single partition occupying the whole disk, you would
pass C<lines> as a single element list, when the single element being
-the string C<,> (comma).");
+the string C<,> (comma).
+
+See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>");
("write_file", (RErr, [String "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning],
[InitBasicFS, Always, TestOutput (
@@ -2019,6 +2021,54 @@ mounted.
It is possible that using this program can damage the filesystem
or data on the filesystem.");
+ ("pvresize", (RErr, [String "device"]), 98, [],
+ [],
+ "resize an LVM physical volume",
+ "\
+This resizes (expands or shrinks) an existing LVM physical
+volume to match the new size of the underlying device.");
+
+ ("sfdisk_N", (RErr, [String "device"; Int "n";
+ Int "cyls"; Int "heads"; Int "sectors";
+ String "line"]), 99, [DangerWillRobinson],
+ [],
+ "modify a single partition on a block device",
+ "\
+This runs L<sfdisk(8)> option to modify just the single
+partition C<n> (note: C<n> counts from 1).
+
+For other parameters, see C<guestfs_sfdisk>. You should usually
+pass C<0> for the cyls/heads/sectors parameters.");
+
+ ("sfdisk_l", (RString "partitions", [String "device"]), 100, [],
+ [],
+ "display the partition table",
+ "\
+This displays the partition table on C<device>, in the
+human-readable output of the L<sfdisk(8)> command. It is
+not intended to be parsed.");
+
+ ("sfdisk_kernel_geometry", (RString "partitions", [String "device"]), 101, [],
+ [],
+ "display the kernel geometry",
+ "\
+This displays the kernel's idea of the geometry of C<device>.
+
+The result is in human-readable format, and not designed to
+be parsed.");
+
+ ("sfdisk_disk_geometry", (RString "partitions", [String "device"]), 102, [],
+ [],
+ "display the disk geometry from the partition table",
+ "\
+This displays the disk geometry of C<device> read from the
+partition table. Especially in the case where the underlying
+block device has been resized, this can be different from the
+kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
+
+The result is in human-readable format, and not designed to
+be parsed.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
@@ -2267,8 +2317,10 @@ let check_functions () =
fun (name, _, _, _, _, _, _) ->
if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
failwithf "function name %s does not need 'guestfs' prefix" name;
- if contains_uppercase name then
- failwithf "function name %s should not contain uppercase chars" name;
+ if name = "" then
+ failwithf "function name is empty";
+ if name.[0] < 'a' || name.[0] > 'z' then
+ failwithf "function name %s must start with lowercase a-z" name;
if String.contains name '-' then
failwithf "function name %s should not contain '-', use '_' instead."
name
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c
index d27ef012..49e8961d 100644
--- a/src/guestfs-actions.c
+++ b/src/guestfs-actions.c
@@ -8896,3 +8896,463 @@ int guestfs_zerofree (guestfs_h *g,
return 0;
}
+struct pvresize_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void pvresize_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct pvresize_ctx *ctx = (struct pvresize_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_pvresize");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_pvresize");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_pvresize");
+ return;
+ }
+ goto done;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+int guestfs_pvresize (guestfs_h *g,
+ const char *device)
+{
+ struct guestfs_pvresize_args args;
+ struct pvresize_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_pvresize") == -1) return -1;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.device = (char *) device;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_PVRESIZE,
+ (xdrproc_t) xdr_guestfs_pvresize_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, pvresize_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_pvresize");
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVRESIZE, serial) == -1) {
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ guestfs_end_busy (g);
+ return 0;
+}
+
+struct sfdisk_N_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void sfdisk_N_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct sfdisk_N_ctx *ctx = (struct sfdisk_N_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_N");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_sfdisk_N");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_sfdisk_N");
+ return;
+ }
+ goto done;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+int guestfs_sfdisk_N (guestfs_h *g,
+ const char *device,
+ int n,
+ int cyls,
+ int heads,
+ int sectors,
+ const char *line)
+{
+ struct guestfs_sfdisk_N_args args;
+ struct sfdisk_N_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_sfdisk_N") == -1) return -1;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.device = (char *) device;
+ args.n = n;
+ args.cyls = cyls;
+ args.heads = heads;
+ args.sectors = sectors;
+ args.line = (char *) line;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_N,
+ (xdrproc_t) xdr_guestfs_sfdisk_N_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, sfdisk_N_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_N");
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_N, serial) == -1) {
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ guestfs_end_busy (g);
+ return 0;
+}
+
+struct sfdisk_l_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_sfdisk_l_ret ret;
+};
+
+static void sfdisk_l_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct sfdisk_l_ctx *ctx = (struct sfdisk_l_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_l");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_sfdisk_l");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_sfdisk_l");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_sfdisk_l_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_sfdisk_l");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char *guestfs_sfdisk_l (guestfs_h *g,
+ const char *device)
+{
+ struct guestfs_sfdisk_l_args args;
+ struct sfdisk_l_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_sfdisk_l") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.device = (char *) device;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_L,
+ (xdrproc_t) xdr_guestfs_sfdisk_l_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, sfdisk_l_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_l");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_L, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ return ctx.ret.partitions; /* caller will free */
+}
+
+struct sfdisk_kernel_geometry_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_sfdisk_kernel_geometry_ret ret;
+};
+
+static void sfdisk_kernel_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct sfdisk_kernel_geometry_ctx *ctx = (struct sfdisk_kernel_geometry_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_kernel_geometry");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_sfdisk_kernel_geometry");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_sfdisk_kernel_geometry");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_sfdisk_kernel_geometry_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_sfdisk_kernel_geometry");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char *guestfs_sfdisk_kernel_geometry (guestfs_h *g,
+ const char *device)
+{
+ struct guestfs_sfdisk_kernel_geometry_args args;
+ struct sfdisk_kernel_geometry_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_sfdisk_kernel_geometry") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.device = (char *) device;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY,
+ (xdrproc_t) xdr_guestfs_sfdisk_kernel_geometry_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, sfdisk_kernel_geometry_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_kernel_geometry");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ return ctx.ret.partitions; /* caller will free */
+}
+
+struct sfdisk_disk_geometry_ctx {
+ /* This flag is set by the callbacks, so we know we've done
+ * the callbacks as expected, and in the right sequence.
+ * 0 = not called, 1 = reply_cb called.
+ */
+ int cb_sequence;
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_sfdisk_disk_geometry_ret ret;
+};
+
+static void sfdisk_disk_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct sfdisk_disk_geometry_ctx *ctx = (struct sfdisk_disk_geometry_ctx *) data;
+
+ /* This should definitely not happen. */
+ if (ctx->cb_sequence != 0) {
+ ctx->cb_sequence = 9999;
+ error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_disk_geometry");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_sfdisk_disk_geometry");
+ return;
+ }
+ if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
+ error (g, "%s: failed to parse reply error", "guestfs_sfdisk_disk_geometry");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_sfdisk_disk_geometry_ret (xdr, &ctx->ret)) {
+ error (g, "%s: failed to parse reply", "guestfs_sfdisk_disk_geometry");
+ return;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+char *guestfs_sfdisk_disk_geometry (guestfs_h *g,
+ const char *device)
+{
+ struct guestfs_sfdisk_disk_geometry_args args;
+ struct sfdisk_disk_geometry_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_sfdisk_disk_geometry") == -1) return NULL;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.device = (char *) device;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_DISK_GEOMETRY,
+ (xdrproc_t) xdr_guestfs_sfdisk_disk_geometry_args, (char *) &args);
+ if (serial == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs__switch_to_receiving (g);
+ ctx.cb_sequence = 0;
+ guestfs_set_reply_callback (g, sfdisk_disk_geometry_reply_cb, &ctx);
+ (void) ml->main_loop_run (ml, g);
+ guestfs_set_reply_callback (g, NULL, NULL);
+ if (ctx.cb_sequence != 1) {
+ error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_disk_geometry");
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_DISK_GEOMETRY, serial) == -1) {
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", ctx.err.error_message);
+ free (ctx.err.error_message);
+ guestfs_end_busy (g);
+ return NULL;
+ }
+
+ guestfs_end_busy (g);
+ return ctx.ret.partitions; /* caller will free */
+}
+
diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h
index 9a4e9232..b07e3dd5 100644
--- a/src/guestfs-actions.h
+++ b/src/guestfs-actions.h
@@ -140,3 +140,8 @@ extern char **guestfs_strings (guestfs_h *handle, const char *path);
extern char **guestfs_strings_e (guestfs_h *handle, const char *encoding, const char *path);
extern char *guestfs_hexdump (guestfs_h *handle, const char *path);
extern int guestfs_zerofree (guestfs_h *handle, const char *device);
+extern int guestfs_pvresize (guestfs_h *handle, const char *device);
+extern int guestfs_sfdisk_N (guestfs_h *handle, const char *device, int n, int cyls, int heads, int sectors, const char *line);
+extern char *guestfs_sfdisk_l (guestfs_h *handle, const char *device);
+extern char *guestfs_sfdisk_kernel_geometry (guestfs_h *handle, const char *device);
+extern char *guestfs_sfdisk_disk_geometry (guestfs_h *handle, const char *device);
diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c
index c505b251..e6e865e6 100644
--- a/src/guestfs_protocol.c
+++ b/src/guestfs_protocol.c
@@ -1624,6 +1624,145 @@ xdr_guestfs_zerofree_args (XDR *xdrs, guestfs_zerofree_args *objp)
}
bool_t
+xdr_guestfs_pvresize_args (XDR *xdrs, guestfs_pvresize_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_N_args (XDR *xdrs, guestfs_sfdisk_N_args *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->n))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->n);
+ IXDR_PUT_LONG(buf, objp->cyls);
+ IXDR_PUT_LONG(buf, objp->heads);
+ IXDR_PUT_LONG(buf, objp->sectors);
+ }
+ if (!xdr_string (xdrs, &objp->line, ~0))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->n))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+
+ } else {
+ objp->n = IXDR_GET_LONG(buf);
+ objp->cyls = IXDR_GET_LONG(buf);
+ objp->heads = IXDR_GET_LONG(buf);
+ objp->sectors = IXDR_GET_LONG(buf);
+ }
+ if (!xdr_string (xdrs, &objp->line, ~0))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->n))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->line, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_l_args (XDR *xdrs, guestfs_sfdisk_l_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_l_ret (XDR *xdrs, guestfs_sfdisk_l_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->partitions, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_kernel_geometry_args (XDR *xdrs, guestfs_sfdisk_kernel_geometry_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_kernel_geometry_ret (XDR *xdrs, guestfs_sfdisk_kernel_geometry_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->partitions, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_disk_geometry_args (XDR *xdrs, guestfs_sfdisk_disk_geometry_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_disk_geometry_ret (XDR *xdrs, guestfs_sfdisk_disk_geometry_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->partitions, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp)
{
register int32_t *buf;
diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h
index a855307c..62355774 100644
--- a/src/guestfs_protocol.h
+++ b/src/guestfs_protocol.h
@@ -842,6 +842,51 @@ struct guestfs_zerofree_args {
};
typedef struct guestfs_zerofree_args guestfs_zerofree_args;
+struct guestfs_pvresize_args {
+ char *device;
+};
+typedef struct guestfs_pvresize_args guestfs_pvresize_args;
+
+struct guestfs_sfdisk_N_args {
+ char *device;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ char *line;
+};
+typedef struct guestfs_sfdisk_N_args guestfs_sfdisk_N_args;
+
+struct guestfs_sfdisk_l_args {
+ char *device;
+};
+typedef struct guestfs_sfdisk_l_args guestfs_sfdisk_l_args;
+
+struct guestfs_sfdisk_l_ret {
+ char *partitions;
+};
+typedef struct guestfs_sfdisk_l_ret guestfs_sfdisk_l_ret;
+
+struct guestfs_sfdisk_kernel_geometry_args {
+ char *device;
+};
+typedef struct guestfs_sfdisk_kernel_geometry_args guestfs_sfdisk_kernel_geometry_args;
+
+struct guestfs_sfdisk_kernel_geometry_ret {
+ char *partitions;
+};
+typedef struct guestfs_sfdisk_kernel_geometry_ret guestfs_sfdisk_kernel_geometry_ret;
+
+struct guestfs_sfdisk_disk_geometry_args {
+ char *device;
+};
+typedef struct guestfs_sfdisk_disk_geometry_args guestfs_sfdisk_disk_geometry_args;
+
+struct guestfs_sfdisk_disk_geometry_ret {
+ char *partitions;
+};
+typedef struct guestfs_sfdisk_disk_geometry_ret guestfs_sfdisk_disk_geometry_ret;
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -940,7 +985,12 @@ enum guestfs_procedure {
GUESTFS_PROC_STRINGS_E = 95,
GUESTFS_PROC_HEXDUMP = 96,
GUESTFS_PROC_ZEROFREE = 97,
- GUESTFS_PROC_NR_PROCS = 97 + 1,
+ GUESTFS_PROC_PVRESIZE = 98,
+ GUESTFS_PROC_SFDISK_N = 99,
+ GUESTFS_PROC_SFDISK_L = 100,
+ GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY = 101,
+ GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102,
+ GUESTFS_PROC_NR_PROCS = 102 + 1,
};
typedef enum guestfs_procedure guestfs_procedure;
#define GUESTFS_MESSAGE_MAX 4194304
@@ -1123,6 +1173,14 @@ extern bool_t xdr_guestfs_strings_e_ret (XDR *, guestfs_strings_e_ret*);
extern bool_t xdr_guestfs_hexdump_args (XDR *, guestfs_hexdump_args*);
extern bool_t xdr_guestfs_hexdump_ret (XDR *, guestfs_hexdump_ret*);
extern bool_t xdr_guestfs_zerofree_args (XDR *, guestfs_zerofree_args*);
+extern bool_t xdr_guestfs_pvresize_args (XDR *, guestfs_pvresize_args*);
+extern bool_t xdr_guestfs_sfdisk_N_args (XDR *, guestfs_sfdisk_N_args*);
+extern bool_t xdr_guestfs_sfdisk_l_args (XDR *, guestfs_sfdisk_l_args*);
+extern bool_t xdr_guestfs_sfdisk_l_ret (XDR *, guestfs_sfdisk_l_ret*);
+extern bool_t xdr_guestfs_sfdisk_kernel_geometry_args (XDR *, guestfs_sfdisk_kernel_geometry_args*);
+extern bool_t xdr_guestfs_sfdisk_kernel_geometry_ret (XDR *, guestfs_sfdisk_kernel_geometry_ret*);
+extern bool_t xdr_guestfs_sfdisk_disk_geometry_args (XDR *, guestfs_sfdisk_disk_geometry_args*);
+extern bool_t xdr_guestfs_sfdisk_disk_geometry_ret (XDR *, guestfs_sfdisk_disk_geometry_ret*);
extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*);
extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*);
extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*);
@@ -1264,6 +1322,14 @@ extern bool_t xdr_guestfs_strings_e_ret ();
extern bool_t xdr_guestfs_hexdump_args ();
extern bool_t xdr_guestfs_hexdump_ret ();
extern bool_t xdr_guestfs_zerofree_args ();
+extern bool_t xdr_guestfs_pvresize_args ();
+extern bool_t xdr_guestfs_sfdisk_N_args ();
+extern bool_t xdr_guestfs_sfdisk_l_args ();
+extern bool_t xdr_guestfs_sfdisk_l_ret ();
+extern bool_t xdr_guestfs_sfdisk_kernel_geometry_args ();
+extern bool_t xdr_guestfs_sfdisk_kernel_geometry_ret ();
+extern bool_t xdr_guestfs_sfdisk_disk_geometry_args ();
+extern bool_t xdr_guestfs_sfdisk_disk_geometry_ret ();
extern bool_t xdr_guestfs_procedure ();
extern bool_t xdr_guestfs_message_direction ();
extern bool_t xdr_guestfs_message_status ();
diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x
index f09e5b5b..0df5cb07 100644
--- a/src/guestfs_protocol.x
+++ b/src/guestfs_protocol.x
@@ -652,6 +652,43 @@ struct guestfs_zerofree_args {
string device<>;
};
+struct guestfs_pvresize_args {
+ string device<>;
+};
+
+struct guestfs_sfdisk_N_args {
+ string device<>;
+ int n;
+ int cyls;
+ int heads;
+ int sectors;
+ string line<>;
+};
+
+struct guestfs_sfdisk_l_args {
+ string device<>;
+};
+
+struct guestfs_sfdisk_l_ret {
+ string partitions<>;
+};
+
+struct guestfs_sfdisk_kernel_geometry_args {
+ string device<>;
+};
+
+struct guestfs_sfdisk_kernel_geometry_ret {
+ string partitions<>;
+};
+
+struct guestfs_sfdisk_disk_geometry_args {
+ string device<>;
+};
+
+struct guestfs_sfdisk_disk_geometry_ret {
+ string partitions<>;
+};
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -750,6 +787,11 @@ enum guestfs_procedure {
GUESTFS_PROC_STRINGS_E = 95,
GUESTFS_PROC_HEXDUMP = 96,
GUESTFS_PROC_ZEROFREE = 97,
+ GUESTFS_PROC_PVRESIZE = 98,
+ GUESTFS_PROC_SFDISK_N = 99,
+ GUESTFS_PROC_SFDISK_L = 100,
+ GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY = 101,
+ GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102,
GUESTFS_PROC_NR_PROCS
};
diff --git a/tests.c b/tests.c
index 11a15686..31fa3bf2 100644
--- a/tests.c
+++ b/tests.c
@@ -116,6 +116,11 @@ static void no_test_warnings (void)
fprintf (stderr, "warning: \"guestfs_debug\" has no tests\n");
fprintf (stderr, "warning: \"guestfs_get_e2label\" has no tests\n");
fprintf (stderr, "warning: \"guestfs_get_e2uuid\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_pvresize\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_sfdisk_N\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_sfdisk_l\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_sfdisk_kernel_geometry\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_sfdisk_disk_geometry\" has no tests\n");
}
static int test_zerofree_0 (void)