1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-05-30 00:21:17 +00:00

arm-autonomy: Create xenguest-manager

Add xenguest-manager to handle xenguest image based guests:
- create guest (use LVM to create disks for guests)
- start/stop guests
- provide init script to have guest auto started on boot
- add documentation

Change-Id: I5319ecb77f3aa9f8c1aff4891c05973288156f11
Issue-Id: SCM-767
Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Diego Sueiro <diego.sueiro@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Bertrand Marquis
2020-04-02 18:08:11 +01:00
committed by Jon Mason
parent 37505ea4fc
commit 3ebc163110
7 changed files with 855 additions and 0 deletions
+4
View File
@@ -41,6 +41,7 @@ its documentation.
Those documentation files should be checked for variables: Those documentation files should be checked for variables:
- [xen-devicetree](documentation/xen-devicetree.md) - [xen-devicetree](documentation/xen-devicetree.md)
- [xenguest-manager](documentation/xenguest-manager.md)
BSPs BSPs
---- ----
@@ -70,6 +71,9 @@ This layer is adding the following recipes and classes:
* [xenguest-mkimage](documentation/xenguest-mkimage.md): this is a tool to * [xenguest-mkimage](documentation/xenguest-mkimage.md): this is a tool to
create and modify images to be used as Xen guests. create and modify images to be used as Xen guests.
* [xenguest-manager](documentation/xenguest-manager.md): this is a tool to
create/remove/start/stop xen guest generated using xenguest-mkimage.
Contributing Contributing
------------ ------------
This project has not put in place a process for contributions currently. If you This project has not put in place a process for contributions currently. If you
@@ -0,0 +1,67 @@
Xenguest Manager
================
Introduction
------------
xenguest-manager is a tool to manage Xenguest images generated by
[xenguest-mkimage](xenguest-mkimage.md).
On a Xen Dom0 system it will:
- create a xen guest from a xenguest image: extract its components, create a
disk for the guest using LVM volumes.
- start/stop a xen guest (during init or using xenguest-manager directly).
- check guest status
xenguest-manager is composed of 2 shell scripts:
- xenguest-manager which can be used from command line to start/stop/check
guests and create or remove guest using xenguest images.
- xenguest-init which is called during init to automatically create and start
some guests as part of the host init process.
Usage
-----
xenguest-manager must be called like this:
`xenguest-manager OPERATION [OPTIONS]`
The following operations are available:
- create XENGUEST_IMAGE [GUESTNAME]: create a guest from a xenguest image file
as guest GUESTNAME. If GUESTNAME is not given the image file name is used
without the xenguest extension.
- remove GUESTNAME: remove the guest GUESTNAME.
- start GUESTNAME: start the guest GUESTNAME.
- stop GUESTNAME: stop the guest GUESTNAME (this is using `xl stop` which is
sending a stop signal to the running guest).
- kill GUESTNAME: force stopping the guest GUESTNAME.
- list: list the available guests.
- status [GUESTNAME]: print the current status of GUESTNAME. If GUESTNAME is
not given, print the status of all guests.
For a detailed help on available options please use:
`xenguest-manager --help`
Bitbake parameters
------------------
Several parameters are available to configure the xenguest manager during Yocto
project compilation (those can be set in your project local.conf, for example).
The following parameters are available:
- XENGUEST_MANAGER_VOLUME_DEVICE: This is the device path used by the
xenguest-manager on the device to create LVM disks when guests have a disk
configuration.
This is set by default to "/dev/sda2".
- XENGUEST_MANAGER_VOLUME_NAME: This is the LVM volume name that the
xenguest-manager will create and use to create guest LVM disks.
This is set by default to "vg-xen".
- XENGUEST_MANAGER_GUEST_DIR: This is the directory on Dom0 where the
xenguest-manager will look for xenguest images to create during init. That's
the place where xenguest images can be added to have them automatically
created during next Dom0 boot. The xenguests found there will only be created
if they were not already before (the basename of the files is used as guest
name).
This is set by default to "/usr/share/guests".
@@ -16,6 +16,7 @@ IMAGE_INSTALL += " \
kernel-modules \ kernel-modules \
xen-base \ xen-base \
qemu \ qemu \
xenguest-manager \
" "
# Build xen-devicetree to produce a xen ready devicetree # Build xen-devicetree to produce a xen ready devicetree
@@ -0,0 +1,85 @@
#!/bin/bash
#
# xenguest Init Script to start and stop xenguests during boot
#
XENGUEST_CONF_BASE="/etc/xenguest"
if [ ! -f ${XENGUEST_CONF_BASE}/xenguest-manager.conf ]; then
echo "No xenguest manager configuration !!"
exit 1
fi
source ${XENGUEST_CONF_BASE}/xenguest-manager.conf
# Create guest list
guestlist=$(/usr/bin/xenguest-manager list)
# Unconfigured guests
case "$1" in
start)
echo "Starting xenguest"
# Create unconfigured guests
if [ -d ${XENGUEST_GUEST_DIR} ]; then
for f in $(find ${XENGUEST_GUEST_DIR} -name "*.xenguest" \
-exec basename {} .xenguest \;); do
if [ ! -f ${XENGUEST_CONF_BASE}/guests/${f}/guest.cfg ]; then
# Check if this guest should be auto booted
autoboot=$(/usr/bin/xenguest-mkimage dump-paramsconfig \
${XENGUEST_GUEST_DIR}/${f}.xenguest | \
grep GUEST_AUTOBOOT | sed -e "s,.*=,," | tr -d '"')
if [ "$autoboot" = "0" ]; then
echo "Do not create $f, autoboot disabled"
else
/usr/bin/xenguest-manager create \
${XENGUEST_GUEST_DIR}/${f}.xenguest
# Update guestlist
if [ $? -eq 0 ]; then
guestlist="${guestlist} ${f}"
fi
fi
fi
done
fi
if [ -n "${guestlist}" ]; then
for f in ${guestlist}; do
GUEST_AUTOBOOT="1"
if [ -f ${XENGUEST_CONF_BASE}/guests/${f}/params.cfg ]; then
source ${XENGUEST_CONF_BASE}/guests/${f}/params.cfg
fi
if [ "${GUEST_AUTOBOOT}" = "1" ]; then
/usr/bin/xenguest-manager start ${f}
fi
done
else
echo "No guest configured"
fi
;;
status)
true
;;
stop)
echo "Stopping xenguest"
for f in ${guestlist}; do
/usr/bin/xenguest-manager stop ${f}
done
;;
reload)
echo >&2 'Reload not available; use force-reload'; exit 1
;;
force-reload|restart)
echo "Restarting xenguest"
$0 stop
$0 start
;;
*)
# do not advertise unreasonable commands that there is no reason
# to use with this device
echo $"Usage: $0 {start|stop|status|restart|force-reload}"
exit 1
esac
exit $?
@@ -0,0 +1,640 @@
#!/bin/bash
# This script manages xenguest
#
set -u
this="$0"
XENGUEST_CONF_BASE="/etc/xenguest"
LOGFILE="/var/log/xenguest"
if [ ! -f ${XENGUEST_CONF_BASE}/xenguest-manager.conf ]; then
echo "Cannot find xenguest manager configuration"
exit 1
fi
# Following variables must be set in configuration:
# XENGUEST_VOLUME_DEVICE: device to use for lvm
# XENGUEST_VOLUME_NAME: lvm volume name to create on device
source ${XENGUEST_CONF_BASE}/xenguest-manager.conf
PREF="xenguest:"
if [ -z "${XENGUEST_VOLUME_DEVICE:-}" -o \
! -b ${XENGUEST_VOLUME_DEVICE:-} ]; then
echo "${PREF} Invalid volume device in configuration: ${XENGUEST_VOLUME_DEVICE:-}"
exit 1
fi
if [ -z "${XENGUEST_VOLUME_NAME:-}" ]; then
echo "${PREF} No volume name in configuration, using vg-xen..."
XENGUEST_VOLUME_NAME="vg-xen"
fi
function usage() {
cat <<EOF
Usage $this ACTION [OPTIONS]
with ACTION being one of:
help
Display this help
create GUESTFILE [GUESTNAME]
Create a guest using xenguest image GUESTFILE and name it GUESTNAME.
This will extract and configure the guest and will also create the guest
disk if guest has one configured.
GUESTNAME is set to the basename of GUESTFILE if unspecified.
GUESTNAME guest must not exist
remove GUESTNAME
Remove GUESTNAME and destroy its disk (if it has one)
start GUESTNAME
Start guest GUESTNAME
stop|shutdown GUESTNAME
Stop guest GUESTNAME (send stop signal and let it shutdown normally)
kill|destroy GUESTNAME
Kill guest GUESTNAME (stop directly the guest without signaling it)
list
List configured guests
status
List guests and their current status (running or stopped)
EOF
}
function xenguest_volume_init()
{
pvs ${XENGUEST_VOLUME_DEVICE} > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Initialize lvm on ${XENGUEST_VOLUME_DEVICE}"
echo "pvcreate -f ${XENGUEST_VOLUME_DEVICE}" >> ${LOGFILE} 2>&1
pvcreate -f ${XENGUEST_VOLUME_DEVICE} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error"
exit 1
fi
fi
vgs ${XENGUEST_VOLUME_NAME} > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Create ${XENGUEST_VOLUME_NAME} volume"
echo "vgcreate ${XENGUEST_VOLUME_NAME} ${XENGUEST_VOLUME_DEVICE}" \
>> ${LOGFILE} 2>&1
vgcreate ${XENGUEST_VOLUME_NAME} ${XENGUEST_VOLUME_DEVICE} \
>> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error"
exit 1
fi
fi
}
# Detach a disk we attached to xen
function xenguest_detach_disk()
{
echo "xl block-detach 0 \$\(xl block-list 0 | " \
"grep \"domain/0\" | awk '{print \$1}'\)" \
>> ${LOGFILE} 2>&1
xl block-detach 0 $(xl block-list 0 | \
grep "domain/0" | awk '{print $1}') \
>> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error detaching partition ${part}"
exit 1
fi
}
function xenguest_disk_init()
{
guestname="$1"
guestfile="$2"
devname="/dev/${XENGUEST_VOLUME_NAME}/${guestname}"
source ${XENGUEST_CONF_BASE}/guests/${guestname}/disk.cfg
if [ ${DISK_SIZE:-0} -eq 0 ]; then
echo "${PREF} No disk for ${guestname}"
return
fi
echo "${PREF} Create ${guestname} disk"
# Init our volume
xenguest_volume_init
echo "${PREF} Create hard drive for ${guestname}"
# Remove volume if it already exist
echo "lvs ${XENGUEST_VOLUME_NAME}/${guestname}" >> ${LOGFILE} 2>&1
lvs ${XENGUEST_VOLUME_NAME}/${guestname} >> ${LOGFILE} 2>&1
if [ $? -eq 0 ]; then
echo "lvremove -y ${devname}" >> ${LOGFILE} 2>&1
lvremove -y ${devname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error removing volume ${guestname}"
exit 1
fi
fi
# Create volume
echo "lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME}" \
>> ${LOGFILE} 2>&1
lvcreate -y -L ${DISK_SIZE}G -n ${guestname} ${XENGUEST_VOLUME_NAME} \
>> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error creating volume ${guestname}"
exit 1
fi
# Add partition table
echo "parted -s ${devname} mklabel msdos" >> ${LOGFILE} 2>&1
parted -s ${devname} mklabel msdos >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error creating partition table on ${guestname}"
exit 1
fi
# Setup disk name in xen configuration
echo "xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname}" \
"--xen-disk=${devname}" >> ${LOGFILE} 2>&1
xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname} \
--xen-disk=${devname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error setting disk in xen configuration"
exit 1
fi
# Create partitions
partstart="0"
# For each partition X the disk.cfg file should set a variable DISK_PARTX
# with a : separated list defining the partition:
# DISK_PART3="4:ext4:disk.tgz" means that partition 3 should be 4G formated
# with ext4 and initialized with the content of disk.tgz
for part in $(seq 1 4); do
eval partdesc="\${DISK_PART${part}:-0}"
size=$(echo ${partdesc} | sed -e "s/\(.*\):.*:.*/\1/")
fstype=$(echo ${partdesc} | sed -e "s/.*:\(.*\):.*/\1/")
content=$(echo ${partdesc} | sed -e "s/.*:.*:\(.*\)/\1/")
if [ "${size}" -ne 0 ]; then
# Size is expressed in GB, pass it in MB
size=$(expr ${size} \* 1024)
partend=$(expr ${partstart} + ${size})
# Let first MB of disk free for partition table
if [ ${partstart} -eq 0 ]; then
partstart="1"
fi
# Create partition
echo "parted -s ${devname} unit MB mkpart primary ${partstart}" \
"${partend}" >> ${LOGFILE} 2>&1
parted -s ${devname} unit MB mkpart primary ${partstart} \
${partend} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error adding partition ${part}"
exit 1
fi
# Set next partition start to current partition end
partstart="${partend}"
# Sync to see the created partition
echo "sync" >> ${LOGFILE} 2>&1
sync >> ${LOGFILE} 2>&1
# Prepare format command
if [ -n "${fstype}" ]; then
case ${fstype} in
vfat|ext2|ext3|ext4)
formatcmd="mkfs.${fstype} -F"
;;
swap)
formatcmd="mkswap"
;;
*)
echo "${PREF} partition ${part} of ${guestname}" \
"fstype is invalid: ${fstype}"
exit 1
;;
esac
else
formatcmd=""
fi
# Attach disk to xen
echo "xl block-attach 0 phy:${devname} xvda w" >> ${LOGFILE} 2>&1
xl block-attach 0 phy:${devname} xvda w >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error attaching partition ${part}"
exit 1
fi
# Sometimes it takes time to see the device
if [ ! -b /dev/xvda${part} ]; then
sleep 1
fi
if [ ! -b /dev/xvda${part} ]; then
echo "${PREF} Partition ${part} creation error"
xenguest_detach_disk
exit 1
fi
if [ -n "${formatcmd}" ]; then
echo "${formatcmd} /dev/xvda${part}" >> ${LOGFILE} 2>&1
${formatcmd} /dev/xvda${part}
if [ $? -ne 0 ]; then
echo "${PREF} Cannot create partition ${part} FS"
xenguest_detach_disk
exit 1
fi
fi
case ${content} in
*.img)
# dd into partition
echo "xenguest-mkimage extract-disk-file ${guestfile} " \
"${content} | dd of=/dev/xvda${part} " >> ${LOGFILE} 2>&1
xenguest-mkimage extract-disk-file ${guestfile} ${content} \
| dd of=/dev/xvda${part} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Cannot populate partition ${part}"
xenguest_detach_disk
exit 1
fi
;;
*.tar*)
tararg=""
case ${content} in
*.tar.gz)
tararg="z"
;;
*.tar.bz2)
tararg="j"
;;
*.tar.xz)
tararg="J"
;;
*.tar)
tararg=""
;;
*)
# invalid/unknown tar type
echo "${PREF} Invalid file format in disk ${content}"
xenguest_detach_disk
exit 1
;;
esac
# must mount the partition and extract
mntdir=$(mktemp -d)
echo "mount /dev/xvda${part} ${mntdir}" >> ${LOGFILE} 2>&1
mount /dev/xvda${part} ${mntdir} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Cannot mount partition ${part}"
xenguest_detach_disk
rm -rf ${mntdir}
exit 1
fi
# tar and unmount
echo "xenguest-mkimage extract-disk-file ${guestfile}" \
"${content} | tar -C ${mntdir} -x${tararg}f - " \
>> ${LOGFILE} 2>&1
xenguest-mkimage extract-disk-file ${guestfile} ${content} \
| tar -C ${mntdir} -x${tararg}f - >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Cannot populate partition ${part}"
umount ${mntdir}
rm -rf ${mntdir}
xenguest_detach_disk
exit 1
fi
echo "umount ${mntdir}" >> ${LOGFILE} 2>&1
umount ${mntdir} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error unmounting ${part}"
xenguest_detach_disk
rm -rf ${mntdir}
exit 1
fi
rm -rf ${mntdir}
;;
*)
#invalid content type
;;
esac
# Detach disk
xenguest_detach_disk
fi
done
}
function xenguest_guest_create()
{
guestfile="$1"
guestname="$2"
# extract xenguest tar
# put xen config in etc ?
# if disk config file:
# disk init
# add partititions
echo "${PREF} Create ${guestname} using ${guestfile}"
rm -rf ${XENGUEST_CONF_BASE}/guests/${guestname}
mkdir -p ${XENGUEST_CONF_BASE}/guests/${guestname}
echo "xenguest-mkimage extract-config ${guestfile}" \
"${XENGUEST_CONF_BASE}/guests/${guestname}" >> ${LOGFILE} 2>&1
xenguest-mkimage extract-config ${guestfile} \
${XENGUEST_CONF_BASE}/guests/${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error extracting guest image"
exit 1
fi
# Set guest name inside config
echo "xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname}" \
"--xen-name=${guestname}" >> ${LOGFILE} 2>&1
xenguest-mkimage update ${XENGUEST_CONF_BASE}/guests/${guestname} \
--xen-name=${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error setting guest name"
exit 1
fi
xenguest_disk_init ${guestname} ${guestfile}
}
function xenguest_guest_remove()
{
guestname="$1"
devname="/dev/${XENGUEST_VOLUME_NAME}/${guestname}"
# check if guest had a volume
echo "lvs ${XENGUEST_VOLUME_NAME}/${guestname}" >> ${LOGFILE} 2>&1
lvs ${XENGUEST_VOLUME_NAME}/${guestname} >> ${LOGFILE} 2>&1
if [ $? -eq 0 ]; then
# Remove guest volume
echo "lvremove -y ${devname}" >> ${LOGFILE} 2>&1
lvremove -y ${devname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error removing volume ${guestname}"
exit 1
fi
fi
# remove guest files
rm -rf ${XENGUEST_CONF_BASE}/guests/${guestname}
}
function xenguest_guest_start()
{
guestname="${1}"
guestdir=${XENGUEST_CONF_BASE}/guests/${guestname}
# Get guest configuration
source ${guestdir}/params.cfg
pushd ${guestdir} > /dev/null 2>&1
# create config by merging all configurations together
cat guest.cfg $(find guest.d -type f 2> /dev/null) > ${guestname}.cfg
# Build init script lists (ignore non existing dirs errors,
# sort alphabetically and run global scripts first)
init_pre="$(find ${XENGUEST_CONF_BASE}/init.pre -type f 2> /dev/null | \
sort) $(find ${guestdir}/init.pre -type f 2> /dev/null | sort)"
init_d="$(find ${XENGUEST_CONF_BASE}/init.d -type f 2> /dev/null | \
sort) $(find ${guestdir}/init.d -type f 2> /dev/null | sort)"
init_post="$(find ${XENGUEST_CONF_BASE}/init.post -type f 2> /dev/null | \
sort) $(find ${guestdir}/init.post -type f 2> /dev/null | sort)"
# call pre init scripts
for f in ${init_pre}; do
echo "$f ${guestname}" >> ${LOGFILE} 2>&1
$f ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
rm -f ${guestname}.cfg
popd > /dev/null 2>&1
echo "${PREF} Error during pre init script of ${guestname}"
exit 1
fi
done
# Create non started guest
echo "xl create -p ${guestname}.cfg" >> ${LOGFILE} 2>&1
xl create -p ${guestname}.cfg >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
rm -f ${guestname}.cfg
popd > /dev/null 2>&1
echo "${PREF} Error starting ${guestname}"
exit 1
fi
# call init scripts
for f in ${init_d}; do
echo "$f ${guestname}" >> ${LOGFILE} 2>&1
$f ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
rm -f ${guestname}.cfg
echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1
xl destroy ${guestname} >> ${LOGFILE} 2>&1
popd > /dev/null 2>&1
echo "${PREF} Error during init script of ${guestname}"
exit 1
fi
done
# Start guest
echo "xl unpause ${guestname}" >> ${LOGFILE} 2>&1
xl unpause ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
rm -f ${guestname}.cfg
popd > /dev/null 2>&1
echo "${PREF} Error starting ${guestname}"
exit 1
fi
# call post init scripts
for f in ${init_post}; do
echo "$f ${guestname}" >> ${LOGFILE} 2>&1
$f ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
rm -f ${guestname}.cfg
echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1
xl destroy ${guestname} >> ${LOGFILE} 2>&1
popd > /dev/null 2>&1
echo "${PREF} Error during post init script of ${guestname}"
exit 1
fi
done
rm -f ${guestname}.cfg
popd > /dev/null 2>&1
}
function xenguest_guest_stop()
{
guestname="${1}"
echo "xl shutdown ${guestname}" >> ${LOGFILE} 2>&1
xl shutdown ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error stopping ${guestname}"
exit 1
fi
}
function check_guest_arg()
{
cmd="${1}"
guestname="${2:-}"
if [ -z "${guestname:-}" ]; then
echo "${PREF} Usage ${this} ${cmd} GUESTNAME"
exit 1
fi
}
function check_guest_exist()
{
guestname="${1}"
if [ ! -f ${XENGUEST_CONF_BASE}/guests/${guestname}/guest.cfg -o \
! -f ${XENGUEST_CONF_BASE}/guests/${guestname}/params.cfg ]; then
echo "${PREF} Invalid guest name: ${guestname}"
exit 1
fi
}
function check_guest_running()
{
guestname="${1}"
running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" || echo)
if [ ! "${running}" = "${guestname}" ]; then
echo "${PREF} Guest ${guestname} is not running"
exit 1
fi
}
function check_guest_not_running()
{
guestname="${1}"
running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" || echo)
if [ "${running}" = "${guestname}" ]; then
echo "${PREF} Guest ${guestname} is running"
exit 1
fi
}
cmd="${1:-help}"
arg1="${2:-}"
arg2="${3:-}"
case ${cmd} in
help|--help|-h|-?)
usage
exit 0
;;
create)
guestfile="${arg1}"
guestname="${arg2}"
if [ -z "${guestfile}" -o ! -f "${guestfile}" ]; then
echo "${PREF} Usage ${this} create XENGUEST_FILE [NAME]"
exit 1
fi
if [ -z "${guestname}" ]; then
guestname=$(basename ${guestfile} .xenguest)
fi
if [ -f ${XENGUEST_CONF_BASE}/guests/${guestname}/guest.cfg ]; then
# Guest already exist
echo "${PREF} A guest ${guestname} already exist"
exit 1
fi
xenguest_guest_create ${guestfile} ${guestname}
;;
remove)
guestname="${arg1:-}"
check_guest_arg ${cmd} ${guestname}
check_guest_exist ${guestname}
# We need to stop the guest first
running=$(xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" \
|| echo)
if [ "${running}" = "${guestname}" ]; then
echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1
xl destroy ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error killing ${guestname}"
exit 1
fi
fi
xenguest_guest_remove ${guestname}
;;
start)
guestname="${arg1:-}"
check_guest_arg ${cmd} ${guestname}
check_guest_exist ${guestname}
check_guest_not_running ${guestname}
xenguest_guest_start ${guestname}
;;
stop|shutdown)
guestname="${arg1:-}"
check_guest_arg ${cmd} ${guestname}
check_guest_exist ${guestname}
check_guest_running ${guestname}
xenguest_guest_stop ${guestname}
;;
kill|destroy)
guestname="${arg1:-}"
check_guest_arg ${cmd} ${guestname}
check_guest_exist ${guestname}
check_guest_running ${guestname}
echo "xl destroy ${guestname}" >> ${LOGFILE} 2>&1
xl destroy ${guestname} >> ${LOGFILE} 2>&1
if [ $? -ne 0 ]; then
echo "${PREF} Error killing ${guestname}"
exit 1
fi
;;
list)
if [ -d ${XENGUEST_CONF_BASE}/guests ]; then
for f in $(find ${XENGUEST_CONF_BASE}/guests -mindepth 1 \
-maxdepth 1 -type d -exec basename {} \;); do
if [ -f ${XENGUEST_CONF_BASE}/guests/$f/guest.cfg ]; then
echo "$f"
fi
done
fi
;;
status)
guestname="${arg1}"
if [ -n "${guestname}" ]; then
check_guest_exist ${guestname}
if xl list | awk 'NR > 1 {print $1}' | grep "${guestname}" > \
/dev/null 2>&1; then
echo "${guestname}: Running"
else
echo "${guestname}: Stopped"
fi
else
guestlist=$($this list)
if [ -n "${guestlist}" ]; then
for f in ${guestlist}; do
$this status $f
done
fi
fi
;;
*)
echo "${PREF} Invalid argument ${cmd}"
exit 1
;;
esac
@@ -0,0 +1,52 @@
# Xenguest manager recipe
#
# xenguest-manager is a tool to control xen guest (e.g. create, start, stop)
#
DESCRIPTION = "Xen Guest Manager"
LICENSE = "MIT"
SRC_URI = " \
file://xenguest-manager \
file://xenguest-init \
"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
S = "${WORKDIR}"
# Please refer to documentation/xenguest-manager.md for documentation on those
# parameters
XENGUEST_MANAGER_VOLUME_DEVICE ?= "/dev/sda2"
XENGUEST_MANAGER_VOLUME_NAME ?= "vg-xen"
XENGUEST_MANAGER_GUEST_DIR ?= "${datadir}/guests/"
# We add an init script to create and start guests automatically
INITSCRIPT_NAME = "xenguest"
INITSCRIPT_PARAMS = "defaults 90"
inherit update-rc.d
do_compile() {
echo "XENGUEST_VOLUME_DEVICE=\"${XENGUEST_MANAGER_VOLUME_DEVICE}\"" > \
xenguest-manager.conf
echo "XENGUEST_VOLUME_NAME=\"${XENGUEST_MANAGER_VOLUME_NAME}\"" >> \
xenguest-manager.conf
echo "XENGUEST_GUEST_DIR=\"${XENGUEST_MANAGER_GUEST_DIR}\"" >> \
xenguest-manager.conf
}
do_install() {
install -d -m 755 ${D}${bindir}
install -m 755 xenguest-manager ${D}${bindir}/.
install -d -m 755 ${D}${sysconfdir}/xenguest
install -m 644 xenguest-manager.conf ${D}${sysconfdir}/xenguest/.
install -d -m 755 ${D}${sysconfdir}/init.d
install -m 755 xenguest-init ${D}${sysconfdir}/init.d/${INITSCRIPT_NAME}
install -d -m 755 ${D}${XENGUEST_GUEST_DIR}
}
# Things that we need on the target
RDEPENDS_${PN} += "bash tar xenguest-mkimage lvm2 xen-xl parted e2fsprogs"
FILES_${PN} += "${bindir}/xenguest-manager \
${sysconfdir}/xenguest"
@@ -0,0 +1,6 @@
# Board specific configuration for the manager
# FVP and Foundation are using vda as hard drive and partition 2 is the
# default rootfs, so use vda3 for guest lvm
XENGUEST_MANAGER_VOLUME_DEVICE_foundation-armv8 ?= "/dev/vda3"
XENGUEST_MANAGER_VOLUME_DEVICE_fvp-base ?= "/dev/vda3"