azure-linux-automation/remote-scripts/Perf_BuildKernel.sh

413 строки
13 KiB
Bash

#!/bin/bash
########################################################################
#
# Linux on Hyper-V and Azure Test Code, ver. 1.0.0
# Copyright (c) Microsoft Corporation
#
# 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
#
# THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
# ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
# PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
#
# See the Apache Version 2.0 License for specific language governing
# permissions and limitations under the License.
#
########################################################################
#######################################################################
#
# Description:
# This script was created to automate the testing of a Linux
# kernel source tree. It does this by performing the following
# steps:
# 1. Make sure we were given a kernel source. If a linux-next git address is provided, make sure that
# the VM has a NIC (eth0) connect to Internet.
# 2. Configure and build the new kernel
#
# The outputs are directed into files named:
# Perf_BuildKernel_make.log,
# Perf_BuildKernel_makemodulesinstall.log,
# Perf_BuildKernel_makeinstall.log
#
# This test script requires the below test parameters:
# <param>SOURCE_TYPE=ONLINE</param>
# <param>LINUX_KERNEL_LOCATION=git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git</param>
# <param>KERNEL_VERSION=linux-next</param>
#
# A typical XML test definition for this test case would look
# similar to the following:
# <test>
# <testName>ICA-BUILD-LINUX-KERNEL</testName>
# <testScript>Perf_BuildKernel.sh</testScript>
# <testScriptPs1>ICA-BUILD-LINUX-KERNEL.ps1</testScriptPs1>
# <files>remote-scripts\Perf_BuildKernel.sh,remote-scripts\Packages\linux-3.18.1.tar.xz,SetupScripts\DetectLinuxDistro.sh</files>
# <setupType>MediumVM</setupType>
# <testParams>
# <param>LINUX_KERNEL_LOCATION=https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git</param>
# <param>KERNEL_VERSION=linux-next</param>
# <!-- <param>SOURCE_TYPE=TARBALL</param>
# <param>TARBALL=linux-3.18.1.tar.xz</param>
# <param>KERNEL_VERSION=linux-3.18.1</param> -->
# </testParams>
# <TestType></TestType>
# <TestFeature></TestFeature>
# <TestID></TestID>
# </test>
#
#######################################################################
DEBUG_LEVEL=3
CONFIG_FILE=.config
START_DIR=$(pwd)
#
#Detect Distro
#
LinuxDistro=`./DetectLinuxDistro.sh`
if [ $LinuxDistro == "SLES" -o $LinuxDistro == "SUSE" ]; then
#zypper update
zypper --non-interactive install git-core make tar gcc bc patch dos2unix wget xz
elif [ $LinuxDistro == "CENTOS" -o $LinuxDistro == "REDHAT" -o $LinuxDistro == "FEDORA" -o $LinuxDistro == "ORACLELINUX" ]; then
#yum update
yum install -y git make tar gcc bc patch dos2unix wget xz
elif [ $LinuxDistro == "UBUNTU" ]; then
apt-get update
apt-get install -y git make tar gcc bc patch dos2unix wget
fi
#
# Source the constants.sh file so we know what files to operate on.
#
dos2unix -q constants.sh > /dev/null
source ./constants.sh
dbgprint()
{
if [ $1 -le $DEBUG_LEVEL ]; then
echo "$2"
fi
}
UpdateTestState()
{
echo $1 > ${START_DIR}/state.txt
}
UpdateSummary()
{
echo $1 >> ${START_DIR}/summary.log
}
#
# Create the state.txt file so the ICA script knows
# we are running
#
UpdateTestState "TestRunning"
if [ -e ${START_DIR}/state.txt ]; then
dbgprint 0 "State.txt file is created "
dbgprint 0 "Content of state is : " ; echo `cat ${START_DIR}/state.txt`
fi
#
# Write some useful info to the log file
#
dbgprint 1 "buildKernel.sh - Script to automate building of the kernel"
dbgprint 3 ""
dbgprint 3 "Global values"
dbgprint 3 " DEBUG_LEVEL = ${DEBUG_LEVEL}"
dbgprint 3 " SOURCE_TYPE = ${SOURCE_TYPE}"
dbgprint 3 " LINUX_KERNEL_LOCATION = ${LINUX_KERNEL_LOCATION}"
dbgprint 3 " TARBALL = ${TARBALL}"
dbgprint 3 " KERNEL_VERSION = ${KERNEL_VERSION}"
dbgprint 3 " CONFIG_FILE = ${CONFIG_FILE}"
dbgprint 3 ""
#
# Delete old kernel source tree if it exists.
# This should not be needed, but check to make sure
#
# adding check for summary.log
if [ -e ${START_DIR}/summary.log ]; then
dbgprint 1 "Cleaning up previous copies of summary.log"
rm -rf ${START_DIR}/summary.log
fi
# adding check for old kernel source tree
if [ -e ${KERNEL_VERSION} ]; then
dbgprint 1 "Cleaning up previous copies of source tree"
dbgprint 3 "Removing the ${KERNEL_VERSION} directory"
rm -rf ${KERNEL_VERSION}
fi
if [ "${SOURCE_TYPE}" == "TARBALL" ]; then
dbgprint 1 "Building linux kernel from tarball..."
#
# Make sure we were given the $TARBALL file
#
if [ ! ${TARBALL} ]; then
dbgprint 0 "The TARBALL variable is not defined."
dbgprint 0 "Aborting the test."
UpdateTestState "TestAborted"
exit 20
fi
dbgprint 3 "Extracting Linux kernel sources from ${TARBALL}"
tar -xf ${TARBALL}
sts=$?
if [ 0 -ne ${sts} ]; then
dbgprint 0 "tar failed to extract the kernel from the tarball: ${sts}"
dbgprint 0 "Aborting test."
UpdateTestState "TestAborted"
exit 40
fi
#
# The Linux Kernel is extracted to the folder which is named by the version by default
#
if [ ! -e ${KERNEL_VERSION} ]; then
dbgprint 0 "The tar file did not create the directory: ${KERNEL_VERSION}"
dbgprint 0 "Aborting the test."
UpdateTestState "TestAborted"
exit 50
fi
else
dbgprint 1 "Building linux-next kernel from git repository..."
#
# Make sure we were given the linux-next git location
#
if [ ! ${LINUX_KERNEL_LOCATION} ]; then
dbgprint 0 "The LINUX_KERNEL_LOCATION variable is not defined."
dbgprint 0 "Aborting the test."
UpdateTestState "TestAborted"
exit 20
fi
git clone ${LINUX_KERNEL_LOCATION}
fi
cd ${START_DIR}/${KERNEL_VERSION}
#
# Start the testing
#
proc_count=$(cat /proc/cpuinfo | grep --count processor)
dbgprint 1 "Build kernel with $proc_count CPU(s)"
UpdateSummary "KernelRelease=$(uname -r)"
UpdateSummary "ProcessorCount=$proc_count"
UpdateSummary "$(uname -a)"
#
# Create the .config file
#
dbgprint 1 "Creating the .config file."
if [ -f ${START_DIR}/ica/kernel.config.base ]; then
# Basing a new kernel config on a previous kernel config file will
# provide flexibility in providing know good config files with certain
# options enabled/disabled. Functionality could also potentially be
# added here for choosing between multiple old config files depending
# on the distro that the kernel is being compiled on (i.g. if Fedora
# is detected copy ${START_DIR}/ica/kernel.config.base-fedora to .config before
# running 'make oldconfig')
dbgprint 3 "Creating new config based on a previous .config file"
cp ${START_DIR}/ica/kernel.config.base .config
# Base the new config on the old one and select the default config
# option for any new options in the newer kernel version
yes "" | make oldconfig
else
dbgprint 3 "Create a default .config file"
yes "" | make oldconfig
sts=$?
if [ 0 -ne ${sts} ]; then
dbgprint 0 "make defconfig failed."
dbgprint 0 "Aborting the test."
UpdateTestState "TestAborted"
exit 60
fi
if [ ! -e ${CONFIG_FILE} ]; then
dbgprint 0 "make defconfig did not create the '${CONFIG_FILE}'"
dbgprint 0 "Aborting the test."
UpdateTestState "TestAborted"
exit 70
fi
#
# Enable HyperV support
#
dbgprint 3 "Enabling HyperV support in the ${CONFIG_FILE}"
# On this first 'sed' command use --in-place=.orig to make a backup
# of the original .config file created with 'defconfig'
sed --in-place=.orig -e s:"# CONFIG_HYPERVISOR_GUEST is not set":"CONFIG_HYPERVISOR_GUEST=y\nCONFIG_HYPERV=y\nCONFIG_HYPERV_UTILS=y\nCONFIG_HYPERV_BALLOON=y\nCONFIG_HYPERV_STORAGE=m\nCONFIG_HYPERV_NET=y\nCONFIG_HYPERV_KEYBOARD=y\nCONFIG_FB_HYPERV=y\nCONFIG_HID_HYPERV_MOUSE=m": ${CONFIG_FILE}
#
# Enable Ext4, Reiser support (ext3 is enabled by default)
#
sed --in-place -e s:"# CONFIG_EXT4_FS is not set":"CONFIG_EXT4_FS=y\nCONFIG_EXT4_FS_XATTR=y\nCONFIG_EXT4_FS_POSIX_ACL=y\nCONFIG_EXT4_FS_SECURITY=y": ${CONFIG_FILE}
sed --in-place -e s:"# CONFIG_REISERFS_FS is not set":"CONFIG_REISERFS_FS=y\nCONFIG_REISERFS_PROC_INFO=y\nCONFIG_REISERFS_FS_XATTR=y\nCONFIG_REISERFS_FS_POSIX_ACL=y\nCONFIG_REISERFS_FS_SECURITY=y": ${CONFIG_FILE}
#
# Enable Tulip network driver support. This is needed for the "legacy"
# network adapter provided by Hyper-V
#
sed --in-place -e s:"# CONFIG_TULIP is not set":"CONFIG_TULIP=m\nCONFIG_TULIP_MMIO=y": ${CONFIG_FILE}
yes "" | make oldconfig
fi
UpdateSummary "make oldconfig: Success"
#
# Build the kernel
#
dbgprint 1 "Building the kernel."
if [ $proc_count -eq 1 ]; then
(time make) > ${START_DIR}/Perf_BuildKernel_make.log 2>&1
else
(time make -j $proc_count) > ${START_DIR}/Perf_BuildKernel_make.log 2>&1
fi
sts=$?
if [ 0 -ne ${sts} ]; then
dbgprint 1 "Kernel make failed: ${sts}"
dbgprint 1 "Aborting test."
UpdateTestState "TestAborted"
UpdateSummary "make: Failed"
exit 110
else
UpdateSummary "make: Success"
fi
#
# Build the kernel modules
#
dbgprint 1 "Building the kernel modules."
if [ $proc_count -eq 1 ]; then
(time make modules_install) > ${START_DIR}/Perf_BuildKernel_makemodulesinstall.log 2>&1
else
(time make modules_install -j $proc_count) > ${START_DIR}/Perf_BuildKernel_makemodulesinstall.log 2>&1
fi
sts=$?
if [ 0 -ne ${sts} ]; then
dbgprint 1 "Kernel make failed: ${sts}"
dbgprint 1 "Aborting test."
UpdateTestState "TestAborted"
UpdateSummary "make modules_install: Failed"
exit 110
else
UpdateSummary "make modules_install: Success"
fi
#
# Install the kernel
#
dbgprint 1 "Installing the kernel."
if [ $proc_count -eq 1 ]; then
(time make install) > ${START_DIR}/Perf_BuildKernel_makeinstall.log 2>&1
else
(time make install -j $proc_count) > ${START_DIR}/Perf_BuildKernel_makeinstall.log 2>&1
fi
sts=$?
if [ 0 -ne ${sts} ]; then
echo "kernel build failed: ${sts}"
UpdateTestState "TestAborted"
UpdateSummary "make install: Failed"
exit 130
else
UpdateSummary "make install: Success"
fi
#
# Save the current Kernel version for comparision with the version
# of the new kernel after the reboot.
#
cd ${START_DIR}
dbgprint 3 "Saving version number of current kernel in oldKernelVersion.txt"
uname -r > ${START_DIR}/oldKernelVersion.txt
### Grub Modification ###
# Update grub.conf (we only support v1 right now, grub v2 will have to be added
# later)
grubversion=1
if [ -e /boot/grub/grub.conf ]; then
grubfile="/boot/grub/grub.conf"
elif [ -e /boot/grub/menu.lst ]; then
grubfile="/boot/grub/menu.lst"
elif [ -e /boot/grub2/grub.cfg ]; then
grubversion=2
grub2-mkconfig -o /boot/grub2/grub.cfg
grub2-set-default 0
else
echo "grub v1 files does not appear to be installed on this system. it should use grub v2."
# the new kernel is the default one to boot next time
grubversion=2
fi
if [ 1 -eq ${grubversion} ]; then
echo "Update grub v1 files."
new_default_entry_num="0"
# added
sed --in-place=.bak -e "s/^default\([[:space:]]\+\|=\)[[:digit:]]\+/default\1$new_default_entry_num/" $grubfile
# Display grub configuration after our change
echo "Here are the new contents of the grub configuration file:"
cat $grubfile
fi
# edit /etc/rc.local and /etc/rc.d/rc.local to
# make sure ifup_eth automate run script during boot
#
ifup_eth="ifup eth0 > /dev/null"
#write script path to /etc/rc.local
if [[ -f /etc/rc.local ]]
then
sed "/^\s*exit 0/i ${ifup_eth}" /etc/rc.local -i
if ! grep -q "${ifup_eth}" /etc/rc.local
then
echo "Add ${ifup_eth} to /etc/rc.local"
echo $ifup_eth >> /etc/rc.local
fi
chmod +x /etc/rc.local
fi
#write script path to /etc/rc.d/rc.local
if [[ -f /etc/rc.d/rc.local ]]
then
sed "/^\s*exit 0/i ${ifup_eth}" /etc/rc.d/rc.local -i
if ! grep -q "${ifup_eth}" /etc/rc.d/rc.local
then
echo "Add ${ifup_eth} to /etc/rc.d/rc.local"
echo $ifup_eth >> /etc/rc.d/rc.local
fi
chmod +x /etc/rc.d/rc.local
fi
#if distro is SUSE then configure /etc/rc.d/after.local
if [[ -f /etc/SuSE-release ]]
then
echo "INFO: the distro is SUSE. update /etc/rc.d/after.local" >> ~/summary.log
echo $ifup_eth >> /etc/rc.d/after.local
chmod +x /etc/rc.d/after.local
fi
#
# Let the caller know everything worked
#
dbgprint 1 "Exiting with state: TestCompleted."
UpdateTestState "TestCompleted"
exit 0