nova 创建qcow2的kernel image的过程
来源:互联网 发布:eclipse端口号在哪改 编辑:程序博客网 时间:2024/06/08 17:34
最终调用nova/virt/libvirt/driver.py 中的spawn来创建虚拟机 def spawn(self, context, instance, image_meta, injected_files, admin_password, network_info=None, block_device_info=None): disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type, instance, image_meta, block_device_info) gen_confdrive = functools.partial(self._create_configdrive, context, instance, admin_pass=admin_password, files=injected_files, network_info=network_info)这里有调用_create_image self._create_image(context, instance, disk_info['mapping'], network_info=network_info, block_device_info=block_device_info, files=injected_files, admin_pass=admin_password)_create_image 源码如下: def _create_image(self, context, instance, disk_mapping, suffix='', disk_images=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( instance, disk_mapping) def image(fname, image_type=CONF.libvirt.images_type): return self.image_backend.image(instance, fname + suffix, image_type) def raw(fname): return image(fname, image_type='raw') # ensure directories exist and are writable fileutils.ensure_tree(libvirt_utils.get_instance_path(instance)) LOG.info(_LI('Creating image'), instance=instance) if not disk_images: disk_images = {'image_id': instance.image_ref, 'kernel_id': instance.kernel_id, 'ramdisk_id': instance.ramdisk_id} if disk_images['kernel_id']: fname = imagecache.get_cache_fname(disk_images['kernel_id']) raw('kernel').cache(fetch_func=libvirt_utils.fetch_raw_image, context=context, filename=fname, image_id=disk_images['kernel_id'])可以看到_create_image 中最终调用raw('kernel').cache 来创建kennel镜像,而raw函数调用image。所以最终调用image.cache 来创建kernel镜像,image定义如下:def image(fname, image_type=CONF.libvirt.images_type): return self.image_backend.image(instance, fname + suffix, image_type)可见最终调用mage_backend.image。其源码路径为nova/virt/libvirt/imagebackend.py def cache(self, fetch_func, filename, size=None, *args, **kwargs): """Creates image from template. Ensures that template and image not already exists. Ensures that base directory exists. Synchronizes on template fetching. :fetch_func: Function that creates the base image Should accept `target` argument. :filename: Name of the file in the image directory :size: Size of created image in bytes (optional) """ @utils.synchronized(filename, external=True, lock_path=self.lock_path) def fetch_func_sync(target, *args, **kwargs): # The image may have been fetched while a subsequent # call was waiting to obtain the lock. if not os.path.exists(target): fetch_func(target=target, *args, **kwargs) base_dir = os.path.join(CONF.instances_path, CONF.image_cache_subdirectory_name)//获取kernel镜像 if not os.path.exists(base_dir): fileutils.ensure_tree(base_dir) base = os.path.join(base_dir, filename)//如果镜像不存在则调用create_image 来创建kernel镜像 if not self.exists() or not os.path.exists(base): self.create_image(fetch_func_sync, base, size, *args, **kwargs)由于建立的kernel镜像为qcow2格式,因此create_image实现在qcow2中class Qcow2(Image): def create_image(self, prepare_template, base, size, *args, **kwargs): filename = self._get_lock_name(base) @utils.synchronized(filename, external=True, lock_path=self.lock_path) def copy_qcow2_image(base, target, size): # TODO(pbrady): Consider copying the cow image here # with preallocation=metadata set for performance reasons. # This would be keyed on a 'preallocate_images' setting. libvirt_utils.create_cow_image(base, target) if size: image = imgmodel.LocalFileImage(target, imgmodel.FORMAT_QCOW2) disk.extend(image, size) # Download the unmodified base image unless we already have a copy.//qcow2镜像的制作必须有个base,如果没有base的话,要通过prepare_template来下载base if not os.path.exists(base): prepare_template(target=base, *args, **kwargs) # NOTE(ankit): Update the mtime of the base file so the image # cache manager knows it is in use. libvirt_utils.update_mtime(base) self.verify_base_size(base, size) legacy_backing_size = None legacy_base = base # Determine whether an existing qcow2 disk uses a legacy backing by # actually looking at the image itself and parsing the output of the # backing file it expects to be using.有base后通过copy_qcow2_image创建qcow2镜像 if not os.path.exists(self.path): with fileutils.remove_path_on_error(self.path): copy_qcow2_image(base, self.path, size)这里的prepare_template是create_image的第二个参数,往上回溯可以发现这个函数其实为 self.create_image(fetch_func_sync, base, size, *args, **kwargs)原来就是fetch_func_sync def fetch_func_sync(target, *args, **kwargs): # The image may have been fetched while a subsequent # call was waiting to obtain the lock. if not os.path.exists(target): fetch_func(target=target, *args, **kwargs)这里有调用函数指针fetch_func,继续回溯raw('kernel').cache(fetch_func=libvirt_utils.fetch_raw_image, context=context, filename=fname, image_id=disk_images['kernel_id'])原来最终调用libvirt_utils.fetch_raw_image 来下载base镜像,其源码在libvirt/utils.py def fetch_raw_image(context, target, image_id): """Grab initrd or kernel image. This function does not attempt raw conversion, as these images will already be in raw format. """ images.fetch(context, image_id, target)原来又是调用image.fetch.其源码在virtt/image.py中def fetch(context, image_href, path): with fileutils.remove_path_on_error(path): IMAGE_API.download(context, image_href, dest_path=path)这个download 的函数最终在nova/image/glance.py 中实现。重点是知道这里是通过glance下载的base镜像就行了回到Qcow2类的create_image函数中,下载base镜像后还要通过copy_qcow2_image创建qcow2镜像.其源码在libvirt/utils.py中def create_cow_image(backing_file, path, size=None): """Create COW image Creates a COW image with the given backing file构建命令创建qcow2镜像 :param backing_file: Existing image on which to base the COW image :param path: Desired location of the COW image """ base_cmd = ['qemu-img', 'create', '-f', 'qcow2'] cow_opts = [] if backing_file: cow_opts += ['backing_file=%s' % backing_file] base_details = images.qemu_img_info(backing_file) else: base_details = None # Explicitly inherit the value of 'cluster_size' property of a qcow2 # overlay image from its backing file. This can be useful in cases # when people create a base image with a non-default 'cluster_size' # value or cases when images were created with very old QEMU # versions which had a different default 'cluster_size'. if base_details and base_details.cluster_size is not None: cow_opts += ['cluster_size=%s' % base_details.cluster_size] if size is not None: cow_opts += ['size=%s' % size] if cow_opts: # Format as a comma separated list csv_opts = ",".join(cow_opts) cow_opts = ['-o', csv_opts] cmd = base_cmd + cow_opts + [path]执行命令 execute(*cmd)
阅读全文
0 0
- nova 创建qcow2的kernel image的过程
- 制作qcow2格式的image
- 【nova】【libvirt】【glance】创建VM的过程中的 镜像创建过程
- OpenStack的nova-volume创建
- nova 虚拟机创建过程
- kernel image 与 kernel u-boot 可识别的image
- Nova RPC服务 之 Nova RPC服务的创建
- OpenStack Nova深入学习 -- 创建instance的过程之源码分析
- nova中的service 访问数据库的过程
- The QCOW2 Image Format
- Kernel Thread 的创建
- QCOW2和ROW的区别
- nova-compute的虚拟机创建调度策略
- Nova创建虚拟机的底层代码分析
- nova创建虚拟机时资源的检测
- Image的生成过程
- KVM虚拟化:使用qemu-img创建qcow2虚拟磁盘的预分配策略分析
- linux kernel的启动过程
- 本题主要考查指针与数组
- 原生servlet项目启动自动加载一个方法
- x86从实模式到保护模式学习记录之Bochsdbg
- Android Studio 简单设置
- flume spoolDirectory Source原生代码流程及其拓展
- nova 创建qcow2的kernel image的过程
- RrecyclerView自定义点击长按添加删除修改
- removeFromSuperview
- SQliteSQ语句整理及简介
- 《算法入门经典-训练指南》小记(慢慢填。)
- Tomcat JVM内存调优
- python中log日志的使用
- ubuntu下安装nginx依赖库zlib,pcre,openssl
- 安卓使用隐式Intent(intent-filter)从其他Activity返回MainActivity时,App停止运行,及使用intent步骤简介