#include "qemu-common.h"
#include "hw/hw.h"
#include "hw/qdev.h"
-#include "net.h"
-#include "monitor.h"
-#include "sysemu.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
+#include "net/net.h"
+#include "monitor/monitor.h"
+#include "sysemu/sysemu.h"
+#include "qemu/timer.h"
#include "audio/audio.h"
-#include "migration.h"
-#include "qemu_socket.h"
-#include "qemu-queue.h"
-#include "qemu-timer.h"
-#include "cpus.h"
-#include "memory.h"
+#include "migration/migration.h"
+#include "qemu/sockets.h"
+#include "qemu/queue.h"
+#include "qemu/timer.h"
+#include "sysemu/cpus.h"
+#include "exec/memory.h"
#include "qmp-commands.h"
#include "trace.h"
-#include "bitops.h"
+#include "qemu/bitops.h"
#define SELF_ANNOUNCE_ROUNDS 5
QEMUFile *file;
} QEMUFileSocket;
+static int socket_get_fd(void *opaque)
+{
+ QEMUFileSocket *s = opaque;
+
+ return s->fd;
+}
+
static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
QEMUFileSocket *s = opaque;
ssize_t len;
- do {
+ for (;;) {
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();
-
+ }
return len;
}
static int socket_close(void *opaque)
{
QEMUFileSocket *s = opaque;
+ closesocket(s->fd);
g_free(s);
return 0;
}
+static int stdio_get_fd(void *opaque)
+{
+ QEMUFileStdio *s = opaque;
+
+ return fileno(s->stdio_file);
+}
+
static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
{
QEMUFileStdio *s = opaque;
FILE *fp = s->stdio_file;
int bytes;
- do {
+ for (;;) {
clearerr(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;
}
}
static const QEMUFileOps stdio_pipe_read_ops = {
+ .get_fd = stdio_get_fd,
.get_buffer = stdio_get_buffer,
.close = stdio_pclose
};
static const QEMUFileOps stdio_pipe_write_ops = {
+ .get_fd = stdio_get_fd,
.put_buffer = stdio_put_buffer,
.close = stdio_pclose
};
return qemu_popen(popen_file, mode);
}
-int qemu_stdio_fd(QEMUFile *f)
-{
- QEMUFileStdio *p;
- int fd;
-
- p = (QEMUFileStdio *)f->opaque;
- fd = fileno(p->stdio_file);
-
- return fd;
-}
-
static const QEMUFileOps stdio_file_read_ops = {
+ .get_fd = stdio_get_fd,
.get_buffer = stdio_get_buffer,
.close = stdio_fclose
};
static const QEMUFileOps stdio_file_write_ops = {
+ .get_fd = stdio_get_fd,
.put_buffer = stdio_put_buffer,
.close = stdio_fclose
};
}
static const QEMUFileOps socket_read_ops = {
+ .get_fd = socket_get_fd,
.get_buffer = socket_get_buffer,
.close = socket_close
};
qemu_file_set_error(f, len);
}
+int qemu_get_fd(QEMUFile *f)
+{
+ if (f->ops->get_fd) {
+ return f->ops->get_fd(f->opaque);
+ }
+ return -1;
+}
+
/** Closes the file
*
* Returns negative error value if any error happened on previous operations or
return ret;
}
-int qemu_file_put_notify(QEMUFile *f)
-{
- return f->ops->put_buffer(f->opaque, NULL, 0, 0);
-}
-
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
{
int l;
return qemu_file_get_error(f);
}
+uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size)
+{
+ SaveStateEntry *se;
+ uint64_t ret = 0;
+
+ QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+ if (!se->ops || !se->ops->save_live_pending) {
+ continue;
+ }
+ if (se->ops && se->ops->is_active) {
+ if (!se->ops->is_active(se->opaque)) {
+ continue;
+ }
+ }
+ ret += se->ops->save_live_pending(f, se->opaque, max_size);
+ }
+ return ret;
+}
+
void qemu_savevm_state_cancel(QEMUFile *f)
{
SaveStateEntry *se;