xm create的過程

來源:互聯網
上載者:User

Domian 0 上回合組態相關的設定檔,運行下面命令: xm create example。進入Domain U 的建立過程;

代碼層級分析開始:


首先對xm命令進行分析,找到xen/tools/python/xen/xm/main.py函數:

def main(argv=sys.argv):   首先匯入所有命令對應的處理函數:
for c in IMPORTED_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,可以看到他首先import create.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) .... server.xend.domain.waitForDevices(dom) server.xend.domain.unpause(dom)

……
對該含函數進行分析,找到最為主要的建立函數過程。根據所調用的函數尋找相應的檔案。

在XMLRPCServer.py中註冊:self.server.register_function(domain_create,  'xend.domain.create')
對應的處理函數為XendDomain中的domain_create函數:
     而其中又跳到XendDomainInfo的建立函數  dominfo = XendDomainInfo.create(config)
所對應的檔案是/xen/tools/xen/python/xen/xend/XendDomainInfo.py其中的create函數;

def create(config):

……
vm = XendDomainInfo(domconfig)
 try:
       vm.start()     #XendDomainInfo.start()
    except:
        log.exception('Domain construction failed')
        vm.destroy()
        raise
……
對該函數分析得到其主要的過程,其中有vm的建立資訊的獲得,同時啟動該vm。vm是一個XendDomainInfo類:
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、建立對應的VMMetrics等。配置完成以後,該vm類直接調用start()函數:

def start(self, is_managed = False):
        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):

self.domid = xc.domain_create(
                domid = 0,
                ssidref = ssidref,
                handle = uuid.fromString(self.info['uuid']),
                flags = flags,
                target = self.info.target())
           ……          XendDomain.instance().add_domain(self) #添加到XendDomain裡面去

該函數主要還完成了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)
{
    int err;
    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;
    return 0;
}
然後調用了該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') and self.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的操作;
現在先寫到這裡,後面核心分析會在下篇中介紹。 參考:http://hi.baidu.com/juacm/blog/item/fc4932423b2b78136b63e5b2.html 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.