diskimage-builder/lib/ramdisk-functions
JUN JIE NAN 6b7cf26689 Fixed device or resource busy issue in EXIT trap
cleanup for ramdisk failed to umount TMP_BUILD_DIR with device or
resource busy error.

The patch unmounts all the mountpoints under TMP_BUILD_DIR and
detaches loop devices associated with TMP_IMAGE_PATH.

The unmounts are applied with both force(-f) and lazy(-l)
options. Force option is only for NFS mounts, it's kept here since no
harm for lazy option.

Change-Id: I84035e6a003d8135186b2fda3facbd2c37967529
2014-01-03 16:53:38 +08:00

250 lines
6.8 KiB
Plaintext

# Copyright 2012 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2012 NTT DOCOMO, INC.
#
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
function fullpath() {
local f=$1
if [ "${f#/}" = "$f" ]; then
echo `pwd`/"$f"
else
echo "$f"
fi
}
function cleanup () {
unmount_dir "$TMP_BUILD_DIR/mnt"
if [ -f "$TMP_IMAGE_PATH" ]; then
loopdev=`sudo losetup -j "$TMP_IMAGE_PATH" | cut -d: -f1`
if [ -n "$loopdev" ]; then
detach_loopback "$loopdev"
fi
fi
unmount_dir "$TMP_BUILD_DIR"
rm -rf --one-file-system "$TMP_BUILD_DIR"
}
function create_ramdisk_base () {
echo "Creating base system"
mkdir -p "$TMP_MOUNT_PATH/bin"
ln -s bin "$TMP_MOUNT_PATH/sbin"
mkdir -p "$TMP_MOUNT_PATH/lib"
mkdir -p "$TMP_MOUNT_PATH/lib/modules"
mkdir -p "$TMP_MOUNT_PATH/etc"
mkdir -p "$TMP_MOUNT_PATH/etc/udev"
# cjk adding for discovery support
mkdir -p "$TMP_MOUNT_PATH/var/lib/dhcp"
mkdir -p "$TMP_MOUNT_PATH/var/run"
mkdir -p "$TMP_MOUNT_PATH/lib/udev/rules.d"
DISTRO=`lsb_release -si` || true
if [[ "Fedora RedHatEnterpriseServer" =~ "$DISTRO" ]]; then
mkdir -p "$TMP_MOUNT_PATH/usr"
ln -s ../lib "$TMP_MOUNT_PATH/usr/lib"
if [ "`uname -m`" = "x86_64" ]; then
ln -s lib "$TMP_MOUNT_PATH/lib64"
fi
fi
if [ -e $LIB_UDEV/rules.d/50-firmware.rules ]; then
cp -a "$LIB_UDEV/rules.d/50-firmware.rules" "$TMP_MOUNT_PATH/lib/udev/rules.d"
fi
cp -a "$LIB_UDEV/rules.d/80-drivers.rules" "$TMP_MOUNT_PATH/lib/udev/rules.d"
if [ -a $LIB_UDEV/firmware ]; then
cp -a "$LIB_UDEV/firmware" "$TMP_MOUNT_PATH/lib/udev"
fi
# cjk adding for hwdiscovery support
cp "/sbin/dhclient-script" "$TMP_MOUNT_PATH/sbin"
mkdir -p "$TMP_MOUNT_PATH/etc/modprobe.d"
echo "blacklist evbug" > "$TMP_MOUNT_PATH/etc/modprobe.d/blacklist.conf"
# cjk adding for hwdiscovery support
touch "$TMP_MOUNT_PATH/etc/fstab"
mkdir -p "$TMP_MOUNT_PATH/etc/udev"
cat >"$TMP_MOUNT_PATH/etc/udev/udev.conf" <<EOF
udev_root="/dev"
udev_rules="/lib/udev/rules.d"
udev_log="no"
EOF
generate_hooks
TARGET_ROOT=$TMP_MOUNT_PATH run_d root
}
function copy_required_libs() {
set +e
ldd_out=`ldd "$1"`
local ret_code=$?
set -e
if [ $ret_code -ne 0 ]; then
return
fi
local IFS="
"
# Patterns of output of ldd
#
# 1. name to real path
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f095e784000)
# 2. only path
# /lib64/ld-linux-x86-64.so.2 (0x00007f095ef79000)
# 3. path to path
# /lib64/ld-linux-x86-64.so.2 => /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 (0x00007facff857000)
# 4. name to empty (vdso)
# linux-vdso.so.1 => (0x00007fff0c5ff000)
for i in `echo "$ldd_out" | sed -e 's/^\t*//'`; do
local ref=$( echo "$i" | awk -F '[ ]' '{print $1}')
local real=$( echo "$i" | awk -F '[ ]' '$2 == "=>" {print $3}
$2 != "=>" {print $1}')
if [ -z "$real" ]; then
continue
fi
if [ "$ref" = "${ref#/}" ]; then
ref=/lib/$ref
fi
dest=/lib/`basename "$real"`
cp -Ln "$real" "$TMP_MOUNT_PATH/$dest"
# Create a symbolic link if the shared library is referred
# by the different name
if [ "$ref" != "$dest" ]; then
local link_path=$TMP_MOUNT_PATH/$ref
if ! [ -e "$link_path" -o -L "$link_path" ]; then
mkdir -p `dirname "$link_path"`
ln -s "$dest" "$link_path"
fi
fi
done
}
function populate_lib () {
echo "Populating /lib"
# find udevd
UDEVD=
for f in /sbin/udevd /lib/udev/udevd /lib/systemd/systemd-udevd \
/usr/lib/systemd/systemd-udevd \
/usr/lib/udev/udevd; do
if [ -x "$f" ]; then
UDEVD="$f"
break
fi
done
UDEV_FIRMWARE=
if [ -a $LIB_UDEV/firmware ]; then
UDEV_FIRMWARE="$LIB_UDEV/firmware"
fi
for i in "$BUSYBOX" bash lsmod modprobe udevadm \
wget reboot shutdown $UDEVD $UDEV_FIRMWARE \
$(cat /etc/dib_binary_deps) ; do
if busybox_list | grep "^$i\$" >/dev/null; then
continue
fi
path=`which $i 2>/dev/null` || path=$i
if ! [ -x "$path" ]; then
echo "$i is not found in PATH" 2>&1
exit 1
fi
cp -L "$path" "$TMP_MOUNT_PATH/bin/"
copy_required_libs "$path"
done
cp -a "$MODULE_DIR" "$TMP_MOUNT_PATH/lib/modules/$KERNEL_VERSION"
echo "Removing kernel framebuffer drivers to enforce text mode consoles..."
find $TMP_MOUNT_PATH/lib/modules/$KERNEL_VERSION/kernel/drivers/video -name '*fb.ko' -exec rm -v {} \;
cp -a "$FIRMWARE_DIR" "$TMP_MOUNT_PATH/lib/firmware"
}
function busybox_list () {
# busybox supports --list option since version 1.18
"$BUSYBOX" --list 2> /dev/null && return
# for busybox under 1.18 we parse command list from --help output
scrlet='{ if (go) { print } } /Currently defined functions:/ { go=1 }'
"$BUSYBOX" --help | awk "$scrlet" | tr ',' '\n' | xargs -n1 echo
}
function populate_busybox () {
echo "Creating symlinks for busybox binaries"
for i in $( busybox_list ); do
if [ -f "$TMP_MOUNT_PATH/bin/$i" ]; then
echo "skip $i"
continue
fi
ln -s busybox "$TMP_MOUNT_PATH/bin/$i"
done
}
function populate_init () {
echo "Installing init"
cp "$INIT" "$TMP_MOUNT_PATH/init"
chmod +x $TMP_MOUNT_PATH/init
for F in "$FUNCTIONS_D"/* ; do
cp "$F" "$TMP_MOUNT_PATH"
done
# Append /init with any element fragments that are present
TARGET_DIR="/tmp/in_target.d/"
for _ELEMENT in $(ls $TARGET_DIR/init.d/) ; do
_FILE="${TARGET_DIR}/init.d/${_ELEMENT}"
if [ -a $_FILE ]; then
cat >>$TMP_MOUNT_PATH/init <<EOF
# init fragment from ${_ELEMENT}
EOF
cat <$_FILE >>$TMP_MOUNT_PATH/init
fi
done
# Add our final steps to /init
cat <${INIT}-end >>$TMP_MOUNT_PATH/init
}
function finalise_image () {
echo "Finalising image"
(cd "$TMP_MOUNT_PATH"; find . | cpio -o -H newc | gzip > "$TMP_IMAGE_PATH" )
}
function populate_udev () {
echo "Installing udev rules"
TARGET_DIR="/tmp/in_target.d/"
for _ELEMENT in $(ls $TARGET_DIR/udev.d/) ; do
_FILE="${TARGET_DIR}/udev.d/${_ELEMENT}"
if [ -a $_FILE ]; then
cp ${_FILE} $TMP_MOUNT_PATH/lib/udev/rules.d/
fi
done
}
function find_kernel_version () {
_TMP=$(ls /boot/vmlinuz-* | sort | tail -1)
if [ "$_TMP" == "" ]; then
echo "Unable to find a suitable kernel" >>/dev/stderr
exit 1
fi
echo ${_TMP##/boot/vmlinuz-}
}