[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 20/47] QEMU_VM_CMD_PACKAGED: Send a packaged chun
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v3 20/47] QEMU_VM_CMD_PACKAGED: Send a packaged chunk of migration stream |
Date: |
Thu, 28 Aug 2014 16:03:37 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
QEMU_VM_CMD_PACKAGED is a migration command that allows a chunk
of migration stream to be sent in one go, and be received by
a separate instance of the loadvm loop while not interacting
with the migration stream.
This is used by postcopy to load device state (from the package)
while loading memory pages from the main stream.
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
include/sysemu/sysemu.h | 4 +++
savevm.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 0641cc2..abf0d63 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -86,6 +86,7 @@ enum qemu_vm_cmd {
QEMU_VM_CMD_INVALID = 0, /* Must be 0 */
QEMU_VM_CMD_OPENRP, /* Tell the dest to open the Return path */
QEMU_VM_CMD_REQACK, /* Request an ACK on the RP */
+ QEMU_VM_CMD_PACKAGED, /* Send a wrapped stream within this stream */
QEMU_VM_CMD_POSTCOPY_RAM_ADVISE = 20, /* Prior to any page transfers, just
warn we might want to do PC */
@@ -100,6 +101,8 @@ enum qemu_vm_cmd {
QEMU_VM_CMD_AFTERLASTVALID
};
+#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
+
bool qemu_savevm_state_blocked(Error **errp);
void qemu_savevm_state_begin(QEMUFile *f,
const MigrationParams *params);
@@ -111,6 +114,7 @@ void qemu_savevm_command_send(QEMUFile *f, enum qemu_vm_cmd
command,
uint16_t len, uint8_t *data);
void qemu_savevm_send_reqack(QEMUFile *f, uint32_t value);
void qemu_savevm_send_openrp(QEMUFile *f);
+void qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb);
void qemu_savevm_send_postcopy_ram_advise(QEMUFile *f);
void qemu_savevm_send_postcopy_ram_discard(QEMUFile *f, const char *name,
uint16_t len, uint8_t offset,
diff --git a/savevm.c b/savevm.c
index 13d975d..171676d 100644
--- a/savevm.c
+++ b/savevm.c
@@ -627,6 +627,38 @@ void qemu_savevm_send_openrp(QEMUFile *f)
qemu_savevm_command_send(f, QEMU_VM_CMD_OPENRP, 0, NULL);
}
+/* We have a buffer of data to send; we don't want that all to be loaded
+ * by the command itself, so the command contains just the length of the
+ * extra buffer that we then send straight after it.
+ * TODO: Must be a better way to organise that
+ */
+void qemu_savevm_send_packaged(QEMUFile *f, const QEMUSizedBuffer *qsb)
+{
+ size_t cur_iov;
+ size_t len = qsb_get_length(qsb);
+ uint32_t tmp;
+
+ tmp = cpu_to_be32(len);
+
+ DPRINTF("send_packaged");
+ qemu_savevm_command_send(f, QEMU_VM_CMD_PACKAGED, 4, (uint8_t *)&tmp);
+
+ /* all the data follows (concatinating the iov's) */
+ for (cur_iov = 0; cur_iov < qsb->n_iov; cur_iov++) {
+ /* The iov entries are partially filled */
+ size_t towrite = (qsb->iov[cur_iov].iov_len > len) ?
+ len :
+ qsb->iov[cur_iov].iov_len;
+ len -= towrite;
+
+ if (!towrite) {
+ break;
+ }
+
+ qemu_put_buffer(f, qsb->iov[cur_iov].iov_base, towrite);
+ }
+}
+
/* Send prior to any RAM transfer */
void qemu_savevm_send_postcopy_ram_advise(QEMUFile *f)
{
@@ -1241,6 +1273,45 @@ static int loadvm_process_command_simple_lencheck(const
char *name,
return 0;
}
+/* Immediately following this command is a blob of data containing an embedded
+ * chunk of migration stream; read it and load it.
+ */
+static int loadvm_handle_cmd_packaged(MigrationIncomingState *mis,
+ uint32_t length,
+ LoadStateEntry_Head *loadvm_handlers)
+{
+ int ret;
+ uint8_t *buffer;
+ QEMUSizedBuffer *qsb;
+
+ DPRINTF("loadvm_handle_cmd_packaged: length=%u", length);
+
+ if (length > MAX_VM_CMD_PACKAGED_SIZE) {
+ error_report("Unreasonably large packaged state: %u", length);
+ return -1;
+ }
+ buffer = g_malloc0(length);
+ ret = qemu_get_buffer(mis->file, buffer, (int)length);
+ if (ret != length) {
+ g_free(buffer);
+ error_report("CMD_PACKAGED: Buffer receive fail ret=%d length=%d\n",
+ ret, length);
+ return (ret < 0) ? ret : -EAGAIN;
+ }
+ DPRINTF("%s: Received %d package, going to load", __func__, ret);
+
+ /* Setup a dummy QEMUFile that actually reads from the buffer */
+ qsb = qsb_create(buffer, length);
+ g_free(buffer); /* Because qsb_create copies */
+ QEMUFile *packf = qemu_bufopen("r", qsb);
+
+ ret = qemu_loadvm_state_main(packf, loadvm_handlers);
+ DPRINTF("%s: qemu_loadvm_state_main returned %d", __func__, ret);
+ qemu_fclose(packf); /* also frees the qsb */
+
+ return ret;
+}
+
/*
* Process an incoming 'QEMU_VM_COMMAND'
* negative return on error (will issue error message)
@@ -1290,6 +1361,14 @@ static int loadvm_process_command(QEMUFile *f,
migrate_send_rp_ack(mis, tmp32);
break;
+ case QEMU_VM_CMD_PACKAGED:
+ if (loadvm_process_command_simple_lencheck("CMD_POSTCOPY_RAM_ADVISE",
+ len, 4)) {
+ return -1;
+ }
+ tmp32 = qemu_get_be32(f);
+ return loadvm_handle_cmd_packaged(mis, tmp32, loadvm_handlers);
+
case QEMU_VM_CMD_POSTCOPY_RAM_ADVISE:
if (loadvm_process_command_simple_lencheck("CMD_POSTCOPY_RAM_ADVISE",
len, 0)) {
--
1.9.3
- [Qemu-devel] [PATCH v3 08/47] socket shutdown, (continued)
- [Qemu-devel] [PATCH v3 08/47] socket shutdown, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 10/47] Return path: socket_writev_buffer: Block even on non-blocking fd's, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 14/47] Return path: Source handling of return path, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 09/47] Return path: Open a return path on QEMUFile for sockets, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 12/47] Return path: Control commands, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 13/47] Return path: Send responses from destination to source, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 16/47] ram_debug_dump_bitmap: Dump a migration bitmap as text, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 17/47] Rework loadvm path for subloops, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 06/47] Add qemu_get_counted_string to read a string prefixed by a count byte, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 18/47] Add migration-capability boolean for postcopy-ram., Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 20/47] QEMU_VM_CMD_PACKAGED: Send a packaged chunk of migration stream,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v3 22/47] Allow savevm handlers to state whether they could go into postcopy, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 23/47] postcopy: OS support test, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 11/47] Migration commands, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 21/47] migrate_init: Call from savevm, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 24/47] migrate_start_postcopy: Command to trigger transition to postcopy, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 25/47] MIG_STATE_POSTCOPY_ACTIVE: Add new migration state, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 27/47] Postcopy: Maintain sentmap during postcopy pre phase, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 28/47] Postcopy page-map-incoming (PMI) structure, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 29/47] postcopy: Add incoming_init/cleanup functions, Dr. David Alan Gilbert (git), 2014/08/28
- [Qemu-devel] [PATCH v3 26/47] qemu_savevm_state_complete: Postcopy changes, Dr. David Alan Gilbert (git), 2014/08/28