最近要定位Xen migration后nested中xl创建vm panic的问题,于是把migration的过程看一看,记录如下,使用的迁移命令是“xl migrate centos localhost”,下面的代码走读也是以这个命令为标准。
直接从xl命令看,它在toolslibxlxl.c的main函数中,xl受到操作参数之后通过cmdtable_lookup函数进行查表,就是cmd_table,找到名称对应的数组项,也就是migrate,对应的函数是main_migrate,xl的main函数查到对应数组后立即执行对应函数,完成则xl结束,也就是执行main_migrate函数。

在main_migrate函数中需要关注两点,入参的处理我们就忽略掉了,其中有rune的赋值过程,需要留意rune的值为“exec ssh localhost xl -t migrate-receive”,后面会用到。然后是migrate_domain函数,首先是save_domain_core_begin函数,因为最初入参没有指定config文件,此处需要从被迁移的vm中读取config,libxl_domain_config_init负责初始化d_config,libxl_retrieve_domain_configuration负责读取current vm的config数据,具体读取过程掉过不谈,然后使用libxl_domain_config_to_json将d_config转换格式,存储到config_data_r,传递到函数外。
create_migration_child函数负责创建一个子进程,该子进程ssh到接收端负责接受VM,xl_fork fork的进程都在children的数组管理下,然后父进程返回,子进程执行rune即“xl -t migrate-receive”,通过同样的方式查cmd_table,对应函数是main_migrate_receive,这时候代码就兵分两路,后面具体会使用发送端和接收端等字眼标注,在接收端,main_migrate_receive调用migrate_receive,migrate_receive首先使用CHK_ERRNOVAL(libxl_write_exactly(ctx, send_fd, migrate_receiver_banner,sizeof(migrate_receiver_banner)-1,"migration ack stream", "banner") )往发送端传输一条信息,即migrate_receiver_banner字符串,告诉发送端“xl migration receiver ready, send binary domain data.”。而发送端在子进程创建成功后返回,执行migrate_do_preamble函数,其中migrate_read_fixedmessage负责接受接收端刚发的信息并对比是否正确,如果正确的,则使用save_domain_core_writeconfig函数将config_data_r的配置文件信息传递给接收端,再回到接收端migrate_receive函数,接着上面初始化了dom_info,在create_domain中,接受了config信息,如下

libxl_domain_config_init(&d_config);
CHK_ERRNOVAL(libxl_read_exactly(
             ctx, restore_fd, &hdr, sizeof(hdr),
             restore_source, "header"));

上门就描述了一段信息同步的过程,迁移的原理也就很简单,就是暂停guest后将所有信息同步到对端,同时我们知道xl还有save,restore命令,除了中间信息通过ssh通道传输,原理好像没人什么区别,看一下代码,create_domain被main_restore和migrate_receive调用,而save_domain_core_begin被save_domain和migrate_domain调用,如果再往上看函数调用关系,其实很清楚的可以看出xen的save/restore机制和migration机制用的同一套代码,唯一不同的就是migration在两端需要进行同步通信,类似一下,可以看它们的调用就清楚了:

static const char migrate_receiver_banner[]=
    "xl migration receiver ready, send binary domain data.n";
static const char migrate_receiver_ready[]=
    "domain received, ready to unpause";
static const char migrate_permission_to_go[]=
    "domain is yours, you are cleared to unpause";
static const char migrate_report[]=
    "my copy unpause results are as follows";

还一个差别就是xl save到一个文件中,xl migrate到一个socket句柄中,还好他们都是句柄,直接传递给共同函数,不需要特别处理。当然xl restore也是从句柄中恢复。
这样的话,下面就直接在save/restore机制上描述,因为migration机制两端通信描述的非常混乱。
save方面就进入save_domain函数,首先是save_domain_core_begin函数,直接看libxl_retrieve_domain_configuration函数,从这里可以看到xen是如何从dom0获取hypervisor的系统信息。
libxl_domid_to_name获取domX的name,使用XenStore机制,具体内容请查看

char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid)
{
    unsigned int len;
    char path[strlen("/local/domain") + 12];
    char *s;

    snprintf(path, sizeof(path), "/local/domain/%d/name", domid);
    s = xs_read(ctx->xsh, XBT_NULL, path, &len);
    return s;
}

待续


Xen migration源代码分析来自于OenHan

链接为:http://oenhan.com/xl-migrate-src

5 thoughts on “Xen migration源代码分析”

  1. 这篇文章还有后续吗?我最近想做一些虚拟机动态迁移方面的研究,看了这篇文章对Xen动态迁移的源代码有了一些初步的认识。不过,动态迁移不是有一个迭代传输内存的过程吗?这部分的代码具体在哪里体现?难道它就是直接挂起虚拟机进行迁移的?

    1. @BEAROX 后面有时间再补上吧,当前的XEN xl migrate应该是直接挂起虚拟机进行迁移的,在migrate_domain下面,必然会执行libxl_domain_suspend,且在main_migrate下面,–live是被忽略掉的,貌似xm代码里面有live migrate,有兴趣可以看一下send_domain_memory_live函数。

      1. @OENHAN 我自己尝试阅读、跟踪了这部分的源代码。找不到libxl_write_exactly函数的定义,在libxl_utils.h中有声明,但是在lib_utils.c中却没有定义。
        在save_domain_core_writeconfig这个函数中有两个libxl_write_exactly应该和接收端创建虚拟机时的libxl_read_exactly是对应的,这里传输的应该只是config文件吧。我不知道它的内存数据是在哪里同步的。

  2. 你好,请问,这部分源码位于什么位置呀?我的是xen4.4,安装Ubuntu的系统上的。

发表回复