# # VM specific functions for the build script # # (C) 2014 SUSE, Inc # # defaults for vm_img_mkfs vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super' 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_tunefs_ext4='tune2fs -c 0' vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F' vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback' vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F' vm_img_tunefs_ext2='tune2fs -c 0' vm_img_mkfs_reiserfs='mkreiserfs -q -f' vm_img_mkfs_btrfs='mkfs.btrfs' vm_img_mkfs_xfs='mkfs.xfs -f' # guest visible swap device VM_SWAPDEV=/dev/hda2 VM_TYPE= VM_IMAGE= VM_SWAP= VM_KERNEL= VM_INITRD= VM_WORKER= VM_SERVER= VM_MEMSIZE= VMDISK_ROOTSIZE=4096 VMDISK_SWAPSIZE=1024 VMDISK_FILESYSTEM= VMDISK_MOUNT_OPTIONS=__default VMDISK_CLEAN= # zvm specific? VM_WORKER_NR= # kvm specific? HUGETLBFSPATH= # emulator specific? EMULATOR_SCRIPT= for i in ec2 emulator kvm lxc openstack qemu uml xen zvm ; do . "$BUILD_DIR/build-vm-$i" done VM_WATCHDOG= VM_WATCHDOG_PID= # the following functions just call the corresponding vm versions vm_kill() { vm_kill_$VM_TYPE "$@" } 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() { vm_fixup_$VM_TYPE "$@" } vm_startup() { vm_startup_$VM_TYPE "$@" } vm_kill() { vm_kill_$VM_TYPE "$@" } vm_cleanup() { kill_watchdog vm_cleanup_$VM_TYPE "$@" } vm_parse_options() { case ${PARAM/#--/-} in -emulator-script) needarg EMULATOR_SCRIPT="$ARG" shift ;; -xen|-kvm|-uml|-qemu|-emulator) VM_TYPE=${PARAM##*-} test -z "$VM_IMAGE" && VM_IMAGE=1 if test -n "$ARG" ; then VM_IMAGE="$ARG" shift fi ;; -zvm|-lxc) VM_TYPE=${PARAM##*-} shift ;; -vm-type) needarg VM_TYPE="$ARG" case "$VM_TYPE" in lxc) ;; ec2|xen|kvm|uml|qemu|emulator|openstack|zvm) test -z "$VM_IMAGE" && VM_IMAGE=1 ;; none|chroot) VM_TYPE= ;; *) echo "VM '$VM_TYPE' is not supported" cleanup_and_exit ;; esac shift ;; -vm-worker) needarg VM_WORKER="$ARG" shift ;; -vm-worker-nr|-vm-worker-no) needarg VM_WORKER_NR="$ARG" shift ;; -vm-server|-vm-region) needarg VM_SERVER="$ARG" shift ;; -vm-volumes) needarg VM_VOLUME_NAME="$ARG" shift ARG="$1" test "$ARG" = "${ARG#-}" || ARG= needarg VM_VOLUME_SWAP="$ARG" shift ;; -vm-disk) needarg VM_IMAGE="$ARG" shift ;; -xenswap|-vm-swap|-swap) needarg VM_SWAP="$ARG" shift ;; -xenmemory|-vm-memory|-memory) needarg VM_MEMSIZE="$ARG" shift ;; -vm-kernel) needarg VM_KERNEL="$ARG" shift ;; -vm-initrd) needarg VM_INITRD="$ARG" shift ;; -vmdisk-rootsize|-vm-disk-size) needarg VMDISK_ROOTSIZE="$ARG" shift ;; -vmdisk-swapsize|-vm-swap-size) needarg VMDISK_SWAPSIZE="$ARG" shift ;; -vmdisk-filesystem|-vm-disk-filesystem) needarg VMDISK_FILESYSTEM="$ARG" shift ;; -vmdisk-mount-options|-vm-disk-mount-options) needarg # options needs to be quoted to handle argument which might start with "-o ..." VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g') shift ;; -vmdisk-clean) # delete old root/swap to get rid of the old blocks VMDISK_CLEAN=true ;; -rpmlist) needarg RPMLIST="--rpmlist $ARG" BUILD_RPMS= shift ;; -hugetlbfs) needarg HUGETLBFSPATH="$ARG" shift ;; -vm-watchdog) VM_WATCHDOG=true ;; -*) return 1 ;; esac nextargs=("$@") return 0 } # # shutdown the system from inside the VM # vm_shutdown() { test -n "$VM_WATCHDOG" && echo "### WATCHDOG MARKER START ###" 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 exec >&0 2>&0 # so that the logging tee finishes sleep 1 # wait till tee terminates test "$VM_TYPE" = lxc && exit $1 kill -9 -1 # goodbye cruel world if ! test -x /sbin/halt ; then test -e /proc/sysrq-trigger || mount -n -tproc none /proc sync sleep 2 # like halt does if test -e /proc/sysrq-trigger; then echo o > /proc/sysrq-trigger sleep 5 # wait for sysrq to take effect else echo "Warning: VM doesn't support sysrq and /sbin/halt not installed" fi else sync # halt from systemd is not syncing anymore. halt -f -p fi echo "Warning: clean shut down of the VM didn't work" exit $1 # init died... } vm_img_create() { local img="$1" local size="$2" echo "Creating $img (${size}M)" mkdir -p "${img%/*}" || cleanup_and_exit 3 # prefer fallocate, which avoids fragmentation r=1 if type -p fallocate > /dev/null ; then fallocate -l "${size}M" "$img" r=$? fi # fall back to dd method if fallocate is not supported if test "$r" -gt 0 ; then dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3 fi } vm_img_mkfs() { local fs="$1" local img="$2" local mkfs tunefs eval "mkfs=\"\$vm_img_mkfs_${fs}\"" eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\"" eval "tunefs=\"\$vm_img_tunefs_${fs}\"" if test -z "$mkfs"; then echo "filesystem \"$fs\" is not supported" cleanup_and_exit 3 fi echo "Creating $fs filesystem on $img" if ! $mkfs $mkfs_exta_options "$img"; then if test -z "$mkfs_exta_options"; then cleanup_and_exit 3 else echo "Format call failed, trying again without extra options..." $mkfs "$img" || cleanup_and_exit 3 fi fi if test -n "$tunefs" ; then $tunefs "$img" || cleanup_and_exit 3 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 while sleep 5 ; do WATCH=`grep -a "### WATCHDOG MARKER" "$LOGFILE" | tail -n 1` case $WATCH in *WATCHDOG\ MARKER\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=`date +%s` ;; *WATCHDOG\ MARKER\ END*) WATCHDOG_START= ;; esac if test -n "$WATCHDOG_START" ; then NOW=`date +%s` ELAPSED=$((NOW-WATCHDOG_START)) if test $ELAPSED -gt $WATCHDOG_TIMEOUT ; then # kill the VM echo "### WATCHDOG TRIGGERED, KILLING VM ###" fuser -k -TERM "$VM_IMAGE" 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 ;; i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze) PERSONALITY_SYSCALL=136 ;; *) echo "Unknown architecture personality: '$archname'"; cleanup_and_exit 1 ;; esac } # used before calling kvm or xen linux64() { perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@" } 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 if test $$ -eq 1 || test $$ -eq 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 trap ' ' HUP TERM $0 "$@" cleanup_and_exit $? fi test -n "$VM_WATCHDOG" -a -z "$PERSONALITY_SET" && echo "### WATCHDOG MARKER END ###" echo "2nd stage started in virtual machine" BUILD_ROOT=/ BUILD_DIR=/.build echo "machine type: `uname -m`" 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 ; 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 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 if test -n "$VM_SWAP" ; then 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="$MYHOSTNAME" # fork a process monitoring max filesystem usage during build if test "$DO_STATISTICS" = 1 ; then rm -f /.build/_statistics.exit ( background_monitor_process & ) fi 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 `cat /.build/.date` fi return 0 } 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' 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 } # # create file system and swap space, mount file system to $BUILD_ROOT # vm_setup() { vm_set_mount_options if test "$VM_IMAGE" = 1 ; then VM_IMAGE="$BUILD_ROOT.img" if test -z "$VM_SWAP" -a "$VM_TYPE" != emulator; then VM_SWAP="$BUILD_ROOT.swap" fi echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP" else echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP" vm_attach_root fi # 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/swap to get rid of the old blocks if test -n "$VM_IMAGE" -a -f "$VM_IMAGE" ; then echo "Deleting old $VM_IMAGE" rm -rf "$VM_IMAGE" fi if test -n "$VM_SWAP" -a -f "$VM_SWAP" ; then echo "Deleting old $VM_SWAP" rm -rf "$VM_SWAP" fi fi if test ! -e "$VM_IMAGE" ; then vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE" if test -z "$CLEAN_BUILD" ; then vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" fi fi if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP" ; then vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE" fi if test ! -e "$VM_IMAGE" ; then echo "you need to create $VM_IMAGE first" cleanup_and_exit 3 fi if test -n "$CLEAN_BUILD" ; then vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3 fi # now mount root/swap mkdir_build_root if test -w /root ; then if test -b $VM_IMAGE ; then # mount device directly mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 else mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3 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_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0" cleanup_and_exit 3 fi fi if test -n "$VM_SWAP" ; then vm_attach_swap dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null vm_detach_swap # mkswap happens inside of the vm 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 "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS echo "$* ..." start_time=`date +%s` "$@" || cleanup_and_exit 1 check_exit TIME_PREINSTALL=$(( `date +%s` - $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" if test "$BUILDTYPE" = kiwi ; then cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir else cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir fi 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 vm specific fixups vm_fixup # the watchdog needs a log file test -n "$LOGFILE" || VM_WATCHDOG= # put our config into .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 "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$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}" && PERSONALITY=8 ;; # workaround, to be removed esac test "$VM_TYPE" = lxc && PERSONALITY=0 echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data echo "MYHOSTNAME='`hostname`'" >> $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 "RUN_SHELL='$RUN_SHELL'" >> $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 "ABUILD_TARGET='$ABUILD_TARGET'" >> $BUILD_ROOT/.build/build.data # fallback time for broken hosts date '+@%s' > $BUILD_ROOT/.build/.date # we're done with the root file system, unmount umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true umount -n $BUILD_ROOT/proc 2> /dev/null || true umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true umount -n $BUILD_ROOT/mnt 2> /dev/null || true vm_init_script="/.build/build" if check_use_emulator ; then vm_init_script="/.build/$INITVM_NAME" fi if test -n "$VM_IMAGE" ; then # copy out kernel & initrd (if they exist) during unmounting VM image KERNEL_TEMP_DIR= if test -z "$VM_KERNEL" -a -e "$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 -e "$BUILD_ROOT/.build.initrd.$VM_TYPE" ; then cp "$BUILD_ROOT/.build.initrd.$VM_TYPE" "$KERNEL_TEMP_DIR/initrd" fi fi check_exit # needs to work otherwise we have a corrupted file system if ! umount $BUILD_ROOT; then rm -rf "$KERNEL_TEMP_DIR" cleanup_and_exit 3 fi # copy back the kernel and set it for VM if test -n "$KERNEL_TEMP_DIR" ; then 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 # start watchdog if requested if test -n "$VM_WATCHDOG" ; then start_watchdog echo "### WATCHDOG MARKER START ###" fi echo "booting $VM_TYPE..." vm_startup # kill watchdog again if test -n "$VM_WATCHDOG" ; then echo "### WATCHDOG MARKER END ###" kill_watchdog fi vm_attach_root if test -n "$VM_SWAP" ; then vm_attach_swap BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null` case $BUILDSTATUS in BUILDSTATUS[02]) mkdir -p $BUILD_ROOT/.build.packages cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1 echo "build: extracting built packages..." extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3 if test "$DO_STATISTICS" = 1 ; then mkdir -p OTHER TIME_TOTAL=$(( `date +%s` - $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 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/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" popd >/dev/null fi }