TESTS = $(check_PROGRAMS)
+$(TESTS): $(INITRAMFS) $(VMLINUZ)
+
# Manual pages.
# guestfs-actions.pod and guestfs-structs are autogenerated. There is
# no include mechanism for POD, so we have to do it by hand.
extern int do_mkdir_p (const char *path);
extern int do_chmod (int mode, const char *path);
extern int do_chown (int owner, int group, const char *path);
+extern int do_exists (const char *path);
+extern int do_is_file (const char *path);
+extern int do_is_dir (const char *path);
+extern int do_pvcreate (const char *device);
+extern int do_vgcreate (const char *volgroup, char * const* const physvols);
+extern int do_lvcreate (const char *logvol, const char *volgroup, int mbytes);
+extern int do_mkfs (const char *fstype, const char *device);
+extern int do_sfdisk (const char *device, int cyls, int heads, int sectors, char * const* const lines);
+extern int do_write_file (const char *path, const char *content, int size);
+extern int do_umount (const char *pathordevice);
+extern char **do_mounts (void);
+extern int do_umount_all (void);
+extern int do_lvm_remove_all (void);
#include <stdarg.h>
#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include "../src/guestfs_protocol.h"
/* in guestfsd.c */
-extern void xwrite (int sock, const void *buf, size_t len);
-extern void xread (int sock, void *buf, size_t len);
+extern int xwrite (int sock, const void *buf, size_t len);
+extern int xread (int sock, void *buf, size_t len);
extern int add_string (char ***argv, int *size, int *alloc, const char *str);
-extern int count_strings (char **argv);
+extern int count_strings (char * const* const argv);
extern void sort_strings (char **argv, int len);
extern void free_strings (char **argv);
extern void free_stringslen (char **argv, int len);
extern int command (char **stdoutput, char **stderror, const char *name, ...);
+extern int commandv (char **stdoutput, char **stderror,
+ char * const* const argv);
/* in proto.c */
extern int proc_nr;
} \
} while (0)
+#define IS_DEVICE(path,errcode) \
+ do { \
+ struct stat statbuf; \
+ if (strncmp ((path), "/dev/", 5) != 0) { \
+ reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \
+ return (errcode); \
+ } \
+ if (stat ((path), &statbuf) == -1) { \
+ reply_with_perror ("%s: %s", __func__, (path)); \
+ return (errcode); \
+ } \
+ } while (0)
+
/* NB:
* (1) You must match CHROOT_IN and CHROOT_OUT even along error paths.
* (2) You must not change directory! cwd must always be "/", otherwise
#define CHROOT_OUT \
do { int old_errno = errno; chroot ("."); errno = old_errno; } while (0)
+#define XXX_NOT_IMPL(errcode) \
+ do { \
+ reply_with_error ("%s: function not implemented", __func__); \
+ return (errcode); \
+ } \
+ while (0)
+
#endif /* GUESTFSD_DAEMON_H */
sort_strings (r, size-1);
return r;
}
+
+int
+do_mkfs (const char *fstype, const char *device)
+{
+ char *err;
+ int r;
+
+ IS_DEVICE (device, -1);
+
+ r = command (NULL, &err, "/sbin/mkfs", "-t", fstype, device, NULL);
+ if (r == -1) {
+ reply_with_error ("mkfs: %s", err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
+
+int
+do_sfdisk (const char *device, int cyls, int heads, int sectors,
+ char * const* const lines)
+{
+ FILE *fp;
+ char buf[256];
+ int i;
+
+ IS_DEVICE (device, -1);
+
+ /* Safe because of IS_DEVICE above. */
+ strcpy (buf, "/sbin/sfdisk");
+ if (cyls)
+ sprintf (buf + strlen (buf), " -C %d", cyls);
+ if (heads)
+ sprintf (buf + strlen (buf), " -H %d", heads);
+ if (sectors)
+ sprintf (buf + strlen (buf), " -S %d", sectors);
+ sprintf (buf + strlen (buf), " %s", device);
+
+ fp = popen (buf, "w");
+ if (fp == NULL) {
+ reply_with_perror (buf);
+ return -1;
+ }
+
+ for (i = 0; lines[i] != NULL; ++i) {
+ if (fprintf (fp, "%s\n", lines[i]) < 0) {
+ reply_with_perror (buf);
+ fclose (fp);
+ return -1;
+ }
+ }
+
+ if (fclose (fp) == EOF) {
+ reply_with_perror (buf);
+ fclose (fp);
+ return -1;
+ }
+
+ return 0;
+}
snprintf (buf, len, "/sysroot%s", path);
- r = command (NULL, &err, "rm", "-rf", buf);
+ r = command (NULL, &err, "rm", "-rf", buf, NULL);
free (buf);
/* rm -rf is never supposed to fail. I/O errors perhaps? */
return 0;
}
+
+int
+do_is_dir (const char *path)
+{
+ int r;
+ struct stat buf;
+
+ NEED_ROOT (-1);
+ ABS_PATH (path, -1);
+
+ CHROOT_IN;
+ r = lstat (path, &buf);
+ CHROOT_OUT;
+
+ if (r == -1) {
+ if (errno != ENOENT && errno != ENOTDIR) {
+ reply_with_perror ("stat: %s", path);
+ return -1;
+ }
+ else
+ return 0; /* Not a directory. */
+ }
+
+ return S_ISDIR (buf.st_mode);
+}
return 0;
}
+
+int
+do_exists (const char *path)
+{
+ int r;
+
+ NEED_ROOT (-1);
+ ABS_PATH (path, -1);
+
+ CHROOT_IN;
+ r = access (path, F_OK);
+ CHROOT_OUT;
+
+ return r == 0;
+}
+
+int
+do_is_file (const char *path)
+{
+ int r;
+ struct stat buf;
+
+ NEED_ROOT (-1);
+ ABS_PATH (path, -1);
+
+ CHROOT_IN;
+ r = lstat (path, &buf);
+ CHROOT_OUT;
+
+ if (r == -1) {
+ if (errno != ENOENT && errno != ENOTDIR) {
+ reply_with_perror ("stat: %s", path);
+ return -1;
+ }
+ else
+ return 0; /* Not a file. */
+ }
+
+ return S_ISREG (buf.st_mode);
+}
+
+int
+do_write_file (const char *path, const char *content, int size)
+{
+ int fd;
+
+ NEED_ROOT (-1);
+ ABS_PATH (path, -1);
+
+ if (size == 0)
+ size = strlen (content);
+
+ CHROOT_IN;
+ fd = open (path, O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0666);
+ CHROOT_OUT;
+
+ if (fd == -1) {
+ reply_with_perror ("open: %s", path);
+ return -1;
+ }
+
+ if (xwrite (fd, content, size) == -1) {
+ reply_with_perror ("write");
+ close (fd);
+ return -1;
+ }
+
+ if (close (fd) == -1) {
+ reply_with_perror ("close: %s", path);
+ return -1;
+ }
+
+ return 0;
+}
exit (1);
}
- xwrite (sock, buf, xdr_getpos (&xdr));
+ (void) xwrite (sock, buf, xdr_getpos (&xdr));
xdr_destroy (&xdr);
exit (0);
}
-void
+int
xwrite (int sock, const void *buf, size_t len)
{
int r;
r = write (sock, buf, len);
if (r == -1) {
perror ("write");
- exit (1);
+ return -1;
}
buf += r;
len -= r;
}
+
+ return 0;
}
-void
+int
xread (int sock, void *buf, size_t len)
{
int r;
r = read (sock, buf, len);
if (r == -1) {
perror ("read");
- exit (1);
+ return -1;
}
if (r == 0) {
- fprintf (stderr, "read: unexpected end of file on comms socket\n");
- exit (1);
+ fprintf (stderr, "read: unexpected end of file on fd %d\n", sock);
+ return -1;
}
buf += r;
len -= r;
}
+
+ return 0;
}
static void
}
int
-count_strings (char **argv)
+count_strings (char * const* const argv)
{
int argc;
int
command (char **stdoutput, char **stderror, const char *name, ...)
{
+ va_list args;
+ char **argv;
+ char *s;
+ int i, r;
+
+ /* Collect the command line arguments into an array. */
+ va_start (args, name);
+
+ i = 2;
+ argv = malloc (sizeof (char *) * i);
+ argv[0] = (char *) name;
+ argv[1] = NULL;
+
+ while ((s = va_arg (args, char *)) != NULL) {
+ argv = realloc (argv, sizeof (char *) * (++i));
+ argv[i-2] = s;
+ argv[i-1] = NULL;
+ }
+
+ va_end (args);
+
+ r = commandv (stdoutput, stderror, argv);
+
+ /* NB: Mustn't free the strings which are on the stack. */
+ free (argv);
+
+ return r;
+}
+
+int
+commandv (char **stdoutput, char **stderror, char * const* const argv)
+{
int so_size = 0, se_size = 0;
int so_fd[2], se_fd[2];
- int pid, r, quit;
+ int pid, r, quit, i;
fd_set rset, rset2;
char buf[256];
if (stdoutput) *stdoutput = NULL;
if (stderror) *stderror = NULL;
+ printf ("%s", argv[0]);
+ for (i = 1; argv[i] != NULL; ++i)
+ printf (" %s", argv[i]);
+ printf ("\n");
+
if (pipe (so_fd) == -1 || pipe (se_fd) == -1) {
perror ("pipe");
return -1;
}
if (pid == 0) { /* Child process. */
- va_list args;
- char **argv;
- char *s;
- int i;
-
- /* Collect the command line arguments into an array. */
- va_start (args, name);
-
- i = 2;
- argv = malloc (sizeof (char *) * i);
- argv[0] = (char *) name;
- argv[1] = NULL;
-
- while ((s = va_arg (args, char *)) != NULL) {
- argv = realloc (argv, sizeof (char *) * (++i));
- argv[i-2] = s;
- argv[i-1] = NULL;
- }
-
close (0);
close (so_fd[0]);
close (se_fd[0]);
close (so_fd[1]);
close (se_fd[1]);
- execvp (name, argv);
- perror (name);
+ execvp (argv[0], argv);
+ perror (argv[0]);
_exit (1);
}
FD_SET (se_fd[0], &rset);
quit = 0;
- while (!quit) {
+ while (quit < 2) {
rset2 = rset;
r = select (MAX (so_fd[0], se_fd[0]) + 1, &rset2, NULL, NULL, NULL);
if (r == -1) {
waitpid (pid, NULL, 0);
return -1;
}
- if (r == 0) quit = 1;
+ if (r == 0) { FD_CLR (so_fd[0], &rset); quit++; }
if (r > 0 && stdoutput) {
so_size += r;
waitpid (pid, NULL, 0);
return -1;
}
- if (r == 0) quit = 1;
+ if (r == 0) { FD_CLR (se_fd[0], &rset); quit++; }
if (r > 0 && stderror) {
se_size += r;
{
return parse_command_line_lvs ();
}
+
+int
+do_pvcreate (const char *device)
+{
+ char *err;
+ int r;
+
+ r = command (NULL, &err,
+ "/sbin/lvm", "pvcreate", device, NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
+
+int
+do_vgcreate (const char *volgroup, char * const* const physvols)
+{
+ char *err;
+ int r, argc, i;
+ const char **argv;
+
+ argc = count_strings (physvols) + 3;
+ argv = malloc (sizeof (char *) * (argc + 1));
+ argv[0] = "/sbin/lvm";
+ argv[1] = "vgcreate";
+ argv[2] = volgroup;
+ for (i = 3; i <= argc; ++i)
+ argv[i] = physvols[i-3];
+
+ r = commandv (NULL, &err, argv);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
+
+int
+do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
+{
+ char *err;
+ int r;
+ char size[64];
+
+ snprintf (size, sizeof size, "%d", mbytes);
+
+ r = command (NULL, &err,
+ "/sbin/lvm", "lvcreate",
+ "-L", size, "-n", logvol, volgroup, NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+ return 0;
+}
+
+/* Super-dangerous command used for testing. It removes all
+ * LVs, VGs and PVs permanently.
+ */
+int
+do_lvm_remove_all (void)
+{
+ char **xs;
+ int i, r;
+ char *err;
+
+ /* Remove LVs. */
+ xs = do_lvs ();
+ if (xs == NULL)
+ return -1;
+
+ for (i = 0; xs[i] != NULL; ++i) {
+ r = command (NULL, &err, "/sbin/lvm", "lvremove", "-f", xs[i], NULL);
+ if (r == -1) {
+ reply_with_error ("lvremove: %s: %s", xs[i], err);
+ free (err);
+ free_strings (xs);
+ return -1;
+ }
+ free (err);
+ }
+ free_strings (xs);
+
+ /* Remove VGs. */
+ xs = do_vgs ();
+ if (xs == NULL)
+ return -1;
+
+ for (i = 0; xs[i] != NULL; ++i) {
+ r = command (NULL, &err, "/sbin/lvm", "vgremove", "-f", xs[i], NULL);
+ if (r == -1) {
+ reply_with_error ("vgremove: %s: %s", xs[i], err);
+ free (err);
+ free_strings (xs);
+ return -1;
+ }
+ free (err);
+ }
+ free_strings (xs);
+
+ /* Remove PVs. */
+ xs = do_pvs ();
+ if (xs == NULL)
+ return -1;
+
+ for (i = 0; xs[i] != NULL; ++i) {
+ r = command (NULL, &err, "/sbin/lvm", "pvremove", "-f", xs[i], NULL);
+ if (r == -1) {
+ reply_with_error ("pvremove: %s: %s", xs[i], err);
+ free (err);
+ free_strings (xs);
+ return -1;
+ }
+ free (err);
+ }
+ free_strings (xs);
+
+ /* There, that was easy, sorry about your data. */
+ return 0;
+}
return 0;
}
+
+/* Again, use the external /bin/umount program, so that /etc/mtab
+ * is kept updated.
+ */
+int
+do_umount (const char *pathordevice)
+{
+ int len, freeit = 0, r;
+ char *buf;
+ char *err;
+
+ if (strncmp (pathordevice, "/dev/", 5) == 0)
+ buf = (char *) pathordevice;
+ else {
+ len = strlen (pathordevice) + 9;
+ freeit = 1;
+ buf = malloc (len);
+ if (buf == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+ snprintf (buf, len, "/sysroot%s", pathordevice);
+ }
+
+ r = command (NULL, &err, "umount", buf, NULL);
+ if (freeit) free (buf);
+ if (r == -1) {
+ reply_with_error ("umount: %s: %s", pathordevice, err);
+ free (err);
+ return -1;
+ }
+
+ free (err);
+
+ /* update root_mounted? */
+
+ return 0;
+}
+
+char **
+do_mounts (void)
+{
+ char *out, *err;
+ int r;
+ char **ret = NULL;
+ int size = 0, alloc = 0;
+ char *p, *pend, *p2;
+
+ r = command (&out, &err, "mount", NULL);
+ if (r == -1) {
+ reply_with_error ("mount: %s", err);
+ free (out);
+ free (err);
+ return NULL;
+ }
+
+ free (err);
+
+ p = out;
+ while (p) {
+ pend = strchr (p, '\n');
+ if (pend) {
+ *pend = '\0';
+ pend++;
+ }
+
+ /* Lines have the format:
+ * /dev/foo on /mountpoint type ...
+ */
+ p2 = strstr (p, " on /sysroot");
+ if (p2 != NULL) {
+ *p2 = '\0';
+ if (add_string (&ret, &size, &alloc, p) == -1) {
+ free (out);
+ return NULL;
+ }
+ }
+
+ p = pend;
+ }
+
+ free (out);
+
+ if (add_string (&ret, &size, &alloc, NULL) == -1)
+ return NULL;
+
+ return ret;
+}
+
+/* Only unmount stuff under /sysroot */
+int
+do_umount_all (void)
+{
+ char **mounts;
+ int i, r;
+ char *err;
+
+ mounts = do_mounts ();
+ if (mounts == NULL) /* do_mounts has already replied */
+ return -1;
+
+ for (i = 0; mounts[i] != NULL; ++i) {
+ r = command (NULL, &err, "umount", mounts[i], NULL);
+ if (r == -1) {
+ reply_with_error ("umount: %s: %s", mounts[i], err);
+ free (err);
+ free_strings (mounts);
+ return -1;
+ }
+ free (err);
+ }
+
+ free_strings (mounts);
+ return 0;
+}
xdr_uint32_t (&xdr, &len);
xdr_destroy (&xdr);
- xwrite (sock, lenbuf, 4);
- xwrite (sock, buf, len);
+ (void) xwrite (sock, lenbuf, 4);
+ (void) xwrite (sock, buf, len);
}
void
xdr_uint32_t (&xdr, &len);
xdr_destroy (&xdr);
- xwrite (sock, lenbuf, 4);
- xwrite (sock, buf, len);
+ (void) xwrite (sock, lenbuf, 4);
+ (void) xwrite (sock, buf, len);
}
r = do_mount (device, mountpoint);
if (r == -1)
- /* do_mount has already called reply_with_error, so just return */
- return;
+ /* do_mount has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_mount_args, (char *) &args);
}
static void sync_stub (XDR *xdr_in)
r = do_sync ();
if (r == -1)
- /* do_sync has already called reply_with_error, so just return */
- return;
+ /* do_sync has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done: ;
}
static void touch_stub (XDR *xdr_in)
r = do_touch (path);
if (r == -1)
- /* do_touch has already called reply_with_error, so just return */
- return;
+ /* do_touch has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_touch_args, (char *) &args);
}
static void cat_stub (XDR *xdr_in)
r = do_cat (path);
if (r == NULL)
- /* do_cat has already called reply_with_error, so just return */
- return;
+ /* do_cat has already called reply_with_error */
+ goto done;
struct guestfs_cat_ret ret;
ret.content = r;
reply ((xdrproc_t) &xdr_guestfs_cat_ret, (char *) &ret);
free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_cat_args, (char *) &args);
}
static void ll_stub (XDR *xdr_in)
r = do_ll (directory);
if (r == NULL)
- /* do_ll has already called reply_with_error, so just return */
- return;
+ /* do_ll has already called reply_with_error */
+ goto done;
struct guestfs_ll_ret ret;
ret.listing = r;
reply ((xdrproc_t) &xdr_guestfs_ll_ret, (char *) &ret);
free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_ll_args, (char *) &args);
}
static void ls_stub (XDR *xdr_in)
r = do_ls (directory);
if (r == NULL)
- /* do_ls has already called reply_with_error, so just return */
- return;
+ /* do_ls has already called reply_with_error */
+ goto done;
struct guestfs_ls_ret ret;
ret.listing.listing_len = count_strings (r);
ret.listing.listing_val = r;
reply ((xdrproc_t) &xdr_guestfs_ls_ret, (char *) &ret);
free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_ls_args, (char *) &args);
}
static void list_devices_stub (XDR *xdr_in)
r = do_list_devices ();
if (r == NULL)
- /* do_list_devices has already called reply_with_error, so just return */
- return;
+ /* do_list_devices has already called reply_with_error */
+ goto done;
struct guestfs_list_devices_ret ret;
ret.devices.devices_len = count_strings (r);
ret.devices.devices_val = r;
reply ((xdrproc_t) &xdr_guestfs_list_devices_ret, (char *) &ret);
free_strings (r);
+done: ;
}
static void list_partitions_stub (XDR *xdr_in)
r = do_list_partitions ();
if (r == NULL)
- /* do_list_partitions has already called reply_with_error, so just return */
- return;
+ /* do_list_partitions has already called reply_with_error */
+ goto done;
struct guestfs_list_partitions_ret ret;
ret.partitions.partitions_len = count_strings (r);
ret.partitions.partitions_val = r;
reply ((xdrproc_t) &xdr_guestfs_list_partitions_ret, (char *) &ret);
free_strings (r);
+done: ;
}
static void pvs_stub (XDR *xdr_in)
r = do_pvs ();
if (r == NULL)
- /* do_pvs has already called reply_with_error, so just return */
- return;
+ /* do_pvs has already called reply_with_error */
+ goto done;
struct guestfs_pvs_ret ret;
ret.physvols.physvols_len = count_strings (r);
ret.physvols.physvols_val = r;
reply ((xdrproc_t) &xdr_guestfs_pvs_ret, (char *) &ret);
free_strings (r);
+done: ;
}
static void vgs_stub (XDR *xdr_in)
r = do_vgs ();
if (r == NULL)
- /* do_vgs has already called reply_with_error, so just return */
- return;
+ /* do_vgs has already called reply_with_error */
+ goto done;
struct guestfs_vgs_ret ret;
ret.volgroups.volgroups_len = count_strings (r);
ret.volgroups.volgroups_val = r;
reply ((xdrproc_t) &xdr_guestfs_vgs_ret, (char *) &ret);
free_strings (r);
+done: ;
}
static void lvs_stub (XDR *xdr_in)
r = do_lvs ();
if (r == NULL)
- /* do_lvs has already called reply_with_error, so just return */
- return;
+ /* do_lvs has already called reply_with_error */
+ goto done;
struct guestfs_lvs_ret ret;
ret.logvols.logvols_len = count_strings (r);
ret.logvols.logvols_val = r;
reply ((xdrproc_t) &xdr_guestfs_lvs_ret, (char *) &ret);
free_strings (r);
+done: ;
}
static void pvs_full_stub (XDR *xdr_in)
r = do_pvs_full ();
if (r == NULL)
- /* do_pvs_full has already called reply_with_error, so just return */
- return;
+ /* do_pvs_full has already called reply_with_error */
+ goto done;
struct guestfs_pvs_full_ret ret;
ret.physvols = *r;
reply ((xdrproc_t) xdr_guestfs_pvs_full_ret, (char *) &ret);
xdr_free ((xdrproc_t) xdr_guestfs_pvs_full_ret, (char *) &ret);
+done: ;
}
static void vgs_full_stub (XDR *xdr_in)
r = do_vgs_full ();
if (r == NULL)
- /* do_vgs_full has already called reply_with_error, so just return */
- return;
+ /* do_vgs_full has already called reply_with_error */
+ goto done;
struct guestfs_vgs_full_ret ret;
ret.volgroups = *r;
reply ((xdrproc_t) xdr_guestfs_vgs_full_ret, (char *) &ret);
xdr_free ((xdrproc_t) xdr_guestfs_vgs_full_ret, (char *) &ret);
+done: ;
}
static void lvs_full_stub (XDR *xdr_in)
r = do_lvs_full ();
if (r == NULL)
- /* do_lvs_full has already called reply_with_error, so just return */
- return;
+ /* do_lvs_full has already called reply_with_error */
+ goto done;
struct guestfs_lvs_full_ret ret;
ret.logvols = *r;
reply ((xdrproc_t) xdr_guestfs_lvs_full_ret, (char *) &ret);
xdr_free ((xdrproc_t) xdr_guestfs_lvs_full_ret, (char *) &ret);
+done: ;
}
static void read_lines_stub (XDR *xdr_in)
r = do_read_lines (path);
if (r == NULL)
- /* do_read_lines has already called reply_with_error, so just return */
- return;
+ /* do_read_lines has already called reply_with_error */
+ goto done;
struct guestfs_read_lines_ret ret;
ret.lines.lines_len = count_strings (r);
ret.lines.lines_val = r;
reply ((xdrproc_t) &xdr_guestfs_read_lines_ret, (char *) &ret);
free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_read_lines_args, (char *) &args);
}
static void aug_init_stub (XDR *xdr_in)
r = do_aug_init (root, flags);
if (r == -1)
- /* do_aug_init has already called reply_with_error, so just return */
- return;
+ /* do_aug_init has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_init_args, (char *) &args);
}
static void aug_close_stub (XDR *xdr_in)
r = do_aug_close ();
if (r == -1)
- /* do_aug_close has already called reply_with_error, so just return */
- return;
+ /* do_aug_close has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done: ;
}
static void aug_defvar_stub (XDR *xdr_in)
r = do_aug_defvar (name, expr);
if (r == -1)
- /* do_aug_defvar has already called reply_with_error, so just return */
- return;
+ /* do_aug_defvar has already called reply_with_error */
+ goto done;
struct guestfs_aug_defvar_ret ret;
ret.nrnodes = r;
reply ((xdrproc_t) &xdr_guestfs_aug_defvar_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_defvar_args, (char *) &args);
}
static void aug_defnode_stub (XDR *xdr_in)
r = do_aug_defnode (name, expr, val);
if (r == NULL)
- /* do_aug_defnode has already called reply_with_error, so just return */
- return;
+ /* do_aug_defnode has already called reply_with_error */
+ goto done;
reply ((xdrproc_t) xdr_guestfs_aug_defnode_ret, (char *) r);
xdr_free ((xdrproc_t) xdr_guestfs_aug_defnode_ret, (char *) r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_defnode_args, (char *) &args);
}
static void aug_get_stub (XDR *xdr_in)
r = do_aug_get (path);
if (r == NULL)
- /* do_aug_get has already called reply_with_error, so just return */
- return;
+ /* do_aug_get has already called reply_with_error */
+ goto done;
struct guestfs_aug_get_ret ret;
ret.val = r;
reply ((xdrproc_t) &xdr_guestfs_aug_get_ret, (char *) &ret);
free (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_get_args, (char *) &args);
}
static void aug_set_stub (XDR *xdr_in)
r = do_aug_set (path, val);
if (r == -1)
- /* do_aug_set has already called reply_with_error, so just return */
- return;
+ /* do_aug_set has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_set_args, (char *) &args);
}
static void aug_insert_stub (XDR *xdr_in)
r = do_aug_insert (path, label, before);
if (r == -1)
- /* do_aug_insert has already called reply_with_error, so just return */
- return;
+ /* do_aug_insert has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_insert_args, (char *) &args);
}
static void aug_rm_stub (XDR *xdr_in)
r = do_aug_rm (path);
if (r == -1)
- /* do_aug_rm has already called reply_with_error, so just return */
- return;
+ /* do_aug_rm has already called reply_with_error */
+ goto done;
struct guestfs_aug_rm_ret ret;
ret.nrnodes = r;
reply ((xdrproc_t) &xdr_guestfs_aug_rm_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_rm_args, (char *) &args);
}
static void aug_mv_stub (XDR *xdr_in)
r = do_aug_mv (src, dest);
if (r == -1)
- /* do_aug_mv has already called reply_with_error, so just return */
- return;
+ /* do_aug_mv has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_mv_args, (char *) &args);
}
static void aug_match_stub (XDR *xdr_in)
r = do_aug_match (path);
if (r == NULL)
- /* do_aug_match has already called reply_with_error, so just return */
- return;
+ /* do_aug_match has already called reply_with_error */
+ goto done;
struct guestfs_aug_match_ret ret;
ret.matches.matches_len = count_strings (r);
ret.matches.matches_val = r;
reply ((xdrproc_t) &xdr_guestfs_aug_match_ret, (char *) &ret);
free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_match_args, (char *) &args);
}
static void aug_save_stub (XDR *xdr_in)
r = do_aug_save ();
if (r == -1)
- /* do_aug_save has already called reply_with_error, so just return */
- return;
+ /* do_aug_save has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done: ;
}
static void aug_load_stub (XDR *xdr_in)
r = do_aug_load ();
if (r == -1)
- /* do_aug_load has already called reply_with_error, so just return */
- return;
+ /* do_aug_load has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done: ;
}
static void aug_ls_stub (XDR *xdr_in)
r = do_aug_ls (path);
if (r == NULL)
- /* do_aug_ls has already called reply_with_error, so just return */
- return;
+ /* do_aug_ls has already called reply_with_error */
+ goto done;
struct guestfs_aug_ls_ret ret;
ret.matches.matches_len = count_strings (r);
ret.matches.matches_val = r;
reply ((xdrproc_t) &xdr_guestfs_aug_ls_ret, (char *) &ret);
free_strings (r);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_aug_ls_args, (char *) &args);
}
static void rm_stub (XDR *xdr_in)
r = do_rm (path);
if (r == -1)
- /* do_rm has already called reply_with_error, so just return */
- return;
+ /* do_rm has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_rm_args, (char *) &args);
}
static void rmdir_stub (XDR *xdr_in)
r = do_rmdir (path);
if (r == -1)
- /* do_rmdir has already called reply_with_error, so just return */
- return;
+ /* do_rmdir has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_rmdir_args, (char *) &args);
}
static void rm_rf_stub (XDR *xdr_in)
r = do_rm_rf (path);
if (r == -1)
- /* do_rm_rf has already called reply_with_error, so just return */
- return;
+ /* do_rm_rf has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_rm_rf_args, (char *) &args);
}
static void mkdir_stub (XDR *xdr_in)
r = do_mkdir (path);
if (r == -1)
- /* do_mkdir has already called reply_with_error, so just return */
- return;
+ /* do_mkdir has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_mkdir_args, (char *) &args);
}
static void mkdir_p_stub (XDR *xdr_in)
r = do_mkdir_p (path);
if (r == -1)
- /* do_mkdir_p has already called reply_with_error, so just return */
- return;
+ /* do_mkdir_p has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_mkdir_p_args, (char *) &args);
}
static void chmod_stub (XDR *xdr_in)
r = do_chmod (mode, path);
if (r == -1)
- /* do_chmod has already called reply_with_error, so just return */
- return;
+ /* do_chmod has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_chmod_args, (char *) &args);
}
static void chown_stub (XDR *xdr_in)
r = do_chown (owner, group, path);
if (r == -1)
- /* do_chown has already called reply_with_error, so just return */
+ /* do_chown has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_chown_args, (char *) &args);
+}
+
+static void exists_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_exists_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_exists_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "exists");
return;
+ }
+ path = args.path;
+
+ r = do_exists (path);
+ if (r == -1)
+ /* do_exists has already called reply_with_error */
+ goto done;
+
+ struct guestfs_exists_ret ret;
+ ret.existsflag = r;
+ reply ((xdrproc_t) &xdr_guestfs_exists_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_exists_args, (char *) &args);
+}
+
+static void is_file_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_is_file_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_is_file_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "is_file");
+ return;
+ }
+ path = args.path;
+
+ r = do_is_file (path);
+ if (r == -1)
+ /* do_is_file has already called reply_with_error */
+ goto done;
+
+ struct guestfs_is_file_ret ret;
+ ret.fileflag = r;
+ reply ((xdrproc_t) &xdr_guestfs_is_file_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_is_file_args, (char *) &args);
+}
+
+static void is_dir_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_is_dir_args args;
+ const char *path;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_is_dir_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "is_dir");
+ return;
+ }
+ path = args.path;
+
+ r = do_is_dir (path);
+ if (r == -1)
+ /* do_is_dir has already called reply_with_error */
+ goto done;
+
+ struct guestfs_is_dir_ret ret;
+ ret.dirflag = r;
+ reply ((xdrproc_t) &xdr_guestfs_is_dir_ret, (char *) &ret);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_is_dir_args, (char *) &args);
+}
+
+static void pvcreate_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_pvcreate_args args;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_pvcreate_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "pvcreate");
+ return;
+ }
+ device = args.device;
+
+ r = do_pvcreate (device);
+ if (r == -1)
+ /* do_pvcreate has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_pvcreate_args, (char *) &args);
+}
+
+static void vgcreate_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_vgcreate_args args;
+ const char *volgroup;
+ char **physvols;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_vgcreate_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "vgcreate");
+ return;
+ }
+ volgroup = args.volgroup;
+ args.physvols.physvols_val = realloc (args.physvols.physvols_val, sizeof (char *) * (args.physvols.physvols_len+1));
+ args.physvols.physvols_val[args.physvols.physvols_len] = NULL;
+ physvols = args.physvols.physvols_val;
+
+ r = do_vgcreate (volgroup, physvols);
+ if (r == -1)
+ /* do_vgcreate has already called reply_with_error */
+ goto done;
reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_vgcreate_args, (char *) &args);
+}
+
+static void lvcreate_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_lvcreate_args args;
+ const char *logvol;
+ const char *volgroup;
+ int mbytes;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_lvcreate_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "lvcreate");
+ return;
+ }
+ logvol = args.logvol;
+ volgroup = args.volgroup;
+ mbytes = args.mbytes;
+
+ r = do_lvcreate (logvol, volgroup, mbytes);
+ if (r == -1)
+ /* do_lvcreate has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_lvcreate_args, (char *) &args);
+}
+
+static void mkfs_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_mkfs_args args;
+ const char *fstype;
+ const char *device;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_mkfs_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "mkfs");
+ return;
+ }
+ fstype = args.fstype;
+ device = args.device;
+
+ r = do_mkfs (fstype, device);
+ if (r == -1)
+ /* do_mkfs has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_mkfs_args, (char *) &args);
+}
+
+static void sfdisk_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_sfdisk_args args;
+ const char *device;
+ int cyls;
+ int heads;
+ int sectors;
+ char **lines;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_sfdisk_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "sfdisk");
+ return;
+ }
+ device = args.device;
+ cyls = args.cyls;
+ heads = args.heads;
+ sectors = args.sectors;
+ args.lines.lines_val = realloc (args.lines.lines_val, sizeof (char *) * (args.lines.lines_len+1));
+ args.lines.lines_val[args.lines.lines_len] = NULL;
+ lines = args.lines.lines_val;
+
+ r = do_sfdisk (device, cyls, heads, sectors, lines);
+ if (r == -1)
+ /* do_sfdisk has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_sfdisk_args, (char *) &args);
+}
+
+static void write_file_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_write_file_args args;
+ const char *path;
+ const char *content;
+ int size;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_write_file_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "write_file");
+ return;
+ }
+ path = args.path;
+ content = args.content;
+ size = args.size;
+
+ r = do_write_file (path, content, size);
+ if (r == -1)
+ /* do_write_file has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_write_file_args, (char *) &args);
+}
+
+static void umount_stub (XDR *xdr_in)
+{
+ int r;
+ struct guestfs_umount_args args;
+ const char *pathordevice;
+
+ memset (&args, 0, sizeof args);
+
+ if (!xdr_guestfs_umount_args (xdr_in, &args)) {
+ reply_with_error ("%s: daemon failed to decode procedure arguments", "umount");
+ return;
+ }
+ pathordevice = args.pathordevice;
+
+ r = do_umount (pathordevice);
+ if (r == -1)
+ /* do_umount has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done:
+ xdr_free ((xdrproc_t) xdr_guestfs_umount_args, (char *) &args);
+}
+
+static void mounts_stub (XDR *xdr_in)
+{
+ char **r;
+
+ r = do_mounts ();
+ if (r == NULL)
+ /* do_mounts has already called reply_with_error */
+ goto done;
+
+ struct guestfs_mounts_ret ret;
+ ret.devices.devices_len = count_strings (r);
+ ret.devices.devices_val = r;
+ reply ((xdrproc_t) &xdr_guestfs_mounts_ret, (char *) &ret);
+ free_strings (r);
+done: ;
+}
+
+static void umount_all_stub (XDR *xdr_in)
+{
+ int r;
+
+ r = do_umount_all ();
+ if (r == -1)
+ /* do_umount_all has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done: ;
+}
+
+static void lvm_remove_all_stub (XDR *xdr_in)
+{
+ int r;
+
+ r = do_lvm_remove_all ();
+ if (r == -1)
+ /* do_lvm_remove_all has already called reply_with_error */
+ goto done;
+
+ reply (NULL, NULL);
+done: ;
}
void dispatch_incoming_message (XDR *xdr_in)
case GUESTFS_PROC_CHOWN:
chown_stub (xdr_in);
break;
+ case GUESTFS_PROC_EXISTS:
+ exists_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_IS_FILE:
+ is_file_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_IS_DIR:
+ is_dir_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_PVCREATE:
+ pvcreate_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_VGCREATE:
+ vgcreate_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_LVCREATE:
+ lvcreate_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_MKFS:
+ mkfs_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_SFDISK:
+ sfdisk_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_WRITE_FILE:
+ write_file_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_UMOUNT:
+ umount_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_MOUNTS:
+ mounts_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_UMOUNT_ALL:
+ umount_all_stub (xdr_in);
+ break;
+ case GUESTFS_PROC_LVM_REMOVE_ALL:
+ lvm_remove_all_stub (xdr_in);
+ break;
default:
reply_with_error ("dispatch_incoming_message: unknown procedure number %d", proc_nr);
}
do_sync ()
{
sync ();
- fprintf (stderr, "guestfsd: disk synched\n");
return 0;
}
printf ("%-20s %s\n", "chmod", "change file mode");
printf ("%-20s %s\n", "chown", "change file owner and group");
printf ("%-20s %s\n", "config", "add qemu parameters");
+ printf ("%-20s %s\n", "exists", "test if file or directory exists");
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", "is-dir", "test if file exists");
+ printf ("%-20s %s\n", "is-file", "test if file exists");
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", "ls", "list the files in a directory");
+ printf ("%-20s %s\n", "lvcreate", "create an LVM volume group");
+ printf ("%-20s %s\n", "lvm-remove-all", "remove all LVM LVs, VGs and PVs");
printf ("%-20s %s\n", "lvs", "list the LVM logical volumes (LVs)");
printf ("%-20s %s\n", "lvs-full", "list the LVM logical volumes (LVs)");
printf ("%-20s %s\n", "mkdir", "create a directory");
printf ("%-20s %s\n", "mkdir-p", "create a directory and parents");
+ printf ("%-20s %s\n", "mkfs", "make a filesystem");
printf ("%-20s %s\n", "mount", "mount a guest disk at a position in the filesystem");
+ printf ("%-20s %s\n", "mounts", "show mounted filesystems");
+ printf ("%-20s %s\n", "pvcreate", "create an LVM physical volume");
printf ("%-20s %s\n", "pvs", "list the LVM physical volumes (PVs)");
printf ("%-20s %s\n", "pvs-full", "list the LVM physical volumes (PVs)");
printf ("%-20s %s\n", "read-lines", "read file as lines");
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", "sfdisk", "create partitions on a block device");
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", "umount", "unmount a filesystem");
+ printf ("%-20s %s\n", "umount-all", "unmount all filesystems");
+ printf ("%-20s %s\n", "vgcreate", "create an LVM volume group");
printf ("%-20s %s\n", "vgs", "list the LVM volume groups (VGs)");
printf ("%-20s %s\n", "vgs-full", "list the LVM volume groups (VGs)");
+ printf ("%-20s %s\n", "write-file", "Create a file");
printf (" Use -h <cmd> / help <cmd> to show detailed help for a command.\n");
}
if (strcasecmp (cmd, "chown") == 0)
pod2text ("chown - change file owner and group", " chown <owner> <group> <path>\n\nChange the file owner to C<owner> and group to C<group>.\n\nOnly numeric uid and gid are supported. If you want to use\nnames, you will need to locate and parse the password file\nyourself (Augeas support makes this relatively easy).");
else
+ if (strcasecmp (cmd, "exists") == 0)
+ pod2text ("exists - test if file or directory exists", " exists <path>\n\nThis returns C<true> if and only if there is a file, directory\n(or anything) with the given C<path> name.\n\nSee also C<is_file>, C<is_dir>, C<stat>.");
+ else
+ if (strcasecmp (cmd, "is_file") == 0 || strcasecmp (cmd, "is-file") == 0)
+ pod2text ("is-file - test if file exists", " is-file <path>\n\nThis returns C<true> if and only if there is a file\nwith the given C<path> name. Note that it returns false for\nother objects like directories.\n\nSee also C<stat>.");
+ else
+ if (strcasecmp (cmd, "is_dir") == 0 || strcasecmp (cmd, "is-dir") == 0)
+ pod2text ("is-dir - test if file exists", " is-dir <path>\n\nThis returns C<true> if and only if there is a directory\nwith the given C<path> name. Note that it returns false for\nother objects like files.\n\nSee also C<stat>.");
+ else
+ if (strcasecmp (cmd, "pvcreate") == 0)
+ pod2text ("pvcreate - create an LVM physical volume", " pvcreate <device>\n\nThis creates an LVM physical volume on the named C<device>,\nwhere C<device> should usually be a partition name such\nas C</dev/sda1>.");
+ else
+ if (strcasecmp (cmd, "vgcreate") == 0)
+ pod2text ("vgcreate - create an LVM volume group", " vgcreate <volgroup> <physvols>\n\nThis creates an LVM volume group called C<volgroup>\nfrom the non-empty list of physical volumes C<physvols>.");
+ else
+ if (strcasecmp (cmd, "lvcreate") == 0)
+ pod2text ("lvcreate - create an LVM volume group", " lvcreate <logvol> <volgroup> <mbytes>\n\nThis creates an LVM volume group called C<logvol>\non the volume group C<volgroup>, with C<size> megabytes.");
+ else
+ if (strcasecmp (cmd, "mkfs") == 0)
+ pod2text ("mkfs - make a filesystem", " mkfs <fstype> <device>\n\nThis creates a filesystem on C<device> (usually a partition\nof LVM logical volume). The filesystem type is C<fstype>, for\nexample C<ext3>.");
+ else
+ if (strcasecmp (cmd, "sfdisk") == 0)
+ pod2text ("sfdisk - create partitions on a block device", " sfdisk <device> <cyls> <heads> <sectors> <lines>\n\nThis is a direct interface to the L<sfdisk(8)> program for creating\npartitions on block devices.\n\nC<device> should be a block device, for example C</dev/sda>.\n\nC<cyls>, C<heads> and C<sectors> are the number of cylinders, heads\nand sectors on the device, which are passed directly to sfdisk as\nthe I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any\nof these, then the corresponding parameter is omitted. Usually for\n'large' disks, you can just pass C<0> for these, but for small\n(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work\nout the right geometry and you will need to tell it.\n\nC<lines> is a list of lines that we feed to C<sfdisk>. For more\ninformation refer to the L<sfdisk(8)> manpage.\n\nTo create a single partition occupying the whole disk, you would\npass C<lines> as a single element list, when the single element being\nthe string C<,> (comma).\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
+ else
+ if (strcasecmp (cmd, "write_file") == 0 || strcasecmp (cmd, "write-file") == 0)
+ pod2text ("write-file - Create a file", " write-file <path> <content> <size>\n\nThis call creates a file called C<path>. The contents of the\nfile is the string C<content> (which can contain any 8 bit data),\nwith length C<size>.\n\nAs a special case, if C<size> is C<0>\nthen the length is calculated using C<strlen> (so in this case\nthe content cannot contain embedded ASCII NULs).\n\nBecause of the message protocol, there is a transfer limit \nof somewhere between 2MB and 4MB. To transfer large files you should use\nFTP.");
+ else
+ if (strcasecmp (cmd, "umount") == 0 || strcasecmp (cmd, "unmount") == 0)
+ pod2text ("umount - unmount a filesystem", " umount <pathordevice>\n\nThis unmounts the given filesystem. The filesystem may be\nspecified either by its mountpoint (path) or the device which\ncontains the filesystem.\n\nYou can use 'unmount' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "mounts") == 0)
+ pod2text ("mounts - show mounted filesystems", " mounts\n\nThis returns the list of currently mounted filesystems. It returns\nthe list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).\n\nSome internal mounts are not shown.");
+ else
+ if (strcasecmp (cmd, "umount_all") == 0 || strcasecmp (cmd, "umount-all") == 0 || strcasecmp (cmd, "unmount-all") == 0)
+ pod2text ("umount-all - unmount all filesystems", " umount-all\n\nThis unmounts all mounted filesystems.\n\nSome internal mounts are not unmounted by this call.\n\nYou can use 'unmount-all' as an alias for this command.");
+ else
+ if (strcasecmp (cmd, "lvm_remove_all") == 0 || strcasecmp (cmd, "lvm-remove-all") == 0)
+ pod2text ("lvm-remove-all - remove all LVM LVs, VGs and PVs", " lvm-remove-all\n\nThis command removes all LVM logical volumes, volume groups\nand physical volumes.\n\nB<This command is dangerous. Without careful use you\ncan easily destroy all your data>.");
+ else
display_builtin_command (cmd);
}
return r;
}
+static int run_exists (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_exists (g, path);
+ if (r == -1) return -1;
+ if (r) printf ("true\n"); else printf ("false\n");
+ return 0;
+}
+
+static int run_is_file (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_is_file (g, path);
+ if (r == -1) return -1;
+ if (r) printf ("true\n"); else printf ("false\n");
+ return 0;
+}
+
+static int run_is_dir (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_is_dir (g, path);
+ if (r == -1) return -1;
+ if (r) printf ("true\n"); else printf ("false\n");
+ return 0;
+}
+
+static int run_pvcreate (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *device;
+ if (argc != 1) {
+ fprintf (stderr, "%s should have 1 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ r = guestfs_pvcreate (g, device);
+ return r;
+}
+
+static int run_vgcreate (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *volgroup;
+ char **physvols;
+ 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;
+ }
+ volgroup = argv[0];
+ physvols = parse_string_list (argv[1]);
+ r = guestfs_vgcreate (g, volgroup, physvols);
+ return r;
+}
+
+static int run_lvcreate (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *logvol;
+ const char *volgroup;
+ int mbytes;
+ if (argc != 3) {
+ fprintf (stderr, "%s should have 3 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ logvol = argv[0];
+ volgroup = argv[1];
+ mbytes = atoi (argv[2]);
+ r = guestfs_lvcreate (g, logvol, volgroup, mbytes);
+ return r;
+}
+
+static int run_mkfs (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *fstype;
+ const char *device;
+ 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;
+ }
+ fstype = argv[0];
+ device = argv[1];
+ r = guestfs_mkfs (g, fstype, device);
+ return r;
+}
+
+static int run_sfdisk (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *device;
+ int cyls;
+ int heads;
+ int sectors;
+ char **lines;
+ if (argc != 5) {
+ fprintf (stderr, "%s should have 5 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ device = argv[0];
+ cyls = atoi (argv[1]);
+ heads = atoi (argv[2]);
+ sectors = atoi (argv[3]);
+ lines = parse_string_list (argv[4]);
+ r = guestfs_sfdisk (g, device, cyls, heads, sectors, lines);
+ return r;
+}
+
+static int run_write_file (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *path;
+ const char *content;
+ int size;
+ if (argc != 3) {
+ fprintf (stderr, "%s should have 3 parameter(s)\n", cmd);
+ fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd);
+ return -1;
+ }
+ path = argv[0];
+ content = argv[1];
+ size = atoi (argv[2]);
+ r = guestfs_write_file (g, path, content, size);
+ return r;
+}
+
+static int run_umount (const char *cmd, int argc, char *argv[])
+{
+ int r;
+ const char *pathordevice;
+ 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;
+ }
+ pathordevice = argv[0];
+ r = guestfs_umount (g, pathordevice);
+ return r;
+}
+
+static int run_mounts (const char *cmd, int argc, char *argv[])
+{
+ 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_mounts (g);
+ if (r == NULL) return -1;
+ print_strings (r);
+ free_strings (r);
+ return 0;
+}
+
+static int run_umount_all (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_umount_all (g);
+ return r;
+}
+
+static int run_lvm_remove_all (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_lvm_remove_all (g);
+ return r;
+}
+
int run_action (const char *cmd, int argc, char *argv[])
{
if (strcasecmp (cmd, "launch") == 0 || strcasecmp (cmd, "run") == 0)
if (strcasecmp (cmd, "chown") == 0)
return run_chown (cmd, argc, argv);
else
+ if (strcasecmp (cmd, "exists") == 0)
+ return run_exists (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "is_file") == 0 || strcasecmp (cmd, "is-file") == 0)
+ return run_is_file (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "is_dir") == 0 || strcasecmp (cmd, "is-dir") == 0)
+ return run_is_dir (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "pvcreate") == 0)
+ return run_pvcreate (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "vgcreate") == 0)
+ return run_vgcreate (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "lvcreate") == 0)
+ return run_lvcreate (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "mkfs") == 0)
+ return run_mkfs (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "sfdisk") == 0)
+ return run_sfdisk (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "write_file") == 0 || strcasecmp (cmd, "write-file") == 0)
+ return run_write_file (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "umount") == 0 || strcasecmp (cmd, "unmount") == 0)
+ return run_umount (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "mounts") == 0)
+ return run_mounts (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "umount_all") == 0 || strcasecmp (cmd, "umount-all") == 0 || strcasecmp (cmd, "unmount-all") == 0)
+ return run_umount_all (cmd, argc, argv);
+ else
+ if (strcasecmp (cmd, "lvm_remove_all") == 0 || strcasecmp (cmd, "lvm-remove-all") == 0)
+ return run_lvm_remove_all (cmd, argc, argv);
+ else
{
fprintf (stderr, "%s: unknown command\n", cmd);
return -1;
#include <config.h>
+#define _GNU_SOURCE // for strchrnul
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}
void
-print_strings (char **argv)
+print_strings (char * const * const argv)
{
int argc;
strcasecmp (str, "n") != 0 &&
strcasecmp (str, "no") != 0;
}
+
+/* This is quite inadequate for real use. For example, there is no way
+ * to specify an empty list. We need to use a real parser to allow
+ * quoting, empty lists, etc.
+ */
+char **
+parse_string_list (const char *str)
+{
+ char **argv;
+ const char *p, *pend;
+ int argc, i;
+
+ argc = 1;
+ for (i = 0; str[i]; ++i)
+ if (str[i] == ':') argc++;
+
+ argv = malloc (sizeof (char *) * (argc+1));
+ if (argv == NULL) { perror ("malloc"); exit (1); }
+
+ p = str;
+ i = 0;
+ while (*p) {
+ pend = strchrnul (p, ':');
+ argv[i] = strndup (p, pend-p);
+ i++;
+ p = *pend == ':' ? pend+1 : p;
+ }
+ argv[i] = NULL;
+
+ return argv;
+}
extern void list_builtin_commands (void);
extern void display_builtin_command (const char *cmd);
extern void free_strings (char **argv);
-extern void print_strings (char **argv);
+extern void print_strings (char * const * const argv);
extern int launch (guestfs_h *);
extern int is_true (const char *str);
+extern char **parse_string_list (const char *str);
/* in cmds.c (auto-generated) */
extern void list_commands (void);
as end of string). For those you need to use the C<read_file>
function which has a more complex interface.
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=head2 chmod
chmod mode path
C<value> can be NULL.
+=head2 exists
+
+ exists path
+
+This returns C<true> if and only if there is a file, directory
+(or anything) with the given C<path> name.
+
+See also C<is_file>, C<is_dir>, C<stat>.
+
=head2 get-autosync
get-autosync
This returns the verbose messages flag.
+=head2 is-dir
+
+ is-dir path
+
+This returns C<true> if and only if there is a directory
+with the given C<path> name. Note that it returns false for
+other objects like files.
+
+See also C<stat>.
+
+=head2 is-file
+
+ is-file path
+
+This returns C<true> if and only if there is a file
+with the given C<path> name. Note that it returns false for
+other objects like directories.
+
+See also C<stat>.
+
=head2 kill-subprocess
kill-subprocess
This command is mostly useful for interactive sessions. Programs
should probably use C<readdir> instead.
+=head2 lvcreate
+
+ lvcreate logvol volgroup mbytes
+
+This creates an LVM volume group called C<logvol>
+on the volume group C<volgroup>, with C<size> megabytes.
+
+=head2 lvm-remove-all
+
+ lvm-remove-all
+
+This command removes all LVM logical volumes, volume groups
+and physical volumes.
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=head2 lvs
lvs
Create a directory named C<path>, creating any parent directories
as necessary. This is like the C<mkdir -p> shell command.
+=head2 mkfs
+
+ mkfs fstype device
+
+This creates a filesystem on C<device> (usually a partition
+of LVM logical volume). The filesystem type is C<fstype>, for
+example C<ext3>.
+
=head2 mount
mount device mountpoint
The filesystem options C<sync> and C<noatime> are set with this
call, in order to improve reliability.
+=head2 mounts
+
+ mounts
+
+This returns the list of currently mounted filesystems. It returns
+the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
+
+Some internal mounts are not shown.
+
+=head2 pvcreate
+
+ pvcreate device
+
+This creates an LVM physical volume on the named C<device>,
+where C<device> should usually be a partition name such
+as C</dev/sda1>.
+
=head2 pvs
pvs
Verbose messages are disabled unless the environment variable
C<LIBGUESTFS_DEBUG> is defined and set to C<1>.
+=head2 sfdisk
+
+ sfdisk device cyls heads sectors lines,...
+
+This is a direct interface to the L<sfdisk(8)> program for creating
+partitions on block devices.
+
+C<device> should be a block device, for example C</dev/sda>.
+
+C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
+and sectors on the device, which are passed directly to sfdisk as
+the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
+of these, then the corresponding parameter is omitted. Usually for
+'large' disks, you can just pass C<0> for these, but for small
+(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
+out the right geometry and you will need to tell it.
+
+C<lines> is a list of lines that we feed to C<sfdisk>. For more
+information refer to the L<sfdisk(8)> manpage.
+
+To create a single partition occupying the whole disk, you would
+pass C<lines> as a single element list, when the single element being
+the string C<,> (comma).
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=head2 sync
sync
update the timestamps on a file, or, if the file does not exist,
to create a new zero-length file.
+=head2 umount | unmount
+
+ umount pathordevice
+
+This unmounts the given filesystem. The filesystem may be
+specified either by its mountpoint (path) or the device which
+contains the filesystem.
+
+=head2 umount-all | unmount-all
+
+ umount-all
+
+This unmounts all mounted filesystems.
+
+Some internal mounts are not unmounted by this call.
+
+=head2 vgcreate
+
+ vgcreate volgroup physvols,...
+
+This creates an LVM volume group called C<volgroup>
+from the non-empty list of physical volumes C<physvols>.
+
=head2 vgs
vgs
List all the volumes groups detected. This is the equivalent
of the L<vgs(8)> command. The "full" version includes all fields.
+=head2 write-file
+
+ write-file path content size
+
+This call creates a file called C<path>. The contents of the
+file is the string C<content> (which can contain any 8 bit data),
+with length C<size>.
+
+As a special case, if C<size> is C<0>
+then the length is calculated using C<strlen> (so in this case
+the content cannot contain embedded ASCII NULs).
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
This function returns 0 on success or -1 on error.
+=head2 guestfs_exists
+
+ int guestfs_exists (guestfs_h *handle,
+ const char *path);
+
+This returns C<true> if and only if there is a file, directory
+(or anything) with the given C<path> name.
+
+See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.
+
+This function returns a C truth value on success or -1 on error.
+
=head2 guestfs_get_autosync
int guestfs_get_autosync (guestfs_h *handle);
This function returns a C truth value on success or -1 on error.
+=head2 guestfs_is_dir
+
+ int guestfs_is_dir (guestfs_h *handle,
+ const char *path);
+
+This returns C<true> if and only if there is a directory
+with the given C<path> name. Note that it returns false for
+other objects like files.
+
+See also C<guestfs_stat>.
+
+This function returns a C truth value on success or -1 on error.
+
+=head2 guestfs_is_file
+
+ int guestfs_is_file (guestfs_h *handle,
+ const char *path);
+
+This returns C<true> if and only if there is a file
+with the given C<path> name. Note that it returns false for
+other objects like directories.
+
+See also C<guestfs_stat>.
+
+This function returns a C truth value on success or -1 on error.
+
=head2 guestfs_kill_subprocess
int guestfs_kill_subprocess (guestfs_h *handle);
(like L<environ(3)>), or NULL if there was an error.
I<The caller must free the strings and the array after use>.
+=head2 guestfs_lvcreate
+
+ int guestfs_lvcreate (guestfs_h *handle,
+ const char *logvol,
+ const char *volgroup,
+ int mbytes);
+
+This creates an LVM volume group called C<logvol>
+on the volume group C<volgroup>, with C<size> megabytes.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_lvm_remove_all
+
+ int guestfs_lvm_remove_all (guestfs_h *handle);
+
+This command removes all LVM logical volumes, volume groups
+and physical volumes.
+
+This function returns 0 on success or -1 on error.
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=head2 guestfs_lvs
char **guestfs_lvs (guestfs_h *handle);
This function returns 0 on success or -1 on error.
+=head2 guestfs_mkfs
+
+ int guestfs_mkfs (guestfs_h *handle,
+ const char *fstype,
+ const char *device);
+
+This creates a filesystem on C<device> (usually a partition
+of LVM logical volume). The filesystem type is C<fstype>, for
+example C<ext3>.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_mount
int guestfs_mount (guestfs_h *handle,
This function returns 0 on success or -1 on error.
+=head2 guestfs_mounts
+
+ char **guestfs_mounts (guestfs_h *handle);
+
+This returns the list of currently mounted filesystems. It returns
+the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
+
+Some internal mounts are not shown.
+
+This function returns a NULL-terminated array of strings
+(like L<environ(3)>), or NULL if there was an error.
+I<The caller must free the strings and the array after use>.
+
+=head2 guestfs_pvcreate
+
+ int guestfs_pvcreate (guestfs_h *handle,
+ const char *device);
+
+This creates an LVM physical volume on the named C<device>,
+where C<device> should usually be a partition name such
+as C</dev/sda1>.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_pvs
char **guestfs_pvs (guestfs_h *handle);
This function returns 0 on success or -1 on error.
+=head2 guestfs_sfdisk
+
+ int guestfs_sfdisk (guestfs_h *handle,
+ const char *device,
+ int cyls,
+ int heads,
+ int sectors,
+ char * const* const lines);
+
+This is a direct interface to the L<sfdisk(8)> program for creating
+partitions on block devices.
+
+C<device> should be a block device, for example C</dev/sda>.
+
+C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
+and sectors on the device, which are passed directly to sfdisk as
+the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
+of these, then the corresponding parameter is omitted. Usually for
+'large' disks, you can just pass C<0> for these, but for small
+(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
+out the right geometry and you will need to tell it.
+
+C<lines> is a list of lines that we feed to C<sfdisk>. For more
+information refer to the L<sfdisk(8)> manpage.
+
+To create a single partition occupying the whole disk, you would
+pass C<lines> as a single element list, when the single element being
+the string C<,> (comma).
+
+This function returns 0 on success or -1 on error.
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=head2 guestfs_sync
int guestfs_sync (guestfs_h *handle);
This function returns 0 on success or -1 on error.
+=head2 guestfs_umount
+
+ int guestfs_umount (guestfs_h *handle,
+ const char *pathordevice);
+
+This unmounts the given filesystem. The filesystem may be
+specified either by its mountpoint (path) or the device which
+contains the filesystem.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_umount_all
+
+ int guestfs_umount_all (guestfs_h *handle);
+
+This unmounts all mounted filesystems.
+
+Some internal mounts are not unmounted by this call.
+
+This function returns 0 on success or -1 on error.
+
+=head2 guestfs_vgcreate
+
+ int guestfs_vgcreate (guestfs_h *handle,
+ const char *volgroup,
+ char * const* const physvols);
+
+This creates an LVM volume group called C<volgroup>
+from the non-empty list of physical volumes C<physvols>.
+
+This function returns 0 on success or -1 on error.
+
=head2 guestfs_vgs
char **guestfs_vgs (guestfs_h *handle);
This function returns 0 on success or -1 on error.
+=head2 guestfs_write_file
+
+ int guestfs_write_file (guestfs_h *handle,
+ const char *path,
+ const char *content,
+ int size);
+
+This call creates a file called C<path>. The contents of the
+file is the string C<content> (which can contain any 8 bit data),
+with length C<size>.
+
+As a special case, if C<size> is C<0>
+then the length is calculated using C<strlen> (so in this case
+the content cannot contain embedded ASCII NULs).
+
+This function returns 0 on success or -1 on error.
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
make INSTALLDIRS=vendor
+%check
+make check
+
+
%install
rm -rf $RPM_BUILD_ROOT
find initramfs -name '*python*' -print0 | xargs -0 rm -rf
# Modules take up nearly half of the image. It's a rough guess that
-# we don't need any drivers (which take up most of the space).
+# we don't need many drivers (which take up most of the space).
find initramfs/lib/modules/*/kernel \
-name '*.ko' \
-a ! -name 'mii.ko' \
-a ! -name '8139cp.ko' \
+ -a ! -name 'ext2.ko' \
+ -a ! -name 'ext4.ko' \
-a -delete
# Pull the kernel out into the current directory. We don't want it in
external mkdir_p : t -> string -> unit = "ocaml_guestfs_mkdir_p"
external chmod : t -> int -> string -> unit = "ocaml_guestfs_chmod"
external chown : t -> int -> int -> string -> unit = "ocaml_guestfs_chown"
+external exists : t -> string -> bool = "ocaml_guestfs_exists"
+external is_file : t -> string -> bool = "ocaml_guestfs_is_file"
+external is_dir : t -> string -> bool = "ocaml_guestfs_is_dir"
+external pvcreate : t -> string -> unit = "ocaml_guestfs_pvcreate"
+external vgcreate : t -> string -> string array -> unit = "ocaml_guestfs_vgcreate"
+external lvcreate : t -> string -> string -> int -> unit = "ocaml_guestfs_lvcreate"
+external mkfs : t -> string -> string -> unit = "ocaml_guestfs_mkfs"
+external sfdisk : t -> string -> int -> int -> int -> string array -> unit = "ocaml_guestfs_sfdisk_byte" "ocaml_guestfs_sfdisk"
+external write_file : t -> string -> string -> int -> unit = "ocaml_guestfs_write_file"
+external umount : t -> string -> unit = "ocaml_guestfs_umount"
+external mounts : t -> string array = "ocaml_guestfs_mounts"
+external umount_all : t -> unit = "ocaml_guestfs_umount_all"
+external lvm_remove_all : t -> unit = "ocaml_guestfs_lvm_remove_all"
val chown : t -> int -> int -> string -> unit
(** change file owner and group *)
+val exists : t -> string -> bool
+(** test if file or directory exists *)
+
+val is_file : t -> string -> bool
+(** test if file exists *)
+
+val is_dir : t -> string -> bool
+(** test if file exists *)
+
+val pvcreate : t -> string -> unit
+(** create an LVM physical volume *)
+
+val vgcreate : t -> string -> string array -> unit
+(** create an LVM volume group *)
+
+val lvcreate : t -> string -> string -> int -> unit
+(** create an LVM volume group *)
+
+val mkfs : t -> string -> string -> unit
+(** make a filesystem *)
+
+val sfdisk : t -> string -> int -> int -> int -> string array -> unit
+(** create partitions on a block device *)
+
+val write_file : t -> string -> string -> int -> unit
+(** Create a file *)
+
+val umount : t -> string -> unit
+(** unmount a filesystem *)
+
+val mounts : t -> string array
+(** show mounted filesystems *)
+
+val umount_all : t -> unit
+(** unmount all filesystems *)
+
+val lvm_remove_all : t -> unit
+(** remove all LVM LVs, VGs and PVs *)
+
CAMLreturn (Val_unit);
}
+
+/* Copy string array value. */
+char **
+ocaml_guestfs_strings_val (value sv)
+{
+ CAMLparam1 (sv);
+ char **r;
+ int i;
+
+ r = malloc (sizeof (char *) * (Wosize_val (sv) + 1));
+ for (i = 0; i < Wosize_val (sv); ++i)
+ r[i] = String_val (Field (sv, i));
+ r[i] = NULL;
+
+ CAMLreturnT (char **, r);
+}
+
+/* Free array of strings. */
+void
+ocaml_guestfs_free_strings (char **argv)
+{
+ /* Don't free the actual strings - they are String_vals on
+ * the OCaml heap.
+ */
+ free (argv);
+}
#define Guestfs_val(v) (*((guestfs_h **)Data_custom_val(v)))
extern void ocaml_guestfs_raise_error (guestfs_h *g, const char *func)
Noreturn;
+extern char **ocaml_guestfs_strings_val (value sv);
+extern void ocaml_guestfs_free_strings (char **r);
#endif /* GUESTFS_OCAML_C_H */
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_guestfs_exists (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("exists: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_exists (g, path);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "exists");
+
+ rv = Val_bool (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_is_file (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("is_file: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_is_file (g, path);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "is_file");
+
+ rv = Val_bool (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_is_dir (value gv, value pathv)
+{
+ CAMLparam2 (gv, pathv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("is_dir: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_is_dir (g, path);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "is_dir");
+
+ rv = Val_bool (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_pvcreate (value gv, value devicev)
+{
+ CAMLparam2 (gv, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("pvcreate: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_pvcreate (g, device);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "pvcreate");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_vgcreate (value gv, value volgroupv, value physvolsv)
+{
+ CAMLparam3 (gv, volgroupv, physvolsv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("vgcreate: used handle after closing it");
+
+ const char *volgroup = String_val (volgroupv);
+ char **physvols = ocaml_guestfs_strings_val (physvolsv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_vgcreate (g, volgroup, physvols);
+ caml_leave_blocking_section ();
+ ocaml_guestfs_free_strings (physvols);
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "vgcreate");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_lvcreate (value gv, value logvolv, value volgroupv, value mbytesv)
+{
+ CAMLparam4 (gv, logvolv, volgroupv, mbytesv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("lvcreate: used handle after closing it");
+
+ const char *logvol = String_val (logvolv);
+ const char *volgroup = String_val (volgroupv);
+ int mbytes = Int_val (mbytesv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_lvcreate (g, logvol, volgroup, mbytes);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "lvcreate");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_mkfs (value gv, value fstypev, value devicev)
+{
+ CAMLparam3 (gv, fstypev, devicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("mkfs: used handle after closing it");
+
+ const char *fstype = String_val (fstypev);
+ const char *device = String_val (devicev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_mkfs (g, fstype, device);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "mkfs");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk (value gv, value devicev, value cylsv, value headsv, value sectorsv, value linesv)
+{
+ CAMLparam5 (gv, devicev, cylsv, headsv, sectorsv);
+ CAMLxparam1 (linesv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("sfdisk: used handle after closing it");
+
+ const char *device = String_val (devicev);
+ int cyls = Int_val (cylsv);
+ int heads = Int_val (headsv);
+ int sectors = Int_val (sectorsv);
+ char **lines = ocaml_guestfs_strings_val (linesv);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_sfdisk (g, device, cyls, heads, sectors, lines);
+ caml_leave_blocking_section ();
+ ocaml_guestfs_free_strings (lines);
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "sfdisk");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_sfdisk_byte (value *argv, int argn)
+{
+ return ocaml_guestfs_sfdisk (argv[0], argv[0], argv[1], argv[2], argv[3], argv[4]);
+}
+
+CAMLprim value
+ocaml_guestfs_write_file (value gv, value pathv, value contentv, value sizev)
+{
+ CAMLparam4 (gv, pathv, contentv, sizev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("write_file: used handle after closing it");
+
+ const char *path = String_val (pathv);
+ const char *content = String_val (contentv);
+ int size = Int_val (sizev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_write_file (g, path, content, size);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "write_file");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_umount (value gv, value pathordevicev)
+{
+ CAMLparam2 (gv, pathordevicev);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("umount: used handle after closing it");
+
+ const char *pathordevice = String_val (pathordevicev);
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_umount (g, pathordevice);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "umount");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_mounts (value gv)
+{
+ CAMLparam1 (gv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("mounts: used handle after closing it");
+
+ int i;
+ char **r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_mounts (g);
+ caml_leave_blocking_section ();
+ if (r == NULL)
+ ocaml_guestfs_raise_error (g, "mounts");
+
+ rv = caml_copy_string_array ((const char **) r);
+ for (i = 0; r[i] != NULL; ++i) free (r[i]);
+ free (r);
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_umount_all (value gv)
+{
+ CAMLparam1 (gv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("umount_all: used handle after closing it");
+
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_umount_all (g);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "umount_all");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
+CAMLprim value
+ocaml_guestfs_lvm_remove_all (value gv)
+{
+ CAMLparam1 (gv);
+ CAMLlocal1 (rv);
+
+ guestfs_h *g = Guestfs_val (gv);
+ if (g == NULL)
+ caml_failwith ("lvm_remove_all: used handle after closing it");
+
+ int r;
+
+ caml_enter_blocking_section ();
+ r = guestfs_lvm_remove_all (g);
+ caml_leave_blocking_section ();
+ if (r == -1)
+ ocaml_guestfs_raise_error (g, "lvm_remove_all");
+
+ rv = Val_unit;
+ CAMLreturn (rv);
+}
+
last_error = strdup (msg);
}
+/* http://www.perlmonks.org/?node_id=680842 */
+static char **
+XS_unpack_charPtrPtr (SV *arg) {
+ char **ret;
+ AV *av;
+ I32 i;
+
+ if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV) {
+ croak ("array reference expected");
+ }
+
+ av = (AV *)SvRV (arg);
+ ret = (char **)malloc (av_len (av) + 1 + 1);
+
+ for (i = 0; i <= av_len (av); i++) {
+ SV **elem = av_fetch (av, i, 0);
+
+ if (!elem || !*elem) {
+ croak ("missing element in list");
+ }
+
+ ret[i] = SvPV_nolen (*elem);
+ }
+
+ ret[i + 1] = NULL;
+
+ return ret;
+}
+
MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
guestfs_h *
launch (g)
guestfs_h *g;
PPCODE:
- if (guestfs_launch (g) == -1)
+ if (guestfs_launch (g) == -1) {
croak ("launch: %s", last_error);
+ }
void
wait_ready (g)
guestfs_h *g;
PPCODE:
- if (guestfs_wait_ready (g) == -1)
+ 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)
+ if (guestfs_kill_subprocess (g) == -1) {
croak ("kill_subprocess: %s", last_error);
+ }
void
add_drive (g, filename)
guestfs_h *g;
char *filename;
PPCODE:
- if (guestfs_add_drive (g, filename) == -1)
+ if (guestfs_add_drive (g, filename) == -1) {
croak ("add_drive: %s", last_error);
+ }
void
add_cdrom (g, filename)
guestfs_h *g;
char *filename;
PPCODE:
- if (guestfs_add_cdrom (g, filename) == -1)
+ if (guestfs_add_cdrom (g, filename) == -1) {
croak ("add_cdrom: %s", last_error);
+ }
void
config (g, qemuparam, qemuvalue)
char *qemuparam;
char *qemuvalue;
PPCODE:
- if (guestfs_config (g, qemuparam, qemuvalue) == -1)
+ if (guestfs_config (g, qemuparam, qemuvalue) == -1) {
croak ("config: %s", last_error);
+ }
void
set_path (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_set_path (g, path) == -1)
+ 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)
+ if (path == NULL) {
croak ("get_path: %s", last_error);
+ }
RETVAL = newSVpv (path, 0);
OUTPUT:
RETVAL
guestfs_h *g;
int autosync;
PPCODE:
- if (guestfs_set_autosync (g, autosync) == -1)
+ 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)
+ if (autosync == -1) {
croak ("get_autosync: %s", last_error);
+ }
RETVAL = newSViv (autosync);
OUTPUT:
RETVAL
guestfs_h *g;
int verbose;
PPCODE:
- if (guestfs_set_verbose (g, verbose) == -1)
+ 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)
+ if (verbose == -1) {
croak ("get_verbose: %s", last_error);
+ }
RETVAL = newSViv (verbose);
OUTPUT:
RETVAL
char *device;
char *mountpoint;
PPCODE:
- if (guestfs_mount (g, device, mountpoint) == -1)
+ if (guestfs_mount (g, device, mountpoint) == -1) {
croak ("mount: %s", last_error);
+ }
void
sync (g)
guestfs_h *g;
PPCODE:
- if (guestfs_sync (g) == -1)
+ if (guestfs_sync (g) == -1) {
croak ("sync: %s", last_error);
+ }
void
touch (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_touch (g, path) == -1)
+ if (guestfs_touch (g, path) == -1) {
croak ("touch: %s", last_error);
+ }
SV *
cat (g, path)
char *content;
CODE:
content = guestfs_cat (g, path);
- if (content == NULL)
+ if (content == NULL) {
croak ("cat: %s", last_error);
+ }
RETVAL = newSVpv (content, 0);
free (content);
OUTPUT:
char *listing;
CODE:
listing = guestfs_ll (g, directory);
- if (listing == NULL)
+ if (listing == NULL) {
croak ("ll: %s", last_error);
+ }
RETVAL = newSVpv (listing, 0);
free (listing);
OUTPUT:
int i, n;
PPCODE:
listing = guestfs_ls (g, directory);
- if (listing == NULL)
+ if (listing == NULL) {
croak ("ls: %s", last_error);
+ }
for (n = 0; listing[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
devices = guestfs_list_devices (g);
- if (devices == NULL)
+ if (devices == NULL) {
croak ("list_devices: %s", last_error);
+ }
for (n = 0; devices[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
partitions = guestfs_list_partitions (g);
- if (partitions == NULL)
+ if (partitions == NULL) {
croak ("list_partitions: %s", last_error);
+ }
for (n = 0; partitions[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
physvols = guestfs_pvs (g);
- if (physvols == NULL)
+ if (physvols == NULL) {
croak ("pvs: %s", last_error);
+ }
for (n = 0; physvols[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
volgroups = guestfs_vgs (g);
- if (volgroups == NULL)
+ if (volgroups == NULL) {
croak ("vgs: %s", last_error);
+ }
for (n = 0; volgroups[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
logvols = guestfs_lvs (g);
- if (logvols == NULL)
+ if (logvols == NULL) {
croak ("lvs: %s", last_error);
+ }
for (n = 0; logvols[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
int i, n;
PPCODE:
lines = guestfs_read_lines (g, path);
- if (lines == NULL)
+ if (lines == NULL) {
croak ("read_lines: %s", last_error);
+ }
for (n = 0; lines[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
char *root;
int flags;
PPCODE:
- if (guestfs_aug_init (g, root, flags) == -1)
+ if (guestfs_aug_init (g, root, flags) == -1) {
croak ("aug_init: %s", last_error);
+ }
void
aug_close (g)
guestfs_h *g;
PPCODE:
- if (guestfs_aug_close (g) == -1)
+ if (guestfs_aug_close (g) == -1) {
croak ("aug_close: %s", last_error);
+ }
SV *
aug_defvar (g, name, expr)
int nrnodes;
CODE:
nrnodes = guestfs_aug_defvar (g, name, expr);
- if (nrnodes == -1)
+ if (nrnodes == -1) {
croak ("aug_defvar: %s", last_error);
+ }
RETVAL = newSViv (nrnodes);
OUTPUT:
RETVAL
struct guestfs_int_bool *r;
PPCODE:
r = guestfs_aug_defnode (g, name, expr, val);
- if (r == NULL)
+ if (r == NULL) {
croak ("aug_defnode: %s", last_error);
+ }
EXTEND (SP, 2);
PUSHs (sv_2mortal (newSViv (r->i)));
PUSHs (sv_2mortal (newSViv (r->b)));
char *val;
CODE:
val = guestfs_aug_get (g, path);
- if (val == NULL)
+ if (val == NULL) {
croak ("aug_get: %s", last_error);
+ }
RETVAL = newSVpv (val, 0);
free (val);
OUTPUT:
char *path;
char *val;
PPCODE:
- if (guestfs_aug_set (g, path, val) == -1)
+ if (guestfs_aug_set (g, path, val) == -1) {
croak ("aug_set: %s", last_error);
+ }
void
aug_insert (g, path, label, before)
char *label;
int before;
PPCODE:
- if (guestfs_aug_insert (g, path, label, before) == -1)
+ if (guestfs_aug_insert (g, path, label, before) == -1) {
croak ("aug_insert: %s", last_error);
+ }
SV *
aug_rm (g, path)
int nrnodes;
CODE:
nrnodes = guestfs_aug_rm (g, path);
- if (nrnodes == -1)
+ if (nrnodes == -1) {
croak ("aug_rm: %s", last_error);
+ }
RETVAL = newSViv (nrnodes);
OUTPUT:
RETVAL
char *src;
char *dest;
PPCODE:
- if (guestfs_aug_mv (g, src, dest) == -1)
+ if (guestfs_aug_mv (g, src, dest) == -1) {
croak ("aug_mv: %s", last_error);
+ }
void
aug_match (g, path)
int i, n;
PPCODE:
matches = guestfs_aug_match (g, path);
- if (matches == NULL)
+ if (matches == NULL) {
croak ("aug_match: %s", last_error);
+ }
for (n = 0; matches[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
aug_save (g)
guestfs_h *g;
PPCODE:
- if (guestfs_aug_save (g) == -1)
+ if (guestfs_aug_save (g) == -1) {
croak ("aug_save: %s", last_error);
+ }
void
aug_load (g)
guestfs_h *g;
PPCODE:
- if (guestfs_aug_load (g) == -1)
+ if (guestfs_aug_load (g) == -1) {
croak ("aug_load: %s", last_error);
+ }
void
aug_ls (g, path)
int i, n;
PPCODE:
matches = guestfs_aug_ls (g, path);
- if (matches == NULL)
+ if (matches == NULL) {
croak ("aug_ls: %s", last_error);
+ }
for (n = 0; matches[n] != NULL; ++n) /**/;
EXTEND (SP, n);
for (i = 0; i < n; ++i) {
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_rm (g, path) == -1)
+ if (guestfs_rm (g, path) == -1) {
croak ("rm: %s", last_error);
+ }
void
rmdir (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_rmdir (g, path) == -1)
+ if (guestfs_rmdir (g, path) == -1) {
croak ("rmdir: %s", last_error);
+ }
void
rm_rf (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_rm_rf (g, path) == -1)
+ if (guestfs_rm_rf (g, path) == -1) {
croak ("rm_rf: %s", last_error);
+ }
void
mkdir (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_mkdir (g, path) == -1)
+ if (guestfs_mkdir (g, path) == -1) {
croak ("mkdir: %s", last_error);
+ }
void
mkdir_p (g, path)
guestfs_h *g;
char *path;
PPCODE:
- if (guestfs_mkdir_p (g, path) == -1)
+ if (guestfs_mkdir_p (g, path) == -1) {
croak ("mkdir_p: %s", last_error);
+ }
void
chmod (g, mode, path)
int mode;
char *path;
PPCODE:
- if (guestfs_chmod (g, mode, path) == -1)
+ if (guestfs_chmod (g, mode, path) == -1) {
croak ("chmod: %s", last_error);
+ }
void
chown (g, owner, group, path)
int group;
char *path;
PPCODE:
- if (guestfs_chown (g, owner, group, path) == -1)
+ if (guestfs_chown (g, owner, group, path) == -1) {
croak ("chown: %s", last_error);
+ }
+
+SV *
+exists (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ int existsflag;
+ CODE:
+ existsflag = guestfs_exists (g, path);
+ if (existsflag == -1) {
+ croak ("exists: %s", last_error);
+ }
+ RETVAL = newSViv (existsflag);
+ OUTPUT:
+ RETVAL
+
+SV *
+is_file (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ int fileflag;
+ CODE:
+ fileflag = guestfs_is_file (g, path);
+ if (fileflag == -1) {
+ croak ("is_file: %s", last_error);
+ }
+ RETVAL = newSViv (fileflag);
+ OUTPUT:
+ RETVAL
+
+SV *
+is_dir (g, path)
+ guestfs_h *g;
+ char *path;
+PREINIT:
+ int dirflag;
+ CODE:
+ dirflag = guestfs_is_dir (g, path);
+ if (dirflag == -1) {
+ croak ("is_dir: %s", last_error);
+ }
+ RETVAL = newSViv (dirflag);
+ OUTPUT:
+ RETVAL
+
+void
+pvcreate (g, device)
+ guestfs_h *g;
+ char *device;
+ PPCODE:
+ if (guestfs_pvcreate (g, device) == -1) {
+ croak ("pvcreate: %s", last_error);
+ }
+
+void
+vgcreate (g, volgroup, physvols)
+ guestfs_h *g;
+ char *volgroup;
+ char **physvols;
+ PPCODE:
+ if (guestfs_vgcreate (g, volgroup, physvols) == -1) {
+ free (physvols);
+ croak ("vgcreate: %s", last_error);
+ }
+ free (physvols);
+
+void
+lvcreate (g, logvol, volgroup, mbytes)
+ guestfs_h *g;
+ char *logvol;
+ char *volgroup;
+ int mbytes;
+ PPCODE:
+ if (guestfs_lvcreate (g, logvol, volgroup, mbytes) == -1) {
+ croak ("lvcreate: %s", last_error);
+ }
+
+void
+mkfs (g, fstype, device)
+ guestfs_h *g;
+ char *fstype;
+ char *device;
+ PPCODE:
+ if (guestfs_mkfs (g, fstype, device) == -1) {
+ croak ("mkfs: %s", last_error);
+ }
+
+void
+sfdisk (g, device, cyls, heads, sectors, lines)
+ guestfs_h *g;
+ char *device;
+ int cyls;
+ int heads;
+ int sectors;
+ char **lines;
+ PPCODE:
+ if (guestfs_sfdisk (g, device, cyls, heads, sectors, lines) == -1) {
+ free (lines);
+ croak ("sfdisk: %s", last_error);
+ }
+ free (lines);
+
+void
+write_file (g, path, content, size)
+ guestfs_h *g;
+ char *path;
+ char *content;
+ int size;
+ PPCODE:
+ if (guestfs_write_file (g, path, content, size) == -1) {
+ croak ("write_file: %s", last_error);
+ }
+
+void
+umount (g, pathordevice)
+ guestfs_h *g;
+ char *pathordevice;
+ PPCODE:
+ if (guestfs_umount (g, pathordevice) == -1) {
+ croak ("umount: %s", last_error);
+ }
+
+void
+mounts (g)
+ guestfs_h *g;
+PREINIT:
+ char **devices;
+ int i, n;
+ PPCODE:
+ devices = guestfs_mounts (g);
+ if (devices == NULL) {
+ croak ("mounts: %s", last_error);
+ }
+ for (n = 0; devices[n] != NULL; ++n) /**/;
+ EXTEND (SP, n);
+ for (i = 0; i < n; ++i) {
+ PUSHs (sv_2mortal (newSVpv (devices[i], 0)));
+ free (devices[i]);
+ }
+ free (devices);
+
+void
+umount_all (g)
+ guestfs_h *g;
+ PPCODE:
+ if (guestfs_umount_all (g) == -1) {
+ croak ("umount_all: %s", last_error);
+ }
+
+void
+lvm_remove_all (g)
+ guestfs_h *g;
+ PPCODE:
+ if (guestfs_lvm_remove_all (g) == -1) {
+ croak ("lvm_remove_all: %s", last_error);
+ }
return $self;
}
-=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);
+=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
C<$h-E<gt>aug_init> again before you can use any other
Augeas functions.
-=item ($nrnodes, $created) = $h->aug_defnode (name, expr, val);
+=item ($nrnodes, $created) = $h->aug_defnode ($name, $expr, $val);
Defines a variable C<name> whose value is the result of
evaluating C<expr>.
number of nodes in the nodeset, and a boolean flag
if a node was created.
-=item $nrnodes = $h->aug_defvar (name, expr);
+=item $nrnodes = $h->aug_defvar ($name, $expr);
Defines an Augeas variable C<name> whose value is the result
of evaluating C<expr>. If C<expr> is NULL, then C<name> is
On success this returns the number of nodes in C<expr>, or
C<0> if C<expr> evaluates to something which is not a nodeset.
-=item $val = $h->aug_get (path);
+=item $val = $h->aug_get ($path);
Look up the value associated with C<path>. If C<path>
matches exactly one node, the C<value> is returned.
-=item $h->aug_init (root, flags);
+=item $h->aug_init ($root, $flags);
Create a new Augeas handle for editing configuration files.
If there was any previous Augeas handle associated with this
To find out more about Augeas, see L<http://augeas.net/>.
-=item $h->aug_insert (path, label, before);
+=item $h->aug_insert ($path, $label, $before);
Create a new sibling C<label> for C<path>, inserting it into
the tree before or after C<path> (depending on the boolean
See C<aug_load> in the Augeas documentation for the full gory
details.
-=item @matches = $h->aug_ls (path);
+=item @matches = $h->aug_ls ($path);
This is just a shortcut for listing C<$h-E<gt>aug_match>
C<path/*> and sorting the resulting nodes into alphabetical order.
-=item @matches = $h->aug_match (path);
+=item @matches = $h->aug_match ($path);
Returns a list of paths which match the path expression C<path>.
The returned paths are sufficiently qualified so that they match
exactly one node in the current tree.
-=item $h->aug_mv (src, dest);
+=item $h->aug_mv ($src, $dest);
Move the node C<src> to C<dest>. C<src> must match exactly
one node. C<dest> is overwritten if it exists.
-=item $nrnodes = $h->aug_rm (path);
+=item $nrnodes = $h->aug_rm ($path);
Remove C<path> and all of its children.
The flags which were passed to C<$h-E<gt>aug_init> affect exactly
how files are saved.
-=item $h->aug_set (path, val);
+=item $h->aug_set ($path, $val);
Set the value associated with C<path> to C<value>.
-=item $content = $h->cat (path);
+=item $content = $h->cat ($path);
Return the contents of the file named C<path>.
of somewhere between 2MB and 4MB. To transfer large files you should use
FTP.
-=item $h->chmod (mode, path);
+=item $h->chmod ($mode, $path);
Change the mode (permissions) of C<path> to C<mode>. Only
numeric modes are supported.
-=item $h->chown (owner, group, path);
+=item $h->chown ($owner, $group, $path);
Change the file owner to C<owner> and group to C<group>.
names, you will need to locate and parse the password file
yourself (Augeas support makes this relatively easy).
-=item $h->config (qemuparam, qemuvalue);
+=item $h->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
C<value> can be NULL.
+=item $existsflag = $h->exists ($path);
+
+This returns C<true> if and only if there is a file, directory
+(or anything) with the given C<path> name.
+
+See also C<$h-E<gt>is_file>, C<$h-E<gt>is_dir>, C<$h-E<gt>stat>.
+
=item $autosync = $h->get_autosync ();
Get the autosync flag.
This returns the verbose messages flag.
+=item $dirflag = $h->is_dir ($path);
+
+This returns C<true> if and only if there is a directory
+with the given C<path> name. Note that it returns false for
+other objects like files.
+
+See also C<$h-E<gt>stat>.
+
+=item $fileflag = $h->is_file ($path);
+
+This returns C<true> if and only if there is a file
+with the given C<path> name. Note that it returns false for
+other objects like directories.
+
+See also C<$h-E<gt>stat>.
+
=item $h->kill_subprocess ();
This kills the qemu subprocess. You should never need to call this.
This does not return logical volumes. For that you will need to
call C<$h-E<gt>lvs>.
-=item $listing = $h->ll (directory);
+=item $listing = $h->ll ($directory);
List the files in C<directory> (relative to the root directory,
there is no cwd) in the format of 'ls -la'.
This command is mostly useful for interactive sessions. It
is I<not> intended that you try to parse the output string.
-=item @listing = $h->ls (directory);
+=item @listing = $h->ls ($directory);
List the files in C<directory> (relative to the root directory,
there is no cwd). The '.' and '..' entries are not returned, but
This command is mostly useful for interactive sessions. Programs
should probably use C<$h-E<gt>readdir> instead.
+=item $h->lvcreate ($logvol, $volgroup, $mbytes);
+
+This creates an LVM volume group called C<logvol>
+on the volume group C<volgroup>, with C<size> megabytes.
+
+=item $h->lvm_remove_all ();
+
+This command removes all LVM logical volumes, volume groups
+and physical volumes.
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=item @logvols = $h->lvs ();
List all the logical volumes detected. This is the equivalent
List all the logical volumes detected. This is the equivalent
of the L<lvs(8)> command. The "full" version includes all fields.
-=item $h->mkdir (path);
+=item $h->mkdir ($path);
Create a directory named C<path>.
-=item $h->mkdir_p (path);
+=item $h->mkdir_p ($path);
Create a directory named C<path>, creating any parent directories
as necessary. This is like the C<mkdir -p> shell command.
-=item $h->mount (device, mountpoint);
+=item $h->mkfs ($fstype, $device);
+
+This creates a filesystem on C<device> (usually a partition
+of LVM logical volume). The filesystem type is C<fstype>, for
+example C<ext3>.
+
+=item $h->mount ($device, $mountpoint);
Mount a guest disk at a position in the filesystem. Block devices
are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
The filesystem options C<sync> and C<noatime> are set with this
call, in order to improve reliability.
+=item @devices = $h->mounts ();
+
+This returns the list of currently mounted filesystems. It returns
+the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
+
+Some internal mounts are not shown.
+
+=item $h->pvcreate ($device);
+
+This creates an LVM physical volume on the named C<device>,
+where C<device> should usually be a partition name such
+as C</dev/sda1>.
+
=item @physvols = $h->pvs ();
List all the physical volumes detected. This is the equivalent
List all the physical volumes detected. This is the equivalent
of the L<pvs(8)> command. The "full" version includes all fields.
-=item @lines = $h->read_lines (path);
+=item @lines = $h->read_lines ($path);
Return the contents of the file named C<path>.
as end of line). For those you need to use the C<$h-E<gt>read_file>
function which has a more complex interface.
-=item $h->rm (path);
+=item $h->rm ($path);
Remove the single file C<path>.
-=item $h->rm_rf (path);
+=item $h->rm_rf ($path);
Remove the file or directory C<path>, recursively removing the
contents if its a directory. This is like the C<rm -rf> shell
command.
-=item $h->rmdir (path);
+=item $h->rmdir ($path);
Remove the single directory C<path>.
-=item $h->set_autosync (autosync);
+=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);
+=item $h->set_path ($path);
Set the path that libguestfs searches for kernel and initrd.img.
Setting C<path> to C<NULL> restores the default path.
-=item $h->set_verbose (verbose);
+=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->sfdisk ($device, $cyls, $heads, $sectors, \@lines);
+
+This is a direct interface to the L<sfdisk(8)> program for creating
+partitions on block devices.
+
+C<device> should be a block device, for example C</dev/sda>.
+
+C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
+and sectors on the device, which are passed directly to sfdisk as
+the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
+of these, then the corresponding parameter is omitted. Usually for
+'large' disks, you can just pass C<0> for these, but for small
+(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
+out the right geometry and you will need to tell it.
+
+C<lines> is a list of lines that we feed to C<sfdisk>. For more
+information refer to the L<sfdisk(8)> manpage.
+
+To create a single partition occupying the whole disk, you would
+pass C<lines> as a single element list, when the single element being
+the string C<,> (comma).
+
+B<This command is dangerous. Without careful use you
+can easily destroy all your data>.
+
=item $h->sync ();
This syncs the disk, so that any writes are flushed through to the
You should always call this if you have modified a disk image, before
closing the handle.
-=item $h->touch (path);
+=item $h->touch ($path);
Touch acts like the L<touch(1)> command. It can be used to
update the timestamps on a file, or, if the file does not exist,
to create a new zero-length file.
+=item $h->umount ($pathordevice);
+
+This unmounts the given filesystem. The filesystem may be
+specified either by its mountpoint (path) or the device which
+contains the filesystem.
+
+=item $h->umount_all ();
+
+This unmounts all mounted filesystems.
+
+Some internal mounts are not unmounted by this call.
+
+=item $h->vgcreate ($volgroup, \@physvols);
+
+This creates an LVM volume group called C<volgroup>
+from the non-empty list of physical volumes C<physvols>.
+
=item @volgroups = $h->vgs ();
List all the volumes groups detected. This is the equivalent
You should call this after C<$h-E<gt>launch> to wait for the launch
to complete.
+=item $h->write_file ($path, $content, $size);
+
+This call creates a file called C<path>. The contents of the
+file is the string C<content> (which can contain any 8 bit data),
+with length C<size>.
+
+As a special case, if C<size> is C<0>
+then the length is calculated using C<strlen> (so in this case
+the content cannot contain embedded ASCII NULs).
+
+Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP.
+
=cut
1;
and argt =
| String of string (* const char *name, cannot be NULL *)
| OptString of string (* const char *name, may be NULL *)
+ | StringList of string(* list of strings (each string cannot be NULL) *)
| Bool of string (* boolean *)
| Int of string (* int (smallish ints, signed, <= 31 bits) *)
type flags =
| ProtocolLimitWarning (* display warning about protocol size limits *)
+ | DangerWillRobinson (* flags particularly dangerous commands *)
| 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 *)
+let protocol_limit_warning =
+ "Because of the message protocol, there is a transfer limit
+of somewhere between 2MB and 4MB. To transfer large files you should use
+FTP."
+
+let danger_will_robinson =
+ "B<This command is dangerous. Without careful use you
+can easily destroy all your data>."
+
(* You can supply zero or as many tests as you want per API call.
*
- * Note that the test environment has 3 block devices, of size 10M, 20M
- * and 30M (respectively /dev/sda, /dev/sdb, /dev/sdc). To run the
- * tests in a reasonable amount of time, the virtual machine and
- * block devices are reused between tests. So don't try testing
- * kill_subprocess :-x
+ * Note that the test environment has 3 block devices, of size 500MB,
+ * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc).
+ * Note for partitioning purposes, the 500MB device has 63 cylinders.
+ *
+ * To be able to run the tests in a reasonable amount of time,
+ * the virtual machine and block devices are reused between tests.
+ * So don't try testing kill_subprocess :-x
+ *
+ * Between each test we umount-all and lvm-remove-all.
*
* Don't assume anything about the previous contents of the block
* devices. Use 'Init*' to create some initial scenarios.
*)
-type tests = test list
+type tests = (test_init * test) list
and test =
(* Run the command sequence and just expect nothing to fail. *)
- | TestRun of test_init * seq
+ | TestRun of seq
(* Run the command sequence and expect the output of the final
* command to be the string.
*)
- | TestOutput of test_init * seq * string
+ | TestOutput of seq * string
(* Run the command sequence and expect the output of the final
* command to be the list of strings.
*)
- | TestOutputList of test_init * seq * string list
+ | TestOutputList of seq * string list
(* Run the command sequence and expect the output of the final
* command to be the integer.
*)
- | TestOutputInt of test_init * seq * int
+ | TestOutputInt of seq * int
(* Run the command sequence and expect the output of the final
* command to be a true value (!= 0 or != NULL).
*)
- | TestOutputTrue of test_init * seq
+ | TestOutputTrue of seq
(* Run the command sequence and expect the output of the final
* command to be a false value (== 0 or == NULL, but not an error).
*)
- | TestOutputFalse of test_init * seq
+ | TestOutputFalse of seq
(* Run the command sequence and expect the output of the final
* command to be a list of the given length (but don't care about
* content).
*)
- | TestOutputLength of test_init * seq * int
+ | TestOutputLength of seq * int
(* Run the command sequence and expect the final command (only)
* to fail.
*)
- | TestLastFail of test_init * seq
+ | TestLastFail of seq
(* Some initial scenarios for testing. *)
and test_init =
| InitEmpty
(* /dev/sda:
* /dev/sda1 (is a PV):
- * /dev/VG/LV:
+ * /dev/VG/LV (size 8MB):
* formatted as ext2, empty [except for lost+found], mounted on /
* /dev/sdb and /dev/sdc may have random content.
*)
let daemon_functions = [
("mount", (RErr, [String "device"; String "mountpoint"]), 1, [],
- [TestOutput (
- InitNone,
- [["sfdisk"];
+ [InitNone, TestOutput (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
["mkfs"; "ext2"; "/dev/sda1"];
["mount"; "/dev/sda1"; "/"];
["write_file"; "/new"; "new file contents"; "0"];
call, in order to improve reliability.");
("sync", (RErr, []), 2, [],
- [ TestRun (InitNone, [["sync"]])],
+ [ InitNone, TestRun [["sync"]]],
"sync disks, writes are flushed through to the disk image",
"\
This syncs the disk, so that any writes are flushed through to the
closing the handle.");
("touch", (RErr, [String "path"]), 3, [],
- [TestOutputTrue (
- InitEmpty,
+ [InitEmpty, TestOutputTrue (
[["touch"; "/new"];
["exists"; "/new"]])],
"update file timestamps or create a new file",
to create a new zero-length file.");
("cat", (RString "content", [String "path"]), 4, [ProtocolLimitWarning],
- [TestOutput (
- InitEmpty,
+ [InitEmpty, TestOutput (
[["write_file"; "/new"; "new file contents"; "0"];
["cat"; "/new"]], "new file contents")],
"list the contents of a file",
is I<not> intended that you try to parse the output string.");
("ls", (RStringList "listing", [String "directory"]), 6, [],
- [TestOutputList (
- InitEmpty,
+ [InitEmpty, TestOutputList (
[["touch"; "/new"];
["touch"; "/newer"];
["touch"; "/newest"];
should probably use C<guestfs_readdir> instead.");
("list_devices", (RStringList "devices", []), 7, [],
- [TestOutputList (
- InitNone,
+ [InitNone, TestOutputList (
[["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"])],
"list the block devices",
"\
The full block device names are returned, eg. C</dev/sda>");
("list_partitions", (RStringList "partitions", []), 8, [],
- [TestOutputList (
- InitEmpty,
+ [InitEmpty, TestOutputList (
[["list_partitions"]], ["/dev/sda1"]);
- TestOutputList (
- InitEmpty,
- [["sfdisk"];
+ InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
"list the partitions",
"\
call C<guestfs_lvs>.");
("pvs", (RStringList "physvols", []), 9, [],
- [TestOutputList (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputList (
[["pvs"]], ["/dev/sda1"]);
- TestOutputList (
- InitNone,
- [["sfdisk"];
+ InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
["pvcreate"; "/dev/sda1"];
["pvcreate"; "/dev/sda2"];
["pvcreate"; "/dev/sda3"];
See also C<guestfs_pvs_full>.");
("vgs", (RStringList "volgroups", []), 10, [],
- [TestOutputList (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputList (
[["vgs"]], ["VG"]);
- TestOutputList (
- InitNone,
- [["sfdisk"];
+ InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
["pvcreate"; "/dev/sda1"];
["pvcreate"; "/dev/sda2"];
["pvcreate"; "/dev/sda3"];
See also C<guestfs_vgs_full>.");
("lvs", (RStringList "logvols", []), 11, [],
- [TestOutputList (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputList (
[["lvs"]], ["/dev/VG/LV"]);
- TestOutputList (
- InitNone,
- [["sfdisk"];
+ InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
["pvcreate"; "/dev/sda1"];
["pvcreate"; "/dev/sda2"];
["pvcreate"; "/dev/sda3"];
["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
["vgcreate"; "VG2"; "/dev/sda3"];
- ["lvcreate"; "LV1"; "VG1"; "5000"];
- ["lvcreate"; "LV2"; "VG1"; "5000"];
- ["lvcreate"; "LV3"; "VG2"; "5000"];
- ["lvs"]], ["LV1"; "LV2"; "LV3"])],
+ ["lvcreate"; "LV1"; "VG1"; "50"];
+ ["lvcreate"; "LV2"; "VG1"; "50"];
+ ["lvcreate"; "LV3"; "VG2"; "50"];
+ ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
"list the LVM logical volumes (LVs)",
"\
List all the logical volumes detected. This is the equivalent
See also C<guestfs_lvs_full>.");
("pvs_full", (RPVList "physvols", []), 12, [],
- [TestOutputLength (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputLength (
[["pvs"]], 1)],
"list the LVM physical volumes (PVs)",
"\
of the L<pvs(8)> command. The \"full\" version includes all fields.");
("vgs_full", (RVGList "volgroups", []), 13, [],
- [TestOutputLength (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputLength (
[["pvs"]], 1)],
"list the LVM volume groups (VGs)",
"\
of the L<vgs(8)> command. The \"full\" version includes all fields.");
("lvs_full", (RLVList "logvols", []), 14, [],
- [TestOutputLength (
- InitEmptyLVM,
+ [InitEmptyLVM, TestOutputLength (
[["pvs"]], 1)],
"list the LVM logical volumes (LVs)",
"\
of the L<lvs(8)> command. The \"full\" version includes all fields.");
("read_lines", (RStringList "lines", [String "path"]), 15, [],
- [TestOutputList (
- InitEmpty,
+ [InitEmpty, TestOutputList (
[["write_file"; "/new"; "line1\r\nline2\nline3"; "0"];
["read_lines"; "/new"]], ["line1"; "line2"; "line3"]);
- TestOutputList (
- InitEmpty,
+ InitEmpty, TestOutputList (
[["write_file"; "/new"; ""; "0"];
["read_lines"; "/new"]], [])],
"read file as lines",
C<path/*> and sorting the resulting nodes into alphabetical order.");
("rm", (RErr, [String "path"]), 29, [],
- [TestRun (
- InitEmpty,
+ [InitEmpty, TestRun
[["touch"; "/new"];
- ["rm"; "/new"]]);
- TestLastFail (
- InitEmpty,
- [["rm"; "/new"]]);
- TestLastFail (
- InitEmpty,
+ ["rm"; "/new"]];
+ InitEmpty, TestLastFail
+ [["rm"; "/new"]];
+ InitEmpty, TestLastFail
[["mkdir"; "/new"];
- ["rm"; "/new"]])],
+ ["rm"; "/new"]]],
"remove a file",
"\
Remove the single file C<path>.");
("rmdir", (RErr, [String "path"]), 30, [],
- [TestRun (
- InitEmpty,
+ [InitEmpty, TestRun
[["mkdir"; "/new"];
- ["rmdir"; "/new"]]);
- TestLastFail (
- InitEmpty,
- [["rmdir"; "/new"]]);
- TestLastFail (
- InitEmpty,
+ ["rmdir"; "/new"]];
+ InitEmpty, TestLastFail
+ [["rmdir"; "/new"]];
+ InitEmpty, TestLastFail
[["touch"; "/new"];
- ["rmdir"; "/new"]])],
+ ["rmdir"; "/new"]]],
"remove a directory",
"\
Remove the single directory C<path>.");
("rm_rf", (RErr, [String "path"]), 31, [],
- [TestOutputFalse (
- InitEmpty,
+ [InitEmpty, TestOutputFalse
[["mkdir"; "/new"];
["mkdir"; "/new/foo"];
["touch"; "/new/foo/bar"];
["rm_rf"; "/new"];
- ["exists"; "/new"]])],
+ ["exists"; "/new"]]],
"remove a file or directory recursively",
"\
Remove the file or directory C<path>, recursively removing the
command.");
("mkdir", (RErr, [String "path"]), 32, [],
- [TestOutputTrue (
- InitEmpty,
+ [InitEmpty, TestOutputTrue
[["mkdir"; "/new"];
- ["is_dir"; "/new"]])],
+ ["is_dir"; "/new"]];
+ InitEmpty, TestLastFail
+ [["mkdir"; "/new/foo/bar"]]],
"create a directory",
"\
Create a directory named C<path>.");
("mkdir_p", (RErr, [String "path"]), 33, [],
- [TestOutputTrue (
- InitEmpty,
+ [InitEmpty, TestOutputTrue
[["mkdir_p"; "/new/foo/bar"];
- ["is_dir"; "/new/foo/bar"]]);
- TestOutputTrue (
- InitEmpty,
+ ["is_dir"; "/new/foo/bar"]];
+ InitEmpty, TestOutputTrue
[["mkdir_p"; "/new/foo/bar"];
- ["is_dir"; "/new/foo"]]);
- TestOutputTrue (
- InitEmpty,
+ ["is_dir"; "/new/foo"]];
+ InitEmpty, TestOutputTrue
[["mkdir_p"; "/new/foo/bar"];
- ["is_dir"; "/new"]])],
+ ["is_dir"; "/new"]]],
"create a directory and parents",
"\
Create a directory named C<path>, creating any parent directories
Only numeric uid and gid are supported. If you want to use
names, you will need to locate and parse the password file
yourself (Augeas support makes this relatively easy).");
+
+ ("exists", (RBool "existsflag", [String "path"]), 36, [],
+ [InitEmpty, TestOutputTrue (
+ [["touch"; "/new"];
+ ["exists"; "/new"]]);
+ InitEmpty, TestOutputTrue (
+ [["mkdir"; "/new"];
+ ["exists"; "/new"]])],
+ "test if file or directory exists",
+ "\
+This returns C<true> if and only if there is a file, directory
+(or anything) with the given C<path> name.
+
+See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
+
+ ("is_file", (RBool "fileflag", [String "path"]), 37, [],
+ [InitEmpty, TestOutputTrue (
+ [["touch"; "/new"];
+ ["is_file"; "/new"]]);
+ InitEmpty, TestOutputFalse (
+ [["mkdir"; "/new"];
+ ["is_file"; "/new"]])],
+ "test if file exists",
+ "\
+This returns C<true> if and only if there is a file
+with the given C<path> name. Note that it returns false for
+other objects like directories.
+
+See also C<guestfs_stat>.");
+
+ ("is_dir", (RBool "dirflag", [String "path"]), 38, [],
+ [InitEmpty, TestOutputFalse (
+ [["touch"; "/new"];
+ ["is_dir"; "/new"]]);
+ InitEmpty, TestOutputTrue (
+ [["mkdir"; "/new"];
+ ["is_dir"; "/new"]])],
+ "test if file exists",
+ "\
+This returns C<true> if and only if there is a directory
+with the given C<path> name. Note that it returns false for
+other objects like files.
+
+See also C<guestfs_stat>.");
+
+ ("pvcreate", (RErr, [String "device"]), 39, [],
+ [InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+ ["pvcreate"; "/dev/sda1"];
+ ["pvcreate"; "/dev/sda2"];
+ ["pvcreate"; "/dev/sda3"];
+ ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
+ "create an LVM physical volume",
+ "\
+This creates an LVM physical volume on the named C<device>,
+where C<device> should usually be a partition name such
+as C</dev/sda1>.");
+
+ ("vgcreate", (RErr, [String "volgroup"; StringList "physvols"]), 40, [],
+ [InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+ ["pvcreate"; "/dev/sda1"];
+ ["pvcreate"; "/dev/sda2"];
+ ["pvcreate"; "/dev/sda3"];
+ ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
+ ["vgcreate"; "VG2"; "/dev/sda3"];
+ ["vgs"]], ["VG1"; "VG2"])],
+ "create an LVM volume group",
+ "\
+This creates an LVM volume group called C<volgroup>
+from the non-empty list of physical volumes C<physvols>.");
+
+ ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [],
+ [InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
+ ["pvcreate"; "/dev/sda1"];
+ ["pvcreate"; "/dev/sda2"];
+ ["pvcreate"; "/dev/sda3"];
+ ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
+ ["vgcreate"; "VG2"; "/dev/sda3"];
+ ["lvcreate"; "LV1"; "VG1"; "50"];
+ ["lvcreate"; "LV2"; "VG1"; "50"];
+ ["lvcreate"; "LV3"; "VG2"; "50"];
+ ["lvcreate"; "LV4"; "VG2"; "50"];
+ ["lvcreate"; "LV5"; "VG2"; "50"];
+ ["lvs"]],
+ ["/dev/VG1/LV1"; "/dev/VG1/LV2";
+ "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
+ "create an LVM volume group",
+ "\
+This creates an LVM volume group called C<logvol>
+on the volume group C<volgroup>, with C<size> megabytes.");
+
+ ("mkfs", (RErr, [String "fstype"; String "device"]), 42, [],
+ [InitNone, TestOutput (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["mkfs"; "ext2"; "/dev/sda1"];
+ ["mount"; "/dev/sda1"; "/"];
+ ["write_file"; "/new"; "new file contents"; "0"];
+ ["cat"; "/new"]], "new file contents")],
+ "make a filesystem",
+ "\
+This creates a filesystem on C<device> (usually a partition
+of LVM logical volume). The filesystem type is C<fstype>, for
+example C<ext3>.");
+
+ ("sfdisk", (RErr, [String "device";
+ Int "cyls"; Int "heads"; Int "sectors";
+ StringList "lines"]), 43, [DangerWillRobinson],
+ [],
+ "create partitions on a block device",
+ "\
+This is a direct interface to the L<sfdisk(8)> program for creating
+partitions on block devices.
+
+C<device> should be a block device, for example C</dev/sda>.
+
+C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
+and sectors on the device, which are passed directly to sfdisk as
+the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
+of these, then the corresponding parameter is omitted. Usually for
+'large' disks, you can just pass C<0> for these, but for small
+(floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
+out the right geometry and you will need to tell it.
+
+C<lines> is a list of lines that we feed to C<sfdisk>. For more
+information refer to the L<sfdisk(8)> manpage.
+
+To create a single partition occupying the whole disk, you would
+pass C<lines> as a single element list, when the single element being
+the string C<,> (comma).");
+
+ ("write_file", (RErr, [String "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning],
+ [InitNone, TestOutput (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["mkfs"; "ext2"; "/dev/sda1"];
+ ["mount"; "/dev/sda1"; "/"];
+ ["write_file"; "/new"; "new file contents"; "0"];
+ ["cat"; "/new"]], "new file contents")],
+ "Create a file",
+ "\
+This call creates a file called C<path>. The contents of the
+file is the string C<content> (which can contain any 8 bit data),
+with length C<size>.
+
+As a special case, if C<size> is C<0>
+then the length is calculated using C<strlen> (so in this case
+the content cannot contain embedded ASCII NULs).");
+
+ ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
+ [InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["mkfs"; "ext2"; "/dev/sda1"];
+ ["mount"; "/dev/sda1"; "/"];
+ ["mounts"]], ["/dev/sda1"]);
+ InitNone, TestOutputList (
+ [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["mkfs"; "ext2"; "/dev/sda1"];
+ ["mount"; "/dev/sda1"; "/"];
+ ["umount"; "/"];
+ ["mounts"]], [])],
+ "unmount a filesystem",
+ "\
+This unmounts the given filesystem. The filesystem may be
+specified either by its mountpoint (path) or the device which
+contains the filesystem.");
+
+ ("mounts", (RStringList "devices", []), 46, [],
+ [InitEmpty, TestOutputList (
+ [["mounts"]], ["/dev/sda1"])],
+ "show mounted filesystems",
+ "\
+This returns the list of currently mounted filesystems. It returns
+the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
+
+Some internal mounts are not shown.");
+
+ ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
+ [InitEmpty, TestOutputList (
+ [["umount_all"];
+ ["mounts"]], [])],
+ "unmount all filesystems",
+ "\
+This unmounts all mounted filesystems.
+
+Some internal mounts are not unmounted by this call.");
+
+ ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson],
+ [],
+ "remove all LVM LVs, VGs and PVs",
+ "\
+This command removes all LVM logical volumes, volume groups
+and physical volumes.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
s' ^ s2 ^ replace_str s'' s1 s2
)
+let rec string_split sep str =
+ let len = String.length str in
+ let seplen = String.length sep in
+ let i = find str sep in
+ if i = -1 then [str]
+ else (
+ let s' = String.sub str 0 i in
+ let s'' = String.sub str (i+seplen) (len-i-seplen) in
+ s' :: string_split sep s''
+ )
+
let rec find_map f = function
| [] -> raise Not_found
| x :: xs ->
in
loop 0 xs
-let name_of_argt = function String n | OptString n | Bool n | Int n -> n
+let mapi f xs =
+ let rec loop i = function
+ | [] -> []
+ | x :: xs -> let r = f i x in r :: loop (i+1) xs
+ in
+ loop 0 xs
+
+let name_of_argt = function
+ | String n | OptString n | StringList n | Bool n | Int n -> n
(* Check function names etc. for consistency. *)
let check_functions () =
I<The caller must call C<guestfs_free_lvm_lv_list> after use>.\n\n"
);
if List.mem ProtocolLimitWarning flags then
- 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";
+ pr "%s\n\n" protocol_limit_warning;
+ if List.mem DangerWillRobinson flags then
+ pr "%s\n\n" danger_will_robinson;
) all_functions_sorted
and generate_structs_pod () =
function
| String n -> pr " string %s<>;\n" n
| OptString n -> pr " str *%s;\n" n
+ | StringList n -> pr " str %s<>;\n" n
| Bool n -> pr " bool %s;\n" n
| Int n -> pr " int %s;\n" n
) args;
pr " args.%s = (char *) %s;\n" n n
| OptString n ->
pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
+ | StringList n ->
+ pr " args.%s.%s_val = (char **) %s;\n" n n n;
+ pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
| Bool n ->
pr " args.%s = %s;\n" n n
| Int n ->
function
| String n
| OptString n -> pr " const char *%s;\n" n
+ | StringList n -> pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
) args
function
| String n -> pr " %s = args.%s;\n" n n
| OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
+ | StringList n ->
+ pr " args.%s.%s_val = realloc (args.%s.%s_val, sizeof (char *) * (args.%s.%s_len+1));\n" n n n n n n;
+ pr " args.%s.%s_val[args.%s.%s_len] = NULL;\n" n n n n;
+ pr " %s = args.%s.%s_val;\n" n n n
| Bool n -> pr " %s = args.%s;\n" n n
| Int n -> pr " %s = args.%s;\n" n n
) args;
pr ";\n";
pr " if (r == %s)\n" error_code;
- pr " /* do_%s has already called reply_with_error, so just return */\n" name;
- pr " return;\n";
+ pr " /* do_%s has already called reply_with_error */\n" name;
+ pr " goto done;\n";
pr "\n";
(match fst style with
pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name
);
+ (* Free the args. *)
+ (match snd style with
+ | [] ->
+ pr "done: ;\n";
+ | _ ->
+ pr "done:\n";
+ pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
+ name
+ );
+
pr "}\n\n";
) daemon_functions;
and generate_tests () =
generate_header CStyle GPLv2;
- pr "#include <stdio.h>\n";
- pr "#include <stdlib.h>\n";
- pr "#include <string.h>\n";
- pr "\n";
- pr "#include \"guestfs.h\"\n";
+ pr "\
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include \"guestfs.h\"
+
+static guestfs_h *g;
+static int suppress_error = 0;
+
+static void print_error (guestfs_h *g, void *data, const char *msg)
+{
+ if (!suppress_error)
+ fprintf (stderr, \"%%s\\n\", msg);
+}
+
+static void print_strings (char * const * const argv)
+{
+ int argc;
+
+ for (argc = 0; argv[argc] != NULL; ++argc)
+ printf (\"\\t%%s\\n\", argv[argc]);
+}
+
+";
+
+ let test_names =
+ List.map (
+ fun (name, _, _, _, tests, _, _) ->
+ mapi (generate_one_test name) tests
+ ) all_functions in
+ let test_names = List.concat test_names in
+ let nr_tests = List.length test_names in
+
+ pr "\
+int main (int argc, char *argv[])
+{
+ char c = 0;
+ int failed = 0;
+ const char *srcdir;
+ int fd;
+ char buf[256];
+
+ g = guestfs_create ();
+ if (g == NULL) {
+ printf (\"guestfs_create FAILED\\n\");
+ exit (1);
+ }
+
+ guestfs_set_error_handler (g, print_error, NULL);
+
+ srcdir = getenv (\"srcdir\");
+ if (!srcdir) srcdir = \".\";
+ guestfs_set_path (g, srcdir);
+
+ snprintf (buf, sizeof buf, \"%%s/test1.img\", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, %d, SEEK_SET) == -1) {
+ perror (\"lseek\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror (\"write\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf (\"guestfs_add_drive %%s FAILED\\n\", buf);
+ exit (1);
+ }
+
+ snprintf (buf, sizeof buf, \"%%s/test2.img\", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, %d, SEEK_SET) == -1) {
+ perror (\"lseek\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror (\"write\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf (\"guestfs_add_drive %%s FAILED\\n\", buf);
+ exit (1);
+ }
+
+ snprintf (buf, sizeof buf, \"%%s/test3.img\", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, %d, SEEK_SET) == -1) {
+ perror (\"lseek\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror (\"write\");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf (\"guestfs_add_drive %%s FAILED\\n\", buf);
+ exit (1);
+ }
+
+ if (guestfs_launch (g) == -1) {
+ printf (\"guestfs_launch FAILED\\n\");
+ exit (1);
+ }
+ if (guestfs_wait_ready (g) == -1) {
+ printf (\"guestfs_wait_ready FAILED\\n\");
+ exit (1);
+ }
+
+" (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024);
+
+ iteri (
+ fun i test_name ->
+ pr " printf (\"%3d/%3d %s\\n\");\n" (i+1) nr_tests test_name;
+ pr " if (%s () == -1) {\n" test_name;
+ pr " printf (\"%s FAILED\\n\");\n" test_name;
+ pr " failed++;\n";
+ pr " }\n";
+ ) test_names;
pr "\n";
+ pr " guestfs_close (g);\n";
+ pr " snprintf (buf, sizeof buf, \"%%s/test1.img\", srcdir);\n";
+ pr " unlink (buf);\n";
+ pr " snprintf (buf, sizeof buf, \"%%s/test2.img\", srcdir);\n";
+ pr " unlink (buf);\n";
+ pr " snprintf (buf, sizeof buf, \"%%s/test3.img\", srcdir);\n";
+ pr " unlink (buf);\n";
+ pr "\n";
+ pr " if (failed > 0) {\n";
+ pr " printf (\"***** %%d / %d tests FAILED *****\\n\", failed);\n"
+ nr_tests;
+ pr " exit (1);\n";
+ pr " }\n";
+ pr "\n";
- pr "int main (int argc, char *argv[])\n";
- pr "{\n";
pr " exit (0);\n";
pr "}\n"
+and generate_one_test name i (init, test) =
+ let test_name = sprintf "test_%s_%d" name i in
+
+ pr "static int %s (void)\n" test_name;
+ pr "{\n";
+
+ (match init with
+ | InitNone ->
+ pr " /* InitNone for %s (%d) */\n" name i;
+ List.iter (generate_test_command_call test_name)
+ [["umount_all"];
+ ["lvm_remove_all"]]
+ | InitEmpty ->
+ pr " /* InitEmpty for %s (%d): create ext2 on /dev/sda1 */\n" name i;
+ List.iter (generate_test_command_call test_name)
+ [["umount_all"];
+ ["lvm_remove_all"];
+ ["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["mkfs"; "ext2"; "/dev/sda1"];
+ ["mount"; "/dev/sda1"; "/"]]
+ | InitEmptyLVM ->
+ pr " /* InitEmptyLVM for %s (%d): create ext2 on /dev/VG/LV */\n"
+ name i;
+ List.iter (generate_test_command_call test_name)
+ [["umount_all"];
+ ["lvm_remove_all"];
+ ["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
+ ["pvcreate"; "/dev/sda1"];
+ ["vgcreate"; "VG"; "/dev/sda1"];
+ ["lvcreate"; "LV"; "VG"; "8"];
+ ["mkfs"; "ext2"; "/dev/VG/LV"];
+ ["mount"; "/dev/VG/LV"; "/"]]
+ );
+
+ let get_seq_last = function
+ | [] ->
+ failwithf "%s: you cannot use [] (empty list) when expecting a command"
+ test_name
+ | seq ->
+ let seq = List.rev seq in
+ List.rev (List.tl seq), List.hd seq
+ in
+
+ (match test with
+ | TestRun seq ->
+ pr " /* TestRun for %s (%d) */\n" name i;
+ List.iter (generate_test_command_call test_name) seq
+ | TestOutput (seq, expected) ->
+ pr " /* TestOutput for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ pr " if (strcmp (r, \"%s\") != 0) {\n" (c_quote expected);
+ pr " fprintf (stderr, \"%s: expected \\\"%s\\\" but got \\\"%%s\\\"\\n\", r);\n" test_name (c_quote expected);
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestOutputList (seq, expected) ->
+ pr " /* TestOutputList for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ iteri (
+ fun i str ->
+ pr " if (!r[%d]) {\n" i;
+ pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
+ pr " print_strings (r);\n";
+ pr " return -1;\n";
+ pr " }\n";
+ pr " if (strcmp (r[%d], \"%s\") != 0) {\n" i (c_quote str);
+ pr " fprintf (stderr, \"%s: expected \\\"%s\\\" but got \\\"%%s\\\"\\n\", r[%d]);\n" test_name (c_quote str) i;
+ pr " return -1;\n";
+ pr " }\n"
+ ) expected;
+ pr " if (r[%d] != NULL) {\n" (List.length expected);
+ pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
+ test_name;
+ pr " print_strings (r);\n";
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestOutputInt (seq, expected) ->
+ pr " /* TestOutputInt for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ pr " if (r != %d) {\n" expected;
+ pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\", r);\n"
+ test_name expected;
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestOutputTrue seq ->
+ pr " /* TestOutputTrue for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ pr " if (!r) {\n";
+ pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
+ test_name;
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestOutputFalse seq ->
+ pr " /* TestOutputFalse for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ pr " if (r) {\n";
+ pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
+ test_name;
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestOutputLength (seq, expected) ->
+ pr " /* TestOutputLength for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ let test () =
+ pr " int j;\n";
+ pr " for (j = 0; j < %d; ++j)\n" expected;
+ pr " if (r[j] == NULL) {\n";
+ pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
+ test_name;
+ pr " print_strings (r);\n";
+ pr " return -1;\n";
+ pr " }\n";
+ pr " if (r[j] != NULL) {\n";
+ pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
+ test_name;
+ pr " print_strings (r);\n";
+ pr " return -1;\n";
+ pr " }\n"
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
+ | TestLastFail seq ->
+ pr " /* TestLastFail for %s (%d) */\n" name i;
+ let seq, last = get_seq_last seq in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call test_name ~expect_error:true last
+ );
+
+ pr " return 0;\n";
+ pr "}\n";
+ pr "\n";
+ test_name
+
+(* Generate the code to run a command, leaving the result in 'r'.
+ * If you expect to get an error then you should set expect_error:true.
+ *)
+and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
+ match cmd with
+ | [] -> assert false
+ | name :: args ->
+ (* Look up the command to find out what args/ret it has. *)
+ let style =
+ try
+ let _, style, _, _, _, _, _ =
+ List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
+ style
+ with Not_found ->
+ failwithf "%s: in test, command %s was not found" test_name name in
+
+ if List.length (snd style) <> List.length args then
+ failwithf "%s: in test, wrong number of args given to %s"
+ test_name name;
+
+ pr " {\n";
+
+ List.iter (
+ function
+ | String _, _
+ | OptString _, _
+ | Int _, _
+ | Bool _, _ -> ()
+ | StringList n, arg ->
+ pr " char *%s[] = {\n" n;
+ let strs = string_split " " arg in
+ List.iter (
+ fun str -> pr " \"%s\",\n" (c_quote str)
+ ) strs;
+ pr " NULL\n";
+ pr " };\n";
+ ) (List.combine (snd style) args);
+
+ let error_code =
+ match fst style with
+ | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
+ | RConstString _ -> pr " const char *r;\n"; "NULL"
+ | RString _ -> pr " char *r;\n"; "NULL"
+ | RStringList _ ->
+ pr " char **r;\n";
+ pr " int i;\n";
+ "NULL"
+ | RIntBool _ ->
+ pr " struct guestfs_int_bool *r;\n";
+ "NULL"
+ | RPVList _ ->
+ pr " struct guestfs_lvm_pv_list *r;\n";
+ "NULL"
+ | RVGList _ ->
+ pr " struct guestfs_lvm_vg_list *r;\n";
+ "NULL"
+ | RLVList _ ->
+ pr " struct guestfs_lvm_lv_list *r;\n";
+ "NULL" in
+
+ pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
+ pr " r = guestfs_%s (g" name;
+
+ (* Generate the parameters. *)
+ List.iter (
+ function
+ | String _, arg -> pr ", \"%s\"" (c_quote arg)
+ | OptString _, arg ->
+ if arg = "NULL" then pr ", NULL" else pr ", \"%s\"" (c_quote arg)
+ | StringList n, _ ->
+ pr ", %s" n
+ | Int _, arg ->
+ let i =
+ try int_of_string arg
+ with Failure "int_of_string" ->
+ failwithf "%s: expecting an int, but got '%s'" test_name arg in
+ pr ", %d" i
+ | Bool _, arg ->
+ let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
+ ) (List.combine (snd style) args);
+
+ pr ");\n";
+ if not expect_error then
+ pr " if (r == %s)\n" error_code
+ else
+ pr " if (r != %s)\n" error_code;
+ pr " return -1;\n";
+
+ (* Insert the test code. *)
+ (match test with
+ | None -> ()
+ | Some f -> f ()
+ );
+
+ (match fst style with
+ | RErr | RInt _ | RBool _ | RConstString _ -> ()
+ | RString _ -> pr " free (r);\n"
+ | RStringList _ ->
+ pr " for (i = 0; r[i] != NULL; ++i)\n";
+ pr " free (r[i]);\n";
+ pr " free (r);\n"
+ | RIntBool _ ->
+ pr " guestfs_free_int_bool (r);\n"
+ | RPVList _ ->
+ pr " guestfs_free_lvm_pv_list (r);\n"
+ | RVGList _ ->
+ pr " guestfs_free_lvm_vg_list (r);\n"
+ | RLVList _ ->
+ pr " guestfs_free_lvm_lv_list (r);\n"
+ );
+
+ pr " }\n"
+
+and c_quote str =
+ let str = replace_str str "\r" "\\r" in
+ let str = replace_str str "\n" "\\n" in
+ let str = replace_str str "\t" "\\t" in
+ str
+
(* Generate a lot of different functions for guestfish. *)
and generate_fish_cmds () =
generate_header CStyle GPLv2;
let warnings =
if List.mem ProtocolLimitWarning flags then
- "\n\nBecause 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" ^ protocol_limit_warning)
else "" in
+ (* For DangerWillRobinson commands, we should probably have
+ * guestfish prompt before allowing you to use them (especially
+ * in interactive mode). XXX
+ *)
+ let warnings =
+ warnings ^
+ if List.mem DangerWillRobinson flags then
+ ("\n\n" ^ danger_will_robinson)
+ else "" in
+
let describe_alias =
if name <> alias then
sprintf "\n\nYou can use '%s' as an alias for this command." alias
);
List.iter (
function
- | String n -> pr " const char *%s;\n" n
+ | String n
| OptString n -> pr " const char *%s;\n" n
+ | StringList n -> pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
) (snd style);
| OptString name ->
pr " %s = strcmp (argv[%d], \"\") != 0 ? argv[%d] : NULL;\n"
name i i
+ | StringList name ->
+ pr " %s = parse_string_list (argv[%d]);\n" name i
| Bool name ->
pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
| Int name ->
function
| String n -> pr " %s" n
| OptString n -> pr " %s" n
+ | StringList n -> pr " %s,..." n
| Bool _ -> pr " true|false"
| Int n -> pr " %s" n
) (snd style);
pr "\n";
pr "\n";
- pr "%s\n\n" longdesc
+ pr "%s\n\n" longdesc;
+
+ if List.mem ProtocolLimitWarning flags then
+ pr "%s\n\n" protocol_limit_warning;
+
+ if List.mem DangerWillRobinson flags then
+ pr "%s\n\n" danger_will_robinson
) all_functions_sorted
(* Generate a C function prototype. *)
function
| String n -> next (); pr "const char *%s" n
| OptString n -> next (); pr "const char *%s" n
+ | StringList n -> next (); pr "char * const* const %s" n
| Bool n -> next (); pr "int %s" n
| Int n -> next (); pr "int %s" n
) (snd style);
if !comma then pr ", ";
comma := true;
match arg with
- | String n -> pr "%s" n
- | OptString n -> pr "%s" n
- | Bool n -> pr "%s" n
+ | String n
+ | OptString n
+ | StringList n
+ | Bool n
| Int n -> pr "%s" n
) (snd style);
pr ")"
List.iter (
fun (name, style, _, _, _, _, _) ->
+ let params =
+ "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
+
pr "CAMLprim value\n";
- pr "ocaml_guestfs_%s (value gv" name;
- List.iter (
- fun arg -> pr ", value %sv" (name_of_argt arg)
- ) (snd style);
+ pr "ocaml_guestfs_%s (value %s" name (List.hd params);
+ List.iter (pr ", value %s") (List.tl params);
pr ")\n";
pr "{\n";
- pr " CAMLparam%d (gv" (1 + (List.length (snd style)));
- List.iter (
- fun arg -> pr ", %sv" (name_of_argt arg)
- ) (snd style);
- pr ");\n";
+
+ (match params with
+ | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
+ pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
+ pr " CAMLxparam%d (%s);\n"
+ (List.length rest) (String.concat ", " rest)
+ | ps ->
+ pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
+ );
pr " CAMLlocal1 (rv);\n";
pr "\n";
pr " const char *%s =\n" n;
pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
n n
+ | StringList n ->
+ pr " char **%s = ocaml_guestfs_strings_val (%sv);\n" n n
| Bool n ->
pr " int %s = Bool_val (%sv);\n" n n
| Int n ->
generate_call_args ~handle:"g" style;
pr ";\n";
pr " caml_leave_blocking_section ();\n";
+
+ List.iter (
+ function
+ | StringList n ->
+ pr " ocaml_guestfs_free_strings (%s);\n" n;
+ | String _ | OptString _ | Bool _ | Int _ -> ()
+ ) (snd style);
+
pr " if (r == %s)\n" error_code;
pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
pr "\n";
pr " CAMLreturn (rv);\n";
pr "}\n";
- pr "\n"
+ pr "\n";
+
+ if List.length params > 5 then (
+ pr "CAMLprim value\n";
+ pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
+ pr "{\n";
+ pr " return ocaml_guestfs_%s (argv[0]" name;
+ iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
+ pr ");\n";
+ pr "}\n";
+ pr "\n"
+ )
) all_functions
and generate_ocaml_lvm_structure_decls () =
function
| String _ -> pr "string -> "
| OptString _ -> pr "string option -> "
+ | StringList _ -> pr "string array -> "
| Bool _ -> pr "bool -> "
| Int _ -> pr "int -> "
) (snd style);
| RVGList _ -> pr "lvm_vg array"
| RLVList _ -> pr "lvm_lv array"
);
- if is_external then pr " = \"ocaml_guestfs_%s\"" name;
+ if is_external then (
+ pr " = ";
+ if List.length (snd style) + 1 > 5 then
+ pr "\"ocaml_guestfs_%s_byte\" " name;
+ pr "\"ocaml_guestfs_%s\"" name
+ );
pr "\n"
(* Generate Perl xs code, a sort of crazy variation of C with macros. *)
last_error = strdup (msg);
}
+/* http://www.perlmonks.org/?node_id=680842 */
+static char **
+XS_unpack_charPtrPtr (SV *arg) {
+ char **ret;
+ AV *av;
+ I32 i;
+
+ if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV) {
+ croak (\"array reference expected\");
+ }
+
+ av = (AV *)SvRV (arg);
+ ret = (char **)malloc (av_len (av) + 1 + 1);
+
+ for (i = 0; i <= av_len (av); i++) {
+ SV **elem = av_fetch (av, i, 0);
+
+ if (!elem || !*elem) {
+ croak (\"missing element in list\");
+ }
+
+ ret[i] = SvPV_nolen (*elem);
+ }
+
+ ret[i + 1] = NULL;
+
+ return ret;
+}
+
MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
guestfs_h *
function
| String n -> pr " char *%s;\n" n
| OptString n -> pr " char *%s;\n" n
+ | StringList n -> pr " char **%s;\n" n
| Bool n -> pr " int %s;\n" n
| Int n -> pr " int %s;\n" n
) (snd style);
+
+ let do_cleanups () =
+ List.iter (
+ function
+ | String _
+ | OptString _
+ | Bool _
+ | Int _ -> ()
+ | StringList n -> pr " free (%s);\n" n
+ ) (snd style)
+ in
+
(* Code. *)
(match fst style with
| RErr ->
pr " PPCODE:\n";
pr " if (guestfs_%s " name;
generate_call_args ~handle:"g" style;
- pr " == -1)\n";
- pr " croak (\"%s: %%s\", last_error);\n" name
+ pr " == -1) {\n";
+ do_cleanups ();
+ pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n"
| RInt n
| RBool n ->
pr "PREINIT:\n";
pr " %s = guestfs_%s " n name;
generate_call_args ~handle:"g" style;
pr ";\n";
- pr " if (%s == -1)\n" n;
+ pr " if (%s == -1) {\n" n;
+ do_cleanups ();
pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n";
pr " RETVAL = newSViv (%s);\n" n;
pr " OUTPUT:\n";
pr " RETVAL\n"
pr " %s = guestfs_%s " n name;
generate_call_args ~handle:"g" style;
pr ";\n";
- pr " if (%s == NULL)\n" n;
+ pr " if (%s == NULL) {\n" n;
+ do_cleanups ();
pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n";
pr " RETVAL = newSVpv (%s, 0);\n" n;
pr " OUTPUT:\n";
pr " RETVAL\n"
pr " %s = guestfs_%s " n name;
generate_call_args ~handle:"g" style;
pr ";\n";
- pr " if (%s == NULL)\n" n;
+ pr " if (%s == NULL) {\n" n;
+ do_cleanups ();
pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n";
pr " RETVAL = newSVpv (%s, 0);\n" n;
pr " free (%s);\n" n;
pr " OUTPUT:\n";
pr " %s = guestfs_%s " n name;
generate_call_args ~handle:"g" style;
pr ";\n";
- pr " if (%s == NULL)\n" n;
+ pr " if (%s == NULL) {\n" n;
+ do_cleanups ();
pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n";
pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
pr " EXTEND (SP, n);\n";
pr " for (i = 0; i < n; ++i) {\n";
pr " r = guestfs_%s " name;
generate_call_args ~handle:"g" style;
pr ";\n";
- pr " if (r == NULL)\n";
+ pr " if (r == NULL) {\n";
+ do_cleanups ();
pr " croak (\"%s: %%s\", last_error);\n" name;
+ pr " }\n";
pr " EXTEND (SP, 2);\n";
pr " PUSHs (sv_2mortal (newSViv (r->i)));\n";
pr " PUSHs (sv_2mortal (newSViv (r->b)));\n";
| RLVList n ->
generate_perl_lvm_code "lv" lv_cols name style n;
);
+
+ do_cleanups ();
+
pr "\n"
) all_functions
pr "\n\n";
pr "%s\n\n" longdesc;
if List.mem ProtocolLimitWarning flags then
- 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";
+ pr "%s\n\n" protocol_limit_warning;
+ if List.mem DangerWillRobinson flags then
+ pr "%s\n\n" danger_will_robinson
) all_functions_sorted;
(* End of file. *)
fun arg ->
if !comma then pr ", ";
comma := true;
- pr "%s" (name_of_argt arg)
+ match arg with
+ | String n | OptString n | Bool n | Int n ->
+ pr "$%s" n
+ | StringList n ->
+ pr "\\@%s" n
) (snd style);
pr ");"
return 0;
}
+struct exists_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_exists_ret ret;
+};
+
+static void exists_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct exists_rv *rv = (struct exists_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_exists: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_exists: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_exists_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_exists: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_exists (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_exists_args args;
+ struct exists_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_exists called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_EXISTS,
+ (xdrproc_t) xdr_guestfs_exists_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = exists_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_exists failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_EXISTS, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return rv.ret.existsflag;
+}
+
+struct is_file_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_is_file_ret ret;
+};
+
+static void is_file_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct is_file_rv *rv = (struct is_file_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_is_file: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_is_file: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_is_file_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_is_file: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_is_file (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_is_file_args args;
+ struct is_file_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_is_file called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_IS_FILE,
+ (xdrproc_t) xdr_guestfs_is_file_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = is_file_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_is_file failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_IS_FILE, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return rv.ret.fileflag;
+}
+
+struct is_dir_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_is_dir_ret ret;
+};
+
+static void is_dir_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct is_dir_rv *rv = (struct is_dir_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_is_dir: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_is_dir: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_is_dir_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_is_dir: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_is_dir (guestfs_h *g,
+ const char *path)
+{
+ struct guestfs_is_dir_args args;
+ struct is_dir_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_is_dir called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ serial = dispatch (g, GUESTFS_PROC_IS_DIR,
+ (xdrproc_t) xdr_guestfs_is_dir_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = is_dir_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_is_dir failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_IS_DIR, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return rv.ret.dirflag;
+}
+
+struct pvcreate_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void pvcreate_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct pvcreate_rv *rv = (struct pvcreate_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_pvcreate: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_pvcreate: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_pvcreate (guestfs_h *g,
+ const char *device)
+{
+ struct guestfs_pvcreate_args args;
+ struct pvcreate_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_pvcreate called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.device = (char *) device;
+ serial = dispatch (g, GUESTFS_PROC_PVCREATE,
+ (xdrproc_t) xdr_guestfs_pvcreate_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = pvcreate_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_pvcreate failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_PVCREATE, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct vgcreate_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void vgcreate_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct vgcreate_rv *rv = (struct vgcreate_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_vgcreate: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_vgcreate: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_vgcreate (guestfs_h *g,
+ const char *volgroup,
+ char * const* const physvols)
+{
+ struct guestfs_vgcreate_args args;
+ struct vgcreate_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_vgcreate called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.volgroup = (char *) volgroup;
+ args.physvols.physvols_val = (char **) physvols;
+ for (args.physvols.physvols_len = 0; physvols[args.physvols.physvols_len]; args.physvols.physvols_len++) ;
+ serial = dispatch (g, GUESTFS_PROC_VGCREATE,
+ (xdrproc_t) xdr_guestfs_vgcreate_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = vgcreate_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_vgcreate failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_VGCREATE, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct lvcreate_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void lvcreate_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct lvcreate_rv *rv = (struct lvcreate_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_lvcreate: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_lvcreate: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_lvcreate (guestfs_h *g,
+ const char *logvol,
+ const char *volgroup,
+ int mbytes)
+{
+ struct guestfs_lvcreate_args args;
+ struct lvcreate_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_lvcreate called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.logvol = (char *) logvol;
+ args.volgroup = (char *) volgroup;
+ args.mbytes = mbytes;
+ serial = dispatch (g, GUESTFS_PROC_LVCREATE,
+ (xdrproc_t) xdr_guestfs_lvcreate_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = lvcreate_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_lvcreate failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVCREATE, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct mkfs_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void mkfs_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct mkfs_rv *rv = (struct mkfs_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_mkfs: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_mkfs: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_mkfs (guestfs_h *g,
+ const char *fstype,
+ const char *device)
+{
+ struct guestfs_mkfs_args args;
+ struct mkfs_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_mkfs called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.fstype = (char *) fstype;
+ args.device = (char *) device;
+ serial = dispatch (g, GUESTFS_PROC_MKFS,
+ (xdrproc_t) xdr_guestfs_mkfs_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = mkfs_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_mkfs failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MKFS, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct sfdisk_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void sfdisk_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct sfdisk_rv *rv = (struct sfdisk_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_sfdisk: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_sfdisk: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_sfdisk (guestfs_h *g,
+ const char *device,
+ int cyls,
+ int heads,
+ int sectors,
+ char * const* const lines)
+{
+ struct guestfs_sfdisk_args args;
+ struct sfdisk_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_sfdisk called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.device = (char *) device;
+ args.cyls = cyls;
+ args.heads = heads;
+ args.sectors = sectors;
+ args.lines.lines_val = (char **) lines;
+ for (args.lines.lines_len = 0; lines[args.lines.lines_len]; args.lines.lines_len++) ;
+ serial = dispatch (g, GUESTFS_PROC_SFDISK,
+ (xdrproc_t) xdr_guestfs_sfdisk_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = sfdisk_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_sfdisk failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_SFDISK, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct write_file_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void write_file_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct write_file_rv *rv = (struct write_file_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_write_file: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_write_file: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_write_file (guestfs_h *g,
+ const char *path,
+ const char *content,
+ int size)
+{
+ struct guestfs_write_file_args args;
+ struct write_file_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_write_file called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.path = (char *) path;
+ args.content = (char *) content;
+ args.size = size;
+ serial = dispatch (g, GUESTFS_PROC_WRITE_FILE,
+ (xdrproc_t) xdr_guestfs_write_file_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = write_file_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_write_file failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct umount_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void umount_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct umount_rv *rv = (struct umount_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_umount: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_umount: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_umount (guestfs_h *g,
+ const char *pathordevice)
+{
+ struct guestfs_umount_args args;
+ struct umount_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_umount called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ args.pathordevice = (char *) pathordevice;
+ serial = dispatch (g, GUESTFS_PROC_UMOUNT,
+ (xdrproc_t) xdr_guestfs_umount_args, (char *) &args);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = umount_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_umount failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_UMOUNT, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct mounts_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+ struct guestfs_mounts_ret ret;
+};
+
+static void mounts_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct mounts_rv *rv = (struct mounts_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_mounts: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_mounts: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ if (!xdr_guestfs_mounts_ret (xdr, &rv->ret)) {
+ error (g, "guestfs_mounts: failed to parse reply");
+ return;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+char **guestfs_mounts (guestfs_h *g)
+{
+ struct mounts_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_mounts called from the wrong state, %d != READY",
+ g->state);
+ return NULL;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ serial = dispatch (g, GUESTFS_PROC_MOUNTS, NULL, NULL);
+ if (serial == -1)
+ return NULL;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = mounts_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_mounts failed, see earlier error messages");
+ return NULL;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_MOUNTS, serial) == -1)
+ return NULL;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return NULL;
+ }
+
+ /* caller will free this, but we need to add a NULL entry */
+ rv.ret.devices.devices_val = safe_realloc (g, rv.ret.devices.devices_val,
+ sizeof (char *) * (rv.ret.devices.devices_len + 1));
+ rv.ret.devices.devices_val[rv.ret.devices.devices_len] = NULL;
+ return rv.ret.devices.devices_val;
+}
+
+struct umount_all_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void umount_all_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct umount_all_rv *rv = (struct umount_all_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_umount_all: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_umount_all: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_umount_all (guestfs_h *g)
+{
+ struct umount_all_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_umount_all called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ serial = dispatch (g, GUESTFS_PROC_UMOUNT_ALL, NULL, NULL);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = umount_all_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_umount_all failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct lvm_remove_all_rv {
+ int cb_done; /* flag to indicate callback was called */
+ struct guestfs_message_header hdr;
+ struct guestfs_message_error err;
+};
+
+static void lvm_remove_all_cb (guestfs_h *g, void *data, XDR *xdr)
+{
+ struct lvm_remove_all_rv *rv = (struct lvm_remove_all_rv *) data;
+
+ if (!xdr_guestfs_message_header (xdr, &rv->hdr)) {
+ error (g, "guestfs_lvm_remove_all: failed to parse reply header");
+ return;
+ }
+ if (rv->hdr.status == GUESTFS_STATUS_ERROR) {
+ if (!xdr_guestfs_message_error (xdr, &rv->err)) {
+ error (g, "guestfs_lvm_remove_all: failed to parse reply error");
+ return;
+ }
+ goto done;
+ }
+ done:
+ rv->cb_done = 1;
+ main_loop.main_loop_quit (g);
+}
+
+int guestfs_lvm_remove_all (guestfs_h *g)
+{
+ struct lvm_remove_all_rv rv;
+ int serial;
+
+ if (g->state != READY) {
+ error (g, "guestfs_lvm_remove_all called from the wrong state, %d != READY",
+ g->state);
+ return -1;
+ }
+
+ memset (&rv, 0, sizeof rv);
+
+ serial = dispatch (g, GUESTFS_PROC_LVM_REMOVE_ALL, NULL, NULL);
+ if (serial == -1)
+ return -1;
+
+ rv.cb_done = 0;
+ g->reply_cb_internal = lvm_remove_all_cb;
+ g->reply_cb_internal_data = &rv;
+ main_loop.main_loop_run (g);
+ g->reply_cb_internal = NULL;
+ g->reply_cb_internal_data = NULL;
+ if (!rv.cb_done) {
+ error (g, "guestfs_lvm_remove_all failed, see earlier error messages");
+ return -1;
+ }
+
+ if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1)
+ return -1;
+
+ if (rv.hdr.status == GUESTFS_STATUS_ERROR) {
+ error (g, "%s", rv.err.error);
+ return -1;
+ }
+
+ return 0;
+}
+
extern int guestfs_mkdir_p (guestfs_h *handle, const char *path);
extern int guestfs_chmod (guestfs_h *handle, int mode, const char *path);
extern int guestfs_chown (guestfs_h *handle, int owner, int group, const char *path);
+extern int guestfs_exists (guestfs_h *handle, const char *path);
+extern int guestfs_is_file (guestfs_h *handle, const char *path);
+extern int guestfs_is_dir (guestfs_h *handle, const char *path);
+extern int guestfs_pvcreate (guestfs_h *handle, const char *device);
+extern int guestfs_vgcreate (guestfs_h *handle, const char *volgroup, char * const* const physvols);
+extern int guestfs_lvcreate (guestfs_h *handle, const char *logvol, const char *volgroup, int mbytes);
+extern int guestfs_mkfs (guestfs_h *handle, const char *fstype, const char *device);
+extern int guestfs_sfdisk (guestfs_h *handle, const char *device, int cyls, int heads, int sectors, char * const* const lines);
+extern int guestfs_write_file (guestfs_h *handle, const char *path, const char *content, int size);
+extern int guestfs_umount (guestfs_h *handle, const char *pathordevice);
+extern char **guestfs_mounts (guestfs_h *handle);
+extern int guestfs_umount_all (guestfs_h *handle);
+extern int guestfs_lvm_remove_all (guestfs_h *handle);
}
bool_t
+xdr_guestfs_exists_args (XDR *xdrs, guestfs_exists_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_exists_ret (XDR *xdrs, guestfs_exists_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->existsflag))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_is_file_args (XDR *xdrs, guestfs_is_file_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_is_file_ret (XDR *xdrs, guestfs_is_file_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->fileflag))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_is_dir_args (XDR *xdrs, guestfs_is_dir_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_is_dir_ret (XDR *xdrs, guestfs_is_dir_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->dirflag))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_pvcreate_args (XDR *xdrs, guestfs_pvcreate_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_vgcreate_args (XDR *xdrs, guestfs_vgcreate_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->volgroup, ~0))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->physvols.physvols_val, (u_int *) &objp->physvols.physvols_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_lvcreate_args (XDR *xdrs, guestfs_lvcreate_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->logvol, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->volgroup, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->mbytes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_mkfs_args (XDR *xdrs, guestfs_mkfs_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->fstype, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_sfdisk_args (XDR *xdrs, guestfs_sfdisk_args *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->cyls);
+ IXDR_PUT_LONG(buf, objp->heads);
+ IXDR_PUT_LONG(buf, objp->sectors);
+ }
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+
+ } else {
+ objp->cyls = IXDR_GET_LONG(buf);
+ objp->heads = IXDR_GET_LONG(buf);
+ objp->sectors = IXDR_GET_LONG(buf);
+ }
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_string (xdrs, &objp->device, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->cyls))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->heads))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->sectors))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->lines.lines_val, (u_int *) &objp->lines.lines_len, ~0,
+ sizeof (str), (xdrproc_t) xdr_str))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_write_file_args (XDR *xdrs, guestfs_write_file_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->path, ~0))
+ return FALSE;
+ if (!xdr_string (xdrs, &objp->content, ~0))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->size))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_umount_args (XDR *xdrs, guestfs_umount_args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, &objp->pathordevice, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_guestfs_mounts_ret (XDR *xdrs, guestfs_mounts_ret *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_array (xdrs, (char **)&objp->devices.devices_val, (u_int *) &objp->devices.devices_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;
};
typedef struct guestfs_chown_args guestfs_chown_args;
+struct guestfs_exists_args {
+ char *path;
+};
+typedef struct guestfs_exists_args guestfs_exists_args;
+
+struct guestfs_exists_ret {
+ bool_t existsflag;
+};
+typedef struct guestfs_exists_ret guestfs_exists_ret;
+
+struct guestfs_is_file_args {
+ char *path;
+};
+typedef struct guestfs_is_file_args guestfs_is_file_args;
+
+struct guestfs_is_file_ret {
+ bool_t fileflag;
+};
+typedef struct guestfs_is_file_ret guestfs_is_file_ret;
+
+struct guestfs_is_dir_args {
+ char *path;
+};
+typedef struct guestfs_is_dir_args guestfs_is_dir_args;
+
+struct guestfs_is_dir_ret {
+ bool_t dirflag;
+};
+typedef struct guestfs_is_dir_ret guestfs_is_dir_ret;
+
+struct guestfs_pvcreate_args {
+ char *device;
+};
+typedef struct guestfs_pvcreate_args guestfs_pvcreate_args;
+
+struct guestfs_vgcreate_args {
+ char *volgroup;
+ struct {
+ u_int physvols_len;
+ str *physvols_val;
+ } physvols;
+};
+typedef struct guestfs_vgcreate_args guestfs_vgcreate_args;
+
+struct guestfs_lvcreate_args {
+ char *logvol;
+ char *volgroup;
+ int mbytes;
+};
+typedef struct guestfs_lvcreate_args guestfs_lvcreate_args;
+
+struct guestfs_mkfs_args {
+ char *fstype;
+ char *device;
+};
+typedef struct guestfs_mkfs_args guestfs_mkfs_args;
+
+struct guestfs_sfdisk_args {
+ char *device;
+ int cyls;
+ int heads;
+ int sectors;
+ struct {
+ u_int lines_len;
+ str *lines_val;
+ } lines;
+};
+typedef struct guestfs_sfdisk_args guestfs_sfdisk_args;
+
+struct guestfs_write_file_args {
+ char *path;
+ char *content;
+ int size;
+};
+typedef struct guestfs_write_file_args guestfs_write_file_args;
+
+struct guestfs_umount_args {
+ char *pathordevice;
+};
+typedef struct guestfs_umount_args guestfs_umount_args;
+
+struct guestfs_mounts_ret {
+ struct {
+ u_int devices_len;
+ str *devices_val;
+ } devices;
+};
+typedef struct guestfs_mounts_ret guestfs_mounts_ret;
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
GUESTFS_PROC_MKDIR_P = 33,
GUESTFS_PROC_CHMOD = 34,
GUESTFS_PROC_CHOWN = 35,
- GUESTFS_PROC_dummy = 35 + 1,
+ GUESTFS_PROC_EXISTS = 36,
+ GUESTFS_PROC_IS_FILE = 37,
+ GUESTFS_PROC_IS_DIR = 38,
+ GUESTFS_PROC_PVCREATE = 39,
+ GUESTFS_PROC_VGCREATE = 40,
+ GUESTFS_PROC_LVCREATE = 41,
+ GUESTFS_PROC_MKFS = 42,
+ GUESTFS_PROC_SFDISK = 43,
+ GUESTFS_PROC_WRITE_FILE = 44,
+ GUESTFS_PROC_UMOUNT = 45,
+ GUESTFS_PROC_MOUNTS = 46,
+ GUESTFS_PROC_UMOUNT_ALL = 47,
+ GUESTFS_PROC_LVM_REMOVE_ALL = 48,
+ GUESTFS_PROC_dummy = 48 + 1,
};
typedef enum guestfs_procedure guestfs_procedure;
#define GUESTFS_MESSAGE_MAX 4194304
extern bool_t xdr_guestfs_mkdir_p_args (XDR *, guestfs_mkdir_p_args*);
extern bool_t xdr_guestfs_chmod_args (XDR *, guestfs_chmod_args*);
extern bool_t xdr_guestfs_chown_args (XDR *, guestfs_chown_args*);
+extern bool_t xdr_guestfs_exists_args (XDR *, guestfs_exists_args*);
+extern bool_t xdr_guestfs_exists_ret (XDR *, guestfs_exists_ret*);
+extern bool_t xdr_guestfs_is_file_args (XDR *, guestfs_is_file_args*);
+extern bool_t xdr_guestfs_is_file_ret (XDR *, guestfs_is_file_ret*);
+extern bool_t xdr_guestfs_is_dir_args (XDR *, guestfs_is_dir_args*);
+extern bool_t xdr_guestfs_is_dir_ret (XDR *, guestfs_is_dir_ret*);
+extern bool_t xdr_guestfs_pvcreate_args (XDR *, guestfs_pvcreate_args*);
+extern bool_t xdr_guestfs_vgcreate_args (XDR *, guestfs_vgcreate_args*);
+extern bool_t xdr_guestfs_lvcreate_args (XDR *, guestfs_lvcreate_args*);
+extern bool_t xdr_guestfs_mkfs_args (XDR *, guestfs_mkfs_args*);
+extern bool_t xdr_guestfs_sfdisk_args (XDR *, guestfs_sfdisk_args*);
+extern bool_t xdr_guestfs_write_file_args (XDR *, guestfs_write_file_args*);
+extern bool_t xdr_guestfs_umount_args (XDR *, guestfs_umount_args*);
+extern bool_t xdr_guestfs_mounts_ret (XDR *, guestfs_mounts_ret*);
extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*);
extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*);
extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*);
extern bool_t xdr_guestfs_mkdir_p_args ();
extern bool_t xdr_guestfs_chmod_args ();
extern bool_t xdr_guestfs_chown_args ();
+extern bool_t xdr_guestfs_exists_args ();
+extern bool_t xdr_guestfs_exists_ret ();
+extern bool_t xdr_guestfs_is_file_args ();
+extern bool_t xdr_guestfs_is_file_ret ();
+extern bool_t xdr_guestfs_is_dir_args ();
+extern bool_t xdr_guestfs_is_dir_ret ();
+extern bool_t xdr_guestfs_pvcreate_args ();
+extern bool_t xdr_guestfs_vgcreate_args ();
+extern bool_t xdr_guestfs_lvcreate_args ();
+extern bool_t xdr_guestfs_mkfs_args ();
+extern bool_t xdr_guestfs_sfdisk_args ();
+extern bool_t xdr_guestfs_write_file_args ();
+extern bool_t xdr_guestfs_umount_args ();
+extern bool_t xdr_guestfs_mounts_ret ();
extern bool_t xdr_guestfs_procedure ();
extern bool_t xdr_guestfs_message_direction ();
extern bool_t xdr_guestfs_message_status ();
string path<>;
};
+struct guestfs_exists_args {
+ string path<>;
+};
+
+struct guestfs_exists_ret {
+ bool existsflag;
+};
+
+struct guestfs_is_file_args {
+ string path<>;
+};
+
+struct guestfs_is_file_ret {
+ bool fileflag;
+};
+
+struct guestfs_is_dir_args {
+ string path<>;
+};
+
+struct guestfs_is_dir_ret {
+ bool dirflag;
+};
+
+struct guestfs_pvcreate_args {
+ string device<>;
+};
+
+struct guestfs_vgcreate_args {
+ string volgroup<>;
+ str physvols<>;
+};
+
+struct guestfs_lvcreate_args {
+ string logvol<>;
+ string volgroup<>;
+ int mbytes;
+};
+
+struct guestfs_mkfs_args {
+ string fstype<>;
+ string device<>;
+};
+
+struct guestfs_sfdisk_args {
+ string device<>;
+ int cyls;
+ int heads;
+ int sectors;
+ str lines<>;
+};
+
+struct guestfs_write_file_args {
+ string path<>;
+ string content<>;
+ int size;
+};
+
+struct guestfs_umount_args {
+ string pathordevice<>;
+};
+
+struct guestfs_mounts_ret {
+ str devices<>;
+};
+
enum guestfs_procedure {
GUESTFS_PROC_MOUNT = 1,
GUESTFS_PROC_SYNC = 2,
GUESTFS_PROC_MKDIR_P = 33,
GUESTFS_PROC_CHMOD = 34,
GUESTFS_PROC_CHOWN = 35,
+ GUESTFS_PROC_EXISTS = 36,
+ GUESTFS_PROC_IS_FILE = 37,
+ GUESTFS_PROC_IS_DIR = 38,
+ GUESTFS_PROC_PVCREATE = 39,
+ GUESTFS_PROC_VGCREATE = 40,
+ GUESTFS_PROC_LVCREATE = 41,
+ GUESTFS_PROC_MKFS = 42,
+ GUESTFS_PROC_SFDISK = 43,
+ GUESTFS_PROC_WRITE_FILE = 44,
+ GUESTFS_PROC_UMOUNT = 45,
+ GUESTFS_PROC_MOUNTS = 46,
+ GUESTFS_PROC_UMOUNT_ALL = 47,
+ GUESTFS_PROC_LVM_REMOVE_ALL = 48,
GUESTFS_PROC_dummy
};
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
#include "guestfs.h"
+static guestfs_h *g;
+static int suppress_error = 0;
+
+static void print_error (guestfs_h *g, void *data, const char *msg)
+{
+ if (!suppress_error)
+ fprintf (stderr, "%s\n", msg);
+}
+
+static void print_strings (char * const * const argv)
+{
+ int argc;
+
+ for (argc = 0; argv[argc] != NULL; ++argc)
+ printf ("\t%s\n", argv[argc]);
+}
+
+static int test_mount_0 (void)
+{
+ /* InitNone for mount (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutput for mount (0) */
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "new file contents", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *r;
+ suppress_error = 0;
+ r = guestfs_cat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (strcmp (r, "new file contents") != 0) {
+ fprintf (stderr, "test_mount_0: expected \"new file contents\" but got \"%s\"\n", r);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_sync_0 (void)
+{
+ /* InitNone for sync (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestRun for sync (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_sync (g);
+ if (r == -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_touch_0 (void)
+{
+ /* InitEmpty for touch (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for touch (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_exists (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_touch_0: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_cat_0 (void)
+{
+ /* InitEmpty for cat (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutput for cat (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "new file contents", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *r;
+ suppress_error = 0;
+ r = guestfs_cat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (strcmp (r, "new file contents") != 0) {
+ fprintf (stderr, "test_cat_0: expected \"new file contents\" but got \"%s\"\n", r);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_ls_0 (void)
+{
+ /* InitEmpty for ls (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for ls (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/newer");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/newest");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_ls (g, "/");
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_ls_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "lost+found") != 0) {
+ fprintf (stderr, "test_ls_0: expected \"lost+found\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_ls_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "new") != 0) {
+ fprintf (stderr, "test_ls_0: expected \"new\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_ls_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "newer") != 0) {
+ fprintf (stderr, "test_ls_0: expected \"newer\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (!r[3]) {
+ fprintf (stderr, "test_ls_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[3], "newest") != 0) {
+ fprintf (stderr, "test_ls_0: expected \"newest\" but got \"%s\"\n", r[3]);
+ return -1;
+ }
+ if (r[4] != NULL) {
+ fprintf (stderr, "test_ls_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_list_devices_0 (void)
+{
+ /* InitNone for list_devices (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for list_devices (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_list_devices (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_list_devices_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda") != 0) {
+ fprintf (stderr, "test_list_devices_0: expected \"/dev/sda\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_list_devices_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/sdb") != 0) {
+ fprintf (stderr, "test_list_devices_0: expected \"/dev/sdb\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_list_devices_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/sdc") != 0) {
+ fprintf (stderr, "test_list_devices_0: expected \"/dev/sdc\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_list_devices_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_list_partitions_0 (void)
+{
+ /* InitEmpty for list_partitions (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for list_partitions (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_list_partitions (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_list_partitions_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_list_partitions_0: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_list_partitions_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_list_partitions_1 (void)
+{
+ /* InitNone for list_partitions (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for list_partitions (1) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_list_partitions (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_list_partitions_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_list_partitions_1: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_list_partitions_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/sda2") != 0) {
+ fprintf (stderr, "test_list_partitions_1: expected \"/dev/sda2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_list_partitions_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/sda3") != 0) {
+ fprintf (stderr, "test_list_partitions_1: expected \"/dev/sda3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_list_partitions_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_pvs_0 (void)
+{
+ /* InitEmptyLVM for pvs (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for pvs (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_pvs_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_pvs_0: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_pvs_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_pvs_1 (void)
+{
+ /* InitNone for pvs (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for pvs (1) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_pvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_pvs_1: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_pvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/sda2") != 0) {
+ fprintf (stderr, "test_pvs_1: expected \"/dev/sda2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_pvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/sda3") != 0) {
+ fprintf (stderr, "test_pvs_1: expected \"/dev/sda3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_pvs_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_vgs_0 (void)
+{
+ /* InitEmptyLVM for vgs (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for vgs (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_vgs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_vgs_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "VG") != 0) {
+ fprintf (stderr, "test_vgs_0: expected \"VG\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_vgs_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_vgs_1 (void)
+{
+ /* InitNone for vgs (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for vgs (1) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ "/dev/sda2",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG1", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda3",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG2", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_vgs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_vgs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "VG1") != 0) {
+ fprintf (stderr, "test_vgs_1: expected \"VG1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_vgs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "VG2") != 0) {
+ fprintf (stderr, "test_vgs_1: expected \"VG2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (r[2] != NULL) {
+ fprintf (stderr, "test_vgs_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_lvs_0 (void)
+{
+ /* InitEmptyLVM for lvs (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for lvs (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_lvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_lvs_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/VG/LV") != 0) {
+ fprintf (stderr, "test_lvs_0: expected \"/dev/VG/LV\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_lvs_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_lvs_1 (void)
+{
+ /* InitNone for lvs (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for lvs (1) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ "/dev/sda2",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG1", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda3",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG2", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV1", "VG1", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV2", "VG1", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV3", "VG2", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_lvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_lvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/VG1/LV1") != 0) {
+ fprintf (stderr, "test_lvs_1: expected \"/dev/VG1/LV1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_lvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/VG1/LV2") != 0) {
+ fprintf (stderr, "test_lvs_1: expected \"/dev/VG1/LV2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_lvs_1: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/VG2/LV3") != 0) {
+ fprintf (stderr, "test_lvs_1: expected \"/dev/VG2/LV3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_lvs_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_pvs_full_0 (void)
+{
+ /* InitEmptyLVM for pvs_full (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputLength for pvs_full (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ int j;
+ for (j = 0; j < 1; ++j)
+ if (r[j] == NULL) {
+ fprintf (stderr, "test_pvs_full_0: short list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ if (r[j] != NULL) {
+ fprintf (stderr, "test_pvs_full_0: long list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_vgs_full_0 (void)
+{
+ /* InitEmptyLVM for vgs_full (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputLength for vgs_full (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ int j;
+ for (j = 0; j < 1; ++j)
+ if (r[j] == NULL) {
+ fprintf (stderr, "test_vgs_full_0: short list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ if (r[j] != NULL) {
+ fprintf (stderr, "test_vgs_full_0: long list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_lvs_full_0 (void)
+{
+ /* InitEmptyLVM for lvs_full (0): create ext2 on /dev/VG/LV */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV", "VG", 8);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/VG/LV");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/VG/LV", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputLength for lvs_full (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ int j;
+ for (j = 0; j < 1; ++j)
+ if (r[j] == NULL) {
+ fprintf (stderr, "test_lvs_full_0: short list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ if (r[j] != NULL) {
+ fprintf (stderr, "test_lvs_full_0: long list returned\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_read_lines_0 (void)
+{
+ /* InitEmpty for read_lines (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for read_lines (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "line1\r\nline2\nline3", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_read_lines (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_read_lines_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "line1") != 0) {
+ fprintf (stderr, "test_read_lines_0: expected \"line1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_read_lines_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "line2") != 0) {
+ fprintf (stderr, "test_read_lines_0: expected \"line2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_read_lines_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "line3") != 0) {
+ fprintf (stderr, "test_read_lines_0: expected \"line3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_read_lines_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_read_lines_1 (void)
+{
+ /* InitEmpty for read_lines (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for read_lines (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_read_lines (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (r[0] != NULL) {
+ fprintf (stderr, "test_read_lines_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_rm_0 (void)
+{
+ /* InitEmpty for rm (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestRun for rm (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_rm (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rm_1 (void)
+{
+ /* InitEmpty for rm (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestLastFail for rm (1) */
+ {
+ int r;
+ suppress_error = 1;
+ r = guestfs_rm (g, "/new");
+ if (r != -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rm_2 (void)
+{
+ /* InitEmpty for rm (2): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestLastFail for rm (2) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 1;
+ r = guestfs_rm (g, "/new");
+ if (r != -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rmdir_0 (void)
+{
+ /* InitEmpty for rmdir (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestRun for rmdir (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_rmdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rmdir_1 (void)
+{
+ /* InitEmpty for rmdir (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestLastFail for rmdir (1) */
+ {
+ int r;
+ suppress_error = 1;
+ r = guestfs_rmdir (g, "/new");
+ if (r != -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rmdir_2 (void)
+{
+ /* InitEmpty for rmdir (2): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestLastFail for rmdir (2) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 1;
+ r = guestfs_rmdir (g, "/new");
+ if (r != -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_rm_rf_0 (void)
+{
+ /* InitEmpty for rm_rf (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputFalse for rm_rf (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new/foo");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new/foo/bar");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_rm_rf (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_exists (g, "/new");
+ if (r == -1)
+ return -1;
+ if (r) {
+ fprintf (stderr, "test_rm_rf_0: expected false, got true\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_mkdir_0 (void)
+{
+ /* InitEmpty for mkdir (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for mkdir (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_mkdir_0: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_mkdir_1 (void)
+{
+ /* InitEmpty for mkdir (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestLastFail for mkdir (1) */
+ {
+ int r;
+ suppress_error = 1;
+ r = guestfs_mkdir (g, "/new/foo/bar");
+ if (r != -1)
+ return -1;
+ }
+ return 0;
+}
+
+static int test_mkdir_p_0 (void)
+{
+ /* InitEmpty for mkdir_p (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for mkdir_p (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir_p (g, "/new/foo/bar");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new/foo/bar");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_mkdir_p_0: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_mkdir_p_1 (void)
+{
+ /* InitEmpty for mkdir_p (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for mkdir_p (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir_p (g, "/new/foo/bar");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new/foo");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_mkdir_p_1: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_mkdir_p_2 (void)
+{
+ /* InitEmpty for mkdir_p (2): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for mkdir_p (2) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir_p (g, "/new/foo/bar");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_mkdir_p_2: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_exists_0 (void)
+{
+ /* InitEmpty for exists (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for exists (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_exists (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_exists_0: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_exists_1 (void)
+{
+ /* InitEmpty for exists (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for exists (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_exists (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_exists_1: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_is_file_0 (void)
+{
+ /* InitEmpty for is_file (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for is_file (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_file (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_is_file_0: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_is_file_1 (void)
+{
+ /* InitEmpty for is_file (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputFalse for is_file (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_file (g, "/new");
+ if (r == -1)
+ return -1;
+ if (r) {
+ fprintf (stderr, "test_is_file_1: expected false, got true\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_is_dir_0 (void)
+{
+ /* InitEmpty for is_dir (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputFalse for is_dir (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_touch (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new");
+ if (r == -1)
+ return -1;
+ if (r) {
+ fprintf (stderr, "test_is_dir_0: expected false, got true\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_is_dir_1 (void)
+{
+ /* InitEmpty for is_dir (1): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputTrue for is_dir (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkdir (g, "/new");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_is_dir (g, "/new");
+ if (r == -1)
+ return -1;
+ if (!r) {
+ fprintf (stderr, "test_is_dir_1: expected true, got false\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int test_pvcreate_0 (void)
+{
+ /* InitNone for pvcreate (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for pvcreate (0) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_pvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_pvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_pvcreate_0: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_pvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/sda2") != 0) {
+ fprintf (stderr, "test_pvcreate_0: expected \"/dev/sda2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_pvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/sda3") != 0) {
+ fprintf (stderr, "test_pvcreate_0: expected \"/dev/sda3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (r[3] != NULL) {
+ fprintf (stderr, "test_pvcreate_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_vgcreate_0 (void)
+{
+ /* InitNone for vgcreate (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for vgcreate (0) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ "/dev/sda2",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG1", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda3",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG2", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_vgs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_vgcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "VG1") != 0) {
+ fprintf (stderr, "test_vgcreate_0: expected \"VG1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_vgcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "VG2") != 0) {
+ fprintf (stderr, "test_vgcreate_0: expected \"VG2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (r[2] != NULL) {
+ fprintf (stderr, "test_vgcreate_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_lvcreate_0 (void)
+{
+ /* InitNone for lvcreate (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for lvcreate (0) */
+ {
+ char *lines[] = {
+ ",10",
+ ",20",
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda2");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_pvcreate (g, "/dev/sda3");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda1",
+ "/dev/sda2",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG1", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *physvols[] = {
+ "/dev/sda3",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_vgcreate (g, "VG2", physvols);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV1", "VG1", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV2", "VG1", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV3", "VG2", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV4", "VG2", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvcreate (g, "LV5", "VG2", 50);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_lvs (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_lvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/VG1/LV1") != 0) {
+ fprintf (stderr, "test_lvcreate_0: expected \"/dev/VG1/LV1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (!r[1]) {
+ fprintf (stderr, "test_lvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[1], "/dev/VG1/LV2") != 0) {
+ fprintf (stderr, "test_lvcreate_0: expected \"/dev/VG1/LV2\" but got \"%s\"\n", r[1]);
+ return -1;
+ }
+ if (!r[2]) {
+ fprintf (stderr, "test_lvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[2], "/dev/VG2/LV3") != 0) {
+ fprintf (stderr, "test_lvcreate_0: expected \"/dev/VG2/LV3\" but got \"%s\"\n", r[2]);
+ return -1;
+ }
+ if (!r[3]) {
+ fprintf (stderr, "test_lvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[3], "/dev/VG2/LV4") != 0) {
+ fprintf (stderr, "test_lvcreate_0: expected \"/dev/VG2/LV4\" but got \"%s\"\n", r[3]);
+ return -1;
+ }
+ if (!r[4]) {
+ fprintf (stderr, "test_lvcreate_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[4], "/dev/VG2/LV5") != 0) {
+ fprintf (stderr, "test_lvcreate_0: expected \"/dev/VG2/LV5\" but got \"%s\"\n", r[4]);
+ return -1;
+ }
+ if (r[5] != NULL) {
+ fprintf (stderr, "test_lvcreate_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_mkfs_0 (void)
+{
+ /* InitNone for mkfs (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutput for mkfs (0) */
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "new file contents", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *r;
+ suppress_error = 0;
+ r = guestfs_cat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (strcmp (r, "new file contents") != 0) {
+ fprintf (stderr, "test_mkfs_0: expected \"new file contents\" but got \"%s\"\n", r);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_write_file_0 (void)
+{
+ /* InitNone for write_file (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutput for write_file (0) */
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_write_file (g, "/new", "new file contents", 0);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *r;
+ suppress_error = 0;
+ r = guestfs_cat (g, "/new");
+ if (r == NULL)
+ return -1;
+ if (strcmp (r, "new file contents") != 0) {
+ fprintf (stderr, "test_write_file_0: expected \"new file contents\" but got \"%s\"\n", r);
+ return -1;
+ }
+ free (r);
+ }
+ return 0;
+}
+
+static int test_umount_0 (void)
+{
+ /* InitNone for umount (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for umount (0) */
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_mounts (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_umount_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_umount_0: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_umount_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_umount_1 (void)
+{
+ /* InitNone for umount (1) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for umount (1) */
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount (g, "/");
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_mounts (g);
+ if (r == NULL)
+ return -1;
+ if (r[0] != NULL) {
+ fprintf (stderr, "test_umount_1: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_mounts_0 (void)
+{
+ /* InitEmpty for mounts (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for mounts (0) */
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_mounts (g);
+ if (r == NULL)
+ return -1;
+ if (!r[0]) {
+ fprintf (stderr, "test_mounts_0: short list returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ if (strcmp (r[0], "/dev/sda1") != 0) {
+ fprintf (stderr, "test_mounts_0: expected \"/dev/sda1\" but got \"%s\"\n", r[0]);
+ return -1;
+ }
+ if (r[1] != NULL) {
+ fprintf (stderr, "test_mounts_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
+static int test_umount_all_0 (void)
+{
+ /* InitEmpty for umount_all (0): create ext2 on /dev/sda1 */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_lvm_remove_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char *lines[] = {
+ ",",
+ NULL
+ };
+ int r;
+ suppress_error = 0;
+ r = guestfs_sfdisk (g, "/dev/sda", 0, 0, 0, lines);
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mkfs (g, "ext2", "/dev/sda1");
+ if (r == -1)
+ return -1;
+ }
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_mount (g, "/dev/sda1", "/");
+ if (r == -1)
+ return -1;
+ }
+ /* TestOutputList for umount_all (0) */
+ {
+ int r;
+ suppress_error = 0;
+ r = guestfs_umount_all (g);
+ if (r == -1)
+ return -1;
+ }
+ {
+ char **r;
+ int i;
+ suppress_error = 0;
+ r = guestfs_mounts (g);
+ if (r == NULL)
+ return -1;
+ if (r[0] != NULL) {
+ fprintf (stderr, "test_umount_all_0: extra elements returned from command\n");
+ print_strings (r);
+ return -1;
+ }
+ for (i = 0; r[i] != NULL; ++i)
+ free (r[i]);
+ free (r);
+ }
+ return 0;
+}
+
int main (int argc, char *argv[])
{
+ char c = 0;
+ int failed = 0;
+ const char *srcdir;
+ int fd;
+ char buf[256];
+
+ g = guestfs_create ();
+ if (g == NULL) {
+ printf ("guestfs_create FAILED\n");
+ exit (1);
+ }
+
+ guestfs_set_error_handler (g, print_error, NULL);
+
+ srcdir = getenv ("srcdir");
+ if (!srcdir) srcdir = ".";
+ guestfs_set_path (g, srcdir);
+
+ snprintf (buf, sizeof buf, "%s/test1.img", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, 524288000, SEEK_SET) == -1) {
+ perror ("lseek");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror ("write");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf ("guestfs_add_drive %s FAILED\n", buf);
+ exit (1);
+ }
+
+ snprintf (buf, sizeof buf, "%s/test2.img", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, 52428800, SEEK_SET) == -1) {
+ perror ("lseek");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror ("write");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf ("guestfs_add_drive %s FAILED\n", buf);
+ exit (1);
+ }
+
+ snprintf (buf, sizeof buf, "%s/test3.img", srcdir);
+ fd = open (buf, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
+ if (fd == -1) {
+ perror (buf);
+ exit (1);
+ }
+ if (lseek (fd, 10485760, SEEK_SET) == -1) {
+ perror ("lseek");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (write (fd, &c, 1) == -1) {
+ perror ("write");
+ close (fd);
+ unlink (buf);
+ exit (1);
+ }
+ if (close (fd) == -1) {
+ perror (buf);
+ unlink (buf);
+ exit (1);
+ }
+ if (guestfs_add_drive (g, buf) == -1) {
+ printf ("guestfs_add_drive %s FAILED\n", buf);
+ exit (1);
+ }
+
+ if (guestfs_launch (g) == -1) {
+ printf ("guestfs_launch FAILED\n");
+ exit (1);
+ }
+ if (guestfs_wait_ready (g) == -1) {
+ printf ("guestfs_wait_ready FAILED\n");
+ exit (1);
+ }
+
+ printf (" 1/ 46 test_mount_0\n");
+ if (test_mount_0 () == -1) {
+ printf ("test_mount_0 FAILED\n");
+ failed++;
+ }
+ printf (" 2/ 46 test_sync_0\n");
+ if (test_sync_0 () == -1) {
+ printf ("test_sync_0 FAILED\n");
+ failed++;
+ }
+ printf (" 3/ 46 test_touch_0\n");
+ if (test_touch_0 () == -1) {
+ printf ("test_touch_0 FAILED\n");
+ failed++;
+ }
+ printf (" 4/ 46 test_cat_0\n");
+ if (test_cat_0 () == -1) {
+ printf ("test_cat_0 FAILED\n");
+ failed++;
+ }
+ printf (" 5/ 46 test_ls_0\n");
+ if (test_ls_0 () == -1) {
+ printf ("test_ls_0 FAILED\n");
+ failed++;
+ }
+ printf (" 6/ 46 test_list_devices_0\n");
+ if (test_list_devices_0 () == -1) {
+ printf ("test_list_devices_0 FAILED\n");
+ failed++;
+ }
+ printf (" 7/ 46 test_list_partitions_0\n");
+ if (test_list_partitions_0 () == -1) {
+ printf ("test_list_partitions_0 FAILED\n");
+ failed++;
+ }
+ printf (" 8/ 46 test_list_partitions_1\n");
+ if (test_list_partitions_1 () == -1) {
+ printf ("test_list_partitions_1 FAILED\n");
+ failed++;
+ }
+ printf (" 9/ 46 test_pvs_0\n");
+ if (test_pvs_0 () == -1) {
+ printf ("test_pvs_0 FAILED\n");
+ failed++;
+ }
+ printf (" 10/ 46 test_pvs_1\n");
+ if (test_pvs_1 () == -1) {
+ printf ("test_pvs_1 FAILED\n");
+ failed++;
+ }
+ printf (" 11/ 46 test_vgs_0\n");
+ if (test_vgs_0 () == -1) {
+ printf ("test_vgs_0 FAILED\n");
+ failed++;
+ }
+ printf (" 12/ 46 test_vgs_1\n");
+ if (test_vgs_1 () == -1) {
+ printf ("test_vgs_1 FAILED\n");
+ failed++;
+ }
+ printf (" 13/ 46 test_lvs_0\n");
+ if (test_lvs_0 () == -1) {
+ printf ("test_lvs_0 FAILED\n");
+ failed++;
+ }
+ printf (" 14/ 46 test_lvs_1\n");
+ if (test_lvs_1 () == -1) {
+ printf ("test_lvs_1 FAILED\n");
+ failed++;
+ }
+ printf (" 15/ 46 test_pvs_full_0\n");
+ if (test_pvs_full_0 () == -1) {
+ printf ("test_pvs_full_0 FAILED\n");
+ failed++;
+ }
+ printf (" 16/ 46 test_vgs_full_0\n");
+ if (test_vgs_full_0 () == -1) {
+ printf ("test_vgs_full_0 FAILED\n");
+ failed++;
+ }
+ printf (" 17/ 46 test_lvs_full_0\n");
+ if (test_lvs_full_0 () == -1) {
+ printf ("test_lvs_full_0 FAILED\n");
+ failed++;
+ }
+ printf (" 18/ 46 test_read_lines_0\n");
+ if (test_read_lines_0 () == -1) {
+ printf ("test_read_lines_0 FAILED\n");
+ failed++;
+ }
+ printf (" 19/ 46 test_read_lines_1\n");
+ if (test_read_lines_1 () == -1) {
+ printf ("test_read_lines_1 FAILED\n");
+ failed++;
+ }
+ printf (" 20/ 46 test_rm_0\n");
+ if (test_rm_0 () == -1) {
+ printf ("test_rm_0 FAILED\n");
+ failed++;
+ }
+ printf (" 21/ 46 test_rm_1\n");
+ if (test_rm_1 () == -1) {
+ printf ("test_rm_1 FAILED\n");
+ failed++;
+ }
+ printf (" 22/ 46 test_rm_2\n");
+ if (test_rm_2 () == -1) {
+ printf ("test_rm_2 FAILED\n");
+ failed++;
+ }
+ printf (" 23/ 46 test_rmdir_0\n");
+ if (test_rmdir_0 () == -1) {
+ printf ("test_rmdir_0 FAILED\n");
+ failed++;
+ }
+ printf (" 24/ 46 test_rmdir_1\n");
+ if (test_rmdir_1 () == -1) {
+ printf ("test_rmdir_1 FAILED\n");
+ failed++;
+ }
+ printf (" 25/ 46 test_rmdir_2\n");
+ if (test_rmdir_2 () == -1) {
+ printf ("test_rmdir_2 FAILED\n");
+ failed++;
+ }
+ printf (" 26/ 46 test_rm_rf_0\n");
+ if (test_rm_rf_0 () == -1) {
+ printf ("test_rm_rf_0 FAILED\n");
+ failed++;
+ }
+ printf (" 27/ 46 test_mkdir_0\n");
+ if (test_mkdir_0 () == -1) {
+ printf ("test_mkdir_0 FAILED\n");
+ failed++;
+ }
+ printf (" 28/ 46 test_mkdir_1\n");
+ if (test_mkdir_1 () == -1) {
+ printf ("test_mkdir_1 FAILED\n");
+ failed++;
+ }
+ printf (" 29/ 46 test_mkdir_p_0\n");
+ if (test_mkdir_p_0 () == -1) {
+ printf ("test_mkdir_p_0 FAILED\n");
+ failed++;
+ }
+ printf (" 30/ 46 test_mkdir_p_1\n");
+ if (test_mkdir_p_1 () == -1) {
+ printf ("test_mkdir_p_1 FAILED\n");
+ failed++;
+ }
+ printf (" 31/ 46 test_mkdir_p_2\n");
+ if (test_mkdir_p_2 () == -1) {
+ printf ("test_mkdir_p_2 FAILED\n");
+ failed++;
+ }
+ printf (" 32/ 46 test_exists_0\n");
+ if (test_exists_0 () == -1) {
+ printf ("test_exists_0 FAILED\n");
+ failed++;
+ }
+ printf (" 33/ 46 test_exists_1\n");
+ if (test_exists_1 () == -1) {
+ printf ("test_exists_1 FAILED\n");
+ failed++;
+ }
+ printf (" 34/ 46 test_is_file_0\n");
+ if (test_is_file_0 () == -1) {
+ printf ("test_is_file_0 FAILED\n");
+ failed++;
+ }
+ printf (" 35/ 46 test_is_file_1\n");
+ if (test_is_file_1 () == -1) {
+ printf ("test_is_file_1 FAILED\n");
+ failed++;
+ }
+ printf (" 36/ 46 test_is_dir_0\n");
+ if (test_is_dir_0 () == -1) {
+ printf ("test_is_dir_0 FAILED\n");
+ failed++;
+ }
+ printf (" 37/ 46 test_is_dir_1\n");
+ if (test_is_dir_1 () == -1) {
+ printf ("test_is_dir_1 FAILED\n");
+ failed++;
+ }
+ printf (" 38/ 46 test_pvcreate_0\n");
+ if (test_pvcreate_0 () == -1) {
+ printf ("test_pvcreate_0 FAILED\n");
+ failed++;
+ }
+ printf (" 39/ 46 test_vgcreate_0\n");
+ if (test_vgcreate_0 () == -1) {
+ printf ("test_vgcreate_0 FAILED\n");
+ failed++;
+ }
+ printf (" 40/ 46 test_lvcreate_0\n");
+ if (test_lvcreate_0 () == -1) {
+ printf ("test_lvcreate_0 FAILED\n");
+ failed++;
+ }
+ printf (" 41/ 46 test_mkfs_0\n");
+ if (test_mkfs_0 () == -1) {
+ printf ("test_mkfs_0 FAILED\n");
+ failed++;
+ }
+ printf (" 42/ 46 test_write_file_0\n");
+ if (test_write_file_0 () == -1) {
+ printf ("test_write_file_0 FAILED\n");
+ failed++;
+ }
+ printf (" 43/ 46 test_umount_0\n");
+ if (test_umount_0 () == -1) {
+ printf ("test_umount_0 FAILED\n");
+ failed++;
+ }
+ printf (" 44/ 46 test_umount_1\n");
+ if (test_umount_1 () == -1) {
+ printf ("test_umount_1 FAILED\n");
+ failed++;
+ }
+ printf (" 45/ 46 test_mounts_0\n");
+ if (test_mounts_0 () == -1) {
+ printf ("test_mounts_0 FAILED\n");
+ failed++;
+ }
+ printf (" 46/ 46 test_umount_all_0\n");
+ if (test_umount_all_0 () == -1) {
+ printf ("test_umount_all_0 FAILED\n");
+ failed++;
+ }
+
+ guestfs_close (g);
+ snprintf (buf, sizeof buf, "%s/test1.img", srcdir);
+ unlink (buf);
+ snprintf (buf, sizeof buf, "%s/test2.img", srcdir);
+ unlink (buf);
+ snprintf (buf, sizeof buf, "%s/test3.img", srcdir);
+ unlink (buf);
+
+ if (failed > 0) {
+ printf ("***** %d / 46 tests FAILED *****\n", failed);
+ exit (1);
+ }
+
exit (0);
}