[libvirt] [PATCH] migrate VMs between different-endian hosts

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Apr 11 10:32:21 UTC 2011


On 04/10/2011 11:09 PM, Daniel Veillard wrote:
> On Sat, Apr 09, 2011 at 11:48:41AM -0400, Stefan Berger wrote:
>> This patch enables the migration of Qemu VMs between hosts of
>> different endianess. I tested this by migrating a i686 VM between a
>> x86 and ppc64 host.
>    OMG, there is really a use case for this :-) ?
:-) There may be other architectures that run more efficiently than an 
x86 one.
Btw, my use case is 'testing'.
>> I am converting the 'int's in the VM's state header to uint32_t
>> assuming this doesn't break compatibility with existing deployments
>> other than Linux.
>>
>> Signed-off-by: Stefan Berger<stefanb at linux.vnet.ibm.com>
>>
>> ---
>>   src/qemu/qemu_driver.c |   25 ++++++++++++++++++++-----
>>   1 file changed, 20 insertions(+), 5 deletions(-)
>>
>> Index: libvirt-acl/src/qemu/qemu_driver.c
>> ===================================================================
>> --- libvirt-acl.orig/src/qemu/qemu_driver.c
>> +++ libvirt-acl/src/qemu/qemu_driver.c
>> @@ -43,6 +43,7 @@
>>   #include<sys/wait.h>
>>   #include<sys/ioctl.h>
>>   #include<sys/un.h>
>> +#include<byteswap.h>
>>
>>
>>   #include "qemu_driver.h"
>> @@ -1881,13 +1882,22 @@ VIR_ENUM_IMPL(qemudSaveCompression, QEMU
>>
>>   struct qemud_save_header {
>>       char magic[sizeof(QEMUD_SAVE_MAGIC)-1];
>> -    int version;
>> -    int xml_len;
>> -    int was_running;
>> -    int compressed;
>> -    int unused[15];
>> +    uint32_t version;
>> +    uint32_t xml_len;
>> +    uint32_t was_running;
>> +    uint32_t compressed;
>> +    uint32_t unused[15];
>>   };
>>
>> +static inline void
>> +bswap_header(struct qemud_save_header *hdr) {
>> +    hdr->version = bswap_32(hdr->version);
>> +    hdr->xml_len = bswap_32(hdr->xml_len);
>> +    hdr->was_running = bswap_32(hdr->was_running);
>> +    hdr->compressed = bswap_32(hdr->compressed);
>> +}
>> +
>> +
>>   /* return -errno on failure, or 0 on success */
>>   static int
>>   qemuDomainSaveHeader(int fd, const char *path, char *xml,
>> @@ -3097,6 +3107,11 @@ qemuDomainSaveImageOpen(struct qemud_dri
>>       }
>>
>>       if (header.version>  QEMUD_SAVE_VERSION) {
>> +        /* convert endianess and try again */
>> +        bswap_header(&header);
>> +    }
>    Hum, isn't there a more reliable way to detect the change of
> endianness ? That's a bit fishy IMHO :-)
The problem is that the header should not have been written in a hosts' 
native format. So what can go wrong? QEMUD_SAVE_VERSION is '2'. Either 
we find 1 or 2 here and go ahead and accept it 'as-is'. Otherwise 
anything bigger than 3 is not accepted and swapped. 3 then becomes 0x03 
00 00 00 and is discarded. 0x 02 00 00 00 would be swapped to '2' and 
accepted.

    Stefan
>> +    if (header.version>  QEMUD_SAVE_VERSION) {
>>           qemuReportError(VIR_ERR_OPERATION_FAILED,
>>                           _("image version is not supported (%d>  %d)"),
>>                           header.version, QEMUD_SAVE_VERSION);
> Daniel
>




More information about the libvir-list mailing list