Skip to the content.

migration

not only live upgrade

TODO: 每一个问题都需要看看:

memory_region 重启和热迁移

TODO

核心流程

输入:

彻底完成 precopy

核心的数据结构关系

static SaveState savevm_state = {
    .handlers = QTAILQ_HEAD_INITIALIZER(savevm_state.handlers),
    .handler_pri_head = { [MIG_PRI_DEFAULT ... MIG_PRI_MAX] = NULL },
    .global_section_id = 0,
};

的这个上面挂

SaveStateEntry

然后将 savevm_ram_handlersram_state 关联为其成员:

register_savevm_live("ram", 0, 4, &savevm_ram_handlers, &ram_state);
static RAMState *ram_state;

caller of migration_channel_connect

fd

exec

tls

socket

[ ] what’s channel

[ ] multifd

typedef struct {
    /* Setup for sending side */
    int (*send_setup)(MultiFDSendParams *p, Error **errp);
    /* Cleanup for sending side */
    void (*send_cleanup)(MultiFDSendParams *p, Error **errp);
    /* Prepare the send packet */
    int (*send_prepare)(MultiFDSendParams *p, Error **errp);
    /* Setup for receiving side */
    int (*recv_setup)(MultiFDRecvParams *p, Error **errp);
    /* Cleanup for receiving side */
    void (*recv_cleanup)(MultiFDRecvParams *p);
    /* Read all pages */
    int (*recv_pages)(MultiFDRecvParams *p, Error **errp);
} MultiFDMethods;

KeyStructure

Question

colo

关联的模块

./io

channel-file.c 的 qio_channel_file_new_fd 存在多个调用者

notify

migration.c

capability

status 转换

typedef enum MigrationStatus {
    MIGRATION_STATUS_NONE,
    MIGRATION_STATUS_SETUP,
    MIGRATION_STATUS_CANCELLING,
    MIGRATION_STATUS_CANCELLED,
    MIGRATION_STATUS_ACTIVE,
    MIGRATION_STATUS_POSTCOPY_ACTIVE,
    MIGRATION_STATUS_POSTCOPY_PAUSED,
    MIGRATION_STATUS_POSTCOPY_RECOVER,
    MIGRATION_STATUS_COMPLETED,
    MIGRATION_STATUS_FAILED,
    MIGRATION_STATUS_COLO,
    MIGRATION_STATUS_PRE_SWITCHOVER,
    MIGRATION_STATUS_DEVICE,
    MIGRATION_STATUS_WAIT_UNPLUG,
    MIGRATION_STATUS__MAX,
} MigrationStatus;

ram_mig_ram_block_resized 中的注释说:

    if (!migration_is_idle()) {
        /*
         * Precopy code on the source cannot deal with the size of RAM blocks
         * changing at random points in time - especially after sending the
         * RAM block sizes in the migration stream, they must no longer change.
         * Abort and indicate a proper reason.
         */
        error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr);
        migration_cancel(err);
        error_free(err);
    }

那么,precopy 的时候,一共可能的状态是什么?

常规流程:

为什么没有做任何操作,就已经初始化好了。

current_migration

qemu-file.c

是不是对于 file 存在什么误解

snapshot

manual: https://www.qemu.org/docs/master/devel/migration.html

message 机制

难道 to_src_file 是通信的 channel 吗?

    qemu_put_be16(mis->to_src_file, (unsigned int)message_type);
    qemu_put_be16(mis->to_src_file, len);
    qemu_put_buffer(mis->to_src_file, data, len);
    qemu_fflush(mis->to_src_file);

RP: Return Pass

/* Messages sent on the return path from destination to source */
enum mig_rp_message_type {
    MIG_RP_MSG_INVALID = 0,  /* Must be 0 */
    MIG_RP_MSG_SHUT,         /* sibling will not send any more RP messages */
    MIG_RP_MSG_PONG,         /* Response to a PING; data (seq: be32 ) */

    MIG_RP_MSG_REQ_PAGES_ID, /* data (start: be64, len: be32, id: string) */
    MIG_RP_MSG_REQ_PAGES,    /* data (start: be64, len: be32) */
    MIG_RP_MSG_RECV_BITMAP,  /* send recved_bitmap back to source */
    MIG_RP_MSG_RESUME_ACK,   /* tell source that we are ready to resume */

    MIG_RP_MSG_MAX
};

kvm

获取一次 memory 的内容:

migration_is_idle

在初始化的时候,这个函数会被反复调用:

#0  migration_is_idle () at ../migration/migration.c:2115
#1  0x00005555559e3115 in qdev_device_add_from_qdict (opts=opts@entry=0x5555576382a0, from_json=from_json@entry=false, errp=0x7fffffffb430, errp@entry=0x5555565b9bb0 <error_fatal>) at ../softmmu/qdev-monitor.c:671
#2  0x00005555559e3662 in qdev_device_add (opts=0x55555664a110, errp=errp@entry=0x5555565b9bb0 <error_fatal>) at ../softmmu/qdev-monitor.c:733
#3  0x00005555559e54ff in device_init_func (opaque=<optimized out>, opts=<optimized out>, errp=0x5555565b9bb0 <error_fatal>) at ../softmmu/vl.c:1140
#4  0x0000555555d80ea2 in qemu_opts_foreach (list=<optimized out>, func=func@entry=0x5555559e54f0 <device_init_func>, opaque=opaque@entry=0x0, errp=errp@entry=0x5555565b9bb0 <error_fatal>) at ../util/qemu-option.c:1135
#5  0x00005555559e7c2a in qemu_create_cli_devices () at ../softmmu/vl.c:2536
#6  qmp_x_exit_preconfig (errp=<optimized out>) at ../softmmu/vl.c:2604
#7  0x00005555559eb68f in qmp_x_exit_preconfig (errp=<optimized out>) at ../softmmu/vl.c:2598
#8  qemu_init (argc=<optimized out>, argv=<optimized out>) at ../softmmu/vl.c:3601
#9  0x00005555558301e9 in main (argc=<optimized out>, argv=<optimized out>) at ../softmmu/main.c:47

VMStateDescription

struct VMStateDescription {
    const char *name;
    int unmigratable;
    int version_id;
    int minimum_version_id;
    MigrationPriority priority;
    int (*pre_load)(void *opaque);
    int (*post_load)(void *opaque, int version_id);
    int (*pre_save)(void *opaque);
    int (*post_save)(void *opaque);
    bool (*needed)(void *opaque);
    bool (*dev_unplug_pending)(void *opaque);

    const VMStateField *fields;
    const VMStateDescription **subsections;
};
static const VMStateDescription vmstate_hpet = {
    .name = "hpet",
    .version_id = 2,
    .minimum_version_id = 1,
    .pre_save = hpet_pre_save,
    .pre_load = hpet_pre_load,
    .post_load = hpet_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(config, HPETState),
        VMSTATE_UINT64(isr, HPETState),
        VMSTATE_UINT64(hpet_counter, HPETState),
        VMSTATE_UINT8_V(num_timers, HPETState, 2),
        VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers),
        VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
                                    vmstate_hpet_timer, HPETTimer),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription*[]) {
        &vmstate_hpet_rtc_irq_level,
        &vmstate_hpet_offset,
        NULL
    }
};

post_copy 的调用时机是什么

和 post copy 机制无关。

开始的执行一次:

#0  vmstate_load_state (f=f@entry=0x555556883d90, vmsd=vmsd@entry=0x5555561adc00 <vmstate_configuration>, opaque=opaque@entry=0x5555564ae940 <savevm_state>, version_id=version_id@entry=0) at ../migration/vmstate.c:80
#1  0x0000555555a18db9 in qemu_loadvm_state_header (f=0x555556883d90) at ../migration/savevm.c:2497
#2  qemu_loadvm_state (f=0x555556883d90) at ../migration/savevm.c:2701
#3  0x0000555555a0660e in process_incoming_migration_co (opaque=<optimized out>) at ../migration/migration.c:591
#4  0x0000555555d8d08b in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at ../util/coroutine-ucontext.c:177
#5  0x00007ffff6a537a0 in ?? () from /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/libc.so.6

之后多次执行:

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。