openstack关于libvirt相关代码的分析(一)

来源:互联网 发布:淘宝网页html模板代码 编辑:程序博客网 时间:2024/06/03 14:53

这段时间研究openstack+xen可惜资料太少,决定看一下源代码得了。

如果看过一篇关于启动Openstack中启动一个虚拟机的过程的文章的话,就一定知道有一个叫做Spawn instance的过程。

我使用的代码是nova-2012.2的版本。

下面我们看一下nova/virt/libvirt/connection.py文件。

"""A connection to a hypervisor through libvirt.Supports KVM, LXC, QEMU, UML, and XEN.**Related Flags**:libvirt_type:  Libvirt domain type.  Can be kvm, qemu, uml, xen                (default: kvm).:libvirt_uri:  Override for the default libvirt URI (depends on libvirt_type).:libvirt_disk_prefix:  Override the default disk prefix for the devices                       attached to a server.:rescue_image_id:  Rescue ami image (None = original image).:rescue_kernel_id:  Rescue aki image (None = original image).:rescue_ramdisk_id:  Rescue ari image (None = original image).:injected_network_template:  Template file for injected network:allow_same_net_traffic:  Whether to allow in project network traffic

我们需要创建以个libvirt xml去新建一个实例。这将会涉及到其中的to_xml函数。

   def to_xml(self, instance, network_info, image_meta=None, rescue=False,               block_device_info=None):        LOG.debug(_('Starting toXML method'), instance=instance)        conf = self.get_guest_config(instance, network_info, image_meta,                                     rescue, block_device_info)        xml = conf.to_xml()        LOG.debug(_('Finished toXML method'), instance=instance)        return xml

可以看到,它调用了一个叫get_guest_config的函数

    def get_guest_config(self, instance, network_info, image_meta, rescue,                         block_device_info=None):        block_device_mapping = driver.block_device_info_get_mapping(            block_device_info)        devs = []        # FIXME(vish): stick this in db        inst_type_id = instance['instance_type_id']        inst_type = instance_types.get_instance_type(inst_type_id)        guest = config.LibvirtConfigGuest()        guest.virt_type = FLAGS.libvirt_type        guest.name = instance['name']        guest.uuid = instance['uuid']        guest.memory = inst_type['memory_mb'] * 1024        guest.vcpus = inst_type['vcpus']        root_device_name = driver.block_device_info_get_root(block_device_info)        if root_device_name:            root_device = block_device.strip_dev(root_device_name)        else:            # NOTE(yamahata):            # for nova.api.ec2.cloud.CloudController.get_metadata()            root_device = self.default_root_device            db.instance_update(                nova_context.get_admin_context(), instance['id'],                {'root_device_name': '/dev/' + self.default_root_device})        if FLAGS.libvirt_type == "lxc":            guest.os_type = "exe"            guest.os_init_path = "/sbin/init"            guest.os_cmdline = "console=ttyS0"        elif FLAGS.libvirt_type == "uml":            guest.os_type = "uml"            guest.os_kernel = "/usr/bin/linux"            guest.os_root = root_device_name or "/dev/ubda"        else:            if FLAGS.libvirt_type == "xen":                guest.os_type = "linux"                guest.os_root = root_device_name or "/dev/xvda"            else:                guest.os_type = "hvm"            if rescue:                guest.os_kernel = os.path.join(FLAGS.instances_path,                                               instance['name'],                                               "kernel.rescue")                guest.os_initrd = os.path.join(FLAGS.instances_path,                                               instance['name'],                                               "ramdisk.rescue")            elif instance['kernel_id']:                guest.os_kernel = os.path.join(FLAGS.instances_path,                                               instance['name'],                                               "kernel")                if FLAGS.libvirt_type == "xen":                    guest.os_cmdline = "ro"                else:                    guest.os_cmdline = "root=%s console=ttyS0" % (                        root_device_name or "/dev/vda",)                if instance['ramdisk_id']:                    guest.os_initrd = os.path.join(FLAGS.instances_path,                                                   instance['name'],                                                   "ramdisk")            else:                guest.os_boot_dev = "hd"        if FLAGS.libvirt_type != "lxc" and FLAGS.libvirt_type != "uml":            guest.acpi = True        if FLAGS.libvirt_type == "lxc":            fs = config.LibvirtConfigGuestFilesys()            fs.type = "mount"            fs.source_dir = os.path.join(FLAGS.instances_path,                                         instance['name'],                                         "rootfs")            guest.add_device(fs)        else:            if FLAGS.use_cow_images:                driver_type = 'qcow2'            else:                driver_type = 'raw'            if image_meta and image_meta.get('disk_format') == 'iso':                root_device_type = 'cdrom'            else:                root_device_type = 'disk'            if FLAGS.libvirt_type == "uml":                ephemeral_disk_bus = "uml"            elif FLAGS.libvirt_type == "xen":                ephemeral_disk_bus = "xen"            else:                ephemeral_disk_bus = "virtio"            if rescue:                diskrescue = config.LibvirtConfigGuestDisk()                diskrescue.source_type = "file"                diskrescue.source_path = os.path.join(FLAGS.instances_path,                                                      instance['name'],                                                      "disk.rescue")                diskrescue.driver_format = driver_type                diskrescue.driver_cache = self.disk_cachemode                diskrescue.target_dev = self.default_root_device                diskrescue.target_bus = ephemeral_disk_bus                guest.add_device(diskrescue)                diskos = config.LibvirtConfigGuestDisk()                diskos.source_type = "file"                diskos.source_path = os.path.join(FLAGS.instances_path,                                                  instance['name'],                                                  "disk")                diskos.driver_format = driver_type                diskos.driver_cache = self.disk_cachemode                diskos.target_dev = self.default_second_device                diskos.target_bus = ephemeral_disk_bus                guest.add_device(diskos)            else:                ebs_root = self._volume_in_mapping(self.default_root_device,                                                   block_device_info)                if not ebs_root:                    diskos = config.LibvirtConfigGuestDisk()                    diskos.source_type = "file"                    diskos.source_device = root_device_type                    diskos.driver_format = driver_type                    diskos.driver_cache = self.disk_cachemode                    diskos.source_path = os.path.join(FLAGS.instances_path,                                                      instance['name'],                                                      "disk")                    diskos.target_dev = root_device                    if root_device_type == "cdrom":                        diskos.target_bus = "ide"                    else:                        diskos.target_bus = "virtio"                    guest.add_device(diskos)                ephemeral_device = None                if not (self._volume_in_mapping(self.default_second_device,                                                block_device_info) or                        0 in [eph['num'] for eph in                              driver.block_device_info_get_ephemerals(                            block_device_info)]):                    if instance['ephemeral_gb'] > 0:                        ephemeral_device = self.default_second_device                if ephemeral_device is not None:                    disklocal = config.LibvirtConfigGuestDisk()                    disklocal.source_type = "file"                    disklocal.source_device = root_device_type                    disklocal.driver_format = driver_type                    disklocal.driver_cache = self.disk_cachemode                    disklocal.source_path = os.path.join(FLAGS.instances_path,                                                         instance['name'],                                                         "disk.local")                    disklocal.target_dev = ephemeral_device                    disklocal.target_bus = ephemeral_disk_bus                    guest.add_device(disklocal)                if ephemeral_device is not None:                    swap_device = self.default_third_device                    db.instance_update(                        nova_context.get_admin_context(), instance['id'],                        {'default_ephemeral_device':                             '/dev/' + self.default_second_device})                else:                    swap_device = self.default_second_device                for eph in driver.block_device_info_get_ephemerals(                    block_device_info):                    diskeph = config.LibvirtConfigGuestDisk()                    diskeph.source_type = "block"                    diskeph.source_device = root_device_type                    diskeph.driver_format = driver_type                    diskeph.driver_cache = self.disk_cachemode                    diskeph.source_path = os.path.join(FLAGS.instances_path,                                                       instance['name'],                                                       _get_eph_disk(eph))                    diskeph.target_dev = block_device.strip_dev(                        eph['device_name'])                    diskeph.target_bus = ephemeral_disk_bus                    guest.add_device(diskeph)                swap = driver.block_device_info_get_swap(block_device_info)                if driver.swap_is_usable(swap):                    diskswap = config.LibvirtConfigGuestDisk()                    diskswap.disk_type = "file"                    diskswap.driver_format = driver_type                    diskswap.driver_cache = self.disk_cachemode                    diskswap.source_path = os.path.join(FLAGS.instances_path,                                                        instance['name'],                                                        "disk.swap")                    diskswap.target_dev = block_device.strip_dev(                        swap['device_name'])                    diskswap.target_bus = ephemeral_disk_bus                    guest.add_device(diskswap)                elif (inst_type['swap'] > 0 and                      not self._volume_in_mapping(swap_device,                                                  block_device_info)):                    diskswap = config.LibvirtConfigGuestDisk()                    diskswap.disk_type = "file"                    diskswap.driver_format = driver_type                    diskswap.driver_cache = self.disk_cachemode                    diskswap.source_path = os.path.join(FLAGS.instances_path,                                                        instance['name'],                                                        "disk.swap")                    diskswap.target_dev = swap_device                    diskswap.target_bus = ephemeral_disk_bus                    guest.add_device(diskswap)                    db.instance_update(                        nova_context.get_admin_context(), instance['id'],                        {'default_swap_device': '/dev/' + swap_device})                for vol in block_device_mapping:                    connection_info = vol['connection_info']                    mountpoint = vol['mount_device']                    cfg = self.volume_driver_method('connect_volume',                                                    connection_info,                                                    mountpoint)                    guest.add_device(cfg)            if self._has_config_drive(instance):                diskconfig = config.LibvirtConfigGuestDisk()                diskconfig.source_type = "file"                diskconfig.driver_format = "raw"                diskconfig.driver_cache = self.disk_cachemode                diskconfig.source_path = os.path.join(FLAGS.instances_path,                                                      instance['name'],                                                      "disk.config")                diskconfig.target_dev = self.default_last_device                diskconfig.target_bus = ephemeral_disk_bus                guest.add_device(diskconfig)        for (network, mapping) in network_info:            cfg = self.vif_driver.plug(instance, network, mapping)            guest.add_device(cfg)        if FLAGS.libvirt_type == "qemu" or FLAGS.libvirt_type == "kvm":            # The QEMU 'pty' driver throws away any data if no            # client app is connected. Thus we can't get away            # with a single type=pty console. Instead we have            # to configure two separate consoles.            consolelog = config.LibvirtConfigGuestSerial()            consolelog.type = "file"            consolelog.source_path = os.path.join(FLAGS.instances_path,                                                  instance['name'],                                                  "console.log")            guest.add_device(consolelog)            consolepty = config.LibvirtConfigGuestSerial()            consolepty.type = "pty"            guest.add_device(consolepty)        else:            consolepty = config.LibvirtConfigGuestConsole()            consolepty.type = "pty"            guest.add_device(consolepty)        if FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc', 'uml'):            if FLAGS.use_usb_tablet:                tablet = config.LibvirtConfigGuestInput()                tablet.type = "tablet"                tablet.bus = "usb"                guest.add_device(tablet)            graphics = config.LibvirtConfigGuestGraphics()            graphics.type = "vnc"            graphics.keymap = FLAGS.vnc_keymap            graphics.listen = FLAGS.vncserver_listen            guest.add_device(graphics)        return guest

原创粉丝点击