Created
January 15, 2017 14:05
-
-
Save ferdinandkeil/827212e9d897bd6e5db71bb1aef2c708 to your computer and use it in GitHub Desktop.
/usr/share/initramfs-tools/hook-functions for read-only fs on Raspbian
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- shell-script -*- | |
catenate_cpiogz() { | |
# Sanity check | |
if [ ! -e "${1}" ]; then | |
echo "W: catenate_cpiogz: arg1='${1}' does not exist." >&2 | |
return | |
fi | |
cat "${1}" >>"${__TMPCPIOGZ}" | |
} | |
prepend_earlyinitramfs() { | |
# Sanity check | |
if [ ! -e "${1}" ]; then | |
echo "W: prepend_earlyinitramfs: arg1='${1}' does not exist." >&2 | |
return | |
fi | |
cat "${1}" >>"${__TMPEARLYCPIO}" | |
} | |
# force_load module [args...] | |
force_load() | |
{ | |
manual_add_modules "$1" | |
echo "${@}" >>"${DESTDIR}/conf/modules" | |
} | |
# Takes a file containing a list of modules to be added as an | |
# argument, figures out dependancies, and adds them. | |
# | |
# Input file syntax: | |
# | |
# # comment | |
# modprobe_module_name [args ...] | |
# [...] | |
# | |
add_modules_from_file() | |
{ | |
# Sanity check | |
if [ ! -e "${1}" ]; then | |
echo "W: add_modules_from_file: arg1='${1}' does not exist." >&2 | |
return | |
fi | |
grep '^[^#]' ${1} | while read module args; do | |
[ -n "$module" ] || continue | |
force_load "${module}" "${args}" | |
done | |
} | |
# Add dependent modules + eventual firmware | |
manual_add_modules() | |
{ | |
local prefix kmod options firmware | |
if [ $# -eq 0 ]; then | |
return | |
fi | |
modprobe --all --set-version="${version}" --ignore-install --quiet --show-depends "$@" | | |
while read prefix kmod options ; do | |
if [ "${prefix}" != "insmod" ]; then | |
continue | |
fi | |
# Prune duplicates | |
if [ -e "${DESTDIR}/${kmod}" ]; then | |
continue | |
fi | |
install -Dpm 644 "$kmod" "${DESTDIR}/$kmod" | |
if [ "${verbose}" = "y" ]; then | |
echo "Adding module ${kmod}" | |
fi | |
# Add required firmware | |
for firmware in $(modinfo -k "${version}" -F firmware "${kmod}"); do | |
if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \ | |
|| [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then | |
continue | |
fi | |
# Only print warning for missing fw of loaded module | |
# or forced loaded module | |
if [ ! -e "/lib/firmware/${firmware}" ] \ | |
&& [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then | |
# Only warn about missing firmware if | |
# /proc/modules exists | |
if [ ! -e /proc/modules ] ; then | |
continue | |
fi | |
kmod_modname="${kmod##*/}" | |
kmod_modname="${kmod_modname%.ko}" | |
if grep -q "^$kmod_modname\\>" /proc/modules "${CONFDIR}/modules"; then | |
echo "W: Possible missing firmware /lib/firmware/${firmware} for module $(basename ${kmod} .ko)" >&2 | |
fi | |
continue | |
fi | |
if [ -e "/lib/firmware/${version}/${firmware}" ]; then | |
copy_exec "/lib/firmware/${version}/${firmware}" | |
else | |
copy_exec "/lib/firmware/${firmware}" | |
fi | |
if [ "${verbose}" = "y" ]; then | |
echo "Adding firmware ${firmware}" | |
fi | |
done | |
done | |
} | |
# $1 = file to copy to ramdisk | |
# $2 (optional) Name for the file on the ramdisk | |
# Location of the image dir is assumed to be $DESTDIR | |
# We never overwrite the target if it exists. | |
copy_exec() { | |
local src target x nonoptlib | |
local libname dirname | |
src="${1}" | |
target="${2:-$1}" | |
[ -f "${src}" ] || return 1 | |
if [ -d "${DESTDIR}/${target}" ]; then | |
# check if already copied | |
[ -e "${DESTDIR}/$target/${src##*/}" ] && return 0 | |
else | |
[ -e "${DESTDIR}/$target" ] && return 0 | |
#FIXME: inst_dir | |
mkdir -p "${DESTDIR}/${target%/*}" | |
fi | |
[ "${verbose}" = "y" ] && echo "Adding binary ${src}" | |
cp -pL "${src}" "${DESTDIR}/${target}" | |
# Copy the dependant libraries | |
for x in $(ldd "${src}" 2>/dev/null | sed -e ' | |
/\//!d; | |
/linux-gate/d; | |
/=>/ {s/.*=>[[:blank:]]*\([^[:blank:]]*\).*/\1/}; | |
s/[[:blank:]]*\([^[:blank:]]*\) (.*)/\1/' 2>/dev/null); do | |
# Try to use non-optimised libraries where possible. | |
# We assume that all HWCAP libraries will be in tls, | |
# sse2, vfp or neon. | |
nonoptlib=$(echo "${x}" | sed -e 's#/lib/\([^/]*/\)\?\(tls\|i686\|sse2\|neon\|vfp\).*/\(lib.*\)#/lib/\1\3#') | |
nonoptlib=$(echo "${nonoptlib}" | sed -e 's#-linux-gnu/\(tls\|i686\|sse2\|neon\|vfp\).*/\(lib.*\)#-linux-gnu/\2#') | |
if [ -e "${nonoptlib}" ]; then | |
x="${nonoptlib}" | |
fi | |
libname=$(basename "${x}") | |
dirname=$(dirname "${x}") | |
# FIXME inst_lib | |
mkdir -p "${DESTDIR}/${dirname}" | |
if [ ! -e "${DESTDIR}/${dirname}/${libname}" ]; then | |
cp -pL "${x}" "${DESTDIR}/${dirname}" | |
[ "${verbose}" = "y" ] && echo "Adding library ${x}" || true | |
fi | |
done | |
} | |
# Copy entire subtrees to the initramfs | |
copy_modules_dir() | |
{ | |
local kmod exclude | |
local modules= | |
local dir="$1" | |
shift | |
if ! [ -d "${MODULESDIR}/${dir}" ]; then | |
return; | |
fi | |
if [ "${verbose}" = "y" ]; then | |
echo "Copying module directory ${dir}" | |
if [ $# -ge 1 ]; then | |
echo "(excluding $*)" | |
fi | |
fi | |
while [ $# -ge 1 ]; do | |
exclude="${exclude:-} -name $1 -prune -o " | |
shift | |
done | |
for kmod in $(find "${MODULESDIR}/${dir}" ${exclude:-} -name '*.ko' -printf '%f\n'); do | |
modules="$modules ${kmod%.ko}" | |
done | |
manual_add_modules $modules | |
} | |
# walk /sys for relevant modules | |
sys_walk_mod_add() | |
{ | |
local driver_path module | |
device_path="$1" | |
sys_walk_modalias "${device_path}" | |
while [ "${device_path}" != "/sys" ]; do | |
driver_path="$(readlink -f ${device_path}/driver/module)" | |
if [ -e "$driver_path" ]; then | |
module="$(basename $(readlink -f $driver_path))" | |
if [ -n "${module}" ]; then | |
force_load "${module}" | |
fi | |
fi | |
device_path="$(dirname ${device_path})" | |
done | |
} | |
# walk /sys for relevant modalias | |
sys_walk_modalias() | |
{ | |
local device_path modalias | |
device_path="$1" | |
while [ "${device_path}" != "/sys" ]; do | |
if [ -e "${device_path}/modalias" ]; then | |
modalias=$(cat "${device_path}/modalias") | |
if [ -n "${modalias}" ]; then | |
force_load "${modalias}" | |
fi | |
fi | |
device_path="$(dirname ${device_path})" | |
done | |
} | |
# Copy all loaded or built-in modules matching the given pattern. | |
# Pattern mustn't include directory or '.ko' suffix but should use | |
# '[-_]' to allow for differences in naming between /sys/module and | |
# modules.builtin. | |
add_loaded_modules() | |
{ | |
local pattern="$1" | |
local module | |
local builtin=/lib/modules/$(uname -r)/modules.builtin | |
for module in /sys/module/$pattern; do | |
if [ -d "$module" ]; then | |
manual_add_modules $(basename $module) | |
fi | |
done | |
if [ -f $builtin ]; then | |
while read module; do | |
case "$module" in | |
*/$pattern.ko) | |
manual_add_modules $(basename $module .ko) | |
;; | |
esac | |
done < $builtin | |
fi | |
} | |
# find and only copy modules relevant to a mountpoint | |
dep_add_modules_mount() | |
{ | |
local dir block minor dev_node FSTYPE dev_sys_path | |
local modules= | |
dir="$1" | |
# require mounted sysfs | |
if [ ! -d /sys/devices/ ]; then | |
echo "mkinitramfs: MODULES dep requires mounted sysfs on /sys" >&2 | |
exit 1 | |
fi | |
# find out block device + fstype | |
eval "$( mount | while read -r dev foo mp foo fs opts rest ; do \ | |
[ "$mp" = "$dir" ] && [ "$fs" != "rootfs" ] \ | |
&& printf "dev_node='%s'\nFSTYPE='%s'" "$dev" "$fs" \ | |
&& break; done)" | |
# On failure fallback to /proc/mounts if readable | |
if [ -z "$dev_node" ] && [ -r /proc/mounts ]; then | |
eval "$(while read dev mp fs opts rest ; do \ | |
[ "$mp" = "$dir" ] && [ "$fs" != "rootfs" ] \ | |
&& printf "dev_node=$dev\nFSTYPE=$fs"\ | |
&& break; done < /proc/mounts)" | |
fi | |
# Only the root mountpoint has to exist; do nothing if any other | |
# directory is not a mountpoint. | |
if [ "$dir" != / ] && [ -z "$dev_node" ]; then | |
return | |
fi | |
# handle ubifs and return since ubifs is mounted on char devices | |
# but most of the commands below only work with block devices. | |
if [ "${FSTYPE}" = "ubifs" ]; then | |
manual_add_modules "${FSTYPE}" | |
return | |
fi | |
if [ "$dir" = / ] && [ "${dev_node}" = "/dev/root" ] ; then | |
if [ -b "${dev_node}" ]; then | |
# Match it to the canonical device name by UUID | |
dev_node="/dev/disk/by-uuid/"$(blkid -o value -s UUID ${dev_node}) 2>/dev/null | |
else | |
# Does not exist in our namespace, so look at the | |
# kernel command line | |
dev_node= | |
for arg in $(cat /proc/cmdline); do | |
case "$arg" in | |
root=*) | |
dev_node="${arg#root=}" | |
if [ "${dev_node#/dev/}" = "$dev_node" ]; then | |
dev_node="/dev/$dev_node" | |
fi | |
;; | |
--) | |
break | |
;; | |
*) | |
;; | |
esac | |
done | |
fi | |
fi | |
# recheck device | |
if [ -z "$dev_node" ] || ! dev_node="$(readlink -f ${dev_node})" \ | |
|| ! [ -b "$dev_node" ]; then | |
echo "mkinitramfs: failed to determine device for $dir" >&2 | |
echo "mkinitramfs: workaround is MODULES=most, check:" >&2 | |
echo "grep -r MODULES /etc/initramfs-tools/" >&2 | |
echo "" >&2 | |
echo "Error please report bug on initramfs-tools" >&2 | |
echo "Include the output of 'mount' and 'cat /proc/mounts'" >&2 | |
exit 1 | |
fi | |
# do not trust mount, check superblock | |
eval "$(/usr/lib/klibc/bin/fstype ${dev_node})" | |
# check that fstype fs recognition | |
if [ "${FSTYPE}" = "unknown" ]; then | |
FSTYPE=$(blkid -o value -s TYPE "${dev_node}") | |
if [ -z "${FSTYPE}" ]; then | |
echo "mkinitramfs: unknown fstype on device ${dev_node}" >&2 | |
echo "mkinitramfs: workaround is MODULES=most" >&2 | |
echo "Error please report bug on initramfs-tools" >&2 | |
exit 1 | |
fi | |
fi | |
# Add filesystem | |
modules="$modules ${FSTYPE}" | |
# lvm or luks device | |
if [ "${dev_node#/dev/mapper/}" != "${dev_node}" ] \ | |
|| [ "${dev_node#/dev/dm-}" != "${dev_node}" ]; then | |
minor=$((0x$(stat --format "%T" ${dev_node}) % 256)) | |
block=$(ls -1 /sys/block/dm-${minor}/slaves | head -n 1) | |
# lvm on luks or luks on lvm, possibly lvm snapshots | |
while [ "${block#dm-}" != "${block}" ]; do | |
block=$(ls -1 /sys/block/${block}/slaves | head -n 1) | |
done | |
# lvm on md or luks on md | |
if [ "${block#md}" != "${block}" ]; then | |
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^'${block}' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat) | |
fi | |
# luks or lvm on cciss or ida | |
if [ "${block#cciss}" != "${block}" ] \ | |
|| [ "${block#ida}" != "${block}" ] \ | |
|| [ "${block#mmcblk}" != "${block}" ] \ | |
|| [ "${block#nvme}" != "${block}" ]; then | |
block="${block%p*}" | |
else | |
block=${block%%[0-9]*} | |
fi | |
# md device new naming scheme /dev/md/X | |
elif [ "${dev_node#/dev/md/}" != "${dev_node}" ]; then | |
dev_node=${dev_node#/dev/md/} | |
# strip partion number | |
dev_node=${dev_node%%p[0-9]*} | |
# drop the partition number only for sdX and hdX devices | |
# and keep it for other devices like loop#, dm-# devices | |
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$dev_node' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat) | |
# md device /dev/mdX | |
elif [ "${dev_node#/dev/md}" != "${dev_node}" ]; then | |
dev_node=${dev_node#/dev/md} | |
# strip partion number | |
dev_node=${dev_node%%p[0-9]*} | |
# drop the partition number only for sdX and hdX devices | |
# and keep it for other devices like loop#, dm-# devices | |
block=$(sed -ne 's/multipath/[/' -e 's/linear/[/' -e 's/raid[0-9][0-9]*/[/' -e 's/\([hs]d[a-z][a-z]*\)[0-9][0-9]*/\1/g' -e '/^md'$dev_node' :/s/^[^[]*\[ \([^\[]*\)\[.*$/\1/p' </proc/mdstat) | |
# cciss device | |
elif [ "${dev_node#/dev/cciss/}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/cciss/*} | |
block="cciss!${block%p*}" | |
# ida device | |
elif [ "${dev_node#/dev/ida/}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/ida/*} | |
block="ida!${block%p*}" | |
# loop device /dev/loopX | |
elif [ "${dev_node#/dev/loop}" != "${dev_node}" ]; then | |
dev_node=${dev_node#/dev/} | |
block=$(losetup -a \ | |
| awk "/${dev_node}/{print substr(\$3, 7, 3); exit}") | |
# Xen virtual device /dev/xvdX | |
elif [ "${dev_node#/dev/xvd}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/} | |
# Xen has a mode where only the individual partitions are | |
# registered with the kernel as well as the usual full disk | |
# with partition table scheme. | |
if [ ! -e /sys/block/${block} ] ; then | |
block=${block%%[0-9]*} | |
fi | |
# mmc device /dev/mmcblkXpX | |
elif [ "${dev_node#/dev/mmcblk}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/} | |
block=${block%%p[0-9]*} | |
# nbd device /dev/nbdXpX | |
elif [ "${dev_node#/dev/nbd}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/} | |
block=${block%%p[0-9]*} | |
# DAC960 - good old mylex raid - device format /dev/rd/cXdXpX | |
elif [ "${dev_node#/dev/rd/c}" != "${dev_node}" ]; then | |
block="rd!c${dev_node#/dev/rd/c}" | |
block=${block%%p[0-9]*} | |
# etherd device | |
elif [ "${dev_node#/dev/etherd/}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/etherd/*} | |
block="etherd!${block%p*}" | |
# i2o raid device | |
elif [ "${dev_node#/dev/i2o/}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/i2o/} | |
block=${block%%[0-9]*} | |
block='i2o!'$block | |
# nvme device | |
elif [ "${dev_node#/dev/nvme}" != "${dev_node}" ]; then | |
block=${dev_node#/dev/} | |
block=${block%p*} | |
# classical block device | |
else | |
block=${dev_node#/dev/} | |
block=${block%%[0-9]*} | |
fi | |
# Error out if /sys lack block dev | |
if [ -z "${block}" ] || [ ! -e /sys/block/${block} ]; then | |
echo "mkinitramfs: for device ${dev_node} missing ${block} /sys/block/ entry" >&2 | |
echo "mkinitramfs: workaround is MODULES=most" >&2 | |
echo "mkinitramfs: Error please report the bug" >&2 | |
exit 1 | |
fi | |
# sys walk ATA | |
dev_sys_path=$(readlink -f /sys/block/${block}/device) | |
sys_walk_mod_add ${dev_sys_path} | |
# sys walk some important device classes | |
for class in gpio phy regulator; do | |
for device in /sys/class/$class/*; do | |
device="$(readlink -f "$device")" \ | |
&& sys_walk_mod_add "$device" | |
done | |
done | |
# clk, USB-PHY and pinctrl devices are outside the device model (!) so | |
# match loaded modules by name | |
add_loaded_modules 'clk[-_]*' | |
add_loaded_modules 'phy[-_]*' | |
add_loaded_modules 'pinctrl[-_]*' | |
# catch old-style IDE | |
if [ -e /sys/bus/ide/devices/ ]; then | |
sys_walk_modalias ${dev_sys_path} | |
modules="$modules ide-gd_mod ide-cd" | |
fi | |
if [ -e /sys/bus/scsi/devices/ ]; then | |
modules="$modules sd_mod" | |
fi | |
if [ -e /sys/bus/mmc/devices/ ]; then | |
modules="$modules mmc_block" | |
fi | |
if [ -e /sys/bus/virtio ] ; then | |
modules="$modules virtio_pci virtio_mmio" | |
fi | |
if [ -e /sys/bus/i2o/devices/ ]; then | |
force_load i2o_block | |
force_load i2o_config | |
fi | |
if [ -e /sys/bus/ps3_system_bus/ ]; then | |
modules="$modules ps3disk ps3rom ps3-gelic ps3_sys_manager" | |
fi | |
if [ -e /sys/bus/vio/ ]; then | |
modules="$modules sunvnet sunvdc" | |
fi | |
manual_add_modules $modules | |
} | |
dep_add_modules() | |
{ | |
dep_add_modules_mount / | |
dep_add_modules_mount /usr | |
} | |
# The modules "most" classes added per default to the initramfs | |
auto_add_modules() | |
{ | |
local arg | |
local modules= | |
if [ "$#" -eq 0 ] ; then | |
set -- base net ide scsi block ata i2o dasd ieee1394 firewire mmc usb_storage | |
fi | |
for arg in "$@" ; do | |
case "$arg" in | |
base) | |
modules="$modules ehci-pci ehci-orion ehci-hcd ohci-hcd ohci-pci uhci-hcd usbhid overlay" | |
modules="$modules xhci xhci-pci xhci-hcd" | |
modules="$modules btrfs ext2 ext3 ext4 ext4dev " | |
modules="$modules isofs jfs reiserfs udf xfs" | |
modules="$modules nfs nfsv2 nfsv3 nfsv4" | |
modules="$modules af_packet atkbd i8042 psmouse" | |
modules="$modules virtio_pci virtio_mmio" | |
# Include all HID drivers unless we're sure they | |
# don't support keyboards. hid-*ff covers various | |
# game controllers with force feedback. | |
copy_modules_dir kernel/drivers/hid \ | |
'hid-*ff.ko' hid-a4tech.ko hid-cypress.ko \ | |
hid-dr.ko hid-elecom.ko hid-gyration.ko \ | |
hid-icade.ko hid-kensington.ko hid-kye.ko \ | |
hid-lcpower.ko hid-magicmouse.ko \ | |
hid-multitouch.ko hid-ntrig.ko \ | |
hid-petalynx.ko hid-picolcd.ko hid-pl.ko \ | |
hid-ps3remote.ko hid-quanta.ko \ | |
'hid-roccat-ko*.ko' hid-roccat-pyra.ko \ | |
hid-saitek.ko hid-sensor-hub.ko hid-sony.ko \ | |
hid-speedlink.ko hid-tivo.ko hid-twinhan.ko \ | |
hid-uclogic.ko hid-wacom.ko hid-waltop.ko \ | |
hid-wiimote.ko hid-zydacron.ko | |
# Any of these might be needed by other drivers | |
copy_modules_dir kernel/drivers/clk | |
copy_modules_dir kernel/drivers/gpio | |
copy_modules_dir kernel/drivers/phy | |
copy_modules_dir kernel/drivers/pinctrl | |
copy_modules_dir kernel/drivers/regulator | |
copy_modules_dir kernel/drivers/usb/phy | |
;; | |
net) | |
copy_modules_dir kernel/drivers/net \ | |
appletalk arcnet bonding can dummy.ko \ | |
hamradio hippi ifb.ko irda macvlan.ko \ | |
macvtap.ko pcmcia sb1000.ko team tokenring \ | |
tun.ko usb veth.ko wan wimax wireless \ | |
xen-netback.ko | |
;; | |
ide) | |
copy_modules_dir kernel/drivers/ide | |
;; | |
mmc) | |
copy_modules_dir kernel/drivers/mmc | |
;; | |
scsi) | |
copy_modules_dir kernel/drivers/scsi | |
modules="$modules mptfc mptsas mptscsih mptspi zfcp" | |
;; | |
ata) | |
copy_modules_dir kernel/drivers/ata | |
;; | |
block) | |
copy_modules_dir kernel/drivers/block | |
copy_modules_dir kernel/drivers/nvme | |
;; | |
ubi) | |
modules="$modules deflate zlib lzo ubi ubifs" | |
;; | |
ieee1394) | |
modules="$modules ohci1394 sbp2" | |
;; | |
firewire) | |
modules="$modules firewire-ohci firewire-sbp2" | |
;; | |
i2o) | |
modules="$modules i2o_block" | |
;; | |
dasd) | |
modules="$modules dasd_diag_mod dasd_eckd_mod dasd_fba_mod" | |
;; | |
usb_storage) | |
copy_modules_dir kernel/drivers/usb/storage | |
;; | |
esac | |
done | |
manual_add_modules $modules | |
} | |
# 'depmod' only looks at symbol dependencies; there is no way for | |
# modules to declare explicit dependencies through module information, | |
# so dependencies on e.g. crypto providers are hidden. Until this is | |
# fixed, we need to handle those hidden dependencies. | |
hidden_dep_add_modules() | |
{ | |
local modules= | |
for dep in "lib/libcrc32c crc32c" \ | |
"fs/ubifs/ubifs deflate zlib lzo" \ | |
"fs/btrfs/btrfs crc32c"; do | |
set -- $dep | |
if [ -f "${DESTDIR}/lib/modules/${version}/kernel/$1.ko" ]; then | |
shift | |
modules="$modules $@" | |
fi | |
done | |
manual_add_modules $modules | |
} | |
# mkinitramfs help message | |
usage() | |
{ | |
cat >&2 << EOF | |
Usage: ${0} [OPTION]... -o outfile [version] | |
Options: | |
-c compress Override COMPRESS setting in initramfs.conf. | |
-d confdir Specify an alternative configuration directory. | |
-k Keep temporary directory used to make the image. | |
-o outfile Write to outfile. | |
-r root Override ROOT setting in initramfs.conf. | |
See mkinitramfs(8) for further details. | |
EOF | |
exit 1 | |
} | |
# Find the source for a script file. This is needed to work around | |
# temporary directories mounted with the noexec option. The source | |
# will be on / or /usr which must be executable. | |
get_source() | |
{ | |
if [ -z "$scriptdir" ]; then | |
echo "${initdir}/$1" | |
elif [ -f "${CONFDIR}${scriptdir}/$1" ]; then | |
echo "${CONFDIR}${scriptdir}/$1" | |
else | |
echo "/usr/share/initramfs-tools${scriptdir}/$1" | |
fi | |
} | |
set_initlist() | |
{ | |
unset initlist | |
for si_x in ${initdir}/*; do | |
# skip empty dirs without warning | |
[ "${si_x}" = "${initdir}/*" ] && return | |
# only allow variable name chars | |
case ${si_x#${initdir}/} in | |
*[![:alnum:]\._-]*) | |
[ "${verbose}" = "y" ] \ | |
&& echo "$si_x ignored: not alphanumeric or '_' file" >&2 | |
continue | |
;; | |
esac | |
# skip directories | |
if [ -d ${si_x} ]; then | |
[ "${verbose}" = "y" ] \ | |
&& echo "$si_x ignored: a directory" >&2 | |
continue | |
fi | |
si_x="$(get_source "${si_x#${initdir}/}")" | |
# skip non executable scripts | |
if [ ! -x ${si_x} ]; then | |
[ "${verbose}" = "y" ] \ | |
&& echo "$si_x ignored: not executable" >&2 | |
continue | |
fi | |
# skip bad syntax | |
if ! sh -n ${si_x} ; then | |
[ "${verbose}" = "y" ] \ | |
&& echo "$si_x ignored: bad syntax" >&2 | |
continue | |
fi | |
initlist="${initlist:-} ${si_x##*/}" | |
done | |
} | |
get_prereq_pairs() | |
{ | |
set_initlist | |
for gp_x in ${initlist:-}; do | |
echo ${gp_x} ${gp_x} | |
gp_src="$(get_source $gp_x)" | |
prereqs=$("${gp_src}" prereqs) | |
for prereq in ${prereqs}; do | |
echo ${prereq} ${gp_x} | |
done | |
done | |
} | |
# cache boot scripts order | |
cache_run_scripts() | |
{ | |
DESTDIR=${1} | |
scriptdir=${2} | |
initdir=${DESTDIR}${scriptdir} | |
[ ! -d ${initdir} ] && return | |
> ${initdir}/ORDER | |
runlist=$(get_prereq_pairs | tsort) | |
for crs_x in ${runlist}; do | |
[ -f ${initdir}/${crs_x} ] || continue | |
echo "${scriptdir}/${crs_x} \"\$@\"" >> ${initdir}/ORDER | |
echo "[ -e /conf/param.conf ] && . /conf/param.conf" >> ${initdir}/ORDER | |
done | |
} | |
call_scripts() | |
{ | |
set -e | |
for cs_x in ${runlist}; do | |
[ -f ${initdir}/${cs_x} ] || continue | |
# mkinitramfs verbose output | |
if [ "${verbose}" = "y" ]; then | |
echo "Calling hook ${cs_x}" | |
fi | |
${initdir}/${cs_x} && ec=$? || ec=$? | |
# allow hooks to abort build: | |
if [ "$ec" -ne 0 ]; then | |
echo "E: ${initdir}/${cs_x} failed with return $ec." | |
# only errexit on mkinitramfs | |
[ -n "${version}" ] && exit $ec | |
fi | |
# allow boot scripts to modify exported boot parameters | |
if [ -e /conf/param.conf ]; then | |
. /conf/param.conf | |
fi | |
done | |
set +e | |
} | |
run_scripts() | |
{ | |
scriptdir=${2:-} | |
initdir=${1} | |
[ ! -d ${initdir} ] && return | |
runlist=$(get_prereq_pairs | tsort) | |
call_scripts $scriptdir | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment