summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2009-05-18 17:16:24 +0100
committerRichard Jones <rjones@redhat.com>2009-05-18 17:16:24 +0100
commit85ed8cef99c19b4143844991d14e0b848fecc5da (patch)
tree61e34886d4ec4b59a37c8e4ab6779e7ef7834f34
parentadf0974245af914c46b48766d0efdd5ee8608dda (diff)
downloadlibguestfs-85ed8cef99c19b4143844991d14e0b848fecc5da.tar.gz
libguestfs-85ed8cef99c19b4143844991d14e0b848fecc5da.tar.xz
libguestfs-85ed8cef99c19b4143844991d14e0b848fecc5da.zip
Add vg-activate{,-all} commands, and resize recipe.
-rw-r--r--TODO22
-rw-r--r--daemon/actions.h2
-rw-r--r--daemon/lvm.c39
-rw-r--r--daemon/sfdisk.c5
-rw-r--r--daemon/stubs.c63
-rw-r--r--fish/cmds.c44
-rw-r--r--fish/completion.c2
-rw-r--r--guestfish-actions.pod27
-rw-r--r--guestfs-actions.pod34
-rw-r--r--java/com/redhat/et/libguestfs/GuestFS.java50
-rw-r--r--java/com_redhat_et_libguestfs_GuestFS.c47
-rw-r--r--ocaml/guestfs.ml2
-rw-r--r--ocaml/guestfs.mli6
-rw-r--r--ocaml/guestfs_c_actions.c48
-rw-r--r--perl/Guestfs.xs24
-rw-r--r--perl/lib/Sys/Guestfs.pm23
-rw-r--r--python/guestfs-py.c57
-rw-r--r--python/guestfs.py26
-rw-r--r--recipes/resize.html19
-rwxr-xr-xrecipes/resize.sh35
-rw-r--r--recipes/resize.title1
-rw-r--r--ruby/ext/guestfs/_guestfs.c51
-rwxr-xr-xsrc/generator.ml27
-rw-r--r--src/guestfs-actions.c177
-rw-r--r--src/guestfs-actions.h2
-rw-r--r--src/guestfs_protocol.c23
-rw-r--r--src/guestfs_protocol.h22
-rw-r--r--src/guestfs_protocol.x11
-rw-r--r--tests.c2
29 files changed, 867 insertions, 24 deletions
diff --git a/TODO b/TODO
index 323dc0b4..71c9d59e 100644
--- a/TODO
+++ b/TODO
@@ -27,25 +27,3 @@ Implement febootstrap command.
----------------------------------------------------------------------
Complete the Haskell bindings (see discussion on haskell-cafe).
-
-----------------------------------------------------------------------
-
-Practically, resizing the partitions when a block device is resized
-isn't possible. So for example it's not possible to resize a Fedora
-block device. If you try to use sfdisk-N to change the boundaries of
-the existing partition to fill up the new space, you get an error that
-the partition is in use.
-
-The reason, I now think, is because LVM is using the partition as a
-PV, and this locks it as far as the kernel is concerned.
-
-Removing the PV [which is what we do in the test suite] isn't
-desirable if the PV contains data you care about. Rebooting the qemu
-subprocess after the partition table change works, but isn't very
-cool. I believe what we need to do is to temporarily reconfigure LVM
-(using /etc/lvm/lvm.conf) to ignore the PV, vgscan (which will then
-ignore the PV), make the changes to the partition table, then set the
-LVM configuration back and do a final vgscan.
-
-Need to test the above, and find a nice way to present it through
-the API.
diff --git a/daemon/actions.h b/daemon/actions.h
index 3e6589e2..dcffd2a2 100644
--- a/daemon/actions.h
+++ b/daemon/actions.h
@@ -123,3 +123,5 @@ extern int do_sfdisk_N (const char *device, int n, int cyls, int heads, int sect
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);
+extern int do_vg_activate_all (int activate);
+extern int do_vg_activate (int activate, char * const* const volgroups);
diff --git a/daemon/lvm.c b/daemon/lvm.c
index d1a6cd60..63a3e7e5 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -376,3 +376,42 @@ do_pvresize (const char *device)
free (err);
return 0;
}
+
+int
+do_vg_activate (int activate, char * const* const volgroups)
+{
+ char *err;
+ int r, i, argc;
+ const char **argv;
+
+ argc = count_strings (volgroups) + 4;
+ argv = malloc (sizeof (char *) * (argc+1));
+ if (argv == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ argv[0] = "/sbin/lvm";
+ argv[1] = "vgchange";
+ argv[2] = "-a";
+ argv[3] = activate ? "y" : "n";
+ for (i = 4; i <= argc; ++i)
+ argv[i] = volgroups[i-4];
+
+ r = commandv (NULL, &err, argv);
+ if (r == -1) {
+ reply_with_error ("vgchange: %s", err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
+
+int
+do_vg_activate_all (int activate)
+{
+ char *empty[] = { NULL };
+ return do_vg_activate (activate, empty);
+}
diff --git a/daemon/sfdisk.c b/daemon/sfdisk.c
index 9d7a220f..2f5206ed 100644
--- a/daemon/sfdisk.c
+++ b/daemon/sfdisk.c
@@ -39,7 +39,7 @@ sfdisk (const char *device, int n, int cyls, int heads, int sectors,
IS_DEVICE (device, -1);
- strcpy (buf, "/sbin/sfdisk --no-reread");
+ strcpy (buf, "/sbin/sfdisk");
if (n > 0)
sprintf (buf + strlen (buf), " -N %d", n);
if (cyls)
@@ -51,6 +51,9 @@ sfdisk (const char *device, int n, int cyls, int heads, int sectors,
/* Safe because of IS_DEVICE above: */
sprintf (buf + strlen (buf), " %s", device);
+ if (verbose)
+ printf ("%s\n", buf);
+
fp = popen (buf, "w");
if (fp == NULL) {
reply_with_perror (buf);
diff --git a/daemon/stubs.c b/daemon/stubs.c
index e80ba9be..2fd2da93 100644
--- a/daemon/stubs.c
+++ b/daemon/stubs.c
@@ -2560,6 +2560,63 @@ done:
xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_disk_geometry_args, (char *) &args);
}
+static void vg_activate_all_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_vg_activate_all_args args;
+ int activate;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_vg_activate_all_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "vg_activate_all");
+ return;
+ }
+ activate = args.activate;
+
+ r = do_vg_activate_all (activate);
+ if (r == -1)
+ /* do_vg_activate_all has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_vg_activate_all_args, (char *) &args);
+}
+
+static void vg_activate_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_vg_activate_args args;
+ int activate;
+ char **volgroups;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_vg_activate_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "vg_activate");
+ return;
+ }
+ activate = args.activate;
+ volgroups = realloc (args.volgroups.volgroups_val,
+ sizeof (char *) * (args.volgroups.volgroups_len+1));
+ if (volgroups == NULL) {
+ reply_with_perror ("realloc");
+ goto done;
+ }
+ volgroups[args.volgroups.volgroups_len] = NULL;
+ args.volgroups.volgroups_val = volgroups;
+
+ r = do_vg_activate (activate, volgroups);
+ if (r == -1)
+ /* do_vg_activate has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_vg_activate_args, (char *) &args);
+}
+
void dispatch_incoming_message (XDR *xdr_in)
{
switch (proc_nr) {
@@ -2869,6 +2926,12 @@ void dispatch_incoming_message (XDR *xdr_in)
case GUESTFS_PROC_SFDISK_DISK_GEOMETRY:
sfdisk_disk_geometry_stub (xdr_in);
break;
+ case GUESTFS_PROC_VG_ACTIVATE_ALL:
+ vg_activate_all_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_VG_ACTIVATE:
+ vg_activate_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 5680bfa3..8d50021e 100644
--- a/fish/cmds.c
+++ b/fish/cmds.c
@@ -146,6 +146,8 @@ void list_commands (void)
printf ("%-20s %s\n", "umount", "unmount a filesystem");
printf ("%-20s %s\n", "umount-all", "unmount all filesystems");
printf ("%-20s %s\n", "upload", "upload a file from the local machine");
+ printf ("%-20s %s\n", "vg-activate", "activate or deactivate some volume groups");
+ printf ("%-20s %s\n", "vg-activate-all", "activate or deactivate all volume groups");
printf ("%-20s %s\n", "vgcreate", "create an LVM volume group");
printf ("%-20s %s\n", "vgremove", "remove an LVM volume group");
printf ("%-20s %s\n", "vgs", "list the LVM volume groups (VGs)");
@@ -524,6 +526,12 @@ void display_command (const char *cmd)
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
+ if (strcasecmp (cmd, "vg_activate_all") == 0 || strcasecmp (cmd, "vg-activate-all") == 0)
+ pod2text ("vg-activate-all - activate or deactivate all volume groups", " vg-activate-all <activate>\n\nThis command activates or (if C<activate> is false) deactivates\nall logical volumes in all volume groups.\nIf activated, then they are made known to the\nkernel, ie. they appear as C</dev/mapper> devices. If deactivated,\nthen those devices disappear.\n\nThis command is the same as running C<vgchange -a y|n>");
+ else
+ if (strcasecmp (cmd, "vg_activate") == 0 || strcasecmp (cmd, "vg-activate") == 0)
+ pod2text ("vg-activate - activate or deactivate some volume groups", " vg-activate <activate> <volgroups>\n\nThis command activates or (if C<activate> is false) deactivates\nall logical volumes in the listed volume groups C<volgroups>.\nIf activated, then they are made known to the\nkernel, ie. they appear as C</dev/mapper> devices. If deactivated,\nthen those devices disappear.\n\nThis command is the same as running C<vgchange -a y|n volgroups...>\n\nNote that if C<volgroups> is an empty list then B<all> volume groups\nare activated or deactivated.");
+ else
display_builtin_command (cmd);
}
@@ -2565,6 +2573,36 @@ static int run_sfdisk_disk_geometry (const char *cmd, int argc, char *argv[])
return 0;
}
+static int run_vg_activate_all (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ int activate;
+ 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;
+ }
+ activate = is_true (argv[0]) ? 1 : 0;
+ r = guestfs_vg_activate_all (g, activate);
+ return r;
+}
+
+static int run_vg_activate (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ int activate;
+ char **volgroups;
+ if (argc != 2) {
+ fprintf (stderr, "%s should have 2 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ activate = is_true (argv[0]) ? 1 : 0;
+ volgroups = parse_string_list (argv[1]);
+ r = guestfs_vg_activate (g, activate, volgroups);
+ return r;
+}
+
int run_action (const char *cmd, int argc, char *argv[])
{
if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
@@ -2933,6 +2971,12 @@ int run_action (const char *cmd, int argc, char *argv[])
if (strcasecmp (cmd, "sfdisk_disk_geometry") == 0 || strcasecmp (cmd, "sfdisk-disk-geometry") == 0)
return run_sfdisk_disk_geometry (cmd, argc, argv);
else
+ if (strcasecmp (cmd, "vg_activate_all") == 0 || strcasecmp (cmd, "vg-activate-all") == 0)
+ return run_vg_activate_all (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "vg_activate") == 0 || strcasecmp (cmd, "vg-activate") == 0)
+ return run_vg_activate (cmd, argc, argv);
+ else
{
fprintf (stderr, "%s: unknown command\n", cmd);
return -1;
diff --git a/fish/completion.c b/fish/completion.c
index 03760ad6..a072ce36 100644
--- a/fish/completion.c
+++ b/fish/completion.c
@@ -159,6 +159,8 @@ static const char *const commands[] = {
"unmount-all",
"upload",
"verbose",
+ "vg-activate",
+ "vg-activate-all",
"vgcreate",
"vgremove",
"vgs",
diff --git a/guestfish-actions.pod b/guestfish-actions.pod
index 213fa66e..7e33cbbe 100644
--- a/guestfish-actions.pod
+++ b/guestfish-actions.pod
@@ -1268,6 +1268,33 @@ See also C<download>.
Use C<-> instead of a filename to read/write from stdin/stdout.
+=head2 vg-activate
+
+ vg-activate true|false 'volgroups ...'
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in the listed volume groups C<volgroups>.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n volgroups...>
+
+Note that if C<volgroups> is an empty list then B<all> volume groups
+are activated or deactivated.
+
+=head2 vg-activate-all
+
+ vg-activate-all true|false
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in all volume groups.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n>
+
=head2 vgcreate
vgcreate volgroup 'physvols ...'
diff --git a/guestfs-actions.pod b/guestfs-actions.pod
index abeed8ff..9ed1cce4 100644
--- a/guestfs-actions.pod
+++ b/guestfs-actions.pod
@@ -1719,6 +1719,40 @@ See also C<guestfs_download>.
This function returns 0 on success or -1 on error.
+=head2 guestfs_vg_activate
+
+ int guestfs_vg_activate (guestfs_h *handle,
+ int activate,
+ char * const* const volgroups);
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in the listed volume groups C<volgroups>.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n volgroups...>
+
+Note that if C<volgroups> is an empty list then B<all> volume groups
+are activated or deactivated.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_vg_activate_all
+
+ int guestfs_vg_activate_all (guestfs_h *handle,
+ int activate);
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in all volume groups.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n>
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_vgcreate
int guestfs_vgcreate (guestfs_h *handle,
diff --git a/java/com/redhat/et/libguestfs/GuestFS.java b/java/com/redhat/et/libguestfs/GuestFS.java
index 7eafce0f..a6d6f6db 100644
--- a/java/com/redhat/et/libguestfs/GuestFS.java
+++ b/java/com/redhat/et/libguestfs/GuestFS.java
@@ -2864,4 +2864,54 @@ public class GuestFS {
private native String _sfdisk_disk_geometry (long g, String device)
throws LibGuestFSException;
+ /**
+ * activate or deactivate all volume groups
+ *
+ * This command activates or (if "activate" is false)
+ * deactivates all logical volumes in all volume groups. If
+ * activated, then they are made known to the kernel, ie.
+ * they appear as "/dev/mapper" devices. If deactivated,
+ * then those devices disappear.
+ *
+ * This command is the same as running "vgchange -a y|n"
+ *
+ * @throws LibGuestFSException
+ */
+ public void vg_activate_all (boolean activate)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("vg_activate_all: handle is closed");
+ _vg_activate_all (g, activate);
+ }
+ private native void _vg_activate_all (long g, boolean activate)
+ throws LibGuestFSException;
+
+ /**
+ * activate or deactivate some volume groups
+ *
+ * This command activates or (if "activate" is false)
+ * deactivates all logical volumes in the listed volume
+ * groups "volgroups". If activated, then they are made
+ * known to the kernel, ie. they appear as "/dev/mapper"
+ * devices. If deactivated, then those devices disappear.
+ *
+ * This command is the same as running "vgchange -a y|n
+ * volgroups..."
+ *
+ * Note that if "volgroups" is an empty list then all
+ * volume groups are activated or deactivated.
+ *
+ * @throws LibGuestFSException
+ */
+ public void vg_activate (boolean activate, String[] volgroups)
+ throws LibGuestFSException
+ {
+ if (g == 0)
+ throw new LibGuestFSException ("vg_activate: handle is closed");
+ _vg_activate (g, activate, volgroups);
+ }
+ private native void _vg_activate (long g, boolean activate, String[] volgroups)
+ throws LibGuestFSException;
+
}
diff --git a/java/com_redhat_et_libguestfs_GuestFS.c b/java/com_redhat_et_libguestfs_GuestFS.c
index be7ea9f2..3bf5c7e5 100644
--- a/java/com_redhat_et_libguestfs_GuestFS.c
+++ b/java/com_redhat_et_libguestfs_GuestFS.c
@@ -2847,3 +2847,50 @@ Java_com_redhat_et_libguestfs_GuestFS__1sfdisk_1disk_1geometry
return jr;
}
+JNIEXPORT void JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1vg_1activate_1all
+ (JNIEnv *env, jobject obj, jlong jg, jboolean jactivate)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ int r;
+ int activate;
+
+ activate = jactivate;
+ r = guestfs_vg_activate_all (g, activate);
+ if (r == -1) {
+ throw_exception (env, guestfs_last_error (g));
+ return ;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_redhat_et_libguestfs_GuestFS__1vg_1activate
+ (JNIEnv *env, jobject obj, jlong jg, jboolean jactivate, jobjectArray jvolgroups)
+{
+ guestfs_h *g = (guestfs_h *) (long) jg;
+ int r;
+ int activate;
+ int volgroups_len;
+ const char **volgroups;
+ int i;
+
+ activate = jactivate;
+ volgroups_len = (*env)->GetArrayLength (env, jvolgroups);
+ volgroups = guestfs_safe_malloc (g, sizeof (char *) * (volgroups_len+1));
+ for (i = 0; i < volgroups_len; ++i) {
+ jobject o = (*env)->GetObjectArrayElement (env, jvolgroups, i);
+ volgroups[i] = (*env)->GetStringUTFChars (env, o, NULL);
+ }
+ volgroups[volgroups_len] = NULL;
+ r = guestfs_vg_activate (g, activate, volgroups);
+ for (i = 0; i < volgroups_len; ++i) {
+ jobject o = (*env)->GetObjectArrayElement (env, jvolgroups, i);
+ (*env)->ReleaseStringUTFChars (env, o, volgroups[i]);
+ }
+ free (volgroups);
+ if (r == -1) {
+ throw_exception (env, guestfs_last_error (g));
+ return ;
+ }
+}
+
diff --git a/ocaml/guestfs.ml b/ocaml/guestfs.ml
index d50b2d8c..fa60a7bb 100644
--- a/ocaml/guestfs.ml
+++ b/ocaml/guestfs.ml
@@ -241,3 +241,5 @@ external sfdisk_N : t -> string -> int -> int -> int -> int -> string -> unit =
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"
+external vg_activate_all : t -> bool -> unit = "ocaml_guestfs_vg_activate_all"
+external vg_activate : t -> bool -> string array -> unit = "ocaml_guestfs_vg_activate"
diff --git a/ocaml/guestfs.mli b/ocaml/guestfs.mli
index 358a6d30..5ce91220 100644
--- a/ocaml/guestfs.mli
+++ b/ocaml/guestfs.mli
@@ -502,3 +502,9 @@ val sfdisk_kernel_geometry : t -> string -> string
val sfdisk_disk_geometry : t -> string -> string
(** display the disk geometry from the partition table *)
+val vg_activate_all : t -> bool -> unit
+(** activate or deactivate all volume groups *)
+
+val vg_activate : t -> bool -> string array -> unit
+(** activate or deactivate some volume groups *)
+
diff --git a/ocaml/guestfs_c_actions.c b/ocaml/guestfs_c_actions.c
index f2d13b03..f0aa7e23 100644
--- a/ocaml/guestfs_c_actions.c
+++ b/ocaml/guestfs_c_actions.c
@@ -3331,3 +3331,51 @@ ocaml_guestfs_sfdisk_disk_geometry (value gv, value devicev)
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_guestfs_vg_activate_all (value gv, value activatev)
+{
+ CAMLparam2 (gv, activatev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("vg_activate_all: used handle after closing it");
+
+ int activate = Bool_val (activatev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_vg_activate_all (g, activate);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "vg_activate_all");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_vg_activate (value gv, value activatev, value volgroupsv)
+{
+ CAMLparam3 (gv, activatev, volgroupsv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("vg_activate: used handle after closing it");
+
+ int activate = Bool_val (activatev);
+ char **volgroups = ocaml_guestfs_strings_val (g, volgroupsv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_vg_activate (g, activate, volgroups);
+ caml_leave_blocking_section ();
+ ocaml_guestfs_free_strings (volgroups);
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "vg_activate");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs
index ff7ca9e1..374a40d1 100644
--- a/perl/Guestfs.xs
+++ b/perl/Guestfs.xs
@@ -1870,3 +1870,27 @@ PREINIT:
OUTPUT:
RETVAL
+void
+vg_activate_all (g, activate)
+ guestfs_h *g;
+ int activate;
+PREINIT:
+ int r;
+ PPCODE:
+ r = guestfs_vg_activate_all (g, activate);
+ if (r == -1)
+ croak ("vg_activate_all: %s", guestfs_last_error (g));
+
+void
+vg_activate (g, activate, volgroups)
+ guestfs_h *g;
+ int activate;
+ char **volgroups;
+PREINIT:
+ int r;
+ PPCODE:
+ r = guestfs_vg_activate (g, activate, volgroups);
+ free (volgroups);
+ if (r == -1)
+ croak ("vg_activate: %s", guestfs_last_error (g));
+
diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm
index 0249a412..0e4dde4d 100644
--- a/perl/lib/Sys/Guestfs.pm
+++ b/perl/lib/Sys/Guestfs.pm
@@ -1141,6 +1141,29 @@ C<filename> can also be a named pipe.
See also C<$h-E<gt>download>.
+=item $h->vg_activate ($activate, \@volgroups);
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in the listed volume groups C<volgroups>.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n volgroups...>
+
+Note that if C<volgroups> is an empty list then B<all> volume groups
+are activated or deactivated.
+
+=item $h->vg_activate_all ($activate);
+
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in all volume groups.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n>
+
=item $h->vgcreate ($volgroup, \@physvols);
This creates an LVM volume group called C<volgroup>
diff --git a/python/guestfs-py.c b/python/guestfs-py.c
index 140594d2..e967bd94 100644
--- a/python/guestfs-py.c
+++ b/python/guestfs-py.c
@@ -3557,6 +3557,61 @@ py_guestfs_sfdisk_disk_geometry (PyObject *self, PyObject *args)
return py_r;
}
+static PyObject *
+py_guestfs_vg_activate_all (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ int r;
+ int activate;
+
+ if (!PyArg_ParseTuple (args, (char *) "Oi:guestfs_vg_activate_all",
+ &py_g, &activate))
+ return NULL;
+ g = get_handle (py_g);
+
+ r = guestfs_vg_activate_all (g, activate);
+ 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_vg_activate (PyObject *self, PyObject *args)
+{
+ PyObject *py_g;
+ guestfs_h *g;
+ PyObject *py_r;
+ int r;
+ int activate;
+ PyObject *py_volgroups;
+ const char **volgroups;
+
+ if (!PyArg_ParseTuple (args, (char *) "OiO:guestfs_vg_activate",
+ &py_g, &activate, &py_volgroups))
+ return NULL;
+ g = get_handle (py_g);
+ volgroups = get_string_list (py_volgroups);
+ if (!volgroups) return NULL;
+
+ r = guestfs_vg_activate (g, activate, volgroups);
+ free (volgroups);
+ 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 PyMethodDef methods[] = {
{ (char *) "create", py_guestfs_create, METH_VARARGS, NULL },
{ (char *) "close", py_guestfs_close, METH_VARARGS, NULL },
@@ -3686,6 +3741,8 @@ static PyMethodDef methods[] = {
{ (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 },
+ { (char *) "vg_activate_all", py_guestfs_vg_activate_all, METH_VARARGS, NULL },
+ { (char *) "vg_activate", py_guestfs_vg_activate, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
diff --git a/python/guestfs.py b/python/guestfs.py
index 8ac4037c..4a2804b4 100644
--- a/python/guestfs.py
+++ b/python/guestfs.py
@@ -1397,3 +1397,29 @@ class GuestFS:
"""
return libguestfsmod.sfdisk_disk_geometry (self._o, device)
+ def vg_activate_all (self, activate):
+ u"""This command activates or (if "activate" is false)
+ deactivates all logical volumes in all volume groups. If
+ activated, then they are made known to the kernel, ie.
+ they appear as "/dev/mapper" devices. If deactivated,
+ then those devices disappear.
+
+ This command is the same as running "vgchange -a y|n"
+ """
+ return libguestfsmod.vg_activate_all (self._o, activate)
+
+ def vg_activate (self, activate, volgroups):
+ u"""This command activates or (if "activate" is false)
+ deactivates all logical volumes in the listed volume
+ groups "volgroups". If activated, then they are made
+ known to the kernel, ie. they appear as "/dev/mapper"
+ devices. If deactivated, then those devices disappear.
+
+ This command is the same as running "vgchange -a y|n
+ volgroups..."
+
+ Note that if "volgroups" is an empty list then all
+ volume groups are activated or deactivated.
+ """
+ return libguestfsmod.vg_activate (self._o, activate, volgroups)
+
diff --git a/recipes/resize.html b/recipes/resize.html
new file mode 100644
index 00000000..1a0ca3bb
--- /dev/null
+++ b/recipes/resize.html
@@ -0,0 +1,19 @@
+<p>
+This example shows how a block device containing a partition
+and a physical volume can be resized.
+</p>
+
+<p>
+If you try this out, you
+may find that attempts to repartition the disk fail because the
+disk is locked by the LVM devices which exist on it. You have
+to deactivate (temporarily) the volume groups, perform the
+fdisk, and then activate them again.
+</p>
+
+<p>
+This example script is self-contained. It first creates a
+block device (a temporary file) containing some LVs, then it extends
+the temporary file, and shows how to deactivate volgroups, repartition,
+and activate them again.
+</p>
diff --git a/recipes/resize.sh b/recipes/resize.sh
new file mode 100755
index 00000000..17a7e770
--- /dev/null
+++ b/recipes/resize.sh
@@ -0,0 +1,35 @@
+#!/bin/sh -
+
+guestfish <<EOF
+alloc test.img 130M
+run
+# You can uncomment the following to see the
+# geometry (CHS), which is needed to repartition.
+#sfdisk-disk-geometry /dev/sda
+sfdisk /dev/sda 0 0 0 ,
+pvcreate /dev/sda1
+vgcreate VG /dev/sda1
+lvcreate LV1 VG 32M
+lvcreate LV2 VG 32M
+lvcreate LV3 VG 32M
+sync
+EOF
+
+truncate --size=260M test.img
+
+guestfish -a test.img <<EOF
+run
+# Turn off the VGs before we can repartition.
+vg-activate-all false
+sfdisk-N /dev/sda 1 32 255 63 0,31
+vg-activate-all true
+
+pvresize /dev/sda1
+
+# The following command would fail if the
+# partition or PV hadn't been resized:
+lvcreate LV4 VG 64M
+
+echo New LV list:
+lvs
+EOF \ No newline at end of file
diff --git a/recipes/resize.title b/recipes/resize.title
new file mode 100644
index 00000000..cc2f3a23
--- /dev/null
+++ b/recipes/resize.title
@@ -0,0 +1 @@
+Repartition and resize a block device \ No newline at end of file
diff --git a/ruby/ext/guestfs/_guestfs.c b/ruby/ext/guestfs/_guestfs.c
index b5c9b53a..c57dcb3a 100644
--- a/ruby/ext/guestfs/_guestfs.c
+++ b/ruby/ext/guestfs/_guestfs.c
@@ -3025,6 +3025,53 @@ static VALUE ruby_guestfs_sfdisk_disk_geometry (VALUE gv, VALUE devicev)
return rv;
}
+static VALUE ruby_guestfs_vg_activate_all (VALUE gv, VALUE activatev)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "vg_activate_all");
+
+ int activate = NUM2INT (activatev);
+
+ int r;
+
+ r = guestfs_vg_activate_all (g, activate);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
+static VALUE ruby_guestfs_vg_activate (VALUE gv, VALUE activatev, VALUE volgroupsv)
+{
+ guestfs_h *g;
+ Data_Get_Struct (gv, guestfs_h, g);
+ if (!g)
+ rb_raise (rb_eArgError, "%s: used handle after closing it", "vg_activate");
+
+ int activate = NUM2INT (activatev);
+ char **volgroups; {
+ int i, len;
+ len = RARRAY_LEN (volgroupsv);
+ volgroups = guestfs_safe_malloc (g, sizeof (char *) * (len+1));
+ for (i = 0; i < len; ++i) {
+ VALUE v = rb_ary_entry (volgroupsv, i);
+ volgroups[i] = StringValueCStr (v);
+ }
+ volgroups[len] = NULL;
+ }
+
+ int r;
+
+ r = guestfs_vg_activate (g, activate, volgroups);
+ free (volgroups);
+ if (r == -1)
+ rb_raise (e_Error, "%s", guestfs_last_error (g));
+
+ return Qnil;
+}
+
/* Initialize the module. */
void Init__guestfs ()
{
@@ -3287,4 +3334,8 @@ void Init__guestfs ()
ruby_guestfs_sfdisk_kernel_geometry, 1);
rb_define_method (c_guestfs, "sfdisk_disk_geometry",
ruby_guestfs_sfdisk_disk_geometry, 1);
+ rb_define_method (c_guestfs, "vg_activate_all",
+ ruby_guestfs_vg_activate_all, 1);
+ rb_define_method (c_guestfs, "vg_activate",
+ ruby_guestfs_vg_activate, 2);
}
diff --git a/src/generator.ml b/src/generator.ml
index 19dc20d5..5717f9b6 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -2069,6 +2069,33 @@ 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.");
+ ("vg_activate_all", (RErr, [Bool "activate"]), 103, [],
+ [],
+ "activate or deactivate all volume groups",
+ "\
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in all volume groups.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n>");
+
+ ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [],
+ [],
+ "activate or deactivate some volume groups",
+ "\
+This command activates or (if C<activate> is false) deactivates
+all logical volumes in the listed volume groups C<volgroups>.
+If activated, then they are made known to the
+kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
+then those devices disappear.
+
+This command is the same as running C<vgchange -a y|n volgroups...>
+
+Note that if C<volgroups> is an empty list then B<all> volume groups
+are activated or deactivated.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c
index 49e8961d..41d873f9 100644
--- a/src/guestfs-actions.c
+++ b/src/guestfs-actions.c
@@ -9356,3 +9356,180 @@ char *guestfs_sfdisk_disk_geometry (guestfs_h *g,
return ctx.ret.partitions; /* caller will free */
}
+struct vg_activate_all_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 vg_activate_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct vg_activate_all_ctx *ctx = (struct vg_activate_all_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_vg_activate_all");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_vg_activate_all");
+ 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_vg_activate_all");
+ return;
+ }
+ goto done;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+int guestfs_vg_activate_all (guestfs_h *g,
+ int activate)
+{
+ struct guestfs_vg_activate_all_args args;
+ struct vg_activate_all_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_vg_activate_all") == -1) return -1;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.activate = activate;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_VG_ACTIVATE_ALL,
+ (xdrproc_t) xdr_guestfs_vg_activate_all_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, vg_activate_all_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_vg_activate_all");
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VG_ACTIVATE_ALL, 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 vg_activate_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 vg_activate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ struct vg_activate_ctx *ctx = (struct vg_activate_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_vg_activate");
+ return;
+ }
+
+ ml->main_loop_quit (ml, g);
+
+ if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
+ error (g, "%s: failed to parse reply header", "guestfs_vg_activate");
+ 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_vg_activate");
+ return;
+ }
+ goto done;
+ }
+ done:
+ ctx->cb_sequence = 1;
+}
+
+int guestfs_vg_activate (guestfs_h *g,
+ int activate,
+ char * const* const volgroups)
+{
+ struct guestfs_vg_activate_args args;
+ struct vg_activate_ctx ctx;
+ guestfs_main_loop *ml = guestfs_get_main_loop (g);
+ int serial;
+
+ if (check_state (g, "guestfs_vg_activate") == -1) return -1;
+ guestfs_set_busy (g);
+
+ memset (&ctx, 0, sizeof ctx);
+
+ args.activate = activate;
+ args.volgroups.volgroups_val = (char **) volgroups;
+ for (args.volgroups.volgroups_len = 0; volgroups[args.volgroups.volgroups_len]; args.volgroups.volgroups_len++) ;
+ serial = guestfs__send_sync (g, GUESTFS_PROC_VG_ACTIVATE,
+ (xdrproc_t) xdr_guestfs_vg_activate_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, vg_activate_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_vg_activate");
+ guestfs_end_busy (g);
+ return -1;
+ }
+
+ if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VG_ACTIVATE, 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;
+}
+
diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h
index b07e3dd5..3c760f23 100644
--- a/src/guestfs-actions.h
+++ b/src/guestfs-actions.h
@@ -145,3 +145,5 @@ extern int guestfs_sfdisk_N (guestfs_h *handle, const char *device, int n, int c
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);
+extern int guestfs_vg_activate_all (guestfs_h *handle, int activate);
+extern int guestfs_vg_activate (guestfs_h *handle, int activate, char * const* const volgroups);
diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c
index e6e865e6..0a3fddc0 100644
--- a/src/guestfs_protocol.c
+++ b/src/guestfs_protocol.c
@@ -1763,6 +1763,29 @@ xdr_guestfs_sfdisk_disk_geometry_ret (XDR *xdrs, guestfs_sfdisk_disk_geometry_re
}
bool_t
+xdr_guestfs_vg_activate_all_args (XDR *xdrs, guestfs_vg_activate_all_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->activate))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_vg_activate_args (XDR *xdrs, guestfs_vg_activate_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->activate))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->volgroups.volgroups_val, (u_int *) &objp->volgroups.volgroups_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ 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 62355774..25ed3529 100644
--- a/src/guestfs_protocol.h
+++ b/src/guestfs_protocol.h
@@ -887,6 +887,20 @@ struct guestfs_sfdisk_disk_geometry_ret {
};
typedef struct guestfs_sfdisk_disk_geometry_ret guestfs_sfdisk_disk_geometry_ret;
+struct guestfs_vg_activate_all_args {
+ bool_t activate;
+};
+typedef struct guestfs_vg_activate_all_args guestfs_vg_activate_all_args;
+
+struct guestfs_vg_activate_args {
+ bool_t activate;
+ struct {
+ u_int volgroups_len;
+ str *volgroups_val;
+ } volgroups;
+};
+typedef struct guestfs_vg_activate_args guestfs_vg_activate_args;
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -990,7 +1004,9 @@ enum guestfs_procedure {
GUESTFS_PROC_SFDISK_L = 100,
GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY = 101,
GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102,
- GUESTFS_PROC_NR_PROCS = 102 + 1,
+ GUESTFS_PROC_VG_ACTIVATE_ALL = 103,
+ GUESTFS_PROC_VG_ACTIVATE = 104,
+ GUESTFS_PROC_NR_PROCS = 104 + 1,
};
typedef enum guestfs_procedure guestfs_procedure;
#define GUESTFS_MESSAGE_MAX 4194304
@@ -1181,6 +1197,8 @@ extern bool_t xdr_guestfs_sfdisk_kernel_geometry_args (XDR *, guestfs_sfdisk_ke
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_vg_activate_all_args (XDR *, guestfs_vg_activate_all_args*);
+extern bool_t xdr_guestfs_vg_activate_args (XDR *, guestfs_vg_activate_args*);
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*);
@@ -1330,6 +1348,8 @@ 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_vg_activate_all_args ();
+extern bool_t xdr_guestfs_vg_activate_args ();
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 0df5cb07..38bb8ea9 100644
--- a/src/guestfs_protocol.x
+++ b/src/guestfs_protocol.x
@@ -689,6 +689,15 @@ struct guestfs_sfdisk_disk_geometry_ret {
string partitions<>;
};
+struct guestfs_vg_activate_all_args {
+ bool activate;
+};
+
+struct guestfs_vg_activate_args {
+ bool activate;
+ str volgroups<>;
+};
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
@@ -792,6 +801,8 @@ enum guestfs_procedure {
GUESTFS_PROC_SFDISK_L = 100,
GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY = 101,
GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102,
+ GUESTFS_PROC_VG_ACTIVATE_ALL = 103,
+ GUESTFS_PROC_VG_ACTIVATE = 104,
GUESTFS_PROC_NR_PROCS
};
diff --git a/tests.c b/tests.c
index 31fa3bf2..b3443208 100644
--- a/tests.c
+++ b/tests.c
@@ -121,6 +121,8 @@ static void no_test_warnings (void)
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");
+ fprintf (stderr, "warning: \"guestfs_vg_activate_all\" has no tests\n");
+ fprintf (stderr, "warning: \"guestfs_vg_activate\" has no tests\n");
}
static int test_zerofree_0 (void)