File build-vm of Package build
#
# VM specific functions for the build script
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
# Only protecting nonroot from root inside guest -> but anyone can be root inside guest
# so disabling spectre/meltdown mitigations doesn't hurt security and gains performance
vm_linux_kernel_parameter="mitigations=off"
# Make sure that dodgy kernels fail quickly and early
vm_linux_always_append="oops=panic panic=1"
# guest visible devices
VM_ROOTDEV=/dev/hda1
VM_SWAPDEV=/dev/hda2
VM_TYPE=
declare -a VM_ARGS
VM_TYPE_PRIVILEGED=
VM_ROOT=
VM_SWAP=
VM_ROOT_TYPE=
VM_SWAP_TYPE=
VM_KERNEL=
VM_INITRD=
VM_CMDLINE=
VM_WORKER=
VM_SERVER=
# the qemu default size is not able to run our default kernel anymore
VM_MEMSIZE=512
VM_NETWORK=
VM_NETOPT=()
VM_NETDEVOPT=()
VM_DEVICEOPT=()
VM_TELNET=
VM_CONSOLE_INPUT=
VM_USER=
VM_USE_MKFS_COPYIN=
VMDISK_ROOTSIZE=4096
VMDISK_SWAPSIZE=1024
VMDISK_FILESYSTEM=
VMDISK_MOUNT_OPTIONS=__default
VMDISK_CLEAN=
VM_HOSTNAME=
# zvm specific?
VM_WORKER_NO=
# kvm specific?
HUGETLBFSPATH=
VM_CUSTOMOPT=
# emulator specific?
EMULATOR_SCRIPT=
# openstack specific
VM_OPENSTACK_FLAVOR=
for i in ec2 emulator kvm lxc openstack qemu uml xen zvm docker pvm nspawn; do
. "$BUILD_DIR/build-vm-$i"
done
VM_WATCHDOG=
VM_WATCHDOG_PID=
# the following functions just call the corresponding vm versions
vm_verify_options() {
vm_verify_options_$VM_TYPE "$@"
}
vm_attach_root() {
vm_attach_root_$VM_TYPE "$@"
}
vm_attach_swap() {
vm_attach_swap_$VM_TYPE "$@"
}
vm_detach_root() {
vm_detach_root_$VM_TYPE "$@"
}
vm_detach_swap() {
vm_detach_swap_$VM_TYPE "$@"
}
vm_fixup() {
test -z "$BUILD_VERBOSE_VM" && vm_linux_always_append="$vm_linux_always_append quiet"
vm_fixup_$VM_TYPE "$@"
}
vm_startup() {
vm_startup_$VM_TYPE "$@"
}
vm_sysrq() {
vm_sysrq_$VM_TYPE "$@"
}
vm_kill() {
vm_kill_$VM_TYPE "$@"
}
vm_cleanup() {
kill_watchdog
vm_cleanup_$VM_TYPE "$@"
}
vm_parse_options() {
case ${PARAM/#--/-} in
-vm-emulator-script|-emulator-script)
needarg
EMULATOR_SCRIPT="$ARG"
shift
;;
-xen|-kvm|-uml|-qemu|-emulator)
VM_TYPE=${PARAM##*-}
test -z "$VM_ROOT" && VM_ROOT=1
if test -n "$ARG" ; then
VM_ROOT="$ARG"
shift
fi
;;
-zvm|-lxc)
VM_TYPE=${PARAM##*-}
shift
;;
-vm-type)
needarg
VM_TYPE="$ARG"
case "$VM_TYPE" in
docker:privileged|nspawn:privileged)
VM_TYPE_PRIVILEGED=true
VM_TYPE=${VM_TYPE%:*}
;;
lxc|docker|nspawn) ;;
ec2|xen|kvm|uml|qemu|emulator|openstack|zvm|pvm)
test -z "$VM_ROOT" && VM_ROOT=1
;;
none|chroot) VM_TYPE= ;;
*)
cleanup_and_exit 1 "VM '$VM_TYPE' is not supported"
;;
esac
shift
;;
-vm-args)
needarg
eval "VM_ARGS=($ARG)"
shift
;;
-vm-worker)
needarg
VM_WORKER="$ARG"
shift
;;
-vm-worker-nr|-vm-worker-no)
needarg
VM_WORKER_NO="$ARG"
shift
;;
-vm-server|-vm-region)
needarg
VM_SERVER="$ARG"
shift
;;
-vm-disk)
needarg
VM_ROOT="$ARG"
shift
;;
-vm-swap|-xenswap|-swap)
needarg
VM_SWAP="$ARG"
shift
;;
-vm-use-mkfs-copyin)
VM_USE_MKFS_COPYIN="true"
;;
-vm-memory|-xenmemory|-memory)
needarg
VM_MEMSIZE="$ARG"
shift
;;
-vm-kernel)
needarg
VM_KERNEL="$ARG"
shift
;;
-vm-initrd)
needarg
VM_INITRD="$ARG"
shift
;;
-vm-cmdline)
needarg
VM_CMDLINE="$ARG"
shift
;;
-vm-disk-size|-vmdisk-rootsize)
needarg
VMDISK_ROOTSIZE="$ARG"
shift
;;
-vm-swap-size|-vmdisk-swapsize)
needarg
VMDISK_SWAPSIZE="$ARG"
shift
;;
-vm-disk-filesystem|-vmdisk-filesystem)
needarg
VMDISK_FILESYSTEM="$ARG"
shift
;;
-vm-disk-filesystem-options|-vmdisk-filesystem-options)
needarg
VMDISK_FILESYSTEM_OPTIONS="$ARG"
shift
;;
-vm-disk-mount-options|-vmdisk-mount-options)
needarg
VMDISK_MOUNT_OPTIONS="$ARG"
# silly code for compat with old bs_worker versions...
if test "$1" != "----noarg=$PARAM" -a "$ARG" != "${ARG#\"}" -a "$ARG" != "${ARG%\"}" ; then
VMDISK_MOUNT_OPTIONS="${VMDISK_MOUNT_OPTIONS#\"}"
VMDISK_MOUNT_OPTIONS="${VMDISK_MOUNT_OPTIONS%\"}"
fi
shift
;;
-vm-disk-clean|-vmdisk-clean)
# delete old root/swap to get rid of the old blocks
VMDISK_CLEAN=true
;;
-vm-hugetlbfs|-hugetlbfs)
needarg
HUGETLBFSPATH="$ARG"
shift
;;
-vm-watchdog)
VM_WATCHDOG=true
;;
-vm-user)
needarg
VM_USER="$ARG"
shift
;;
-vm-enable-console)
VM_CONSOLE_INPUT=true
;;
-vm-telnet)
needarg
VM_TELNET="$ARG"
shift
;;
-vm-network)
VM_NETWORK=true
VM_NETDEVOPT=("${VM_NETDEVOPT[@]}" user,id=u1,host=10.0.2.2,net=10.0.2.0/24)
VM_DEVICEOPT=("${VM_DEVICEOPT[@]}" e1000,netdev=u1)
shift
;;
-vm-net)
needarg
VM_NETOPT=("${VM_NETOPT[@]}" "$ARG")
shift
;;
-vm-netdev)
needarg
VM_NETDEVOPT=("${VM_NETDEVOPT[@]}" "$ARG")
shift
;;
-vm-device)
needarg
VM_DEVICEOPT=("${VM_DEVICEOPT[@]}" "$ARG")
shift
;;
-vm-custom-opt)
needarg
VM_CUSTOMOPT="$ARG"
shift
;;
-vm-openstack-flavor|-openstack-flavor)
needarg
VM_OPENSTACK_FLAVOR="$ARG"
shift
;;
-*)
return 1
;;
esac
nextargs=("$@")
return 0
}
vm_set_buildstatus() {
if test -n "$VM_ROOT" -a -n "$VM_SWAP" -a "$VM_SWAP_TYPE" != unattached -a -e "$VM_SWAP" ; then
echo -n "BUILDSTATUS$1" >"$VM_SWAP"
fi
}
#
# Helper for vm_shutdown() to do the actual system halt
#
vm_shutdown_halt_helper() {
kill -9 -1 # goodbye cruel world
if ! mount -o remount,ro / ; then
echo "Warning: 'remount -o ro /' failed. Triple Syncing.."
sync ; sync ; sync
fi
sync # halt from systemd is not syncing anymore.
if ! test -x /sbin/poweroff ; then
test -e /proc/sysrq-trigger || mount -n -tproc none /proc
echo o > /proc/sysrq-trigger
sleep 5 # wait for sysrq to take effect
echo "Warning: VM doesn't support sysrq and /sbin/poweroff not installed"
else
poweroff -f
fi
exit $1
}
vm_shutdown_halt() {
# get rid of the exit handler
trap EXIT
test "$VM_TYPE" = lxc -o "$VM_TYPE" = docker -o "$VM_TYPE" = nspawn && exit $1
# shutdown from fresh shell to close out deleted inodes
exec -a "build: halt" -- $BASH -c "$(declare -f vm_shutdown_halt_helper); vm_shutdown_halt_helper $1"
echo "Warning: clean shut down of the VM didn't work"
exit $1
}
#
# shutdown the system from inside the VM
#
vm_shutdown() {
test -n "$VM_WATCHDOG" && echo "### VM INTERACTION START ###"
exec >&0 2>&0 # so that the logging tee finishes
cd /
test -n "$1" || set 1
if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then
swapoff "$VM_SWAP" 2>/dev/null
echo -n "BUILDSTATUS$1" >"$VM_SWAP"
fi
# Wait for logging tee to finish
LOGGING_TEE_PID=
test -f "$LOGFILE.pid" -a ! -L "$LOGFILE.pid" && read LOGGING_TEE_PID < "$LOGFILE.pid"
if test -n "$LOGGING_TEE_PID"; then
while kill -0 "$LOGGING_TEE_PID" 2>/dev/null; do
sleep 0.1
done
fi
# if VM_EXTRA_FORK is set we were called from vm_detect_2nd_stage, so just exit and
# let the parent process to the shutdown call
test -n "$VM_EXTRA_FORK" && exit $1
vm_shutdown_halt $1
}
vm_img_create() {
local img="$1"
local size="$2"
if test -e "${img}" ; then
local origsize=$(cat "${img}.size" 2> /dev/null)
if test -z "$origsize" -o "$origsize" != "$size" ; then
echo "Resizing $img (${size}M)"
fi
else
echo "Creating $img (${size}M)"
rm -f "${img}.size"
fi
mkdir -p "${img%/*}" || cleanup_and_exit 4
# truncate file to the desired size
dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" status=none || cleanup_and_exit 4
echo "$size" > "${img}.size"
# allocate blocks
if type -p fallocate > /dev/null ; then
fallocate -p -l "${size}M" "$img" 2> /dev/null
errout=$( fallocate -l "${size}M" "$img" 2>&1 )
if test $? != 0; then
echo $errout
if test "${errout/Operation not supported/}" = "$errout"; then
# Do not fail on not support file systems, eg ext2 or ext3
cleanup_and_exit 4
fi
fi
fi
}
vm_img_wipe() {
vm_wipe_$VM_TYPE "$@"
if test -n "$VM_ROOT" -a "$VM_ROOT_TYPE" = file ; then
rm -f "$VM_ROOT"
fi
if test -n "$VM_SWAP" -a "$VM_SWAP_TYPE" = file ; then
rm -f "$VM_SWAP"
fi
}
vm_img_mkfs() {
local fs="$1"
local img="$2"
local options="$3"
local populate="$4"
local mkfs tunefs
case "$fs" in
ext[234]|xfs|btrfs|reiserfs) ;;
*) cleanup_and_exit 1 "filesystem \"$fs\" is not supported" ;;
esac
# defaults for creating the filesystem
vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super,^metadata_csum'
vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard'
vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options"
vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F'
vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F'
vm_img_mkfs_reiserfs='mkreiserfs -q -f'
vm_img_mkfs_btrfs='mkfs.btrfs'
vm_img_mkfs_xfs='mkfs.xfs -f'
# defaults for tuning the filesystem
vm_img_tunefs_ext4='tune2fs -c 0'
vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback'
vm_img_tunefs_ext2='tune2fs -c 0'
var="vm_img_mkfs_${fs}"; mkfs="${!var}"
var="vm_img_mkfs_extra_options_${fs}"; mkfs_extra_options="${!var}"
var="vm_img_tunefs_${fs}"; vm_img_tunefs="${!var}"
local labelopt=
test "$VM_ROOTDEV" != "${VM_ROOTDEV#LABEL=}" && labelopt="-L ${VM_ROOTDEV#LABEL=}"
# extend options if wanted, multiple -O are fine
if test "$options" = "nodirindex" && test "$fs" = "ext2" -o "$fs" = "ext3" -o "$fs" = "ext4"; then
mkfs_extra_options="$mkfs_extra_options -O ^dir_index"
fi
if test -n "$populate"; then
if test "$fs" = "ext2" -o "$fs" = "ext3" -o "$fs" = "ext4"; then
mkfs_extra_options="$mkfs_extra_options -d $populate"
# mkfs needs to see the files it copies into the fs as owned by root.
# Otherwise the whole fs tree would be owned by the calling user.
# Doesn't matter too much when setting up the build root initially as
# rpm is called inside anway to fix everything. However, when reusing
# an image suddenly all ownerships would change.
[ -x "/usr/bin/unshare" ] && mkfs="unshare --user --map-root-user $mkfs"
else
print "ERROR: populating filesystem is only supported with ext file systems"
cleanup_and_exit 1
fi
fi
if test -z "$mkfs"; then
cleanup_and_exit 1 "filesystem \"$fs\" is not supported"
fi
echo "Creating $fs filesystem on $img"
export MKE2FS_SYNC=0
if ! $mkfs $labelopt $mkfs_extra_options "$img" ; then
if test -z "$mkfs_extra_options" ; then
cleanup_and_exit 3
else
echo "Filesystem creation failed, trying again without extra options..."
$mkfs $labelopt "$img" || cleanup_and_exit 4
fi
fi
if test -n "$tunefs" ; then
$tunefs "$img" || cleanup_and_exit 4
fi
}
background_monitor_process() {
max_disk=0
max_mem=0
while sleep 5; do
test -e /.build/_statistics.exit && exit 0
# memory usage
if test -e /proc/meminfo ; then
memtotal=0
while read key value unit; do
case $key in
MemTotal:|SwapTotal:) memtotal=$(( $memtotal + $value )) ;;
MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:) memtotal=$(( $memtotal - $value )) ;;
esac
done < /proc/meminfo
if test ${memtotal} -gt $max_mem ; then
max_mem="${memtotal}"
echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory
fi
fi
# disk storage usage
if type -p df >& /dev/null; then
c=(`df -m / 2>/dev/null | tail -n 1`)
if test ${c[2]} -gt $max_disk ; then
max_disk="${c[2]}"
echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df
fi
fi
done
}
background_watchdog() {
WATCHDOG_START=
WATCHDOG_TIMEOUT=300
BUILD_OPTIONS_PARSED=
while sleep 5 ; do
WATCH=$(grep -a "### VM INTERACTION" "$LOGFILE" | tr '\0' a | tail -n 1)
case $WATCH in
*VM\ INTERACTION\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=$SECONDS ;;
*VM\ INTERACTION\ END*) WATCHDOG_START= ;;
esac
if test -n "$WATCHDOG_START" ; then
ELAPSED=$(( $SECONDS - $WATCHDOG_START ))
if test $ELAPSED -gt $WATCHDOG_TIMEOUT ; then
# kill the VM
echo
echo "### WATCHDOG TRIGGERED, KILLING VM ###"
vm_kill
exit 0
fi
fi
done
}
start_watchdog() {
local wf=$(mktemp)
( background_watchdog & echo $! > "$wf" )
read VM_WATCHDOG_PID < "$wf"
rm -f "$wf"
}
kill_watchdog() {
test -n "$VM_WATCHDOG_PID" && kill "$VM_WATCHDOG_PID"
VM_WATCHDOG_PID=
}
vm_set_personality_syscall() {
local archname
archname=`perl -V:archname 2>/dev/null`
archname="${archname#archname=?}"
case "$archname" in
x86_64*) PERSONALITY_SYSCALL=135 ;;
alpha*) PERSONALITY_SYSCALL=324 ;;
sparc*) PERSONALITY_SYSCALL=191 ;;
ia64*) PERSONALITY_SYSCALL=1140 ;;
aarch64*) PERSONALITY_SYSCALL=92 ;;
i?86*|ppc*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze|riscv*) PERSONALITY_SYSCALL=136 ;;
*) cleanup_and_exit 1 "Unknown architecture personality: '$archname'" ;;
esac
}
# used before calling kvm or xen
linux64() {
perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@"
}
vm_start_statistics() {
if test "$DO_STATISTICS" = 1 ; then
rm -f /.build/_statistics.exit
( background_monitor_process & )
fi
}
vm_exit_statistics() {
if test "$DO_STATISTICS" = 1 ; then
rm -f /.build/_statistics.exit
fi
}
vm_detect_2nd_stage() {
if test ! -e /.build/build.data -o -n "$BUILD_IGNORE_2ND_STAGE" ; then
return 1
fi
. /.build/build.data
if test -z "$VM_TYPE" ; then
return 1
fi
BUILD_OPTIONS_PARSED=true
if test $$ -le 2 ; then
# ignore special init signals if we're init
# we're using ' ' instead of '' so that the signal handlers
# are reset in the child processes
test $$ -eq 1 && trap ' ' HUP TERM
export VM_EXTRA_FORK=true
$0 "$@"
vm_shutdown_halt $?
fi
test -n "$VM_WATCHDOG" -a -z "$PERSONALITY_SET" && echo "### VM INTERACTION END ###"
echo "2nd stage started in virtual machine"
# fedora packages sometimes do not have the needed links
ldconfig
BUILD_ROOT=/
BUILD_DIR=/.build
echo "machine type: `uname -m`"
echo "Linux version: `uname -rv`"
echo "Increasing log level from now on..."
echo 4 > /proc/sysrq-trigger
echo "Enable sysrq operations"
echo 1 > /proc/sys/kernel/sysrq
if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then
export PERSONALITY_SET=true
echo "switching personality to $PERSONALITY..."
# this is 32bit perl/glibc, thus the 32bit syscall number
exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")'
fi
RUNNING_IN_VM=true
test -e /proc/version || mount -orw -n -tproc none /proc
if test "$VM_TYPE" != lxc -a "$VM_TYPE" != docker -a "$VM_TYPE" != nspawn ; then
mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw /
fi
umount /run >/dev/null 2>&1
# mount /sys
if ! test -e /sys/block; then
mkdir -p /sys
mount -orw -n -tsysfs sysfs /sys
# Docker already has sysfs mounted ro elsewhere,
# need to remount rw explicitly.
mount -o remount,rw sysfs /sys
fi
# mount selinuxfs
if ! test -e /sys/fs/selinux/status; then
mount -orw -n -tselinuxfs selinuxfs /sys/fs/selinux 2>/dev/null || :
fi
# mount securityfs
if ! test -e /sys/kernel/security/lsm; then
mount -orw -n -t securityfs securityfs /sys/kernel/security 2>/dev/null || :
fi
# qemu inside of xen does not work, check again with kvm later before enabling this
# if test -e /dev/kqemu ; then
# # allow abuild user to run qemu
# chmod 0666 /dev/kqemu
# fi
test -d /dev/shm || rm -f /dev/shm
mkdir -p /dev/pts
mkdir -p /dev/shm
mount -n -tdevpts -omode=0620,ptmxmode=0666,gid=5 none /dev/pts
mount -n -ttmpfs none /dev/shm
if test -n "$VM_SWAP" ; then
if test "$VM_SWAP" != "${VM_SWAP#LABEL=}" ; then
i=$(blkid -l -o device -t "$VM_SWAP")
if test "$i" = "${i#/}" ; then
cleanup_and_exit 1 "could not find swap device with $VM_SWAP"
fi
echo "resolved swap device $VM_SWAP to $i"
VM_SWAP=$i
fi
for i in 1 2 3 4 5 6 7 8 9 10 ; do
test -e "$VM_SWAP" && break
test $i = 1 && echo "waiting for $VM_SWAP to appear"
echo -n .
sleep 1
done
test $i = 1 || echo
# recreate the swap device manually if it didn't exist for some
# reason, hardcoded to hda2 atm
if ! test -b "$VM_SWAP" ; then
rm -f "$VM_SWAP"
umask 027
mknod "$VM_SWAP" b 3 2
umask 022
fi
# Do not rely on external system writing the signature, it might differ...
mkswap "$VM_SWAP"
swapon -v "$VM_SWAP" || exit 1
fi
HOST="$VM_HOSTNAME"
# repair dracut damage, see bsc#922676
test -L /var/run -a ! -e /var/run && rm -f /var/run
test -L /var/lock -a ! -e /var/lock && rm -f /var/lock
# start a process monitoring max filesystem usage during build
vm_start_statistics
if test ! -e /dev/.udev ; then
echo "WARNING: udev not running, creating extra device nodes"
test -e /dev/fd || ln -sf /proc/self/fd /dev/fd
test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab
fi
# set date to build start on broken systems (now < build start)
if test $(date '+%s') -lt $(date -r /.build/.date '+%s') ; then
echo -n "WARNING: system has a broken clock, setting it to a newer time: "
date -s $(</.build/.date)
fi
# Enable Core dump generation
mkdir -p "$BUILD_ROOT/.build/cores"
echo "/.build/cores/%p" > /proc/sys/kernel/core_pattern
# Load selinux policy (if a preinstall image is used)
if test -s /etc/selinux/config -a -x /usr/sbin/load_policy -a -e /sys/fs/selinux/status -a -e /installed-pkg ; then
echo "loading selinux policy"
/usr/sbin/load_policy
fi
return 0
}
vm_set_filesystem_type() {
local vmfstype
local vmfsoptions
if test -n "$BUILD_DIST" ; then
# testing for build specific filesystem, which are more important then worker defaults
vmfstype=`queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags vmfstype`
vmfsoptions=`queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags vmfsoptions`
fi
test -n "$vmfstype" && VMDISK_FILESYSTEM="$vmfstype"
test -n "$vmfsoptions" && VMDISK_FILESYSTEM_OPTIONS="$vmfsoptions"
# use either commandline specified fs or ext3 as fallback
test -n "$VMDISK_FILESYSTEM" || VMDISK_FILESYSTEM=ext3
if test -n "$VM_USE_MKFS_COPYIN"; then
test "${VMDISK_FILESYSTEM:0:3}" == "ext" || cleanup_and_exit 4 "mkfs copyin works only with ext filesystems"
/sbin/mkfs.ext3 -d /var/lib/empty -V >& /dev/null || cleanup_and_exit 4 "mkfs is missing the -d option needed for copyin files"
fi
}
vm_set_mount_options() {
if test "$VMDISK_MOUNT_OPTIONS" = __default; then
if test "$VMDISK_FILESYSTEM" = reiserfs ; then
VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime'
elif test "$VMDISK_FILESYSTEM" = btrfs ; then
VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime,nodatacow'
elif test "$VMDISK_FILESYSTEM" = "ext4" ; then
VMDISK_MOUNT_OPTIONS='-o noatime'
elif test "$VMDISK_FILESYSTEM" = "ext3" ; then
VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime'
elif test "$VMDISK_FILESYSTEM" = "ext2" ; then
VMDISK_MOUNT_OPTIONS='-o noacl,noatime'
elif test "$VMDISK_FILESYSTEM" = "xfs" ; then
VMDISK_MOUNT_OPTIONS='-o noatime'
else
VMDISK_MOUNT_OPTIONS='-o noatime'
fi
fi
}
vm_set_defaults() {
# setup root/swap defaults and type, called after option verification
if test "$VM_ROOT" = 1 ; then
VM_ROOT="$BUILD_ROOT.img"
if test -z "$VM_SWAP" -a "$VM_TYPE" != emulator ; then
VM_SWAP="$BUILD_ROOT.swap"
fi
fi
if test -n "$VM_ROOT" -a -z "$VM_ROOT_TYPE" ; then
VM_ROOT_TYPE=file
test -b "$VM_ROOT" && VM_ROOT_TYPE=device
fi
if test -n "$VM_SWAP" -a -z "$VM_SWAP_TYPE" ; then
VM_SWAP_TYPE=file
test -b "$VM_SWAP" && VM_SWAP_TYPE=device
fi
test $UID != 0 && VM_USE_MKFS_COPYIN="true"
}
#
# create swap space
#
vm_setup_swap() {
if test -n "$VMDISK_CLEAN" ; then
# delete old swap to get rid of the old blocks
if test -n "$VM_SWAP" -a "$VM_SWAP_TYPE" = file -a -f "$VM_SWAP" ; then
echo "Deleting old $VM_SWAP"
rm -f "$VM_SWAP"
fi
fi
if test -n "$VM_SWAP" -a "$VM_SWAP_TYPE" = file ; then
vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE"
fi
if test -n "$VM_SWAP" ; then
vm_attach_swap
dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc status=none || cleanup_and_exit 4
if test "$VM_SWAPDEV" != "${VM_SWAPDEV#LABEL=}"; then
# call mkswap to set a label
mkswap -L "${VM_SWAPDEV#LABEL=}" "$VM_SWAP" || cleanup_and_exit 4
fi
vm_detach_swap
# mkswap happens inside of the vm
fi
}
#
# create file system, mount file system to $BUILD_ROOT
#
vm_setup() {
vm_set_filesystem_type
vm_set_mount_options
echo "VM_ROOT: $VM_ROOT, VM_SWAP: $VM_SWAP"
vm_attach_root
vm_setup_swap
# this should not be needed, but sometimes a xen instance got lost
test "$VM_TYPE" = xen && vm_purge_xen
if test -n "$VMDISK_CLEAN" ; then
# delete old root to get rid of the old blocks
if test -n "$VM_ROOT" -a "$VM_ROOT_TYPE" = file -a -f "$VM_ROOT" ; then
echo "Deleting old $VM_ROOT"
rm -f "$VM_ROOT"
fi
fi
# Check for populating filesystem during mkfs
if test -n "$VM_USE_MKFS_COPYIN" ; then
echo "Using mkfs copyin mode to populate the root filesystem"
mkdir_build_root
if test ! -w /root ; then
find "$BUILD_ROOT" -type d -not -perm /200 -print0 | xargs -0 --no-run-if-empty chmod +w
fi
rm -rf "$BUILD_ROOT"/* "$BUILD_ROOT"/.[^.]*
if test -z "$CLEAN_BUILD" -a -e "$VM_ROOT" ; then
echo "Recovering former build root"
debugfs -f <(echo rdump / "$BUILD_ROOT") "$VM_ROOT" 2>/dev/null
fi
fi
local clean_build="$CLEAN_BUILD"
if test "$VM_ROOT_TYPE" = file ; then
if test -z "$clean_build" ; then
local origrootsize
test -e "$VM_ROOT" -a -e "${VM_ROOT}.size" && origrootsize=$(cat "${VM_ROOT}.size" 2>/dev/null)
if test -z "$origrootsize" -o "$origrootsize" != "$VMDISK_ROOTSIZE" ; then
# the size has changed, re-create file system
clean_build=true
fi
fi
if test -n "$clean_build" ; then
vm_img_create "$VM_ROOT" "$VMDISK_ROOTSIZE"
fi
fi
if test ! -e "$VM_ROOT" ; then
cleanup_and_exit 4 "you need to create $VM_ROOT first"
fi
if test -n "$VM_USE_MKFS_COPYIN" ; then
return
fi
if test -n "$clean_build" ; then
vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_ROOT" "$VMDISK_FILESYSTEM_OPTIONS" || cleanup_and_exit 4
fi
# now mount root/swap
mkdir_build_root
if test -w /root ; then
if test -b $VM_ROOT ; then
# mount device directly
mount $VMDISK_MOUNT_OPTIONS $VM_ROOT $BUILD_ROOT || cleanup_and_exit 4
else
mount ${VMDISK_MOUNT_OPTIONS},loop $VM_ROOT $BUILD_ROOT || cleanup_and_exit 4
fi
else
if ! mount $BUILD_ROOT; then
echo "mounting the build root failed. An fstab entry is probably missing or incorrect."
echo "/etc/fstab should contain an entry like this:"
echo "$VM_ROOT $BUILD_ROOT auto noauto,user,loop 0 0"
cleanup_and_exit 4
fi
fi
}
vm_update_hostarch() {
local kernel="$vm_kernel"
local hostarchfile
local newhostarch
local vm_type="$VM_TYPE"
test "$vm_type" = "qemu" && vm_type=kvm
if test -z "$VM_KERNEL" -a -f "$BUILD_ROOT/.build.kernel.$vm_type" -a ! -L "$BUILD_ROOT/.build.kernel.$vm_type" ; then
kernel="$BUILD_ROOT/.build.kernel.$vm_type"
if test -f "$BUILD_ROOT/.build.hostarch.$vm_type" -a ! -L "$BUILD_ROOT/.build.hostarch.$vm_type" ; then
hostarchfile="$BUILD_ROOT/.build.hostarch.$vm_type"
fi
elif test -n "$kernel" -a -f "$kernel" -a -f "$kernel.hostarch" ; then
hostarchfile="$kernel.hostarch"
fi
if test -n "$hostarchfile" -a -f "$hostarchfile" ; then
local dummy
read newhostarch dummy < "$hostarchfile"
elif test -n "$kernel" -a -f "$kernel" ; then
case `objdump -f "$kernel" 2>/dev/null | sed -ne 's/.*file format //p'` in
elf64-powerpcle) newhostarch=ppc64le ;;
elf64-powerpc) newhostarch=ppc64 ;;
esac
fi
if test -n "$newhostarch" -a "$newhostarch" != "$BUILD_HOST_ARCH" ; then
echo "setting hostarch to $newhostarch"
BUILD_HOST_ARCH="$newhostarch"
# update BUILD_INITVM_ARCH
build_host_arch
fi
}
#
# prepare for vm startup
#
vm_first_stage() {
vm_set_personality_syscall
rm -rf "$BUILD_ROOT/.build"
mkdir -p "$BUILD_ROOT/.build"
TIME_PREINSTALL=
if test "$DO_INIT" = true ; then
# do first stage of init_buildsystem
rm -f $BUILD_ROOT/.build.success
set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${initbuildsysstuff[@]}" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USEUSEDFORBUILD $RPMLIST "$RECIPEPATH" $ADDITIONAL_PACKS
echo "$* ..."
start_time=$SECONDS
"$@" || cleanup_and_exit 1
check_exit
TIME_PREINSTALL=$(( $SECONDS - $start_time ))
unset start_time
if test ! -w /root ; then
# remove setuid bit if files belong to user to make e.g. mount work
find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm /4000 -print0 | xargs -0 --no-run-if-empty chmod -s
fi
copy_oldpackages
fi
# start up VM, rerun ourself
cp -a $BUILD_DIR/. $BUILD_ROOT/.build
if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
rm -rf "$BUILD_ROOT/.build-srcdir"
mkdir "$BUILD_ROOT/.build-srcdir" || cleanup_and_exit 1
copy_sources "$MYSRCDIR" "$BUILD_ROOT/.build-srcdir"
MYSRCDIR=$BUILD_ROOT/.build-srcdir
else
# cwd is at $BUILD_ROOT/.build-srcdir which we want to
# umount later so step aside
cd "$SRCDIR"
fi
# do the conversion now because a yaml reader may be missing in the vm
if test -n "$MODULEMDFILE" -a "${MODULEMDFILE##*/}" != _modulemd.pst ; then
$BUILD_DIR/writemodulemd --converttopst "$MODULEMDFILE" > "$MYSRCDIR/_modulemd.pst"
fi
# some time has passed copying files, lets make sure we should not exit
check_exit
# update the hostarch
if test -n "$VM_ROOT" ; then
vm_update_hostarch
fi
# do vm specific fixups
vm_fixup
# copy ccache archive
if test -n "$CCACHE" -a -n "$CCACHE_ARCHIVE" -a "$CCACHE_ARCHIVE" = "${CCACHE_ARCHIVE#redis://}"; then
mkdir -p "$BUILD_ROOT/.build.oldpackages"
if ! test "$BUILD_ROOT/.build.oldpackages/_ccache.tar" -ef "$CCACHE_ARCHIVE" ; then
cp --remove-destination -a "$CCACHE_ARCHIVE" "$BUILD_ROOT/.build.oldpackages/_ccache.tar"
fi
CCACHE_ARCHIVE="/.build.oldpackages/_ccache.tar"
fi
# the watchdog needs a log file
test -n "$LOGFILE" || VM_WATCHDOG=
# put our config into .build/build.data
rm -rf $BUILD_ROOT/.build/build.data
Q="'\''"
echo "RECIPEFILE='${RECIPEFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data
echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
case $BUILD_DIST in
*/*)
cp $BUILD_DIST $BUILD_ROOT/.build/build.dist
BUILD_DIST=/.build/build.dist
;;
esac
echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data
echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_INIT_TOPDIR='${DO_INIT_TOPDIR//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "VM_TELNET='${VM_TELNET//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "VM_CONSOLE_INPUT='${VM_CONSOLE_INPUT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
PERSONALITY=0
test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'`
test "$PERSONALITY" = -1 && PERSONALITY=0 # syscall failed?
case $(uname -m) in
ppc|ppcle|s390) PERSONALITY=8 ;; # ppc/s390 kernel never tells us if a 32bit personality is active, assume we run on 64bit
aarch64) test "$BUILD_ARCH" != "${BUILD_ARCH#armv[567]}" && PERSONALITY=8 ;; # workaround, to be removed
esac
test "$VM_TYPE" = lxc -o "$VM_TYPE" = docker -o "$VM_TYPE" = nspawn && PERSONALITY=0
echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data
echo "VM_HOSTNAME='$HOST'" >> $BUILD_ROOT/.build/build.data
echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data
shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data
echo ")" >> $BUILD_ROOT/.build/build.data
echo -n "repos=(" >> $BUILD_ROOT/.build/build.data
shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data
echo ")" >> $BUILD_ROOT/.build/build.data
echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data
echo "VM_NETWORK='$VM_NETWORK'" >> $BUILD_ROOT/.build/build.data
echo "RUN_SHELL='$RUN_SHELL'" >> $BUILD_ROOT/.build/build.data
echo "RUN_SHELL_AFTER_FAIL='$RUN_SHELL_AFTER_FAIL'" >> $BUILD_ROOT/.build/build.data
echo "RUN_SHELL_CMD='$RUN_SHELL_CMD'" >> $BUILD_ROOT/.build/build.data
echo "DO_STATISTICS='$DO_STATISTICS'" >> $BUILD_ROOT/.build/build.data
echo "TIME_PREINSTALL='$TIME_PREINSTALL'" >> $BUILD_ROOT/.build/build.data
echo "VM_WATCHDOG='$VM_WATCHDOG'" >> $BUILD_ROOT/.build/build.data
echo "BUILDENGINE='$BUILDENGINE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE='$CCACHE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE_TYPE='$CCACHE_TYPE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE_ARCHIVE='$CCACHE_ARCHIVE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE_CREATE_ARCHIVE='$CCACHE_CREATE_ARCHIVE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE_CLEAN='$CCACHE_CLEAN'" >> $BUILD_ROOT/.build/build.data
echo "ABUILD_TARGET='$ABUILD_TARGET'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_FLAVOR='$BUILD_FLAVOR'" >> $BUILD_ROOT/.build/build.data
echo "OBS_PACKAGE='$OBS_PACKAGE'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_SKIP_BUNDLE='$BUILD_SKIP_BUNDLE'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_RPM_BUILD_STAGE='$BUILD_RPM_BUILD_STAGE'" >> $BUILD_ROOT/.build/build.data
echo "RPM_BUILD_IN_PLACE='$RPM_BUILD_IN_PLACE'" >> $BUILD_ROOT/.build/build.data
echo "RPM_NOPREP='$RPM_NOPREP'" >> $BUILD_ROOT/.build/build.data
# fallback time for broken hosts
rm -rf $BUILD_ROOT/.build/.date
date '+@%s' > $BUILD_ROOT/.build/.date
# we're done with the root file system, unmount
buildroot_umount /proc/sys/fs/binfmt_misc
buildroot_umount /proc
buildroot_umount /sys
buildroot_umount /dev/pts
buildroot_umount /dev/shm
buildroot_umount /mnt
vm_init_script="/.build/build"
if set_initvm_name_for_emulator_in "$BUILD_ROOT/.build" ; then
vm_init_script="/.build/$INITVM_NAME"
fi
if test -n "$VM_ROOT" ; then
# copy out kernel & initrd (if they exist) during unmounting VM image
KERNEL_TEMP_DIR=
local vm_type="$VM_TYPE"
test "$vm_type" = "qemu" && vm_type=kvm
if test -z "$VM_KERNEL" -a -f "$BUILD_ROOT/.build.kernel.$vm_type" -a ! -L "$BUILD_ROOT/.build.kernel.$vm_type" ; then
KERNEL_TEMP_DIR=`mktemp -d`
cp "$BUILD_ROOT/.build.kernel.$vm_type" "$KERNEL_TEMP_DIR/kernel"
if test -f "$BUILD_ROOT/.build.initrd.$vm_type" -a ! -L "$BUILD_ROOT/.build.initrd.$vm_type" ; then
cp "$BUILD_ROOT/.build.initrd.$vm_type" "$KERNEL_TEMP_DIR/initrd"
fi
if test -f "$BUILD_ROOT/.build.cmdline.$vm_type" -a ! -L "$BUILD_ROOT/.build.cmdline.$vm_type" ; then
vm_cmdline="$(cat $BUILD_ROOT/.build.cmdline.$vm_type)"
fi
fi
check_exit
if test -n "$VM_USE_MKFS_COPYIN" ; then
vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_ROOT" "$VMDISK_FILESYSTEM_OPTIONS" "$BUILD_ROOT" || cleanup_and_exit 4
else
# needs to work otherwise we have a corrupted file system
if ! umount $BUILD_ROOT; then
test -n "$KERNEL_TEMP_DIR" && rm -rf "$KERNEL_TEMP_DIR"
cleanup_and_exit 4
fi
fi
# copy back the kernel and set it for VM
if test -n "$KERNEL_TEMP_DIR" ; then
rm -rf "$BUILD_ROOT/boot"
mkdir -p "$BUILD_ROOT/boot"
mv "$KERNEL_TEMP_DIR/kernel" "$BUILD_ROOT/boot/kernel"
vm_kernel="$BUILD_ROOT/boot/kernel"
if test -e "$KERNEL_TEMP_DIR/initrd" ; then
mv "$KERNEL_TEMP_DIR/initrd" "$BUILD_ROOT/boot/initrd"
test -z "$VM_INITRD" && vm_initrd="$BUILD_ROOT/boot/initrd"
fi
rmdir "$KERNEL_TEMP_DIR"
fi
fi
vm_detach_root
echo "booting $VM_TYPE..."
unset VM_EXTRA_FORK
# start watchdog if requested
if test -n "$VM_WATCHDOG" ; then
start_watchdog
echo "### VM INTERACTION START ###"
fi
vm_startup "${VM_ARGS[@]}"
# kill watchdog again
if test -n "$VM_WATCHDOG" ; then
echo "### VM INTERACTION END ###"
kill_watchdog
fi
vm_attach_root
if test -n "$VM_SWAP" -a -z "$RUN_SHELL" ; then
vm_attach_swap
BUILDSTATUS=$(dd if="$VM_SWAP" bs=12 count=1 status=none | tr '\0' a)
case $BUILDSTATUS in
BUILDSTATUS[029])
mkdir -p $BUILD_ROOT/.build.packages
cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
echo "build: extracting built packages..."
extractbuild --disk "$VM_ROOT" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3
if test "$BUILDTYPE" = "preinstallimage" ; then
preinstallimage_compress OTHER
fi
if test "$DO_STATISTICS" = 1 ; then
mkdir -p OTHER
TIME_TOTAL=$(( $SECONDS - $TIME_START_TIME ))
echo "TIME_total: $TIME_TOTAL" >> OTHER/_statistics
fi
cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
;;
BUILDSTATUS*)
cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
;;
*)
echo "No buildstatus set, either the base system is broken (kernel/initrd/udev/glibc/bash/perl)"
echo "or the build host has a kernel or hardware problem..."
cleanup_and_exit 3
;;
esac
cleanup_and_exit 1
fi
}
vm_save_statistics() {
echo "... saving statistics"
local sys_mounted otherdir
otherdir="$BUILD_ROOT$TOPDIR/OTHER"
test -n "$TIME_PREINSTALL" && echo "TIME_preinstall: $TIME_PREINSTALL" >> $otherdir/_statistics
test -n "$TIME_INSTALL" && echo "TIME_install: $TIME_INSTALL" >> $otherdir/_statistics
test -n "$TIME_POSTCHECKS" && echo "TIME_postchecks: $TIME_POSTCHECKS" >> $otherdir/_statistics
test -n "$TIME_RPMLINT" && echo "TIME_rpmlint: $TIME_RPMLINT" >> $otherdir/_statistics
test -n "$TIME_BUILDCMP" && echo "TIME_buildcmp: $TIME_BUILDCMP" >> $otherdir/_statistics
test -n "$TIME_DELTARPMS" && echo "TIME_deltarpms: $TIME_DELTARPMS" >> $otherdir/_statistics
local cpustat=($(head -n 1 /proc/stat))
test "${cpustat[8]}" -gt 0 && echo "TIME_cpusteal: $(( ${cpustat[8]} / 100 ))" >> $otherdir/_statistics
if test -e /.build/_statistics.df ; then
echo -n "MAX_mb_used_on_disk: " >> $otherdir/_statistics
cat /.build/_statistics.df >> $otherdir/_statistics
echo "" >> $otherdir/_statistics
rm /.build/_statistics.df
fi
if test -e /.build/_statistics.memory ; then
echo -n "MAX_mb_used_memory: " >> $otherdir/_statistics
cat /.build/_statistics.memory >> $otherdir/_statistics
echo "" >> $otherdir/_statistics
rm /.build/_statistics.memory
fi
if ! test -e /sys/block; then
mkdir -p /sys
mount -n sys /sys -t sysfs
sys_mounted=1
fi
device="hda1"
test -e /dev/sda && device="sda"
test -e /dev/vda && device="vda"
test -e /dev/xvda && device="xvda" # in newer XEN setups
test -e /dev/dasda && device="dasda" # in z/VM
test -e /dev/nfhd0 && device="nfhd0" # in aranym
if test -e /sys/block/${device}/stat ; then
disk=(`cat /sys/block/${device}/stat`)
test "0${disk[0]}" -gt 0 && echo "IO_requests_read: ${disk[0]}" >> $otherdir/_statistics
test "0${disk[2]}" -gt 0 && echo "IO_sectors_read: ${disk[2]}" >> $otherdir/_statistics
test "0${disk[4]}" -gt 0 && echo "IO_requests_write: ${disk[4]}" >> $otherdir/_statistics
test "0${disk[6]}" -gt 0 && echo "IO_sectors_write: ${disk[6]}" >> $otherdir/_statistics
else
echo "ERROR: no root disk device found, yet another new device name?"
ls -l /sys/block/
fi
test -n "$sys_mounted" && umount /sys
}
# args: resultdirs
vm_wrapup_build() {
test "$DO_STATISTICS" = 1 && vm_save_statistics
if test -n "$VM_SWAP"; then
echo "... saving built packages"
swapoff "$VM_SWAP"
pushd "$BUILD_ROOT$TOPDIR" >/dev/null
find "$@" -print0 | computeblocklists --padstart 512 --padend 512 -v --manifest - -0 > "$VM_SWAP" || cleanup_and_exit 1
popd >/dev/null
fi
}
vm_setup_network() {
if test -x /sbin/ip ; then
ip addr add 127.0.0.1/8 dev lo
ip addr add ::1/128 dev lo
ip link set lo up
elif test -x /sbin/ifconfig ; then
ifconfig lo 127.0.0.1 up
ifconfig lo add ::1/128
fi
. /.build/build.data
if test -n "$VM_NETWORK"; then
echo "Network setup"
NETDEV=eth0
# these IPs are the built-in adresses in qemu
echo nameserver 10.0.2.3 >> /etc/resolv.conf
if test -x /sbin/ip ; then
ip addr add 10.0.2.15/24 dev ${NETDEV}
ip addr add ::1/24 dev ${NETDEV}
ip link set ${NETDEV} up
ip route add default via 10.0.2.2
elif test -x /sbin/ifconfig ; then
ifconfig ${NETDEV} 10.0.2.15 netmask 255.255.255.0 up
ifconfig ${NETDEV} add ::1/24
route add default gw 10.0.2.2
else
dhclient eth0
fi
ip a
fi
if test -n "$VM_TELNET"; then
VM_TELNET_DEVICE=$( cd /sys/class/net/; echo * )
VM_TELNET_DEVICE=${VM_TELNET_DEVICE#lo }
VM_TELNET_DEVICE=${VM_TELNET_DEVICE%% *}
if test -z "$VM_TELNET_DEVICE" ; then
cleanup_and_exit 1 "ERROR: no network device found for telnet server"
fi
if test -x /sbin/ip ; then
# these IPs are the built-in adresses in qemu
ip addr add 10.0.2.15/8 dev ${VM_TELNET_DEVICE}
ip addr add ::1/24 dev ${VM_TELNET_DEVICE}
ip link set ${VM_TELNET_DEVICE} up
elif test -x /sbin/ifconfig ; then
ifconfig ${VM_TELNET_DEVICE} 10.0.2.15 up
ifconfig ${VM_TELNET_DEVICE} add ::1/24
else
cleanup_and_exit 1 "ERROR: neither /sbin/ifconfig nor /sbin/ip is installed, please specify correct package via -x option"
fi
fi
if test -n "$VM_HOSTNAME" ; then
if test -e /bin/hostname -o -e /usr/bin/hostname -o -e /sbin/hostname -o -e /usr/sbin/hostname ; then
hostname "$VM_HOSTNAME"
elif test -e /proc/sys/kernel/hostname ; then
echo "$VM_HOSTNAME" > /proc/sys/kernel/hostname
fi
fi
if test -n "$VM_TELNET"; then
echo WARNING: telnet option used, setting up telnet server ${VM_TELNET_DEVICE}
if test -x /usr/sbin/in.telnetd; then
( /usr/sbin/in.telnetd -L /.build/telnet_login_wrapper -debug 23 & )
else
cleanup_and_exit 1 "ERROR: /usr/sbin/in.telnetd is not installed, please specify correct package via -x option"
fi
fi
}