收入啤酒88 发表于 2015-12-24 14:39:06

qemu-kvm savevm/loadvm 流程

1. 流程:
1)测试设备是否支持snapshot保存
2)停止虚拟机
3)保存虚拟机状态
4)创建快照
5)恢复虚拟机


2. 函数调用:
1) 入口函数
    do_savevm()


2) 函数调用:
1) bdrv_snapshots()
2) vm_stop()
3) qemu_savevm_state()
4) bdrv_snapshot_create()
5) vm_start()


3. 保存状态关键函数qemu_savevm_state()调用
1) qemu_savevm_state_begin()
2) qemu_savevm_state_iterate()
3) qemu_savevm_state_complete()


4. 关键结构体
1)savevm_handlers 设备状态保存函数链表头
通过QTAILQ_FOREACH(se, &savevm_handlers, entry){}遍历保存所有设备状态;


2)QEMUFile
struct QEMUFile {
    QEMUFilePutBufferFunc *put_buffer;
    QEMUFileGetBufferFunc *get_buffer;
    QEMUFileCloseFunc *close;
    QEMUFileRateLimit *rate_limit;
    QEMUFileSetRateLimit *set_rate_limit;
    QEMUFileGetRateLimit *get_rate_limit;
    void *opaque;
    int is_write;            

    int64_t buf_offset; /* start of buffer when writing, end of buffer
                           when reading */
    int buf_index;            
    int buf_size; /* 0 when writing */
    int buf_max_size;
    uint8_t *buf;            
   
    int has_error;            
};
其中put_buffer/get_buffer为关键函数,用来保存/获取设备状态
通过qemu_fopen_ops()函数注册该结构体
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,                                                                                    
                         QEMUFileGetBufferFunc *get_buffer,
                         QEMUFileCloseFunc *close,
                         QEMUFileRateLimit *rate_limit,
                         QEMUFileSetRateLimit *set_rate_limit,
                         QEMUFileGetRateLimit *get_rate_limit)
{   
    QEMUFile *f;
   
    f = qemu_mallocz(sizeof(QEMUFile));
   
    f->opaque = opaque;
    f->put_buffer = put_buffer;
    f->get_buffer = get_buffer;
    f->close = close;
    f->rate_limit = rate_limit;
    f->set_rate_limit = set_rate_limit;
    f->get_rate_limit = get_rate_limit;
    f->is_write = 0;
   
    f->buf_max_size = IO_BUF_SIZE;
    f->buf = qemu_malloc(sizeof(uint8_t) * f->buf_max_size);
                           
    return f;
}   
3)SaveStateEntry
typedef struct SaveStateEntry {                                                                                                                              
    QTAILQ_ENTRY(SaveStateEntry) entry;
    char idstr;
    int instance_id;
    int alias_id;
    int version_id;
    int section_id;
    SaveSetParamsHandler *set_params;
    SaveLiveStateHandler *save_live_state;
    SaveStateHandler *save_state;
    LoadStateHandler *load_state;
    const VMStateDescription *vmsd;
    void *opaque;
    CompatEntry *compat;
    int no_migrate;
} SaveStateEntry;

4) register_savevm_live()
注册保存设备状态函数,填充了结构体SaveStateEntry,并把函数加入到队列中:
QTAILQ_INSERT_TAIL(&savevm_handlers, se, entry);


如果该设备支持动态迁移和状态保存,必须注册调用改函数注册信息。
页: [1]
查看完整版本: qemu-kvm savevm/loadvm 流程