#!/bin/bash # ----------------------------------------------------------------------------- # # Copyright (c) 2013 - OpenSLX GmbH # # This program is free software distributed under the GPL version 2. # See http://openslx.org/COPYING # # If you have any feedback please consult http://openslx.org/feedback and # send your suggestions, praise, or complaints to feedback@openslx.org # # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- # # # Script to create the stage3.1 root file system: # - generate the rootfs directory structure and copy system devices # - copies kernel modules and firmware as given in the config # file (core/core.conf) to be able to load NIC/GFX modules early. # - compile and include following tools: 'busybox' and 'hwinfo' # MODULE_DIR="${ROOT_DIR}/remote" STAGE31_DIR="${MODULE_DIR}/stage3.1" initial_checks() { [ ! -z "${KERNEL_VERSION}" ] || perror "No kernel version, cannot proceed." [ ! -z "${ARCH_TRIPLET}" ] || perror "No arch triplet, cannot proceed." [ -d "${STAGE31_DIR}" ] || mkdir -p "${STAGE31_DIR}" [ ! -z "$(which depmod)" ] || perror "No 'depmod' found on this systemd." [ -d "${MODULE_DIR}"/tools/busybox/build ] \ || perror "No busybox found, build it with './mltk tools -b busybox'" } read_config() { local CORE_CONFIG="${MODULE_DIR}/core/core.conf" [ ! -e "${CORE_CONFIG}" ] && perror "${MODULE_DIR}/core/core.conf not found." . "${CORE_CONFIG}" || perror "Sourcing "${MODULE_DIR}"/core/core.conf failed." } generate_rootfs() { # create basic directory structure mkdir -p "${STAGE31_DIR}"/{bin,dev,proc,run,etc,mnt,sys} \ || perror "Cannot create basic directory structure in '${STAGE31_DIR}'" # copy device files from running system cp -a /dev/{console,kmsg,mem,null,tty,tty0,tty1,tty9,urandom,zero} \ "${STAGE31_DIR}"/dev || perror "Cannot copy devices from running system" # copy libc and ld-linux tarcopy "$(list_basic_libs)" "${STAGE31_DIR}" # copy required files tarcopy "${REQUIRED_FILES}" "${STAGE31_DIR}" # copy static data cp -r "${MODULE_DIR}"/core/data/* "${STAGE31_DIR}" } copy_kernel_modules() { local MODLIST="stage31_modules_list" [ -e $MODLIST ] && rm -f $MODLIST # process modules list for MOD in ${REQUIRED_MODULES}; do local MOD_PATH="/lib/modules/${KERNEL_VERSION}/${MOD}" if [ ! -e "${MOD_PATH}" ]; then pwarning "Module $MOD not found. Skipping. (might cause problem on certain clients!)" continue else pdebug "Copying "${MOD_PATH}"" echo "${MOD_PATH}" >> "${MODLIST}" fi done if [ -s "$MODLIST" ]; then local MODLISTCOUNT=$(cat "$MODLIST" | wc -l) pinfo "Copying $MODLISTCOUNT modules to stage 3.1 target directory." tarcopy "$(cat "$MODLIST")" "${STAGE31_DIR}" fi } generate_modules_map_files() { # first strip modules.order of all the modules we don't use cat /lib/modules/"${KERNEL_VERSION}"/modules.order | grep -E $(echo ${REQUIRED_MODULES} | tr '\ ' '|') \ >> "${STAGE31_DIR}"/lib/modules/"${KERNEL_VERSION}"/modules.order # copy list of builtin kernel modules cp /lib/modules/"${KERNEL_VERSION}"/modules.builtin "${STAGE31_DIR}"/lib/modules/"${KERNEL_VERSION}" # with modules.order and modules.builtin, we can run depmod for the rest of the files depmod -b "${STAGE31_DIR}" } copy_firmware() { local FWLIST="stage31_firmware_list" [ -e $FWLIST ] && rm -f $FWLIST local FW_PATH="/lib/firmware" # process firmware list for FW in ${REQUIRED_FIRMWARE}; do local FOUND=0 if [ -e "${FW_PATH}"/"${FW}" ]; then pdebug "Copying "${FW_PATH}"/"${FW}"" echo "${FW_PATH}"/"${FW}" >> "$FWLIST" FOUND=1 fi if [ -e "${FW_PATH}"/"${KERNEL_VERSION}"/"${FW}" ]; then pdebug "Copying "${FW_PATH}"/"${KERNEL_VERSION}"/"${FW}"" echo "${FW_PATH}"/"${KERNEL_VERSION}"/"${FW}" >> "$FWLIST" FOUND=1 fi [ $FOUND -ne 1 ] && pwarning "Neither "${FW_PATH}"/"${FW}" nor "${FW_PATH}"/"${KERNEL_VERSION}"/"${FW}" found on the system." done if [ -s "${FWLIST}" ]; then local FWLISTCOUNT=$(cat "$FWLIST"|wc -l) pinfo "Copying $FWLISTCOUNT firmware to stage 3.1 target directory." tarcopy "$(cat "$FWLIST")" "${STAGE31_DIR}" fi } install_basic_tools() { # get busybox from tools/ we checked earlier if its there. pinfo "Copying busybox to ${STAGE31_DIR}." cp -r "${MODULE_DIR}"/tools/busybox/build/openslx/* "${STAGE31_DIR}" # install plymouth pinfo "Copying plymouth to ${STAGE31_DIR}." rm -f list.ply cd "${MODULE_DIR}"/tools/plymouth/build echo ./bin/plymouth >> list.ply echo ./sbin/plymouthd >> list.ply get_dynamic_dependencies -l "${MODULE_DIR}"/tools/plymouth/build ./bin/plymouth >> list.ply get_dynamic_dependencies -l "${MODULE_DIR}"/tools/plymouth/build ./sbin/plymouthd >> list.ply for i in $(find lib/plymouth -name \*.so); do get_link_chain "${MODULE_DIR}"/tools/plymouth/build/"$i" "${MODULE_DIR}"/tools/plymouth/build >> list.ply get_dynamic_dependencies -l "${MODULE_DIR}"/tools/plymouth/build $i >> list.ply done tarcopy "$(cat list.ply | sort -u)" "${STAGE31_DIR}" cd - &> /dev/null cp -r "${MODULE_DIR}"/tools/plymouth/data/* "${STAGE31_DIR}" # copy debugging tools STRACE=$(which strace) [ "x${STRACE}" != "x" ] && tarcopy "$(get_link_chain ${STRACE})" "${STAGE31_DIR}" LDD=$(which ldd) [ "x${LDD}" != "x" ] && tarcopy "$(get_link_chain ${LDD})" "${STAGE31_DIR}" # get hwinfo and the required libx86emu [ ! -d "${MODULE_DIR}"/core/src ] && mkdir -p "${MODULE_DIR}"/core/src cd "${MODULE_DIR}"/core/src # start with libx86emu pinfo "Cloning 'git://gitorious.org/x86emu/libx86emu.git'..." git clone git://gitorious.org/x86emu/libx86emu.git cd libx86emu pinfo "Compiling 'libx86emu'..." make || perror "libx86emu: make failed." pinfo "Installing 'libx86emu' in ${MODULE_DIR}/core/build" DESTDIR="${MODULE_DIR}"/core/build make install || perror "libx86emu: make install to "${STAGE31_DIR}" failed." cd - &> /dev/null # now hwinfo pinfo "Cloning 'git://gitorious.org/opensuse/hwinfo.git'..." git clone git://gitorious.org/opensuse/hwinfo.git cd hwinfo pinfo "Compiling 'hwinfo'..." make || perror "hwinfo: make failed." pinfo "Installing 'hwinfo' in ${MODULE_DIR}/core/build" DESTDIR="${MODULE_DIR}"/core/build make install || perror "hwinfo: make install failed." cd - &> /dev/null # get dependencies of hwinfo cd "${MODULE_DIR}"/core/build HWINFO=$(find . -type f -name hwinfo -executable) get_link_chain "${MODULE_DIR}"/core/build/"${HWINFO}" "${MODULE_DIR}"/core/build >> list_wanted_stage3.1 get_dynamic_dependencies -l "${MODULE_DIR}"/core/build "${MODULE_DIR}"/core/build/"${HWINFO}" >> list_wanted_stage3.1 tarcopy "$(cat list_wanted_stage3.1)" "${STAGE31_DIR}" cd - &> /dev/null } generate_stage31() { local TOOL_STR="[core]" pinfo "Generating stage 3.1 file system..." cd "${MODULE_DIR}"/core initial_checks read_config generate_rootfs copy_kernel_modules generate_modules_map_files copy_firmware install_basic_tools cd - &> /dev/null } clean_core() { pinfo "Cleaning '${STAGE31_DIR}'..." [ -d ${STAGE31_DIR} ] && { rm -rf ${STAGE31_DIR} || perror "rm -rf failed."; } pinfo "Cleaning '${MODULE_DIR}/core'..." [ -e ${MODULE_DIR}/core/stage31_modules_list ] && { rm -f ${MODULE_DIR}/core/stage31_modules_list || perror "rm -f failed."; } [ -e ${MODULE_DIR}/core/stage31_firmware_list ] && { rm -f ${MODULE_DIR}/core/stage31_firmware_list || perror "rm -f failed."; } pinfo "Cleaning '${MODULE_DIR}/core/build'..." [ -e ${MODULE_DIR}/core/build ] && { rm -rf ${MODULE_DIR}/core/build || perror "rm -rf failed."; } pinfo "Cleaning '${MODULE_DIR}/core/src'..." [ -e ${MODULE_DIR}/core/src ] && { rm -rf ${MODULE_DIR}/core/src || perror "rm -rf failed."; } }