Richard W.M. Jones
2013-Mar-07 11:44 UTC
[Libguestfs] [PATCH 0/4] Small refactorings of the protocol layer.
As the start of work to add remote support, I'm taking a close look at the protocol layer in the library. These are some small cleanups. Rich.
Richard W.M. Jones
2013-Mar-07 11:44 UTC
[Libguestfs] [PATCH 1/4] launch: appliance: Use socketpair instead of pipe for qemu stdin/stdout.
From: "Richard W.M. Jones" <rjones at redhat.com>
The libvirt backend already uses a Unix socket for the appliance
console, and so for the libvirt backend the fields g->fd[0] == g->fd[1].
Change the appliance backend to use a socketpair, so we need just a
single file descriptor for qemu stdin/stdout (ie. appliance console).
Consequently we can remove the array int fd[2] in the handle and
replace it with a single file descriptor.
---
src/guestfs-internal.h | 2 +-
src/handle.c | 12 ++++--------
src/launch-appliance.c | 49 +++++++++++++++++++------------------------------
src/launch-libvirt.c | 18 ++++--------------
src/launch-unix.c | 7 +++----
src/proto.c | 36 +++++++++++++++++-------------------
6 files changed, 48 insertions(+), 76 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 793549f..4c632e8 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -263,7 +263,7 @@ struct guestfs_h
int unique;
/*** Protocol. ***/
- int fd[2]; /* Stdin/stdout of qemu. */
+ int fd; /* Stdin/stdout of qemu. */
int sock; /* Daemon communications socket. */
int msg_next_serial;
diff --git a/src/handle.c b/src/handle.c
index 0e66d1a..cefe385 100644
--- a/src/handle.c
+++ b/src/handle.c
@@ -91,8 +91,7 @@ guestfs_create_flags (unsigned flags, ...)
g->state = CONFIG;
- g->fd[0] = -1;
- g->fd[1] = -1;
+ g->fd = -1;
g->sock = -1;
guestfs___init_error_handler (g);
@@ -367,14 +366,11 @@ shutdown_backend (guestfs_h *g, int check_for_errors)
}
/* Close sockets. */
- if (g->fd[0] >= 0)
- close (g->fd[0]);
- if (g->fd[1] >= 0)
- close (g->fd[1]);
+ if (g->fd >= 0)
+ close (g->fd);
if (g->sock >= 0)
close (g->sock);
- g->fd[0] = -1;
- g->fd[1] = -1;
+ g->fd = -1;
g->sock = -1;
if (g->attach_ops->shutdown (g, check_for_errors) == -1)
diff --git a/src/launch-appliance.c b/src/launch-appliance.c
index a86a8cc..4016d61 100644
--- a/src/launch-appliance.c
+++ b/src/launch-appliance.c
@@ -167,7 +167,7 @@ static int
launch_appliance (guestfs_h *g, const char *arg)
{
int r;
- int wfd[2], rfd[2];
+ int sv[2];
char guestfsd_sock[256];
struct sockaddr_un addr;
CLEANUP_FREE char *kernel = NULL, *initrd = NULL, *appliance = NULL;
@@ -235,8 +235,8 @@ launch_appliance (guestfs_h *g, const char *arg)
}
if (!g->direct) {
- if (pipe (wfd) == -1 || pipe (rfd) == -1) {
- perrorf (g, "pipe");
+ if (socketpair (AF_LOCAL, SOCK_STREAM, 0, sv) == -1) {
+ perrorf (g, "socketpair");
goto cleanup0;
}
}
@@ -248,10 +248,8 @@ launch_appliance (guestfs_h *g, const char *arg)
if (r == -1) {
perrorf (g, "fork");
if (!g->direct) {
- close (wfd[0]);
- close (wfd[1]);
- close (rfd[0]);
- close (rfd[1]);
+ close (sv[0]);
+ close (sv[1]);
}
goto cleanup0;
}
@@ -484,17 +482,16 @@ launch_appliance (guestfs_h *g, const char *arg)
/* Set up stdin, stdout, stderr. */
close (0);
close (1);
- close (wfd[1]);
- close (rfd[0]);
+ close (sv[0]);
/* Stdin. */
- if (dup (wfd[0]) == -1) {
+ if (dup (sv[1]) == -1) {
dup_failed:
perror ("dup failed");
_exit (EXIT_FAILURE);
}
/* Stdout. */
- if (dup (rfd[1]) == -1)
+ if (dup (sv[1]) == -1)
goto dup_failed;
/* Particularly since qemu 0.15, qemu spews all sorts of debug
@@ -502,11 +499,10 @@ launch_appliance (guestfs_h *g, const char *arg)
* not confuse casual users, so send stderr to the pipe as well.
*/
close (2);
- if (dup (rfd[1]) == -1)
+ if (dup (sv[1]) == -1)
goto dup_failed;
- close (wfd[0]);
- close (rfd[1]);
+ close (sv[1]);
}
/* Dump the command line (after setting up stderr above). */
@@ -600,19 +596,16 @@ launch_appliance (guestfs_h *g, const char *arg)
}
if (!g->direct) {
- /* Close the other ends of the pipe. */
- close (wfd[0]);
- close (rfd[1]);
+ /* Close the other end of the socketpair. */
+ close (sv[1]);
- if (fcntl (wfd[1], F_SETFL, O_NONBLOCK) == -1 ||
- fcntl (rfd[0], F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (sv[0], F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup1;
}
- g->fd[0] = wfd[1]; /* stdin of child */
- g->fd[1] = rfd[0]; /* stdout of child */
- wfd[1] = rfd[0] = -1;
+ g->fd = sv[0]; /* stdin of child */
+ sv[0] = -1;
}
g->state = LAUNCHING;
@@ -680,18 +673,14 @@ launch_appliance (guestfs_h *g, const char *arg)
return 0;
cleanup1:
- if (!g->direct) {
- if (wfd[1] >= 0) close (wfd[1]);
- if (rfd[1] >= 0) close (rfd[0]);
- }
+ if (!g->direct && sv[0] >= 0)
+ close (sv[0]);
if (g->app.pid > 0) kill (g->app.pid, 9);
if (g->app.recoverypid > 0) kill (g->app.recoverypid, 9);
if (g->app.pid > 0) waitpid (g->app.pid, NULL, 0);
if (g->app.recoverypid > 0) waitpid (g->app.recoverypid, NULL, 0);
- if (g->fd[0] >= 0) close (g->fd[0]);
- if (g->fd[1] >= 0) close (g->fd[1]);
- g->fd[0] = -1;
- g->fd[1] = -1;
+ if (g->fd >= 0) close (g->fd);
+ g->fd = -1;
g->app.pid = 0;
g->app.recoverypid = 0;
memset (&g->launch_t, 0, sizeof g->launch_t);
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index 5a69ced..caad5d4 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -399,13 +399,7 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
goto cleanup;
}
console = -1;
- g->fd[0] = r; /* This is the accepted console socket. */
-
- g->fd[1] = dup (g->fd[0]);
- if (g->fd[1] == -1) {
- perrorf (g, "dup");
- goto cleanup;
- }
+ g->fd = r; /* This is the accepted console socket. */
/* Wait for libvirt domain to start and to connect back to us via
* virtio-serial and send the GUESTFS_LAUNCH_FLAG message.
@@ -481,13 +475,9 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
if (console >= 0)
close (console);
- if (g->fd[0] >= 0) {
- close (g->fd[0]);
- g->fd[0] = -1;
- }
- if (g->fd[1] >= 0) {
- close (g->fd[1]);
- g->fd[1] = -1;
+ if (g->fd >= 0) {
+ close (g->fd);
+ g->fd = -1;
}
if (g->sock >= 0) {
close (g->sock);
diff --git a/src/launch-unix.c b/src/launch-unix.c
index 9bd64fa..a7a3ae2 100644
--- a/src/launch-unix.c
+++ b/src/launch-unix.c
@@ -46,11 +46,10 @@ launch_unix (guestfs_h *g, const char *sockpath)
return -1;
}
- /* Set these to nothing so we don't try to read from random file
- * descriptors.
+ /* Set this to nothing so we don't try to read from a random file
+ * descriptor.
*/
- g->fd[0] = -1;
- g->fd[1] = -1;
+ g->fd = -1;
if (g->verbose)
guestfs___print_timestamped_message (g, "connecting to %s",
sockpath);
diff --git a/src/proto.c b/src/proto.c
index 3d00b2b..57cb609 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -161,11 +161,9 @@ child_cleanup (guestfs_h *g)
debug (g, "child_cleanup: %p: child process died", g);
g->attach_ops->shutdown (g, 0);
- if (g->fd[0] >= 0) close (g->fd[0]);
- if (g->fd[1] >= 0) close (g->fd[1]);
+ if (g->fd >= 0) close (g->fd);
close (g->sock);
- g->fd[0] = -1;
- g->fd[1] = -1;
+ g->fd = -1;
g->sock = -1;
memset (&g->launch_t, 0, sizeof g->launch_t);
guestfs___free_drives (g);
@@ -385,12 +383,12 @@ send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
FD_ZERO (&rset);
FD_ZERO (&wset);
- if (g->fd[1] >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd[1], &rset);
+ if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
+ FD_SET (g->fd, &rset);
FD_SET (g->sock, &rset); /* Read socket for cancellation &
EOF. */
FD_SET (g->sock, &wset); /* Write to socket to send the data. */
- int max_fd = MAX (g->sock, g->fd[1]);
+ int max_fd = MAX (g->sock, g->fd);
while (n > 0) {
rset2 = rset;
@@ -403,8 +401,8 @@ send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
return -1;
}
- if (g->fd[1] >= 0 && FD_ISSET (g->fd[1], &rset2)) {
- if (read_log_message_or_eof (g, g->fd[1], 0) == -1)
+ if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
+ if (read_log_message_or_eof (g, g->fd, 0) == -1)
return -1;
}
if (FD_ISSET (g->sock, &rset2)) {
@@ -516,11 +514,11 @@ recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void
**buf_rtn)
FD_ZERO (&rset);
- if (g->fd[1] >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd[1], &rset);
+ if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
+ FD_SET (g->fd, &rset);
FD_SET (g->sock, &rset); /* Read socket for data & EOF. */
- max_fd = MAX (g->sock, g->fd[1]);
+ max_fd = MAX (g->sock, g->fd);
*size_rtn = 0;
*buf_rtn = NULL;
@@ -548,8 +546,8 @@ recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void
**buf_rtn)
return -1;
}
- if (g->fd[1] >= 0 && FD_ISSET (g->fd[1], &rset2)) {
- if (read_log_message_or_eof (g, g->fd[1], 0) == -1) {
+ if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
+ if (read_log_message_or_eof (g, g->fd, 0) == -1) {
free (*buf_rtn);
*buf_rtn = NULL;
return -1;
@@ -728,11 +726,11 @@ guestfs___accept_from_daemon (guestfs_h *g)
FD_ZERO (&rset);
- if (g->fd[1] >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd[1], &rset);
+ if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
+ FD_SET (g->fd, &rset);
FD_SET (g->sock, &rset); /* Read socket for accept. */
- int max_fd = MAX (g->sock, g->fd[1]);
+ int max_fd = MAX (g->sock, g->fd);
int sock = -1;
while (sock == -1) {
@@ -760,8 +758,8 @@ guestfs___accept_from_daemon (guestfs_h *g)
return -1;
}
- if (g->fd[1] >= 0 && FD_ISSET (g->fd[1], &rset2)) {
- if (read_log_message_or_eof (g, g->fd[1], 1) == -1)
+ if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
+ if (read_log_message_or_eof (g, g->fd, 1) == -1)
return -1;
}
if (FD_ISSET (g->sock, &rset2)) {
--
1.8.1.4
Richard W.M. Jones
2013-Mar-07 11:44 UTC
[Libguestfs] [PATCH 2/4] launch: appliance: Set FD_CLOEXEC flag on console socket.
From: "Richard W.M. Jones" <rjones at redhat.com>
The earlier (pipe-based) code never set this flag, but that was a bug,
potentially allowing the file descriptor to be leaked to subprocesses.
Set the FD_CLOEXEC flag, but also ensure it is cleared in the child
process just before qemu is exec'd (otherwise qemu would not have a
console).
---
src/launch-appliance.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/launch-appliance.c b/src/launch-appliance.c
index 4016d61..30c139e 100644
--- a/src/launch-appliance.c
+++ b/src/launch-appliance.c
@@ -33,6 +33,7 @@
#include <pcre.h>
+#include "cloexec.h"
#include "ignore-value.h"
#include "guestfs.h"
@@ -235,7 +236,7 @@ launch_appliance (guestfs_h *g, const char *arg)
}
if (!g->direct) {
- if (socketpair (AF_LOCAL, SOCK_STREAM, 0, sv) == -1) {
+ if (socketpair (AF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC, 0, sv) == -1) {
perrorf (g, "socketpair");
goto cleanup0;
}
@@ -484,6 +485,12 @@ launch_appliance (guestfs_h *g, const char *arg)
close (1);
close (sv[0]);
+ /* We set the FD_CLOEXEC flag on the socket above, but now (in
+ * the child) it's safe to unset this flag so qemu can use the
+ * socket.
+ */
+ set_cloexec_flag (sv[1], 0);
+
/* Stdin. */
if (dup (sv[1]) == -1) {
dup_failed:
--
1.8.1.4
Richard W.M. Jones
2013-Mar-07 11:44 UTC
[Libguestfs] [PATCH 3/4] lib: Rename g->fd to console_sock and g->sock to daemon_sock.
From: "Richard W.M. Jones" <rjones at redhat.com>
This just renames the fields in the handle to more descriptive names.
There is no functional change.
---
src/guestfs-internal.h | 4 +--
src/handle.c | 16 +++++------
src/launch-appliance.c | 30 ++++++++++-----------
src/launch-libvirt.c | 32 +++++++++++-----------
src/launch-unix.c | 14 +++++-----
src/proto.c | 72 +++++++++++++++++++++++++-------------------------
6 files changed, 84 insertions(+), 84 deletions(-)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 4c632e8..c63ea40 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -263,8 +263,8 @@ struct guestfs_h
int unique;
/*** Protocol. ***/
- int fd; /* Stdin/stdout of qemu. */
- int sock; /* Daemon communications socket. */
+ int console_sock; /* Appliance console (for debug info). */
+ int daemon_sock; /* Daemon communications socket. */
int msg_next_serial;
#if HAVE_FUSE
diff --git a/src/handle.c b/src/handle.c
index cefe385..47a2246 100644
--- a/src/handle.c
+++ b/src/handle.c
@@ -91,8 +91,8 @@ guestfs_create_flags (unsigned flags, ...)
g->state = CONFIG;
- g->fd = -1;
- g->sock = -1;
+ g->console_sock = -1;
+ g->daemon_sock = -1;
guestfs___init_error_handler (g);
g->abort_cb = abort;
@@ -366,12 +366,12 @@ shutdown_backend (guestfs_h *g, int check_for_errors)
}
/* Close sockets. */
- if (g->fd >= 0)
- close (g->fd);
- if (g->sock >= 0)
- close (g->sock);
- g->fd = -1;
- g->sock = -1;
+ if (g->console_sock >= 0)
+ close (g->console_sock);
+ if (g->daemon_sock >= 0)
+ close (g->daemon_sock);
+ g->console_sock = -1;
+ g->daemon_sock = -1;
if (g->attach_ops->shutdown (g, check_for_errors) == -1)
ret = -1;
diff --git a/src/launch-appliance.c b/src/launch-appliance.c
index 30c139e..99bc541 100644
--- a/src/launch-appliance.c
+++ b/src/launch-appliance.c
@@ -210,13 +210,13 @@ launch_appliance (guestfs_h *g, const char *arg)
snprintf (guestfsd_sock, sizeof guestfsd_sock, "%s/guestfsd.sock",
g->tmpdir);
unlink (guestfsd_sock);
- g->sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
- if (g->sock == -1) {
+ g->daemon_sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
+ if (g->daemon_sock == -1) {
perrorf (g, "socket");
goto cleanup0;
}
- if (fcntl (g->sock, F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (g->daemon_sock, F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup0;
}
@@ -225,12 +225,12 @@ launch_appliance (guestfs_h *g, const char *arg)
strncpy (addr.sun_path, guestfsd_sock, UNIX_PATH_MAX);
addr.sun_path[UNIX_PATH_MAX-1] = '\0';
- if (bind (g->sock, &addr, sizeof addr) == -1) {
+ if (bind (g->daemon_sock, &addr, sizeof addr) == -1) {
perrorf (g, "bind");
goto cleanup0;
}
- if (listen (g->sock, 1) == -1) {
+ if (listen (g->daemon_sock, 1) == -1) {
perrorf (g, "listen");
goto cleanup0;
}
@@ -611,7 +611,7 @@ launch_appliance (guestfs_h *g, const char *arg)
goto cleanup1;
}
- g->fd = sv[0]; /* stdin of child */
+ g->console_sock = sv[0]; /* stdin of child */
sv[0] = -1;
}
@@ -632,15 +632,15 @@ launch_appliance (guestfs_h *g, const char *arg)
*/
/* Close the listening socket. */
- if (close (g->sock) != 0) {
+ if (close (g->daemon_sock) != 0) {
perrorf (g, "close: listening socket");
close (r);
- g->sock = -1;
+ g->daemon_sock = -1;
goto cleanup1;
}
- g->sock = r; /* This is the accepted data socket. */
+ g->daemon_sock = r; /* This is the accepted data socket. */
- if (fcntl (g->sock, F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (g->daemon_sock, F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup1;
}
@@ -686,16 +686,16 @@ launch_appliance (guestfs_h *g, const char *arg)
if (g->app.recoverypid > 0) kill (g->app.recoverypid, 9);
if (g->app.pid > 0) waitpid (g->app.pid, NULL, 0);
if (g->app.recoverypid > 0) waitpid (g->app.recoverypid, NULL, 0);
- if (g->fd >= 0) close (g->fd);
- g->fd = -1;
+ if (g->console_sock >= 0) close (g->console_sock);
+ g->console_sock = -1;
g->app.pid = 0;
g->app.recoverypid = 0;
memset (&g->launch_t, 0, sizeof g->launch_t);
cleanup0:
- if (g->sock >= 0) {
- close (g->sock);
- g->sock = -1;
+ if (g->daemon_sock >= 0) {
+ close (g->daemon_sock);
+ g->daemon_sock = -1;
}
g->state = CONFIG;
return -1;
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index caad5d4..d771392 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -258,13 +258,13 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
set_socket_create_context (g);
- g->sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
- if (g->sock == -1) {
+ g->daemon_sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
+ if (g->daemon_sock == -1) {
perrorf (g, "socket");
goto cleanup;
}
- if (fcntl (g->sock, F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (g->daemon_sock, F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup;
}
@@ -272,12 +272,12 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
addr.sun_family = AF_UNIX;
memcpy (addr.sun_path, params.guestfsd_sock, UNIX_PATH_MAX);
- if (bind (g->sock, &addr, sizeof addr) == -1) {
+ if (bind (g->daemon_sock, &addr, sizeof addr) == -1) {
perrorf (g, "bind");
goto cleanup;
}
- if (listen (g->sock, 1) == -1) {
+ if (listen (g->daemon_sock, 1) == -1) {
perrorf (g, "listen");
goto cleanup;
}
@@ -399,7 +399,7 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
goto cleanup;
}
console = -1;
- g->fd = r; /* This is the accepted console socket. */
+ g->console_sock = r; /* This is the accepted console socket. */
/* Wait for libvirt domain to start and to connect back to us via
* virtio-serial and send the GUESTFS_LAUNCH_FLAG message.
@@ -416,15 +416,15 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
*/
/* Close the listening socket. */
- if (close (g->sock) == -1) {
+ if (close (g->daemon_sock) == -1) {
perrorf (g, "close: listening socket");
close (r);
- g->sock = -1;
+ g->daemon_sock = -1;
goto cleanup;
}
- g->sock = r; /* This is the accepted data socket. */
+ g->daemon_sock = r; /* This is the accepted data socket. */
- if (fcntl (g->sock, F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (g->daemon_sock, F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup;
}
@@ -475,13 +475,13 @@ launch_libvirt (guestfs_h *g, const char *libvirt_uri)
if (console >= 0)
close (console);
- if (g->fd >= 0) {
- close (g->fd);
- g->fd = -1;
+ if (g->console_sock >= 0) {
+ close (g->console_sock);
+ g->console_sock = -1;
}
- if (g->sock >= 0) {
- close (g->sock);
- g->sock = -1;
+ if (g->daemon_sock >= 0) {
+ close (g->daemon_sock);
+ g->daemon_sock = -1;
}
if (dom) {
diff --git a/src/launch-unix.c b/src/launch-unix.c
index a7a3ae2..69de2f7 100644
--- a/src/launch-unix.c
+++ b/src/launch-unix.c
@@ -49,13 +49,13 @@ launch_unix (guestfs_h *g, const char *sockpath)
/* Set this to nothing so we don't try to read from a random file
* descriptor.
*/
- g->fd = -1;
+ g->console_sock = -1;
if (g->verbose)
guestfs___print_timestamped_message (g, "connecting to %s",
sockpath);
- g->sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
- if (g->sock == -1) {
+ g->daemon_sock = socket (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
+ if (g->daemon_sock == -1) {
perrorf (g, "socket");
return -1;
}
@@ -66,12 +66,12 @@ launch_unix (guestfs_h *g, const char *sockpath)
g->state = LAUNCHING;
- if (connect (g->sock, &addr, sizeof addr) == -1) {
+ if (connect (g->daemon_sock, &addr, sizeof addr) == -1) {
perrorf (g, "bind");
goto cleanup;
}
- if (fcntl (g->sock, F_SETFL, O_NONBLOCK) == -1) {
+ if (fcntl (g->daemon_sock, F_SETFL, O_NONBLOCK) == -1) {
perrorf (g, "fcntl");
goto cleanup;
}
@@ -97,14 +97,14 @@ launch_unix (guestfs_h *g, const char *sockpath)
return 0;
cleanup:
- close (g->sock);
+ close (g->daemon_sock);
return -1;
}
static int
shutdown_unix (guestfs_h *g, int check_for_errors)
{
- /* Merely closing g->sock is sufficient and that is already done
+ /* Merely closing g->daemon_sock is sufficient and that is already done
* in the calling code.
*/
return 0;
diff --git a/src/proto.c b/src/proto.c
index 57cb609..569b805 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -161,10 +161,10 @@ child_cleanup (guestfs_h *g)
debug (g, "child_cleanup: %p: child process died", g);
g->attach_ops->shutdown (g, 0);
- if (g->fd >= 0) close (g->fd);
- close (g->sock);
- g->fd = -1;
- g->sock = -1;
+ if (g->console_sock >= 0) close (g->console_sock);
+ close (g->daemon_sock);
+ g->console_sock = -1;
+ g->daemon_sock = -1;
memset (&g->launch_t, 0, sizeof g->launch_t);
guestfs___free_drives (g);
g->state = CONFIG;
@@ -383,12 +383,12 @@ send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
FD_ZERO (&rset);
FD_ZERO (&wset);
- if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd, &rset);
- FD_SET (g->sock, &rset); /* Read socket for cancellation &
EOF. */
- FD_SET (g->sock, &wset); /* Write to socket to send the data. */
+ if (g->console_sock >= 0) /* Read qemu stdout for log messages &
EOF. */
+ FD_SET (g->console_sock, &rset);
+ FD_SET (g->daemon_sock, &rset); /* Read socket for cancellation &
EOF. */
+ FD_SET (g->daemon_sock, &wset); /* Write to socket to send the data.
*/
- int max_fd = MAX (g->sock, g->fd);
+ int max_fd = MAX (g->daemon_sock, g->console_sock);
while (n > 0) {
rset2 = rset;
@@ -401,12 +401,12 @@ send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
return -1;
}
- if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
- if (read_log_message_or_eof (g, g->fd, 0) == -1)
+ if (g->console_sock >= 0 && FD_ISSET (g->console_sock,
&rset2)) {
+ if (read_log_message_or_eof (g, g->console_sock, 0) == -1)
return -1;
}
- if (FD_ISSET (g->sock, &rset2)) {
- r = check_for_daemon_cancellation_or_eof (g, g->sock);
+ if (FD_ISSET (g->daemon_sock, &rset2)) {
+ r = check_for_daemon_cancellation_or_eof (g, g->daemon_sock);
if (r == -1)
return r;
if (r == -2) {
@@ -414,15 +414,15 @@ send_to_daemon (guestfs_h *g, const void *v_buf, size_t n)
* synchronization we must write out the remainder of the
* write buffer before we return (RHBZ#576879).
*/
- if (xwrite (g->sock, buf, n) == -1) {
+ if (xwrite (g->daemon_sock, buf, n) == -1) {
perrorf (g, "write");
return -1;
}
return -2; /* cancelled */
}
}
- if (FD_ISSET (g->sock, &wset2)) {
- r = write (g->sock, buf, n);
+ if (FD_ISSET (g->daemon_sock, &wset2)) {
+ r = write (g->daemon_sock, buf, n);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
@@ -507,18 +507,18 @@ recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void
**buf_rtn)
* socket connection just before this function is called, so just
* return an error if this happens.
*/
- if (g->sock == -1) {
+ if (g->daemon_sock == -1) {
unexpected_closed_connection_from_daemon_error (g);
return -1;
}
FD_ZERO (&rset);
- if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd, &rset);
- FD_SET (g->sock, &rset); /* Read socket for data & EOF. */
+ if (g->console_sock >= 0) /* Read qemu stdout for log messages &
EOF. */
+ FD_SET (g->console_sock, &rset);
+ FD_SET (g->daemon_sock, &rset); /* Read socket for data & EOF. */
- max_fd = MAX (g->sock, g->fd);
+ max_fd = MAX (g->daemon_sock, g->console_sock);
*size_rtn = 0;
*buf_rtn = NULL;
@@ -546,16 +546,16 @@ recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void
**buf_rtn)
return -1;
}
- if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
- if (read_log_message_or_eof (g, g->fd, 0) == -1) {
+ if (g->console_sock >= 0 && FD_ISSET (g->console_sock,
&rset2)) {
+ if (read_log_message_or_eof (g, g->console_sock, 0) == -1) {
free (*buf_rtn);
*buf_rtn = NULL;
return -1;
}
}
- if (FD_ISSET (g->sock, &rset2)) {
+ if (FD_ISSET (g->daemon_sock, &rset2)) {
if (nr < 0) { /* Have we read the message length word yet? */
- r = read (g->sock, lenbuf+nr+4, -nr);
+ r = read (g->daemon_sock, lenbuf+nr+4, -nr);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
@@ -623,7 +623,7 @@ recv_from_daemon (guestfs_h *g, uint32_t *size_rtn, void
**buf_rtn)
size_t sizetoread = message_size - nr;
if (sizetoread > BUFSIZ) sizetoread = BUFSIZ;
- r = read (g->sock, (char *) (*buf_rtn) + nr, sizetoread);
+ r = read (g->daemon_sock, (char *) (*buf_rtn) + nr, sizetoread);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
@@ -712,7 +712,7 @@ guestfs___recv_from_daemon (guestfs_h *g, uint32_t
*size_rtn, void **buf_rtn)
return 0;
}
-/* This is very much like recv_from_daemon above, but g->sock is
+/* This is very much like recv_from_daemon above, but g->daemon_sock is
* a listening socket and we are accepting a new connection on
* that socket instead of reading anything. Returns the newly
* accepted socket.
@@ -726,11 +726,11 @@ guestfs___accept_from_daemon (guestfs_h *g)
FD_ZERO (&rset);
- if (g->fd >= 0) /* Read qemu stdout for log messages
& EOF. */
- FD_SET (g->fd, &rset);
- FD_SET (g->sock, &rset); /* Read socket for accept. */
+ if (g->console_sock >= 0) /* Read qemu stdout for log messages &
EOF. */
+ FD_SET (g->console_sock, &rset);
+ FD_SET (g->daemon_sock, &rset); /* Read socket for accept. */
- int max_fd = MAX (g->sock, g->fd);
+ int max_fd = MAX (g->daemon_sock, g->console_sock);
int sock = -1;
while (sock == -1) {
@@ -758,12 +758,12 @@ guestfs___accept_from_daemon (guestfs_h *g)
return -1;
}
- if (g->fd >= 0 && FD_ISSET (g->fd, &rset2)) {
- if (read_log_message_or_eof (g, g->fd, 1) == -1)
+ if (g->console_sock >= 0 && FD_ISSET (g->console_sock,
&rset2)) {
+ if (read_log_message_or_eof (g, g->console_sock, 1) == -1)
return -1;
}
- if (FD_ISSET (g->sock, &rset2)) {
- sock = accept4 (g->sock, NULL, NULL, SOCK_CLOEXEC);
+ if (FD_ISSET (g->daemon_sock, &rset2)) {
+ sock = accept4 (g->daemon_sock, NULL, NULL, SOCK_CLOEXEC);
if (sock == -1) {
if (errno == EINTR || errno == EAGAIN)
continue;
@@ -1154,7 +1154,7 @@ guestfs___recv_file (guestfs_h *g, const char *filename)
xdr_uint32_t (&xdr, &flag);
xdr_destroy (&xdr);
- if (xwrite (g->sock, fbuf, sizeof fbuf) == -1) {
+ if (xwrite (g->daemon_sock, fbuf, sizeof fbuf) == -1) {
perrorf (g, _("write to daemon socket"));
return -1;
}
--
1.8.1.4
Richard W.M. Jones
2013-Mar-07 11:44 UTC
[Libguestfs] [PATCH 4/4] launch: unix: Set g->daemon_sock = -1 after closing it.
From: "Richard W.M. Jones" <rjones at redhat.com> This ensures we don't accidentally use the closed fd. --- src/launch-unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/launch-unix.c b/src/launch-unix.c index 69de2f7..db49a3c 100644 --- a/src/launch-unix.c +++ b/src/launch-unix.c @@ -98,6 +98,7 @@ launch_unix (guestfs_h *g, const char *sockpath) cleanup: close (g->daemon_sock); + g->daemon_sock = -1; return -1; } -- 1.8.1.4
Seemingly Similar Threads
- [PATCH 0/3] protocol: Abstract out socket operations.
- Libguestfs (1.22.6) driver/changes for mingw/win32
- [PATCH] lib: command: switch from select() to poll()
- Re: [PATCH] lib: command: switch from select() to poll()
- [PATCH v2 0/4] Experimental User-Mode Linux backend.