|
|
05bba0 |
From da3039bc7ec4fda6719be3bdd10f4b0fdaceb17a Mon Sep 17 00:00:00 2001
|
|
|
05bba0 |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
05bba0 |
Date: Fri, 16 Jan 2015 17:35:35 +0100
|
|
|
05bba0 |
Subject: [PATCH 03/16] socket shutdown
|
|
|
05bba0 |
|
|
|
05bba0 |
Message-id: <1421429737-23581-2-git-send-email-dgilbert@redhat.com>
|
|
|
05bba0 |
Patchwork-id: 63332
|
|
|
05bba0 |
O-Subject: [RHEL-7.2 qemu-kvm PATCH 1/3] socket shutdown
|
|
|
05bba0 |
Bugzilla: 1086168
|
|
|
05bba0 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Add QEMUFile interface to allow a socket to be 'shut down' - i.e. any
|
|
|
05bba0 |
reads/writes will fail (and any blocking read/write will be woken).
|
|
|
05bba0 |
|
|
|
05bba0 |
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
05bba0 |
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
05bba0 |
Reviewed-by: Amit Shah <amit.shah@redhat.com>
|
|
|
05bba0 |
Signed-off-by: Amit Shah <amit.shah@redhat.com>
|
|
|
05bba0 |
(cherry picked from commit e1a8c9b67fc97d293211773edcae9e8e2f3367ab)
|
|
|
05bba0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Conflicts:
|
|
|
05bba0 |
include/migration/qemu-file.h
|
|
|
05bba0 |
migration/qemu-file-unix.c
|
|
|
05bba0 |
migration/qemu-file.c
|
|
|
05bba0 |
|
|
|
05bba0 |
Because we split qemu-file.c out of savevm and moved it
|
|
|
05bba0 |
---
|
|
|
05bba0 |
include/migration/qemu-file.h | 10 ++++++++++
|
|
|
05bba0 |
include/qemu/sockets.h | 7 +++++++
|
|
|
05bba0 |
savevm.c | 33 +++++++++++++++++++++++++++++----
|
|
|
05bba0 |
3 files changed, 46 insertions(+), 4 deletions(-)
|
|
|
05bba0 |
|
|
|
05bba0 |
diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
|
|
|
05bba0 |
index 0f757fb..032de47 100644
|
|
|
05bba0 |
--- a/include/migration/qemu-file.h
|
|
|
05bba0 |
+++ b/include/migration/qemu-file.h
|
|
|
05bba0 |
@@ -82,6 +82,14 @@ typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
|
|
|
05bba0 |
size_t size,
|
|
|
05bba0 |
int *bytes_sent);
|
|
|
05bba0 |
|
|
|
05bba0 |
+/*
|
|
|
05bba0 |
+ * Stop any read or write (depending on flags) on the underlying
|
|
|
05bba0 |
+ * transport on the QEMUFile.
|
|
|
05bba0 |
+ * Existing blocking reads/writes must be woken
|
|
|
05bba0 |
+ * Returns 0 on success, -err on error
|
|
|
05bba0 |
+ */
|
|
|
05bba0 |
+typedef int (QEMUFileShutdownFunc)(void *opaque, bool rd, bool wr);
|
|
|
05bba0 |
+
|
|
|
05bba0 |
typedef struct QEMUFileOps {
|
|
|
05bba0 |
QEMUFilePutBufferFunc *put_buffer;
|
|
|
05bba0 |
QEMUFileGetBufferFunc *get_buffer;
|
|
|
05bba0 |
@@ -92,6 +100,7 @@ typedef struct QEMUFileOps {
|
|
|
05bba0 |
QEMURamHookFunc *after_ram_iterate;
|
|
|
05bba0 |
QEMURamHookFunc *hook_ram_load;
|
|
|
05bba0 |
QEMURamSaveFunc *save_page;
|
|
|
05bba0 |
+ QEMUFileShutdownFunc *shut_down;
|
|
|
05bba0 |
} QEMUFileOps;
|
|
|
05bba0 |
|
|
|
05bba0 |
QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
|
|
|
05bba0 |
@@ -141,6 +150,7 @@ void qemu_file_reset_rate_limit(QEMUFile *f);
|
|
|
05bba0 |
void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
|
|
|
05bba0 |
int64_t qemu_file_get_rate_limit(QEMUFile *f);
|
|
|
05bba0 |
int qemu_file_get_error(QEMUFile *f);
|
|
|
05bba0 |
+int qemu_file_shutdown(QEMUFile *f);
|
|
|
05bba0 |
void qemu_fflush(QEMUFile *f);
|
|
|
05bba0 |
|
|
|
05bba0 |
static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
|
|
|
05bba0 |
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
|
|
|
05bba0 |
index c5174d7..729ff52 100644
|
|
|
05bba0 |
--- a/include/qemu/sockets.h
|
|
|
05bba0 |
+++ b/include/qemu/sockets.h
|
|
|
05bba0 |
@@ -42,6 +42,13 @@ void qemu_set_nonblock(int fd);
|
|
|
05bba0 |
int send_all(int fd, const void *buf, int len1);
|
|
|
05bba0 |
int recv_all(int fd, void *buf, int len1, bool single_read);
|
|
|
05bba0 |
|
|
|
05bba0 |
+#ifdef WIN32
|
|
|
05bba0 |
+/* Windows has different names for the same constants with the same values */
|
|
|
05bba0 |
+#define SHUT_RD 0
|
|
|
05bba0 |
+#define SHUT_WR 1
|
|
|
05bba0 |
+#define SHUT_RDWR 2
|
|
|
05bba0 |
+#endif
|
|
|
05bba0 |
+
|
|
|
05bba0 |
/* callback function for nonblocking connect
|
|
|
05bba0 |
* valid fd on success, negative error code on failure
|
|
|
05bba0 |
*/
|
|
|
05bba0 |
diff --git a/savevm.c b/savevm.c
|
|
|
05bba0 |
index 963dc7d..731d5c0 100644
|
|
|
05bba0 |
--- a/savevm.c
|
|
|
05bba0 |
+++ b/savevm.c
|
|
|
05bba0 |
@@ -204,6 +204,17 @@ static int socket_close(void *opaque)
|
|
|
05bba0 |
return 0;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
+static int socket_shutdown(void *opaque, bool rd, bool wr)
|
|
|
05bba0 |
+{
|
|
|
05bba0 |
+ QEMUFileSocket *s = opaque;
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ if (shutdown(s->fd, rd ? (wr ? SHUT_RDWR : SHUT_RD) : SHUT_WR)) {
|
|
|
05bba0 |
+ return -errno;
|
|
|
05bba0 |
+ } else {
|
|
|
05bba0 |
+ return 0;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+}
|
|
|
05bba0 |
+
|
|
|
05bba0 |
static int stdio_get_fd(void *opaque)
|
|
|
05bba0 |
{
|
|
|
05bba0 |
QEMUFileStdio *s = opaque;
|
|
|
05bba0 |
@@ -448,17 +459,31 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
static const QEMUFileOps socket_read_ops = {
|
|
|
05bba0 |
- .get_fd = socket_get_fd,
|
|
|
05bba0 |
+ .get_fd = socket_get_fd,
|
|
|
05bba0 |
.get_buffer = socket_get_buffer,
|
|
|
05bba0 |
- .close = socket_close
|
|
|
05bba0 |
+ .close = socket_close,
|
|
|
05bba0 |
+ .shut_down = socket_shutdown
|
|
|
05bba0 |
};
|
|
|
05bba0 |
|
|
|
05bba0 |
static const QEMUFileOps socket_write_ops = {
|
|
|
05bba0 |
- .get_fd = socket_get_fd,
|
|
|
05bba0 |
+ .get_fd = socket_get_fd,
|
|
|
05bba0 |
.writev_buffer = socket_writev_buffer,
|
|
|
05bba0 |
- .close = socket_close
|
|
|
05bba0 |
+ .close = socket_close,
|
|
|
05bba0 |
+ .shut_down = socket_shutdown
|
|
|
05bba0 |
};
|
|
|
05bba0 |
|
|
|
05bba0 |
+/*
|
|
|
05bba0 |
+ * Stop a file from being read/written - not all backing files can do this
|
|
|
05bba0 |
+ * typically only sockets can.
|
|
|
05bba0 |
+ */
|
|
|
05bba0 |
+int qemu_file_shutdown(QEMUFile *f)
|
|
|
05bba0 |
+{
|
|
|
05bba0 |
+ if (!f->ops->shut_down) {
|
|
|
05bba0 |
+ return -ENOSYS;
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+ return f->ops->shut_down(f->opaque, true, true);
|
|
|
05bba0 |
+}
|
|
|
05bba0 |
+
|
|
|
05bba0 |
bool qemu_file_mode_is_not_valid(const char *mode)
|
|
|
05bba0 |
{
|
|
|
05bba0 |
if (mode == NULL ||
|
|
|
05bba0 |
--
|
|
|
05bba0 |
1.8.3.1
|
|
|
05bba0 |
|