qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 08/47] socket shutdown


From: Dr. David Alan Gilbert (git)
Subject: [Qemu-devel] [PATCH v3 08/47] socket shutdown
Date: Thu, 28 Aug 2014 16:03:25 +0100

From: "Dr. David Alan Gilbert" <address@hidden>

Add QEMUFile interface to allow a socket to be 'shut down' - i.e. any
reads/writes will fail (and any blocking read/write will be woken).

Add qemu_socket wrapper to let OS dependencies be extracted out.

Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
 include/migration/qemu-file.h | 10 ++++++++++
 include/qemu/sockets.h        |  1 +
 qemu-file.c                   | 27 +++++++++++++++++++++++++--
 util/qemu-sockets.c           | 28 ++++++++++++++++++++++++++++
 4 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index e50d696..ca8fbdc 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -84,6 +84,14 @@ typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
                                size_t size,
                                int *bytes_sent);
 
+/*
+ * Stop any read or write (depending on flags) on the underlying
+ * transport on the QEMUFile.
+ * Existing blocking reads/writes must be woken
+ * Returns 0 on success, -err on error
+ */
+typedef int (QEMUFileShutdownFunc)(void *opaque, bool rd, bool wr);
+
 typedef struct QEMUFileOps {
     QEMUFilePutBufferFunc *put_buffer;
     QEMUFileGetBufferFunc *get_buffer;
@@ -94,6 +102,7 @@ typedef struct QEMUFileOps {
     QEMURamHookFunc *after_ram_iterate;
     QEMURamHookFunc *hook_ram_load;
     QEMURamSaveFunc *save_page;
+    QEMUFileShutdownFunc *shut_down;
 } QEMUFileOps;
 
 struct QEMUSizedBuffer {
@@ -178,6 +187,7 @@ void qemu_file_set_rate_limit(QEMUFile *f, int64_t 
new_rate);
 int64_t qemu_file_get_rate_limit(QEMUFile *f);
 int qemu_file_get_error(QEMUFile *f);
 void qemu_file_set_error(QEMUFile *f, int ret);
+void qemu_file_shutdown(QEMUFile *f);
 void qemu_fflush(QEMUFile *f);
 
 static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index fdbb196..ea8ffc6 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -41,6 +41,7 @@ int socket_set_nodelay(int fd);
 void qemu_set_block(int fd);
 void qemu_set_nonblock(int fd);
 int socket_set_fast_reuse(int fd);
+int socket_shutdown(int fd, bool rd, bool wr);
 int send_all(int fd, const void *buf, int len1);
 int recv_all(int fd, void *buf, int len1, bool single_read);
 
diff --git a/qemu-file.c b/qemu-file.c
index f6d64ce..d7401fa 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -90,6 +90,14 @@ static int socket_close(void *opaque)
     return 0;
 }
 
+/* qemufile_ to disambiguate from the qemu-sockets.c code which it uses */
+static int qemufile_socket_shutdown(void *opaque, bool rd, bool wr)
+{
+    QEMUFileSocket *s = opaque;
+
+    return socket_shutdown(s->fd, rd, wr);
+}
+
 static int stdio_get_fd(void *opaque)
 {
     QEMUFileStdio *s = opaque;
@@ -337,15 +345,30 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
 static const QEMUFileOps socket_read_ops = {
     .get_fd =     socket_get_fd,
     .get_buffer = socket_get_buffer,
-    .close =      socket_close
+    .close =      socket_close,
+    .shut_down       = qemufile_socket_shutdown
+
 };
 
 static const QEMUFileOps socket_write_ops = {
     .get_fd =     socket_get_fd,
     .writev_buffer = socket_writev_buffer,
-    .close =      socket_close
+    .close =      socket_close,
+    .shut_down       = qemufile_socket_shutdown
+
 };
 
+/*
+ * Stop a file from being read/written - not all backing files can do this
+ * typically only sockets can.  The caller should make sure they only
+ * call this for things that can.
+ */
+void qemu_file_shutdown(QEMUFile *f)
+{
+    assert(f->ops->shut_down);
+    f->ops->shut_down(f, true, true);
+}
+
 bool qemu_file_mode_is_not_valid(const char *mode)
 {
     if (mode == NULL ||
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 5d38395..c68cb52 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -982,3 +982,31 @@ int socket_dgram(SocketAddress *remote, SocketAddress 
*local, Error **errp)
     qemu_opts_del(opts);
     return fd;
 }
+
+int socket_shutdown(int fd, bool rd, bool wr)
+{
+    int how = 0;
+
+#ifndef WIN32
+    if (rd) {
+        how = SHUT_RD;
+    }
+
+    if (wr) {
+        how = rd ? SHUT_RDWR : SHUT_WR;
+    }
+
+#else
+    /* Untested */
+    if (rd) {
+        how = SD_RECEIVE;
+    }
+
+    if (wr) {
+        how = rd ? SD_BOTH : SD_SEND;
+    }
+
+#endif
+
+    return shutdown(fd, how);
+}
-- 
1.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]