integ/virt/libvirt/libvirt/hooks/qemu

128 lines
4.2 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script logs to user.log
#
# An instance with vTPM enable will have a QEMU config section in its XML file.
# e.g.
# <qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
# <qemu:arg value="-device"/>
# <qemu:arg value="tpm-tis,tpmdev=tpm-tpm0,id=tpm0"/>
# <qemu:arg value="-bios"/>
# <qemu:arg value="/guest/bios.bin"/>
# <qemu:arg value="-tpmdev"/>
# <qemu:arg value="cuse-tpm,id=tpm-tpm0,path=/dev/vtpm-instance-000001ad,cancel-path=/dev/null"/>
# </qemu:commandline>
#
# For more information see the vTPM HLD in /folk/cgts/docs/security/
#
# The script is called with the following parameters
# e.g. /etc/libvirt/hooks/qemu <guest_name> <operation>
#
# Save the instance's XML. The guest qemu hook scrips are given the full XML description
# on their stdin.
XML_DATA=$(/bin/cat)
GUEST_NAME=$1
shift
OPERATION=$*
logger -p info -t $0 "hook qemu file guest $GUEST_NAME with operation $OPERATION"
# CPU Low latency setup:
#
# A cpu is set to low latency when:
# 1) host is set to subfunction=lowlatency in platform.conf and
# 2) domain has dedicated pinning
#
# example of <cputune> section when domain has dedicated pinning:
# <cputune>
# <vcpupin vcpu='0' cpuset='5'/>
# <vcpupin vcpu='1' cpuset='6'/>
# <vcpupin vcpu='2' cpuset='7'/>
# <emulatorpin cpuset='5'/>
# </cputune>
#
# example of <cputune> section when domain has shared pinning:
# <cputune>
# <shares>4096</shares>
# <vcpupin vcpu='0' cpuset='5-21'/>
# <vcpupin vcpu='1' cpuset='5-21'/>
# <vcpupin vcpu='2' cpuset='5-21'/>
# <vcpupin vcpu='3' cpuset='5-21'/>
# <emulatorpin cpuset='5-21'/>
# </cputune>
if [ "${OPERATION}" == "prepare begin -" ] || [ "${OPERATION}" == "stopped end -" ]; then
# verify this host is set as lowlatency
lowlat=$(cat /etc/platform/platform.conf 2>/dev/null | grep -E 'subfunction.*lowlatency')
if [ -n "${lowlat}" ]; then
# grab the <cputune> settings and remove single quotes
CPUTUNE=$(echo ${XML_DATA} | grep -oP '(?<=<cputune).*?(?=</cputune>)' | sed "s/'//g")
# grab all cpuset pinned to a unique CPU. Treat them as dedicated
CPUSET=($(echo ${CPUTUNE} | grep -oP '(?<=cpuset=)[^/]+(?=.+emulator)' | grep -vP '[^0-9]'))
if [ ${#CPUSET[@]} -ne 0 ]; then
# convert to a comma separated list
CPUS=$(IFS=, ; echo "${CPUSET[*]}")
if [ "${OPERATION}" == "prepare begin -" ]; then
/usr/bin/set-cpu-wakeup-latency.sh "low" "${CPUS}"
else
/usr/bin/set-cpu-wakeup-latency.sh "high" "${CPUS}"
fi
fi
fi
fi
VTPM_OPER=""
if [ "$OPERATION" == "prepare begin -" ]; then
# Get the instance's uuid
UUID=$(echo $XML_DATA | grep -oP '(?<=<uuid>).*?(?=</uuid>)')
if [ -z "$UUID" ]; then
# This should not happen
logger -p err -t $0 "Failed to retrieve uuid for guest $GUEST_NAME"
exit 1
fi
# Grab the qemu line "<qemu:arg value='cuse-tpm ... "
LINE=$(echo $XML_DATA | grep -oP "(?<=<qemu:arg value=')[^<]+" | grep cuse-tpm )
if [ -z "$LINE" ]; then
# We do not setup a vTPM but we need to check if this Guest has previous vTPM data
# and if so delete it. This can happen when we Resize a Guest with a flavor that
# does not contain the vTPM extra spec xml data.
VTPM_OPER="clear"
else
# Extract the device name
VTPM=$(echo $LINE | tail -n1 | grep -Po '(?<=,path=)[^ ]+' | cut -d ',' -f1)
if [ -z "$VTPM" ]; then
# This instance does not require a vTPM. See comment above regarding "clear".
VTPM_OPER="clear"
else
logger -p info -t $0 "Found vTPM configuration for guest $GUEST_NAME"
VTPM_OPER="setup"
fi
fi
# Setup the vTPM device
/etc/libvirt/setup_vtpm "$VTPM_OPER" "/dev/vtpm-$GUEST_NAME" "$UUID" 2>&1 > /dev/null
rc=$?
if [[ $rc != 0 ]]; then
logger -p err -t $0 "setup_vtpm failed with return value $rc for device $VTPM and guest $UUID"
# Do not return error if we were just doing a clear
if [ "$VTPM_OPER" != "clear" ]; then
exit 1;
fi
fi
fi
exit 0