767 lines
24 KiB
Bash
Executable file
767 lines
24 KiB
Bash
Executable file
#!/bin/bash
|
||
# Copyright 2015-2016 Mir Calculate. http://www.calculate-linux.org
|
||
#
|
||
# 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.
|
||
|
||
TEXTDOMAIN=cl_kernel
|
||
CL_KERNEL_VERSION=0.2.7
|
||
DESCRIPTION=$"Kernel building tool"
|
||
DEFAULT_KERNEL_DIRECTORY="$(readlink -f /usr/src/linux)"
|
||
SRC_DIRECTORY=/usr/src
|
||
LOCAL_TEMPLATES_DIR=/var/calculate/templates/kernel
|
||
TEMPLATES_BACKUP=${LOCAL_TEMPLATES_DIR}/backup
|
||
DEBUG_LOG=/var/log/calculate/cl-kernel.log
|
||
KVER=
|
||
KERNEL_DIR=${DEFAULT_KERNEL_DIRECTORY}
|
||
# создавать базовую конфигурацию ядра
|
||
# create the base kernel configuration
|
||
CREATE_BASE=1
|
||
# создавать текущую конфигурацию ядра
|
||
# create the current kernel configuration
|
||
CREATE_NEW=1
|
||
# собирать ядро после конфигурации
|
||
# compile the kernel once configuration is complete
|
||
BUILD_KERNEL=1
|
||
# обновить MBR запись диска во время установки ядра
|
||
# update the MBR record of the disk during the kernel installation
|
||
UPDATE_MBR=1
|
||
# очистить исходники ядра перед сборкой
|
||
# clean the kernel sources before the compilation
|
||
CLEAN_KERNEL=1
|
||
# запускать изменение конфигурации ядра пользователем
|
||
# execute manual kernel configuration
|
||
MANUAL_CONFIG=1
|
||
# права на файл шаблона
|
||
# template file privileges
|
||
CHMOD=0644
|
||
# наличие dracut в системе
|
||
# dracut present or not in the system
|
||
DRACUT=$(which dracut 2>/dev/null)
|
||
declare -a TAILOUT=()
|
||
|
||
# поддержка настроек ccache
|
||
# support ccache
|
||
source <(cat /etc/portage/make.conf/* | grep CCACHE_DIR)
|
||
export CCACHE_DIR
|
||
if [[ -n $CCACHE_DIR ]]
|
||
then
|
||
export PATH="/usr/lib/ccache/bin:/lib/rc/bin:$PATH"
|
||
else
|
||
export PATH="/lib/rc/bin:$PATH"
|
||
fi
|
||
|
||
# проверить пользователя
|
||
# check user
|
||
if [[ $(id -u) -ne 0 ]]
|
||
then
|
||
eerror $"This program must be run as root"
|
||
exit 1
|
||
fi
|
||
|
||
# прервать скрипт в случае ошибки любой из команд
|
||
# break the script execution in case of a command error
|
||
set -e
|
||
|
||
: >$DEBUG_LOG
|
||
|
||
# вывод короткой справки
|
||
# show the short help message
|
||
usage() {
|
||
echo $"Usage: $0 [OPTION]
|
||
|
||
Version: $CL_KERNEL_VERSION
|
||
|
||
${DESCRIPTION}
|
||
|
||
-h, --help display all options and exit"
|
||
}
|
||
|
||
# вывод полной справки
|
||
# show the long help message
|
||
long_usage() {
|
||
echo $"Usage: $0 [OPTION]
|
||
|
||
Version: $CL_KERNEL_VERSION
|
||
|
||
${DESCRIPTION}
|
||
|
||
--kver [VERSION] specify the kernel version ('list' for displaying possible values)
|
||
--kver-old [VERSION] specify the kernel version for new options ('list' for displaying possible values)
|
||
--convert migrate .config from the kernel directory to templates
|
||
-s, --skip-build do not build the kernel after configuration
|
||
--mbr [ON/OFF] update MBR
|
||
--skip-config do not manual configure the kernel
|
||
--noclean do not clean the kernel sources before the compilation
|
||
--march [ARCH] kernel architecture (x86 or x86_64)
|
||
--safemode create an additional initrd with all modules (only for calculate-sources)
|
||
--help display this help and exit
|
||
"
|
||
}
|
||
|
||
# подготовить параметры командной строки
|
||
# prepare the commmand line parameters
|
||
rearrange_params() {
|
||
set +e
|
||
TEMP=$(unset POSIXLY_CORRECT; getopt \
|
||
-o "hs" \
|
||
--long help \
|
||
--long kver: \
|
||
--long kver-old: \
|
||
--long march: \
|
||
--long convert \
|
||
--long noclean \
|
||
--long skip-build \
|
||
--long mbr: \
|
||
--long skip-config \
|
||
--long safemode \
|
||
-- "$@" 2>&1)
|
||
if (( $? != 0 )); then
|
||
echo "$TEMP" | sed 's/getopt: /cl-kernel: /;$d'
|
||
exit 1
|
||
fi
|
||
set -e
|
||
}
|
||
|
||
# выполнить параметры командной строки
|
||
# apply the command line parameters
|
||
do_args() {
|
||
while :; do
|
||
case $1 in
|
||
-h|--help)
|
||
long_usage
|
||
exit 0
|
||
;;
|
||
--kver)
|
||
KVER="$2"
|
||
shift
|
||
;;
|
||
--kver-old)
|
||
KVER_OLD="$2"
|
||
shift
|
||
;;
|
||
--safemode)
|
||
SAFEMODE=1
|
||
;;
|
||
--march)
|
||
MARCH="$2"
|
||
if [[ ${MARCH} != "x86" ]] && [[ ${MARCH} != "x86_64" ]]
|
||
then
|
||
eerror $"Error in parameter --march. The value may be 'x86' or 'x86_64'"
|
||
fi
|
||
shift
|
||
;;
|
||
--convert)
|
||
MIGRATE=1
|
||
CREATE_NEW=
|
||
;;
|
||
-s|--skip-build)
|
||
BUILD_KERNEL=
|
||
;;
|
||
--mbr)
|
||
UPDATE_MBR="$2"
|
||
if [[ ${UPDATE_MBR} =~ ^[Oo][Nn]$ ]]
|
||
then
|
||
UPDATE_MBR='on'
|
||
elif [[ ${UPDATE_MBR} =~ ^[Oo][Ff][Ff]$ ]]
|
||
then
|
||
UPDATE_MBR='off'
|
||
else
|
||
eerror $"Error in parameter --mbr. The value may be 'on' or 'off'"
|
||
fi
|
||
shift
|
||
;;
|
||
--skip-config)
|
||
MANUAL_CONFIG=
|
||
;;
|
||
--noclean)
|
||
CLEAN_KERNEL=
|
||
;;
|
||
--) shift;break;;
|
||
*) usage;
|
||
eerror $"Unknown option: $1"
|
||
;;
|
||
esac
|
||
shift
|
||
done
|
||
if [[ -n $1 ]]
|
||
then
|
||
usage;
|
||
eerror $"Unknown argument: $1"
|
||
fi
|
||
}
|
||
|
||
# получить значение переменной calculate
|
||
# get the value of variable 'calculate'
|
||
variable_value()
|
||
{
|
||
local varname=$1
|
||
/usr/libexec/calculate/cl-variable --value $varname
|
||
}
|
||
|
||
# оставить только названия параметров + "="
|
||
# keep parameter names only + "="
|
||
options_name() {
|
||
sed -r 's/^# (CON.*) is not set.*$/\1=/' | sed -r 's/^(CON.*=).*/\1/'
|
||
}
|
||
|
||
# преобразовать опции в синтаксис удаления параметра
|
||
# convert the options into parameter removal syntax
|
||
remove_syntax() {
|
||
sed -r 's/^(.*=).*$/!\1/'
|
||
}
|
||
|
||
# преобразовать CONFIG_XXX=n -> # CONFIG_XXX is not set
|
||
# make the conversion # CONFIG_XXX is not set -> CONFIG_XXX=n
|
||
n2not_set() {
|
||
sed -r 's/(CONFIG.*)=n/# \1 is not set/'
|
||
}
|
||
|
||
# получить разницу в конфигурационных файлах
|
||
# get a difference of configuration files
|
||
diff_config() {
|
||
diff -u <(grep CONFIG_ $1 | sort | n2not_set) <(grep CONFIG_ $2 | sort | n2not_set)
|
||
}
|
||
|
||
# получить разницу в параметрах конфигурационных файлов
|
||
# get paramters difference of configuration files
|
||
diff_config_options() {
|
||
diff -u <(cat $1 | options_name | sort) <(cat $2 | options_name | sort)
|
||
}
|
||
|
||
# изменённые параметры
|
||
# changed parameters
|
||
append_options() {
|
||
diff_config $1 $2 | grep -e "^+CON" -e "^+# CON" | sed 's/^.//' | sort
|
||
}
|
||
|
||
|
||
# удаленные параметры
|
||
# removed parameters
|
||
removed_options() {
|
||
diff_config_options $1 $2 | grep -e "^-CON" | sed 's/^.//' | sort
|
||
}
|
||
|
||
|
||
# получить содержимое шаблона
|
||
# get the template contents
|
||
diff_template_body() {
|
||
append_options $1 $2
|
||
removed_options $1 $2 | remove_syntax
|
||
}
|
||
|
||
# вывести заголов для шаблона
|
||
# show the template headers
|
||
# Args:
|
||
# category/package name
|
||
# package version
|
||
diff_template_head() {
|
||
local category_pn=$1
|
||
local pv=$2
|
||
echo "# Calculate format=kernel name=.config os_install_arch_machine==${TEMPLATE_ARCH}&&merge(${category_pn})>=${pv}"
|
||
}
|
||
|
||
# вывести полный шаблон
|
||
# show the full template
|
||
# Args:
|
||
# category/package name
|
||
# package version
|
||
# base configuration file
|
||
# new configuration file
|
||
create_template() {
|
||
local category_pn=$1
|
||
local pv=$2
|
||
local base_config=$3
|
||
local new_config=$4
|
||
diff_template_head ${category_pn} ${pv}
|
||
diff_template_body ${base_config} ${new_config}
|
||
}
|
||
|
||
# получить конфигурацию ядра
|
||
# get the kernel configuration
|
||
# Args:
|
||
# kernel sources directory
|
||
# category/package name
|
||
# package version
|
||
# used templates (locations)
|
||
create_kernel_config() {
|
||
local kernel_dir=$1
|
||
local category_pn=( ${2/\// } )
|
||
local category=${category_pn[0]}
|
||
local pn=${category_pn[1]}
|
||
local pv=$3
|
||
# создать временную директорию для выполнения шаблонов
|
||
# create temporary directory for templates applying
|
||
local tempdir=$(${MKTEMP} -d)
|
||
[[ -n $4 ]] && local templates="-T $4"
|
||
# получить конфигурацию ядра по умолчанию, нужной архитектуры
|
||
# get default kernel configuration for architecture
|
||
local temp_config=".config_clkernel_${ARCH}"
|
||
(cd ${kernel_dir};ARCH=$MARCH KCONFIG_CONFIG=${temp_config} make defconfig;mv ${temp_config} ${tempdir}/.config) &>>$DEBUG_LOG ||
|
||
eerror $"Failed to create the default kernel config"
|
||
# получить тип системы
|
||
if [[ "$(variable_value main.os_linux_system)" == "desktop" ]]
|
||
then
|
||
USEVALUE=desktop
|
||
else
|
||
USEVALUE=-desktop
|
||
fi
|
||
|
||
# выполнить шаблоны (патчи)
|
||
# apply templates (patches)
|
||
USE="$USEVALUE" /usr/sbin/cl-core --method core_patch --march=$TEMPLATE_ARCH --pkg-name ${pn} --pkg-category ${category} --pkg-version=${pv} --pkg-slot=${pv} --pkg-path=$tempdir $templates &>>$DEBUG_LOG || eerror $"Failed to apply kernel templates"
|
||
# вывести содержимое файла конфигурации ядра
|
||
# display content of kernel configuration file
|
||
cat $tempdir/.config || eerror $"Kernel configuration file not found"
|
||
rm -rf $tempdir &>>$DEBUG_LOG
|
||
}
|
||
|
||
# проверить, содержит ли каталог полный исходный код ядра
|
||
# check if the directory contains the full kernel sources
|
||
check_kernel_sources() {
|
||
local sources_dir=$1
|
||
[[ -f ${sources_dir}/arch/x86/configs/i386_defconfig ]]
|
||
}
|
||
|
||
# версия исходного кода ядра
|
||
# kernel sources version
|
||
sources_ver() {
|
||
basename "$(readlink -f $1)" | sed 's/linux-//' || true
|
||
}
|
||
|
||
# текущее ядро
|
||
# current_kernel
|
||
current_kernel() {
|
||
sources_ver /usr/src/linux
|
||
}
|
||
|
||
# вывести список версий ядер с полным исходным кодом
|
||
# list all kernels with full sources available
|
||
list_kernel() {
|
||
local asterisk=$(echo -e "\033[1m*\033[0m")
|
||
local green_asterisk=$(echo -e "\033[1;32m*\033[0m")
|
||
local red_asterisk=$(echo -e "\033[1;31m*\033[0m")
|
||
local curver=$1
|
||
for f in $(ls -drv /usr/src/linux-[[:digit:]]*); do
|
||
local ver=$(sources_ver "${f}")
|
||
[[ $ver == $curver ]] && mark=$asterisk || mark=
|
||
check_kernel_sources $f && echo " ${green_asterisk}" $ver $mark || echo " ${red_asterisk}" $ver $mark
|
||
done
|
||
}
|
||
|
||
# вывести сообщение и добавить его в список выводимых после сборки ядра сообщений
|
||
# show the message and add it to the list of messages to be displayed after compilation
|
||
einfo_tail() {
|
||
einfo $*
|
||
TAILOUT+=( "$*" )
|
||
}
|
||
|
||
# получить содержимое текущего конфига
|
||
# get the content of current kernel configuration
|
||
# .config into kernel sources directory
|
||
# /boot/config-
|
||
# /proc/config.gz
|
||
get_old_config() {
|
||
local source_config="${KERNEL_DIR}/.config"
|
||
local boot_config="/boot/config-$(uname -r)"
|
||
local proc_config="/proc/config.gz"
|
||
if [[ -f $source_config ]]
|
||
then
|
||
config=$source_config
|
||
elif [[ -f $boot_config ]]
|
||
then
|
||
config=$boot_config
|
||
cp $config $NEW_CONFIG
|
||
elif [[ -f $proc_config ]]
|
||
then
|
||
config=$proc_config
|
||
zcat $proc_config >$NEW_CONFIG
|
||
fi
|
||
if [[ -n $config ]]
|
||
then
|
||
einfo $"Will be used $config kernel configuration"
|
||
else
|
||
eerror $"Failed to get current kernel configuration"
|
||
fi
|
||
}
|
||
|
||
# qfile hack
|
||
_qfile() {
|
||
(cd /; qfile $*)
|
||
}
|
||
|
||
qfile_pkgname() {
|
||
_qfile $* | sed -r 's/:? .*$//;'
|
||
}
|
||
|
||
# проверить принадлежит ли директория только одному пакету
|
||
# check that the directory belongs to only one package
|
||
check_belong() {
|
||
local fn=$1
|
||
local linenum=$(_qfile -C $fn | wc -l)
|
||
if [[ $linenum -lt 1 ]]
|
||
then
|
||
eerror $"${fn} does not belong to any package"
|
||
elif [[ $linenum -gt 1 ]]
|
||
then
|
||
eerror $"${fn} belongs to multiple packages"
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
real_kernel_version() {
|
||
local kdir=$1
|
||
file $kdir/arch/x86/boot/bzImage | sed -r 's/.*version\s(\S+)\s.*/\1/'
|
||
}
|
||
|
||
######################
|
||
# Обработать параметры
|
||
# Process the options
|
||
######################
|
||
rearrange_params "$@"
|
||
eval set -- "$TEMP"
|
||
do_args "$@"
|
||
|
||
########################
|
||
# Подготовить переменные
|
||
# Prepare variables
|
||
########################
|
||
[[ "$(variable_value main.cl_chroot_status)" == "off" ]] && NOT_CHROOT=1
|
||
|
||
# вычислить архитектуру
|
||
# detect the architecture
|
||
[[ -z $MARCH ]] && MARCH=$(/usr/bin/arch)
|
||
if [[ "$MARCH" == "x86" ]] || [[ "$MARCH" == "i686" ]]
|
||
then
|
||
# архитектура для конфигурации по умолчанию
|
||
# default configuration architecture
|
||
MARCH=i386
|
||
# templates architecture
|
||
# архитектура для шаблонов
|
||
TEMPLATE_ARCH=i686
|
||
# название архитектуры
|
||
# architecture name
|
||
NAME_ARCH=x86
|
||
else
|
||
TEMPLATE_ARCH=$MARCH
|
||
NAME_ARCH=$MARCH
|
||
fi
|
||
|
||
# подготовить имя для шаблона очистить старые временные данные
|
||
# prepare the template name; clear old temporary data
|
||
TMP_TEMPLATE=/tmp/cl_kernel_${MARCH}
|
||
MKTEMP="/usr/bin/mktemp ${TMP_TEMPLATE}.XXXXXX"
|
||
rm -rf ${TMP_TEMPLATE}*
|
||
|
||
# пропустить сборку ядра если выбранная архитектура и архитектура машины отличаются
|
||
# skip the kernel compilation if selected architecture is different from machine architecture
|
||
if [[ $TEMPLATE_ARCH != $(/usr/bin/arch) ]]
|
||
then
|
||
OTHER_ARCH=1
|
||
BUILD_KERNEL=
|
||
fi
|
||
|
||
# вывести список доступных ядер
|
||
# list avaiable kernels
|
||
if [[ $KVER == "list" ]] || [[ $KVER_OLD == "list" ]]
|
||
then
|
||
list_kernel $(current_kernel)
|
||
exit 0
|
||
fi
|
||
|
||
# получить директорию ядра по версии
|
||
# get the kernel directory by version
|
||
if [[ -n $KVER ]]
|
||
then
|
||
KERNEL_DIR=${SRC_DIRECTORY}/linux-${KVER}
|
||
fi
|
||
if [[ -n $KVER_OLD ]]
|
||
then
|
||
KERNEL_OLD_DIR=${SRC_DIRECTORY}/linux-${KVER_OLD}
|
||
fi
|
||
# проверить правильность исходников
|
||
# check the integrity of the sources
|
||
for check_dir in ${KERNEL_DIR} ${KERNEL_OLD_DIR}
|
||
do
|
||
[[ -d ${check_dir} ]] || eerror $"Kernel directory ${check_dir} not found"
|
||
check_kernel_sources ${check_dir} || eerror $"Kernel directory ${check_dir} has no full sources"
|
||
done
|
||
|
||
# получить версию из директории ядра
|
||
# get the version from the kernel directory
|
||
if [[ -z $KVER ]]
|
||
then
|
||
KVER=$(sources_ver $KERNEL_DIR)
|
||
fi
|
||
|
||
# проверка доступности safemode
|
||
# check if safemode is available
|
||
if [[ -n $SAFEMODE ]] && [[ -z $NOT_CHROOT ]]
|
||
then
|
||
eerror $"--safemode unavailable for chroot"
|
||
fi
|
||
|
||
if [[ -n $SAFEMODE ]] && ! [[ $KVER =~ -calculate ]]
|
||
then
|
||
eerror $"--safemode available for calculate-sources only"
|
||
fi
|
||
|
||
if [[ -n $SAFEMODE ]] && [[ -z $DRACUT ]]
|
||
then
|
||
eerror $"--safemode unavailable without dracut"
|
||
fi
|
||
|
||
# создать каталог в локальных шаблонах для шаблонов ядра
|
||
# create the directory for kernel templates in the local tempalte tree
|
||
if ! [[ -d $LOCAL_TEMPLATES_DIR ]]
|
||
then
|
||
(mkdir -p $LOCAL_TEMPLATES_DIR ;
|
||
echo "# Calculate env=install ac_install_patch==on append=skip" >${LOCAL_TEMPLATES_DIR}/.calculate_directory) ||
|
||
eerror $"Failed to create the kernel template directory"
|
||
fi
|
||
|
||
# если другая архитектура
|
||
# if other architecture
|
||
if [[ -n $OTHER_ARCH ]]
|
||
then
|
||
NEW_CONFIG=${KERNEL_DIR}/.config_${TEMPLATE_ARCH}
|
||
else
|
||
NEW_CONFIG=${KERNEL_DIR}/.config
|
||
fi
|
||
|
||
check_belong ${KERNEL_DIR}/Makefile
|
||
# получение параметров пакета, которому принадлежат исходники
|
||
# getting the parameters for the package whose sources are being processed
|
||
CATEGORY_PN=$( qfile_pkgname -C ${KERNEL_DIR}/Makefile )
|
||
PV=$( qfile_pkgname -Cv ${KERNEL_DIR}/Makefile )
|
||
PV=${PV/$CATEGORY_PN-/}
|
||
|
||
if [[ -n $KERNEL_OLD_DIR ]]
|
||
then
|
||
check_belong ${KERNEL_OLD_DIR}/Makefile
|
||
CATEGORY_PN_OLD=$( qfile_pkgname -C ${KERNEL_OLD_DIR}/Makefile )
|
||
PV_OLD=$( qfile_pkgname -Cv ${KERNEL_OLD_DIR}/Makefile )
|
||
PV_OLD=${PV_OLD/${CATEGORY_PN_OLD}-/}
|
||
fi
|
||
|
||
# получить версии MAJOR.MINOR для условий в шаблонах
|
||
# get the version (MAJOR.MINOR format) for conditions in templates
|
||
[[ $KVER =~ ^([[:digit:]]+\.[[:digit:]]+) ]] && PV2=${BASH_REMATCH[0]} || PV2=$PV
|
||
|
||
# определение имени шаблонов для пакета
|
||
# define templates name for the package
|
||
if [[ $CATEGORY_PN =~ ^.*/(.*)-sources ]]
|
||
then
|
||
TEMPLATE_NAME_PREFIX=10-${BASH_REMATCH[1]}-
|
||
else
|
||
TEMPLATE_NAME_PREFIX=10-config-
|
||
fi
|
||
TEMPLATE_NAME_ARCH_PREFIX=${TEMPLATE_NAME_PREFIX}${NAME_ARCH}-
|
||
TEMPLATE_NAME="${LOCAL_TEMPLATES_DIR}/${TEMPLATE_NAME_ARCH_PREFIX}${PV2}"
|
||
|
||
########################################
|
||
# Подготовка новой конфигурации ядра
|
||
# Preparing the new kernel configuration
|
||
########################################
|
||
|
||
CONFIG_GZ=/proc/config.gz
|
||
|
||
if [[ -n $CREATE_NEW ]]
|
||
then
|
||
ebegin $"Preparing the current kernel configuration"
|
||
create_kernel_config ${KERNEL_OLD_DIR:-${KERNEL_DIR}} \
|
||
${CATEGORY_PN_OLD:-${CATEGORY_PN}} \
|
||
${PV_OLD:-${PV}} >$NEW_CONFIG
|
||
eend
|
||
else
|
||
if [[ -n $OTHER_ARCH ]]
|
||
then
|
||
eerror $"--convert is uncompatible with --march"
|
||
fi
|
||
if [[ -n $KVER_OLD ]]
|
||
then
|
||
eerror $"--convert is uncompatible with --kver-old"
|
||
fi
|
||
get_old_config
|
||
fi
|
||
|
||
#########################################
|
||
# Подготовка базовой конфигурации ядра
|
||
# Preparing the base kernel configuration
|
||
#########################################
|
||
BASE_CONFIG=$( ${MKTEMP} )
|
||
|
||
ebegin $"Preparing the basic kernel configuration"
|
||
if [[ -n $CREATE_BASE ]]
|
||
then
|
||
# будут использоваться только шаблоны оверлеев
|
||
# will be used the overlay templates only
|
||
TEMPLATES=$(variable_value main.cl_template_location)
|
||
create_kernel_config ${KERNEL_DIR} ${CATEGORY_PN} ${PV} ${TEMPLATES/,local,remote/} >$BASE_CONFIG
|
||
else
|
||
cp $NEW_CONFIG $BASE_CONFIG
|
||
fi
|
||
eend
|
||
|
||
###########################################
|
||
# Изменение конфигурации ядра пользователем
|
||
# Manual kernel configuration
|
||
###########################################
|
||
if [[ -n $MANUAL_CONFIG ]]
|
||
then
|
||
(cd $KERNEL_DIR; [[ -n ${KERNEL_OLD_DIR} || -z ${CREATE_NEW} ]] && KCONFIG_CONFIG=$(basename $NEW_CONFIG) make oldconfig;KCONFIG_CONFIG=$(basename $NEW_CONFIG) make -s menuconfig) || true
|
||
fi
|
||
|
||
###########################
|
||
# Создание шаблона
|
||
# Template creation
|
||
###########################
|
||
NEW_TEMPLATE=$( ${MKTEMP} )
|
||
create_template $CATEGORY_PN $PV2 $BASE_CONFIG $NEW_CONFIG >${NEW_TEMPLATE}
|
||
|
||
##################################
|
||
# Создание резервной копии шаблона
|
||
# Template backup
|
||
##################################
|
||
if ls ${LOCAL_TEMPLATES_DIR}/${TEMPLATE_NAME_ARCH_PREFIX}* &>/dev/null
|
||
then
|
||
for i in ${LOCAL_TEMPLATES_DIR}/${TEMPLATE_NAME_ARCH_PREFIX}*
|
||
do
|
||
if diff -u $i $NEW_TEMPLATE &>/dev/null
|
||
then
|
||
einfo_tail $"The kernel configuration has not changed"
|
||
rm $i
|
||
SKIP_CREATE_INFO=1
|
||
else
|
||
newname="$(basename $i)-$(date +%Y%m%d_%H%M -r $i)"
|
||
einfo_tail $"Backing up the template" "$(basename $i) -> ${newname}"
|
||
if ! [[ -d ${TEMPLATES_BACKUP} ]]
|
||
then
|
||
(mkdir -p ${TEMPLATES_BACKUP} &&
|
||
echo "# Calculate cl_action==skip" >${TEMPLATES_BACKUP}/.calculate_directory) || eerror $"Failed to create a backup directory"
|
||
fi
|
||
mv $i ${TEMPLATES_BACKUP}/${newname}
|
||
fi
|
||
done
|
||
fi
|
||
|
||
# пропуск создания пустого шаблона
|
||
# skip the empty template
|
||
if [[ $(sed 1d $NEW_TEMPLATE | wc -l) -gt 0 ]]
|
||
then
|
||
mv $NEW_TEMPLATE $TEMPLATE_NAME
|
||
chmod ${CHMOD} $TEMPLATE_NAME
|
||
if [[ -z $SKIP_CREATE_INFO ]]
|
||
then
|
||
einfo_tail $"Creating the template" "$(basename $TEMPLATE_NAME)"
|
||
fi
|
||
else
|
||
einfo_tail $"Skipping the empty template"
|
||
fi
|
||
|
||
rm -f $BASE_CONFIG
|
||
|
||
STARTTIME=$(date +%s)
|
||
|
||
####################
|
||
# Сборка ядра
|
||
# Kernel compilation
|
||
####################
|
||
if [[ -n ${BUILD_KERNEL} ]]
|
||
then
|
||
cd $KERNEL_DIR
|
||
(
|
||
MAKEOPTS=$(variable_value install.os_install_makeopts)
|
||
echo -- $MAKEOPTS
|
||
set -e
|
||
if [[ -n ${CLEAN_KERNEL} ]]
|
||
then
|
||
make clean || eerror $"Failed to clean the kernel sources" || exit 1
|
||
fi
|
||
make $MAKEOPTS || eerror $"Failed to compile the kernel" || exit 1
|
||
make $MAKEOPTS modules_install || eerror $"Failed to compile the kernel modules" || exit 1
|
||
make $MAKEOPTS install || eerror $"Failed to install the kernel" || exit 1
|
||
) || eerror $"Failed to build kernel"
|
||
# использовать сжатие если поддерживается ядром (zstd,gzip,xz)
|
||
if grep -q "CONFIG_RD_ZSTD=y" ${NEW_CONFIG}
|
||
then
|
||
COMPRESS=--zstd
|
||
elif grep -q "CONFIG_RD_GZIP=y" ${NEW_CONFIG}
|
||
then
|
||
COMPRESS=--gzip
|
||
elif grep -q "CONFIG_RD_XZ=y" ${NEW_CONFIG}
|
||
then
|
||
COMPRESS=--xz
|
||
fi
|
||
# сборка initramfs
|
||
# initramfs building
|
||
VMLINUZ_VER=$(real_kernel_version $KERNEL_DIR)
|
||
if [[ -n $DRACUT ]] && grep -q "CONFIG_BLK_DEV_INITRD=y" ${NEW_CONFIG}
|
||
then
|
||
${DRACUT} -f${NOT_CHROOT:+H} $COMPRESS --kver=$VMLINUZ_VER /boot/initramfs-${VMLINUZ_VER}.img || eerror $"Failed to create the host-only initramfs"
|
||
if [[ $KVER =~ calculate ]] && [[ -n $SAFEMODE ]]
|
||
then
|
||
${DRACUT} -f $COMPRESS --kver=$VMLINUZ_VER /boot/initramfs-${VMLINUZ_VER/-calculate/-SafeMode-calculate}.img || eerror $"Failed to create the safemode initramfs"
|
||
fi
|
||
else
|
||
# удалить старый ramfs если его поддержка выключена в ядре
|
||
# remove the old ramfs if its support disabled in the kernel configuration
|
||
rm -f /boot/initramfs-${VMLINUZ_VER}.img /boot/initramfs-${VMLINUZ_VER/-calculate/-SafeMode-calculate}.img
|
||
fi
|
||
|
||
# выполнение шаблонов для настройки загрузки системы
|
||
# applying the templates for boot configuration
|
||
if [[ -n $NOT_CHROOT ]]
|
||
then
|
||
mbr_set=
|
||
if [[ $UPDATE_MBR == 'off' ]]
|
||
then
|
||
mbr_set=' --mbr none'
|
||
fi
|
||
cl-setup-boot $mbr_set
|
||
fi
|
||
|
||
# вывод времени компиляции ядра
|
||
# display kernel compilation time
|
||
DELTATIME=$(( $(date +%s) - $STARTTIME ))
|
||
HOUR=$(( $DELTATIME / 3600 ))
|
||
DELTATIME=$(( $DELTATIME % 3600 ))
|
||
MIN=$(( $DELTATIME / 60 ))
|
||
SEC=$(( $DELTATIME % 60 ))
|
||
|
||
echo -en " \033[1;32m*\033[0m "
|
||
echo -n $"Kernel build time: "
|
||
if [[ ${HOUR} -gt 0 ]]
|
||
then
|
||
printf $"%d hour %d min %d sec\n" ${HOUR} ${MIN} ${SEC}
|
||
else
|
||
printf $"%d min %d sec\n" ${MIN} ${SEC}
|
||
fi
|
||
|
||
# вывод информационных сообщений, отображённых до сборки ядра
|
||
# display info messages, show before kernel compilation
|
||
for line in "${TAILOUT[@]}"
|
||
do
|
||
einfo $line
|
||
done
|
||
|
||
# rebuild kernel modules if kernel directory is /usr/src/linux
|
||
if [[ "$(readlink -f ${DEFAULT_KERNEL_DIRECTORY})" == "$(readlink -f $KERNEL_DIR)" ]]
|
||
then
|
||
ewarn $"To rebuild kernel modules packages, please run:"
|
||
ewarn ""
|
||
ewarn " emerge -a @module-rebuild"
|
||
fi
|
||
|
||
fi
|
||
|
||
einfo $"All done!"
|