diff mbox

[v5,09/45] Migration commands

Message ID 1424883128-9841-10-git-send-email-dgilbert@redhat.com
State New
Headers show

Commit Message

Dr. David Alan Gilbert Feb. 25, 2015, 4:51 p.m. UTC
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Create QEMU_VM_COMMAND section type for sending commands from
source to destination.  These commands are not intended to convey
guest state but to control the migration process.

For use in postcopy.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 include/migration/migration.h |  1 +
 include/sysemu/sysemu.h       |  7 +++++++
 savevm.c                      | 48 +++++++++++++++++++++++++++++++++++++++++++
 trace-events                  |  1 +
 4 files changed, 57 insertions(+)

Comments

David Gibson March 10, 2015, 4:58 a.m. UTC | #1
On Wed, Feb 25, 2015 at 04:51:32PM +0000, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> Create QEMU_VM_COMMAND section type for sending commands from
> source to destination.  These commands are not intended to convey
> guest state but to control the migration process.
> 
> For use in postcopy.
> 
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

[snip]
> +/* Send a 'QEMU_VM_COMMAND' type element with the command
> + * and associated data.
> + */
> +void qemu_savevm_command_send(QEMUFile *f,
> +                              enum qemu_vm_cmd command,
> +                              uint16_t len,
> +                              uint8_t *data)
> +{
> +    uint32_t tmp = (uint16_t)command;

Erm.. cast to u16, assign to u32, then send as u16?  What's up with
that?

> +    qemu_put_byte(f, QEMU_VM_COMMAND);
> +    qemu_put_be16(f, tmp);
> +    qemu_put_be16(f, len);
> +    if (len) {
> +        qemu_put_buffer(f, data, len);
> +    }
> +    qemu_fflush(f);
> +}
> +
Dr. David Alan Gilbert March 10, 2015, 11:04 a.m. UTC | #2
* David Gibson (david@gibson.dropbear.id.au) wrote:
> On Wed, Feb 25, 2015 at 04:51:32PM +0000, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > 
> > Create QEMU_VM_COMMAND section type for sending commands from
> > source to destination.  These commands are not intended to convey
> > guest state but to control the migration process.
> > 
> > For use in postcopy.
> > 
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> 
> [snip]
> > +/* Send a 'QEMU_VM_COMMAND' type element with the command
> > + * and associated data.
> > + */
> > +void qemu_savevm_command_send(QEMUFile *f,
> > +                              enum qemu_vm_cmd command,
> > +                              uint16_t len,
> > +                              uint8_t *data)
> > +{
> > +    uint32_t tmp = (uint16_t)command;
> 
> Erm.. cast to u16, assign to u32, then send as u16?  What's up with
> that?

Hmm yes, that is insane;  now changed to:

+void qemu_savevm_command_send(QEMUFile *f,
+                              enum qemu_vm_cmd command,
+                              uint16_t len,
+                              uint8_t *data)
+{
+    qemu_put_byte(f, QEMU_VM_COMMAND);
+    qemu_put_be16(f, (uint16_t)command);
+    qemu_put_be16(f, len);
+    if (len) {
+        qemu_put_buffer(f, data, len);
+    }
+    qemu_fflush(f);
+}

Thanks,

Dave

> 
> > +    qemu_put_byte(f, QEMU_VM_COMMAND);
> > +    qemu_put_be16(f, tmp);
> > +    qemu_put_be16(f, len);
> > +    if (len) {
> > +        qemu_put_buffer(f, data, len);
> > +    }
> > +    qemu_fflush(f);
> > +}
> > +
> 
> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson


--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
David Gibson March 10, 2015, 11:06 a.m. UTC | #3
On Tue, Mar 10, 2015 at 11:04:14AM +0000, Dr. David Alan Gilbert wrote:
> * David Gibson (david@gibson.dropbear.id.au) wrote:
> > On Wed, Feb 25, 2015 at 04:51:32PM +0000, Dr. David Alan Gilbert (git) wrote:
> > > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > > 
> > > Create QEMU_VM_COMMAND section type for sending commands from
> > > source to destination.  These commands are not intended to convey
> > > guest state but to control the migration process.
> > > 
> > > For use in postcopy.
> > > 
> > > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > 
> > [snip]
> > > +/* Send a 'QEMU_VM_COMMAND' type element with the command
> > > + * and associated data.
> > > + */
> > > +void qemu_savevm_command_send(QEMUFile *f,
> > > +                              enum qemu_vm_cmd command,
> > > +                              uint16_t len,
> > > +                              uint8_t *data)
> > > +{
> > > +    uint32_t tmp = (uint16_t)command;
> > 
> > Erm.. cast to u16, assign to u32, then send as u16?  What's up with
> > that?
> 
> Hmm yes, that is insane;  now changed to:
> 
> +void qemu_savevm_command_send(QEMUFile *f,
> +                              enum qemu_vm_cmd command,
> +                              uint16_t len,
> +                              uint8_t *data)
> +{
> +    qemu_put_byte(f, QEMU_VM_COMMAND);
> +    qemu_put_be16(f, (uint16_t)command);
> +    qemu_put_be16(f, len);
> +    if (len) {
> +        qemu_put_buffer(f, data, len);
> +    }
> +    qemu_fflush(f);
> +}

That looks better.
diff mbox

Patch

diff --git a/include/migration/migration.h b/include/migration/migration.h
index 8505543..1b1dc34 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -34,6 +34,7 @@ 
 #define QEMU_VM_SECTION_FULL         0x04
 #define QEMU_VM_SUBSECTION           0x05
 #define QEMU_VM_VMDESCRIPTION        0x06
+#define QEMU_VM_COMMAND              0x07
 
 struct MigrationParams {
     bool blk;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ebab098..88e5e76 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -82,6 +82,11 @@  void do_info_snapshots(Monitor *mon, const QDict *qdict);
 
 void qemu_announce_self(void);
 
+/* Subcommands for QEMU_VM_COMMAND */
+enum qemu_vm_cmd {
+    MIG_CMD_INVALID = 0,   /* Must be 0 */
+};
+
 bool qemu_savevm_state_blocked(Error **errp);
 void qemu_savevm_state_begin(QEMUFile *f,
                              const MigrationParams *params);
@@ -90,6 +95,8 @@  int qemu_savevm_state_iterate(QEMUFile *f);
 void qemu_savevm_state_complete(QEMUFile *f);
 void qemu_savevm_state_cancel(void);
 uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size);
+void qemu_savevm_command_send(QEMUFile *f, enum qemu_vm_cmd command,
+                              uint16_t len, uint8_t *data);
 int qemu_loadvm_state(QEMUFile *f);
 
 /* SLIRP */
diff --git a/savevm.c b/savevm.c
index cce7ff0..3d04ba1 100644
--- a/savevm.c
+++ b/savevm.c
@@ -602,6 +602,25 @@  static void vmstate_save(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
     vmstate_save_state(f, se->vmsd, se->opaque, vmdesc);
 }
 
+
+/* Send a 'QEMU_VM_COMMAND' type element with the command
+ * and associated data.
+ */
+void qemu_savevm_command_send(QEMUFile *f,
+                              enum qemu_vm_cmd command,
+                              uint16_t len,
+                              uint8_t *data)
+{
+    uint32_t tmp = (uint16_t)command;
+    qemu_put_byte(f, QEMU_VM_COMMAND);
+    qemu_put_be16(f, tmp);
+    qemu_put_be16(f, len);
+    if (len) {
+        qemu_put_buffer(f, data, len);
+    }
+    qemu_fflush(f);
+}
+
 bool qemu_savevm_state_blocked(Error **errp)
 {
     SaveStateEntry *se;
@@ -918,6 +937,29 @@  static SaveStateEntry *find_se(const char *idstr, int instance_id)
     return NULL;
 }
 
+/*
+ * Process an incoming 'QEMU_VM_COMMAND'
+ * negative return on error (will issue error message)
+ */
+static int loadvm_process_command(QEMUFile *f)
+{
+    uint16_t com;
+    uint16_t len;
+
+    com = qemu_get_be16(f);
+    len = qemu_get_be16(f);
+
+    trace_loadvm_process_command(com, len);
+    switch (com) {
+
+    default:
+        error_report("VM_COMMAND 0x%x unknown (len 0x%x)", com, len);
+        return -1;
+    }
+
+    return 0;
+}
+
 typedef struct LoadStateEntry {
     QLIST_ENTRY(LoadStateEntry) entry;
     SaveStateEntry *se;
@@ -1033,6 +1075,12 @@  int qemu_loadvm_state(QEMUFile *f)
                 goto out;
             }
             break;
+        case QEMU_VM_COMMAND:
+            ret = loadvm_process_command(f);
+            if (ret < 0) {
+                goto out;
+            }
+            break;
         default:
             error_report("Unknown savevm section type %d", section_type);
             ret = -EINVAL;
diff --git a/trace-events b/trace-events
index 83231d7..4e2fbc8 100644
--- a/trace-events
+++ b/trace-events
@@ -1167,6 +1167,7 @@  vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
 qemu_loadvm_state_section(unsigned int section_type) "%d"
 qemu_loadvm_state_section_partend(uint32_t section_id) "%u"
 qemu_loadvm_state_section_startfull(uint32_t section_id, const char *idstr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u"
+loadvm_process_command(uint16_t com, uint16_t len) "com=0x%x len=%d"
 savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u"
 savevm_section_end(const char *id, unsigned int section_id, int ret) "%s, section_id %u -> %d"
 savevm_state_begin(void) ""