diff options
author | Richard Jones <rjones@redhat.com> | 2009-04-10 18:25:07 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-04-11 17:04:35 +0100 |
commit | b4d2a01828e5de85e5eee3631f7fe3925a0312ca (patch) | |
tree | 6f77ecceccd53a84afce4cecf0fe199ba7707752 /daemon | |
parent | 99f68f259f92eee884c6c7396f61b9c16e2bf354 (diff) | |
download | libguestfs-b4d2a01828e5de85e5eee3631f7fe3925a0312ca.tar.gz libguestfs-b4d2a01828e5de85e5eee3631f7fe3925a0312ca.tar.xz libguestfs-b4d2a01828e5de85e5eee3631f7fe3925a0312ca.zip |
Added test suite.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/actions.h | 13 | ||||
-rw-r--r-- | daemon/daemon.h | 31 | ||||
-rw-r--r-- | daemon/devsparts.c | 62 | ||||
-rw-r--r-- | daemon/dir.c | 27 | ||||
-rw-r--r-- | daemon/file.c | 74 | ||||
-rw-r--r-- | daemon/guestfsd.c | 88 | ||||
-rw-r--r-- | daemon/lvm.c | 131 | ||||
-rw-r--r-- | daemon/mount.c | 115 | ||||
-rw-r--r-- | daemon/proto.c | 8 | ||||
-rw-r--r-- | daemon/stubs.c | 548 | ||||
-rw-r--r-- | daemon/sync.c | 1 |
11 files changed, 987 insertions, 111 deletions
diff --git a/daemon/actions.h b/daemon/actions.h index 1b35cad1..2a9d3d1d 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -56,3 +56,16 @@ extern int do_mkdir (const char *path); 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); diff --git a/daemon/daemon.h b/daemon/daemon.h index b2396a19..27d86c9b 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -21,6 +21,9 @@ #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> @@ -28,16 +31,18 @@ #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; @@ -75,6 +80,19 @@ extern void reply (xdrproc_t xdrp, char *ret); } \ } 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 @@ -86,4 +104,11 @@ extern void reply (xdrproc_t xdrp, char *ret); #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 */ diff --git a/daemon/devsparts.c b/daemon/devsparts.c index b0d79569..324b8870 100644 --- a/daemon/devsparts.c +++ b/daemon/devsparts.c @@ -131,3 +131,65 @@ do_list_partitions (void) 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; +} diff --git a/daemon/dir.c b/daemon/dir.c index 7892682f..f7064660 100644 --- a/daemon/dir.c +++ b/daemon/dir.c @@ -76,7 +76,7 @@ do_rm_rf (const char *path) 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? */ @@ -165,3 +165,28 @@ do_mkdir_p (const char *path) 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); +} diff --git a/daemon/file.c b/daemon/file.c index 43c875cc..0b8b463c 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -240,3 +240,77 @@ do_chown (int owner, int group, const char *path) 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; +} diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index a243c0be..c701f194 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -170,7 +170,7 @@ main (int argc, char *argv[]) exit (1); } - xwrite (sock, buf, xdr_getpos (&xdr)); + (void) xwrite (sock, buf, xdr_getpos (&xdr)); xdr_destroy (&xdr); @@ -188,7 +188,7 @@ main (int argc, char *argv[]) exit (0); } -void +int xwrite (int sock, const void *buf, size_t len) { int r; @@ -197,14 +197,16 @@ xwrite (int sock, const void *buf, size_t len) 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; @@ -213,15 +215,17 @@ xread (int sock, void *buf, size_t len) 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 @@ -263,7 +267,7 @@ add_string (char ***argv, int *size, int *alloc, const char *str) } int -count_strings (char **argv) +count_strings (char * const* const argv) { int argc; @@ -314,15 +318,52 @@ free_stringslen (char **argv, int len) 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; @@ -335,25 +376,6 @@ command (char **stdoutput, char **stderror, const char *name, ...) } 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]); @@ -362,8 +384,8 @@ command (char **stdoutput, char **stderror, const char *name, ...) close (so_fd[1]); close (se_fd[1]); - execvp (name, argv); - perror (name); + execvp (argv[0], argv); + perror (argv[0]); _exit (1); } @@ -376,7 +398,7 @@ command (char **stdoutput, char **stderror, const char *name, ...) 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) { @@ -392,7 +414,7 @@ command (char **stdoutput, char **stderror, const char *name, ...) 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; @@ -413,7 +435,7 @@ command (char **stdoutput, char **stderror, const char *name, ...) 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; diff --git a/daemon/lvm.c b/daemon/lvm.c index 7f31c84e..55b41f02 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -169,3 +169,134 @@ do_lvs_full (void) { 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; +} diff --git a/daemon/mount.c b/daemon/mount.c index 440ec0de..fd9c8e43 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -74,3 +74,118 @@ do_mount (const char *device, const char *mountpoint) 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; +} diff --git a/daemon/proto.c b/daemon/proto.c index 93d33c2c..42bc6eaa 100644 --- a/daemon/proto.c +++ b/daemon/proto.c @@ -206,8 +206,8 @@ send_error (const char *msg) 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 @@ -247,6 +247,6 @@ reply (xdrproc_t xdrp, char *ret) 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); } diff --git a/daemon/stubs.c b/daemon/stubs.c index 1227fa88..4540ca56 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -51,10 +51,12 @@ static void mount_stub (XDR *xdr_in) 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) @@ -63,10 +65,11 @@ 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) @@ -85,10 +88,12 @@ 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) @@ -107,13 +112,15 @@ 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) @@ -132,13 +139,15 @@ 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) @@ -157,14 +166,16 @@ 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) @@ -173,14 +184,15 @@ 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) @@ -189,14 +201,15 @@ 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) @@ -205,14 +218,15 @@ 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) @@ -221,14 +235,15 @@ 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) @@ -237,14 +252,15 @@ 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) @@ -253,13 +269,14 @@ 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) @@ -268,13 +285,14 @@ 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) @@ -283,13 +301,14 @@ 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) @@ -308,14 +327,16 @@ 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) @@ -336,10 +357,12 @@ 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) @@ -348,10 +371,11 @@ 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) @@ -372,12 +396,14 @@ 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) @@ -400,11 +426,13 @@ 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) @@ -423,13 +451,15 @@ 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) @@ -450,10 +480,12 @@ 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) @@ -476,10 +508,12 @@ 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) @@ -498,12 +532,14 @@ 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) @@ -524,10 +560,12 @@ 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) @@ -546,14 +584,16 @@ 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) @@ -562,10 +602,11 @@ 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) @@ -574,10 +615,11 @@ 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) @@ -596,14 +638,16 @@ 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) @@ -622,10 +666,12 @@ 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) @@ -644,10 +690,12 @@ 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) @@ -666,10 +714,12 @@ 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) @@ -688,10 +738,12 @@ 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) @@ -710,10 +762,12 @@ 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) @@ -734,10 +788,12 @@ 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) @@ -760,10 +816,325 @@ 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) @@ -874,6 +1245,45 @@ 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); } diff --git a/daemon/sync.c b/daemon/sync.c index 9ade8403..70962dff 100644 --- a/daemon/sync.c +++ b/daemon/sync.c @@ -27,6 +27,5 @@ int do_sync () { sync (); - fprintf (stderr, "guestfsd: disk synched\n"); return 0; } |