這里只關(guān)注Nova virt的spawn函數(shù),glance、nova后端為ceph
創(chuàng)新互聯(lián)建站是專業(yè)的渝北網(wǎng)站建設(shè)公司,渝北接單;提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行渝北網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!nova/virt/libvirt/driver.py def spawn(self, context, instance, p_w_picpath_meta, injected_files, admin_password, network_info=None, block_device_info=None): p_w_picpath_meta = objects.ImageMeta.from_dict(p_w_picpath_meta) disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, instance, p_w_picpath_meta, block_device_info) self._create_p_w_picpath(context, instance, # 虛擬機(jī)拉取glance p_w_picpath disk_info['mapping'], network_info=network_info, block_device_info=block_device_info, files=injected_files, admin_pass=admin_password) xml = self._get_guest_xml(context, instance, network_info, disk_info, p_w_picpath_meta, block_device_info=block_device_info, write_to_disk=True) self._create_domain_and_network(context, xml, instance, network_info, disk_info, block_device_info=block_device_info) LOG.debug("Instance is running", instance=instance) def _wait_for_boot(): """Called at an interval until the VM is running.""" state = self.get_info(instance).state if state == power_state.RUNNING: LOG.info(_LI("Instance spawned successfully."), instance=instance) raise loopingcall.LoopingCallDone() timer = loopingcall.FixedIntervalLoopingCall(_wait_for_boot) # loopingcall等待虛擬機(jī)running的狀態(tài) timer.start(interval=0.5).wait() nova/virt/libvirt/driver.py def _create_p_w_picpath(self, context, instance, disk_mapping, suffix='', disk_p_w_picpaths=None, network_info=None, block_device_info=None, files=None, admin_pass=None, inject_files=True, fallback_from_host=None): booted_from_volume = self._is_booted_from_volume( # 判斷是不是boot_from_volume,boot_from_volume沒有base p_w_picpath instance) if not booted_from_volume: root_fname = p_w_picpathcache.get_cache_fname(disk_p_w_picpaths, 'p_w_picpath_id') size = instance.root_gb * units.Gi if size == 0 or suffix == '.rescue': size = None backend = p_w_picpath('disk') if backend.SUPPORTS_CLONE: # 只有backend為rbd的才支持clone操作 def clone_fallback_to_fetch(*args, **kwargs): try: backend.clone(context, disk_p_w_picpaths['p_w_picpath_id']) # clone操作在nova/virt/libvirt/p_w_picpathbackend.py中class Rbd下 except exception.ImageUnacceptable: # 除p_w_picpath格式為raw和iso外的格式都拋異常 libvirt_utils.fetch_p_w_picpath(*args, **kwargs) fetch_func = clone_fallback_to_fetch else: fetch_func = libvirt_utils.fetch_p_w_picpath self._try_fetch_p_w_picpath_cache(backend, fetch_func, context, # 進(jìn)入_try_fetch_p_w_picpath_cache函數(shù) root_fname, disk_p_w_picpaths['p_w_picpath_id'], instance, size, fallback_from_host) 。。。。。。。。 # File injection only if needed, # 這里在OpenStack in Openstack環(huán)境下注入密碼有坑,從nova-compute log中看到一直卡在create p_w_picpath過程, # 實際上是卡在密碼注入過程。。。 elif inject_files and CONF.libvirt.inject_partition != -2: if booted_from_volume: LOG.warn(_LW('File injection into a boot from volume ' 'instance is not supported'), instance=instance) self._inject_data( # 注入相關(guān)的操作 instance, network_info, admin_pass, files, suffix) if CONF.libvirt.virt_type == 'uml': libvirt_utils.chown(p_w_picpath('disk').path, 'root') nova/virt/libvirt/p_w_picpathbackend.py def clone(self, context, p_w_picpath_id_or_uri): p_w_picpath_meta = IMAGE_API.get(context, p_w_picpath_id_or_uri, include_locations=True) locations = p_w_picpath_meta['locations'] LOG.debug('Image locations are: %(locs)s' % {'locs': locations}) if p_w_picpath_meta.get('disk_format') not in ['raw', 'iso']: # p_w_picpath格式判斷, 所以ceph p_w_picpath格式最好是raw,這樣走的ceph的clone reason = _('Image is not raw format') raise exception.ImageUnacceptable(p_w_picpath_id=p_w_picpath_id_or_uri, reason=reason) for location in locations: if self.driver.is_cloneable(location, p_w_picpath_meta): return self.driver.clone(location, self.rbd_name) # 調(diào)用nova/virt/libvirt/storage/rbd_utils.py reason = _('No p_w_picpath locations are accessible') raise exception.ImageUnacceptable(p_w_picpath_id=p_w_picpath_id_or_uri, reason=reason) nova/virt/libvirt/driver.py def _try_fetch_p_w_picpath_cache(self, p_w_picpath, fetch_func, context, filename, p_w_picpath_id, instance, size, fallback_from_host=None): try: p_w_picpath.cache(fetch_func=fetch_func, # 進(jìn)入cache函數(shù) context=context, filename=filename, p_w_picpath_id=p_w_picpath_id, user_id=instance.user_id, project_id=instance.project_id, size=size) except exception.ImageNotFound: if not fallback_from_host: raise LOG.debug("Image %(p_w_picpath_id)s doesn't exist anymore " "on p_w_picpath service, attempting to copy " "p_w_picpath from %(host)s", {'p_w_picpath_id': p_w_picpath_id, 'host': fallback_from_host}, instance=instance) def copy_from_host(target, max_size): libvirt_utils.copy_p_w_picpath(src=target, dest=target, host=fallback_from_host, receive=True) p_w_picpath.cache(fetch_func=copy_from_host, filename=filename) nova/virt/libvirt/p_w_picpathbackend.py def cache(self, fetch_func, filename, size=None, *args, **kwargs): """Creates p_w_picpath from template. Ensures that template and p_w_picpath not already exists. Ensures that base directory exists. Synchronizes on template fetching. :fetch_func: Function that creates the base p_w_picpath Should accept `target` argument. :filename: Name of the file in the p_w_picpath directory :size: Size of created p_w_picpath in bytes (optional) """ @utils.synchronized(filename, external=True, lock_path=self.lock_path) def fetch_func_sync(target, *args, **kwargs): # The p_w_picpath may have been fetched while a subsequent # call was waiting to obtain the lock. if not os.path.exists(target): # 如果不存在base p_w_picpath的話 fetch_func(target=target, *args, **kwargs) # fetch_func是clone_fallback_to_fetch base_dir = os.path.join(CONF.instances_path, CONF.p_w_picpath_cache_subdirectory_name) if not os.path.exists(base_dir): fileutils.ensure_tree(base_dir) base = os.path.join(base_dir, filename) if not self.check_p_w_picpath_exists() or not os.path.exists(base): self.create_p_w_picpath(fetch_func_sync, base, size, base p_w_picpath如果不存在的話,進(jìn)入create_p_w_picpath *args, **kwargs) if (size and self.preallocate and self._can_fallocate() and os.access(self.path, os.W_OK)): utils.execute('fallocate', '-n', '-l', size, self.path) nova/virt/libvirt/p_w_picpathbackend.py def create_p_w_picpath(self, prepare_template, base, size, *args, **kwargs): if not self.check_p_w_picpath_exists(): prepare_template(target=base, max_size=size, *args, **kwargs) # prepare_template這里是fetch_func_sync # prepare_template() may have cloned the p_w_picpath into a new rbd # p_w_picpath already instead of downloading it locally if not self.check_p_w_picpath_exists(): # 如果走的是rbd clone操作,這里就不會用rbd import了 self.driver.import_p_w_picpath(base, self.rbd_name) self.verify_base_size(base, size) if size and size > self.get_disk_size(self.rbd_name): self.driver.resize(self.rbd_name, size)
總結(jié): nova、glance后端為ceph,raw格式的p_w_picpath沒有base p_w_picpath, qcow2格式還是有base p_w_picpath的,不過rbd import base p_w_picpath到pool后,可以把緩存的base p_w_picpath刪除
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。