由于该文件大于8万字符 所以我分4次挂载(3)

 

     该文件位于nova/virt/libvirt目录下的connection.py!我只是浅浅的分析了一下类中函数的方法 细节并没有多看,肯定有很多地方是错的 或者不好!希望大家能够帮忙指出错误!

      接下来 看源代码如下:中文部分是我加的注释 !或许大家会问 为什么要看这个connection.py呢 因为我发现该文件外部virt目录下有个connection.py 其中引用了 这个文件 所以觉得这个应该很重要 而且发现 好多方法都是重写的底层的driver的方法

 

  1. if FLAGS.libvirt_type == 'uml':  
  2.        _disk_prefix = 'ubd' 
  3.    elif FLAGS.libvirt_type == 'xen':  
  4.        _disk_prefix = 'sd' 
  5.    elif FLAGS.libvirt_type == 'lxc':  
  6.        _disk_prefix = '' 
  7.    else:  
  8.        _disk_prefix = 'vd' 
  9.  
  10.    default_root_device = _disk_prefix + 'a' 
  11.    default_local_device = _disk_prefix + 'b' 
  12.    default_swap_device = _disk_prefix + 'c' 
  13.  
  14.    def _volume_in_mapping(self, mount_device, block_device_info):  
  15.        block_device_list = [block_device.strip_dev(vol['mount_device'])  
  16.                             for vol in 
  17.                             driver.block_device_info_get_mapping(  
  18.                                 block_device_info)]  
  19.        swap = driver.block_device_info_get_swap(block_device_info)  
  20.        if driver.swap_is_usable(swap):  
  21.            block_device_list.append(  
  22.                block_device.strip_dev(swap['device_name']))  
  23.        block_device_list += [block_device.strip_dev(ephemeral['device_name'])  
  24.                              for ephemeral in 
  25.                              driver.block_device_info_get_ephemerals(  
  26.                                  block_device_info)]  
  27.  
  28.        LOG.debug(_("block_device_list %s"), block_device_list)  
  29.        return block_device.strip_dev(mount_device) in block_device_list  
  30.  
  31.    def _get_volume_device_info(self, device_path):  
  32.        if device_path.startswith('/dev/'):  
  33.            return ('block'NoneNone)  
  34.        elif ':' in device_path:  
  35.            (protocol, name) = device_path.split(':')  
  36.            return ('network', protocol, name)  
  37.        else:  
  38.            raise exception.InvalidDevicePath(path=device_path)  
  39.  
  40.    def _prepare_xml_info(self, instance, network_info, rescue,  
  41.                          block_device_info=None):  
  42.                       #感觉是返回的xml的信息  
  43.        block_device_mapping = driver.block_device_info_get_mapping(  
  44.            block_device_info)  
  45.  
  46.        nics = []  
  47.        for (network, mapping) in network_info:  
  48.            nics.append(self.vif_driver.plug(instance, network, mapping))  
  49.        # FIXME(vish): stick this in db  
  50.        inst_type_id = instance['instance_type_id']  
  51.        inst_type = instance_types.get_instance_type(inst_type_id)  
  52.  
  53.        if FLAGS.use_cow_p_w_picpaths:  
  54.            driver_type = 'qcow2' 
  55.        else:  
  56.            driver_type = 'raw' 
  57.  
  58.        for vol in block_device_mapping:  
  59.            vol['mount_device'] = block_device.strip_dev(vol['mount_device'])  
  60.            (vol['type'], vol['protocol'], vol['name']) = \  
  61.                self._get_volume_device_info(vol['device_path'])  
  62.  
  63.        ebs_root = self._volume_in_mapping(self.default_root_device,  
  64.                                           block_device_info)  
  65.  
  66.        local_device = False 
  67.        if not (self._volume_in_mapping(self.default_local_device,  
  68.                                        block_device_info) or 
  69.                0 in [eph['num'for eph in 
  70.                      driver.block_device_info_get_ephemerals(  
  71.                          block_device_info)]):  
  72.            if instance['local_gb'] > 0:  
  73.                local_device = self.default_local_device  
  74.  
  75.        ephemerals = []  
  76.        for eph in driver.block_device_info_get_ephemerals(block_device_info):  
  77.            ephemerals.append({'device_path': _get_eph_disk(eph),  
  78.                               'device': block_device.strip_dev(  
  79.                                   eph['device_name'])})  
  80.  
  81.        xml_info = {'type': FLAGS.libvirt_type,  
  82.                    'name': instance['name'],  
  83.                    'basepath': os.path.join(FLAGS.instances_path,  
  84.                                             instance['name']),  
  85.                    'memory_kb': inst_type['memory_mb'] * 1024,  
  86.                    'vcpus': inst_type['vcpus'],  
  87.                    'rescue': rescue,  
  88.                    'disk_prefix'self._disk_prefix,  
  89.                    'driver_type': driver_type,  
  90.                    'vif_type': FLAGS.libvirt_vif_type,  
  91.                    'nics': nics,  
  92.                    'ebs_root': ebs_root,  
  93.                    'local_device': local_device,  
  94.                    'volumes': block_device_mapping,  
  95.                    'use_virtio_for_bridges':  
  96.                            FLAGS.libvirt_use_virtio_for_bridges,  
  97.                    'ephemerals': ephemerals}  
  98.  
  99.        root_device_name = driver.block_device_info_get_root(block_device_info)  
  100.        if root_device_name:  
  101.            xml_info['root_device'] = block_device.strip_dev(root_device_name)  
  102.            xml_info['root_device_name'] = root_device_name  
  103.        else:  
  104.            # NOTE(yamahata):  
  105.            # for nova.api.ec2.cloud.CloudController.get_metadata()  
  106.            xml_info['root_device'] = self.default_root_device  
  107.            db.instance_update(  
  108.                nova_context.get_admin_context(), instance['id'],  
  109.                {'root_device_name''/dev/' + self.default_root_device})  
  110.  
  111.        if local_device:  
  112.            db.instance_update(  
  113.                nova_context.get_admin_context(), instance['id'],  
  114.                {'default_local_device''/dev/' + self.default_local_device})  
  115.  
  116.        swap = driver.block_device_info_get_swap(block_device_info)  
  117.        if driver.swap_is_usable(swap):  
  118.            xml_info['swap_device'] = block_device.strip_dev(  
  119.                swap['device_name'])  
  120.        elif (inst_type['swap'] > 0 and 
  121.              not self._volume_in_mapping(self.default_swap_device,  
  122.                                          block_device_info)):  
  123.            xml_info['swap_device'] = self.default_swap_device  
  124.            db.instance_update(  
  125.                nova_context.get_admin_context(), instance['id'],  
  126.                {'default_swap_device''/dev/' + self.default_swap_device})  
  127.  
  128.        config_drive = False 
  129.        if instance.get('config_drive'or instance.get('config_drive_id'):  
  130.            xml_info['config_drive'] = xml_info['basepath'] + "/disk.config" 
  131.  
  132.        if FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc''uml'):  
  133.            xml_info['vncserver_host'] = FLAGS.vncserver_host  
  134.            xml_info['vnc_keymap'] = FLAGS.vnc_keymap  
  135.        if not rescue:  
  136.            if instance['kernel_id']:  
  137.                xml_info['kernel'] = xml_info['basepath'] + "/kernel" 
  138.  
  139.            if instance['ramdisk_id']:  
  140.                xml_info['ramdisk'] = xml_info['basepath'] + "/ramdisk" 
  141.  
  142.            xml_info['disk'] = xml_info['basepath'] + "/disk" 
  143.        return xml_info  
  144.  
  145.    def to_xml(self, instance, network_info, rescue=False,  
  146.               block_device_info=None):  
  147.        # TODO(termie): cache?  
  148.        LOG.debug(_('instance %s: starting toXML method'), instance['name'])  
  149.        xml_info = self._prepare_xml_info(instance, network_info, rescue,  
  150.                                          block_device_info)  
  151.        xml = str(Template(self.libvirt_xml, searchList=[xml_info]))  
  152.        LOG.debug(_('instance %s: finished toXML method'), instance['name'])  
  153.        return xml  
  154.  
  155.    def _lookup_by_name(self, instance_name):  
  156.     #检索libvirt(授权)域对象 给定一个实例名 所有的 libvirt错误在这个 方法中 都应该有被处理的handler   
  157.        """Retrieve libvirt domain object given an instance name.  
  158.       
  159.  
  160.        All libvirt error handling should be handled in this method and  
  161.        relevant nova exceptions should be raised in response.  
  162.  
  163.        """ 
  164.        try:  
  165.            return self._conn.lookupByName(instance_name)  
  166.        except libvirt.libvirtError as ex:  
  167.            error_code = ex.get_error_code()  
  168.            if error_code == libvirt.VIR_ERR_NO_DOMAIN:  
  169.                raise exception.InstanceNotFound(instance_id=instance_name)  
  170.  
  171.            msg = _("Error from libvirt while looking up %(instance_name)s: " 
  172.                    "[Error Code %(error_code)s] %(ex)s") % locals()  
  173.            raise exception.Error(msg)  
  174.  
  175.    def get_info(self, instance_name):  
  176.     #为了一个特定的实例名从libvirt中检索信息 返回一个 字典  
  177.        """Retrieve information from libvirt for a specific instance name.  
  178.  
  179.        If a libvirt error is encountered during lookup, we might raise a  
  180.        NotFound exception or Error exception depending on how severe the  
  181.        libvirt error is.  
  182.  
  183.        """ 
  184.        virt_dom = self._lookup_by_name(instance_name)  
  185.        (state, max_mem, mem, num_cpu, cpu_time) = virt_dom.info()  
  186.        return {'state': state,  
  187.                'max_mem': max_mem,  
  188.                'mem': mem,  
  189.                'num_cpu': num_cpu,  
  190.                'cpu_time': cpu_time}  
  191.  
  192.    def _create_new_domain(self, xml, persistent=True, launch_flags=0):  
  193.     #创建一个新的域 返回值是domain  
  194.        # NOTE(justinsb): libvirt has two types of domain:  
  195.        # * a transient domain disappears when the guest is shutdown  
  196.        # or the host is rebooted.  
  197.        # * a permanent domain is not automatically deleted  
  198.        # NOTE(justinsb): Even for ephemeral instances, transient seems risky  
  199.  
  200.        if persistent:  
  201.            # To create a persistent domain, first define it, then launch it.  
  202.            domain = self._conn.defineXML(xml)  
  203.  
  204.            domain.createWithFlags(launch_flags)  
  205.        else:  
  206.            # createXML call creates a transient domain  
  207.            domain = self._conn.createXML(xml, launch_flags)  
  208.  
  209.        return domain  
  210.  
  211.    def get_diagnostics(self, instance_name):  
  212.     #诊断?  
  213.        raise exception.ApiError(_("diagnostics are not supported " 
  214.                                   "for libvirt"))  
  215.  
  216.    def get_disks(self, instance_name):  
  217.     #该函数接受一个实例名 作为参数 最后对于该域返回一个所有块devices的列表  
  218.        """  
  219.        Note that this function takes an instance name.  
  220.  
  221.        Returns a list of all block devices for this domain.  
  222.        """ 
  223.        domain = self._lookup_by_name(instance_name)  
  224.        # TODO(devcamcar): Replace libxml2 with etree.  
  225.        xml = domain.XMLDesc(0)  
  226.        doc = None 
  227.  
  228.        try:  
  229.            doc = libxml2.parseDoc(xml)  
  230.        except Exception:  
  231.            return []  
  232.  
  233.        ctx = doc.xpathNewContext()  
  234.        disks = []  
  235.  
  236.        try:  
  237.            ret = ctx.xpathEval('/domain/devices/disk')  
  238.  
  239.            for node in ret:  
  240.                devdst = None 
  241.  
  242.                for child in node.children:  
  243.                    if child.name == 'target':  
  244.                        devdst = child.prop('dev')  
  245.  
  246.                if devdst is None:  
  247.                    continue 
  248.  
  249.                disks.append(devdst)  
  250.        finally:  
  251.            if ctx is not None:  
  252.                ctx.xpathFreeContext()  
  253.            if doc is not None:  
  254.                doc.freeDoc()  
  255.  
  256.        return disks  
  257.  
  258.    def get_interfaces(self, instance_name):  
  259.        #该函数同样 接受一个 实例名作为参数 最后对于该 实例返回一个所有network interface的 列表  
  260.     """  
  261.        Note that this function takes an instance name.  
  262.  
  263.        Returns a list of all network interfaces for this instance.  
  264.        """ 
  265.        domain = self._lookup_by_name(instance_name)  
  266.        # TODO(devcamcar): Replace libxml2 with etree.  
  267.        xml = domain.XMLDesc(0)  
  268.        doc = None 
  269.  
  270.        try:  
  271.            doc = libxml2.parseDoc(xml)  
  272.        except Exception:  
  273.            return []  
  274.  
  275.        ctx = doc.xpathNewContext()  
  276.        interfaces = []  
  277.  
  278.        try:  
  279.            ret = ctx.xpathEval('/domain/devices/interface')  
  280.  
  281.            for node in ret:  
  282.                devdst = None 
  283.  
  284.                for child in node.children:  
  285.                    if child.name == 'target':  
  286.                        devdst = child.prop('dev')  
  287.  
  288.                if devdst is None:  
  289.                    continue 
  290.  
  291.                interfaces.append(devdst)  
  292.        finally:  
  293.            if ctx is not None:  
  294.                ctx.xpathFreeContext()  
  295.            if doc is not None:  
  296.                doc.freeDoc()  
  297.  
  298.        return interfaces  
  299.  
  300.    def get_vcpu_total(self):  
  301.     #得到虚拟处理器物理computermb 最后返回核心cpu的数量?  
  302.        """Get vcpu nuer of physical computermb.  
  303.  
  304.        :returns: the number of cpu core.  
  305.  
  306.        """ 
  307.  
  308.        # On certain platforms, this will raise a NotImplementedError.  
  309.        try:  
  310.            return multiprocessing.cpu_count()  
  311.        except NotImplementedError:  
  312.            LOG.warn(_("Cannot get the number of cpu, because this " 
  313.                       "function is not implemented for this platform. " 
  314.                       "This error can be safely ignored for now."))  
  315.            return 0 
  316.  
  317.    def get_memory_mb_total(self):  
  318. # 得到 总的物理电脑的内存   返回 总共的memory(MB)  
  319.        """Get the total memory size(MB) of physical computer.  
  320.  
  321.        :returns: the total amount of memory(MB).  
  322.  
  323.        """ 
  324.  
  325.        if sys.platform.upper() != 'LINUX2':  
  326.            return 0 
  327.  
  328.        meminfo = open('/proc/meminfo').read().split()  
  329.        idx = meminfo.index('MemTotal:')  
  330.        # transforming kb to mb.  
  331.        return int(meminfo[idx + 1]) / 1024 
  332.  
  333.    def get_local_gb_total(self):  
  334. #得到 总的硬盘驱动器的size 返回 总size 注意该值显示一个 实例挂载点分区的值  
  335.        """Get the total hdd size(GB) of physical computer.  
  336.  
  337.        :returns:  
  338.            The total amount of HDD(GB).  
  339.            Note that this value shows a partition where  
  340.            NOVA-INST-DIR/instances mounts.  
  341.  
  342.        """ 
  343.  
  344.        hddinfo = os.statvfs(FLAGS.instances_path)  
  345.        return hddinfo.f_frsize * hddinfo.f_blocks / 1024 / 1024 / 1024 
  346.  
  347.    def get_vcpu_used(self):  
  348. #得到一个可用 的物理电脑的虚拟处理器的number 最后返回当前用的total number of vcpu  
  349.        """ Get vcpu usage number of physical computer.  
  350.  
  351.        :returns: The total number of vcpu that currently used.  
  352.  
  353.        """ 
  354.  
  355.        total = 0 
  356.        for dom_id in self._conn.listDomainsID():  
  357.            dom = self._conn.lookupByID(dom_id)  
  358.            total += len(dom.vcpus()[1])  
  359.        return total  
  360.  
  361.    def get_memory_mb_used(self):  
  362. #得到物理计算机free内存大小 返回total usage内存(总使用)  
  363.        """Get the free memory size(MB) of physical computer.  
  364.  
  365.        :returns: the total usage of memory(MB).  
  366.  
  367.        """ 
  368.  
  369.        if sys.platform.upper() != 'LINUX2':  
  370.            return 0 
  371.  
  372.        m = open('/proc/meminfo').read().split()  
  373.        idx1 = m.index('MemFree:')  
  374.        idx2 = m.index('Buffers:')  
  375.        idx3 = m.index('Cached:')  
  376.        avail = (int(m[idx1 + 1]) + int(m[idx2 + 1]) + int(m[idx3 + 1])) / 1024 
  377.        return  self.get_memory_mb_total() - avail  
  378.  
  379.    def get_local_gb_used(self):  
  380.     #得到物理计算机(硬盘驱动器)free内存大小 返回total usage内存(总使用)  
  381.        """Get the free hdd size(GB) of physical computer.  
  382.  
  383.        :returns:  
  384.           The total usage of HDD(GB).  
  385.           Note that this value shows a partition where  
  386.           NOVA-INST-DIR/instances mounts.  
  387.  
  388.        """ 
  389.  
  390.        hddinfo = os.statvfs(FLAGS.instances_path)  
  391.        avail = hddinfo.f_frsize * hddinfo.f_bavail / 1024 / 1024 / 1024 
  392.        return self.get_local_gb_total() - avail  
  393.  
  394.    def get_hypervisor_type(self):  
  395. #得到管理程序的类型 最后返回 一个类型  
  396.        """Get hypervisor type.  
  397.  
  398.        :returns: hypervisor type (ex. qemu)  
  399.  
  400.        """ 
  401.  
  402.        return self._conn.getType()  
  403.  
  404.    def get_hypervisor_version(self):  
  405. #得到版本 返回版本  
  406.        """Get hypervisor version.  
  407.  
  408.        :returns: hypervisor version (ex. 12003)  
  409.  
  410.        """ 
  411.  
  412.        # NOTE(justinsb): getVersion moved between libvirt versions  
  413.        # Trying to do be compatible with older versions is a lost cause  
  414.        # But ... we can at least give the user a nice message  
  415.        method = getattr(self._conn, 'getVersion'None)  
  416.        if method is None:  
  417.            raise exception.Error(_("libvirt version is too old" 
  418.                                    " (does not support getVersion)"))  
  419.            # NOTE(justinsb): If we wanted to get the version, we could:  
  420.            # method = getattr(libvirt, 'getVersion', None)  
  421.            # NOTE(justinsb): This would then rely on a proper version check  
  422.  
  423.        return method()