summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcommon_functions47
-rwxr-xr-xinit_buildsystem116
-rw-r--r--initvm.c56
3 files changed, 144 insertions, 75 deletions
diff --git a/common_functions b/common_functions
index f0084f8..54a1573 100755
--- a/common_functions
+++ b/common_functions
@@ -88,20 +88,27 @@ check_exit() {
fi
}
-check_use_emulator() {
- INITVM_NAME=
- # check if the extended host arch contains the build arch
+check_native_arch() {
+ local arch="$1"
local old_build_arch="$BUILD_ARCH"
- local arch="${BUILD_ARCH%%:*}"
BUILD_ARCH="$BUILD_HOST_ARCH"
extend_build_arch
BUILD_ARCH=":$BUILD_ARCH:"
if test "$BUILD_ARCH" != "${BUILD_ARCH/:$arch:/}" ; then
- # native supported arch, no emulator
BUILD_ARCH="$old_build_arch"
- return 1
+ return 0
fi
BUILD_ARCH="$old_build_arch"
+ return 1
+}
+
+check_use_emulator() {
+ INITVM_NAME=
+ # check if the extended host arch contains the build arch
+ if check_native_arch "${BUILD_ARCH%%:*}" ; then
+ # native supported arch, no emulator needed
+ return 1
+ fi
# to run the qemu initialization in the vm, we need to
# register it with a static program or shell script
@@ -158,4 +165,32 @@ buildroot_umount() {
LOOP_CNT=$((LOOP_CNT+1))
done
}
+# rm that makes sure the file is gone
+buildroot_rm() {
+ rm -rf "$BUILD_ROOT/$1"
+ test -e "$BUILD_ROOT/$1" && cleanup_and_exit 1 "could not remove $BUILD_ROOT/$1"
+}
+
+assert_dirs() {
+ local d rl
+ if test -z "$1" ; then
+ set usr sbin usr/bin usr/sbin etc .build .build.oldpackages .init_b_cache .init_b_cache/scripts .init_b_cache/rpms .preinstall_image proc proc/sys proc/sys/fs proc/sys/fs/binfmt_misc sys dev dev/pts dev/shm mnt
+ fi
+ for d in "$@" ; do
+ if test -L "$BUILD_ROOT/$d" ; then
+ rl="$(readlink "$BUILD_ROOT/$d")"
+ test "$d" = sbin -a "x$rl" = "xusr/sbin" && continue
+ test "$d" = sbin -a "x$rl" = "xusr/bin" && continue
+ test "$d" = usr/sbin -a "x$rl" = "xbin" && continue
+ cleanup_and_exit 1 "$d: illegal symlink to $rl"
+ else
+ test -e "$BUILD_ROOT/$d" -a ! -d "$BUILD_ROOT/$d" && cleanup_and_exit 1 "$d: not a directory"
+ fi
+ done
+}
+
+assert_dir_path() {
+ test "$1" != "${1%/*}" && assert_dir_path "${1%/*}"
+ assert_dirs "$1"
+}
diff --git a/init_buildsystem b/init_buildsystem
index 30f4132..6876514 100755
--- a/init_buildsystem
+++ b/init_buildsystem
@@ -152,45 +152,60 @@ TMPFILE="$BUILD_ROOT"/tmpfile
#
# needed functions
#
-
-cleanup_and_exit() {
- trap EXIT
- test "$BUILD_ROOT" = / -a -n "$browner" && chown "$browner" "$BUILD_ROOT"
- # umount so init_buildsystem can be used standalone
-# XXX: use stat -f /dev/pts/ -c %T to check whether it's mounted and not suppress errors then?
- buildroot_umount "/proc/sys/fs/binfmt_misc"
- buildroot_umount "/proc"
- buildroot_umount "/sys"
- buildroot_umount "/dev/pts"
- buildroot_umount "/dev/shm"
- buildroot_umount "/mnt"
- exit ${1:-0}
+mount_stuff() {
+ if test "$UID" = 0 -a -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
+ mount -n -tproc none "$BUILD_ROOT/proc"
+ test -e "$BUILD_ROOT/proc/self" || cleanup_and_exit 1 "Could not mount /proc, is this a container with missing capabilities?"
+ mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts"
+ fi
}
-clean_build_root() {
- if test -n "$BUILD_ROOT" ; then
+umount_stuff() {
+ if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
buildroot_umount "/proc/sys/fs/binfmt_misc"
buildroot_umount "/proc"
buildroot_umount "/sys"
buildroot_umount "/dev/pts"
buildroot_umount "/dev/shm"
buildroot_umount "/mnt"
+ fi
+}
+
+cleanup_and_exit() {
+ trap EXIT
+ test -z "$1" && set 0
+ if test -n "$2" ; then
+ if test "$1" -ne 0 ; then
+ echo "$2" >&2
+ else
+ echo "$2"
+ fi
+ fi
+ test "$BUILD_ROOT" = / -a -n "$browner" && chown "$browner" "$BUILD_ROOT"
+ # umount so init_buildsystem can be used standalone
+ umount_stuff
+ # never report a fatal error when the job got killed from outside
+ test "$1" = 4 -a -e "$BUILD_ROOT/exit" && exit 1
+ exit $1
+}
+
+clean_build_root() {
+ if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
+ umount_stuff
rm -rf -- "$BUILD_ROOT"/* 2> /dev/null || true
- chattr -a -A -i -R -- "$BUILD_ROOT" 2> /dev/null || true
+ chattr -a -A -i -R -- "$BUILD_ROOT" 2> /dev/null || true # does not follow symlinks
rm -rf -- "$BUILD_ROOT"/*
rm -rf -- "$BUILD_ROOT/.build"
+ rm -rf -- "$BUILD_ROOT"/.build.console.*
+ rm -rf -- "$BUILD_ROOT"/.build.hostarch.*
rm -rf -- "$BUILD_ROOT"/.build.kernel.*
rm -rf -- "$BUILD_ROOT"/.build.initrd.*
+ rm -rf -- "$BUILD_ROOT"/.build.sysroot
rm -rf -- "$BUILD_ROOT/.root"
rm -rf -- "$BUILD_ROOT/.init_b_cache"
+ test -L "$BUILD_ROOT/.preinstall_image" && rm -f -- "$BUILD_ROOT/.preinstall_image"
rm -rf -- "$BUILD_ROOT"/.preinstall_image/*
rm -rf -- "$BUILD_ROOT"/.preinstallimage*
- mkdir -p "$BUILD_ROOT/proc"
- mkdir -p "$BUILD_ROOT/dev/pts"
- if test "$UID" = 0 ; then
- mount -n -tproc none "$BUILD_ROOT/proc"
- mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT/dev/pts"
- fi
fi
}
@@ -281,7 +296,7 @@ create_devs() {
done << DEVLIST
mknod null 666 c 1 3
mknod zero 666 c 1 5
- mknod full 622 c 1 7
+ mknod full 666 c 1 7
mknod random 666 c 1 8
mknod urandom 644 c 1 9
mknod tty 666 c 5 0
@@ -572,10 +587,7 @@ fi
if test -e "$BUILD_IS_RUNNING" ; then
echo "It seems that there was an incomplete setup of $BUILD_ROOT."
echo "To be sure, we will build it again completely..."
- umount -n "$BUILD_ROOT"/proc/sys/fs/binfmt_misc 2> /dev/null || true
- umount -n "$BUILD_ROOT"/proc 2> /dev/null
- umount -n "$BUILD_ROOT"/dev/pts 2> /dev/null
- umount -n "$BUILD_ROOT"/mnt 2> /dev/null
+ umount_stuff
echo "Your build system is broken!! Shall I execute"
echo
echo " rm -rf -- $BUILD_ROOT/*"
@@ -595,11 +607,21 @@ if test -e "$BUILD_IS_RUNNING" ; then
esac
fi
+# check for surprises
+if test -z "$CLEAN_BUILD" -a -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / ; then
+ assert_dirs
+fi
+
+# umount stuff if mounted
+if test -n "$BUILD_ROOT" -a "$BUILD_ROOT" != / -a -e "$BUILD_ROOT/proc/self" ; then
+ umount_stuff
+fi
+
#
-# store that we start to build system
+# store that we start to build the system
#
-mkdir -p "$BUILD_ROOT"
-mkdir -p "$BUILD_ROOT"/.build
+mkdir -p -- "$BUILD_ROOT" "$BUILD_ROOT/.build" "$BUILD_ROOT/proc" "$BUILD_ROOT/sys" "$BUILD_ROOT/dev/pts" || cleanup_and_exit 4
+
touch $BUILD_IS_RUNNING
if test -n "$PREPARE_VM" ; then
@@ -607,14 +629,8 @@ if test -n "$PREPARE_VM" ; then
fi
if test -e "$BUILD_ROOT"/.build/init_buildsystem.data ; then
- # vm continuation
+ # vm continuation, read old config
. "$BUILD_ROOT"/.build/init_buildsystem.data
- if ! test -e "$BUILD_ROOT"/.init_b_cache/preinstall_finished ; then
- # finish preinstall
- run_pkg_scripts
- pkg_initdb
- touch "$BUILD_ROOT"/.init_b_cache/preinstall_finished
- fi
else
#
# now make sure that all the packages are installed.
@@ -661,7 +677,7 @@ else
# register the QEMU emulator if needed
# (we do not need this for the prepare step, as we do not run scripts in this case)
#
- copy_qemu
+ copy_qemu
if test -z "$PREPARE_VM" ; then
if check_use_emulator ; then
echo "registering binfmt handlers for cross build"
@@ -884,6 +900,7 @@ if test ! -e "$BUILD_ROOT"/installed-pkg -a ! -e "$BUILD_ROOT"/.build/init_build
test -e "$BUILD_ROOT"/etc/fstab || touch "$BUILD_ROOT"/etc/fstab
test ! -e "$BUILD_ROOT"/etc/ld.so.conf -a -e "$BUILD_ROOT"/etc/ld.so.conf.in && cp "$BUILD_ROOT"/etc/ld.so.conf.in "$BUILD_ROOT"/etc/ld.so.conf
if test -z "$PREPARE_VM" ; then
+ mount_stuff
run_pkg_scripts
pkg_initdb
touch "$BUILD_ROOT"/.init_b_cache/preinstall_finished
@@ -891,6 +908,11 @@ if test ! -e "$BUILD_ROOT"/installed-pkg -a ! -e "$BUILD_ROOT"/.build/init_build
# mark as preinstalled no longer needed
rm -rf "$BUILD_ROOT/installed-pkg"
mkdir -p "$BUILD_ROOT/installed-pkg"
+else
+ # preinstall was already done
+ if test -z "$PREPARE_VM" ; then
+ mount_stuff
+ fi
fi
if test -n "$PREPARE_VM" ; then
@@ -917,11 +939,15 @@ if test -n "$PREPARE_VM" ; then
cleanup_and_exit 0
fi
+#
+# finish preinstall if this is a vm continuation
+#
+if test -e "$BUILD_ROOT/.build/init_buildsystem.data" -a ! -e "$BUILD_ROOT/.init_b_cache/preinstall_finished" ; then
+ run_pkg_scripts
+ pkg_initdb
+ touch "$BUILD_ROOT/.init_b_cache/preinstall_finished"
+fi
-mkdir -p "$BUILD_ROOT"/proc
-mkdir -p "$BUILD_ROOT"/dev/pts
-mount -n -tproc none "$BUILD_ROOT"/proc 2>/dev/null || true
-mount -n -tdevpts -omode=0620,gid=5 none "$BUILD_ROOT"/dev/pts 2>/dev/null || true
#
# create .build.binaries directory if requested
@@ -1111,9 +1137,9 @@ cd "$BUILD_ROOT" || cleanup_and_exit 1
#
# setup /etc/mtab
#
-rm -f "$BUILD_ROOT"/etc/mtab
-cp /proc/mounts "$BUILD_ROOT"/etc/mtab
-chmod 644 "$BUILD_ROOT"/etc/mtab
+#init_buildsystem: make /etc/mtab a symlink
+#from patch:https://github.com/openSUSE/obs-build/commit/f0e7d37c811dbde49fcd5b9c8779063f4e87cb74
+ln -sf ../proc/self/mounts $BUILD_ROOT/etc/mtab
#
# make sure, that our nis is not present in the chroot system
diff --git a/initvm.c b/initvm.c
index db23045..f77687c 100644
--- a/initvm.c
+++ b/initvm.c
@@ -20,7 +20,7 @@
*
* AUTHOR
* Copyright (c) 2012 James Perkins <james.perkins@linuxfoundation.org>
- * i Adrian Schroeter <adrian@suse.de>
+ * Adrian Schroeter <adrian@suse.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 or 3 as
@@ -45,6 +45,7 @@
#include <string.h>
#include <errno.h>
#include <stdio.h>
+#include <unistd.h>
/* to enable debugging, compile with -DDEBUG */
#ifdef DEBUG
@@ -273,7 +274,7 @@ enum okfail binfmt_register(char *datafile, char *regfile)
f[name]);
#endif /* DEBUG */
- /* Does the interpreter exists? */
+ /* Does the interpreter exists? */
ret=access(f[interpreter], X_OK);
if (ret != 0) {
#ifdef DEBUG
@@ -316,29 +317,34 @@ enum okfail binfmt_register(char *datafile, char *regfile)
int main(int argc, char* argv[], char* env[])
{
int retval;
- char buf[BUFSIZ];
+ char buf[BUFSIZ], *build_dir;
- /* mount proc filesystem if it isn't already */
- if (mount("proc", "/proc", "proc", MS_MGC_VAL, NULL) == -1) {
- if (errno != EBUSY) {
- perror("mount: /proc");
- exit(1);
+ if (system("mount | grep 'proc on /proc type proc' >/dev/null") != 0) {
+ /* mount proc filesystem if it isn't already. */
+ if (mount("proc", "/proc", "proc", MS_MGC_VAL, NULL) == -1) {
+ if (errno != EBUSY) {
+ perror("mount: /proc");
+ exit(1);
+ }
+ }
+ }
+
+ /* need to have binfmt_misc loaded already */
+ if (system("mount | grep 'binfmt_misc on /proc/sys/fs/binfmt_misc' >/dev/null") != 0) {
+ /* try to load binfmt module if present, no big deal if it fails */
+ if ((retval = system("/sbin/modprobe binfmt_misc")) != 0) {
+ DBG(fprintf(stderr, "modprobe binfmt_misc exit code %d\n",
+ retval));
}
- }
-
- /* try to load binfmt module if present, no big deal if it fails */
- if ((retval = system("/sbin/modprobe binfmt_misc")) != 0) {
- DBG(fprintf(stderr, "modprobe binfmt_misc exit code %d\n",
- retval));
- }
- /* mount binfmt filesystem */
- if (mount("binfmt_misc", SYSFS_BINFMT_MISC, "binfmt_misc", MS_MGC_VAL,
- NULL) == -1) {
- if (errno != EBUSY) {
- perror("mount: binfmt_misc, " SYSFS_BINFMT_MISC);
+ /* mount binfmt filesystem */
+ if (mount("binfmt_misc", SYSFS_BINFMT_MISC, "binfmt_misc", MS_MGC_VAL,
+ NULL) == -1) {
+ if (errno != EBUSY) {
+ perror("mount: binfmt_misc, " SYSFS_BINFMT_MISC);
+ }
}
- }
+ }
/* verify all paths resulting from this are OK */
if (!test_access_files(rx_files, R_OK|X_OK, "read/search")) {
@@ -361,10 +367,12 @@ int main(int argc, char* argv[], char* env[])
exit(1);
}
- if (getenv("BUILD_DIR"))
- sprintf(buf, "%s/qemu-reg", getenv("BUILD_DIR"));
+ *buf = 0;
+ build_dir = getenv("BUILD_DIR");
+ if (build_dir && strlen(build_dir) < sizeof(buf) - 10)
+ sprintf(buf, "%s/qemu-reg", build_dir);
- if (!buf || !binfmt_register(buf, SYSFS_BINFMT_MISC_REG)) {
+ if (!*buf || !binfmt_register(buf, SYSFS_BINFMT_MISC_REG)) {
/* setup all done, do the registration */
if (!binfmt_register(BINFMT_REGF_0, SYSFS_BINFMT_MISC_REG)) {
fprintf(stderr, "%s: failed. Trying alternate binfmt file\n",