mirror of https://github.com/xqemu/xqemu.git
migration: handle EAGAIN while reading QEMUFile
This will never happen right now (the assertion would fail). The next patch will set the socket or pipe in non-blocking mode, thus enabling this part of the code. Coroutines can just stop whenever they want with qemu_coroutine_yield. As soon as select tells the main loop that the migration stream is readable, the coroutine is re-entered directly in qemu_get_buffer, where it will read more data and pass it to the loading routines. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
1c12e1f5b2
commit
595ab64169
30
savevm.c
30
savevm.c
|
@ -200,13 +200,22 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||||
QEMUFileSocket *s = opaque;
|
QEMUFileSocket *s = opaque;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
do {
|
for (;;) {
|
||||||
len = qemu_recv(s->fd, buf, size, 0);
|
len = qemu_recv(s->fd, buf, size, 0);
|
||||||
} while (len == -1 && socket_error() == EINTR);
|
if (len != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (socket_error() == EAGAIN) {
|
||||||
|
assert(qemu_in_coroutine());
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
} else if (socket_error() != EINTR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (len == -1)
|
if (len == -1) {
|
||||||
len = -socket_error();
|
len = -socket_error();
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,10 +246,19 @@ static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
|
||||||
FILE *fp = s->stdio_file;
|
FILE *fp = s->stdio_file;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
do {
|
for (;;) {
|
||||||
clearerr(fp);
|
clearerr(fp);
|
||||||
bytes = fread(buf, 1, size, fp);
|
bytes = fread(buf, 1, size, fp);
|
||||||
} while ((bytes == 0) && ferror(fp) && (errno == EINTR));
|
if (bytes != 0 || !ferror(fp)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
assert(qemu_in_coroutine());
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
} else if (errno != EINTR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue