1. 解析xml文件
当在nova中配置大页之后,会在xml文件中添加<hugepage>相关的字段。在domain_conf.c文件中,首先libvirt会在virDomainDefParseXML函数中对xml文件进行解析,解析对应的hugepage参数,并对hugepage结构进行初始化,如下图所示:
首先使用virXPathNodeSet函数获取需要配置的大页信息的数量,分配对应数量的内存大页。然后会在virDomainHugepagesParseXML函数中对每一条大页信息进行解析:
在这个函数中会解析对应的各配置信息,生成hugepage的各个配置信息。
2. 生成qemu创建命令
在qemu_command.c文件中,libvirt通过qemuBuildCommandLine函数生成虚机创建命令,如下所示:
如果没有使用numa,将会通过qemuBuildMemCommandLine函数初始化qemu命令,如果使用了numa,则会通过 qemuBuildNumaArgStr函数初始化qemu命令。
2.1 配置numa的情况
配置了numa的情况下,首先判断配置的大页大小和数量是否有问题,然后判断配置的numa节点是否可用,如果没问题的话会通过qemuBuildMemoryCellBackendStr函数来生成大页创建参数。
在这个函数里又是通过qemuBuildMemoryBackendProps函数来真正生成命令:
qemuBuildMemoryBackendProps函数创建一个配置对象,代表给定客户NUMA节点的内存后端。如果能找到大页但没办法找到对应numa上的大页,返回1的值。成功将返回0。
在qemuBuildMemoryBackendProps函数中,主要逻辑如下所示:
如果没有设pagesize,会在内存维护的大页链表中遍历大页,找到有与指定numa节点相符合的大页,自动将找到的大页分配给虚机;如果遍历完没有找到符合的内存大页,找到了没有在numa节点中的大页内存,会使用该大页内存。
最后会在上面两段代码中分别进行大页参数和绑定的节点参数的生成。在qemuGetDomainHupageMemPath中,libvirt找到指定大页对应的hugetlbfs文件挂载目录,并以此目录作为mem-path的参数。
2.2 未配置numa的情况
没有配置numa的情况只需要生成大页的配置文件即可。
在qemuBuildMemCommandLine中会判断是否没有配置numa,如果是的话会通过qemuBuildMemPathStr函数生成配置参数。
同样是通过qemuGetDomainHupageMemPath来获取大页挂载的路径。