Chinaunix首页 | 论坛 | 博客
  • 博客访问: 554151
  • 博文数量: 168
  • 博客积分: 62
  • 博客等级: 民兵
  • 技术积分: 442
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-30 11:45
文章分类

全部博文(168)

文章存档

2016年(2)

2015年(19)

2014年(98)

2013年(22)

2012年(6)

2011年(21)

分类: 虚拟化

2014-08-12 15:31:57

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);


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

阅读(2408) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~