mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-19 08:02:15 -06:00
migration/multifd: Split packet into header and RAM data
Read packet header first so in the future we will be able to differentiate between a RAM multifd packet and a device state multifd packet. Since these two are of different size we can't read the packet body until we know which packet type it is. Reviewed-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com> Link: https://lore.kernel.org/qemu-devel/832ad055fe447561ac1ad565d61658660cb3f63f.1741124640.git.maciej.szmigiero@oracle.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
b1937fd1eb
commit
8050c435b7
2 changed files with 49 additions and 11 deletions
|
@ -209,10 +209,10 @@ void multifd_send_fill_packet(MultiFDSendParams *p)
|
||||||
|
|
||||||
memset(packet, 0, p->packet_len);
|
memset(packet, 0, p->packet_len);
|
||||||
|
|
||||||
packet->magic = cpu_to_be32(MULTIFD_MAGIC);
|
packet->hdr.magic = cpu_to_be32(MULTIFD_MAGIC);
|
||||||
packet->version = cpu_to_be32(MULTIFD_VERSION);
|
packet->hdr.version = cpu_to_be32(MULTIFD_VERSION);
|
||||||
|
|
||||||
packet->flags = cpu_to_be32(p->flags);
|
packet->hdr.flags = cpu_to_be32(p->flags);
|
||||||
packet->next_packet_size = cpu_to_be32(p->next_packet_size);
|
packet->next_packet_size = cpu_to_be32(p->next_packet_size);
|
||||||
|
|
||||||
packet_num = qatomic_fetch_inc(&multifd_send_state->packet_num);
|
packet_num = qatomic_fetch_inc(&multifd_send_state->packet_num);
|
||||||
|
@ -228,12 +228,12 @@ void multifd_send_fill_packet(MultiFDSendParams *p)
|
||||||
p->flags, p->next_packet_size);
|
p->flags, p->next_packet_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
static int multifd_recv_unfill_packet_header(MultiFDRecvParams *p,
|
||||||
|
const MultiFDPacketHdr_t *hdr,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
const MultiFDPacket_t *packet = p->packet;
|
uint32_t magic = be32_to_cpu(hdr->magic);
|
||||||
uint32_t magic = be32_to_cpu(packet->magic);
|
uint32_t version = be32_to_cpu(hdr->version);
|
||||||
uint32_t version = be32_to_cpu(packet->version);
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (magic != MULTIFD_MAGIC) {
|
if (magic != MULTIFD_MAGIC) {
|
||||||
error_setg(errp, "multifd: received packet magic %x, expected %x",
|
error_setg(errp, "multifd: received packet magic %x, expected %x",
|
||||||
|
@ -247,7 +247,16 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->flags = be32_to_cpu(packet->flags);
|
p->flags = be32_to_cpu(hdr->flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
|
||||||
|
{
|
||||||
|
const MultiFDPacket_t *packet = p->packet;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
p->next_packet_size = be32_to_cpu(packet->next_packet_size);
|
p->next_packet_size = be32_to_cpu(packet->next_packet_size);
|
||||||
p->packet_num = be64_to_cpu(packet->packet_num);
|
p->packet_num = be64_to_cpu(packet->packet_num);
|
||||||
p->packets_recved++;
|
p->packets_recved++;
|
||||||
|
@ -1165,14 +1174,18 @@ static void *multifd_recv_thread(void *opaque)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
MultiFDPacketHdr_t hdr;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
bool has_data = false;
|
bool has_data = false;
|
||||||
|
uint8_t *pkt_buf;
|
||||||
|
size_t pkt_len;
|
||||||
|
|
||||||
p->normal_num = 0;
|
p->normal_num = 0;
|
||||||
|
|
||||||
if (use_packets) {
|
if (use_packets) {
|
||||||
struct iovec iov = {
|
struct iovec iov = {
|
||||||
.iov_base = (void *)p->packet,
|
.iov_base = (void *)&hdr,
|
||||||
.iov_len = p->packet_len
|
.iov_len = sizeof(hdr)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (multifd_recv_should_exit()) {
|
if (multifd_recv_should_exit()) {
|
||||||
|
@ -1191,6 +1204,26 @@ static void *multifd_recv_thread(void *opaque)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = multifd_recv_unfill_packet_header(p, &hdr, &local_err);
|
||||||
|
if (ret) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt_buf = (uint8_t *)p->packet + sizeof(hdr);
|
||||||
|
pkt_len = p->packet_len - sizeof(hdr);
|
||||||
|
|
||||||
|
ret = qio_channel_read_all_eof(p->c, (char *)pkt_buf, pkt_len,
|
||||||
|
&local_err);
|
||||||
|
if (!ret) {
|
||||||
|
/* EOF */
|
||||||
|
error_setg(&local_err, "multifd: unexpected EOF after packet header");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_mutex_lock(&p->mutex);
|
qemu_mutex_lock(&p->mutex);
|
||||||
ret = multifd_recv_unfill_packet(p, &local_err);
|
ret = multifd_recv_unfill_packet(p, &local_err);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -69,6 +69,11 @@ typedef struct {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
} __attribute__((packed)) MultiFDPacketHdr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MultiFDPacketHdr_t hdr;
|
||||||
|
|
||||||
/* maximum number of allocated pages */
|
/* maximum number of allocated pages */
|
||||||
uint32_t pages_alloc;
|
uint32_t pages_alloc;
|
||||||
/* non zero pages */
|
/* non zero pages */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue