xm create创建DomU深层代码分析

xm create创建DomU深层代码分析

Quote From :http://blog.sina.com.cn/s/blog_6a18dd270100kxy0.html

Domian 0 上运行配置相关的配置文件,运行下面命令: xm create example。进入Domain U的创建过程;

代码级别分析开始:
首先对xm命令进行分析,找到xen/tools/python/xen/xm/main.py函数:
----------------------------------------------------------------------
defmain(argv=sys.argv):  调用 _run_cmd(cmd, cmd_name, args):
for c inIMPORTED_COMMANDS:
   commands[c] = eval_r('lambda args: xm_importcommand("%s", args)' %c)
def xm_importcommand(command,args):
    cmd =__import__(command, globals(), locals(), 'xen.xm')
   cmd.main([command] + args)
通过对上面的操作分析,最后根据cmd =create的命令,分析xm_importcommand,可以看到他首先importcreate.py,然后调用create.main(create + args);
----------------------------------------------------------------
找到相同文件下的create.py文件
def main(argv):
……
dom = make_domain(opts,config)
……
根据相应的调用过程,找到make_domain()函数;
def make_domain(opts,config):
……
dominfo =server.xend.domain.create(config)
……
对该含函数进行分析,找到最为主要的创建函数过程。根据所调用的函数查找相应的文件。
---------------------------------------------------------------------
所对应的文件应该是/xen/tools/xen/python/xen/xend/XendDomainInfo.py其中的create函数;

defcreate(config):
    """Createsand start a VM using the supplied configuration.

    @paramconfig: A configuration object involving lists of tuples.
   @type  config: list of lists, eg ['vm', ['image','xen.gz']]

   @rtype:  XendDomainInfo
    @return: Anup and running XendDomainInfo instance
    @raiseVmError: Invalid configuration or failure to start.
    """
……
vm =XendDomainInfo(domconfig)
 try:
       vm.start()
   except:
       log.exception('Domain construction failed')
       vm.destroy()
       raise
……
对该函数分析得到其主要的过程,其中有vm的创建信息的获得,同时启动该vm;根据该函数查找下面的信息获得函数。根据分析发现,vm是一个类的结构。
class XendDomainInfo:
{
def __init__(self, info, domid = None, dompath = None, augment =False,
                priv = False, resume = False, vmpath = None):
……
 def start(self, is_managed = False):
……
}
其中_init_的函数主要是读取DomU创建过程的配置文件,同时设置相应的值,其中主要包括maxmem、memory等。配置完成以后,根据上面create()函数,可以知道该vm类直接调用start()函数,然后对该start函数进行具体分析。

def start(self, is_managed =False):
       """Attempts to start the VM by do the appropriate
       initialisation if it not started.
       """
       from xen.xend import XendDomain

       if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED,XEN_API_VM_POWER_STATE_SUSPENDED,XEN_API_VM_POWER_STATE_CRASHED):
           try:
               XendTask.log_progress(0, 30,self._constructDomain)
               XendTask.log_progress(31, 60, self._initDomain)
               
               XendTask.log_progress(61, 70,self._storeVmDetails)
               XendTask.log_progress(71, 80,self._storeDomDetails)
               XendTask.log_progress(81, 90,self._registerWatches)
               XendTask.log_progress(91, 100, self.refreshShutdown)

               xendomains = XendDomain.instance()

               # save running configuration if XendDomains believe domain is
               # persistent
               if is_managed:
                   xendomains.managed_config_save(self)
           except:
               log.exception('VM start failed')
               self.destroy()
               raise
       else:
           raise XendError('VM already running')
通过类的初始化过程_init_设置self._statGet()过程
self._stateSet(DOM_STATE_HALTED)
,然后执行start()函数时,根据判断条件进入上述四个XendTask.log_progeress()函数中;
现在挨个分析该三个函数的操作过程,以及所得结果。
-----------------------------------------------------------------------------------------------
通过分析XendTask.log_progress()函数,发现该函数只是一个包装函数,它通过线程的方式把参数传递给想要调用的函数接口,同时执行该调用函数,现在挨个分析:

   def _constructDomain(self):
       """Construct the domain.

       @raise: VmError on error
       """

       log.debug('XendDomainInfo.constructDomain')
    ……
self.domid = xc.domain_create(
               domid = 0,
               ssidref = ssidref,
               handle = uuid.fromString(self.info['uuid']),
               flags = flags,
               target = self.info.target())
          ……

该函数主要还完成了hvm的判断、设置domain为TSC模式、设置时间配置、设置接口、最大CPU数目以及PCI等。
其中该过程调用了xen.lowlevle.xc.xc()函数创建domain;然后找到相应的xc.c文件,查找相应的函数接口;

static PyObject *pyxc_domain_create(XcObject *self,
                                   PyObject *args,
                                   PyObject *kwds)
……
 if ( (ret =xc_domain_create(self->xc_handle, ssidref,
                                handle, flags, &dom)) < 0 )
       return pyxc_error_to_exception();

    if ( target)
       if ( (ret = xc_domain_set_target(self->xc_handle,dom, target)) < 0 )
           return pyxc_error_to_exception();
……
其中它又调用相关的 libxc库文件;

int xc_domain_create(int xc_handle,
                    uint32_t ssidref,
                    xen_domain_handle_t handle,
                    uint32_t flags,
                    uint32_t *pdomid)
{
    interr;
   DECLARE_DOMCTL;

    domctl.cmd =XEN_DOMCTL_createdomain;
   domctl.domain = (domid_t)*pdomid;
   domctl.u.createdomain.ssidref = ssidref;
   domctl.u.createdomain.flags   =flags;
   memcpy(domctl.u.createdomain.handle, handle,sizeof(xen_domain_handle_t));
    if ( (err =do_domctl(xc_handle,&domctl)) != 0 )
       return err;

    *pdomid =(uint16_t)domctl.domain;
    return0;
}
然后调用了该do_domctl()控制接口来创建DomU;
static inline int do_domctl(int xc_handle, struct xen_domctl*domctl)
……
 hypercall.op    = __HYPERVISOR_domctl;
   hypercall.arg[0] = (unsigned long)domctl;

    if ( (ret =do_xen_hypercall(xc_handle,&hypercall)) < 0 )
    {
       if ( errno == EACCES )
           DPRINTF("domctl operation failed -- need to"
                   " rebuild the user-space tool set?\n");
    }
……
-------------------------------------------------------------------------
第二个处理函数分析:
def_initDomain(self):
……
 self.image = image.create(self, self.info)

           # repin domain vcpus if a restricted cpus list is provided
           # this is done prior to memory allocation to aide in memory
           # distribution for NUMA systems.
           node = self._setCPUAffinity()

           # Set scheduling parameters.
           self._setSchedParams()
balloon.free(memory +shadow + vtd_mem, self)
 # machine address size
           if self.info.has_key('machine_address_size'):
               log.debug("_initDomain: setting maximum machine address size %d" %self.info['machine_address_size'])
               xc.domain_set_machine_address_size(self.domid,self.info['machine_address_size'])

           if self.info.has_key('suppress_spurious_page_faults') andself.info['suppress_spurious_page_faults']:
               log.debug("_initDomain: suppressing spurious page faults")
               xc.domain_suppress_spurious_page_faults(self.domid)
该函数具体还有创建事件通道self._createChannels()、self._introduceDomain()、self._freeDMAmemory(node)、self._createDevices();
----------------------------------------------------------------------------------------------------------
第三个处理过程分析:
def_storeVmDetails(self):
 ……
 self._writeVm(to_store)
 self._setVmPermissions()
……
该函数主要完成存储Vm细节信息;
-----------------------------------------------------------------------------------------------------------
其中第三个和第三个函数调用过程,是完成DomU的系统注册和数据刷新工作,这里就不再详细分析,其中主要根据第一个和第二个的domu的创建和初始化过程,找到在系统内核中的操作位置,同时找到内存分配过程的相关内容。

---------------------------------------------------------------------------------------------------------------
所有的xm的最后接口都到达了lowlevle.xc.xc()函数的处理过程,那么重点分析该过程到内核文件的交互过程,同时关注参数的传递过程即可。
其中lowlevel下面的xc主要是通过函数调用,主要过程调度到外层的libxc库中进行处理。在这里lowlevel.xc.xc()主要作为一个函数调度转换接口,其中在python层xm进行数据处理和分析过程,然后进入该层重组参数序列,然后进入到外层的libxc进行具体的细节操作过程,现在问题就是通过在libxc层,找到突破口到系统内核的处理过程分析。
最后通过分析所有的xm命令到会到domctl这个过程,从而引发hypercall的操作;
通过分析得到所有的domctl命令都到libxc/Xc_private.h中,从这个接口来调用对hypercall的操作;
现在先写到这里,后面内核分析会在下篇中介绍。

你可能感兴趣的:(xm create创建DomU深层代码分析)