Example #1
0
    def appendOs(self, use_serial_console=False):
        """
        Add <os> element to domain:

        <os>
            <type arch="x86_64" machine="pc">hvm</type>
            <boot dev="cdrom"/>
            <kernel>/tmp/vmlinuz-2.6.18</kernel>
            <initrd>/tmp/initrd-2.6.18.img</initrd>
            <cmdline>ARGs 1</cmdline>
            <smbios mode="sysinfo"/>
        </os>

        If 'use_serial_console' is true and we are on x86, use the console:

        <os>
            ...
            <bios useserial="yes"/>
        </os>

        """

        oselem = Element('os')
        self.dom.appendChild(oselem)

        DEFAULT_MACHINES = {cpuarch.X86_64: 'pc',
                            cpuarch.PPC64: 'pseries',
                            cpuarch.PPC64LE: 'pseries'}

        machine = self.conf.get('emulatedMachine', DEFAULT_MACHINES[self.arch])

        oselem.appendChildWithArgs('type', text='hvm', arch=self.arch,
                                   machine=machine)

        qemu2libvirtBoot = {'a': 'fd', 'c': 'hd', 'd': 'cdrom', 'n': 'network'}
        for c in self.conf.get('boot', ''):
            oselem.appendChildWithArgs('boot', dev=qemu2libvirtBoot[c])

        if self.conf.get('initrd'):
            oselem.appendChildWithArgs('initrd', text=self.conf['initrd'])

        if self.conf.get('kernel'):
            oselem.appendChildWithArgs('kernel', text=self.conf['kernel'])

        if self.conf.get('kernelArgs'):
            oselem.appendChildWithArgs('cmdline', text=self.conf['kernelArgs'])

        if cpuarch.is_x86(self.arch):
            oselem.appendChildWithArgs('smbios', mode='sysinfo')

        if utils.tobool(self.conf.get('bootMenuEnable', False)):
            oselem.appendChildWithArgs('bootmenu', enable='yes',
                                       timeout=str(_BOOT_MENU_TIMEOUT))

        if use_serial_console and cpuarch.is_x86(self.arch):
            oselem.appendChildWithArgs('bios', useserial='yes')
Example #2
0
    def appendOs(self, use_serial_console=False):
        """
        Add <os> element to domain:

        <os>
            <type arch="x86_64" machine="pc">hvm</type>
            <boot dev="cdrom"/>
            <kernel>/tmp/vmlinuz-2.6.18</kernel>
            <initrd>/tmp/initrd-2.6.18.img</initrd>
            <cmdline>ARGs 1</cmdline>
            <smbios mode="sysinfo"/>
        </os>

        If 'use_serial_console' is true and we are on x86, use the console:

        <os>
            ...
            <bios useserial="yes"/>
        </os>

        """

        oselem = Element('os')
        self.dom.appendChild(oselem)

        DEFAULT_MACHINES = {cpuarch.X86_64: 'pc',
                            cpuarch.PPC64: 'pseries',
                            cpuarch.PPC64LE: 'pseries'}

        machine = self.conf.get('emulatedMachine', DEFAULT_MACHINES[self.arch])

        oselem.appendChildWithArgs('type', text='hvm', arch=self.arch,
                                   machine=machine)

        qemu2libvirtBoot = {'a': 'fd', 'c': 'hd', 'd': 'cdrom', 'n': 'network'}
        for c in self.conf.get('boot', ''):
            oselem.appendChildWithArgs('boot', dev=qemu2libvirtBoot[c])

        if self.conf.get('initrd'):
            oselem.appendChildWithArgs('initrd', text=self.conf['initrd'])

        if self.conf.get('kernel'):
            oselem.appendChildWithArgs('kernel', text=self.conf['kernel'])

        if self.conf.get('kernelArgs'):
            oselem.appendChildWithArgs('cmdline', text=self.conf['kernelArgs'])

        if cpuarch.is_x86(self.arch):
            oselem.appendChildWithArgs('smbios', mode='sysinfo')

        if utils.tobool(self.conf.get('bootMenuEnable', False)):
            oselem.appendChildWithArgs('bootmenu', enable='yes',
                                       timeout=str(_BOOT_MENU_TIMEOUT))

        if use_serial_console and cpuarch.is_x86(self.arch):
            oselem.appendChildWithArgs('bios', useserial='yes')
Example #3
0
    def appendClock(self):
        """
        Add <clock> element to domain:

        <clock offset="variable" adjustment="-3600">
            <timer name="rtc" tickpolicy="catchup">
        </clock>

        for hyperv:
        <clock offset="variable" adjustment="-3600">
            <timer name="hypervclock" present="yes">
            <timer name="rtc" tickpolicy="catchup">
        </clock>
        """

        m = Element('clock', offset='variable',
                    adjustment=str(self.conf.get('timeOffset', 0)))
        if utils.tobool(self.conf.get('hypervEnable', 'false')):
            m.appendChildWithArgs('timer', name='hypervclock', present='yes')
        m.appendChildWithArgs('timer', name='rtc', tickpolicy='catchup')
        m.appendChildWithArgs('timer', name='pit', tickpolicy='delay')

        if cpuarch.is_x86(self.arch):
            m.appendChildWithArgs('timer', name='hpet', present='no')

        self.dom.appendChild(m)
Example #4
0
def uuid():
    host_UUID = None

    try:
        if os.path.exists(constants.P_VDSM_NODE_ID):
            with open(constants.P_VDSM_NODE_ID) as f:
                host_UUID = f.readline().replace("\n", "")
        else:
            arch = cpuarch.real()
            if cpuarch.is_x86(arch):
                ret, out, err = execCmd(
                    [constants.EXT_DMIDECODE, "-s", "system-uuid"],
                    raw=True,
                    sudo=True)
                out = '\n'.join(line for line in out.splitlines()
                                if not line.startswith('#'))

                if ret == 0 and 'Not' not in out:
                    # Avoid error string - 'Not Settable' or 'Not Present'
                    host_UUID = out.strip()
                else:
                    logging.warning('Could not find host UUID.')
            elif cpuarch.is_ppc(arch):
                # eg. output IBM,03061C14A
                try:
                    with open('/proc/device-tree/system-id') as f:
                        systemId = f.readline()
                        host_UUID = systemId.rstrip('\0').replace(',', '')
                except IOError:
                    logging.warning('Could not find host UUID.')

    except:
        logging.error("Error retrieving host UUID", exc_info=True)

    return host_UUID
Example #5
0
    def appendClock(self):
        """
        Add <clock> element to domain:

        <clock offset="variable" adjustment="-3600">
            <timer name="rtc" tickpolicy="catchup">
        </clock>

        for hyperv:
        <clock offset="variable" adjustment="-3600">
            <timer name="hypervclock" present="yes">
            <timer name="rtc" tickpolicy="catchup">
        </clock>
        """

        m = Element('clock', offset='variable',
                    adjustment=str(self.conf.get('timeOffset', 0)))
        if utils.tobool(self.conf.get('hypervEnable', 'false')):
            m.appendChildWithArgs('timer', name='hypervclock', present='yes')
        m.appendChildWithArgs('timer', name='rtc', tickpolicy='catchup')
        m.appendChildWithArgs('timer', name='pit', tickpolicy='delay')

        if cpuarch.is_x86(self.arch):
            m.appendChildWithArgs('timer', name='hpet', present='no')

        self.dom.appendChild(m)
Example #6
0
def _fake_caps_arch(caps, arch):
    '''
    Mutate 'caps' to act as an architecture set by fake_kvm_architecture
    configuration option.

    Arguments:

    caps        The host capabilities as returned by hooking.read_json.
    '''
    arch = arch

    caps['kvmEnabled'] = True

    if cpuarch.is_x86(arch):
        caps['emulatedMachines'] = _X86_64_MACHINES
        caps['cpuModel'] = 'Intel(Fake) CPU'

        flag_list = ['vmx', 'sse2', 'nx']

        if cpuarch.real() == cpuarch.X86_64:
            flag_list += cpuinfo.flags()

        flags = set(flag_list)

        caps['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
            'model_pentium2,model_pentium3,model_pentiumpro,' \
            'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
            'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
    elif cpuarch.is_ppc(arch):
        caps['emulatedMachines'] = _PPC64LE_MACHINES
        caps['cpuModel'] = 'POWER 8(fake)'
        caps['cpuFlags'] = 'powernv,model_POWER8'
    else:
        raise cpuarch.UnsupportedArchitecture(arch)
Example #7
0
def _fake_caps_arch(caps, arch):
    '''
    Mutate 'caps' to act as an architecture set by fake_kvm_architecture
    configuration option.

    Arguments:

    caps        The host capabilities as returned by hooking.read_json.
    '''
    arch = arch

    caps['kvmEnabled'] = True

    if cpuarch.is_x86(arch):
        caps['emulatedMachines'] = _X86_64_MACHINES
        caps['cpuModel'] = 'Intel(Fake) CPU'

        flag_list = ['vmx', 'sse2', 'nx']

        if cpuarch.real() == cpuarch.X86_64:
            flag_list += cpuinfo.flags()

        flags = set(flag_list)

        caps['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
            'model_pentium2,model_pentium3,model_pentiumpro,' \
            'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
            'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
    elif cpuarch.is_ppc(arch):
        caps['emulatedMachines'] = _PPC64LE_MACHINES
        caps['cpuModel'] = 'POWER 8(fake)'
        caps['cpuFlags'] = 'powernv,model_POWER8'
    else:
        raise cpuarch.UnsupportedArchitecture(arch)
Example #8
0
def getHardwareInfo(*args, **kwargs):
    arch = cpuarch.real()
    if cpuarch.is_x86(arch):
        from vdsm.dmidecodeUtil import getHardwareInfoStructure
        return getHardwareInfoStructure()
    elif cpuarch.is_ppc(arch):
        from vdsm.ppc64HardwareInfo import getHardwareInfoStructure
        return getHardwareInfoStructure()
    else:
        #  not implemented over other architecture
        return {}
Example #9
0
    def appendInput(self):
        """
        Add input device.

        <input bus="ps2" type="mouse"/>
        """
        if utils.tobool(self.conf.get('tabletEnable')):
            inputAttrs = {'type': 'tablet', 'bus': 'usb'}
        elif cpuarch.is_x86(self.arch):
            inputAttrs = {'type': 'mouse', 'bus': 'ps2'}
        else:
            inputAttrs = {'type': 'mouse', 'bus': 'usb'}

        self._devices.appendChildWithArgs('input', **inputAttrs)
Example #10
0
    def appendInput(self):
        """
        Add input device.

        <input bus="ps2" type="mouse"/>
        """
        if utils.tobool(self.conf.get('tabletEnable')):
            inputAttrs = {'type': 'tablet', 'bus': 'usb'}
        elif cpuarch.is_x86(self.arch):
            inputAttrs = {'type': 'mouse', 'bus': 'ps2'}
        else:
            inputAttrs = {'type': 'mouse', 'bus': 'usb'}

        self._devices.appendChildWithArgs('input', **inputAttrs)
Example #11
0
def make_minimal_domain(dom):
    """
    Enhance a Domain object, appending all the elements which
    - are not devices - which require extra logic
    - don't need additional logic or parameters, besides the trivial
      check on the CPU architecture.

    Args:
        dom (libvirtxml.Domain): domain object to enhance. It is recommended
            to use a freshly-built domain object, whose append* methods are
            not yet being called.

    Example:

    dom = make_minimal_domain(Domain(conf, log, arch))
    """
    dom.appendMetadata()
    dom.appendClock()
    if cpuarch.is_x86(dom.arch):
        dom.appendFeatures()
    return dom
Example #12
0
def uuid():
    host_UUID = None

    try:
        if os.path.exists(constants.P_VDSM_NODE_ID):
            with open(constants.P_VDSM_NODE_ID) as f:
                host_UUID = f.readline().replace("\n", "")
        else:
            arch = cpuarch.real()
            if cpuarch.is_x86(arch):
                ret, out, err = execCmd([constants.EXT_DMIDECODE,
                                         "-s",
                                         "system-uuid"],
                                        raw=True,
                                        sudo=True)
                out = '\n'.join(line for line in out.splitlines()
                                if not line.startswith('#'))

                if ret == 0 and 'Not' not in out:
                    # Avoid error string - 'Not Settable' or 'Not Present'
                    host_UUID = out.strip()
                else:
                    logging.warning('Could not find host UUID.')
            elif cpuarch.is_ppc(arch):
                # eg. output IBM,03061C14A
                try:
                    with open('/proc/device-tree/system-id') as f:
                        systemId = f.readline()
                        host_UUID = systemId.rstrip('\0').replace(',', '')
                except IOError:
                    logging.warning('Could not find host UUID.')

    except:
        logging.error("Error retrieving host UUID", exc_info=True)

    return host_UUID
Example #13
0
    def appendCpu(self):
        """
        Add guest CPU definition.

        <cpu match="exact">
            <model>qemu64</model>
            <topology sockets="S" cores="C" threads="T"/>
            <feature policy="require" name="sse2"/>
            <feature policy="disable" name="svm"/>
        </cpu>

        For POWER8, there is no point in trying to use baseline CPU for flags
        since there are only HW features. There are 2 ways of creating a valid
        POWER8 element that we support:

            <cpu>
                <model>POWER{X}</model>
            </cpu>

        This translates to -cpu POWER{X} (where {X} is version of the
        processor - 7 and 8), which tells qemu to emulate the CPU in POWER8
        family that it's capable of emulating - in case of hardware
        virtualization, that will be the host cpu (so an equivalent of
        -cpu host). Using this option does not limit migration between POWER8
        machines - it is still possible to migrate from e.g. POWER8 to
        POWER8e. The second option is not supported and serves only for
        reference:

            <cpu mode="host-model">
                <model>power{X}</model>
            </cpu>

        where {X} is the binary compatibility version of POWER that we
        require (6, 7, 8). This translates to qemu's -cpu host,compat=power{X}.

        Using the second option also does not limit migration between POWER8
        machines - it is still possible to migrate from e.g. POWER8 to POWER8e.
        """

        cpu = Element('cpu')

        if cpuarch.is_x86(self.arch):
            cpu.setAttrs(match='exact')

            features = self.conf.get('cpuType', 'qemu64').split(',')
            model = features[0]

            if model == 'hostPassthrough':
                cpu.setAttrs(mode='host-passthrough')
            elif model == 'hostModel':
                cpu.setAttrs(mode='host-model')
            else:
                cpu.appendChildWithArgs('model', text=model)

                # This hack is for backward compatibility as the libvirt
                # does not allow 'qemu64' guest on intel hardware
                if model == 'qemu64' and '+svm' not in features:
                    features += ['-svm']

                for feature in features[1:]:
                    # convert Linux name of feature to libvirt
                    if feature[1:6] == 'sse4_':
                        feature = feature[0] + 'sse4.' + feature[6:]

                    featureAttrs = {'name': feature[1:]}
                    if feature[0] == '+':
                        featureAttrs['policy'] = 'require'
                    elif feature[0] == '-':
                        featureAttrs['policy'] = 'disable'
                    cpu.appendChildWithArgs('feature', **featureAttrs)
        elif cpuarch.is_ppc(self.arch):
            features = self.conf.get('cpuType', 'POWER8').split(',')
            model = features[0]
            cpu.appendChildWithArgs('model', text=model)

        if ('smpCoresPerSocket' in self.conf or
                'smpThreadsPerCore' in self.conf):
            maxVCpus = int(self._getMaxVCpus())
            cores = int(self.conf.get('smpCoresPerSocket', '1'))
            threads = int(self.conf.get('smpThreadsPerCore', '1'))
            cpu.appendChildWithArgs('topology',
                                    sockets=str(maxVCpus / cores / threads),
                                    cores=str(cores), threads=str(threads))

        # CPU-pinning support
        # see http://www.ovirt.org/wiki/Features/Design/cpu-pinning
        if 'cpuPinning' in self.conf:
            cputune = Element('cputune')
            cpuPinning = self.conf.get('cpuPinning')
            for cpuPin in cpuPinning.keys():
                cputune.appendChildWithArgs('vcpupin', vcpu=cpuPin,
                                            cpuset=cpuPinning[cpuPin])
            self.dom.appendChild(cputune)

        # Guest numa topology support
        # see http://www.ovirt.org/Features/NUMA_and_Virtual_NUMA
        if 'guestNumaNodes' in self.conf:
            numa = Element('numa')
            guestNumaNodes = sorted(
                self.conf.get('guestNumaNodes'), key=itemgetter('nodeIndex'))
            for vmCell in guestNumaNodes:
                nodeMem = int(vmCell['memory']) * 1024
                numa.appendChildWithArgs('cell',
                                         cpus=vmCell['cpus'],
                                         memory=str(nodeMem))
            cpu.appendChild(numa)

        self.dom.appendChild(cpu)
Example #14
0
    def appendCpu(self):
        """
        Add guest CPU definition.

        <cpu match="exact">
            <model>qemu64</model>
            <topology sockets="S" cores="C" threads="T"/>
            <feature policy="require" name="sse2"/>
            <feature policy="disable" name="svm"/>
        </cpu>

        For POWER8, there is no point in trying to use baseline CPU for flags
        since there are only HW features. There are 2 ways of creating a valid
        POWER8 element that we support:

            <cpu>
                <model>POWER{X}</model>
            </cpu>

        This translates to -cpu POWER{X} (where {X} is version of the
        processor - 7 and 8), which tells qemu to emulate the CPU in POWER8
        family that it's capable of emulating - in case of hardware
        virtualization, that will be the host cpu (so an equivalent of
        -cpu host). Using this option does not limit migration between POWER8
        machines - it is still possible to migrate from e.g. POWER8 to
        POWER8e. The second option is not supported and serves only for
        reference:

            <cpu mode="host-model">
                <model>power{X}</model>
            </cpu>

        where {X} is the binary compatibility version of POWER that we
        require (6, 7, 8). This translates to qemu's -cpu host,compat=power{X}.

        Using the second option also does not limit migration between POWER8
        machines - it is still possible to migrate from e.g. POWER8 to POWER8e.
        """

        cpu = Element('cpu')

        if cpuarch.is_x86(self.arch):
            cpu.setAttrs(match='exact')

            features = self.conf.get('cpuType', 'qemu64').split(',')
            model = features[0]

            if model == 'hostPassthrough':
                cpu.setAttrs(mode='host-passthrough')
            elif model == 'hostModel':
                cpu.setAttrs(mode='host-model')
            else:
                cpu.appendChildWithArgs('model', text=model)

                # This hack is for backward compatibility as the libvirt
                # does not allow 'qemu64' guest on intel hardware
                if model == 'qemu64' and '+svm' not in features:
                    features += ['-svm']

                for feature in features[1:]:
                    # convert Linux name of feature to libvirt
                    if feature[1:6] == 'sse4_':
                        feature = feature[0] + 'sse4.' + feature[6:]

                    featureAttrs = {'name': feature[1:]}
                    if feature[0] == '+':
                        featureAttrs['policy'] = 'require'
                    elif feature[0] == '-':
                        featureAttrs['policy'] = 'disable'
                    cpu.appendChildWithArgs('feature', **featureAttrs)
        elif cpuarch.is_ppc(self.arch):
            features = self.conf.get('cpuType', 'POWER8').split(',')
            model = features[0]
            cpu.appendChildWithArgs('model', text=model)

        if ('smpCoresPerSocket' in self.conf or
                'smpThreadsPerCore' in self.conf):
            maxVCpus = int(self._getMaxVCpus())
            cores = int(self.conf.get('smpCoresPerSocket', '1'))
            threads = int(self.conf.get('smpThreadsPerCore', '1'))
            cpu.appendChildWithArgs('topology',
                                    sockets=str(maxVCpus / cores / threads),
                                    cores=str(cores), threads=str(threads))

        # CPU-pinning support
        # see http://www.ovirt.org/wiki/Features/Design/cpu-pinning
        if 'cpuPinning' in self.conf:
            cputune = Element('cputune')
            cpuPinning = self.conf.get('cpuPinning')
            for cpuPin in cpuPinning.keys():
                cputune.appendChildWithArgs('vcpupin', vcpu=cpuPin,
                                            cpuset=cpuPinning[cpuPin])
            self.dom.appendChild(cputune)

        # Guest numa topology support
        # see http://www.ovirt.org/Features/NUMA_and_Virtual_NUMA
        if 'guestNumaNodes' in self.conf:
            numa = Element('numa')
            guestNumaNodes = sorted(
                self.conf.get('guestNumaNodes'), key=itemgetter('nodeIndex'))
            for vmCell in guestNumaNodes:
                nodeMem = int(vmCell['memory']) * 1024
                numa.appendChildWithArgs('cell',
                                         cpus=vmCell['cpus'],
                                         memory=str(nodeMem))
            cpu.appendChild(numa)

        self.dom.appendChild(cpu)