From: ya su <suya94335@gmail.com>
To: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
Cc: kwolf@redhat.com, aliguori@us.ibm.com, dlaor@redhat.com,
ananth@in.ibm.com, kvm@vger.kernel.org, mst@redhat.com,
mtosatti@redhat.com, qemu-devel@nongnu.org,
vatsa@linux.vnet.ibm.com, blauwirbel@gmail.com,
ohmura.kei@lab.ntt.co.jp, avi@redhat.com, pbonzini@redhat.com,
psuriset@linux.vnet.ibm.com, stefanha@linux.vnet.ibm.com
Subject: [Qemu-devel] Re: [PATCH 07/18] Introduce fault tolerant VM transaction QEMUFile and ft_mode.
Date: Mon, 21 Feb 2011 12:46:09 +0800 [thread overview]
Message-ID: <AANLkTimrBRkqB9_Sjutf0bK6ZQOFupRB3drn4zGgkG0G@mail.gmail.com> (raw)
In-Reply-To: <1297330258-20494-8-git-send-email-tamura.yoshiaki@lab.ntt.co.jp>
[-- Attachment #1: Type: text/plain, Size: 23415 bytes --]
Yoshiaki:
I have one question about ram_save_live, during migration 3
stage(completation stage), it will call
cpu_physical_memory_set_dirty_tracking(0) to stop recording ram dirty pages.
at the end of migrate_ft_trans_connect function, it will invoke vm_start(),
at this time, cpu_physical_memory_set_dirty_tracking(1) is not called yet,
so there may have some ram pages not recorded when qemu_savevm_trans_begin
is called. I think you need calll
cpu_physical_memory_set_dirty_tracking(1) in migrate_ft_trans_connect
function, Am I right?
BR
Green.
2011/2/10 Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
> This code implements VM transaction protocol. Like buffered_file, it
> sits between savevm and migration layer. With this architecture, VM
> transaction protocol is implemented mostly independent from other
> existing code.
>
> Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
> Signed-off-by: OHMURA Kei <ohmura.kei@lab.ntt.co.jp>
> ---
> Makefile.objs | 1 +
> ft_trans_file.c | 624
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ft_trans_file.h | 72 +++++++
> migration.c | 3 +
> trace-events | 15 ++
> 5 files changed, 715 insertions(+), 0 deletions(-)
> create mode 100644 ft_trans_file.c
> create mode 100644 ft_trans_file.h
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 353b1a8..04148b5 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -100,6 +100,7 @@ common-obj-y += msmouse.o ps2.o
> common-obj-y += qdev.o qdev-properties.o
> common-obj-y += block-migration.o
> common-obj-y += pflib.o
> +common-obj-y += ft_trans_file.o
>
> common-obj-$(CONFIG_BRLAPI) += baum.o
> common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o
> migration-fd.o
> diff --git a/ft_trans_file.c b/ft_trans_file.c
> new file mode 100644
> index 0000000..2b42b95
> --- /dev/null
> +++ b/ft_trans_file.c
> @@ -0,0 +1,624 @@
> +/*
> + * Fault tolerant VM transaction QEMUFile
> + *
> + * Copyright (c) 2010 Nippon Telegraph and Telephone Corporation.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + * This source code is based on buffered_file.c.
> + * Copyright IBM, Corp. 2008
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + */
> +
> +#include "qemu-common.h"
> +#include "qemu-error.h"
> +#include "hw/hw.h"
> +#include "qemu-timer.h"
> +#include "sysemu.h"
> +#include "qemu-char.h"
> +#include "trace.h"
> +#include "ft_trans_file.h"
> +
> +typedef struct FtTransHdr
> +{
> + uint16_t cmd;
> + uint16_t id;
> + uint32_t seq;
> + uint32_t payload_len;
> +} FtTransHdr;
> +
> +typedef struct QEMUFileFtTrans
> +{
> + FtTransPutBufferFunc *put_buffer;
> + FtTransGetBufferFunc *get_buffer;
> + FtTransPutReadyFunc *put_ready;
> + FtTransGetReadyFunc *get_ready;
> + FtTransWaitForUnfreezeFunc *wait_for_unfreeze;
> + FtTransCloseFunc *close;
> + void *opaque;
> + QEMUFile *file;
> +
> + enum QEMU_VM_TRANSACTION_STATE state;
> + uint32_t seq;
> + uint16_t id;
> +
> + int has_error;
> +
> + bool freeze_output;
> + bool freeze_input;
> + bool rate_limit;
> + bool is_sender;
> + bool is_payload;
> +
> + uint8_t *buf;
> + size_t buf_max_size;
> + size_t put_offset;
> + size_t get_offset;
> +
> + FtTransHdr header;
> + size_t header_offset;
> +} QEMUFileFtTrans;
> +
> +#define IO_BUF_SIZE 32768
> +
> +static void ft_trans_append(QEMUFileFtTrans *s,
> + const uint8_t *buf, size_t size)
> +{
> + if (size > (s->buf_max_size - s->put_offset)) {
> + trace_ft_trans_realloc(s->buf_max_size, size + 1024);
> + s->buf_max_size += size + 1024;
> + s->buf = qemu_realloc(s->buf, s->buf_max_size);
> + }
> +
> + trace_ft_trans_append(size);
> + memcpy(s->buf + s->put_offset, buf, size);
> + s->put_offset += size;
> +}
> +
> +static void ft_trans_flush(QEMUFileFtTrans *s)
> +{
> + size_t offset = 0;
> +
> + if (s->has_error) {
> + error_report("flush when error %d, bailing", s->has_error);
> + return;
> + }
> +
> + while (offset < s->put_offset) {
> + ssize_t ret;
> +
> + ret = s->put_buffer(s->opaque, s->buf + offset, s->put_offset -
> offset);
> + if (ret == -EAGAIN) {
> + break;
> + }
> +
> + if (ret <= 0) {
> + error_report("error flushing data, %s", strerror(errno));
> + s->has_error = FT_TRANS_ERR_FLUSH;
> + break;
> + } else {
> + offset += ret;
> + }
> + }
> +
> + trace_ft_trans_flush(offset, s->put_offset);
> + memmove(s->buf, s->buf + offset, s->put_offset - offset);
> + s->put_offset -= offset;
> + s->freeze_output = !!s->put_offset;
> +}
> +
> +static ssize_t ft_trans_put(void *opaque, void *buf, int size)
> +{
> + QEMUFileFtTrans *s = opaque;
> + size_t offset = 0;
> + ssize_t len;
> +
> + /* flush buffered data before putting next */
> + if (s->put_offset) {
> + ft_trans_flush(s);
> + }
> +
> + while (!s->freeze_output && offset < size) {
> + len = s->put_buffer(s->opaque, (uint8_t *)buf + offset, size -
> offset);
> +
> + if (len == -EAGAIN) {
> + trace_ft_trans_freeze_output();
> + s->freeze_output = 1;
> + break;
> + }
> +
> + if (len <= 0) {
> + error_report("putting data failed, %s", strerror(errno));
> + s->has_error = 1;
> + offset = -EINVAL;
> + break;
> + }
> +
> + offset += len;
> + }
> +
> + if (s->freeze_output) {
> + ft_trans_append(s, buf + offset, size - offset);
> + offset = size;
> + }
> +
> + return offset;
> +}
> +
> +static int ft_trans_send_header(QEMUFileFtTrans *s,
> + enum QEMU_VM_TRANSACTION_STATE state,
> + uint32_t payload_len)
> +{
> + int ret;
> + FtTransHdr *hdr = &s->header;
> +
> + trace_ft_trans_send_header(state);
> +
> + hdr->cmd = s->state = state;
> + hdr->id = s->id;
> + hdr->seq = s->seq;
> + hdr->payload_len = payload_len;
> +
> + ret = ft_trans_put(s, hdr, sizeof(*hdr));
> + if (ret < 0) {
> + error_report("send header failed");
> + s->has_error = FT_TRANS_ERR_SEND_HDR;
> + }
> +
> + return ret;
> +}
> +
> +static int ft_trans_put_buffer(void *opaque, const uint8_t *buf, int64_t
> pos, int size)
> +{
> + QEMUFileFtTrans *s = opaque;
> + ssize_t ret;
> +
> + trace_ft_trans_put_buffer(size, pos);
> +
> + if (s->has_error) {
> + error_report("put_buffer when error %d, bailing", s->has_error);
> + return -EINVAL;
> + }
> +
> + /* assuming qemu_file_put_notify() is calling */
> + if (pos == 0 && size == 0) {
> + trace_ft_trans_put_ready();
> + ft_trans_flush(s);
> +
> + if (!s->freeze_output) {
> + trace_ft_trans_cb(s->put_ready);
> + ret = s->put_ready();
> + }
> +
> + ret = 0;
> + goto out;
> + }
> +
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_CONTINUE, size);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + ret = ft_trans_put(s, (uint8_t *)buf, size);
> + if (ret < 0) {
> + error_report("send palyload failed");
> + s->has_error = FT_TRANS_ERR_SEND_PAYLOAD;
> + goto out;
> + }
> +
> + s->seq++;
> +
> +out:
> + return ret;
> +}
> +
> +static int ft_trans_fill_buffer(void *opaque, void *buf, int size)
> +{
> + QEMUFileFtTrans *s = opaque;
> + size_t offset = 0;
> + ssize_t len;
> +
> + s->freeze_input = 0;
> +
> + while (offset < size) {
> + len = s->get_buffer(s->opaque, (uint8_t *)buf + offset,
> + 0, size - offset);
> + if (len == -EAGAIN) {
> + trace_ft_trans_freeze_input();
> + s->freeze_input = 1;
> + break;
> + }
> +
> + if (len <= 0) {
> + error_report("fill buffer failed, %s", strerror(errno));
> + s->has_error = 1;
> + return -EINVAL;
> + }
> +
> + offset += len;
> + }
> +
> + return offset;
> +}
> +
> +static int ft_trans_recv_header(QEMUFileFtTrans *s)
> +{
> + int ret;
> + char *buf = (char *)&s->header + s->header_offset;
> +
> + ret = ft_trans_fill_buffer(s, buf, sizeof(FtTransHdr) -
> s->header_offset);
> + if (ret < 0) {
> + error_report("recv header failed");
> + s->has_error = FT_TRANS_ERR_RECV_HDR;
> + goto out;
> + }
> +
> + s->header_offset += ret;
> + if (s->header_offset == sizeof(FtTransHdr)) {
> + trace_ft_trans_recv_header(s->header.cmd);
> + s->state = s->header.cmd;
> + s->header_offset = 0;
> +
> + if (!s->is_sender) {
> + s->id = s->header.id;
> + s->seq = s->header.seq;
> + }
> + }
> +
> +out:
> + return ret;
> +}
> +
> +static int ft_trans_recv_payload(QEMUFileFtTrans *s)
> +{
> + QEMUFile *f = s->file;
> + int ret = -1;
> +
> + /* extend QEMUFile buf if there weren't enough space */
> + if (s->header.payload_len > (s->buf_max_size - s->get_offset)) {
> + s->buf_max_size += (s->header.payload_len -
> + (s->buf_max_size - s->get_offset));
> + s->buf = qemu_realloc_buffer(f, s->buf_max_size);
> + }
> +
> + ret = ft_trans_fill_buffer(s, s->buf + s->get_offset,
> + s->header.payload_len);
> + if (ret < 0) {
> + error_report("recv payload failed");
> + s->has_error = FT_TRANS_ERR_RECV_PAYLOAD;
> + goto out;
> + }
> +
> + trace_ft_trans_recv_payload(ret, s->header.payload_len,
> s->get_offset);
> +
> + s->header.payload_len -= ret;
> + s->get_offset += ret;
> + s->is_payload = !!s->header.payload_len;
> +
> +out:
> + return ret;
> +}
> +
> +static int ft_trans_recv(QEMUFileFtTrans *s)
> +{
> + int ret;
> +
> + /* get payload and return */
> + if (s->is_payload) {
> + ret = ft_trans_recv_payload(s);
> + goto out;
> + }
> +
> + ret = ft_trans_recv_header(s);
> + if (ret < 0 || s->freeze_input) {
> + goto out;
> + }
> +
> + switch (s->state) {
> + case QEMU_VM_TRANSACTION_BEGIN:
> + /* CONTINUE or COMMIT should come shortly */
> + s->is_payload = 0;
> + break;
> +
> + case QEMU_VM_TRANSACTION_CONTINUE:
> + /* get payload */
> + s->is_payload = 1;
> + break;
> +
> + case QEMU_VM_TRANSACTION_COMMIT:
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_ACK, 0);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + trace_ft_trans_cb(s->get_ready);
> + ret = s->get_ready(s->opaque);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + qemu_clear_buffer(s->file);
> + s->get_offset = 0;
> + s->is_payload = 0;
> +
> + break;
> +
> + case QEMU_VM_TRANSACTION_ATOMIC:
> + /* not implemented yet */
> + error_report("QEMU_VM_TRANSACTION_ATOMIC not implemented. %d",
> + ret);
> + break;
> +
> + case QEMU_VM_TRANSACTION_CANCEL:
> + /* return -EINVAL until migrate cancel on recevier side is
> supported */
> + ret = -EINVAL;
> + break;
> +
> + default:
> + error_report("unknown QEMU_VM_TRANSACTION_STATE %d", ret);
> + s->has_error = FT_TRANS_ERR_STATE_INVALID;
> + ret = -EINVAL;
> + }
> +
> +out:
> + return ret;
> +}
> +
> +static int ft_trans_get_buffer(void *opaque, uint8_t *buf,
> + int64_t pos, int size)
> +{
> + QEMUFileFtTrans *s = opaque;
> + int ret;
> +
> + if (s->has_error) {
> + error_report("get_buffer when error %d, bailing", s->has_error);
> + return -EINVAL;
> + }
> +
> + /* assuming qemu_file_get_notify() is calling */
> + if (pos == 0 && size == 0) {
> + trace_ft_trans_get_ready();
> + s->freeze_input = 0;
> +
> + /* sender should be waiting for ACK */
> + if (s->is_sender) {
> + ret = ft_trans_recv_header(s);
> + if (s->freeze_input) {
> + ret = 0;
> + goto out;
> + }
> + if (ret < 0) {
> + error_report("recv ack failed");
> + goto out;
> + }
> +
> + if (s->state != QEMU_VM_TRANSACTION_ACK) {
> + error_report("recv invalid state %d", s->state);
> + s->has_error = FT_TRANS_ERR_STATE_INVALID;
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + trace_ft_trans_cb(s->get_ready);
> + ret = s->get_ready(s->opaque);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + /* proceed trans id */
> + s->id++;
> +
> + return 0;
> + }
> +
> + /* set QEMUFile buf at beginning */
> + if (!s->buf) {
> + s->buf = buf;
> + }
> +
> + ret = ft_trans_recv(s);
> + goto out;
> + }
> +
> + ret = s->get_offset;
> +
> +out:
> + return ret;
> +}
> +
> +static int ft_trans_close(void *opaque)
> +{
> + QEMUFileFtTrans *s = opaque;
> + int ret;
> +
> + trace_ft_trans_close();
> + ret = s->close(s->opaque);
> + if (s->is_sender) {
> + qemu_free(s->buf);
> + }
> + qemu_free(s);
> +
> + return ret;
> +}
> +
> +static int ft_trans_rate_limit(void *opaque)
> +{
> + QEMUFileFtTrans *s = opaque;
> +
> + if (s->has_error) {
> + return 0;
> + }
> +
> + if (s->rate_limit && s->freeze_output) {
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int64_t ft_trans_set_rate_limit(void *opaque, int64_t new_rate)
> +{
> + QEMUFileFtTrans *s = opaque;
> +
> + if (s->has_error) {
> + goto out;
> + }
> +
> + s->rate_limit = !!new_rate;
> +
> +out:
> + return s->rate_limit;
> +}
> +
> +int ft_trans_begin(void *opaque)
> +{
> + QEMUFileFtTrans *s = opaque;
> + int ret;
> + s->seq = 0;
> +
> + /* receiver sends QEMU_VM_TRANSACTION_ACK to start transaction */
> + if (!s->is_sender) {
> + if (s->state != QEMU_VM_TRANSACTION_INIT) {
> + error_report("invalid state %d", s->state);
> + s->has_error = FT_TRANS_ERR_STATE_INVALID;
> + ret = -EINVAL;
> + }
> +
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_ACK, 0);
> + goto out;
> + }
> +
> + /* sender waits for QEMU_VM_TRANSACTION_ACK to start transaction */
> + if (s->state == QEMU_VM_TRANSACTION_INIT) {
> +retry:
> + ret = ft_trans_recv_header(s);
> + if (s->freeze_input) {
> + goto retry;
> + }
> + if (ret < 0) {
> + error_report("recv ack failed");
> + goto out;
> + }
> +
> + if (s->state != QEMU_VM_TRANSACTION_ACK) {
> + error_report("recv invalid state %d", s->state);
> + s->has_error = FT_TRANS_ERR_STATE_INVALID;
> + ret = -EINVAL;
> + goto out;
> + }
> + }
> +
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_BEGIN, 0);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + s->state = QEMU_VM_TRANSACTION_CONTINUE;
> +
> +out:
> + return ret;
> +}
> +
> +int ft_trans_commit(void *opaque)
> +{
> + QEMUFileFtTrans *s = opaque;
> + int ret;
> +
> + if (!s->is_sender) {
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_ACK, 0);
> + goto out;
> + }
> +
> + /* sender should flush buf before sending COMMIT */
> + qemu_fflush(s->file);
> +
> + ret = ft_trans_send_header(s, QEMU_VM_TRANSACTION_COMMIT, 0);
> + if (ret < 0) {
> + goto out;
> + }
> +
> + while (!s->has_error && s->put_offset) {
> + ft_trans_flush(s);
> + if (s->freeze_output) {
> + s->wait_for_unfreeze(s);
> + }
> + }
> +
> + if (s->has_error) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + ret = ft_trans_recv_header(s);
> + if (s->freeze_input) {
> + ret = -EAGAIN;
> + goto out;
> + }
> + if (ret < 0) {
> + error_report("recv ack failed");
> + goto out;
> + }
> +
> + if (s->state != QEMU_VM_TRANSACTION_ACK) {
> + error_report("recv invalid state %d", s->state);
> + s->has_error = FT_TRANS_ERR_STATE_INVALID;
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + s->id++;
> + ret = 0;
> +
> +out:
> + return ret;
> +}
> +
> +int ft_trans_cancel(void *opaque)
> +{
> + QEMUFileFtTrans *s = opaque;
> +
> + /* invalid until migrate cancel on recevier side is supported */
> + if (!s->is_sender) {
> + return -EINVAL;
> + }
> +
> + return ft_trans_send_header(s, QEMU_VM_TRANSACTION_CANCEL, 0);
> +}
> +
> +QEMUFile *qemu_fopen_ops_ft_trans(void *opaque,
> + FtTransPutBufferFunc *put_buffer,
> + FtTransGetBufferFunc *get_buffer,
> + FtTransPutReadyFunc *put_ready,
> + FtTransGetReadyFunc *get_ready,
> + FtTransWaitForUnfreezeFunc
> *wait_for_unfreeze,
> + FtTransCloseFunc *close,
> + bool is_sender)
> +{
> + QEMUFileFtTrans *s;
> +
> + s = qemu_mallocz(sizeof(*s));
> +
> + s->opaque = opaque;
> + s->put_buffer = put_buffer;
> + s->get_buffer = get_buffer;
> + s->put_ready = put_ready;
> + s->get_ready = get_ready;
> + s->wait_for_unfreeze = wait_for_unfreeze;
> + s->close = close;
> + s->is_sender = is_sender;
> + s->id = 0;
> + s->seq = 0;
> + s->rate_limit = 1;
> +
> + if (!s->is_sender) {
> + s->buf_max_size = IO_BUF_SIZE;
> + }
> +
> + s->file = qemu_fopen_ops(s, ft_trans_put_buffer, ft_trans_get_buffer,
> + ft_trans_close, ft_trans_rate_limit,
> + ft_trans_set_rate_limit, NULL);
> +
> + return s->file;
> +}
> diff --git a/ft_trans_file.h b/ft_trans_file.h
> new file mode 100644
> index 0000000..5ca6b53
> --- /dev/null
> +++ b/ft_trans_file.h
> @@ -0,0 +1,72 @@
> +/*
> + * Fault tolerant VM transaction QEMUFile
> + *
> + * Copyright (c) 2010 Nippon Telegraph and Telephone Corporation.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + * This source code is based on buffered_file.h.
> + * Copyright IBM, Corp. 2008
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + */
> +
> +#ifndef QEMU_FT_TRANSACTION_FILE_H
> +#define QEMU_FT_TRANSACTION_FILE_H
> +
> +#include "hw/hw.h"
> +
> +enum QEMU_VM_TRANSACTION_STATE {
> + QEMU_VM_TRANSACTION_NACK = -1,
> + QEMU_VM_TRANSACTION_INIT,
> + QEMU_VM_TRANSACTION_BEGIN,
> + QEMU_VM_TRANSACTION_CONTINUE,
> + QEMU_VM_TRANSACTION_COMMIT,
> + QEMU_VM_TRANSACTION_CANCEL,
> + QEMU_VM_TRANSACTION_ATOMIC,
> + QEMU_VM_TRANSACTION_ACK,
> +};
> +
> +enum FT_MODE {
> + FT_ERROR = -1,
> + FT_OFF,
> + FT_INIT,
> + FT_TRANSACTION_BEGIN,
> + FT_TRANSACTION_ITER,
> + FT_TRANSACTION_COMMIT,
> + FT_TRANSACTION_ATOMIC,
> + FT_TRANSACTION_RECV,
> +};
> +extern enum FT_MODE ft_mode;
> +
> +#define FT_TRANS_ERR_UNKNOWN 0x01 /* Unknown error */
> +#define FT_TRANS_ERR_SEND_HDR 0x02 /* Send header failed */
> +#define FT_TRANS_ERR_RECV_HDR 0x03 /* Recv header failed */
> +#define FT_TRANS_ERR_SEND_PAYLOAD 0x04 /* Send payload failed */
> +#define FT_TRANS_ERR_RECV_PAYLOAD 0x05 /* Recv payload failed */
> +#define FT_TRANS_ERR_FLUSH 0x06 /* Flush buffered data failed */
> +#define FT_TRANS_ERR_STATE_INVALID 0x07 /* Invalid state */
> +
> +typedef ssize_t (FtTransPutBufferFunc)(void *opaque, const void *data,
> size_t size);
> +typedef int (FtTransGetBufferFunc)(void *opaque, uint8_t *buf, int64_t
> pos, size_t size);
> +typedef ssize_t (FtTransPutVectorFunc)(void *opaque, const struct iovec
> *iov, int iovcnt);
> +typedef int (FtTransPutReadyFunc)(void);
> +typedef int (FtTransGetReadyFunc)(void *opaque);
> +typedef void (FtTransWaitForUnfreezeFunc)(void *opaque);
> +typedef int (FtTransCloseFunc)(void *opaque);
> +
> +int ft_trans_begin(void *opaque);
> +int ft_trans_commit(void *opaque);
> +int ft_trans_cancel(void *opaque);
> +
> +QEMUFile *qemu_fopen_ops_ft_trans(void *opaque,
> + FtTransPutBufferFunc *put_buffer,
> + FtTransGetBufferFunc *get_buffer,
> + FtTransPutReadyFunc *put_ready,
> + FtTransGetReadyFunc *get_ready,
> + FtTransWaitForUnfreezeFunc
> *wait_for_unfreeze,
> + FtTransCloseFunc *close,
> + bool is_sender);
> +
> +#endif
> diff --git a/migration.c b/migration.c
> index dd3bf94..c5e0146 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -15,6 +15,7 @@
> #include "migration.h"
> #include "monitor.h"
> #include "buffered_file.h"
> +#include "ft_trans_file.h"
> #include "sysemu.h"
> #include "block.h"
> #include "qemu_socket.h"
> @@ -31,6 +32,8 @@
> do { } while (0)
> #endif
>
> +enum FT_MODE ft_mode = FT_OFF;
> +
> /* Migration speed throttling */
> static int64_t max_throttle = (32 << 20);
>
> diff --git a/trace-events b/trace-events
> index e6138ea..50ac840 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -254,3 +254,18 @@ disable spice_vmc_write(ssize_t out, int len) "spice
> wrottn %lu of requested %zd
> disable spice_vmc_read(int bytes, int len) "spice read %lu of requested
> %zd"
> disable spice_vmc_register_interface(void *scd) "spice vmc registered
> interface %p"
> disable spice_vmc_unregister_interface(void *scd) "spice vmc unregistered
> interface %p"
> +
> +# ft_trans_file.c
> +disable ft_trans_realloc(size_t old_size, size_t new_size) "increasing
> buffer from %zu by %zu"
> +disable ft_trans_append(size_t size) "buffering %zu bytes"
> +disable ft_trans_flush(size_t size, size_t req) "flushed %zu of %zu bytes"
> +disable ft_trans_send_header(uint16_t cmd) "send header %d"
> +disable ft_trans_recv_header(uint16_t cmd) "recv header %d"
> +disable ft_trans_put_buffer(size_t size, int64_t pos) "putting %d bytes at
> %"PRId64""
> +disable ft_trans_recv_payload(size_t len, uint32_t hdr, size_t total)
> "recv %d of %d total %d"
> +disable ft_trans_close(void) "closing"
> +disable ft_trans_freeze_output(void) "backend not ready, freezing output"
> +disable ft_trans_freeze_input(void) "backend not ready, freezing input"
> +disable ft_trans_put_ready(void) "file is ready to put"
> +disable ft_trans_get_ready(void) "file is ready to get"
> +disable ft_trans_cb(void *cb) "callback %p"
> --
> 1.7.1.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
[-- Attachment #2: Type: text/html, Size: 27588 bytes --]
next prev parent reply other threads:[~2011-02-21 4:46 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-10 9:30 [Qemu-devel] [PATCH 00/18] Kemari for KVM v0.2.10 Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 01/18] Make QEMUFile buf expandable, and introduce qemu_realloc_buffer() and qemu_clear_buffer() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 02/18] Introduce read() to FdMigrationState Yoshiaki Tamura
2011-02-10 9:54 ` Anthony Liguori
2011-02-10 10:00 ` Yoshiaki Tamura
2011-02-10 10:18 ` Daniel P. Berrange
2011-02-10 10:23 ` Yoshiaki Tamura
2011-02-10 10:44 ` Daniel P. Berrange
2011-02-10 10:51 ` Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 03/18] Introduce skip_header parameter to qemu_loadvm_state() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 04/18] qemu-char: export socket_set_nodelay() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 05/18] vl.c: add deleted flag for deleting the handler Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 06/18] virtio: decrement last_avail_idx with inuse before saving Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 07/18] Introduce fault tolerant VM transaction QEMUFile and ft_mode Yoshiaki Tamura
2011-02-21 4:46 ` ya su [this message]
2011-02-21 9:42 ` [Qemu-devel] " Yoshiaki Tamura
2011-02-23 2:28 ` ya su
2011-02-23 5:05 ` Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 08/18] savevm: introduce util functions to control ft_trans_file from savevm layer Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 09/18] Introduce event-tap Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 10/18] Call init handler of event-tap at main() in vl.c Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 11/18] ioport: insert event_tap_ioport() to ioport_write() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 12/18] Insert event_tap_mmio() to cpu_physical_memory_rw() in exec.c Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 13/18] net: insert event-tap to qemu_send_packet() and qemu_sendv_packet_async() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 14/18] block: insert event-tap to bdrv_aio_writev(), bdrv_aio_flush() and bdrv_flush() Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 15/18] savevm: introduce qemu_savevm_trans_{begin, commit} Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 16/18] migration: introduce migrate_ft_trans_{put, get}_ready(), and modify migrate_fd_put_ready() when ft_mode is on Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 17/18] migration-tcp: modify tcp_accept_incoming_migration() to handle ft_mode, and add a hack not to close fd when ft_mode is enabled Yoshiaki Tamura
2011-02-10 9:30 ` [Qemu-devel] [PATCH 18/18] Introduce "kemari:" to enable FT migration mode (Kemari) Yoshiaki Tamura
2011-02-10 9:52 ` [Qemu-devel] " Paolo Bonzini
-- strict thread matches above, loose matches on Subject: below --
2011-02-23 13:48 [Qemu-devel] [PATCH 00/18] Kemari for KVM v0.2.11 Yoshiaki Tamura
2011-02-23 13:48 ` [Qemu-devel] [PATCH 07/18] Introduce fault tolerant VM transaction QEMUFile and ft_mode Yoshiaki Tamura
2011-02-23 22:16 ` [Qemu-devel] " Juan Quintela
2011-02-24 3:54 ` Yoshiaki Tamura
2011-02-24 9:30 ` Juan Quintela
2011-02-24 9:44 ` Yoshiaki Tamura
2011-03-09 8:01 ` ya su
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=AANLkTimrBRkqB9_Sjutf0bK6ZQOFupRB3drn4zGgkG0G@mail.gmail.com \
--to=suya94335@gmail.com \
--cc=aliguori@us.ibm.com \
--cc=ananth@in.ibm.com \
--cc=avi@redhat.com \
--cc=blauwirbel@gmail.com \
--cc=dlaor@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=kwolf@redhat.com \
--cc=mst@redhat.com \
--cc=mtosatti@redhat.com \
--cc=ohmura.kei@lab.ntt.co.jp \
--cc=pbonzini@redhat.com \
--cc=psuriset@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
--cc=tamura.yoshiaki@lab.ntt.co.jp \
--cc=vatsa@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).