#!/bin/bash
# Script to build a package.  It uses init_buildsystem to setup a chroot
# building tree.  This script needs a directory as parameter.  This directory
# has to include sources and a spec file.
#
# BUILD_ROOT        here the packages will be built
#
# (c) 1997-2008 SuSE GmbH Nuernberg, Germany

# some VMs do not allow to specify the init process...
if test "$0" = "/sbin/init" ; then
   exec /.build/build "$@"
fi

test -z "$BUILD_DIR" && BUILD_DIR=/usr/lib/build
test -z "$BUILD_ROOT" && BUILD_ROOT=/var/tmp/build-root
test -z "$CONFIG_DIR" && CONFIG_DIR="$BUILD_DIR/configs"

export BUILD_ARCH BUILD_HOST_ARCH BUILD_ROOT BUILD_RPMS BUILD_DIR BUILD_DEBUG
export BUILD_DIST

ccache=0
icecream=0
statistics=0
shell=
definesnstuff=()
repos=()
old_packages=()

# defaults for vm_img_mkfs
vm_img_mkfs_ext4='mkfs.ext4 -m 0 -q -F'
vm_img_tunefs_ext4='tune2fs -c 0 -O ^has_journal'
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'

vm_kernel=/boot/vmlinuz
vm_initrd=/boot/initrd
qemu_bin=/usr/bin/qemu
uml_kernel=/boot/vmlinux-um
uml_initrd=/boot/initrd-um

# z/VM: use default kernel image from local machine
# lets go with the default parameters. However zvm_initrd will be a required parameter
#zvm_kernel=/boot/image
#zvm_initrd=/boot/initrd_worker
zvm_param="root=/dev/disk/by-path/ccw-0.0.0150-part1 hvc_iucv=8 console=hvc0"
zvm_mult_pass="THR4ME"
#zvm_worker_nr="1"
zvm_init_script="/.build/build"

kvm_bin=/usr/bin/qemu-kvm
# whether we have virtio support
kvm_virtio=

# guest visible console device name
console=ttyS0

# need to restore build root owner for non-root builds
browner=

# Default uid:gid for the build user
ABUILD_UID=399
ABUILD_GID=399

DO_INIT=true
DO_BUILD=true
DO_LINT=
DO_CHECKS=true
SHORT_CIRCUIT=false
NO_TOPDIR_CLEANUP=false
CLEAN_BUILD=
USE_SYSTEM_QEMU=
KEEP_PACKS=
SPECFILES=()
SRCDIR=
BUILD_JOBS=
ABUILD_TARGET=
CREATE_BASELIBS=
USEUSEDFORBUILD=
LIST_STATE=
VM_IMAGE=
VM_SWAP=
VM_KERNEL=
VM_INITRD=
VMDISK_ROOTSIZE=4096
VMDISK_SWAPSIZE=1024
VMDISK_FILESYSTEM=ext4
# settings are for speed and not data safety, we format anyway on next run
VMDISK_MOUNT_OPTIONS=__default
VMDISK_CLEAN=
HUGETLBFSPATH=
MEMSIZE=
RUNNING_IN_VM=
RPMLIST=
RELEASE=
REASON=
NOROOTFORBUILD=
LOGFILE=
KILL=
CHANGELOG=
BUILD_DEBUG=
PERSONALITY_SYSCALL=
INCARNATION=
DISTURL=
LINKSOURCES=
OVERLAY=
RSYNCSRC=
RSYNCDEST=
RSYNCDONE=
SIGNDUMMY=
HOST_ARCH=
EMULATOR_SCRIPT=
KVM_OPTIONS=

# list of archs which need emulator initialization
: ${EMULATOR_ARCHS:="armv4l armv5l armv6l armv7l armv5el armv6el armv7el armv7hl armv8el mips mipsel mips64 mips64el ppc ppc64 sh4 sparc sparc64 s390 s390x"}
export EMULATOR_ARCHS

# list of devices registered by binfmt handlers in /proc/sys/fs/binfmt_misc
: ${EMULATOR_DEVS:="arm armeb mips mipsel mips64 mips64el ppc sh4 sh4eb sparc s390x"}
export EMULATOR_DEVS

# This is for insserv
export YAST_IS_RUNNING=instsys

unset LANGUAGE
unset LANG
export LC_ALL=POSIX
umask 022

echo_help () {
    cat << EOT

Some comments for build
-----------------------

With build you can create rpm packages.  They will be built in a chroot
system.  This chroot system will be setup automatically.  Normally you can
simply call build with a spec file as parameter - nothing else has to be
set.

If you want to set the directory were the chroot system will be setup
(at the moment it uses $BUILD_ROOT),
simply set the the environment variable BUILD_ROOT.

Example:

  export BUILD_ROOT=/var/tmp/mybuildroot


Normally build builds the complete package including src.rpm (rpmbuild -ba).
If you want let build only make the binary package, simply set

   export BUILD_RPM_BUILD_STAGE=-bb

(or -bc, -bp, -bi, ...  see "Maximum RPM" for more details [*]).

When the build command succeeds, the rpm files can be found under
$BUILD_ROOT/usr/src/packages/RPMS/


Known Parameters:

  --help      You already got it :)

  --kill      Instead of starting a build kill the one currently
              running.

  --shell     Instead of starting a build start a root shell in
              the build root.

  --clean     Delete old build root before initializing it

  --no-init   Skip initialization of build root and start with build
              immediately.

  --no-checks Do not run post-build checks

  --lint      Run rpmlint after build.

  --logfile logfile
              Capture build output to logfile. Defaults to
              .build.log in the build root for non-VM builds.

  --repository PATH
	      Use package repository at PATH. Supported formats are
	      rpm-md and yast2.
	      Alternatively zypp://NAME specifies the zypp
	      repository NAME. The repo must be refreshed with zypp
	      so package meta data is available locally. With emtpy
	      NAME all enabled repositories are used.
              a url can specify a remote repo.

  --rpms path1:path2:...
              Specify path where to find the RPMs for the build system

  --arch arch1:arch2:...
              Specify what architectures to select from the RPMs

  --verify    Run verify when initializing the build root

  --extra-packs pack
  -X pack
              Also install package 'pack'

  --root rootdir
              Use 'rootdir' to setup chroot environment

  --cachedir cachedir
              Use 'cachedir' to cache remote repo's packages, the
              default cache dir is /var/cache/build, every repo
              given by --repository corresponds to a subdir named
              as md5sum of its repo url, for example:
                 /var/cache/build/3e8ea9b47808629414a0cebc33ea285e

  --oldpackages oldpackagesdir
              Define a directory with a former build

  --baselibs  Create -32bit/-64bit/-x86 rpms for other architectures

  --list-state
              List rpms that would be used to create a fresh build root.
              Does not create the build root or perform a build.

  --dist dist
              Distribution to use

  --with X
              Enable feature X for build

  --without X
              Disable feature X for build

  --define 'X Y'
              Define macro X with value Y

  --release release
              Override Release in spec file

  --stage -bSTAGE
              Set stage for rpmbuild. Defaults to -ba.

  --target platform
              Set target platform for rpmbuild

  --jobs N    Use N parallel processes during build.
              Sets %jobs and %_smp_mflags macros and
              defines the number of CPUs to use for
              VMs.

  --ccache
              Use ccache to speed up rebuilds

  --icecream N
              Use N parallel build jobs with icecream

  --overlay OVERLAY
              Copy overlay filesystem to buildroot after installing
              all RPMs. This must be a valid directory.

  --rsync-src RSYNCSRC
              Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
              inside the buildroot using rsync.
              It will "%define RSYNCDONE 1" for handling %setup in your
              specfile. E.g.:
              %prep
              %if 0%{?RSYNCDONE}
              %setup -n aaa_base -T -D -b 5 -b 7
              %else
              %setup -n aaa_base -b 5 -b 7
              %endif

  --rsync-dest RSYNCDEST
              Copy overlay folder (RSYNCSRC) to a folder (RSYNCDEST)
              inside the buildroot using rsync.

  --uid uid:gid
              Specify the uid and gid to use for the abuild user.
              This is useful if you are hacking in the buildroot.
              This must be set to the same value if the buildroot is re-used.

  --statistics
              monitor used resources during build inside VM

  --kvm
              Use KVM to secure build process. Your hardware needs to support
              virtualization

  --xen
              Use XEN to secure build process, you to run in a XEN Dom0 environment.

  --lxc
              Use Linux Containers to isolate the process. This may not be 100% safe.

  --emulator 
              Use any generic emulator to isolate the build process. You need to write
              an emulator/emulator.sh script and put it next to the build script sources.
              You must NOT use any vm swap file for this.

  --emulator-script SCRIPT
              specify another emulator instead of emulator.sh

  --vm-type TYPE
              Use virtual machine instead of chroot
              TYPE is one of xen|kvm|uml|qemu|lxc|zvm

  --vm-worker GUEST
              GUEST is a z/VM build worker controlled by the controlling
	      z/VM build machine. 

  --vm-worker-nr N
              Each worker in z/VM needs a uniq number. This is needed to 
              calculate uniq device addresses for root and swap device.

  --vm-disk FILE
              Use FILE as disk for virtual machine.
              Defaults to \$BUILD_ROOT.img if unset

  --vm-swap FILE
              Use FILE as swap space for virtual machine. The swap space is
              also used for retrieving packages from the VM so its size must
              be sufficiently large

  --vm-disk-size SIZEINMB
  --vm-swap-size SIZEINMB
  --vm-disk-filesystem TYPE
              Defaults for automatic setup of VM root/swap files

  --vm-memory SIZEINMB
              Set amount of RAM for VMs

  --hugetlbfs HUGETLBFSPATH
              Use hugetlb for memory management, path to mounted hugetlbfs.

  --vm-kernel FILE
  --vm-initrd FILE
              Kernel and initrd to use for VM (kvm and qemu only)

  --debug
              Enable creation of a debuginfo package

Remember to have fun!

[*] Maximum RPM: http://www.rpm.org/max-rpm/
EOT
}
usage () {
    echo "Usage: `basename $0` [--no-init|--clean|--rpms path|--verify|--help] [dir-to-build|spec-to-build]"
    cleanup_and_exit 1
}

#
#  cleanup_and_exit
#  return values: 0 -> success, new packages built
#                 1 -> error, build failed
#                 2 -> successfull build, but no changes to former built packages
#                 3 -> something wrong with build host
#
cleanup_and_exit () {
    trap EXIT
    test -z "$1" && set 0
    rm -f $BUILD_ROOT/.repo.config
    rm -f $BUILD_ROOT/exit
    if test "$1" -eq 1 -a -x /bin/df ; then
        # okay, it failed, but maybe because disk space?
	if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then
	    set 3
        fi
    fi
    if test -n "$RUNNING_IN_VM" ; then
	echo "$1" >  /.build/_exitcode
	test -n "$browner" && chown "$browner" $BUILD_ROOT
	cd /
	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
	if test "$VM_TYPE" != lxc; then
	    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
		halt -f -p
	    fi
	    echo "Warning: clean shut down of the VM didn't work"
	fi
    else
	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
	test "$VM_IMAGE" = 1 && VM_IMAGE=
	[ -n "$VM_IMAGE" ] && umount $BUILD_ROOT 2>/dev/null || true
    fi
#    echo "pid $$ exit $1"
    exit $1
}

fail_exit()
{
  cleanup_and_exit 1
}

shellquote()
{
    for arg; do
	arg=${arg/\\/\\\\}
	arg=${arg/\$/\\\$}
	arg=${arg/\"/\\\"}
	arg=${arg/\`/\\\`}
	echo -n " \"$arg\""
    done
}

# create a shell script from command line. Used for preserving arguments
# through /bin/su -c
toshellscript()
{
	echo "#!/bin/sh -x"
	echo -n exec
	shellquote "$@"
	echo
}

setupccache()
{
    if [ "$ccache" = 1 ]; then
	if mkdir -p $BUILD_ROOT/var/lib/build/ccache/bin; then
	    for i in $(ls $BUILD_ROOT/usr/bin | grep -E '^(cc|gcc|[cg][+][+])([-]?[234][.]?[0-9])*$'); do
#                ln -sf /usr/bin/ccache $BUILD_ROOT/var/lib/build/ccache/bin/$i
		rm -f $BUILD_ROOT/var/lib/build/ccache/bin/$i
		test -e $BUILD_ROOT/usr/bin/$i || continue
		echo '#! /bin/sh' > $BUILD_ROOT/var/lib/build/ccache/bin/$i
		echo "test -e /usr/bin/$i || exit 1" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
		echo 'export PATH=/usr/lib/icecream/bin:/opt/icecream/bin:/usr/bin:$PATH' >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
		echo "ccache $i \"\$@\"" >> $BUILD_ROOT/var/lib/build/ccache/bin/$i
		chmod 755 $BUILD_ROOT/var/lib/build/ccache/bin/$i
		echo "Installed ccache wrapper as $BUILD_ROOT/var/lib/build/ccache/bin/$i"
	    done
	fi
	mkdir -p "$BUILD_ROOT"/.ccache
	chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/.ccache"
	echo "export CCACHE_DIR=/.ccache" > "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
	echo 'export PATH=/var/lib/build/ccache/bin:$PATH' >> "$BUILD_ROOT"/etc/profile.d/build_ccache.sh
    else
	rm -f "$BUILD_ROOT"/var/lib/build/ccache/bin/{gcc,g++,cc,c++}
    fi
}

setupicecream()
{
    if [ "$icecream" -eq 0 ]; then
	rm -rf "$BUILD_ROOT/var/run/icecream"
	rm -f "$BUILD_ROOT/etc/profile.d/build_icecream.sh"
	return
    fi

    if ! chroot "$BUILD_ROOT" rpm -q icecream >/dev/null 2>/dev/null; then
	echo "*** icecream package not installed ***"
	false
	return
    fi

    echo "using icecream with $icecream jobs"

    if [ "$ccache" -ne 1 ]; then
	echo 'export PATH=/usr/lib/icecream/bin:/opt/icecream/bin:$PATH' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
    else
	echo 'export CCACHE_PATH=/usr/lib/icecream/bin:/opt/icecream/bin' > "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
    fi

    local icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/var/run/icecream/*.tar.{bz2,gz}`)
    icecc_vers=${icecc_vers//$BUILD_ROOT/}

    # XXX use changelog like autobuild does instead?
    # only run create-env if compiler or glibc changed
    if [ -z "$icecc_vers" \
	-o ! -e "$BUILD_ROOT/$icecc_vers" \
	-o "$BUILD_ROOT/usr/bin/gcc" -nt "$BUILD_ROOT/$icecc_vers" \
	-o "$BUILD_ROOT/usr/bin/g++" -nt "$BUILD_ROOT/$icecc_vers" \
	-o "$BUILD_ROOT/usr/bin/as" -nt "$BUILD_ROOT/$icecc_vers" \
	-o "$BUILD_ROOT/lib/libc.so.6" -nt "$BUILD_ROOT/$icecc_vers" ]
    then
	rm -rf "$BUILD_ROOT/var/run/icecream"
	mkdir -p "$BUILD_ROOT/var/run/icecream"
	if [ -e "$BUILD_ROOT"/usr/bin/create-env ]; then
	  createenv=/usr/bin/create-env
	elif [ -e "$BUILD_ROOT"/usr/lib/icecc/icecc-create-env ]; then
	  createenv="/usr/lib/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
	elif [ -e "$BUILD_ROOT"/usr/lib64/icecc/icecc-create-env ]; then
	  createenv="/usr/lib64/icecc/icecc-create-env /usr/bin/gcc /usr/bin/g++" # XXX
	else
	  echo "create-env not found"
	  false
	  return
	fi
	chroot $BUILD_ROOT bash -c "cd /var/run/icecream; $createenv" || cleanup_and_exit 1
	icecc_vers=(`shopt -s nullglob; echo $BUILD_ROOT/var/run/icecream/*.tar.{bz2,gz}`)
	icecc_vers=${icecc_vers//$BUILD_ROOT/}
    else
	echo "reusing existing icecream environment $icecc_vers"
    fi
    if [ -n "$icecc_vers" ]; then
      echo "export ICECC_VERSION=$icecc_vers" >> "$BUILD_ROOT"/etc/profile.d/build_icecream.sh
    fi
}

setmemorylimit()
{
    if [ -n "$VM_IMAGE" -o -n "$RUNNING_IN_VM" ]; then
	return
    fi
    local mem
    local limit
    while read mem; do
	case "$mem" in
	    MemTotal:*)
		set -- $mem
		eval "limit=\$(($2/3*4))"
	    ;;
	    SwapTotal:*)
		set -- $mem
		eval "limit=\$(($2/3*4+$limit))"
	    ;;
	esac
    done < <(cat /proc/meminfo) # cat for proc stuff

    ulimit -v $limit
    echo "Memory limit set to ${limit}KB"
}

create_baselibs()
{
    local pkgs=()
    local line

    BASELIBS_CFG=

    if test "$BUILDTYPE" == "arch" ; then
	return
    fi
    if test "$BUILDTYPE" == "dsc" ; then
	pkgs=($DEBS)
    else # spec and kiwi
	if test -e $BUILD_ROOT$TOPDIR/SOURCES/baselibs.conf ; then
	    BASELIBS_CFG="-c $TOPDIR/SOURCES/baselibs.conf"
	fi
	if test -e $BUILD_ROOT/usr/lib/build/baselibs_global.conf; then
	    BASELIBS_GLOBAL="-c /usr/lib/build/baselibs_global.conf"
	fi
	pkgs=($RPMS)
    fi

    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
    # don't use -R as extracted sources, build root etc might be below $TOPDIR
    chown "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/RPMS/* || true

    local mkbaselibs="/usr/lib/build/mkbaselibs"
    local whichone=''
    # $BUILD_DIR is set to /.build when using a vm. So we need to
    # hardcode /usr/lib/build instead of $BUILD_DIR to prefer
    # mkbaselibs from the distro.
    if test -f $BUILD_ROOT$mkbaselibs; then
	if test -z "$BASELIBS_CFG" -a -e $BUILD_ROOT/usr/lib/build/baselibs.conf ; then
	    BASELIBS_CFG="-c /usr/lib/build/baselibs.conf"
	fi
    else
	if test "$CREATE_BASELIBS" = 'internal'; then
	    echo "Warning: mkbaselibs missing in build root, skipping baselibs"
	    return
	fi
	# use external version
	whichone=" (external)"
	mkbaselibs="/.mkbaselibs/mkbaselibs"
	rm -rf "$BUILD_ROOT/.mkbaselibs"
	mkdir -p "$BUILD_ROOT/.mkbaselibs"
	cp -f $BUILD_DIR/mkbaselibs $BUILD_ROOT/.mkbaselibs/
	if test "$BUILDTYPE" == "dsc" ; then
	    cp -f $BUILD_DIR/baselibs_global-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf
	    cp -f $BUILD_ROOT$TOPDIR/SOURCES/baselibs-deb.conf $BUILD_ROOT/.mkbaselibs/baselibs-deb.conf
	    BASELIBS_CFG="-c /.mkbaselibs/baselibs-deb.conf"
	else
	    cp -f $BUILD_DIR/baselibs_global.conf $BUILD_ROOT/.mkbaselibs/baselibs_g.conf
	    if test -z "$BASELIBS_CFG" -a -e $BUILD_DIR/baselibs.conf; then
		cp -f $BUILD_DIR/baselibs.conf $BUILD_ROOT/.mkbaselibs/baselibs.conf
		BASELIBS_CFG="-c /.mkbaselibs/baselibs.conf"
	    fi
	fi
	if test -e $BUILD_ROOT/.mkbaselibs/baselibs_g.conf; then
	    BASELIBS_GLOBAL="-c /.mkbaselibs/baselibs_g.conf"
	fi
    fi
    echo "... creating baselibs$whichone"
    while read line
    do
	chroot $BUILD_ROOT su -c "$mkbaselibs $BASELIBS_GLOBAL $BASELIBS_CFG $line" - $BUILD_USER || cleanup_and_exit 1
    done < <(IFS=$'\n'; echo "${pkgs[*]#$BUILD_ROOT}" | xargs -n 1024)
    rm -rf "$BUILD_ROOT/.mkbaselibs"
}

copy_oldpackages()
{
    local i=0
    local d
    local dest
    [ -z "$RUNNING_IN_VM" ] || return 0
    if [ -z "$old_packages" ]; then
	rm -rf "$BUILD_ROOT"/.build.oldpackages*
	return 0
    fi
    for d in "${old_packages[@]}"; do
	dest="$BUILD_ROOT/.build.oldpackages"
	test "$i" = 0 || dest="$dest$i"
	if [ -d "$d" -a "$d" != "$dest" ] ; then
	    rm -rf "$dest"
	    mkdir -p "$dest"
	    cp -L $d/* "$dest"
	    : $((++i))
	fi
    done
}

vm_img_mkfs()
{
    local fs="$1"
    local img="$2"
    local mkfs tunefs
    eval "mkfs=\"\$vm_img_mkfs_${fs}\""
    eval "tunefs=\"\$vm_img_tunefs_${fs}\""

    if test -z "$mkfs"; then
	echo "filesystem \"$fs\" isn't supported"
	cleanup_and_exit 3
    fi


    echo "Creating $fs filesystem on $img"
    $mkfs "$img"
    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

    # memory usage
    if [ -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 [ ${memtotal} -gt $max_mem ]; then
        max_mem="${memtotal}"
        echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory
      fi
    fi

    # disk storage usage
    if type -p df >& /dev/null; then
      c=(`df -m / | tail -n 1`)

      if [ ${c[2]} -gt $max_disk ]; then
        max_disk="${c[2]}"
        echo -n $max_disk > /.build/_statistics.df
      fi
    fi

    [ -e /.build/_statistics.exit ] && exit 0
  done
}

detect_vm_2nd_stage()
{
    if ! test "$0" = "/.build/build" ; then
	return 1
    fi
    if test $$ -eq 1 ; 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
    echo "2nd stage started in virtual machine"
    BUILD_ROOT=/
    BUILD_DIR=/.build
    . $BUILD_DIR/build.data
    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
# qemu inside of xen does not work, check again with kvm later before enabling this
#    if [ -e /dev/kqemu ]; then
#        # allow abuild user to run qemu
#        chmod 0666 /dev/kqemu
#    fi
    if test "$VM_TYPE" = 'zvm' ; then
        VM_SWAP='/dev/dasdb1'
    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
	swapon -v "$VM_SWAP" || exit 1
    fi
    HOST="$MYHOSTNAME"

    # fork a process monitoring max filesystem fillment during build
    if test "$statistics" = "1"; then
        background_monitor_process &
    fi

    # set date to build start on broken systems (now < build start)
    if [ $(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
}

find_spec_files()
{
    local spec files
    if [ -z "$SPECFILES" ]; then
	set -- "`pwd`"
    else
	set -- "${SPECFILES[@]}"
    fi
    SPECFILES=()
    for spec in "$@"; do
	if [ "$spec" = "${spec#/}" ]; then
	    spec="`pwd`/$spec"
	fi

	if [ -d "$spec" ]; then
	    specs=("$spec"/*.spec)
	    if [ -n "$specs" ]; then
		SPECFILES=("${SPECFILES[@]}" "${specs[@]}")
	    else
		specs=("$spec"/*.spec)
		if [ -n "$specs" ]; then
		    SPECFILES=("${SPECFILES[@]}" "${specs[@]}")
		fi
	    fi
	else
	    SPECFILES[${#SPECFILES[@]}]="$spec";
	fi
    done

    if test -z "$SPECFILES"; then
	echo no spec files or src rpms found in $@. exit...
	cleanup_and_exit 1
    fi
}

become_root_or_fail()
{
    if [ ! -w /root ]; then
	echo "You have to be root to use $0" >&2
	exit 1
    fi
    cleanup_and_exit 1
}

mkdir_build_root()
{
    if [ -d "$BUILD_ROOT" ]; then
	# check if it is owned by root
	if [ -z "$RUNNING_IN_VM" -a \! -O "$BUILD_ROOT" -a "`stat -c %u $BUILD_ROOT`" -ne 0 ]; then
	    echo "BUILD_ROOT=$BUILD_ROOT must be owned by root. Exit..."
	    cleanup_and_exit 1
	fi
    else
	test "$BUILD_ROOT" != "${BUILD_ROOT%/*}" && mkdir -p "${BUILD_ROOT%/*}"
	if ! mkdir $BUILD_ROOT; then
	    echo "can not create BUILD_ROOT=$BUILD_ROOT. Exit..."
	    cleanup_and_exit 1
	fi
    fi

    if [ ! -w "$BUILD_ROOT" ]; then
	echo "Error: BUILD_ROOT=$BUILD_ROOT not writeable, try --clean."
	cleanup_and_exit 3
    fi

    rm -rf "$BUILD_ROOT/.build.packages"
    if [ -z "$VM_TYPE" -a -z "$RUNNING_IN_VM" ]; then
       # don't touch this in VM
       rm -rf "$BUILD_ROOT/.build"
       mkdir -p "$BUILD_ROOT/.build"
    fi
}

linux64()
{
	perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@"
}

check_for_arm()
{
    local uname

    uname=$(uname -m)

    if [ "$uname" != "armv7l" ]; then
        return
    fi

    export HOST_ARCH=armv7l

    export kvm_bin="/usr/bin/qemu-system-arm"
    export console=ttyAMA0
    export KVM_OPTIONS="-enable-kvm -M vexpress-a15 -dtb /boot/a15-guest.dtb -cpu cortex-a15 -m 1500"
    export VM_KERNEL=/boot/zImage.vexpress
    export VM_INITRD=/boot/initrd
}

hide_passwords()
{
    local i j
    r=()
    rm -f $BUILD_ROOT/.repo.config
    for i in "${repos[@]}"; do
        if [ "$i" == "--repo" -o "$i" == "--repository" ]; then
            r=("${r[@]}" "$i")
        else
            echo $i |grep -E "^http[s]?:\/\/[^\/]*\/?" >/dev/null && echo $i >> $BUILD_ROOT/.repo.config
            j=$(echo $i | sed -e "s#://[^@]*@#://#")
            r=("${r[@]}" "$j")
        fi
    done
    repos=("${r[@]}")
    echo ${repos[@]}
}

check_for_ppc()
{
    local uname

    uname=$(uname -m)

    if [ "$uname" != "ppc" -a "$uname" != "ppc64" ]; then
        return
    fi

    grep -q "PowerNV" /proc/cpuinfo && export HOST_ARCH=power7 || export HOST_ARCH=ppc970

    export kvm_bin="/usr/bin/qemu-system-ppc64"
    export console=hvc0
    export KVM_OPTIONS="-enable-kvm -M pseries -mem-path /hugetlbfs"
    export VM_KERNEL=/boot/vmlinux
    export VM_INITRD=/boot/initrd
    if [ -z "$RUNNING_IN_VM" -a "$VM_TYPE" = "kvm" ];then
      if ! grep -q "/hugetlbfs" /proc/mounts; then
         echo "hugetlbfs is not mounted"
         exit 1
      fi
         PAGES_FREE=$(cat /sys/kernel/mm/hugepages/hugepages-16384kB/free_hugepages)
         PAGES_REQ=$(( ${MEMSIZE:-64} / 16 ))
      if [ "$PAGES_FREE" -lt "$PAGES_REQ" ];then
         echo "please adjust nr_hugepages"
         exit 1
      fi
      if [ "$HOST_ARCH" = "ppc970" ];then
          if ! grep -q -E '(kvm_rma_count.*kvm_hpt_count)|(kvm_hpt_count.*kvm_rma_count)' /proc/cmdline; then
             echo "put kvm_rma_count=<VM number> or kvm_hpt_count=<> to your boot options"
             exit 1
          fi
      fi
   fi
}

#### main ####

trap fail_exit EXIT

archname=`perl -V:archname`
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 "ARCHITECTURE PERSONALITY IS UNKNOWN"; exit 1;;
esac

shopt -s nullglob

export PATH=$BUILD_DIR:/sbin:/usr/sbin:$PATH

if detect_vm_2nd_stage ; then
    set "/.build-srcdir/$SPECFILE"
    export PATH=/.build:$PATH
fi

. $BUILD_DIR/common_functions || exit 1
. $BUILD_DIR/zvm_functions || exit 1

export HOST

needarg()
{
  if [ -z "$ARG" ]; then
    echo "$PARAM needs an agrument" >&2
    cleanup_and_exit 1
  fi
}

while test -n "$1"; do
  PARAM="$1"
  ARG="$2"
  [ "$ARG" = "${ARG#-}" ] || ARG=""
  shift
  case $PARAM in
    *-*=*)
      ARG=${PARAM#*=}
      PARAM=${PARAM%%=*}
      set -- "----noarg=$PARAM" "$@"
  esac
  case $PARAM in
      *-help|-h)
	echo_help
	cleanup_and_exit
      ;;
      *-no*init)
	DO_INIT=false
      ;;
      *-no-build)
	DO_BUILD=false
      ;;
      *-no*checks)
	DO_CHECKS=false
      ;;
      -clean|--clean)
	CLEAN_BUILD='--clean'
      ;;
      *-kill)
	KILL=true
      ;;
      *-rpms)
	needarg
	BUILD_RPMS="$ARG"
	shift
      ;;
      *-arch)
	needarg
	BUILD_ARCH="$ARG"
	shift
      ;;
      *-verify)
	export VERIFY_BUILD_SYSTEM=true
      ;;
      *-target)
	needarg
	ABUILD_TARGET="$ARG"
	shift
      ;;
      *-jobs)
	needarg
	BUILD_JOBS="$ARG"
	shift
      ;;
      *-extra*packs|-X)
	needarg
	BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS $ARG"
	shift
      ;;
      *-lint)
	DO_LINT=true
	;;
      *-baselibs)
	CREATE_BASELIBS=true
	;;
      *-baselibs-internal)
	CREATE_BASELIBS=internal
	;;
      *-use-system-qemu)
	USE_SYSTEM_QEMU="--use-system-qemu"
      ;;
      --keep-packs)
	KEEP_PACKS="--keep-packs"
      ;;
      *-root)
	needarg
	BUILD_ROOT="$ARG"
	shift
      ;;
      *-cachedir)
	needarg
	CACHE_DIR="$ARG"
	shift
      ;;
      *-oldpackages)
	needarg
	old_packages=("${old_packages[@]}" "$ARG")
	shift
      ;;
      *-dist)
	needarg
	BUILD_DIST="$ARG"
	shift
      ;;
      *-emulator-script)
	needarg
	EMULATOR_SCRIPT="$ARG"
	shift
      ;;
      *-xen|*-kvm|--uml|--qemu|--emulator)
	VM_TYPE=${PARAM##*-}
	if [ -n "$ARG" ]; then
	    VM_IMAGE="$ARG"
	    shift
	else
	    VM_IMAGE=1
	fi
      ;;
      *-zvm)
        VM_TYPE="zvm"
	shift
      ;;
      --lxc)
	VM_TYPE=${PARAM##*-}
      ;;
      --vm-type)
	needarg
	VM_TYPE="$ARG"
	case "$VM_TYPE" in
            zvm) ;;
	    xen|kvm|uml|qemu|lxc|emulator)
		test -z "$VM_IMAGE" && VM_IMAGE=1
	        ;;
	    none|chroot) VM_TYPE='' ;;
	    *)
		echo "VM $VM_TYPE not supported"
		cleanup_and_exit
	    ;;
	esac
	shift
      ;;
      --vm-worker)
        needarg
        VM_WORKER="$ARG"
        shift
      ;;
      --vm-worker-nr)
        needarg
        zvm_worker_nr="$ARG"
        shift
      ;;
      --vm-disk)
	needarg
	VM_IMAGE="$ARG"
	shift
      ;;
      *-xenswap|*-swap)
	needarg
	VM_SWAP="$ARG"
	shift
      ;;
      *-xenmemory|*-memory)
	needarg
	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)
        HUGETLBFSPATH="$ARG"
	shift
      ;;
      *-release)
	needarg
	RELEASE="$ARG"
	shift
      ;;
      *-logfile)
	needarg
	LOGFILE="$ARG"
	shift
      ;;
      *-reason)
	needarg
	REASON="$ARG"
	shift
      ;;
      *-norootforbuild)
	NOROOTFORBUILD=true
      ;;
      *-stage)
	needarg
	BUILD_RPM_BUILD_STAGE="$ARG"
	shift
      ;;
      *-short-circuit)
        SHORT_CIRCUIT=true
      ;;
      *-no-topdir-cleanup)
        NO_TOPDIR_CLEANUP=true
      ;;
      *-useusedforbuild)
	USEUSEDFORBUILD="--useusedforbuild"
      ;;
      *-configdir)
        needarg
	CONFIG_DIR="$ARG"
        shift
      ;;
      *-list*state)
	LIST_STATE=true
      ;;
      --define|--with|--without)
	needarg
	definesnstuff[${#definesnstuff[@]}]="$PARAM";
	definesnstuff[${#definesnstuff[@]}]="$ARG";
	shift
      ;;
      --repository|--repo)
	needarg
	repos[${#repos[@]}]="$PARAM";
	repos[${#repos[@]}]="$ARG";
	shift
      ;;
      --icecream)
	needarg
	icecream="$ARG"
	if [ "$icecream" -gt 0 ]; then
		BUILD_JOBS="$ARG"
	fi
	shift
      ;;
      --ccache)
	ccache=1
      ;;
      --statistics)
	statistics=1
      ;;
      --debug)
	BUILD_DEBUG=1
      ;;
      --incarnation)
	needarg
	INCARNATION=$ARG
	shift
      ;;
      --disturl)
	needarg
	DISTURL=$ARG
	shift
      ;;
      --linksources)
	LINKSOURCES=true
      ;;
      ----noarg)
	echo "$ARG does not take an argument"
	cleanup_and_exit
      ;;
      *-changelog)
	CHANGELOG=true
      ;;
      --overlay)
	needarg
	OVERLAY=$ARG
	shift
      ;;
      --rsync-src)
	needarg
	RSYNCSRC=$ARG
	shift
      ;;
      --rsync-dest)
	needarg
	RSYNCDEST=$ARG
	shift
      ;;
      --uid)
	needarg
	ABUILD_ID="$ARG"
	if test -n "${ABUILD_ID//[0-9:]/}"; then
	    echo "--uid argument must be uid:gid"
	    cleanup_and_exit
	fi
	ABUILD_UID=${ABUILD_ID%:*}
	ABUILD_GID=${ABUILD_ID#*:}
	shift
      ;;
      --shell)
	  shell=1
	  shift
      ;;
      --signdummy)
	SIGNDUMMY=1
      ;;
      -*)
	echo Unknown Option "$PARAM". Exit.
	cleanup_and_exit 1
      ;;
      *)
	SPECFILES[${#SPECFILES[@]}]="$PARAM";
      ;;
    esac
done

check_for_ppc
check_for_arm

if [ "$SHORT_CIRCUIT" = true -a -z "$BUILD_RPM_BUILD_STAGE" ]; then
    echo "--short-circuit needs a stage (use --stage)"
    cleanup_and_exit 1
fi

if test "$VM_TYPE" = "lxc"; then
    VM_IMAGE=''
    VM_SWAP=''
fi

if test "$VM_TYPE" = "zvm"; then
    VM_IMAGE='/dev/dasda1'
    VM_SWAP='/dev/dasdb1'
fi

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" -o "$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

if test -n "$KILL" ; then
    test -z "$SRCDIR" || usage
    if test -n "$VM_IMAGE" -a -n "$VM_SWAP" -a -n "$VM_TYPE"; then
	# mark job as failed so that we don't extract packages
	if test "$VM_TYPE" != "zvm"; then
	    echo -n "BUILDSTATUS1" >"$VM_SWAP"
        fi
    fi
    (set -C; > "$BUILD_ROOT/exit" 2>/dev/null || true)
    if test "$VM_TYPE" = 'lxc'; then
	LXCID=${BUILD_ROOT##*/}
	lxc-stop -n "$LXCID" || true
	lxc-destroy -n "$LXCID"
    elif test -z "$VM_IMAGE" ; then
	if ! $BUILD_DIR/killchroot -s 9 $BUILD_ROOT ; then
	    echo "could not kill build in $BUILD_ROOT"
	    cleanup_and_exit 1
	fi
    elif test "$VM_TYPE" = 'xen'; then
	XENID="${VM_IMAGE%/root}"
	XENID="${XENID%/tmpfs}"
	XENID="${XENID##*/}"
	XENID="${XENID#root_}"
	if xm list "build_$XENID" >/dev/null 2>&1 ; then
	    if ! xm destroy "build_$XENID" ; then
		echo "could not kill xen build $XENID"
		cleanup_and_exit 1
	    fi
	fi
    elif test "$VM_TYPE" = 'zvm'; then
	if vmcp q "$VM_WORKER" > /dev/nulll 2>&1 ; then
            if ! zvm_cp destroy $VM_WORKER ; then
	        echo "could not kill zvm worker $VM_WORKER"
		cleanup_and_exit 1
            fi
        fi
    elif test -n "$VM_TYPE"; then
	if ! fuser -k -TERM "$VM_IMAGE"; then
	    echo "could not kill build in $VM_IMAGE"
	    cleanup_and_exit 1
	fi
    else
	echo "don't know how to kill this build job"
	cleanup_and_exit 1
    fi
    cleanup_and_exit 0
fi

if [ "$VM_TYPE" = 'xen' -a -z "$RUNNING_IN_VM" ]; then
    # XXX: merge with kvm path?
    if [ -n "$VM_KERNEL" ]; then
	vm_kernel="$VM_KERNEL"
    elif [ -e "/boot/vmlinuz-xen" ]; then
	vm_kernel="/boot/vmlinuz-xen"
    fi
    if [ -n "$VM_INITRD" ]; then
	vm_initrd="$VM_INITRD"
    elif [ -e "/boot/initrd-xen" ]; then
	vm_initrd="/boot/initrd-xen"
    fi
fi

if [ "$VM_TYPE" = 'zvm' -a -z "$RUNNING_IN_VM" ]; then
    # verify settings
    # In z/VM, this is a 4 digit hex number instead of a linux device.
    # This is the root disk defined in user direct
    # This number can be given with the parameter --root NR.
    if [ -z "$VM_VOLUME_ROOT" ]; then
        if [ -n "$BUILD_ROOT" -a ${#BUILD_ROOT} -le 4 ]; then
            VM_VOLUME_ROOT="$BUILD_ROOT"
        else
            VM_VOLUME_ROOT="0150"
        fi
    fi
    # In z/VM, this is a 4 digit hex number instead of a linux device.
    # This is the swap disk defined in user direct
    # This number can be given with the parameter --swap NR.
    if [ -z "$VM_VOLUME_SWAP" ]; then
        if [ -n "$VM_SWAP" -a ${#VM_SWAP} -le 4 ]; then
            VM_VOLUME_SWAP="$VM_SWAP"
        else
            VM_VOLUME_SWAP="0250"
        fi
    fi
    # z/VM guest name that is already defined in z/VM
    if [ -z "$VM_WORKER" ]; then
        echo "ERROR: No z/VM worker id specified"
	cleanup_and_exit 3
    fi
    if [ -z "$zvm_worker_nr" ]; then
        echo "ERROR: No z/VM worker number specified"
        cleanup_and_exit 3
    fi
    # need the name for a kernel in zvm
    if [ -n "$VM_KERNEL" ]; then
        vm_kernel="$VM_KERNEL"
    elif [ -e "/boot/vmlinux.gz" ]; then
        vm_kernel="/boot/vmlinux.gz"
    else
        echo "ERROR: No z/VM kernel specified"
	cleanup_and_exit 3
    fi
    # need the name for an initrd in zvm
    # this normally will not be the local initrd
    if [ -n "$VM_INITRD" ]; then
        vm_initrd="$VM_INITRD"
    else
        echo "ERROR: No z/VM initrd specified"
	cleanup_and_exit 3
    fi
fi

if [ "$VM_TYPE" = 'kvm' -a -z "$RUNNING_IN_VM" ]; then
    if [ ! -r /dev/kvm -o ! -x "$kvm_bin" ]; then
	echo "host doesn't support kvm"
	echo "either the kvm kernel-module is not loaded or kvm is not installed or hardware virtualization is deactivated in the BIOS."
	cleanup_and_exit 3
    fi
    qemu_bin="$kvm_bin"
    if [ -n "$VM_KERNEL" ]; then
	vm_kernel="$VM_KERNEL"
    fi

    # check if a SUSE system with virtio initrd is running
    if [ -z "$VM_INITRD" -a -e /etc/sysconfig/kernel ]; then
       a=$( source /etc/sysconfig/kernel; echo $INITRD_MODULES )
       have_virtio_pci=""
       have_virtio_blk=""
       for i in $a; do
          [ "$i" == "virtio_pci" ] && have_virtio_pci="1"
          [ "$i" == "virtio_blk" ] && have_virtio_blk="1"
       done
       [ -n "$have_virtio_pci" -a -n "$have_virtio_blk" ] && VM_INITRD="/boot/initrd"
    fi

    if [ -n "$VM_INITRD" ]; then
	vm_initrd="$VM_INITRD"
	kvm_virtio=1
    elif [ -e "${vm_initrd}-build" ]; then
	vm_initrd="${vm_initrd}-build"
	kvm_virtio=1
    else
	if [ -L "$vm_initrd" ]; then
	    vm_initrd=`readlink -f "$vm_initrd"` || cleanup_and_exit 3
	fi
	vm_initrd_virtio="${vm_initrd}-virtio"

	if [ ! -e ${vm_initrd_virtio} -o $vm_kernel -nt ${vm_initrd_virtio} ]; then
	    mkinitrd_virtio_cmd=(env rootfstype="$VMDISK_FILESYSTEM" \
		    mkinitrd -d /dev/null \
		    -m "ext3 ext4 btrfs reiserfs binfmt_misc virtio_pci virtio_blk" \
		    -k $vm_kernel \
		    -i ${vm_initrd_virtio})
	    if [ ! -w /root -o -n "$RPMLIST" ]; then
		echo "No initrd that provides virtio support found. virtio accelleration disabled."
		echo "Run the following command as root to enable virtio:"
		shellquote "${mkinitrd_virtio_cmd[@]}"
		echo
	    elif /sbin/modinfo virtio_pci >/dev/null 2>&1; then
		echo "creating $vm_initrd_virtio"
		"${mkinitrd_virtio_cmd[@]}" || cleanup_and_exit 1
		kvm_virtio=1
		vm_initrd="${vm_initrd_virtio}"
	    fi
	else
	    kvm_virtio=1
	    vm_initrd="${vm_initrd_virtio}"
	fi
    fi

    case $HOST_ARCH in
        power7|armv7l) kvm_virtio=1;;
        ppc970) kvm_virtio=;;
    esac

    if [ "$kvm_virtio" = 1 ]; then
	VM_SWAPDEV=/dev/vdb
	qemu_rootdev=/dev/vda
    else
	VM_SWAPDEV=/dev/sdb
	qemu_rootdev=/dev/sda
    fi
fi

if [ "$VM_TYPE" = 'qemu' ]; then
    VM_SWAPDEV=/dev/sdb
    qemu_rootdev=/dev/sda
fi

if [ -z "$RPMLIST" -a -z "$RUNNING_IN_VM" ]; then
    if [ -z "$repos" -a -z "$BUILD_RPMS" ]; then
	repos=(--repository 'zypp://')
    fi
else
    repos=()
fi

set_build_arch

if [ -n "$CLEAN_BUILD" ]; then
    DO_INIT=true
fi

find_spec_files

if test -n "$LIST_STATE" ; then
    BUILD_ROOT=`mktemp -d /var/tmp/build-list-state-XXXXXX`
    test -d "$BUILD_ROOT" || cleanup_and_exit 3
    SPECFILE=$SPECFILES # only one specified anyways
    if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then
       rm -rf "$BUILD_ROOT/usr/src/packages"
       mkdir -p $BUILD_ROOT/usr/src/packages/SOURCES $BUILD_ROOT/usr/src/packages/SPECS
       rpm -i --nodigest --nosignature --root $BUILD_ROOT $SPECFILE || {
	   echo "could not install $SPECFILE." 2>&1
	   rm -rf "$BUILD_ROOT"
	   cleanup_and_exit 3
       }
       for SPECFILE in $BUILD_ROOT/usr/src/packages/SPECS/*.spec ; do : ; done
    fi
    init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --list-state "${definesnstuff[@]}" "${repos[@]}" $USEUSEDFORBUILD $SPECFILE $BUILD_EXTRA_PACKS
    ERR=$?
    rm -rf "$BUILD_ROOT"
    cleanup_and_exit $ERR
fi

# z/VM:
# 1. make sure that no buildjob exists anymore by doing an ipl of cms
# 2. detach the root device from the worker
# 3. link the device to the controlling guest
#    -> Need a uniq worker id to calculate a uniq device address for linking
#    -> VM_IMAGE is the resulting block device
echo "***********************************"
echo "VM_TYPE: $VM_TYPE script: $0"
if [ "$VM_TYPE" = 'zvm' ]; then
    if [ ! "$0" = "/.build/build" ] ; then
	echo "in controlling guest"
        zvm_cp worker_init $VM_WORKER $VM_VOLUME_ROOT $VM_VOLUME_SWAP $zvm_worker_nr
        zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
        zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
        VM_IMAGE=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr )
        VM_SWAP=$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr )
        if [ ! "${VM_IMAGE}" = "dasd${VM_IMAGE#dasd}" -o ! "${VM_SWAP}" = "dasd${VM_SWAP#dasd}" ]; then
            echo "did not get a real device for VM_IMAGES: $VM_IMAGE $VM_SWAP"
            cleanup_and_exit 3
        else 
echo "FIRST: VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
            VM_IMAGE="/dev/"${VM_IMAGE}
	    VM_SWAP="/dev/"${VM_SWAP}
        fi
    fi
fi

echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"

# doing setup
if test -z "$RUNNING_IN_VM" ; then
    if test -n "$VM_IMAGE" ; then
	if test "$VM_IMAGE" = 1 ; then
	    VM_IMAGE="$BUILD_ROOT.img"
	    echo "using $VM_IMAGE as vm image"
	    if test -z "$VM_SWAP" -a "$VM_TYPE" != "emulator"; then
		VM_SWAP="$BUILD_ROOT.swap"
		echo "using $VM_SWAP as vm swap"
	    fi
	fi
	if [ "$VM_TYPE" = 'xen' ]; then
	    # this should not be needed, but sometimes a xen instance got lost
	    XENID="${VM_IMAGE%/root}"
	    XENID="${XENID%/tmpfs}"
	    XENID="${XENID##*/}"
	    XENID="${XENID#root_}"
	    xm destroy "build_$XENID" >/dev/null 2>&1
	fi
	if test -n "$VMDISK_CLEAN" ; then
	    # delete old root/swap to get rid of the old blocks
	    if test -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
	    echo "Creating $VM_IMAGE (${VMDISK_ROOTSIZE}M)"
	    mkdir -p "${VM_IMAGE%/*}"
	    dd if=/dev/zero of="$VM_IMAGE" bs=1M count=0 seek="$VMDISK_ROOTSIZE" || cleanup_and_exit 3
	    if test -z "$CLEAN_BUILD" ; then
		vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3
	    fi
	fi
	if test -n "$VM_SWAP" -a ! -e "$VM_SWAP" -a ! -b "$VM_SWAP"; then
	    # setup VM_SWAP
	    echo "Creating $VM_SWAP (${VMDISK_SWAPSIZE}M)"
	    mkdir -p "${VM_SWAP%/*}"
	    dd if=/dev/zero of="$VM_SWAP" bs=1M count=0 seek="$VMDISK_SWAPSIZE" || cleanup_and_exit 3
	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
	mkdir_build_root
	if [ -w /root ]; then
            if [ -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
    else
	test -w /root || become_root_or_fail
    fi
    if test -n "$VM_SWAP" ; then
	dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null
	echo "mkswap $VM_SWAP"
	mkswap "$VM_SWAP"
    fi
fi

mkdir_build_root
hide_passwords

if [ "$BUILD_ROOT" = / ]; then
    read dummy dummy browner dummy < <(ls -ld /)
fi

rm -f $BUILD_ROOT/exit

if [ -w /root ]; then
    mkdir -p $BUILD_ROOT/proc
    mkdir -p $BUILD_ROOT/dev/pts
    mount -n -tproc none $BUILD_ROOT/proc || true
    mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts
fi

if test -z "$VM_IMAGE" -a -z "$LOGFILE"; then
    LOGFILE="$BUILD_ROOT/.build.log"
fi

if test -n "$LOGFILE" -a -z "$shell" ; then
    echo  logging output to $LOGFILE...
    rm -f $LOGFILE
    touch $LOGFILE
    # set start time, to be substracted for build log timestamps
    STARTTIME=`perl -e 'print time()'`

    if [ -n "$RUNNING_IN_VM" ]; then
        # no additional timestamps in inner vm build system
	exec 1> >(exec -a 'build logging' tee -a $LOGFILE) 2>&1
    elif test -n "$VM_IMAGE" ; then
        # external run of virtualization build
	exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;s/^\r//s;s/\r\n/\n/gs;print F $p.$_}' $LOGFILE) 2>&1
    else
        # plain chroot
	exec 1> >(exec -a 'build logging' perl -e 'open(F,">>",$ARGV[0])||die("$ARGV[0]: $!\n");$|=1;select(F);$|=1;while(<STDIN>){my $p=sprintf("[%5ds] ", time()-'$STARTTIME');print STDOUT $p.$_;print F $p.$_}' $LOGFILE) 2>&1
    fi
fi

setmemorylimit

#
# say hello
#
test -z "$HOST" && HOST=`hostname`

if [ -z "$RUNNING_IN_VM" ]; then
    echo Using BUILD_ROOT=$BUILD_ROOT
    test -n "$BUILD_RPMS" && echo Using BUILD_RPMS=$BUILD_RPMS
    echo Using BUILD_ARCH=$BUILD_ARCH
    test -n "$VM_TYPE" && echo "Doing $VM_TYPE build${VM_IMAGE:+ in $VM_IMAGE}"
    echo
fi

test "$BUILD_ARCH" = all && BUILD_ARCH=
BUILD_USER_ABUILD_USED=

for SPECFILE in "${SPECFILES[@]}" ; do

    SRCDIR="${SPECFILE%/*}"
    SPECFILE="${SPECFILE##*/}"

    BUILDTYPE=
    case $SPECFILE in
      *.spec|*.src.rpm) BUILDTYPE=spec ;;
      *.dsc) BUILDTYPE=dsc ;;
      *.kiwi) BUILDTYPE=kiwi ;;
      PKGBUILD) BUILDTYPE=arch ;;
      _preinstallimage) BUILDTYPE=preinstallimage ;;
    esac
    if test -z "$BUILDTYPE" ; then
       echo "don't know how to build $SPECFILE"
       cleanup_and_exit 1
    fi

    cd "$SRCDIR"

    if [ -z "$RUNNING_IN_VM" ]; then
	echo
	echo "$HOST started \"build $SPECFILE\" at `date --utc`."
	echo
	test -n "$REASON" && echo "$REASON"
	echo
        TIME_START_TIME=`date +%s` # for statistics
    fi

    #
    # first setup building directory...
    #
    test -s "$SPECFILE" || {
       echo "$SPECFILE" is empty.  This should not happen...
       cleanup_and_exit 1
    }

    if test "$SPECFILE" != "${SPECFILE%.src.rpm}" ; then
	echo processing src rpm $SRCDIR/$SPECFILE ...
	MYSRCDIR=$BUILD_ROOT/.build-srcdir
	rm -rf "$MYSRCDIR"
	mkdir -p "$MYSRCDIR"
	cd $MYSRCDIR || cleanup_and_exit 1
	$BUILD_DIR/unrpm -q $SRCDIR/$SPECFILE || {
	    echo "could not install $SPECFILE."
	    cleanup_and_exit 1
	}
	for SPECFILE in *.spec ; do : ; done
    else
	MYSRCDIR="$SRCDIR"
    fi

    # FIX to work with baselibs_$PROJ etc
    if test "$BUILDTYPE" == "dsc" -a -e ${SRCDIR}/baselibs-deb.conf ; then
	# Set CREATE_BASELIBS if not set
	echo "dsc build and baselibs-deb.conf present: forcing --baselibs to true"
	CREATE_BASELIBS=true
    fi

# Currently local osc build does not allow extra .deb packages to be
# specified on the command line. Both init_buildsystem and expanddeps
# need to handle .deb dependencies first
#    if test -n "$CREATE_BASELIBS" ; then
#        case $BUILDTYPE in
#            spec) ;;
#            dsc) BUILD_EXTRA_PACKS="$BUILD_EXTRA_PACKS libparse-debcontrol-perl" ;;
#        esac
#    fi

    echo processing specfile $MYSRCDIR/$SPECFILE ...

    ADDITIONAL_PACKS=""
    test -z "$BUILD_EXTRA_PACKS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS $BUILD_EXTRA_PACKS"
    test -z "$CREATE_BASELIBS" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS build"
    test "$ccache" = '0' || ADDITIONAL_PACKS="$ADDITIONAL_PACKS ccache"
    test "$icecream" = 0 || ADDITIONAL_PACKS="$ADDITIONAL_PACKS icecream gcc-c++"
    test -z "$DO_LINT" || ADDITIONAL_PACKS="$ADDITIONAL_PACKS rpmlint-Factory"
    test "$VMDISK_FILESYSTEM" = 'xfs' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS libblkid1"
    test "$VM_TYPE" = 'zvm' && ADDITIONAL_PACKS="$ADDITIONAL_PACKS udev libcap2"

    if test -n "$CHANGELOG" -a -z "$RUNNING_IN_VM" ; then
	rm -f $BUILD_ROOT/.build-changelog
	case $SPECFILE in
	  *.dsc) CFFORMAT=debian ;;
	  *) CFFORMAT=rpm ;;
	esac
	echo "running changelog2spec --target $CFFORMAT --file $MYSRCDIR/$SPECFILE"
	if ! $BUILD_DIR/changelog2spec --target $CFFORMAT --file "$MYSRCDIR/$SPECFILE" > $BUILD_ROOT/.build-changelog ; then
	    rm -f $BUILD_ROOT/.build-changelog
	fi
    fi

    if test -n "$VM_TYPE" -a -z "$RUNNING_IN_VM"; then
	rm -rf "$BUILD_ROOT/.build"
	mkdir -p "$BUILD_ROOT/.build"
	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 $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS
	    echo "$* ..."
            start_time=`date +%s`
	    "$@" || cleanup_and_exit 1
	    check_exit
            TIME_PREINSTALL=$(( `date +%s` - $start_time ))
            unset start_time
	    if [ ! -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 xen, 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
	Q="'\''"
	echo "SPECFILE='${SPECFILE//"'"/$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
	# FIXME: this depends on the kernel and vm.
	# could be hda2, sda2 for xen or hdb/sdb for qemu
	test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV:-/dev/hda2}'" >> $BUILD_ROOT/.build/build.data
	test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS}'" >> $BUILD_ROOT/.build/build.data
	PERSONALITY=0
	if test "$VM_TYPE" != 'lxc'; then
	    test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'`
	fi
	if test "$(uname -m)" = 'ppc'; then
            # ppc kernel never tells us if a 32bit personality is active
            PERSONALITY=8
        fi
	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 "shell='$shell'" >> $BUILD_ROOT/.build/build.data
	echo "statistics='$statistics'" >> $BUILD_ROOT/.build/build.data
        # fallback time for broken hosts
        date '+@%s' > $BUILD_ROOT/.build/.date
	if [ "$VM_TYPE" = 'emulator' ]; then
            ln -sf /.build/build $BUILD_ROOT/sbin/init
        fi
        if [ "$VM_TYPE" = 'zvm' ]; then
            # initrd is created in obsstoragesetup.
            # If it is desired to use a project dependent kernel, use make_guestinitrd from zvm_functions.
            # have to copy kernel/initrd and run zipl to be able to IPL
            # have to set init_script before unmounting, thus doing it statically for now.
            zvm_init_script="/.build/build"
            mkdir -p $BUILD_ROOT/boot
            cp $vm_kernel $vm_initrd $BUILD_ROOT/boot
            mkdir -p $BUILD_ROOT/boot/zipl
             # finally, install bootloader to the worker disk
             zipl -t $BUILD_ROOT/boot/zipl -i ${BUILD_ROOT}${vm_kernel} -r ${BUILD_ROOT}${vm_initrd} \
                --parameters "${zvm_param} init=$zvm_init_script rootfsopts=noatime"
        fi
	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/mnt 2> /dev/null || true

	if [ -n "$VM_IMAGE" ]; then
	    check_exit
	    # needs to work otherwise we have a corrupted file system
	    umount $BUILD_ROOT || cleanup_and_exit 1
	    if [ "$VM_TYPE" = "zvm" ]; then
		# detach the worker root and swap locally and link it in the worker
		zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
		zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
		zvm_cp volume_attach $VM_WORKER $VM_VOLUME_ROOT
		zvm_cp volume_attach $VM_WORKER $VM_VOLUME_SWAP
	    fi
	fi

	if check_use_emulator; then
	    if [ -x "$BUILD_DIR/initvm" -a -e "$BUILD_DIR/qemu-reg" ]; then
		vm_init_script="/.build/initvm"
	    elif [ -e $BUILD_DIR/initscript_qemu_vm ]; then
		vm_init_script="/.build/initscript_qemu_vm"
	    else
		echo "Warning: can't find initscript to register binfmts"
	    fi
	else
	    vm_init_script="/.build/build"
	fi

	if [ "$VM_TYPE" = 'emulator' ]; then
                # generic emulator hook. an external script is needed to define
                # the emulator startup
                sync
                pushd $BUILD_DIR/emulator
                if [ -z "$EMULATOR_SCRIPT" ]; then
                   EMULATOR_SCRIPT="./emulator.sh"
                elif [ "${EMULATOR_SCRIPT:0:1}" != "/" ]; then
                   EMULATOR_SCRIPT="./$EMULATOR_SCRIPT"
                fi
		set -- "$EMULATOR_SCRIPT" "$VM_IMAGE"
		echo "$@"
		if ! "$@"; then
                     popd
                     echo "ERROR: The emulator return with an failure"
                     cleanup_and_exit 3
                fi
                popd

	elif [ "$VM_TYPE" = 'xen' ]; then
		XMROOT="file:$(readlink -f $VM_IMAGE)"
		XMROOT=${XMROOT/#file:\/dev/phy:/dev}
		XMROOT="disk=$XMROOT,hda1,w"
		XMSWAP=
		if test -n "$VM_SWAP" ; then
		    XMSWAP="file:$(readlink -f $VM_SWAP)"
		    XMSWAP=${XMSWAP/#file:\/dev/phy:/dev}
		    XMSWAP="disk=$XMSWAP,hda2,w"
		fi
		XENID="${VM_IMAGE%/root}"
		XENID="${XENID%/tmpfs}"
		XENID="${XENID##*/}"
	        XENID="${XENID#root_}"

		echo "booting XEN kernel ..."
		if xm list "build_$XENID" >/dev/null 2>&1 ; then
		   echo "Instance already exist, something really went wrong..."
		   echo "Please report to your server admin, there might be multiple services running for same domain"
		   cleanup_and_exit 3
		fi
		XEN_CONF_FILE=`mktemp /var/tmp/build.xen.conf-XXXXXXXXX` || cleanup_and_exit 3
		echo "kernel = \"$vm_kernel\""                                           >  $XEN_CONF_FILE
		echo "ramdisk = \"$vm_initrd\""                                          >> $XEN_CONF_FILE
		echo "memory = ${MEMSIZE:-64}"                                           >> $XEN_CONF_FILE
		echo "vcpus = $BUILD_JOBS"                                               >> $XEN_CONF_FILE
		echo "root = \"/dev/hda1 ro\""                                           >> $XEN_CONF_FILE
		echo "extra = \"init=/bin/bash console=ttyS0 panic=1 udev_timeout=360\"" >> $XEN_CONF_FILE
		echo "on_poweroff = 'destroy'"                                           >> $XEN_CONF_FILE
		echo "on_reboot = 'destroy'"                                             >> $XEN_CONF_FILE
		echo "on_crash = 'destroy'"                                              >> $XEN_CONF_FILE
		set -- xm create -c $XEN_CONF_FILE name="build_$XENID" $XMROOT $XMSWAP extra="quiet init="$vm_init_script" elevator=noop panic=1 console=ttyS0"
		if test "$PERSONALITY" != 0 ; then
		    # have to switch back to PER_LINUX to make xm work
		    set -- linux64 "$@"
		fi
		echo "$@"
		"$@" || cleanup_and_exit 3
		rm "$XEN_CONF_FILE"
	elif [ "$VM_TYPE" = 'uml' ]; then
		echo "booting UML kernel ..."
		set -- $uml_kernel initrd=$uml_initrd root=/ubda init="$vm_init_script" panic=1 elevator=noop quiet ubd0=$VM_IMAGE ${MEMSIZE:+mem=$MEMSIZE}
		echo "$@"
		"$@"
	elif [ "$VM_TYPE" = 'qemu' -o "$VM_TYPE" = 'kvm' ]; then
		echo "booting $VM_TYPE ..."
                if [ "$VM_TYPE" = 'kvm' -a -b "$VM_IMAGE" ]; then
                  # speed optimization when using kvm with raw devices
		  CACHE=",cache=none"
                else
                  # speed optimization when using kvm with raw files
		  CACHE=",cache=unsafe"
                fi

		if [ "$kvm_virtio" = 1 ]; then
		    qemu_args=(-drive file="$VM_IMAGE",if=virtio$CACHE -drive file="$VM_IMAGE",if=ide,index=0$CACHE)
		    if [ -n "$VM_SWAP" ]; then
			qemu_args=("${qemu_args[@]}" "-drive")
			qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=virtio$CACHE")
		    fi
		    if [ "$HOST_ARCH" = "armv7l" ]; then
			qemu_args=(-drive file="$VM_IMAGE",if=none,id=disk$CACHE -device virtio-blk,transport=virtio-mmio.0,drive=disk)
			qemu_args=("${qemu_args[@]}" "-drive")
			qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=none,id=swap$CACHE")
			qemu_args=("${qemu_args[@]}" "-device")
			qemu_args=("${qemu_args[@]}" "virtio-blk,transport=virtio-mmio.1,drive=swap")
		    fi
		else
			if [ "$HOST_ARCH" = "ppc970" ];then
				qemu_args=( "-drive" )
				qemu_args=("${qemu_args[@]}" "file=$VM_IMAGE,if=scsi,cache=unsafe")
			else
				qemu_args=(-hda "$VM_IMAGE")
			fi
			if [ -n "$VM_SWAP" ]; then
				qemu_args=("${qemu_args[@]}" "-drive")
				if [ "$HOST_ARCH" = "ppc970" ];then
					DISK_IF=scsi
				else
					DISK_IF=ide
				fi
				qemu_args=("${qemu_args[@]}" "file=$VM_SWAP,if=$DISK_IF,index=1$CACHE")
			fi
		fi
		if [ -n "$BUILD_JOBS" -a "$icecream" = 0 -a "$HOST_ARCH" != "armv7l" ]; then
		    qemu_args=("${qemu_args[@]}" "-smp" "$BUILD_JOBS")
		fi
		if [ "$VM_TYPE" = 'kvm' -a "$HOST_ARCH" != "armv7l" ]; then
			KVM_OPTIONS="$KVM_OPTIONS -cpu host"
		        if [ -n "$HUGETLBFSPATH" ]; then
			      KVM_OPTIONS="$KVM_OPTIONS -mem-path $HUGETLBFSPATH"
		        fi
		fi

		set -- $qemu_bin -no-reboot -nographic -net none $KVM_OPTIONS \
		    -kernel $vm_kernel \
		    -initrd $vm_initrd \
		    -append "root=$qemu_rootdev panic=1 quiet no-kvmclock nmi_watchdog=0 rw elevator=noop console=$console init=$vm_init_script" \
		    ${MEMSIZE:+-m $MEMSIZE} \
		    "${qemu_args[@]}"

		if test "$PERSONALITY" != 0 ; then
		    # have to switch back to PER_LINUX to make qemu work
		    set -- linux64 "$@"
		fi
		echo "$@"
		"$@"
	elif [ "$VM_TYPE" = 'lxc' ]; then
		echo "booting $VM_TYPE ..."
		LXCCONF="$BUILD_ROOT/.build.lxc.conf"
		rm -f "$LXCCONF"
		cat $BUILD_DIR/lxc.conf > "$LXCCONF"
		cat >> "$LXCCONF" <<-EOF
		lxc.rootfs = $BUILD_ROOT
		EOF
		# XXX: do this always instead of leaking the hosts' one?
		echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
		LXCID=${BUILD_ROOT##*/}
		lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true
		lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1
		lxc-start -n "$LXCID" "$vm_init_script"
		BUILDSTATUS="$?"
		test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
		cleanup_and_exit "$BUILDSTATUS"
        elif [ "$VM_TYPE" = 'zvm' ]; then
                echo "booting $VM_TYPE ..."
                zvm_cp ipl $VM_WORKER $VM_VOLUME_ROOT
                # start IUCV Console
                # IPL needs some time until IPL really starts...
                 sleep 2
                 # start iucv console. This blocks until build process is finished.
                iucvconn $VM_WORKER lnxhvc0
                # Take root and swap devices from worker
                # This might be critical regarding timing (IUCV_CONSOLE down, but machine still running)
                sleep 5
                zvm_cp volume_detach $VM_WORKER $VM_VOLUME_ROOT
                zvm_cp volume_detach $VM_WORKER $VM_VOLUME_SWAP
                VM_IMAGE="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_ROOT $zvm_mult_pass $zvm_worker_nr)"
                VM_SWAP="/dev/$(zvm_cp volume_link_local $VM_WORKER $VM_VOLUME_SWAP $zvm_mult_pass $zvm_worker_nr)"
	fi

        # Exctract build resutls from VM
	if [ "$VM_TYPE" = 'emulator' ]; then
            # Emulators may not offer to use a second swap space.
            # So we just mount the filesystem.
            # WARNING: This is not safe against attacks.

	    mkdir -p $BUILD_ROOT/.build.packages
	    cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
            mkdir -p .mount
            mount $VM_IMAGE -o loop .mount
            if [ -e .mount/.build.packages ]; then
              cp -a .mount/.build.packages/* .
            fi
            exitcode=`cat .mount/.build/_exitcode`
            umount .mount
            rmdir .mount

	    cleanup_and_exit "$exitcode"

	elif test -n "$VM_SWAP" ; then
	    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
		# create same layout as with plain chroot
		if test "$BUILDTYPE" = spec ; then
		    mkdir -p SRPMS
		    for i in *src.rpm *.desktopfiles ; do
			test -e "$i" || continue
			mv "$i" SRPMS/
		    done
		    for i in *.rpm ; do
			test -e "$i" || continue
			arch=${i%.rpm}
			arch=${i%.delta}
			arch=${arch##*\.}
			mkdir -p RPMS/$arch
			mv "$i" RPMS/$arch/
		    done
		elif test "$BUILDTYPE" = dsc ; then
		    mkdir -p DEBS
		    find . -type f | while read i; do mv "$i" DEBS/; done
		elif test "$BUILDTYPE" = arch ; then
		    mkdir -p ARCHPKGS
		    find . -type f | while read i; do mv "$i" ARCHPKGS/; done
		elif test "$BUILDTYPE" = kiwi ; then
		    mkdir -p KIWI
		    find . -type f | while read i; do mv "$i" KIWI/; done
		fi
		for i in * ; do
		    test -f "$i" || continue
		    case $i in
			_*|.*) ;;
			*) mkdir -p OTHER ; mv $i OTHER/ ;;
		    esac
		done
                if test "$statistics" = 1; then
                    mkdir -p OTHER
                    mv _statistics OTHER/
                    [ -n "$TIME_PREINSTALL" ] && echo "TIME_preinstall: $TIME_PREINSTALL"  >> OTHER/_statistics
                    TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME ))
                    echo "TIME_total: $TIME_TOTAL"  >> OTHER/_statistics
                fi
		if [ "$VM_TYPE" = 'zvm' ]; then
		    # free worker devices
		    zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
		    zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
		fi
		cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
		;;
	      BUILDSTATUS*)
		if [ "$VM_TYPE" = 'zvm' ]; then
		    # free worker devices
		    zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
		    zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
		fi
		cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
		;;
	      *)
		if [ "$VM_TYPE" = 'zvm' ]; then
		    # free worker devices
		    zvm_cp volume_detach_local $VM_VOLUME_ROOT ${zvm_worker_nr}
		    zvm_cp volume_detach_local $VM_VOLUME_SWAP ${zvm_worker_nr}
		fi
		echo "No buildstatus set, either the base system is broken (glibc/bash/perl)"
		echo "or the build host has a kernel or hardware problem..."
		cleanup_and_exit 3
		;;
	    esac

	    cleanup_and_exit 1
	fi

	cleanup_and_exit 0
    fi

    if test "$DO_INIT" = true ; then
        start_time=`date +%s`
	#
	# create legacy .buildenv file
	#
	test -z "$INCARNATION" && INCARNATION=0
	echo "BUILD_INCARNATION=$INCARNATION" > $BUILD_ROOT/.buildenv
	CREATE_BUILD_BINARIES=
	test "$BUILDTYPE" = preinstallimage && mkdir -p $BUILD_ROOT/.preinstall_image
	egrep '^#[       ]*needsbinariesforbuild[       ]*$' >/dev/null <$MYSRCDIR/$SPECFILE && CREATE_BUILD_BINARIES=--create-build-binaries
	set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USE_SYSTEM_QEMU $KEEP_PACKS $USEUSEDFORBUILD $CREATE_BUILD_BINARIES $RPMLIST "$MYSRCDIR/$SPECFILE" $ADDITIONAL_PACKS
	echo "$* ..."
        start_time=`date +%s`
	"$@" || cleanup_and_exit 1
	check_exit
        TIME_INSTALL=$(( `date +%s` - $start_time ))
        unset start_time
	# arbitrary limit of 10MB
	if test $((`stat -f -c "%a*%S/1024/1024" $BUILD_ROOT`)) -lt 10; then
            # ensure that old stat is not failing (RHEL4)
            if df $BUILD_ROOT 2>/dev/null | grep -q "100%"; then
		df -h $BUILD_ROOT
		echo "build does not work on a completely full filesystem"
		cleanup_and_exit 1
	    fi
	fi
	mount -n -tproc none $BUILD_ROOT/proc || true
	mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts

	copy_oldpackages
    fi

    if test "$BUILDTYPE" = preinstallimage ; then
	echo "creating preinstall image..."
	test -d "$BUILD_ROOT/.preinstall_image" || cleanup_and_exit 1
	cd $BUILD_ROOT || cleanup_and_exit 1
	TAR="tar"
	if test -x /usr/bin/bsdtar; then
	    TAR="/usr/bin/bsdtar --chroot"
	fi
	TOPDIRS=
	for DIR  in .* * ; do
	  case "$DIR" in
	    .|..) continue ;;
	    .build*) continue ;;
	    .preinstallimage*) continue ;;
	    .srcfiles*) continue ;;
	    .pkgs) continue ;;
	    .rpm-cache) continue ;;
	    installed-pkg) continue ;;
	    proc|sys) continue ;;
	  esac
	  TOPDIRS="$TOPDIRS $DIR"
        done
	if ! $TAR -czf .preinstallimage.$$.tar.gz --one-file-system $TOPDIRS ; then
	    cleanup_and_exit 1
	fi
	echo "image created."
	TOPDIR=/usr/src/packages
	mkdir -p $BUILD_ROOT$TOPDIR/OTHER
	rm -f $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
	for PKG in $BUILD_ROOT/.preinstall_image/* ; do
	    PKG=${PKG##*/}
	    read PKG_HDRMD5 PKGID < $BUILD_ROOT/.preinstall_image/$PKG
	    test -n "$PKG_HDRMD5" || cleanup_and_exit 1
	    echo "$PKG_HDRMD5  $PKG" >> $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
	done
	mv $BUILD_ROOT/.preinstallimage.$$.tar.gz $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.tar.gz
	rm -f $BUILD_ROOT/.build.packages
	ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
	test -d "$SRCDIR" && cd "$SRCDIR"
	continue
    fi

    if test -z "$BUILD_DIST" -a -e "$BUILD_ROOT/.guessed_dist" ; then
	read BUILD_DIST < $BUILD_ROOT/.guessed_dist
    fi

    #
    # fix rpmrc if we are compiling for i686
    #
    test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
    if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
	mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
	sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
    fi
    if test "$DO_BUILD" = false ; then
        cleanup_and_exit 0
    fi

    #
    # install dummy sign program if needed
    #
    test -f $BUILD_ROOT/usr/bin/sign_installed && mv $BUILD_ROOT/usr/bin/sign_installed $BUILD_ROOT/usr/bin/sign
    if test -n "$SIGNDUMMY" ; then
	test -f $BUILD_ROOT/usr/bin/sign && mv $BUILD_ROOT/usr/bin/sign $BUILD_ROOT/usr/bin/sign_installed
	cp $BUILD_DIR/signdummy $BUILD_ROOT/usr/bin/sign
	chmod 755 $BUILD_ROOT/usr/bin/sign
    fi

    #
    # check if we want to build with the abuild user
    #
    BUILD_USER=abuild
    if test -x $BUILD_ROOT/bin/rpm ; then
	SUSE_VERSION=`chroot $BUILD_ROOT /bin/rpm --eval '%{?suse_version}' 2>/dev/null`
	if test -n "$SUSE_VERSION" && test "$SUSE_VERSION" -le 1020 ; then
	    BUILD_USER=root
	fi
    fi
    if test "$BUILD_USER" = abuild ; then
	egrep '^#[       ]*needsrootforbuild[       ]*$' >/dev/null <$SPECFILE && BUILD_USER=root
    else
	egrep '^#[       ]*norootforbuild[       ]*$' >/dev/null <$SPECFILE && BUILD_USER=abuild
    fi
    test -n "$NOROOTFORBUILD" && BUILD_USER=abuild

    # appliance builds must run as root
    if test "$BUILDTYPE" = kiwi; then
      imagetype=$(perl -I$BUILD_DIR -MBuild::Kiwi -e Build::Kiwi::show $SPECFILE imagetype)
      test "$imagetype" = 'product' || BUILD_USER=root
    fi

    if test $BUILD_USER = abuild ; then
	if ! egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then
	    echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/etc/passwd
	    echo 'abuild:*:::::::' >>$BUILD_ROOT/etc/shadow # This is needed on Mandriva 2009
	    echo 'abuild:*::' >>$BUILD_ROOT/etc/gshadow # This is needed on Ubuntu
	    echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/etc/group
	    mkdir -p $BUILD_ROOT/home/abuild
	    chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/home/abuild
	else
	    if ! egrep "^abuild:x?:${ABUILD_UID}:${ABUILD_GID}" >/dev/null <$BUILD_ROOT/etc/passwd ; then
                sed -i '/^abuild:/d' $BUILD_ROOT/etc/passwd
                sed -i '/^abuild:/d' $BUILD_ROOT/etc/group
                echo "abuild:x:${ABUILD_UID}:${ABUILD_GID}:Autobuild:/home/abuild:/bin/bash" >>$BUILD_ROOT/etc/passwd
                echo "abuild:x:${ABUILD_GID}:" >>$BUILD_ROOT/etc/group
                chown "$ABUILD_UID:$ABUILD_GID" $BUILD_ROOT/home/abuild -R
	    fi
	fi
	if test -f $BUILD_ROOT/etc/shadow ; then
	    sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/shadow > $BUILD_ROOT/etc/shadow.t && mv $BUILD_ROOT/etc/shadow.t $BUILD_ROOT/etc/shadow
	fi
	if test -f $BUILD_ROOT/etc/gshadow ; then
	    sed -e "s@^root::@root:*:@" < $BUILD_ROOT/etc/gshadow > $BUILD_ROOT/etc/gshadow.t && mv $BUILD_ROOT/etc/gshadow.t $BUILD_ROOT/etc/gshadow
	fi
	BUILD_USER_ABUILD_USED=true
    else
	# building as root
	ABUILD_UID=0
	ABUILD_GID=0
	if egrep '^abuild:' >/dev/null <$BUILD_ROOT/etc/passwd ; then
	    rm -rf "$BUILD_ROOT/home/abuild"
	    egrep -v '^abuild:' <$BUILD_ROOT/etc/passwd >$BUILD_ROOT/etc/passwd.new
	    mv $BUILD_ROOT/etc/passwd.new $BUILD_ROOT/etc/passwd
	    egrep -v '^abuild:' <$BUILD_ROOT/etc/group >$BUILD_ROOT/etc/group.new
	    mv $BUILD_ROOT/etc/group.new $BUILD_ROOT/etc/group
	    if test -f $BUILD_ROOT/etc/shadow ; then
	      egrep -v '^abuild:' <$BUILD_ROOT/etc/shadow >$BUILD_ROOT/etc/shadow.new
	      mv $BUILD_ROOT/etc/shadow.new $BUILD_ROOT/etc/shadow
	    fi
	    if test -f $BUILD_ROOT/etc/gshadow ; then
	      egrep -v '^abuild:' <$BUILD_ROOT/etc/gshadow >$BUILD_ROOT/etc/gshadow.new
	      mv $BUILD_ROOT/etc/gshadow.new $BUILD_ROOT/etc/gshadow
	    fi
	fi
    fi

    if test "$BUILDTYPE" = spec ; then
	TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
	if test -z "$TOPDIR"; then
	    echo "Error: TOPDIR empty"
	    cleanup_and_exit 1
	fi
    else
	TOPDIR=/usr/src/packages
	mkdir -p $BUILD_ROOT$TOPDIR
    fi

    rm -f $BUILD_ROOT/.build.packages
    ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages

    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
    mount -n -tdevpts -omode=0620,gid=5 none $BUILD_ROOT/dev/pts 2> /dev/null

    setupicecream

    setupccache

    # nasty hack to prevent rpath on known paths
    # FIXME: do this only for suse
    if test -d "$BUILD_ROOT/etc/profile.d" ; then
	echo "export SUSE_IGNORED_RPATHS=/etc/ld.so.conf" > "$BUILD_ROOT/etc/profile.d/buildsystem.sh"
    fi

    #
    # now clean up RPM building directories
    if [ "$NO_TOPDIR_CLEANUP" = false ]; then
        rm -rf "$BUILD_ROOT$TOPDIR"
        for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do
            mkdir -p $BUILD_ROOT$TOPDIR/$i
        done
    fi

    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
    check_exit

    mkdir -p $BUILD_ROOT$TOPDIR/SOURCES
    if test "$BUILDTYPE" = kiwi ; then
	mkdir -p $BUILD_ROOT$TOPDIR/KIWI
	if test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
	    mv "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
	else
	    if test -z "$LINKSOURCES" ; then
		cp -dLR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
	    else
		cp -lR "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
	    fi
	    if test "$?" != 0 ; then
		echo "source copy failed"
		cleanup_and_exit 1
	    fi
	fi
    else
	cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
    fi
    # strip prefix from autogenerated files of source services.
    for i in $BUILD_ROOT$TOPDIR/SOURCES/_service\:*; do
      mv "$i" "${i%/*}/${i##*:}"
    done
    SPECFILE="${SPECFILE##*:}"

    test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir && rm -rf "$MYSRCDIR"
    CHANGELOGARGS=
    test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"

    if test "$BUILDTYPE" = spec ; then
	# do buildrequires/release substitution
	args=()
	if test -n "$RELEASE"; then
		args=(--release "$RELEASE")
	fi
	substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1
	# extract macros from configuration
	getmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/.rpmmacros
	if test -n "$BUILD_DEBUG" ; then
	    echo '
%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep
%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package
%_build_insert_debug_package \
%global __debug_package 1 \
%undefine _enable_debug_packages \
%debug_package

' >> $BUILD_ROOT/root/.rpmmacros
	fi

	if [ -n "$BUILD_JOBS" ]; then
		cat >> $BUILD_ROOT/root/.rpmmacros <<-EOF
		%jobs $BUILD_JOBS
		%_smp_mflags -j$BUILD_JOBS
		EOF
	fi
	test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmmacros $BUILD_ROOT/home/abuild/.rpmmacros
	# extract optflags from configuration
	getoptflags --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" ${BUILD_DEBUG:+--debug} > $BUILD_ROOT/root/.rpmrc
	test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc
	if test -z "$ABUILD_TARGET"; then
	    ABUILD_TARGET=$(getchangetarget --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
	    test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
	fi
    fi
    if test -f $BUILD_ROOT/.spec.new ; then
	if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT/.spec.new ; then
	    echo -----------------------------------------------------------------
	    echo "I have the following modifications for $SPECFILE:"
	    sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE > $BUILD_ROOT/.spec.t1
	    sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
	    diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE
	else
	    rm -f $BUILD_ROOT/.spec.new
	fi
    fi

    if test "$BUILDTYPE" = dsc ; then
	rm -rf "$BUILD_ROOT$TOPDIR/BUILD"
	mkdir -p $BUILD_ROOT$TOPDIR/SOURCES.DEB
	chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
	DEB_TRANSFORM=
	DEB_SOURCEDIR=$TOPDIR/SOURCES
	DEB_DSCFILE=$SPECFILE
	for f in $BUILD_ROOT$TOPDIR/SOURCES/debian.* ; do
	    test -f $f && DEB_TRANSFORM=true
	done
	if test -n "$DEB_TRANSFORM" ; then
	    echo "running debian transformer..."
	    if ! debtransform $CHANGELOGARGS $BUILD_ROOT$TOPDIR/SOURCES $BUILD_ROOT$TOPDIR/SOURCES/$SPECFILE $BUILD_ROOT$TOPDIR/SOURCES.DEB ; then
		echo "debian transforming failed."
		cleanup_and_exit 1
	    fi
	    DEB_SOURCEDIR=$TOPDIR/SOURCES.DEB
	    for DEB_DSCFILE in $BUILD_ROOT/$DEB_SOURCEDIR/*.dsc ; do : ; done
	    DEB_DSCFILE="${DEB_DSCFILE##*/}"
	fi
	chroot $BUILD_ROOT su -c "dpkg-source -x $DEB_SOURCEDIR/$DEB_DSCFILE $TOPDIR/BUILD" - $BUILD_USER
    fi

    if test "$BUILDTYPE" = arch ; then
	echo "Preparing sources..."
	chroot $BUILD_ROOT su -c "cd $TOPDIR/SOURCES && makepkg -s -o 2>&1 >/dev/null" - $BUILD_USER
	mv $BUILD_ROOT/$TOPDIR/SOURCES/* -t $BUILD_ROOT/$TOPDIR/BUILD
    fi

    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
    cd $BUILD_ROOT$TOPDIR/SOURCES || cleanup_and_exit 1

    echo -----------------------------------------------------------------
    if test "$BUILD_USER" = root ; then
	echo ----- building $SPECFILE
    else
	echo ----- building $SPECFILE "(user $BUILD_USER)"
    fi
    echo -----------------------------------------------------------------
    echo -----------------------------------------------------------------
    if [ -n "$RUNNING_IN_VM" ]; then
	if [ -x /sbin/ip ]; then
	    ip addr add 127.0.0.1/8 dev lo
	    ip link set lo up
	else
	    ifconfig lo 127.0.0.1 up
	fi
	if [ -n "$MYHOSTNAME" ]; then
	    hostname "$MYHOSTNAME"
	fi
    fi

    BUILD_SUCCEEDED=false

    if test -n "$OVERLAY" ; then
	if test -d "$OVERLAY"; then
	    pushd $OVERLAY
	    echo "Copying overlay to BUILD_ROOT"
	    tar -cpf - . | (cd $BUILD_ROOT ; tar -xvf -)
	    popd
	else
	    echo "OVERLAY ($OVERLAY) is no directory - skipping"
	fi
    fi

    if test -n "$RSYNCSRC" ; then
	if test -n "$RSYNCDEST"; then
	    if test -d "$RSYNCSRC"; then
		if ! test -d "$BUILD_ROOT/$RSYNCDEST"; then
		    echo "ATTENTION! Creating target directory ($BUILD_ROOT/$RSYNCDEST) as its not there."
		    mkdir -p $BUILD_ROOT/$RSYNCDEST
		fi
		echo "Running rsync ..."
		rsync -av $RSYNCSRC/* $BUILD_ROOT/$RSYNCDEST/
		chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT/$RSYNCDEST"
		RSYNCDONE=true
		echo "... done"
	    else
		echo "RSYNCSRC is no directory - skipping"
	    fi
	else
	    echo "RSYNCSRC given, but not RSYNCDEST - skipping"
	fi
    fi

    start_time=`date +%s`
    if test "$BUILDTYPE" = spec ; then
	test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba

	rpmbuild=rpmbuild
	test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm

	# XXX: move _srcdefattr to macro file?
	rpmbopts=("--define" "_srcdefattr (-,root,root)")
	if test "$rpmbuild" == "rpmbuild" ; then
                # use only --nosignature for rpm v4
	    rpmbopts[${#rpmbopts[@]}]="--nosignature"
	fi
	if test -n "$ABUILD_TARGET" ; then
	    rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
	fi
	if test -n "$BUILD_DEBUG" ; then
	    rpmbopts[${#rpmbopts[@]}]='--define'
	    rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
	fi
	if test -n "$DISTURL" ; then
	    rpmbopts[${#rpmbopts[@]}]='--define'
	    rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
	fi
	if test -n "$RSYNCDONE" ; then
	    rpmbopts[${#rpmbopts[@]}]='--define'
	    rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
	fi

	# su involves a shell which would require even more
	# complicated quoting to bypass than this
        if test "$SHORT_CIRCUIT" = false ; then
            rpmbopts[${#rpmbopts[@]}]="$BUILD_RPM_BUILD_STAGE"
            toshellscript $rpmbuild \
                    "${definesnstuff[@]}" \
                    "${rpmbopts[@]}" \
                    "$TOPDIR/SOURCES/$SPECFILE" \
                    > $BUILD_ROOT/.build.command
        else
            rpmbopts[${#rpmbopts[@]}]='--short-circuit'
            buildopts="-bc -bi -bb -bs"
            cmds=""
            echo "#!/bin/sh -x" >$BUILD_ROOT/.build.command
            echo "set -e" >>$BUILD_ROOT/.build.command
            for opt in $buildopts
            do
                shellquote $rpmbuild  \
                        "${definesnstuff[@]}" \
                        "${rpmbopts[@]}" $opt \
                        "$TOPDIR/SOURCES/$SPECFILE" \
                        >> $BUILD_ROOT/.build.command
                echo >>$BUILD_ROOT/.build.command
                [ "$opt" == "$BUILD_RPM_BUILD_STAGE" ] && break
            done
        fi

	chmod 755 $BUILD_ROOT/.build.command
	check_exit
	if test -n "$shell"; then
	    chroot $BUILD_ROOT su -
	else
	    chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
	fi
    fi

    if test "$BUILDTYPE" = dsc ; then
	# Checks to see if a build script should be used
	# this allows the build environment to be manipulated
	# and alternate build commands can be used
# Debian policy requires to build with single CPU by default
#	if [ -n "$BUILD_JOBS" ]; then
#	    DSC_BUILD_JOBS="-j$BUILD_JOBS"
#	fi
	DSC_BUILD_CMD="dpkg-buildpackage -us -uc -rfakeroot-tcp $DSC_BUILD_JOBS"
	if test -e $BUILD_ROOT/$TOPDIR/SOURCES/build.script ; then
	    echo "Sourcing build.script to build - it should normally run 'dpkg-buildpackage -us -uc -rfakeroot-tcp'"
	    DSC_BUILD_CMD="source $TOPDIR/SOURCES/build.script"
	    chmod +x $BUILD_ROOT/$TOPDIR/SOURCES/build.script
	fi

	if test -n "$shell"; then
	    chroot $BUILD_ROOT su -
	else
	    chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && $DSC_BUILD_CMD" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
	fi

	mkdir -p $BUILD_ROOT/$TOPDIR/DEBS
	for DEB in $BUILD_ROOT/$TOPDIR/*.deb ; do
	    test -e "$DEB" && mv "$DEB" "$BUILD_ROOT/$TOPDIR/DEBS"
	done
	# link sources over
	ln $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE $BUILD_ROOT/$TOPDIR/DEBS/
	while read f ; do
	    ln $BUILD_ROOT/$DEB_SOURCEDIR/$f $BUILD_ROOT/$TOPDIR/DEBS/
	done < <(sed -ne '/^Files:/,$s/^ ................................ [0-9][0-9]* //p' < $BUILD_ROOT/$DEB_SOURCEDIR/$DEB_DSCFILE)
    fi

    if test "$BUILDTYPE" = arch ; then
	chroot $BUILD_ROOT su -c "cd $TOPDIR/BUILD && makepkg -f" - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
	mkdir -p $BUILD_ROOT/$TOPDIR/ARCHPKGS
	for PKG in $BUILD_ROOT/$TOPDIR/BUILD/*.pkg.tar.?z ; do
	    test -e "$PKG" && mv "$PKG" "$BUILD_ROOT/$TOPDIR/ARCHPKGS"
	done
    fi

    if test "$BUILDTYPE" = kiwi ; then
	. $BUILD_DIR/build_kiwi.sh
	run_kiwi
    fi
    if test "$statistics" = 1; then
        mkdir -p $TOPDIR/OTHER
        echo "TIME_main_build: $(( `date +%s` - $start_time ))"  >> $TOPDIR/OTHER/_statistics
    fi
    unset start_time

    test "$BUILD_SUCCEEDED" = true || cleanup_and_exit 1
    test -d "$SRCDIR" && cd "$SRCDIR"
done

if test -n "$RUNNING_IN_VM" -a -n "$VM_SWAP"; then
    touch /.build/_statistics.exit
fi

RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true`
DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true`

if test -n "$RPMS" -a -n "$BUILD_USER_ABUILD_USED" ; then
    echo "... checking for files with abuild user/group"
    BADFILE=
    while read un gn fn ; do
	if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
	    echo "  $un $gn $fn"
	    BADFILE=true
	fi
    done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
    if test -n "$BADFILE" ; then
	echo "please fix your filelist (e.g. add defattr)"
	cleanup_and_exit 1
    fi
fi

if test -n "$RPMS" -a -d "$BUILD_ROOT/usr/lib/build/checks" ; then
    export PNAME=""
    export DO_RPM_REMOVE=true
    for SRPM in $BUILD_ROOT/$TOPDIR/SRPMS/*src.rpm ; do
	test -f "$SRPM" && PNAME=`rpm --nodigest --nosignature -qp --qf "%{NAME}" $SRPM`
    done
    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
    for CHECKSCRIPT in $BUILD_ROOT/usr/lib/build/checks/* ; do
	echo "... running `basename $CHECKSCRIPT`"
	$CHECKSCRIPT || cleanup_and_exit 1
    done
    umount -n $BUILD_ROOT/proc 2>/dev/null || true
fi

RPMS=`find $BUILD_ROOT/$TOPDIR/RPMS -type f -name "*.rpm" 2>/dev/null || true`
DEBS=`find $BUILD_ROOT/$TOPDIR/DEBS -type f -name "*.deb" 2>/dev/null || true`

if test -n "$RPMS" -a "$DO_CHECKS" != "false" -a -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then
    LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
	\( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
	-o -name "*-32bit-*" -o -name "*-64bit-*" \
	-o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
	-o -type f -name '*.rpm' -print))
    SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
    echo
    echo "RPMLINT report:"
    echo "==============="
    rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
    rm -f "$BUILD_ROOT$rpmlint_logfile"
    ret=0
    mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
    chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \
	    --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
	    ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > "$BUILD_ROOT$rpmlint_logfile" || ret=1
	    cat "$BUILD_ROOT$rpmlint_logfile"
	    echo
    umount -n $BUILD_ROOT/proc 2>/dev/null || true
    if test "$ret" = 1; then
	cleanup_and_exit 1
    fi
fi

if test \( -n "$RPMS" -o -n "$DEBS" \) -a -n "$CREATE_BASELIBS"; then
    create_baselibs
fi

exitcode=0
# post build scripts
# TODO: don't hardcode. instead run scripts in a directory as it's done for the checks
if test -n "$RPMS" \
	-a -d "$BUILD_ROOT/$TOPDIR/RPMS" \
	-a -d "$BUILD_ROOT/.build.oldpackages" \
	; then
    if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then
	echo "... comparing built packages with the former built"
	mount -n -tproc none $BUILD_ROOT/proc 2> /dev/null
	if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then
	    chroot $BUILD_ROOT touch /.build/.same_result_marker
	    # XXX: dirty build service hack. fix bs_worker. Search for
	    # 'same_result_marker' for traces of a first try to get rid of this
	    if test -n "$REASON" -a -n "$DISTURL"; then
		exitcode=2
	    fi
	fi
        umount -n $BUILD_ROOT/proc 2>/dev/null || true
    fi
    if test ! -e $BUILD_ROOT/.build/.same_result_marker \
	-a -x "$BUILD_ROOT/usr/bin/makedeltarpm" \
	-a -x $BUILD_ROOT/usr/lib/build/mkdrpms; then
	echo "... creating delta rpms"
	ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
	chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
    fi
fi

if test -n "$RUNNING_IN_VM"; then
    if test "$statistics" = 1; then
         echo "... saving built statistics"
         [ -n "$TIME_INSTALL" ] && echo "TIME_install: $TIME_INSTALL"  >> $BUILD_ROOT$TOPDIR/OTHER/_statistics
         if [ -e /.build/_statistics.df ]; then
           echo -n "MAX_mb_used_on_disk: " >> $TOPDIR/OTHER/_statistics
           cat /.build/_statistics.df >> $TOPDIR/OTHER/_statistics
           echo "" >> $TOPDIR/OTHER/_statistics
           rm /.build/_statistics.df
         fi
         if [ -e /.build/_statistics.memory ]; then
           echo -n "MAX_mb_used_memory: " >> $TOPDIR/OTHER/_statistics
           cat /.build/_statistics.memory >> $TOPDIR/OTHER/_statistics
           echo "" >> $TOPDIR/OTHER/_statistics
           rm /.build/_statistics.memory
         fi
         mount -n sys /sys -t sysfs
         device="sda"
         [ -e /dev/vda ] && device="vda"
         [ -e /dev/dasda ] && device="dasda" # in z/VM
         disk=(`cat /sys/block/${device}/stat`)
         [ "0${disk[0]}" -gt 0 ] && echo "IO_requests_read: ${disk[0]}"  >> $TOPDIR/OTHER/_statistics
         [ "0${disk[2]}" -gt 0 ] && echo "IO_sectors_read: ${disk[2]}"   >> $TOPDIR/OTHER/_statistics
         [ "0${disk[4]}" -gt 0 ] && echo "IO_requests_write: ${disk[4]}" >> $TOPDIR/OTHER/_statistics
         [ "0${disk[6]}" -gt 0 ] && echo "IO_sectors_write: ${disk[6]}"  >> $TOPDIR/OTHER/_statistics
         umount /sys
    fi

    if test -n "$VM_SWAP"; then
         echo "... saving built packages"
         swapoff "$VM_SWAP"
         args="--padstart 512 --padend 512 -v"
         case "$BUILDTYPE" in
             spec)
                 computeblocklists $args $TOPDIR/RPMS/*/*.{d,}rpm $TOPDIR/SRPMS/* $TOPDIR/OTHER/* > "$VM_SWAP"
                 ;;
             dsc)
                 computeblocklists $args $TOPDIR/DEBS/*.deb $TOPDIR/SOURCES.DEB/* $TOPDIR/OTHER/* > "$VM_SWAP"
                 ;;
             kiwi)
                 computeblocklists $args $TOPDIR/KIWI/* $TOPDIR/OTHER/* > "$VM_SWAP"
                 ;;
             arch)
                 computeblocklists $args $TOPDIR/ARCHPKGS/* $TOPDIR/OTHER/* > "$VM_SWAP"
                 ;;
             preinstallimage)
                 computeblocklists $args $TOPDIR/OTHER/* > "$VM_SWAP"
                 ;;
             *)
                 cleanup_and_exit 1
                 ;;
         esac || cleanup_and_exit 1
    else
         # quit inside of the emulator
         cleanup_and_exit "$exitcode"
    fi
fi

echo
echo "$HOST finished \"build $SPECFILE\" at `date --utc`."
echo

cleanup_and_exit "$exitcode"
