def test_config_host(self):
        xmlin = """
        <capabilities>
          <host>
            <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
            <cpu>
              <arch>x86_64</arch>
              <model>Opteron_G3</model>
              <vendor>AMD</vendor>
              <topology sockets='1' cores='4' threads='1'/>
              <feature name='ibs'/>
              <feature name='osvw'/>
            </cpu>
          </host>
          <guest>
            <os_type>hvm</os_type>
            <arch name='x86_64'/>
          </guest>
          <guest>
            <os_type>hvm</os_type>
            <arch name='i686'/>
          </guest>
        </capabilities>"""

        obj = config.LibvirtConfigCaps()
        obj.parse_str(xmlin)

        self.assertEqual(type(obj.host), config.LibvirtConfigCapsHost)
        self.assertEqual(obj.host.uuid, "c7a5fdbd-edaf-9455-926a-d65c16db1809")

        xmlout = obj.to_xml()

        self.assertXmlEqual(xmlin, xmlout)
Beispiel #2
0
    def get_capabilities(self):
        """Returns the host capabilities information

        Returns an instance of config.LibvirtConfigCaps representing
        the capabilities of the host.

        Note: The result is cached in the member attribute _caps.

        :returns: a config.LibvirtConfigCaps object
        """
        if not self._caps:
            xmlstr = self.get_connection().getCapabilities()
            LOG.info(_LI("Libvirt host capabilities %s"), xmlstr)
            self._caps = vconfig.LibvirtConfigCaps()
            self._caps.parse_str(xmlstr)
            if hasattr(libvirt, 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES'):
                try:
                    features = self.get_connection().baselineCPU(
                        [self._caps.host.cpu.to_xml()],
                        libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
                    # FIXME(wangpan): the return value of baselineCPU should be
                    #                 None or xml string, but libvirt has a bug
                    #                 of it from 1.1.2 which is fixed in 1.2.0,
                    #                 this -1 checking should be removed later.
                    if features and features != -1:
                        cpu = vconfig.LibvirtConfigCPU()
                        cpu.parse_str(features)
                        self._caps.host.cpu.features = cpu.features
                except libvirt.libvirtError as ex:
                    error_code = ex.get_error_code()
                    if error_code == libvirt.VIR_ERR_NO_SUPPORT:
                        LOG.warn(
                            _LW("URI %(uri)s does not support full set"
                                " of host capabilities: %(error)s"), {
                                    'uri': self._uri,
                                    'error': ex
                                })
                    else:
                        raise
            # PF9: Get sockets, cores and threads from lscpu instead of
            # libvirt
            try:
                (stdout, stderr) = processutils.execute("lscpu")
                lscpu_cpu_info = Host._parse_cpu_info_pf9(stdout)
                if set(['cores', 'sockets',
                        'threads']) == set(lscpu_cpu_info.keys()):
                    LOG.info("Using cpu information from lscpu")
                    self._caps.host.cpu.cores = lscpu_cpu_info["cores"]
                    self._caps.host.cpu.sockets = lscpu_cpu_info["sockets"]
                    self._caps.host.cpu.threads = lscpu_cpu_info["threads"]
                else:
                    LOG.info("Using cpu information from libvirt")
            except (OSError, processutils.ProcessExecutionError):
                # Looks like we can't use lscpu on this hypervisor. We continue
                # to use libvirt provided cores, socket and thread counts.
                LOG.info("Using cpu information from libvirt")
            # PF9 end
        return self._caps
Beispiel #3
0
    def get_capabilities(self):
        """Returns the host capabilities information

        Returns an instance of config.LibvirtConfigCaps representing
        the capabilities of the host.

        Note: The result is cached in the member attribute _caps.

        :returns: a config.LibvirtConfigCaps object
        """
        if not self._caps:
            xmlstr = self.get_connection().getCapabilities()
            LOG.info(_LI("Libvirt host capabilities %s"), xmlstr)
            self._caps = vconfig.LibvirtConfigCaps()
            self._caps.parse_str(xmlstr)
            # NOTE(mriedem): Don't attempt to get baseline CPU features
            # if libvirt can't determine the host cpu model.
            if (hasattr(libvirt, 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES')
                    and self._caps.host.cpu.model is not None):
                try:
                    features = self.get_connection().baselineCPU(
                        [self._caps.host.cpu.to_xml()],
                        libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
                    # FIXME(wangpan): the return value of baselineCPU should be
                    #                 None or xml string, but libvirt has a bug
                    #                 of it from 1.1.2 which is fixed in 1.2.0,
                    #                 this -1 checking should be removed later.
                    if features and features != -1:
                        cpu = vconfig.LibvirtConfigCPU()
                        cpu.parse_str(features)
                        self._caps.host.cpu.features = cpu.features
                except libvirt.libvirtError as ex:
                    error_code = ex.get_error_code()
                    if error_code == libvirt.VIR_ERR_NO_SUPPORT:
                        LOG.warn(
                            _LW("URI %(uri)s does not support full set"
                                " of host capabilities: "
                                "%(error)s"), {
                                    'uri': self._uri,
                                    'error': ex
                                })
                    else:
                        raise
        return self._caps
Beispiel #4
0
    def get_capabilities(self):
        """Returns the host capabilities information

        Returns an instance of config.LibvirtConfigCaps representing
        the capabilities of the host.

        Note: The result is cached in the member attribute _caps.

        :returns: a config.LibvirtConfigCaps object
        """
        if not self._caps:
            xmlstr = self.get_connection().getCapabilities()
            LOG.info("Libvirt host capabilities %s", xmlstr)
            self._caps = vconfig.LibvirtConfigCaps()
            self._caps.parse_str(xmlstr)
            # NOTE(mriedem): Don't attempt to get baseline CPU features
            # if libvirt can't determine the host cpu model.
            if (hasattr(libvirt, 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES')
                    and self._caps.host.cpu.model is not None):
                try:
                    xml_str = self._caps.host.cpu.to_xml()
                    if six.PY3 and isinstance(xml_str, six.binary_type):
                        xml_str = xml_str.decode('utf-8')
                    features = self.get_connection().baselineCPU(
                        [xml_str],
                        libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
                    if features:
                        cpu = vconfig.LibvirtConfigCPU()
                        cpu.parse_str(features)
                        self._caps.host.cpu.features = cpu.features
                except libvirt.libvirtError as ex:
                    error_code = ex.get_error_code()
                    if error_code == libvirt.VIR_ERR_NO_SUPPORT:
                        LOG.warning(
                            "URI %(uri)s does not support full set"
                            " of host capabilities: %(error)s", {
                                'uri': self._uri,
                                'error': ex
                            })
                    else:
                        raise
        return self._caps
Beispiel #5
0
    def get_capabilities(self):
        """Returns the host capabilities information

        Returns an instance of config.LibvirtConfigCaps representing
        the capabilities of the host.

        Note: The result is cached in the member attribute _caps.

        :returns: a config.LibvirtConfigCaps object
        """
        if not self._caps:
            xmlstr = self.get_connection().getCapabilities()
            LOG.info(_LI("Libvirt host capabilities %s"), xmlstr)
            self._caps = vconfig.LibvirtConfigCaps()
            self._caps.parse_str(xmlstr)
#            if False:
#                try:
#                    features = self.get_connection().baselineCPU(
#                        [self._caps.host.cpu.to_xml()],
#                        libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
#                    # FIXME(wangpan): the return value of baselineCPU should be
#                    #                 None or xml string, but libvirt has a bug
#                    #                 of it from 1.1.2 which is fixed in 1.2.0,
#                    #                 this -1 checking should be removed later.
#                    if features and features != -1:
#                        cpu = vconfig.LibvirtConfigCPU()
#                        cpu.parse_str(features)
#                        self._caps.host.cpu.features = cpu.features
#                except libvirt.libvirtError as ex:
#                    error_code = ex.get_error_code()
#                    if error_code == libvirt.VIR_ERR_NO_SUPPORT:
#                        LOG.warn(_LW("URI %(uri)s does not support full set"
#                                     " of host capabilities: " "%(error)s"),
#                                     {'uri': self._uri, 'error': ex})
#                    else:
#                        raise
        return self._caps
Beispiel #6
0
    def get_capabilities(self):
        """Returns the host capabilities information

        Returns an instance of config.LibvirtConfigCaps representing
        the capabilities of the host.

        Note: The result is cached in the member attribute _caps.

        :returns: a config.LibvirtConfigCaps object
        """
        if not self._caps:
            xmlstr = self.get_connection().getCapabilities()
            LOG.info("Libvirt host capabilities %s", xmlstr)
            self._caps = vconfig.LibvirtConfigCaps()
            self._caps.parse_str(xmlstr)
            # NOTE(mriedem): Don't attempt to get baseline CPU features
            # if libvirt can't determine the host cpu model.
            if (hasattr(libvirt, 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES')
                and self._caps.host.cpu.model is not None):
                try:
                    xml_str = self._caps.host.cpu.to_xml()
                    if six.PY3 and isinstance(xml_str, six.binary_type):
                        xml_str = xml_str.decode('utf-8')
                    features = self.get_connection().baselineCPU(
                        [xml_str],
                        libvirt.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
                    if features:
                        cpu = vconfig.LibvirtConfigCPU()
                        cpu.parse_str(features)
                        self._caps.host.cpu.features = cpu.features
                except libvirt.libvirtError as ex:
                    error_code = ex.get_error_code()
                    if error_code == libvirt.VIR_ERR_NO_SUPPORT:
                        LOG.warning("URI %(uri)s does not support full set"
                                    " of host capabilities: %(error)s",
                                     {'uri': self._uri, 'error': ex})
                    else:
                        raise

            # WRS - Simplify memory accounting by engineering out of maximum
            # VM available memory instead of total physical memory.
            # After this adjustment, cell.mempages[] only represents VM memory
            # and corresponds exactly match compute-huge.
            # The following adjustment also removes vswitch hugepages overheads
            # and 4K pages overheads from accounting.
            # Important: cell.memory obtained from getCapabilities() is KiB.
            # The NumaCell.memory field is in MiB as converted by routine
            # virt/libvirt/driver.py: _get_host_numa_topology().  This is
            # confusing since both use same variable name.
            topology = self._caps.host.topology
            if topology is None or not topology.cells:
                return self._caps
            vm_4K_nodes = self._get_configured_pages(
                csv=CONF.compute_vm_4K_pages)
            vs_2M_nodes = self._get_configured_pages(
                csv=CONF.compute_vswitch_2M_pages)
            vs_1G_nodes = self._get_configured_pages(
                csv=CONF.compute_vswitch_1G_pages)
            for cell in topology.cells:
                msg = []
                cell.memory = 0
                for k, pages in enumerate(cell.mempages):
                    pg = cell.mempages[k]
                    if pages.size == MEMPAGE_SZ_4K and vm_4K_nodes:
                        vm_4K = vm_4K_nodes[cell.id]
                        oh_4K = pg.total - vm_4K
                        pg.total -= oh_4K
                        cell.memory += (pg.total * pg.size)
                        MiB = oh_4K * MEMPAGE_SZ_4K // units.Ki
                        msg.append('%d MiB 4K overhead' % (MiB))
                    if pages.size == MEMPAGE_SZ_2M and vs_2M_nodes:
                        vs_2M = vs_2M_nodes[cell.id]
                        pg.total -= vs_2M
                        cell.memory += (pg.total * pg.size)
                        MiB = vs_2M * MEMPAGE_SZ_2M // units.Ki
                        msg.append('%d MiB 2M vswitch' % (MiB))
                    if pages.size == MEMPAGE_SZ_1G and vs_1G_nodes:
                        vs_1G = vs_1G_nodes[cell.id]
                        pg.total -= vs_1G
                        cell.memory += (pg.total * pg.size)
                        MiB = vs_1G * MEMPAGE_SZ_1G // units.Ki
                        msg.append('%d MiB 1G vswitch' % (MiB))
                LOG.info("cell:%(id)s exclude: %(msg)s",
                         {'id': cell.id, 'msg': '; '.join(msg)})
        return self._caps