{
printf (" %-16s %s\n", "Command", "Description");
list_builtin_commands ();
+ printf ("%-20s %s\n", "add-cdrom", "add a CD-ROM disk image to examine");
+ printf ("%-20s %s\n", "add-drive", "add an image to examine or modify");
printf ("%-20s %s\n", "cat", "list the contents of a file");
+ printf ("%-20s %s\n", "config", "add qemu parameters");
+ printf ("%-20s %s\n", "get-autosync", "get autosync mode");
+ printf ("%-20s %s\n", "get-path", "get the search path");
+ printf ("%-20s %s\n", "get-verbose", "get verbose mode");
+ printf ("%-20s %s\n", "kill-subprocess", "kill the qemu subprocess");
+ printf ("%-20s %s\n", "launch", "launch the qemu subprocess");
printf ("%-20s %s\n", "list-devices", "list the block devices");
printf ("%-20s %s\n", "list-partitions", "list the partitions");
printf ("%-20s %s\n", "ll", "list the files in a directory (long format)");
printf ("%-20s %s\n", "mount", "mount a guest disk at a position in the filesystem");
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", "set-autosync", "set autosync mode");
+ printf ("%-20s %s\n", "set-path", "set the search path");
+ printf ("%-20s %s\n", "set-verbose", "set verbose mode");
printf ("%-20s %s\n", "sync", "sync disks, writes are flushed through to the disk image");
printf ("%-20s %s\n", "touch", "update file timestamps or create a new file");
printf ("%-20s %s\n", "vgs", "list the LVM volume groups (VGs)");
void display_command (const char *cmd)
{
+ if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
+ pod2text ("launch - launch the qemu subprocess", " launch\n\nInternally libguestfs is implemented by running a virtual machine\nusing L<qemu(1)>.\n\nYou should call this after configuring the handle\n(eg. adding drives) but before performing any actions.\n\nYou can use 'run' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "kill_subprocess") == 0 || strcasecmp (cmd, "kill-subprocess") == 0)
+ pod2text ("kill-subprocess - kill the qemu subprocess", " kill-subprocess\n\nThis kills the qemu subprocess. You should never need to call this.");
+ else
+ if (strcasecmp (cmd, "add_drive") == 0 || strcasecmp (cmd, "add-drive") == 0 || strcasecmp (cmd, "add") == 0)
+ pod2text ("add-drive - add an image to examine or modify", " add-drive <filename>\n\nThis function adds a virtual machine disk image C<filename> to the\nguest. The first time you call this function, the disk appears as IDE\ndisk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and\nso on.\n\nYou don't necessarily need to be root when using libguestfs. However\nyou obviously do need sufficient permissions to access the filename\nfor whatever operations you want to perform (ie. read access if you\njust want to read the image or write access if you want to modify the\nimage).\n\nThis is equivalent to the qemu parameter C<-drive file=filename>.\n\nYou can use 'add' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "add_cdrom") == 0 || strcasecmp (cmd, "add-cdrom") == 0 || strcasecmp (cmd, "cdrom") == 0)
+ pod2text ("add-cdrom - add a CD-ROM disk image to examine", " add-cdrom <filename>\n\nThis function adds a virtual CD-ROM disk image to the guest.\n\nThis is equivalent to the qemu parameter C<-cdrom filename>.\n\nYou can use 'cdrom' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "config") == 0)
+ pod2text ("config - add qemu parameters", " config <qemuparam> <qemuvalue>\n\nThis can be used to add arbitrary qemu command line parameters\nof the form C<-param value>. Actually it's not quite arbitrary - we\nprevent you from setting some parameters which would interfere with\nparameters that we use.\n\nThe first character of C<param> string must be a C<-> (dash).\n\nC<value> can be NULL.");
+ else
+ if (strcasecmp (cmd, "set_path") == 0 || strcasecmp (cmd, "set-path") == 0 || strcasecmp (cmd, "path") == 0)
+ pod2text ("set-path - set the search path", " set-path <path>\n\nSet the path that libguestfs searches for kernel and initrd.img.\n\nThe default is C<$libdir/guestfs> unless overridden by setting\nC<LIBGUESTFS_PATH> environment variable.\n\nThe string C<path> is stashed in the libguestfs handle, so the caller\nmust make sure it remains valid for the lifetime of the handle.\n\nSetting C<path> to C<NULL> restores the default path.\n\nYou can use 'path' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "get_path") == 0 || strcasecmp (cmd, "get-path") == 0)
+ pod2text ("get-path - get the search path", " get-path\n\nReturn the current search path.\n\nThis is always non-NULL. If it wasn't set already, then this will\nreturn the default path.");
+ else
+ if (strcasecmp (cmd, "set_autosync") == 0 || strcasecmp (cmd, "set-autosync") == 0 || strcasecmp (cmd, "autosync") == 0)
+ pod2text ("set-autosync - set autosync mode", " set-autosync <autosync>\n\nIf C<autosync> is true, this enables autosync. Libguestfs will make a\nbest effort attempt to run C<sync> when the handle is closed\n(also if the program exits without closing handles).\n\nYou can use 'autosync' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "get_autosync") == 0 || strcasecmp (cmd, "get-autosync") == 0)
+ pod2text ("get-autosync - get autosync mode", " get-autosync\n\nGet the autosync flag.");
+ else
+ if (strcasecmp (cmd, "set_verbose") == 0 || strcasecmp (cmd, "set-verbose") == 0 || strcasecmp (cmd, "verbose") == 0)
+ pod2text ("set-verbose - set verbose mode", " set-verbose <verbose>\n\nIf C<verbose> is true, this turns on verbose messages (to C<stderr>).\n\nVerbose messages are disabled unless the environment variable\nC<LIBGUESTFS_DEBUG> is defined and set to C<1>.\n\nYou can use 'verbose' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "get_verbose") == 0 || strcasecmp (cmd, "get-verbose") == 0)
+ pod2text ("get-verbose - get verbose mode", " get-verbose\n\nThis returns the verbose messages flag.");
+ else
if (strcasecmp (cmd, "mount") == 0)
pod2text ("mount - mount a guest disk at a position in the filesystem", " mount <device> <mountpoint>\n\nMount a guest disk at a position in the filesystem. Block devices\nare named C</dev/sda>, C</dev/sdb> and so on, as they were added to\nthe guest. If those block devices contain partitions, they will have\nthe usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style\nnames can be used.\n\nThe rules are the same as for L<mount(2)>: A filesystem must\nfirst be mounted on C</> before others can be mounted. Other\nfilesystems can only be mounted on directories which already\nexist.\n\nThe mounted filesystem is writable, if we have sufficient permissions\non the underlying device.\n\nThe filesystem options C<sync> and C<noatime> are set with this\ncall, in order to improve reliability.");
else
print_lv (&lvs->val[i]);
}
+static int run_launch (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ if (argc != 0) {
+ fprintf (stderr, "%s should have 0 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ r = launch (g);
+ return r;
+}
+
+static int run_kill_subprocess (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ if (argc != 0) {
+ fprintf (stderr, "%s should have 0 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ r = guestfs_kill_subprocess (g);
+ return r;
+}
+
+static int run_add_drive (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *filename;
+ 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;
+ }
+ filename = argv[0];
+ r = guestfs_add_drive (g, filename);
+ return r;
+}
+
+static int run_add_cdrom (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *filename;
+ 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;
+ }
+ filename = argv[0];
+ r = guestfs_add_cdrom (g, filename);
+ return r;
+}
+
+static int run_config (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *qemuparam;
+ const char *qemuvalue;
+ 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;
+ }
+ qemuparam = argv[0];
+ qemuvalue = strcmp (argv[1], "") != 0 ? argv[1] : NULL;
+ r = guestfs_config (g, qemuparam, qemuvalue);
+ return r;
+}
+
+static int run_set_path (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *path;
+ 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;
+ }
+ path = argv[0];
+ r = guestfs_set_path (g, path);
+ return r;
+}
+
+static int run_get_path (const char *cmd, int argc, char *argv[])
+{
+ const char *r;
+ if (argc != 0) {
+ fprintf (stderr, "%s should have 0 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ r = guestfs_get_path (g);
+ if (r == NULL) return -1;
+ printf ("%s\n", r);
+ return 0;
+}
+
+static int run_set_autosync (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ int autosync;
+ 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;
+ }
+ autosync = is_true (argv[0]) ? 1 : 0;
+ r = guestfs_set_autosync (g, autosync);
+ return r;
+}
+
+static int run_get_autosync (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ if (argc != 0) {
+ fprintf (stderr, "%s should have 0 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ r = guestfs_get_autosync (g);
+ if (r == -1) return -1;
+ if (r) printf ("true\n"); else printf ("false\n");
+ return 0;
+}
+
+static int run_set_verbose (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ int verbose;
+ 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;
+ }
+ verbose = is_true (argv[0]) ? 1 : 0;
+ r = guestfs_set_verbose (g, verbose);
+ return r;
+}
+
+static int run_get_verbose (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ if (argc != 0) {
+ fprintf (stderr, "%s should have 0 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ r = guestfs_get_verbose (g);
+ if (r == -1) return -1;
+ if (r) printf ("true\n"); else printf ("false\n");
+ return 0;
+}
+
static int run_mount (const char *cmd, int argc, char *argv[])
{
int r;
path = argv[0];
r = guestfs_cat (g, path);
if (r == NULL) return -1;
- printf ("%s", r);
+ printf ("%s\n", r);
free (r);
return 0;
}
directory = argv[0];
r = guestfs_ll (g, directory);
if (r == NULL) return -1;
- printf ("%s", r);
+ 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)
+ return run_launch (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "kill_subprocess") == 0 || strcasecmp (cmd, "kill-subprocess") == 0)
+ return run_kill_subprocess (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "add_drive") == 0 || strcasecmp (cmd, "add-drive") == 0 || strcasecmp (cmd, "add") == 0)
+ return run_add_drive (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "add_cdrom") == 0 || strcasecmp (cmd, "add-cdrom") == 0 || strcasecmp (cmd, "cdrom") == 0)
+ return run_add_cdrom (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "config") == 0)
+ return run_config (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "set_path") == 0 || strcasecmp (cmd, "set-path") == 0 || strcasecmp (cmd, "path") == 0)
+ return run_set_path (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "get_path") == 0 || strcasecmp (cmd, "get-path") == 0)
+ return run_get_path (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "set_autosync") == 0 || strcasecmp (cmd, "set-autosync") == 0 || strcasecmp (cmd, "autosync") == 0)
+ return run_set_autosync (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "get_autosync") == 0 || strcasecmp (cmd, "get-autosync") == 0)
+ return run_get_autosync (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "set_verbose") == 0 || strcasecmp (cmd, "set-verbose") == 0 || strcasecmp (cmd, "verbose") == 0)
+ return run_set_verbose (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "get_verbose") == 0 || strcasecmp (cmd, "get-verbose") == 0)
+ return run_get_verbose (cmd, argc, argv);
+ else
if (strcasecmp (cmd, "mount") == 0)
return run_mount (cmd, argc, argv);
else
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
+#include <assert.h>
#include <guestfs.h>
int verbose = 0;
int
-launch (void)
+launch (guestfs_h *_g)
{
+ assert (_g == g);
+
if (!g_launched) {
if (guestfs_launch (g) == -1)
return -1;
/* If we've got mountpoints, we must launch the guest and mount them. */
if (mps != NULL) {
- if (launch () == -1) exit (1);
+ if (launch (g) == -1) exit (1);
mount_mps (mps);
}
quit = 1;
return 0;
}
- else if (strcasecmp (cmd, "add") == 0 ||
- strcasecmp (cmd, "drive") == 0 ||
- strcasecmp (cmd, "add-drive") == 0 ||
- strcasecmp (cmd, "add_drive") == 0) {
- if (argc != 1) {
- fprintf (stderr, "use 'add image' to add a guest image\n");
- return -1;
- }
- else
- return guestfs_add_drive (g, argv[0]);
- }
- else if (strcasecmp (cmd, "cdrom") == 0 ||
- strcasecmp (cmd, "add-cdrom") == 0 ||
- strcasecmp (cmd, "add_cdrom") == 0) {
- if (argc != 1) {
- fprintf (stderr, "use 'cdrom image' to add a CD-ROM image\n");
- return -1;
- }
- else
- return guestfs_add_cdrom (g, argv[0]);
- }
else if (strcasecmp (cmd, "alloc") == 0 ||
strcasecmp (cmd, "allocate") == 0) {
if (argc != 2) {
return 0;
}
}
- else if (strcasecmp (cmd, "launch") == 0 ||
- strcasecmp (cmd, "run") == 0) {
- if (argc != 0) {
- fprintf (stderr, "'launch' command takes no parameters\n");
- return -1;
- }
- else
- return launch ();
- }
else
return run_action (cmd, argc, argv);
}
printf ("%-20s %s\n",
"quit", "quit guestfish");
- /* then the non-actions, in alphabetical order */
- printf ("%-20s %s\n",
- "add", "add a guest image to be examined or modified");
printf ("%-20s %s\n",
"alloc", "allocate an image");
- printf ("%-20s %s\n",
- "cdrom", "add a CD-ROM image to be examined");
- printf ("%-20s %s\n",
- "launch", "launch the subprocess");
/* actions are printed after this (see list_commands) */
}
{
/* help for actions is auto-generated, see display_command */
- if (strcasecmp (cmd, "add") == 0)
- printf ("add - add a guest image to be examined or modified\n"
- " add <image>\n");
- else if (strcasecmp (cmd, "alloc") == 0)
+ if (strcasecmp (cmd, "alloc") == 0)
printf ("alloc - allocate an image\n"
" alloc <filename> <size>\n"
"\n"
" <nn>M or <nn>MB number of megabytes\n"
" <nn>G or <nn>GB number of gigabytes\n"
" <nn>sects number of 512 byte sectors\n");
- else if (strcasecmp (cmd, "cdrom") == 0)
- printf ("cdrom - add a CD-ROM image to be examined\n"
- " cdrom <iso-file>\n");
else if (strcasecmp (cmd, "help") == 0)
printf ("help - display a list of commands or help on a command\n"
" help cmd\n"
else if (strcasecmp (cmd, "quit") == 0)
printf ("quit - quit guestfish\n"
" quit\n");
- else if (strcasecmp (cmd, "launch") == 0)
- printf ("launch - launch the subprocess\n"
- " launch\n");
else
fprintf (stderr, "%s: command not known, use -h to list all commands\n",
cmd);
for (argc = 0; argv[argc] != NULL; ++argc)
printf ("%s\n", argv[argc]);
}
+
+int
+is_true (const char *str)
+{
+ return
+ strcasecmp (str, "0") != 0 &&
+ strcasecmp (str, "f") != 0 &&
+ strcasecmp (str, "false") != 0 &&
+ strcasecmp (str, "n") != 0 &&
+ strcasecmp (str, "no") != 0;
+}
extern void display_builtin_command (const char *cmd);
extern void free_strings (char **argv);
extern void print_strings (char **argv);
+extern int launch (guestfs_h *);
+extern int is_true (const char *str);
/* in cmds.c (auto-generated) */
extern void list_commands (void);
+=head2 add-cdrom | cdrom
+
+ add-cdrom filename
+
+This function adds a virtual CD-ROM disk image to the guest.
+
+This is equivalent to the qemu parameter C<-cdrom filename>.
+
+=head2 add-drive | add
+
+ add-drive filename
+
+This function adds a virtual machine disk image C<filename> to the
+guest. The first time you call this function, the disk appears as IDE
+disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
+so on.
+
+You don't necessarily need to be root when using libguestfs. However
+you obviously do need sufficient permissions to access the filename
+for whatever operations you want to perform (ie. read access if you
+just want to read the image or write access if you want to modify the
+image).
+
+This is equivalent to the qemu parameter C<-drive file=filename>.
+
=head2 cat
cat path
as end of string). For those you need to use the C<read_file>
function which has a more complex interface.
+=head2 config
+
+ config qemuparam qemuvalue
+
+This can be used to add arbitrary qemu command line parameters
+of the form C<-param value>. Actually it's not quite arbitrary - we
+prevent you from setting some parameters which would interfere with
+parameters that we use.
+
+The first character of C<param> string must be a C<-> (dash).
+
+C<value> can be NULL.
+
+=head2 get-autosync
+
+ get-autosync
+
+Get the autosync flag.
+
+=head2 get-path
+
+ get-path
+
+Return the current search path.
+
+This is always non-NULL. If it wasn't set already, then this will
+return the default path.
+
+=head2 get-verbose
+
+ get-verbose
+
+This returns the verbose messages flag.
+
+=head2 kill-subprocess
+
+ kill-subprocess
+
+This kills the qemu subprocess. You should never need to call this.
+
+=head2 launch | run
+
+ launch
+
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after configuring the handle
+(eg. adding drives) but before performing any actions.
+
=head2 list-devices
list-devices
List all the physical volumes detected. This is the equivalent
of the L<pvs(8)> command. The "full" version includes all fields.
+=head2 set-autosync | autosync
+
+ set-autosync true|false
+
+If C<autosync> is true, this enables autosync. Libguestfs will make a
+best effort attempt to run C<sync> when the handle is closed
+(also if the program exits without closing handles).
+
+=head2 set-path | path
+
+ set-path path
+
+Set the path that libguestfs searches for kernel and initrd.img.
+
+The default is C<$libdir/guestfs> unless overridden by setting
+C<LIBGUESTFS_PATH> environment variable.
+
+The string C<path> is stashed in the libguestfs handle, so the caller
+must make sure it remains valid for the lifetime of the handle.
+
+Setting C<path> to C<NULL> restores the default path.
+
+=head2 set-verbose | verbose
+
+ set-verbose true|false
+
+If C<verbose> is true, this turns on verbose messages (to C<stderr>).
+
+Verbose messages are disabled unless the environment variable
+C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
+
=head2 sync
sync
This exits guestfish. You can also use C<^D> key.
-=head2 add | drive | add-drive
-
- add filename
-
-This adds a block device to be examined or modified.
-
-=head2 cdrom | add-cdrom
-
- cdrom iso-file
-
-This adds a CD-ROM device to be examined.
-
=head2 alloc | allocate
alloc filename size
=back
-=head2 launch | run
-
-Launch the guest so that you can issue other commands (see below).
-
@ACTIONS@
=head1 ENVIRONMENT VARIABLES
+=head2 guestfs_add_cdrom
+
+ int guestfs_add_cdrom (guestfs_h *handle,
+ const char *filename);
+
+This function adds a virtual CD-ROM disk image to the guest.
+
+This is equivalent to the qemu parameter C<-cdrom filename>.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_add_drive
+
+ int guestfs_add_drive (guestfs_h *handle,
+ const char *filename);
+
+This function adds a virtual machine disk image C<filename> to the
+guest. The first time you call this function, the disk appears as IDE
+disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
+so on.
+
+You don't necessarily need to be root when using libguestfs. However
+you obviously do need sufficient permissions to access the filename
+for whatever operations you want to perform (ie. read access if you
+just want to read the image or write access if you want to modify the
+image).
+
+This is equivalent to the qemu parameter C<-drive file=filename>.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_cat
char *guestfs_cat (guestfs_h *handle,
of somewhere between 2MB and 4MB. To transfer large files you should use
FTP.
+=head2 guestfs_config
+
+ int guestfs_config (guestfs_h *handle,
+ const char *qemuparam,
+ const char *qemuvalue);
+
+This can be used to add arbitrary qemu command line parameters
+of the form C<-param value>. Actually it's not quite arbitrary - we
+prevent you from setting some parameters which would interfere with
+parameters that we use.
+
+The first character of C<param> string must be a C<-> (dash).
+
+C<value> can be NULL.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_get_autosync
+
+ int guestfs_get_autosync (guestfs_h *handle);
+
+Get the autosync flag.
+
+This function returns a C truth value on success or -1 on error.
+
+=head2 guestfs_get_path
+
+ const char *guestfs_get_path (guestfs_h *handle);
+
+Return the current search path.
+
+This is always non-NULL. If it wasn't set already, then this will
+return the default path.
+
+This function returns a string or NULL on error.
+The string is owned by the guest handle and must I<not> be freed.
+
+=head2 guestfs_get_verbose
+
+ int guestfs_get_verbose (guestfs_h *handle);
+
+This returns the verbose messages flag.
+
+This function returns a C truth value on success or -1 on error.
+
+=head2 guestfs_kill_subprocess
+
+ int guestfs_kill_subprocess (guestfs_h *handle);
+
+This kills the qemu subprocess. You should never need to call this.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_launch
+
+ int guestfs_launch (guestfs_h *handle);
+
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after configuring the handle
+(eg. adding drives) but before performing any actions.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_list_devices
char **guestfs_list_devices (guestfs_h *handle);
This function returns a C<struct guestfs_lvm_pv_list>.
I<The caller must call C<guestfs_free_lvm_pv_list> after use.>.
+=head2 guestfs_set_autosync
+
+ int guestfs_set_autosync (guestfs_h *handle,
+ int autosync);
+
+If C<autosync> is true, this enables autosync. Libguestfs will make a
+best effort attempt to run C<guestfs_sync> when the handle is closed
+(also if the program exits without closing handles).
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_set_path
+
+ int guestfs_set_path (guestfs_h *handle,
+ const char *path);
+
+Set the path that libguestfs searches for kernel and initrd.img.
+
+The default is C<$libdir/guestfs> unless overridden by setting
+C<LIBGUESTFS_PATH> environment variable.
+
+The string C<path> is stashed in the libguestfs handle, so the caller
+must make sure it remains valid for the lifetime of the handle.
+
+Setting C<path> to C<NULL> restores the default path.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_set_verbose
+
+ int guestfs_set_verbose (guestfs_h *handle,
+ int verbose);
+
+If C<verbose> is true, this turns on verbose messages (to C<stderr>).
+
+Verbose messages are disabled unless the environment variable
+C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_sync
int guestfs_sync (guestfs_h *handle);
This function returns a C<struct guestfs_lvm_vg_list>.
I<The caller must call C<guestfs_free_lvm_vg_list> after use.>.
+=head2 guestfs_wait_ready
+
+ int guestfs_wait_ready (guestfs_h *handle);
+
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after C<guestfs_launch> to wait for the launch
+to complete.
+
+This function returns 0 on success or -1 on error.
+
Create a connection handle.
You have to call C<guestfs_add_drive> on the handle at least once.
-See CONFIGURATION MANAGEMENT section below.
This function returns a non-NULL pointer to a handle on success or
NULL on error.
This closes the connection handle and frees up all resources used.
-=head2 guestfs_launch, guestfs_wait_ready
-
- int guestfs_launch (guestfs_h *handle);
- int guestfs_wait_ready (guestfs_h *handle);
-
-Internally libguestfs is implemented by running a virtual machine
-using L<qemu(1)>. These calls are necessary in order to boot the
-virtual machine. More discussion of this is available in the section
-STATE MACHINE AND LOW-LEVEL EVENT API below.
-
-You should call these two functions after configuring the handle
-(eg. adding drives) but before performing any actions.
-
-=head2 guestfs_kill_subprocess
-
- int guestfs_kill_subprocess (guestfs_h *handle);
-
-This kills the qemu subprocess. You should never need to call this.
-
-=head1 CONFIGURATION MANAGEMENT
-
-The configuration functions allow you to configure which drive images
-will be examined or modified, and set other aspects of the L<qemu(1)>
-virtual machine that we will be running. You need to call only
-C<guestfs_add_drive> at least once for each guest image that you want
-to examine.
-
-=head2 guestfs_add_drive
-
- int guestfs_add_drive (guestfs_h *handle, const char *filename);
-
-This function adds a virtual machine disk image C<filename> to the
-guest. The first time you call this function, the disk appears as IDE
-disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
-so on.
-
-You don't necessarily need to be root when using libguestfs. However
-you obviously do need sufficient permissions to access the filename
-for whatever operations you want to perform (ie. read access if you
-just want to read the image or write access if you want to modify the
-image).
-
-This is equivalent to the qemu parameter C<-drive file=filename>.
-
-=head2 guestfs_add_cdrom
-
- int guestfs_add_cdrom (guestfs_h *handle, const char *filename);
-
-This function adds a virtual CD-ROM disk image to the guest.
-
-This is equivalent to the qemu parameter C<-cdrom filename>.
-
-=head2 guestfs_config
-
- int guestfs_config (guestfs_h *handle,
- const char *qemu_param, const char *qemu_value);
-
-This can be used to add arbitrary qemu command line parameters
-of the form C<-param value>. Actually it's not quite arbitrary - we
-prevent you from setting some parameters which would interfere with
-parameters that we use.
-
-The first character of C<qemu_param> string must be a C<-> (dash).
-
-C<qemu_value> can be NULL.
-
=head1 ERROR HANDLING
The convention in all functions that return C<int> is that they return
or C<.>. For example C<LIBGUESTFS_PATH=:/usr/lib/guestfs> would
search the current directory and then C</usr/lib/guestfs>.
-=head2 guestfs_set_path
-
- void guestfs_set_path (guestfs_h *handle, const char *path);
-
-Set the path that libguestfs searches for kernel and initrd.img.
-
-The default is C<$libdir/guestfs> unless overridden by setting
-C<LIBGUESTFS_PATH> environment variable.
-
-The string C<path> is stashed in the libguestfs handle, so the caller
-must make sure it remains valid for the lifetime of the handle.
-
-Setting C<path> to C<NULL> restores the default path.
-
-=head2 guestfs_get_path
-
- const char *guestfs_get_path (guestfs_h *handle);
-
-Return the current search path.
-
-This is always non-NULL. If it wasn't set already, then this will
-return the default path.
-
-=head1 AUTOSYNC
-
-=head2 guestfs_set_autosync
-
- void guestfs_set_autosync (guestfs_h *handle, int autosync);
-
-If C<autosync> is true, this enables autosync. Libguestfs will make a
-best effort attempt to run C<guestfs_sync> when the handle is closed
-(also if the program exits without closing handles).
-
-=head2 guestfs_get_autosync
-
- int guestfs_get_autosync (guestfs_h *handle);
-
-Get the autosync flag.
-
-=head1 VERBOSE MESSAGES
-
-=head2 guestfs_set_verbose
-
- void guestfs_set_verbose (guestfs_h *handle, int verbose);
-
-If C<verbose> is true, this turns on verbose messages (to C<stderr>).
-
-Verbose messages are disabled unless the environment variable
-C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
-
-=head2 guestfs_get_verbose
-
- int guestfs_get_verbose (guestfs_h *handle);
-
-This returns the verbose messages flag.
-
=head1 HIGH-LEVEL API ACTIONS
@ACTIONS@
=item LIBGUESTFS_PATH
Set the path that libguestfs uses to search for kernel and initrd.img.
-See the discussion of paths in C<guestfs_set_path> above.
+See the discussion of paths in section PATH above.
=back
exception Error of string
external create : unit -> t = "ocaml_guestfs_create"
external close : t -> unit = "ocaml_guestfs_create"
-external launch : t -> unit = "ocaml_guestfs_launch"
-external wait_ready : t -> unit = "ocaml_guestfs_wait_ready"
-external kill_subprocess : t -> unit = "ocaml_guestfs_kill_subprocess"
-external add_drive : t -> string -> unit = "ocaml_guestfs_add_drive"
-external add_cdrom : t -> string -> unit = "ocaml_guestfs_add_cdrom"
-external config : t -> string -> string option -> unit = "ocaml_guestfs_config"
-external set_path : t -> string option -> unit = "ocaml_guestfs_set_path"
-external get_path : t -> string = "ocaml_guestfs_get_path"
-external set_autosync : t -> bool -> unit = "ocaml_guestfs_set_autosync"
-external get_autosync : t -> bool = "ocaml_guestfs_get_autosync"
-external set_verbose : t -> bool -> unit = "ocaml_guestfs_set_verbose"
-external get_verbose : t -> bool = "ocaml_guestfs_get_verbose"
type lvm_pv = {
pv_name : string;
modules : string;
}
+external launch : t -> unit = "ocaml_guestfs_launch"
+external wait_ready : t -> unit = "ocaml_guestfs_wait_ready"
+external kill_subprocess : t -> unit = "ocaml_guestfs_kill_subprocess"
+external add_drive : t -> string -> unit = "ocaml_guestfs_add_drive"
+external add_cdrom : t -> string -> unit = "ocaml_guestfs_add_cdrom"
+external config : t -> string -> string option -> unit = "ocaml_guestfs_config"
+external set_path : t -> string -> unit = "ocaml_guestfs_set_path"
+external get_path : t -> string = "ocaml_guestfs_get_path"
+external set_autosync : t -> bool -> unit = "ocaml_guestfs_set_autosync"
+external get_autosync : t -> bool = "ocaml_guestfs_get_autosync"
+external set_verbose : t -> bool -> unit = "ocaml_guestfs_set_verbose"
+external get_verbose : t -> bool = "ocaml_guestfs_get_verbose"
+external mount : t -> string -> string -> unit = "ocaml_guestfs_mount"
+external sync : t -> unit = "ocaml_guestfs_sync"
+external touch : t -> string -> unit = "ocaml_guestfs_touch"
external cat : t -> string -> string = "ocaml_guestfs_cat"
-external list_devices : t -> string list = "ocaml_guestfs_list_devices"
-external list_partitions : t -> string list = "ocaml_guestfs_list_partitions"
external ll : t -> string -> string = "ocaml_guestfs_ll"
external ls : t -> string -> string list = "ocaml_guestfs_ls"
-external lvs : t -> string list = "ocaml_guestfs_lvs"
-external lvs_full : t -> lvm_lv list = "ocaml_guestfs_lvs_full"
-external mount : t -> string -> string -> unit = "ocaml_guestfs_mount"
+external list_devices : t -> string list = "ocaml_guestfs_list_devices"
+external list_partitions : t -> string list = "ocaml_guestfs_list_partitions"
external pvs : t -> string list = "ocaml_guestfs_pvs"
-external pvs_full : t -> lvm_pv list = "ocaml_guestfs_pvs_full"
-external sync : t -> unit = "ocaml_guestfs_sync"
-external touch : t -> string -> unit = "ocaml_guestfs_touch"
external vgs : t -> string list = "ocaml_guestfs_vgs"
+external lvs : t -> string list = "ocaml_guestfs_lvs"
+external pvs_full : t -> lvm_pv list = "ocaml_guestfs_pvs_full"
external vgs_full : t -> lvm_vg list = "ocaml_guestfs_vgs_full"
+external lvs_full : t -> lvm_lv list = "ocaml_guestfs_lvs_full"
unreferenced, but callers can also call this in order to
provide predictable cleanup. *)
-val launch : t -> unit
-val wait_ready : t -> unit
-val kill_subprocess : t -> unit
-
-val add_drive : t -> string -> unit
-val add_cdrom : t -> string -> unit
-val config : t -> string -> string option -> unit
-
-val set_path : t -> string option -> unit
-val get_path : t -> string
-val set_autosync : t -> bool -> unit
-val get_autosync : t -> bool
-val set_verbose : t -> bool -> unit
-val get_verbose : t -> bool
-
type lvm_pv = {
pv_name : string;
pv_uuid : string;
modules : string;
}
-val cat : t -> string -> string
-(** list the contents of a file *)
+val launch : t -> unit
+(** launch the qemu subprocess *)
-val list_devices : t -> string list
-(** list the block devices *)
+val wait_ready : t -> unit
+(** wait until the qemu subprocess launches *)
-val list_partitions : t -> string list
-(** list the partitions *)
+val kill_subprocess : t -> unit
+(** kill the qemu subprocess *)
-val ll : t -> string -> string
-(** list the files in a directory (long format) *)
+val add_drive : t -> string -> unit
+(** add an image to examine or modify *)
-val ls : t -> string -> string list
-(** list the files in a directory *)
+val add_cdrom : t -> string -> unit
+(** add a CD-ROM disk image to examine *)
-val lvs : t -> string list
-(** list the LVM logical volumes (LVs) *)
+val config : t -> string -> string option -> unit
+(** add qemu parameters *)
-val lvs_full : t -> lvm_lv list
-(** list the LVM logical volumes (LVs) *)
+val set_path : t -> string -> unit
+(** set the search path *)
-val mount : t -> string -> string -> unit
-(** mount a guest disk at a position in the filesystem *)
+val get_path : t -> string
+(** get the search path *)
-val pvs : t -> string list
-(** list the LVM physical volumes (PVs) *)
+val set_autosync : t -> bool -> unit
+(** set autosync mode *)
-val pvs_full : t -> lvm_pv list
-(** list the LVM physical volumes (PVs) *)
+val get_autosync : t -> bool
+(** get autosync mode *)
+
+val set_verbose : t -> bool -> unit
+(** set verbose mode *)
+
+val get_verbose : t -> bool
+(** get verbose mode *)
+
+val mount : t -> string -> string -> unit
+(** mount a guest disk at a position in the filesystem *)
val sync : t -> unit
(** sync disks, writes are flushed through to the disk image *)
val touch : t -> string -> unit
(** update file timestamps or create a new file *)
+val cat : t -> string -> string
+(** list the contents of a file *)
+
+val ll : t -> string -> string
+(** list the files in a directory (long format) *)
+
+val ls : t -> string -> string list
+(** list the files in a directory *)
+
+val list_devices : t -> string list
+(** list the block devices *)
+
+val list_partitions : t -> string list
+(** list the partitions *)
+
+val pvs : t -> string list
+(** list the LVM physical volumes (PVs) *)
+
val vgs : t -> string list
(** list the LVM volume groups (VGs) *)
+val lvs : t -> string list
+(** list the LVM logical volumes (LVs) *)
+
+val pvs_full : t -> lvm_pv list
+(** list the LVM physical volumes (PVs) *)
+
val vgs_full : t -> lvm_vg list
(** list the LVM volume groups (VGs) *)
+val lvs_full : t -> lvm_lv list
+(** list the LVM logical volumes (LVs) *)
+
#include "guestfs_c.h"
CAMLprim value
-ocaml_guestfs_cat (value hv /* XXX */)
+ocaml_guestfs_launch (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_list_devices (value hv /* XXX */)
+ocaml_guestfs_wait_ready (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_list_partitions (value hv /* XXX */)
+ocaml_guestfs_kill_subprocess (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_ll (value hv /* XXX */)
+ocaml_guestfs_add_drive (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_ls (value hv /* XXX */)
+ocaml_guestfs_add_cdrom (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_lvs (value hv /* XXX */)
+ocaml_guestfs_config (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_lvs_full (value hv /* XXX */)
+ocaml_guestfs_set_path (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_mount (value hv /* XXX */)
+ocaml_guestfs_get_path (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_pvs (value hv /* XXX */)
+ocaml_guestfs_set_autosync (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
-ocaml_guestfs_pvs_full (value hv /* XXX */)
+ocaml_guestfs_get_autosync (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_set_verbose (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_get_verbose (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_mount (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
/* XXX write something here */
}
CAMLprim value
+ocaml_guestfs_cat (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_ll (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_ls (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_list_devices (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_list_partitions (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_pvs (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
ocaml_guestfs_vgs (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
}
CAMLprim value
+ocaml_guestfs_lvs (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
+ocaml_guestfs_pvs_full (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
+CAMLprim value
ocaml_guestfs_vgs_full (value hv /* XXX */)
{
CAMLparam1 (hv); /* XXX */
CAMLreturn (Val_unit); /* XXX */
}
+CAMLprim value
+ocaml_guestfs_lvs_full (value hv /* XXX */)
+{
+ CAMLparam1 (hv); /* XXX */
+/* XXX write something here */
+ CAMLreturn (Val_unit); /* XXX */
+}
+
guestfs_close (g);
void
+launch (g)
+ guestfs_h *g;
+ PPCODE:
+ if (guestfs_launch (g) == -1)
+ croak ("launch: %s", last_error);
+
+void
+wait_ready (g)
+ guestfs_h *g;
+ PPCODE:
+ if (guestfs_wait_ready (g) == -1)
+ croak ("wait_ready: %s", last_error);
+
+void
+kill_subprocess (g)
+ guestfs_h *g;
+ PPCODE:
+ if (guestfs_kill_subprocess (g) == -1)
+ croak ("kill_subprocess: %s", last_error);
+
+void
add_drive (g, filename)
guestfs_h *g;
- const char *filename;
- CODE:
+ char *filename;
+ PPCODE:
if (guestfs_add_drive (g, filename) == -1)
croak ("add_drive: %s", last_error);
void
add_cdrom (g, filename)
guestfs_h *g;
- const char *filename;
- CODE:
+ char *filename;
+ PPCODE:
if (guestfs_add_cdrom (g, filename) == -1)
croak ("add_cdrom: %s", last_error);
void
-config (g, param, value)
+config (g, qemuparam, qemuvalue)
guestfs_h *g;
- const char *param;
- const char *value;
- CODE:
- if (guestfs_config (g, param, value) == -1)
+ char *qemuparam;
+ char *qemuvalue;
+ PPCODE:
+ if (guestfs_config (g, qemuparam, qemuvalue) == -1)
croak ("config: %s", last_error);
void
-launch (g)
- guestfs_h *g;
- CODE:
- if (guestfs_launch (g) == -1)
- croak ("launch: %s", last_error);
-
-void
-wait_ready (g)
- guestfs_h *g;
- CODE:
- if (guestfs_wait_ready (g) == -1)
- croak ("wait_ready: %s", last_error);
-
-void
set_path (g, path)
guestfs_h *g;
- const char *path;
- CODE:
- guestfs_set_path (g, path);
+ char *path;
+ PPCODE:
+ if (guestfs_set_path (g, path) == -1)
+ croak ("set_path: %s", last_error);
SV *
get_path (g)
const char *path;
CODE:
path = guestfs_get_path (g);
+ if (path == NULL)
+ croak ("get_path: %s", last_error);
RETVAL = newSVpv (path, 0);
OUTPUT:
RETVAL
set_autosync (g, autosync)
guestfs_h *g;
int autosync;
- CODE:
- guestfs_set_autosync (g, autosync);
+ PPCODE:
+ if (guestfs_set_autosync (g, autosync) == -1)
+ croak ("set_autosync: %s", last_error);
SV *
get_autosync (g)
int autosync;
CODE:
autosync = guestfs_get_autosync (g);
+ if (autosync == -1)
+ croak ("get_autosync: %s", last_error);
RETVAL = newSViv (autosync);
OUTPUT:
RETVAL
set_verbose (g, verbose)
guestfs_h *g;
int verbose;
- CODE:
- guestfs_set_verbose (g, verbose);
+ PPCODE:
+ if (guestfs_set_verbose (g, verbose) == -1)
+ croak ("set_verbose: %s", last_error);
SV *
get_verbose (g)
int verbose;
CODE:
verbose = guestfs_get_verbose (g);
+ if (verbose == -1)
+ croak ("get_verbose: %s", last_error);
RETVAL = newSViv (verbose);
OUTPUT:
RETVAL
return $self;
}
-=item $h->add_drive ($filename);
+=item $h->add_cdrom (filename);
-=item $h->add_cdrom ($filename);
+This function adds a virtual CD-ROM disk image to the guest.
+
+This is equivalent to the qemu parameter C<-cdrom filename>.
+
+=item $h->add_drive (filename);
This function adds a virtual machine disk image C<filename> to the
guest. The first time you call this function, the disk appears as IDE
just want to read the image or write access if you want to modify the
image).
-The C<add_cdrom> variation adds a CD-ROM device.
-
-=item $h->config ($param, $value);
+This is equivalent to the qemu parameter C<-drive file=filename>.
-=item $h->config ($param);
+=item $content = $h->cat (path);
-Use this to add arbitrary parameters to the C<qemu> command line.
-See L<qemu(1)>.
+Return the contents of the file named C<path>.
-=item $h->launch ();
+Note that this function cannot correctly handle binary files
+(specifically, files containing C<\0> character which is treated
+as end of string). For those you need to use the C<$h-E<gt>read_file>
+function which has a more complex interface.
-=item $h->wait_ready ();
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
-Internally libguestfs is implemented by running a virtual machine
-using L<qemu(1)>. These calls are necessary in order to boot the
-virtual machine.
+=item $h->config (qemuparam, qemuvalue);
-You should call these two functions after configuring the handle
-(eg. adding drives) but before performing any actions.
+This can be used to add arbitrary qemu command line parameters
+of the form C<-param value>. Actually it's not quite arbitrary - we
+prevent you from setting some parameters which would interfere with
+parameters that we use.
-=item $h->set_path ($path);
+The first character of C<param> string must be a C<-> (dash).
-=item $path = $h->get_path ();
+C<value> can be NULL.
-See the discussion of C<PATH> in the L<guestfs(3)>
-manpage.
+=item $autosync = $h->get_autosync ();
-=item $h->set_autosync ($autosync);
+Get the autosync flag.
-=item $autosync = $h->get_autosync ();
+=item $path = $h->get_path ();
-See the discussion of I<AUTOSYNC> in the L<guestfs(3)>
-manpage.
+Return the current search path.
-=item $h->set_verbose ($verbose);
+This is always non-NULL. If it wasn't set already, then this will
+return the default path.
=item $verbose = $h->get_verbose ();
-This sets or gets the verbose messages flag. Verbose
-messages are sent to C<stderr>.
+This returns the verbose messages flag.
-=item $content = $h->cat (path);
+=item $h->kill_subprocess ();
-Return the contents of the file named C<path>.
+This kills the qemu subprocess. You should never need to call this.
-Note that this function cannot correctly handle binary files
-(specifically, files containing C<\0> character which is treated
-as end of string). For those you need to use the C<$h-E<gt>read_file>
-function which has a more complex interface.
+=item $h->launch ();
-Because of the message protocol, there is a transfer limit
-of somewhere between 2MB and 4MB. To transfer large files you should use
-FTP.
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after configuring the handle
+(eg. adding drives) but before performing any actions.
=item @devices = $h->list_devices ();
List all the physical volumes detected. This is the equivalent
of the L<pvs(8)> command. The "full" version includes all fields.
+=item $h->set_autosync (autosync);
+
+If C<autosync> is true, this enables autosync. Libguestfs will make a
+best effort attempt to run C<$h-E<gt>sync> when the handle is closed
+(also if the program exits without closing handles).
+
+=item $h->set_path (path);
+
+Set the path that libguestfs searches for kernel and initrd.img.
+
+The default is C<$libdir/guestfs> unless overridden by setting
+C<LIBGUESTFS_PATH> environment variable.
+
+The string C<path> is stashed in the libguestfs handle, so the caller
+must make sure it remains valid for the lifetime of the handle.
+
+Setting C<path> to C<NULL> restores the default path.
+
+=item $h->set_verbose (verbose);
+
+If C<verbose> is true, this turns on verbose messages (to C<stderr>).
+
+Verbose messages are disabled unless the environment variable
+C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
+
=item $h->sync ();
This syncs the disk, so that any writes are flushed through to the
List all the volumes groups detected. This is the equivalent
of the L<vgs(8)> command. The "full" version includes all fields.
+=item $h->wait_ready ();
+
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after C<$h-E<gt>launch> to wait for the launch
+to complete.
+
=cut
1;
* indication, ie. 0 or -1.
*)
| Err
- (* "RString" and "RStringList" require special treatment because
- * the caller must free them.
+ (* "RBool" is a bool return value which can be true/false or
+ * -1 for error.
*)
+ | RBool of string
+ (* "RConstString" is a string that refers to a constant value.
+ * Try to avoid using this.
+ *)
+ | RConstString of string
+ (* "RString" and "RStringList" are caller-frees. *)
| RString of string
| RStringList of string
(* LVM PVs, VGs and LVs. *)
| P2 of argt * argt
and argt =
| String of string (* const char *name, cannot be NULL *)
+ | OptString of string (* const char *name, may be NULL *)
+ | Bool of string (* boolean *)
-type flags = ProtocolLimitWarning
+type flags =
+ | ProtocolLimitWarning (* display warning about protocol size limits *)
+ | FishAlias of string (* provide an alias for this cmd in guestfish *)
+ | FishAction of string (* call this function in guestfish *)
+ | NotInFish (* do not export via guestfish *)
(* Note about long descriptions: When referring to another
* action, use the format C<guestfs_other> (ie. the full name of
* Apart from that, long descriptions are just perldoc paragraphs.
*)
-let functions = [
+let non_daemon_functions = [
+ ("launch", (Err, P0), -1, [FishAlias "run"; FishAction "launch"],
+ "launch the qemu subprocess",
+ "\
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after configuring the handle
+(eg. adding drives) but before performing any actions.");
+
+ ("wait_ready", (Err, P0), -1, [NotInFish],
+ "wait until the qemu subprocess launches",
+ "\
+Internally libguestfs is implemented by running a virtual machine
+using L<qemu(1)>.
+
+You should call this after C<guestfs_launch> to wait for the launch
+to complete.");
+
+ ("kill_subprocess", (Err, P0), -1, [],
+ "kill the qemu subprocess",
+ "\
+This kills the qemu subprocess. You should never need to call this.");
+
+ ("add_drive", (Err, P1 (String "filename")), -1, [FishAlias "add"],
+ "add an image to examine or modify",
+ "\
+This function adds a virtual machine disk image C<filename> to the
+guest. The first time you call this function, the disk appears as IDE
+disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
+so on.
+
+You don't necessarily need to be root when using libguestfs. However
+you obviously do need sufficient permissions to access the filename
+for whatever operations you want to perform (ie. read access if you
+just want to read the image or write access if you want to modify the
+image).
+
+This is equivalent to the qemu parameter C<-drive file=filename>.");
+
+ ("add_cdrom", (Err, P1 (String "filename")), -1, [FishAlias "cdrom"],
+ "add a CD-ROM disk image to examine",
+ "\
+This function adds a virtual CD-ROM disk image to the guest.
+
+This is equivalent to the qemu parameter C<-cdrom filename>.");
+
+ ("config", (Err, P2 (String "qemuparam", OptString "qemuvalue")), -1, [],
+ "add qemu parameters",
+ "\
+This can be used to add arbitrary qemu command line parameters
+of the form C<-param value>. Actually it's not quite arbitrary - we
+prevent you from setting some parameters which would interfere with
+parameters that we use.
+
+The first character of C<param> string must be a C<-> (dash).
+
+C<value> can be NULL.");
+
+ ("set_path", (Err, P1 (String "path")), -1, [FishAlias "path"],
+ "set the search path",
+ "\
+Set the path that libguestfs searches for kernel and initrd.img.
+
+The default is C<$libdir/guestfs> unless overridden by setting
+C<LIBGUESTFS_PATH> environment variable.
+
+The string C<path> is stashed in the libguestfs handle, so the caller
+must make sure it remains valid for the lifetime of the handle.
+
+Setting C<path> to C<NULL> restores the default path.");
+
+ ("get_path", (RConstString "path", P0), -1, [],
+ "get the search path",
+ "\
+Return the current search path.
+
+This is always non-NULL. If it wasn't set already, then this will
+return the default path.");
+
+ ("set_autosync", (Err, P1 (Bool "autosync")), -1, [FishAlias "autosync"],
+ "set autosync mode",
+ "\
+If C<autosync> is true, this enables autosync. Libguestfs will make a
+best effort attempt to run C<guestfs_sync> when the handle is closed
+(also if the program exits without closing handles).");
+
+ ("get_autosync", (RBool "autosync", P0), -1, [],
+ "get autosync mode",
+ "\
+Get the autosync flag.");
+
+ ("set_verbose", (Err, P1 (Bool "verbose")), -1, [FishAlias "verbose"],
+ "set verbose mode",
+ "\
+If C<verbose> is true, this turns on verbose messages (to C<stderr>).
+
+Verbose messages are disabled unless the environment variable
+C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
+
+ ("get_verbose", (RBool "verbose", P0), -1, [],
+ "get verbose mode",
+ "\
+This returns the verbose messages flag.")
+]
+
+let daemon_functions = [
("mount", (Err, P2 (String "device", String "mountpoint")), 1, [],
"mount a guest disk at a position in the filesystem",
"\
of the L<lvs(8)> command. The \"full\" version includes all fields.");
]
+let all_functions = non_daemon_functions @ daemon_functions
+
+(* In some places we want the functions to be displayed sorted
+ * alphabetically, so this is useful:
+ *)
+let all_functions_sorted =
+ List.sort (fun (n1,_,_,_,_,_) (n2,_,_,_,_,_) -> compare n1 n2) all_functions
+
(* Column names and types from LVM PVs/VGs/LVs. *)
let pv_cols = [
"pv_name", `String;
"modules", `String;
]
-(* In some places we want the functions to be displayed sorted
- * alphabetically, so this is useful:
- *)
-let sorted_functions =
- List.sort (fun (n1,_,_,_,_,_) (n2,_,_,_,_,_) -> compare n1 n2) functions
-
(* Useful functions.
* Note we don't want to use any external OCaml libraries which
* makes this a bit harder than it should be.
s' ^ s2 ^ replace_str s'' s1 s2
)
+let rec find_map f = function
+ | [] -> raise Not_found
+ | x :: xs ->
+ match f x with
+ | Some y -> y
+ | None -> find_map f xs
+
(* 'pr' prints to the current output file. *)
let chan = ref stdout
let pr fs = ksprintf (output_string !chan) fs
List.iter (
fun (name, _, _, _, _, longdesc) ->
if String.contains name '-' then
- failwithf "Function name '%s' should not contain '-', use '_' instead."
+ failwithf "function name '%s' should not contain '-', use '_' instead."
name;
if longdesc.[String.length longdesc-1] = '\n' then
- failwithf "Long description of %s should not end with \\n." name
- ) functions;
+ failwithf "long description of %s should not end with \\n." name
+ ) all_functions;
+
+ List.iter (
+ fun (name, _, proc_nr, _, _, _) ->
+ if proc_nr <= 0 then
+ failwithf "daemon function %s should have proc_nr > 0" name
+ ) daemon_functions;
+
+ List.iter (
+ fun (name, _, proc_nr, _, _, _) ->
+ if proc_nr <> -1 then
+ failwithf "non-daemon function %s should have proc_nr -1" name
+ ) non_daemon_functions;
let proc_nrs =
- List.map (fun (name, _, proc_nr, _, _, _) -> name, proc_nr) functions in
+ List.map (fun (name, _, proc_nr, _, _, _) -> name, proc_nr)
+ daemon_functions in
let proc_nrs =
List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
let rec loop = function
(match fst style with
| Err ->
pr "This function returns 0 on success or -1 on error.\n\n"
+ | RBool _ ->
+ pr "This function returns a C truth value on success or -1 on error.\n\n"
+ | RConstString _ ->
+ pr "This function returns a string or NULL on error.
+The string is owned by the guest handle and must I<not> be freed.\n\n"
| RString _ ->
pr "This function returns a string or NULL on error.
I<The caller must free the returned string after use>.\n\n"
pr "Because of the message protocol, there is a transfer limit
of somewhere between 2MB and 4MB. To transfer large files you should use
FTP.\n\n";
- ) sorted_functions
+ ) all_functions_sorted
and generate_structs_pod () =
(* LVM structs documentation. *)
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols];
List.iter (
- fun (shortname, style, _, _, _, _) ->
+ fun(shortname, style, _, _, _, _) ->
let name = "guestfs_" ^ shortname in
pr "/* %s */\n\n" name;
(match snd style with
iter_args (
function
| String name -> pr " string %s<>;\n" name
+ | OptString name -> pr " string *%s<>;\n" name
+ | Bool name -> pr " bool %s;\n" name
) args;
pr "};\n\n"
);
(match fst style with
- | Err -> ()
+ | Err -> ()
+ | RBool n ->
+ pr "struct %s_ret {\n" name;
+ pr " bool %s;\n" n;
+ pr "};\n\n"
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
| RString n ->
pr "struct %s_ret {\n" name;
pr " string %s<>;\n" n;
pr " guestfs_lvm_int_lv_list %s;\n" n;
pr "};\n\n"
);
- ) functions;
+ ) daemon_functions;
(* Table of procedure numbers. *)
pr "enum guestfs_procedure {\n";
List.iter (
fun (shortname, _, proc_nr, _, _, _) ->
pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
- ) functions;
+ ) daemon_functions;
pr " GUESTFS_PROC_dummy\n"; (* so we don't have a "hanging comma" *)
pr "};\n";
pr "\n";
let name = "guestfs_" ^ shortname in
generate_prototype ~single_line:true ~newline:true ~handle:"handle"
name style
- ) functions
+ ) all_functions
(* Generate the client-side dispatch stubs. *)
and generate_client_actions () =
pr " struct guestfs_message_error err;\n";
(match fst style with
| Err -> ()
- | RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
+ | RBool _ | RString _ | RStringList _
+ | RPVList _ | RVGList _ | RLVList _ ->
pr " struct %s_ret ret;\n" name
);
pr "};\n\n";
(match fst style with
| Err -> ()
- | RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
+ | RBool _ | RString _ | RStringList _
+ | RPVList _ | RVGList _ | RLVList _ ->
pr " if (!xdr_%s_ret (xdr, &rv->ret)) {\n" name;
pr " error (g, \"%s: failed to parse reply\");\n" name;
pr " return;\n";
let error_code =
match fst style with
- | Err -> "-1"
+ | Err | RBool _ -> "-1"
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
| RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
"NULL" in
| args ->
iter_args (
function
- | String name -> pr " args.%s = (char *) %s;\n" name name
+ | String name ->
+ pr " args.%s = (char *) %s;\n" name name
+ | OptString name ->
+ pr " args.%s = %s ? *%s : NULL;\n" name name name
+ | Bool name ->
+ pr " args.%s = %s;\n" name name
) args;
pr " serial = dispatch (g, GUESTFS_PROC_%s,\n"
(String.uppercase shortname);
(match fst style with
| Err -> pr " return 0;\n"
+ | RBool n -> pr " return rv.ret.%s;\n" n
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
| RString n ->
pr " return rv.ret.%s; /* caller will free */\n" n
| RStringList n ->
);
pr "}\n\n"
- ) functions
+ ) daemon_functions
(* Generate daemon/actions.h. *)
and generate_daemon_actions_h () =
List.iter (
fun (name, style, _, _, _, _) ->
- generate_prototype
- ~single_line:true ~newline:true ~in_daemon:true ("do_" ^ name) style;
- ) functions
+ generate_prototype
+ ~single_line:true ~newline:true ~in_daemon:true ("do_" ^ name) style;
+ ) daemon_functions
(* Generate the server-side stubs. *)
and generate_daemon_actions () =
let error_code =
match fst style with
| Err -> pr " int r;\n"; "-1"
+ | RBool _ -> pr " int r;\n"; "-1"
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
| RString _ -> pr " char *r;\n"; "NULL"
| RStringList _ -> pr " char **r;\n"; "NULL"
| RPVList _ -> pr " guestfs_lvm_int_pv_list *r;\n"; "NULL"
pr " struct guestfs_%s_args args;\n" name;
iter_args (
function
- | String name -> pr " const char *%s;\n" name
+ | String name
+ | OptString name -> pr " const char *%s;\n" name
+ | Bool name -> pr " int %s;\n" name
) args
);
pr "\n";
iter_args (
function
| String name -> pr " %s = args.%s;\n" name name
+ | OptString name -> pr " %s = args.%s;\n" name name (* XXX? *)
+ | Bool name -> pr " %s = args.%s;\n" name name
) args;
pr "\n"
);
(match fst style with
| Err -> pr " reply (NULL, NULL);\n"
+ | RBool n ->
+ pr " struct guestfs_%s_ret ret;\n" name;
+ pr " ret.%s = r;\n" n;
+ pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name
+ | RConstString _ ->
+ failwithf "RConstString cannot be returned from a daemon function"
| RString n ->
pr " struct guestfs_%s_ret ret;\n" name;
pr " ret.%s = r;\n" n;
);
pr "}\n\n";
- ) functions;
+ ) daemon_functions;
(* Dispatch function. *)
pr "void dispatch_incoming_message (XDR *xdr_in)\n";
List.iter (
fun (name, style, _, _, _, _) ->
- pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
- pr " %s_stub (xdr_in);\n" name;
- pr " break;\n"
- ) functions;
+ pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
+ pr " %s_stub (xdr_in);\n" name;
+ pr " break;\n"
+ ) daemon_functions;
pr " default:\n";
pr " reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d\", proc_nr);\n";
and generate_fish_cmds () =
generate_header CStyle GPLv2;
+ let all_functions =
+ List.filter (
+ fun (_, _, _, flags, _, _) -> not (List.mem NotInFish flags)
+ ) all_functions in
+ let all_functions_sorted =
+ List.filter (
+ fun (_, _, _, flags, _, _) -> not (List.mem NotInFish flags)
+ ) all_functions_sorted in
+
pr "#include <stdio.h>\n";
pr "#include <stdlib.h>\n";
pr "#include <string.h>\n";
pr " printf (\" %%-16s %%s\\n\", \"Command\", \"Description\");\n";
pr " list_builtin_commands ();\n";
List.iter (
- fun (name, _, _, _, shortdesc, _) ->
+ fun (name, _, _, flags, shortdesc, _) ->
let name = replace_char name '_' '-' in
pr " printf (\"%%-20s %%s\\n\", \"%s\", \"%s\");\n"
name shortdesc
- ) sorted_functions;
+ ) all_functions_sorted;
pr " printf (\" Use -h <cmd> / help <cmd> to show detailed help for a command.\\n\");\n";
pr "}\n";
pr "\n";
List.iter (
fun (name, style, _, flags, shortdesc, longdesc) ->
let name2 = replace_char name '_' '-' in
+ let alias =
+ try find_map (function FishAlias n -> Some n | _ -> None) flags
+ with Not_found -> name in
let longdesc = replace_str longdesc "C<guestfs_" "C<" in
let synopsis =
match snd style with
name2 (
String.concat "> <" (
map_args (function
- | String n -> n) args
+ | String n | OptString n | Bool n -> n) args
)
) in
FTP."
else "" in
+ let describe_alias =
+ if name <> alias then
+ sprintf "\n\nYou can use '%s' as an alias for this command." alias
+ else "" in
+
pr " if (";
pr "strcasecmp (cmd, \"%s\") == 0" name;
if name <> name2 then
pr " || strcasecmp (cmd, \"%s\") == 0" name2;
+ if name <> alias then
+ pr " || strcasecmp (cmd, \"%s\") == 0" alias;
pr ")\n";
pr " pod2text (\"%s - %s\", %S);\n"
name2 shortdesc
- (" " ^ synopsis ^ "\n\n" ^ longdesc ^ warnings);
+ (" " ^ synopsis ^ "\n\n" ^ longdesc ^ warnings ^ describe_alias);
pr " else\n"
- ) functions;
+ ) all_functions;
pr " display_builtin_command (cmd);\n";
pr "}\n";
pr "\n";
(* run_<action> actions *)
List.iter (
- fun (name, style, _, _, _, _) ->
+ fun (name, style, _, flags, _, _) ->
pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
pr "{\n";
(match fst style with
- | Err -> pr " int r;\n"
+ | Err
+ | RBool _ -> pr " int r;\n"
+ | RConstString _ -> pr " const char *r;\n"
| RString _ -> pr " char *r;\n"
| RStringList _ -> pr " char **r;\n"
| RPVList _ -> pr " struct guestfs_lvm_pv_list *r;\n"
iter_args (
function
| String name -> pr " const char *%s;\n" name
+ | OptString name -> pr " const char *%s;\n" name
+ | Bool name -> pr " int %s;\n" name
) (snd style);
(* Check and convert parameters. *)
fun i ->
function
| String name -> pr " %s = argv[%d];\n" name i
+ | OptString name ->
+ pr " %s = strcmp (argv[%d], \"\") != 0 ? argv[%d] : NULL;\n"
+ name i i
+ | Bool name ->
+ pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
) (snd style);
(* Call C API function. *)
- pr " r = guestfs_%s " name;
+ let fn =
+ try find_map (function FishAction n -> Some n | _ -> None) flags
+ with Not_found -> sprintf "guestfs_%s" name in
+ pr " r = %s " fn;
generate_call_args ~handle:"g" style;
pr ";\n";
(* Check return value for errors and display command results. *)
(match fst style with
| Err -> pr " return r;\n"
+ | RBool _ ->
+ pr " if (r == -1) return -1;\n";
+ pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
+ pr " return 0;\n"
+ | RConstString _ ->
+ pr " if (r == NULL) return -1;\n";
+ pr " printf (\"%%s\\n\", r);\n";
+ pr " return 0;\n"
| RString _ ->
pr " if (r == NULL) return -1;\n";
- pr " printf (\"%%s\", r);\n";
+ pr " printf (\"%%s\\n\", r);\n";
pr " free (r);\n";
pr " return 0;\n"
| RStringList _ ->
);
pr "}\n";
pr "\n"
- ) functions;
+ ) all_functions;
(* run_action function *)
pr "int run_action (const char *cmd, int argc, char *argv[])\n";
pr "{\n";
List.iter (
- fun (name, _, _, _, _, _) ->
+ fun (name, _, _, flags, _, _) ->
let name2 = replace_char name '_' '-' in
+ let alias =
+ try find_map (function FishAlias n -> Some n | _ -> None) flags
+ with Not_found -> name in
pr " if (";
pr "strcasecmp (cmd, \"%s\") == 0" name;
if name <> name2 then
pr " || strcasecmp (cmd, \"%s\") == 0" name2;
+ if name <> alias then
+ pr " || strcasecmp (cmd, \"%s\") == 0" alias;
pr ")\n";
pr " return run_%s (cmd, argc, argv);\n" name;
pr " else\n";
- ) functions;
+ ) all_functions;
pr " {\n";
pr " fprintf (stderr, \"%%s: unknown command\\n\", cmd);\n";
pr " return -1;\n";
(* Generate the POD documentation for guestfish. *)
and generate_fish_actions_pod () =
+ let all_functions_sorted =
+ List.filter (
+ fun (_, _, _, flags, _, _) -> not (List.mem NotInFish flags)
+ ) all_functions_sorted in
+
List.iter (
- fun (name, style, _, _, _, longdesc) ->
+ fun (name, style, _, flags, _, longdesc) ->
let longdesc = replace_str longdesc "C<guestfs_" "C<" in
let name = replace_char name '_' '-' in
- pr "=head2 %s\n\n" name;
+ let alias =
+ try find_map (function FishAlias n -> Some n | _ -> None) flags
+ with Not_found -> name in
+
+ pr "=head2 %s" name;
+ if name <> alias then
+ pr " | %s" alias;
+ pr "\n";
+ pr "\n";
pr " %s" name;
iter_args (
function
| String n -> pr " %s" n
+ | OptString n -> pr " %s" n
+ | Bool _ -> pr " true|false"
) (snd style);
pr "\n";
pr "\n";
pr "%s\n\n" longdesc
- ) sorted_functions
+ ) all_functions_sorted
(* Generate a C function prototype. *)
and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
if static then pr "static ";
(match fst style with
| Err -> pr "int "
+ | RBool _ -> pr "int "
+ | RConstString _ -> pr "const char *"
| RString _ -> pr "char *"
| RStringList _ -> pr "char **"
| RPVList _ ->
iter_args (
function
| String name -> next (); pr "const char *%s" name
+ | OptString name -> next (); pr "const char *%s" name
+ | Bool name -> next (); pr "int %s" name
) (snd style);
pr ")";
if semicolon then pr ";";
comma := true;
match arg with
| String name -> pr "%s" name
+ | OptString name -> pr "%s" name
+ | Bool name -> pr "%s" name
) (snd style);
pr ")"
unreferenced, but callers can also call this in order to
provide predictable cleanup. *)
-val launch : t -> unit
-val wait_ready : t -> unit
-val kill_subprocess : t -> unit
-
-val add_drive : t -> string -> unit
-val add_cdrom : t -> string -> unit
-val config : t -> string -> string option -> unit
-
-val set_path : t -> string option -> unit
-val get_path : t -> string
-val set_autosync : t -> bool -> unit
-val get_autosync : t -> bool
-val set_verbose : t -> bool -> unit
-val get_verbose : t -> bool
-
";
generate_ocaml_lvm_structure_decls ();
generate_ocaml_prototype name style;
pr "(** %s *)\n" shortdesc;
pr "\n"
- ) sorted_functions
+ ) all_functions
(* Generate the OCaml bindings implementation. *)
and generate_ocaml_ml () =
exception Error of string
external create : unit -> t = \"ocaml_guestfs_create\"
external close : t -> unit = \"ocaml_guestfs_create\"
-external launch : t -> unit = \"ocaml_guestfs_launch\"
-external wait_ready : t -> unit = \"ocaml_guestfs_wait_ready\"
-external kill_subprocess : t -> unit = \"ocaml_guestfs_kill_subprocess\"
-external add_drive : t -> string -> unit = \"ocaml_guestfs_add_drive\"
-external add_cdrom : t -> string -> unit = \"ocaml_guestfs_add_cdrom\"
-external config : t -> string -> string option -> unit = \"ocaml_guestfs_config\"
-external set_path : t -> string option -> unit = \"ocaml_guestfs_set_path\"
-external get_path : t -> string = \"ocaml_guestfs_get_path\"
-external set_autosync : t -> bool -> unit = \"ocaml_guestfs_set_autosync\"
-external get_autosync : t -> bool = \"ocaml_guestfs_get_autosync\"
-external set_verbose : t -> bool -> unit = \"ocaml_guestfs_set_verbose\"
-external get_verbose : t -> bool = \"ocaml_guestfs_get_verbose\"
";
generate_ocaml_lvm_structure_decls ();
List.iter (
fun (name, style, _, _, shortdesc, _) ->
generate_ocaml_prototype ~is_external:true name style;
- ) sorted_functions
+ ) all_functions
(* Generate the OCaml bindings C implementation. *)
and generate_ocaml_c () =
pr " CAMLreturn (Val_unit); /* XXX */\n";
pr "}\n";
pr "\n"
- ) sorted_functions
+ ) all_functions
and generate_ocaml_lvm_structure_decls () =
List.iter (
pr "%s : t -> " name;
iter_args (
function
- | String _ -> pr "string -> " (* note String is not allowed to be NULL *)
+ | String _ -> pr "string -> "
+ | OptString _ -> pr "string option -> "
+ | Bool _ -> pr "bool -> "
) (snd style);
(match fst style with
| Err -> pr "unit" (* all errors are turned into exceptions *)
+ | RBool _ -> pr "bool"
+ | RConstString _ -> pr "string"
| RString _ -> pr "string"
| RStringList _ -> pr "string list"
| RPVList _ -> pr "lvm_pv list"
PPCODE:
guestfs_close (g);
-void
-add_drive (g, filename)
- guestfs_h *g;
- const char *filename;
- CODE:
- if (guestfs_add_drive (g, filename) == -1)
- croak (\"add_drive: %%s\", last_error);
-
-void
-add_cdrom (g, filename)
- guestfs_h *g;
- const char *filename;
- CODE:
- if (guestfs_add_cdrom (g, filename) == -1)
- croak (\"add_cdrom: %%s\", last_error);
-
-void
-config (g, param, value)
- guestfs_h *g;
- const char *param;
- const char *value;
- CODE:
- if (guestfs_config (g, param, value) == -1)
- croak (\"config: %%s\", last_error);
-
-void
-launch (g)
- guestfs_h *g;
- CODE:
- if (guestfs_launch (g) == -1)
- croak (\"launch: %%s\", last_error);
-
-void
-wait_ready (g)
- guestfs_h *g;
- CODE:
- if (guestfs_wait_ready (g) == -1)
- croak (\"wait_ready: %%s\", last_error);
-
-void
-set_path (g, path)
- guestfs_h *g;
- const char *path;
- CODE:
- guestfs_set_path (g, path);
-
-SV *
-get_path (g)
- guestfs_h *g;
-PREINIT:
- const char *path;
- CODE:
- path = guestfs_get_path (g);
- RETVAL = newSVpv (path, 0);
- OUTPUT:
- RETVAL
-
-void
-set_autosync (g, autosync)
- guestfs_h *g;
- int autosync;
- CODE:
- guestfs_set_autosync (g, autosync);
-
-SV *
-get_autosync (g)
- guestfs_h *g;
-PREINIT:
- int autosync;
- CODE:
- autosync = guestfs_get_autosync (g);
- RETVAL = newSViv (autosync);
- OUTPUT:
- RETVAL
-
-void
-set_verbose (g, verbose)
- guestfs_h *g;
- int verbose;
- CODE:
- guestfs_set_verbose (g, verbose);
-
-SV *
-get_verbose (g)
- guestfs_h *g;
-PREINIT:
- int verbose;
- CODE:
- verbose = guestfs_get_verbose (g);
- RETVAL = newSViv (verbose);
- OUTPUT:
- RETVAL
-
";
List.iter (
fun (name, style, _, _, _, _) ->
(match fst style with
| Err -> pr "void\n"
+ | RBool _ -> pr "SV *\n"
+ | RConstString _ -> pr "SV *\n"
| RString _ -> pr "SV *\n"
| RStringList _
| RPVList _ | RVGList _ | RLVList _ ->
iter_args (
function
| String n -> pr " char *%s;\n" n
+ | OptString n -> pr " char *%s;\n" n
+ | Bool n -> pr " int %s;\n" n
) (snd style);
(* Code. *)
(match fst style with
generate_call_args ~handle:"g" style;
pr " == -1)\n";
pr " croak (\"%s: %%s\", last_error);\n" name
+ | RConstString n ->
+ pr "PREINIT:\n";
+ pr " const char *%s;\n" n;
+ pr " CODE:\n";
+ pr " %s = guestfs_%s " n name;
+ generate_call_args ~handle:"g" style;
+ pr ";\n";
+ pr " if (%s == NULL)\n" n;
+ pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " RETVAL = newSVpv (%s, 0);\n" n;
+ pr " OUTPUT:\n";
+ pr " RETVAL\n"
| RString n ->
pr "PREINIT:\n";
pr " char *%s;\n" n;
pr " free (%s);\n" n;
pr " OUTPUT:\n";
pr " RETVAL\n"
+ | RBool n ->
+ pr "PREINIT:\n";
+ pr " int %s;\n" n;
+ pr " CODE:\n";
+ pr " %s = guestfs_%s " n name;
+ generate_call_args ~handle:"g" style;
+ pr ";\n";
+ pr " if (%s == -1)\n" n;
+ pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " RETVAL = newSViv (%s);\n" n;
+ pr " OUTPUT:\n";
+ pr " RETVAL\n"
| RStringList n ->
pr "PREINIT:\n";
pr " char **%s;\n" n;
generate_perl_lvm_code "lv" lv_cols name style n;
);
pr "\n"
- ) functions
+ ) all_functions
and generate_perl_lvm_code typ cols name style n =
pr "PREINIT:\n";
return $self;
}
-=item $h->add_drive ($filename);
-
-=item $h->add_cdrom ($filename);
-
-This function adds a virtual machine disk image C<filename> to the
-guest. The first time you call this function, the disk appears as IDE
-disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
-so on.
-
-You don't necessarily need to be root when using libguestfs. However
-you obviously do need sufficient permissions to access the filename
-for whatever operations you want to perform (ie. read access if you
-just want to read the image or write access if you want to modify the
-image).
-
-The C<add_cdrom> variation adds a CD-ROM device.
-
-=item $h->config ($param, $value);
-
-=item $h->config ($param);
-
-Use this to add arbitrary parameters to the C<qemu> command line.
-See L<qemu(1)>.
-
-=item $h->launch ();
-
-=item $h->wait_ready ();
-
-Internally libguestfs is implemented by running a virtual machine
-using L<qemu(1)>. These calls are necessary in order to boot the
-virtual machine.
-
-You should call these two functions after configuring the handle
-(eg. adding drives) but before performing any actions.
-
-=item $h->set_path ($path);
-
-=item $path = $h->get_path ();
-
-See the discussion of C<PATH> in the L<guestfs(3)>
-manpage.
-
-=item $h->set_autosync ($autosync);
-
-=item $autosync = $h->get_autosync ();
-
-See the discussion of I<AUTOSYNC> in the L<guestfs(3)>
-manpage.
-
-=item $h->set_verbose ($verbose);
-
-=item $verbose = $h->get_verbose ();
-
-This sets or gets the verbose messages flag. Verbose
-messages are sent to C<stderr>.
-
";
(* Actions. We only need to print documentation for these as
pr "Because of the message protocol, there is a transfer limit
of somewhere between 2MB and 4MB. To transfer large files you should use
FTP.\n\n";
- ) sorted_functions;
+ ) all_functions_sorted;
(* End of file. *)
pr "\
and generate_perl_prototype name style =
(match fst style with
| Err -> ()
+ | RBool n
+ | RConstString n
| RString n -> pr "$%s = " n
| RStringList n
| RPVList n
comma := true;
match arg with
| String n -> pr "%s" n
+ | OptString n -> pr "%s" n
+ | Bool n -> pr "%s" n
) (snd style);
pr ");"
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+extern int guestfs_launch (guestfs_h *handle);
+extern int guestfs_wait_ready (guestfs_h *handle);
+extern int guestfs_kill_subprocess (guestfs_h *handle);
+extern int guestfs_add_drive (guestfs_h *handle, const char *filename);
+extern int guestfs_add_cdrom (guestfs_h *handle, const char *filename);
+extern int guestfs_config (guestfs_h *handle, const char *qemuparam, const char *qemuvalue);
+extern int guestfs_set_path (guestfs_h *handle, const char *path);
+extern const char *guestfs_get_path (guestfs_h *handle);
+extern int guestfs_set_autosync (guestfs_h *handle, int autosync);
+extern int guestfs_get_autosync (guestfs_h *handle);
+extern int guestfs_set_verbose (guestfs_h *handle, int verbose);
+extern int guestfs_get_verbose (guestfs_h *handle);
extern int guestfs_mount (guestfs_h *handle, const char *device, const char *mountpoint);
extern int guestfs_sync (guestfs_h *handle);
extern int guestfs_touch (guestfs_h *handle, const char *path);
return g->error_cb;
}
-void
+int
guestfs_set_verbose (guestfs_h *g, int v)
{
- g->verbose = v;
+ g->verbose = !!v;
+ return 0;
}
int
return g->verbose;
}
-void
+int
guestfs_set_autosync (guestfs_h *g, int a)
{
- g->autosync = a;
+ g->autosync = !!a;
+ return 0;
}
int
return g->autosync;
}
-void
+int
guestfs_set_path (guestfs_h *g, const char *path)
{
if (path == NULL)
g->path = GUESTFS_DEFAULT_PATH;
else
g->path = path;
+ return 0;
}
const char *
/* Connection management. */
extern guestfs_h *guestfs_create (void);
extern void guestfs_close (guestfs_h *g);
-extern int guestfs_launch (guestfs_h *g);
-extern int guestfs_wait_ready (guestfs_h *g);
-extern int guestfs_kill_subprocess (guestfs_h *g);
-
-/* Configuration management. */
-extern int guestfs_config (guestfs_h *g,
- const char *qemu_param, const char *qemu_value);
-extern int guestfs_add_drive (guestfs_h *g, const char *filename);
-extern int guestfs_add_cdrom (guestfs_h *g, const char *filename);
/* Error handling. */
typedef void (*guestfs_error_handler_cb) (guestfs_h *g, void *data, const char *msg);
extern void guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb);
extern guestfs_abort_cb guestfs_get_out_of_memory_handler (guestfs_h *g);
-/* Misc. */
-extern void guestfs_set_verbose (guestfs_h *g, int verbose);
-extern int guestfs_get_verbose (guestfs_h *g);
-extern void guestfs_set_autosync (guestfs_h *g, int a);
-extern int guestfs_get_autosync (guestfs_h *g);
-extern void guestfs_set_path (guestfs_h *g, const char *path);
-extern const char *guestfs_get_path (guestfs_h *g);
-
#include <guestfs-structs.h>
#include <guestfs-actions.h>