由于该文件大于8万字符 所以我分4次挂载(3)
该文件位于nova/virt/libvirt目录下的connection.py!我只是浅浅的分析了一下类中函数的方法 细节并没有多看,肯定有很多地方是错的 或者不好!希望大家能够帮忙指出错误!
接下来 看源代码如下:中文部分是我加的注释 !或许大家会问 为什么要看这个connection.py呢 因为我发现该文件外部virt目录下有个connection.py 其中引用了 这个文件 所以觉得这个应该很重要 而且发现 好多方法都是重写的底层的driver的方法
- if FLAGS.libvirt_type == 'uml':
- _disk_prefix = 'ubd'
- elif FLAGS.libvirt_type == 'xen':
- _disk_prefix = 'sd'
- elif FLAGS.libvirt_type == 'lxc':
- _disk_prefix = ''
- else:
- _disk_prefix = 'vd'
- default_root_device = _disk_prefix + 'a'
- default_local_device = _disk_prefix + 'b'
- default_swap_device = _disk_prefix + 'c'
- def _volume_in_mapping(self, mount_device, block_device_info):
- block_device_list = [block_device.strip_dev(vol['mount_device'])
- for vol in
- driver.block_device_info_get_mapping(
- block_device_info)]
- swap = driver.block_device_info_get_swap(block_device_info)
- if driver.swap_is_usable(swap):
- block_device_list.append(
- block_device.strip_dev(swap['device_name']))
- block_device_list += [block_device.strip_dev(ephemeral['device_name'])
- for ephemeral in
- driver.block_device_info_get_ephemerals(
- block_device_info)]
- LOG.debug(_("block_device_list %s"), block_device_list)
- return block_device.strip_dev(mount_device) in block_device_list
- def _get_volume_device_info(self, device_path):
- if device_path.startswith('/dev/'):
- return ('block', None, None)
- elif ':' in device_path:
- (protocol, name) = device_path.split(':')
- return ('network', protocol, name)
- else:
- raise exception.InvalidDevicePath(path=device_path)
- def _prepare_xml_info(self, instance, network_info, rescue,
- block_device_info=None):
- #感觉是返回的xml的信息
- block_device_mapping = driver.block_device_info_get_mapping(
- block_device_info)
- nics = []
- for (network, mapping) in network_info:
- nics.append(self.vif_driver.plug(instance, network, mapping))
- # FIXME(vish): stick this in db
- inst_type_id = instance['instance_type_id']
- inst_type = instance_types.get_instance_type(inst_type_id)
- if FLAGS.use_cow_p_w_picpaths:
- driver_type = 'qcow2'
- else:
- driver_type = 'raw'
- for vol in block_device_mapping:
- vol['mount_device'] = block_device.strip_dev(vol['mount_device'])
- (vol['type'], vol['protocol'], vol['name']) = \
- self._get_volume_device_info(vol['device_path'])
- ebs_root = self._volume_in_mapping(self.default_root_device,
- block_device_info)
- local_device = False
- if not (self._volume_in_mapping(self.default_local_device,
- block_device_info) or
- 0 in [eph['num'] for eph in
- driver.block_device_info_get_ephemerals(
- block_device_info)]):
- if instance['local_gb'] > 0:
- local_device = self.default_local_device
- ephemerals = []
- for eph in driver.block_device_info_get_ephemerals(block_device_info):
- ephemerals.append({'device_path': _get_eph_disk(eph),
- 'device': block_device.strip_dev(
- eph['device_name'])})
- xml_info = {'type': FLAGS.libvirt_type,
- 'name': instance['name'],
- 'basepath': os.path.join(FLAGS.instances_path,
- instance['name']),
- 'memory_kb': inst_type['memory_mb'] * 1024,
- 'vcpus': inst_type['vcpus'],
- 'rescue': rescue,
- 'disk_prefix': self._disk_prefix,
- 'driver_type': driver_type,
- 'vif_type': FLAGS.libvirt_vif_type,
- 'nics': nics,
- 'ebs_root': ebs_root,
- 'local_device': local_device,
- 'volumes': block_device_mapping,
- 'use_virtio_for_bridges':
- FLAGS.libvirt_use_virtio_for_bridges,
- 'ephemerals': ephemerals}
- root_device_name = driver.block_device_info_get_root(block_device_info)
- if root_device_name:
- xml_info['root_device'] = block_device.strip_dev(root_device_name)
- xml_info['root_device_name'] = root_device_name
- else:
- # NOTE(yamahata):
- # for nova.api.ec2.cloud.CloudController.get_metadata()
- xml_info['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 local_device:
- db.instance_update(
- nova_context.get_admin_context(), instance['id'],
- {'default_local_device': '/dev/' + self.default_local_device})
- swap = driver.block_device_info_get_swap(block_device_info)
- if driver.swap_is_usable(swap):
- xml_info['swap_device'] = block_device.strip_dev(
- swap['device_name'])
- elif (inst_type['swap'] > 0 and
- not self._volume_in_mapping(self.default_swap_device,
- block_device_info)):
- xml_info['swap_device'] = self.default_swap_device
- db.instance_update(
- nova_context.get_admin_context(), instance['id'],
- {'default_swap_device': '/dev/' + self.default_swap_device})
- config_drive = False
- if instance.get('config_drive') or instance.get('config_drive_id'):
- xml_info['config_drive'] = xml_info['basepath'] + "/disk.config"
- if FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc', 'uml'):
- xml_info['vncserver_host'] = FLAGS.vncserver_host
- xml_info['vnc_keymap'] = FLAGS.vnc_keymap
- if not rescue:
- if instance['kernel_id']:
- xml_info['kernel'] = xml_info['basepath'] + "/kernel"
- if instance['ramdisk_id']:
- xml_info['ramdisk'] = xml_info['basepath'] + "/ramdisk"
- xml_info['disk'] = xml_info['basepath'] + "/disk"
- return xml_info
- def to_xml(self, instance, network_info, rescue=False,
- block_device_info=None):
- # TODO(termie): cache?
- LOG.debug(_('instance %s: starting toXML method'), instance['name'])
- xml_info = self._prepare_xml_info(instance, network_info, rescue,
- block_device_info)
- xml = str(Template(self.libvirt_xml, searchList=[xml_info]))
- LOG.debug(_('instance %s: finished toXML method'), instance['name'])
- return xml
- def _lookup_by_name(self, instance_name):
- #检索libvirt(授权)域对象 给定一个实例名 所有的 libvirt错误在这个 方法中 都应该有被处理的handler
- """Retrieve libvirt domain object given an instance name.
- All libvirt error handling should be handled in this method and
- relevant nova exceptions should be raised in response.
- """
- try:
- return self._conn.lookupByName(instance_name)
- except libvirt.libvirtError as ex:
- error_code = ex.get_error_code()
- if error_code == libvirt.VIR_ERR_NO_DOMAIN:
- raise exception.InstanceNotFound(instance_id=instance_name)
- msg = _("Error from libvirt while looking up %(instance_name)s: "
- "[Error Code %(error_code)s] %(ex)s") % locals()
- raise exception.Error(msg)
- def get_info(self, instance_name):
- #为了一个特定的实例名从libvirt中检索信息 返回一个 字典
- """Retrieve information from libvirt for a specific instance name.
- If a libvirt error is encountered during lookup, we might raise a
- NotFound exception or Error exception depending on how severe the
- libvirt error is.
- """
- virt_dom = self._lookup_by_name(instance_name)
- (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info()
- return {'state': state,
- 'max_mem': max_mem,
- 'mem': mem,
- 'num_cpu': num_cpu,
- 'cpu_time': cpu_time}
- def _create_new_domain(self, xml, persistent=True, launch_flags=0):
- #创建一个新的域 返回值是domain
- # NOTE(justinsb): libvirt has two types of domain:
- # * a transient domain disappears when the guest is shutdown
- # or the host is rebooted.
- # * a permanent domain is not automatically deleted
- # NOTE(justinsb): Even for ephemeral instances, transient seems risky
- if persistent:
- # To create a persistent domain, first define it, then launch it.
- domain = self._conn.defineXML(xml)
- domain.createWithFlags(launch_flags)
- else:
- # createXML call creates a transient domain
- domain = self._conn.createXML(xml, launch_flags)
- return domain
- def get_diagnostics(self, instance_name):
- #诊断?
- raise exception.ApiError(_("diagnostics are not supported "
- "for libvirt"))
- def get_disks(self, instance_name):
- #该函数接受一个实例名 作为参数 最后对于该域返回一个所有块devices的列表
- """
- Note that this function takes an instance name.
- Returns a list of all block devices for this domain.
- """
- domain = self._lookup_by_name(instance_name)
- # TODO(devcamcar): Replace libxml2 with etree.
- xml = domain.XMLDesc(0)
- doc = None
- try:
- doc = libxml2.parseDoc(xml)
- except Exception:
- return []
- ctx = doc.xpathNewContext()
- disks = []
- try:
- ret = ctx.xpathEval('/domain/devices/disk')
- for node in ret:
- devdst = None
- for child in node.children:
- if child.name == 'target':
- devdst = child.prop('dev')
- if devdst is None:
- continue
- disks.append(devdst)
- finally:
- if ctx is not None:
- ctx.xpathFreeContext()
- if doc is not None:
- doc.freeDoc()
- return disks
- def get_interfaces(self, instance_name):
- #该函数同样 接受一个 实例名作为参数 最后对于该 实例返回一个所有network interface的 列表
- """
- Note that this function takes an instance name.
- Returns a list of all network interfaces for this instance.
- """
- domain = self._lookup_by_name(instance_name)
- # TODO(devcamcar): Replace libxml2 with etree.
- xml = domain.XMLDesc(0)
- doc = None
- try:
- doc = libxml2.parseDoc(xml)
- except Exception:
- return []
- ctx = doc.xpathNewContext()
- interfaces = []
- try:
- ret = ctx.xpathEval('/domain/devices/interface')
- for node in ret:
- devdst = None
- for child in node.children:
- if child.name == 'target':
- devdst = child.prop('dev')
- if devdst is None:
- continue
- interfaces.append(devdst)
- finally:
- if ctx is not None:
- ctx.xpathFreeContext()
- if doc is not None:
- doc.freeDoc()
- return interfaces
- def get_vcpu_total(self):
- #得到虚拟处理器物理computermb 最后返回核心cpu的数量?
- """Get vcpu nuer of physical computermb.
- :returns: the number of cpu core.
- """
- # On certain platforms, this will raise a NotImplementedError.
- try:
- return multiprocessing.cpu_count()
- except NotImplementedError:
- LOG.warn(_("Cannot get the number of cpu, because this "
- "function is not implemented for this platform. "
- "This error can be safely ignored for now."))
- return 0
- def get_memory_mb_total(self):
- # 得到 总的物理电脑的内存 返回 总共的memory(MB)
- """Get the total memory size(MB) of physical computer.
- :returns: the total amount of memory(MB).
- """
- if sys.platform.upper() != 'LINUX2':
- return 0
- meminfo = open('/proc/meminfo').read().split()
- idx = meminfo.index('MemTotal:')
- # transforming kb to mb.
- return int(meminfo[idx + 1]) / 1024
- def get_local_gb_total(self):
- #得到 总的硬盘驱动器的size 返回 总size 注意该值显示一个 实例挂载点分区的值
- """Get the total hdd size(GB) of physical computer.
- :returns:
- The total amount of HDD(GB).
- Note that this value shows a partition where
- NOVA-INST-DIR/instances mounts.
- """
- hddinfo = os.statvfs(FLAGS.instances_path)
- return hddinfo.f_frsize * hddinfo.f_blocks / 1024 / 1024 / 1024
- def get_vcpu_used(self):
- #得到一个可用 的物理电脑的虚拟处理器的number 最后返回当前用的total number of vcpu
- """ Get vcpu usage number of physical computer.
- :returns: The total number of vcpu that currently used.
- """
- total = 0
- for dom_id in self._conn.listDomainsID():
- dom = self._conn.lookupByID(dom_id)
- total += len(dom.vcpus()[1])
- return total
- def get_memory_mb_used(self):
- #得到物理计算机free内存大小 返回total usage内存(总使用)
- """Get the free memory size(MB) of physical computer.
- :returns: the total usage of memory(MB).
- """
- if sys.platform.upper() != 'LINUX2':
- return 0
- m = open('/proc/meminfo').read().split()
- idx1 = m.index('MemFree:')
- idx2 = m.index('Buffers:')
- idx3 = m.index('Cached:')
- avail = (int(m[idx1 + 1]) + int(m[idx2 + 1]) + int(m[idx3 + 1])) / 1024
- return self.get_memory_mb_total() - avail
- def get_local_gb_used(self):
- #得到物理计算机(硬盘驱动器)free内存大小 返回total usage内存(总使用)
- """Get the free hdd size(GB) of physical computer.
- :returns:
- The total usage of HDD(GB).
- Note that this value shows a partition where
- NOVA-INST-DIR/instances mounts.
- """
- hddinfo = os.statvfs(FLAGS.instances_path)
- avail = hddinfo.f_frsize * hddinfo.f_bavail / 1024 / 1024 / 1024
- return self.get_local_gb_total() - avail
- def get_hypervisor_type(self):
- #得到管理程序的类型 最后返回 一个类型
- """Get hypervisor type.
- :returns: hypervisor type (ex. qemu)
- """
- return self._conn.getType()
- def get_hypervisor_version(self):
- #得到版本 返回版本
- """Get hypervisor version.
- :returns: hypervisor version (ex. 12003)
- """
- # NOTE(justinsb): getVersion moved between libvirt versions
- # Trying to do be compatible with older versions is a lost cause
- # But ... we can at least give the user a nice message
- method = getattr(self._conn, 'getVersion', None)
- if method is None:
- raise exception.Error(_("libvirt version is too old"
- " (does not support getVersion)"))
- # NOTE(justinsb): If we wanted to get the version, we could:
- # method = getattr(libvirt, 'getVersion', None)
- # NOTE(justinsb): This would then rely on a proper version check
- return method()
转载于:https://blog.51cto.com/brucemars/968457