1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
|
#!/bin/bash
# Author: Steven Shiau <steven _at_ clonezilla org>, Ceasar Sun <ceasar _at_ nchc org tw>
# License: GPL
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Load DRBL setting and functions
# Setting
# Source function library.
[ -f /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions
# Source DRBL setting
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
#
USAGE() {
echo "Usage: $0 [OPTION]"
echo "OPTION"
language_help_prompt_by_idx_no
echo "-k, --client-kernel-pkg KERNEL_PKG: specify the KERNEL_PKG (rpm or deb) which you want DRBL client to use."
echo "-s, --client-kernel-ver-from-server KERNEL_VER: use the kernel version KERNEL_VER from server, i.e. from /boot/vmlinuz-KERNEL_VER and /usr/lib/modules/KERNEL_VER..."
echo "-c, --just-cp-files: just install files for client, do not create kernel tag for client and do not run some script. Usually this option is useed to install linux-restricted-modules in ubuntu."
echo "-v, --verbose: prints verbose information"
}
# default settings
just_cp_files="no"
depmod_stderr="/dev/null"
# Parse command-line options
while [ $# -gt 0 ]; do
case "$1" in
-l|--language)
shift
if [ -z "$(echo $1 |grep ^-.)" ]; then
# skip the -xx option, in case
specified_lang="$1"
shift
fi
;;
-k|--client-kernel-pkg)
shift
if [ -z "$(echo $1 |grep ^-.)" ]; then
# skip the -xx option, in case
client_kernel_pkg="$1"
shift
fi
;;
-s|--client-kernel-ver-from-server)
shift
if [ -z "$(echo $1 |grep ^-.)" ]; then
# skip the -xx option, in case
client_kernel_ver_from_server="$1"
shift
fi
;;
-c|--just-cp-files)
shift; just_cp_files="yes"
;;
-v|--verbose)
verbose="on"
shift;;
-*) echo "${0}: ${1}: invalid option" >&2
USAGE >& 2
exit 2 ;;
*) break ;;
esac
done
#
check_if_root
#
ask_and_load_lang_set $specified_lang
#
if [ "$verbose" = "on" ]; then
# The default output for depmod is surpressed, now turn it on
depmod_stderr="/dev/stderr"
fi
# parse the input kernel package
if [ -n "$client_kernel_pkg" ]; then
if [ -n "$(file -Ls $client_kernel_pkg | grep -i RPM)" ]; then
mode="rpm"
elif [ -n "$(file -Ls $client_kernel_pkg | grep -i "Debian binary package")" ]; then
mode="deb"
fi
elif [ -n "$client_kernel_ver_from_server" -a \
-f /boot/vmlinuz-$client_kernel_ver_from_server -a \
-d /usr/lib/modules/$client_kernel_ver_from_server ]; then
mode="local"
client_kernel_ver="$client_kernel_ver_from_server"
else
[ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
echo "You must provide the kernel package (rpm or deb) or the kernel in the server"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
USAGE
exit 1
fi
case "$mode" in
rpm)
client_kernel_ver="$(rpm -qpl $client_kernel_pkg | grep -E "^/boot/vmlinuz-" | sed -e "s|/boot/vmlinuz-||g")"
if [ -z "$client_kernel_ver" ]; then
# For OpenSuSE 11.1, kernel-default or kernel-pae, there is no vmlinuz-* file, try another method, i.e. use the path:
# /usr/lib/modules/2.6.27.7-9-default/...
client_kernel_ver="$(rpm -qpl $client_kernel_pkg | grep -E "/usr/lib/modules/[[:print:]]+" | awk -F" " '{print $NF}' | awk -F"/" '/\/usr\/lib\/modules/ {print $4}' | sort | uniq)"
fi
# we might need /tftpboot/node_root/var/lock/rpm/ for locking in some dist (like CentOS 4.4).
mkdir -p $drbl_common_root/var/lock/rpm/
echo "Installing $client_kernel_pkg for clients... "
echo "$msg_install_kernel_might_take_several_minutes "
# We do not care about those files put into $drbl_common_root/usr/
rpm -ivh --root $drbl_common_root/ --force --nodeps --noscripts $client_kernel_pkg
rc=$?
echo "$msg_done!"
;;
deb)
client_kernel_ver="$(dpkg --contents $client_kernel_pkg | awk -F" " '{print $NF}' | grep -E "./boot/vmlinuz-" | sed -e "s|\./boot/vmlinuz-||g")"
if [ -z "$client_kernel_ver" ]; then
# For deb linux-ubuntu-modules-* or linux-restricted-modules-*, there is no vmlinuz-* file, try another method, i.e. use the path:
# ./usr/lib/modules/2.6.22-14-386/...
client_kernel_ver="$(dpkg --contents $client_kernel_pkg | grep -E "/usr/lib/modules/[[:print:]]+" | awk -F" " '{print $NF}' | awk -F"/" '/\.\/usr\/lib\/modules/ {print $4}' | sort | uniq)"
fi
echo "Installing $client_kernel_pkg for clients... "
echo "$msg_install_kernel_might_take_several_minutes "
# Check if "^./lib/modules/" exists. If so, it's old format (Debian <= 12)
cvrt_flag="no"
if [ -n "$(dpkg -c $client_kernel_pkg | awk '{print $NF}' | grep -Ew "^\.\/lib\/modules\/")" ]; then
cvrt_flag="yes"
fi
dpkg-deb --extract $client_kernel_pkg $drbl_common_root
rc=$?
# 2025/Sep/21
# "dpkg-deb --extract" command will overwrite the linked file $drbl_common_root/lib file even when it already exists.
# For Debian <= 12, linux-image will have files under /lib/modules/, e.g.:
# linux-image-6.1.0-39-amd64:
# /lib/modules/6.1.0-39-amd64/kernel/arch/x86/crypto/aegis128-aesni.ko
# /lib/modules/6.1.0-39-amd64/kernel/arch/x86/crypto/aesni-intel.ko
# /lib/modules/6.1.0-39-amd64/kernel/arch/x86/crypto/blowfish-x86_64.ko
# While for newer Debian/Ubuntu, they are like:
# linux-image-6.12.38+deb13-amd64:
# /usr/lib/modules/6.12.38+deb13-amd64/kernel/arch/x86/crypto/aegis128-aesni.ko.xz
# /usr/lib/modules/6.12.38+deb13-amd64/kernel/arch/x86/crypto/aesni-intel.ko.xz
# /usr/lib/modules/6.12.38+deb13-amd64/kernel/arch/x86/crypto/blowfish-x86_64.ko.xz
# Hence
# If $drbl_common_root/lib is a dir, not linked file, and if dir $drbl_common_root/lib/modules/ exists
# linux-image is still in the old path /lib/modules/*
# We move $drbl_common_root/lib/moduels to drbl_common_root/usr/lib/modules/, remove linked file $drbl_common_root/lib
# and create a link file $drbl_common_root/lib to drbl_common_root/usr/lib
if [ "$cvrt_flag" = "yes" ]; then
if [ -d "$drbl_common_root/lib" ]; then
if [ -d "$drbl_common_root/lib/modules" ]; then
echo -n "Converting the old path of kernel modules $drbl_common_root/lib to $drbl_common_root/usr/lib "
mkdir -p $drbl_common_root/usr/lib/modules/ # in case modules dir does not exist.
mv $drbl_common_root/lib/modules/* $drbl_common_root/usr/lib/modules/
fi
rmdir $drbl_common_root/lib/modules/ $drbl_common_root/lib/
(cd $drbl_common_root; ln -fs usr/lib lib)
fi
fi
echo "$msg_done!"
;;
"local")
echo "Installing kernel $client_kernel_ver for clients... "
echo -n "$msg_install_kernel_might_take_several_minutes"
echo -n "."
mkdir -p $drbl_common_root/boot/ $drbl_common_root/usr/lib/modules/
echo -n "."
rsync -a /boot/*$client_kernel_ver $drbl_common_root/boot/
echo -n "."
rsync -a /usr/lib/modules/$client_kernel_ver $drbl_common_root/usr/lib/modules/
echo "$msg_done!"
rc=0
;;
esac
if [ "$rc" -eq 1 ]; then
[ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
echo "Failed to install the kernel $client_kernel_pkg!"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
exit 1
fi
if [ ! "$just_cp_files" = "yes" ]; then
# For FC 22 or later, rpm -ivh doesn't put /boot/System.map-$client_kernel_ver with --noscripts
# Therefore we copy vmlinuz, System.map-$client_kernel_ver, config-$client_kernel_ver
# This is only required for Fedora rpm. Ubuntu's linux-modules deb contains System.map-$client_kernel_ver
if [ ! -e "$drbl_common_root/boot/System.map-$client_kernel_ver" -a \
-n "$(ls $client_kernel_pkg | grep -iE "^.*.rpm")" ]; then
KRC=0
echo "Preparing client's /boot/System.map-$client_kernel_ver..."
_ksystem_map_realpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E 'System.map' | grep -vE '^/boot/')"
_ksystem_map_bootpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E '^/boot/System.map' )"
if [ -e "$drbl_common_root/$_ksystem_map_realpath" \
-a "$_ksystem_map_bootpath" = "/boot/System.map-$client_kernel_ver" ]
then
cp -a $drbl_common_root/$_ksystem_map_realpath $drbl_common_root/$_ksystem_map_bootpath
else
KRC=1
fi
echo "Preparing client's /boot/vmlinuz-$client_kernel_ver..."
_kvmlinuz_realpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E 'vmlinuz$' | grep -vE '^/boot/')"
_kvmlinuz_bootpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E '^/boot/vmlinuz' )"
if [ -e "$drbl_common_root/$_kvmlinuz_realpath" \
-a "$_kvmlinuz_bootpath" = "/boot/vmlinuz-$client_kernel_ver" ]
then
cp -a $drbl_common_root/$_kvmlinuz_realpath $drbl_common_root/$_kvmlinuz_bootpath
else
KRC=1
fi
echo "Preparing client's /boot/config-$client_kernel_ver ..."
_kconfig_realpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E 'config$' | grep -vE '^/boot/')"
_kconfig_bootpath="$(LC_ALL=C rpm -qpl $client_kernel_pkg | grep -E '^/boot/config' )"
if [ -e "$drbl_common_root/$_kconfig_realpath" \
-a "$_kconfig_bootpath" = "/boot/config-$client_kernel_ver" ]
then
cp -a $drbl_common_root/$_kconfig_realpath $drbl_common_root/$_kconfig_bootpath
else
KRC=1
fi
# Output error messages about failing to prepare kernel for clients.
if [ "$KRC" -ne 0 ]; then
[ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
echo "Failed to prepare Linux kernel for DRBL clients in RedHat-like environment."
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo "$msg_program_stop!"
exit 1
fi
fi
# Need to create the files
# $pxecfg_pd/kernel_version_in_initrd.txt
# $pxecfg_pd/client_kernel_arch.txt
# Only when we can find something like /tftpboot/node_root/boot/System.map-2.6.27.39-0.2-default we can find KARCH.
if [ -e "$drbl_common_root/boot/System.map-$client_kernel_ver" ]; then
# make a tag in the system for client's kernel arch.
KARCH="$(LC_ALL=C drbl-check-kernel-cpu-arch --drbl-client $client_kernel_ver)"
if [ -z "$KARCH" ]; then
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "Client CPU arch NOT found! The $pxecfg_pd/client_kernel_arch.txt will be empty!"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo -n "$msg_press_enter_to_continue"
read
fi
mkdir -p $pxecfg_pd/
echo "$KARCH" > $pxecfg_pd/client_kernel_arch.txt
fi
# UGLY... find a better to strip the tail for MDK kernel
# for MDK kernel-2.6.8.1.24mdk-1-1mdk, however the kernel tag is 2.6.8.1-24mdk
# we need to strip the -1-1mdk
client_kernel_ver="$(echo $client_kernel_ver | sed -e "s/-1-1mdk//g")"
fi
# create modules.dep...
# we still neeed to build $drbl_common_root/boot/System.map-$client_kernel_ver for client if kernel is installed from package
if [ "$mode" != "local" ]; then
if [ -e "$drbl_common_root/boot/System.map-$client_kernel_ver" ]; then
echo -n "Generating modules.dep and map files for clients... "
depmod -ae -b $drbl_common_root/ -F $drbl_common_root/boot/System.map-$client_kernel_ver $client_kernel_ver 2> $depmod_stderr
echo "done!"
else
echo "$drbl_common_root/boot/System.map-$client_kernel_ver NOT found! Assume it's in another kernel package."
fi
fi
# we stop here for kernel extra/module package
[ "$just_cp_files" = "yes" ] && exit 0
# Firmwares. For Ubuntu, the firmwares come with kernel package, however, it's not true for other distributions. We can only try to use that from server
if [ -d "/usr/lib/firmware" ]; then
echo "Preparing the kernel firmware for clients..."
rsync -a /usr/lib/firmware $drbl_common_root/usr/lib/
fi
exit 0
|