[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 08/47] socket shutdown
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v4 08/47] socket shutdown |
Date: |
Fri, 3 Oct 2014 18:47:14 +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 a8cac7a..935cf42 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 a057b3e..14dcf34 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 1eef590..830e6d7 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -981,3 +981,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
- [Qemu-devel] [PATCH v4 00/47] Postcopy implementation, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 01/47] QEMUSizedBuffer based QEMUFile, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 02/47] Tests: QEMUSizedBuffer/QEMUBuffer, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 03/47] Start documenting how postcopy works., Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 05/47] improve DPRINTF macros, add to savevm, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 04/47] qemu_ram_foreach_block: pass up error value, and down the ramblock name, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 06/47] Add qemu_get_counted_string to read a string prefixed by a count byte, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 07/47] Create MigrationIncomingState, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 08/47] socket shutdown,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v4 09/47] Provide runtime Target page information, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 10/47] Return path: Open a return path on QEMUFile for sockets, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 12/47] Handle bi-directional communication for fd migration, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 11/47] Return path: socket_writev_buffer: Block even on non-blocking fd's, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 13/47] Migration commands, Dr. David Alan Gilbert (git), 2014/10/03
- [Qemu-devel] [PATCH v4 14/47] Return path: Control commands, Dr. David Alan Gilbert (git), 2014/10/03