qemu-kvm savevm/loadvm 流程

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[256];
    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);


如果该设备支持动态迁移和状态保存,必须注册调用改函数注册信息。


你可能感兴趣的:(qemu-kvm savevm/loadvm 流程)