improve portability, code quality, fix bugs, etc...
This commit is contained in:
parent
1287f2996b
commit
9c16bad562
15
Makefile
15
Makefile
@ -4,10 +4,17 @@ BINDIR = ${PREFIX}/bin
|
|||||||
DATADIR = ${PREFIX}/share
|
DATADIR = ${PREFIX}/share
|
||||||
|
|
||||||
install:
|
install:
|
||||||
install -Dm600 config ${DESTDIR}${SYSCONFDIR}/tinyramfs/config
|
mkdir -p \
|
||||||
install -Dm755 tinyramfs ${DESTDIR}${BINDIR}/tinyramfs
|
${DESTDIR}${DATADIR}/tinyramfs/hooks \
|
||||||
install -Dm755 init ${DESTDIR}${DATADIR}/tinyramfs/init
|
${DESTDIR}${SYSCONFDIR}/tinyramfs \
|
||||||
install -Dm755 device-helper ${DESTDIR}${DATADIR}/tinyramfs/device-helper
|
${DESTDIR}${BINDIR}
|
||||||
|
cp -R hooks/* ${DESTDIR}${DATADIR}/tinyramfs/hooks/
|
||||||
|
cp init device-helper ${DESTDIR}${DATADIR}/tinyramfs
|
||||||
|
chmod -R 644 ${DESTDIR}${DATADIR}/tinyramfs
|
||||||
|
cp config ${DESTDIR}${SYSCONFDIR}/tinyramfs
|
||||||
|
chmod 600 ${DESTDIR}${SYSCONFDIR}/tinyramfs/config
|
||||||
|
cp tinyramfs ${DESTDIR}${BINDIR}/tinyramfs
|
||||||
|
chmod 755 ${DESTDIR}${BINDIR}/tinyramfs
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f ${DESTDIR}${BINDIR}/tinyramfs
|
rm -f ${DESTDIR}${BINDIR}/tinyramfs
|
||||||
|
36
README.md
36
README.md
@ -7,27 +7,24 @@ Features
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
- No `local`'s, no bashisms, only POSIX shell
|
- No `local`'s, no bashisms, only POSIX shell
|
||||||
- Easy configuration
|
- Portable, not distro specific
|
||||||
|
- Easy to use configuration
|
||||||
|
- Build time and init time hooks
|
||||||
|
- LUKS (detached header, key), LVM
|
||||||
- mdev, mdevd, eudev
|
- mdev, mdevd, eudev
|
||||||
- LUKS, LVM
|
|
||||||
- LUKS detached header and key embedded into initramfs
|
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
* POSIX utilities ( find, mkdir, ... )
|
* POSIX utilities
|
||||||
* POSIX shell
|
* POSIX shell
|
||||||
* `switch_root`
|
* `switch_root`
|
||||||
* `readlink`
|
|
||||||
* `install`
|
|
||||||
* `mount`
|
* `mount`
|
||||||
* `blkid`
|
* `blkid`
|
||||||
* `cpio`
|
* `cpio`
|
||||||
* `strip`
|
* POSIX SD `strip`
|
||||||
- Optional
|
- Optional
|
||||||
* `gzip`
|
* `mdev` OR `mdevd` OR `eudev` OR `systemd-udevd`
|
||||||
- Required by default
|
|
||||||
* `mdev` OR `mdevd` OR `eudev`
|
|
||||||
- systemd-udevd not tested
|
- systemd-udevd not tested
|
||||||
* `lvm2`
|
* `lvm2`
|
||||||
- Required for LVM support
|
- Required for LVM support
|
||||||
@ -39,9 +36,8 @@ Dependencies
|
|||||||
Notes
|
Notes
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* busybox modutils doesn't handle soft dependencies (modules.softdep). You must manually include them using `modules` config option
|
* busybox modutils doesn't handle soft dependencies (modules.softdep). You must manually copy them using hooks
|
||||||
* busybox and toybox blkid doesn't support PARTUUID. You must use util-linux blkid
|
* busybox and toybox blkid doesn't support PARTUUID. You must use util-linux blkid for PARTUUID support
|
||||||
* zsh (in POSIX mode) shows some errors in init stage. Just ignore these errors, it's harmless
|
|
||||||
* `cp` in toybox incorrectly handles `-P` flag. You need to apply patch from [this issue](https://github.com/landley/toybox/issues/174) or replace cp with another implementation
|
* `cp` in toybox incorrectly handles `-P` flag. You need to apply patch from [this issue](https://github.com/landley/toybox/issues/174) or replace cp with another implementation
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
@ -57,20 +53,6 @@ tinyramfs -o /boot/initramfs
|
|||||||
# reboot...
|
# reboot...
|
||||||
```
|
```
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
```
|
|
||||||
usage: tinyramfs [option]
|
|
||||||
-o, --output <file> set initramfs output path
|
|
||||||
-c, --config <file> set config file path
|
|
||||||
-m, --moddir <dir> set modules directory
|
|
||||||
-k, --kernel <ver> set kernel version
|
|
||||||
-F, --files <dir> set files directory
|
|
||||||
-d, --debug enable debug mode
|
|
||||||
-f, --force overwrite initramfs image
|
|
||||||
```
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
110
config
110
config
@ -2,23 +2,9 @@
|
|||||||
# configuration
|
# configuration
|
||||||
#
|
#
|
||||||
# uncomment and fill settings which you needed
|
# uncomment and fill settings which you needed
|
||||||
|
|
||||||
# debug mode
|
|
||||||
# default - 0
|
|
||||||
#
|
#
|
||||||
#debug=0|1
|
# 0 - disable
|
||||||
|
# 1 - enable
|
||||||
# overwrite initramfs
|
|
||||||
# default - 0
|
|
||||||
#
|
|
||||||
#force=0|1
|
|
||||||
|
|
||||||
# initramfs output path
|
|
||||||
#
|
|
||||||
# default - /tmp/initramfs-$kernel
|
|
||||||
# example - output="/tmp/myinitramfs.img.gz"
|
|
||||||
#
|
|
||||||
#output=""
|
|
||||||
|
|
||||||
# monolithic kernel
|
# monolithic kernel
|
||||||
#
|
#
|
||||||
@ -27,48 +13,35 @@
|
|||||||
#
|
#
|
||||||
#monolith=0|1
|
#monolith=0|1
|
||||||
|
|
||||||
# modules directory
|
|
||||||
#
|
|
||||||
# default - /lib/modules
|
|
||||||
# example - moddir="/mnt/root/lib/modules"
|
|
||||||
#
|
|
||||||
#moddir=""
|
|
||||||
|
|
||||||
# kernel version
|
|
||||||
#
|
|
||||||
# default - $(uname -r)
|
|
||||||
# example - kernel="5.4.18_1"
|
|
||||||
#
|
|
||||||
#kernel=""
|
|
||||||
|
|
||||||
# compression program
|
# compression program
|
||||||
#
|
#
|
||||||
# default - gzip -9
|
# supported - whatever you choose
|
||||||
# example -
|
# default - none
|
||||||
# compress="pigz -9"
|
# example - compress="pigz -9"
|
||||||
# compress="none" # disable compress
|
|
||||||
#
|
#
|
||||||
#compress=""
|
#compress=""
|
||||||
|
|
||||||
# root
|
# root file system
|
||||||
#
|
#
|
||||||
# supported - PARTUUID, DEVICE, LABEL, UUID
|
# supported - UUID, LABEL, DEVICE, PARTUUID
|
||||||
# example -
|
# example -
|
||||||
# root="/dev/sda1"
|
# root="/dev/sda1"
|
||||||
# root="/dev/dm-0"
|
# root="/dev/dm-0"
|
||||||
|
# root="/dev/disk/by-uuid/13bcb7cc-8fe5-4f8e-a1fe-e4b5b336f3ef"
|
||||||
# root="PARTUUID=35f923c5-083a-4950-a4da-e611d0778121"
|
# root="PARTUUID=35f923c5-083a-4950-a4da-e611d0778121"
|
||||||
#
|
#
|
||||||
#root=""
|
#root=""
|
||||||
|
|
||||||
# root type
|
# root file system type
|
||||||
#
|
#
|
||||||
# default - autodetected
|
# default - autodetected throught /proc/mounts
|
||||||
# example - root_type="btrfs"
|
# example - root_type="btrfs"
|
||||||
#
|
#
|
||||||
#root_type=""
|
#root_type=""
|
||||||
|
|
||||||
# root options
|
# root file system options
|
||||||
# example - see fstab(5)
|
# example - root_opts="subvol=mysubvolume,nodatacow,defaults"
|
||||||
|
# see fstab(5) man page for more info
|
||||||
#
|
#
|
||||||
#root_opts=""
|
#root_opts=""
|
||||||
|
|
||||||
@ -79,72 +52,57 @@
|
|||||||
|
|
||||||
# hostonly mode
|
# hostonly mode
|
||||||
#
|
#
|
||||||
|
# default - 0
|
||||||
# dramatically reduce initramfs size
|
# dramatically reduce initramfs size
|
||||||
# useful only for modular kernels
|
# useful only for modular kernels
|
||||||
#
|
#
|
||||||
#hostonly=0|1
|
#hostonly=0|1
|
||||||
|
|
||||||
# additional modules
|
# hooks
|
||||||
# example - modules="fat crc32c_generic"
|
|
||||||
#
|
#
|
||||||
#modules=""
|
# currently supported - lvm, luks
|
||||||
|
# example -
|
||||||
# exclude modules
|
# hooks="lvm luks" will support booting LUKS on LVM
|
||||||
# example - modules_exclude="wmi fuse"
|
# hooks="luks lvm" will support booting LVM on LUKS
|
||||||
|
# hooks="luks" will support booting only LUKS
|
||||||
|
# and so on...
|
||||||
#
|
#
|
||||||
#modules_exclude=""
|
#hooks=""
|
||||||
|
|
||||||
# additional binaries
|
|
||||||
# example - binaries="ls cat /path/to/mycustomprog"
|
|
||||||
#
|
|
||||||
#binaries=""
|
|
||||||
|
|
||||||
# LVM support
|
|
||||||
# default - 0
|
|
||||||
#
|
|
||||||
#lvm=0|1
|
|
||||||
|
|
||||||
# LVM options
|
# LVM options
|
||||||
#
|
#
|
||||||
# supported - tag, name, group, config, discard
|
# supported - tag, name, group, config, discard
|
||||||
# description -
|
# description -
|
||||||
# tag - trigger lvm by tag
|
# tag - trigger lvm by tag
|
||||||
# name - trigger lvm by logical volume name
|
# name - trigger lvm by logical volume name. group must be specified
|
||||||
# group - trigger lvm by volume group name
|
# group - trigger lvm by volume group name
|
||||||
# config - embed host lvm config
|
# config - embed host lvm config
|
||||||
# discard - enable issue_discards
|
# discard - enable issue_discards
|
||||||
# example -
|
# example -
|
||||||
# lvm_opts="tag=lvm-server"
|
# lvm_opts="tag=lvm-server"
|
||||||
# lvm_opts="name=lv1,group=vg1"
|
# lvm_opts="name=lv1,group=vg1"
|
||||||
# lvm_opts="config=1,discard"
|
# lvm_opts="config=1,discard=1"
|
||||||
# lvm_opts="discard=1"
|
# lvm_opts="discard=1"
|
||||||
#
|
#
|
||||||
#lvm_opts=""
|
#lvm_opts=""
|
||||||
|
|
||||||
# LUKS support
|
|
||||||
# default - 0
|
|
||||||
#
|
|
||||||
#luks=0|1
|
|
||||||
|
|
||||||
# LUKS encrypted root
|
|
||||||
#
|
|
||||||
# supported - PARTUUID, DEVICE, LABEL, UUID
|
|
||||||
# example -
|
|
||||||
# luks_root="/dev/sda1"
|
|
||||||
# luks_root="PARTUUID=35f923c5-083a-4950-a4da-e611d0778121"
|
|
||||||
#
|
|
||||||
#luks_root=""
|
|
||||||
|
|
||||||
# LUKS options
|
# LUKS options
|
||||||
#
|
#
|
||||||
# supported - key, name, header, discard
|
# supported - key, name, root, header, discard
|
||||||
# description -
|
# description -
|
||||||
# key - embed key
|
# key - embed key
|
||||||
# name - device mapper name
|
# name - device mapper name
|
||||||
|
# root - encrypted root ( UUID, LABEL, DEVICE, PARTUUID )
|
||||||
# header - embed header
|
# header - embed header
|
||||||
# discard - enable allow-discards
|
# discard - enable allow-discards
|
||||||
# example -
|
# example -
|
||||||
# luks_opts="key=/path/to/keyfile,name=myluksroot,header=/path/to/header,discard"
|
# luks_opts="root=PARTUUID=35f923c5-083a-4950-a4da-e611d0778121,key=/path/to/keyfile,name=myluksroot,header=/path/to/header,discard=1"
|
||||||
# luks_opts="discard=1"
|
# luks_opts="root=PARTUUID=35f923c5-083a-4950-a4da-e611d0778121,
|
||||||
|
# key=/path/to/keyfile,
|
||||||
|
# name=myluksroot,
|
||||||
|
# header=/path/to/header,
|
||||||
|
# discard=1"
|
||||||
|
#
|
||||||
|
# luks_opts="root=/dev/sda1,discard=1"
|
||||||
#
|
#
|
||||||
#luks_opts=""
|
#luks_opts=""
|
||||||
|
@ -6,7 +6,6 @@ create_symlink()
|
|||||||
{
|
{
|
||||||
dir="$1"; sym="$2"
|
dir="$1"; sym="$2"
|
||||||
|
|
||||||
# remove double quotes
|
|
||||||
sym="${sym%\"}"
|
sym="${sym%\"}"
|
||||||
sym="${sym#\"}"
|
sym="${sym#\"}"
|
||||||
sym="${dir}/${sym}"
|
sym="${dir}/${sym}"
|
||||||
@ -20,7 +19,7 @@ create_symlink()
|
|||||||
[ -b "/dev/${dev_name=${DEVPATH##*/}}" ] || exit 1
|
[ -b "/dev/${dev_name=${DEVPATH##*/}}" ] || exit 1
|
||||||
|
|
||||||
# prevent race condition
|
# prevent race condition
|
||||||
while ! blkid "/dev/${dev_name}"; do sleep 1; done
|
blkid "/dev/${dev_name}" || sleep 2
|
||||||
|
|
||||||
for line in $(blkid "/dev/${dev_name}"); do case "${line%%=*}" in
|
for line in $(blkid "/dev/${dev_name}"); do case "${line%%=*}" in
|
||||||
UUID) create_symlink /dev/disk/by-uuid "${line##*=}" ;;
|
UUID) create_symlink /dev/disk/by-uuid "${line##*=}" ;;
|
||||||
|
37
hooks/luks/luks
Normal file
37
hooks/luks/luks
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# vim: set ft=sh:
|
||||||
|
#
|
||||||
|
# handle_luks()
|
||||||
|
{
|
||||||
|
print "configuring LUKS"
|
||||||
|
|
||||||
|
[ "$hostonly" = 1 ] &&
|
||||||
|
for _module in \
|
||||||
|
aes ecb xts lrw wp512 sha256 \
|
||||||
|
sha512 twofish serpent dm-crypt
|
||||||
|
do
|
||||||
|
copy_module "$_module"
|
||||||
|
done
|
||||||
|
|
||||||
|
copy_binary cryptsetup
|
||||||
|
|
||||||
|
# avoid possible issues with libgcc_s.so.1
|
||||||
|
# see https://bugs.archlinux.org/task/56771
|
||||||
|
[ -e /lib/libgcc_s.so.1 ] && copy_library /lib/libgcc_s.so.1
|
||||||
|
|
||||||
|
# word splitting is safe by design
|
||||||
|
# shellcheck disable=2086
|
||||||
|
IFS=,; set -- $luks_opts; unset IFS
|
||||||
|
|
||||||
|
set -C; for opt; do case "${opt%%=*}" in
|
||||||
|
key | header)
|
||||||
|
cp "${opt#*=}" "${tmpdir}/root/${opt%%=*}"
|
||||||
|
chmod 400 "${tmpdir}/root/${opt%%=*}"
|
||||||
|
|
||||||
|
sed "s|${opt#*=}|/root/${opt%%=*}|" \
|
||||||
|
"${tmpdir}/etc/tinyramfs/config" > "${tmpdir}/_"
|
||||||
|
|
||||||
|
cp "${tmpdir}/_" "${tmpdir}/etc/tinyramfs/config"
|
||||||
|
chmod 600 "${tmpdir}/etc/tinyramfs/config"
|
||||||
|
rm "${tmpdir}/_"
|
||||||
|
esac || panic; done; set +C
|
||||||
|
}
|
31
hooks/luks/luks.init
Normal file
31
hooks/luks/luks.init
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# vim: set ft=sh:
|
||||||
|
#
|
||||||
|
# unlock_luks()
|
||||||
|
{
|
||||||
|
[ "$break" = luks ] && { print "break before unlock_luks()"; sh; }
|
||||||
|
|
||||||
|
mkdir -p /run/cryptsetup
|
||||||
|
|
||||||
|
IFS=,; set -- $luks_opts; unset IFS
|
||||||
|
|
||||||
|
for opt; do case "$opt" in
|
||||||
|
discard=1) luks_discard="--allow-discards" ;;
|
||||||
|
header=*) luks_header="--${opt}" ;;
|
||||||
|
name=*) luks_name="${opt#*=}" ;;
|
||||||
|
root=*) luks_root="${opt#*=}" ;;
|
||||||
|
key=*) luks_key="-d ${opt#*=}" ;;
|
||||||
|
esac; done
|
||||||
|
|
||||||
|
resolve_device "$luks_root"
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"$luks_key" "$luks_header" "$luks_discard" \
|
||||||
|
"$device" "${luks_name:-crypt-${device##*/}}"
|
||||||
|
|
||||||
|
# libdevice-mapper assumes that udev has dm rules
|
||||||
|
# which is not true because we use our device-helper for dm stuff
|
||||||
|
# this variable fixes possible(?) hang
|
||||||
|
export DM_DISABLE_UDEV=1
|
||||||
|
|
||||||
|
cryptsetup open $@ || panic "failed to unlock LUKS"
|
||||||
|
}
|
44
hooks/lvm/lvm
Normal file
44
hooks/lvm/lvm
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# vim: set ft=sh:
|
||||||
|
#
|
||||||
|
# handle_lvm()
|
||||||
|
{
|
||||||
|
print "configuring LVM"
|
||||||
|
|
||||||
|
[ "$hostonly" = 1 ] &&
|
||||||
|
for _module in \
|
||||||
|
dm-log dm-cache dm-mirror \
|
||||||
|
dm-snapshot dm-multipath dm-thin-pool
|
||||||
|
do
|
||||||
|
copy_module "$_module"
|
||||||
|
done
|
||||||
|
|
||||||
|
copy_binary lvm
|
||||||
|
|
||||||
|
lvm_config="
|
||||||
|
devices {
|
||||||
|
write_cache_state = 0
|
||||||
|
}
|
||||||
|
backup {
|
||||||
|
backup = 0
|
||||||
|
archive = 0
|
||||||
|
}
|
||||||
|
global {
|
||||||
|
use_lvmetad = 0
|
||||||
|
}"
|
||||||
|
|
||||||
|
# word splitting is safe by design
|
||||||
|
# shellcheck disable=2086
|
||||||
|
IFS=,; set -- $lvm_opts; unset IFS
|
||||||
|
|
||||||
|
for opt; do case "$opt" in
|
||||||
|
config=1) embed_lvm_config=
|
||||||
|
esac; done
|
||||||
|
|
||||||
|
mkdir -p "${tmpdir}/etc/lvm"
|
||||||
|
|
||||||
|
lvm config \
|
||||||
|
--config "$lvm_config" \
|
||||||
|
${embed_lvm_config+--mergedconfig} \
|
||||||
|
> "${tmpdir}/etc/lvm/lvm.conf"
|
||||||
|
}
|
||||||
|
|
35
hooks/lvm/lvm.init
Normal file
35
hooks/lvm/lvm.init
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# vim: set ft=sh:
|
||||||
|
#
|
||||||
|
# trigger_lvm()
|
||||||
|
{
|
||||||
|
[ "$break" = lvm ] && { print "break before trigger_lvm()"; sh; }
|
||||||
|
|
||||||
|
mkdir -p /run/lvm /run/lock/lvm
|
||||||
|
|
||||||
|
IFS=,; set -- $lvm_opts; unset IFS
|
||||||
|
|
||||||
|
for opt; do case "$opt" in
|
||||||
|
discard=1) lvm_discard="--config=devices{issue_discards=1}" ;;
|
||||||
|
config=0) : > /etc/lvm/lvm.conf ;;
|
||||||
|
group=*) lvm_group="${opt##*=}" ;;
|
||||||
|
name=*) lvm_name="/${opt##*=}" ;;
|
||||||
|
tag=*) lvm_tag="@${opt##*=}" ;;
|
||||||
|
esac; done
|
||||||
|
|
||||||
|
set -- "--sysinit" "-qq" "-aay" "$lvm_discard"
|
||||||
|
|
||||||
|
# libdevice-mapper assumes that udev have dm rules
|
||||||
|
# which is not true because we use our device-helper for dm stuff
|
||||||
|
# this variable fixes possible(?) hang
|
||||||
|
export DM_DISABLE_UDEV=1
|
||||||
|
|
||||||
|
if [ "$lvm_group" ] && [ "$lvm_name" ]; then
|
||||||
|
lvm lvchange $@ "${lvm_group}${lvm_name}"
|
||||||
|
elif [ "$lvm_group" ]; then
|
||||||
|
lvm vgchange $@ "$lvm_group"
|
||||||
|
elif [ "$lvm_tag" ]; then
|
||||||
|
lvm lvchange $@ "$lvm_tag"
|
||||||
|
else
|
||||||
|
lvm vgchange $@
|
||||||
|
fi || panic "failed to trigger LVM"
|
||||||
|
}
|
111
init
111
init
@ -1,12 +1,7 @@
|
|||||||
#!/bin/sh -ef
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# tiny init
|
# tiny init
|
||||||
#
|
#
|
||||||
# word splitting is safe by design
|
|
||||||
# shellcheck disable=2068,2046,2086
|
|
||||||
#
|
|
||||||
# false positive
|
|
||||||
# shellcheck disable=2154,2163,1091
|
|
||||||
|
|
||||||
print()
|
print()
|
||||||
{
|
{
|
||||||
@ -21,21 +16,33 @@ panic()
|
|||||||
|
|
||||||
resolve_device()
|
resolve_device()
|
||||||
{
|
{
|
||||||
count=0; device=
|
count=0; device="$1"
|
||||||
|
|
||||||
case "${1%%=*}" in
|
case "${device%%=*}" in /dev/*) ;;
|
||||||
/dev/*) device="$1" ;;
|
UUID) device="/dev/disk/by-uuid/${device#*=}" ;;
|
||||||
UUID) device="/dev/disk/by-uuid/${1##*=}" ;;
|
LABEL) device="/dev/disk/by-label/${device#*=}" ;;
|
||||||
LABEL) device="/dev/disk/by-label/${1##*=}" ;;
|
PARTUUID) device="/dev/disk/by-partuuid/${device#*=}" ;;
|
||||||
PARTUUID) device="/dev/disk/by-partuuid/${1##*=}" ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# prevent race condition
|
# prevent race condition
|
||||||
|
# XXX what the hell happens here?
|
||||||
|
# why this loop sometimes trigger panic if i remove '|| :'
|
||||||
while [ ! -b "$device" ]; do sleep 1
|
while [ ! -b "$device" ]; do sleep 1
|
||||||
[ "$(( count += 1 ))" != 30 ] || {
|
[ "$((count += 1))" = 30 ] && {
|
||||||
panic "failed to lookup partition"
|
panic "failed to lookup partition"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
done || :
|
||||||
|
}
|
||||||
|
|
||||||
|
run_hook()
|
||||||
|
{
|
||||||
|
type="$1"; hksdir=/usr/share/tinyramfs/hooks
|
||||||
|
|
||||||
|
# run hooks if any
|
||||||
|
for hook in $hooks; do
|
||||||
|
[ -f "${hksdir}/${hook}/${hook}.${type}" ] || continue
|
||||||
|
. "${hksdir}/${hook}/${hook}.${type}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,23 +52,17 @@ prepare_environment()
|
|||||||
|
|
||||||
export \
|
export \
|
||||||
PATH=/bin TERM=linux SHELL=/bin/sh \
|
PATH=/bin TERM=linux SHELL=/bin/sh \
|
||||||
LANG=C LC_ALL=C PS1="# " HOME=/root \
|
LANG=C LC_ALL=C PS1="# " HOME=/root
|
||||||
|
|
||||||
mount -t proc -o nosuid,noexec,nodev proc /proc
|
mount -t proc -o nosuid,noexec,nodev proc /proc
|
||||||
mount -t sysfs -o nosuid,noexec,nodev sys /sys
|
mount -t sysfs -o nosuid,noexec,nodev sys /sys
|
||||||
mount -t tmpfs -o nosuid,nodev,mode=0755 run /run
|
mount -t tmpfs -o nosuid,nodev,mode=0755 run /run
|
||||||
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
|
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
|
||||||
|
|
||||||
mkdir -p /run/cryptsetup /run/lock /run/lvm
|
|
||||||
|
|
||||||
ln -s /proc/self/fd /dev/fd
|
ln -s /proc/self/fd /dev/fd
|
||||||
ln -s fd/0 /dev/stdin
|
ln -s fd/0 /dev/stdin
|
||||||
ln -s fd/1 /dev/stdout
|
ln -s fd/1 /dev/stdout
|
||||||
ln -s fd/2 /dev/stderr
|
ln -s fd/2 /dev/stderr
|
||||||
|
|
||||||
trap panic EXIT
|
|
||||||
|
|
||||||
[ ! "$modules" ] || modprobe -a "$modules"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_cmdline()
|
parse_cmdline()
|
||||||
@ -69,14 +70,14 @@ parse_cmdline()
|
|||||||
read -r cmdline < /proc/cmdline
|
read -r cmdline < /proc/cmdline
|
||||||
|
|
||||||
for line in $cmdline; do case "$line" in
|
for line in $cmdline; do case "$line" in
|
||||||
debug | debug=1) set -x ;;
|
rootfstype=*) root_type="${line#*=}" ;;
|
||||||
rootfstype=*) root_type="${line##*=}" ;;
|
rootflags=*) root_opts="${line#*=}" ;;
|
||||||
rootflags=*) root_opts="${line##*=}" ;;
|
debug=1) set -x ;;
|
||||||
ro | rw) rorw="-o $line" ;;
|
ro | rw) rorw="-o $line" ;;
|
||||||
--*) init_args="${cmdline##*--}"; break ;;
|
--*) init_args="${cmdline#*-- }"; break ;;
|
||||||
*=*) command export "$line" ;;
|
*=*) command export "$line" ;;
|
||||||
*) command export "${line}=1" ;;
|
*) command export "${line}=1" ;;
|
||||||
esac 2> /dev/null || continue; done
|
esac 2> /dev/null || :; done
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_devmgr()
|
setup_devmgr()
|
||||||
@ -107,55 +108,6 @@ setup_devmgr()
|
|||||||
esac 2> /dev/null
|
esac 2> /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_luks()
|
|
||||||
{
|
|
||||||
[ "$break" = luks ] && { print "break before unlock_luks()"; sh; }
|
|
||||||
|
|
||||||
{ IFS=,; set -- $luks_opts; unset IFS; }
|
|
||||||
|
|
||||||
for opt; do case "$opt" in
|
|
||||||
discard | discard=1) luks_discard="--allow-discards" ;;
|
|
||||||
header=*) luks_header="--${opt}" ;;
|
|
||||||
name=*) luks_name="${opt##*=}" ;;
|
|
||||||
key=*) luks_key="-d ${opt##*=}" ;;
|
|
||||||
esac; done
|
|
||||||
|
|
||||||
resolve_device "$luks_root"
|
|
||||||
|
|
||||||
set -- \
|
|
||||||
"$luks_key" "$luks_header" "$luks_discard" \
|
|
||||||
"$device" "${luks_name:-crypt-${device##*/}}"
|
|
||||||
|
|
||||||
cryptsetup open $@ || panic "failed to unlock LUKS"
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger_lvm()
|
|
||||||
{
|
|
||||||
[ "$break" = lvm ] && { print "break before trigger_lvm()"; sh; }
|
|
||||||
|
|
||||||
{ IFS=,; set -- $lvm_opts; unset IFS; }
|
|
||||||
|
|
||||||
for opt; do case "$opt" in
|
|
||||||
discard | discard=1) lvm_discard="--config=devices{issue_discards=1}" ;;
|
|
||||||
config=0) : > /etc/lvm/lvm.conf ;;
|
|
||||||
group=*) lvm_group="${opt##*=}" ;;
|
|
||||||
name=*) lvm_name="/${opt##*=}" ;;
|
|
||||||
tag=*) lvm_tag="@${opt##*=}" ;;
|
|
||||||
esac; done
|
|
||||||
|
|
||||||
set -- "--sysinit" "-qq" "-aay" "$lvm_discard"
|
|
||||||
|
|
||||||
if [ "$lvm_group" ] && [ "$lvm_name" ]; then
|
|
||||||
lvm lvchange $@ "${lvm_group}${lvm_name}"
|
|
||||||
elif [ "$lvm_group" ]; then
|
|
||||||
lvm vgchange $@ "$lvm_group"
|
|
||||||
elif [ "$lvm_tag" ]; then
|
|
||||||
lvm lvchange $@ "$lvm_tag"
|
|
||||||
else
|
|
||||||
lvm vgchange $@
|
|
||||||
fi || panic "failed to trigger LVM"
|
|
||||||
}
|
|
||||||
|
|
||||||
mount_root()
|
mount_root()
|
||||||
{
|
{
|
||||||
[ "$break" = root ] && { print "break before mount_root()"; sh; }
|
[ "$break" = root ] && { print "break before mount_root()"; sh; }
|
||||||
@ -184,6 +136,7 @@ boot_system()
|
|||||||
|
|
||||||
set -- "/mnt/root" "${init:-/sbin/init}" "$init_args"
|
set -- "/mnt/root" "${init:-/sbin/init}" "$init_args"
|
||||||
|
|
||||||
|
# POSIX exec has no -c flag to execute command with empty environment
|
||||||
# use 'env -i' to prevent leaking exported variables
|
# use 'env -i' to prevent leaking exported variables
|
||||||
exec env -i \
|
exec env -i \
|
||||||
TERM=linux \
|
TERM=linux \
|
||||||
@ -193,14 +146,16 @@ boot_system()
|
|||||||
|
|
||||||
# int main()
|
# int main()
|
||||||
{
|
{
|
||||||
|
# enable exit on error and disable globbing
|
||||||
|
# trap EXIT signal
|
||||||
|
set -ef; trap panic EXIT
|
||||||
|
|
||||||
prepare_environment
|
prepare_environment
|
||||||
|
run_hook init.early
|
||||||
parse_cmdline
|
parse_cmdline
|
||||||
setup_devmgr
|
setup_devmgr
|
||||||
|
|
||||||
# trigger lvm twice to handle both LUKS on LVM and LVM on LUKS
|
run_hook init
|
||||||
[ "$lvm" = 1 ] && trigger_lvm
|
|
||||||
[ "$luks" = 1 ] && unlock_luks
|
|
||||||
[ "$lvm" = 1 ] && trigger_lvm
|
|
||||||
|
|
||||||
mount_root
|
mount_root
|
||||||
boot_system
|
boot_system
|
||||||
|
689
tinyramfs
689
tinyramfs
@ -2,8 +2,6 @@
|
|||||||
#
|
#
|
||||||
# tiny initramfs
|
# tiny initramfs
|
||||||
#
|
#
|
||||||
# false positive
|
|
||||||
# shellcheck disable=2154
|
|
||||||
|
|
||||||
print()
|
print()
|
||||||
{
|
{
|
||||||
@ -19,41 +17,58 @@ panic()
|
|||||||
usage()
|
usage()
|
||||||
{
|
{
|
||||||
cat << EOF
|
cat << EOF
|
||||||
usage: $0 [option]
|
usage: ${0##*/} [option...]
|
||||||
-o, --output <file> set initramfs output path
|
-o, --output <file> set initramfs output path
|
||||||
|
default is /boot/initramfs-$(uname -r)
|
||||||
|
|
||||||
-c, --config <file> set config file path
|
-c, --config <file> set config file path
|
||||||
-m, --moddir <dir> set modules directory
|
default is /etc/tinyramfs/config
|
||||||
|
|
||||||
|
-m, --modules <dir> set modules directory
|
||||||
|
default is /lib/modules
|
||||||
|
|
||||||
|
-s, --sources <dir> set sources directory
|
||||||
|
default is /usr/share/tinyramfs
|
||||||
|
|
||||||
-k, --kernel <ver> set kernel version
|
-k, --kernel <ver> set kernel version
|
||||||
-F, --files <dir> set files directory
|
default is $(uname -r)
|
||||||
|
|
||||||
|
-H, --hooks <dir> set hooks directory
|
||||||
|
default is /etc/tinyramfs/hooks (user hooks)
|
||||||
|
and /usr/share/tinyramfs/hooks (system hooks)
|
||||||
|
|
||||||
-d, --debug enable debug mode
|
-d, --debug enable debug mode
|
||||||
-f, --force overwrite initramfs image
|
-f, --force overwrite initramfs image
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_args()
|
prepare_environment()
|
||||||
{
|
{
|
||||||
while [ "$1" ]; do case "$1" in
|
while [ "$1" ]; do case "$1" in
|
||||||
-o | --output)
|
-o | --output)
|
||||||
_output="${2:?}"; shift 2
|
output="${2:?}"; shift 2
|
||||||
;;
|
;;
|
||||||
-c | --config)
|
-c | --config)
|
||||||
_config="${2:?}"; shift 2
|
config="${2:?}"; shift 2
|
||||||
;;
|
;;
|
||||||
-m | --moddir)
|
-m | --modules)
|
||||||
_moddir="${2:?}"; shift 2
|
moddir="${2:?}"; shift 2
|
||||||
|
;;
|
||||||
|
-s | --sources)
|
||||||
|
srcdir="${2:?}"; shift 2
|
||||||
;;
|
;;
|
||||||
-k | --kernel)
|
-k | --kernel)
|
||||||
_kernel="${2:?}"; shift 2
|
kernel="${2:?}"; shift 2
|
||||||
;;
|
;;
|
||||||
-F | --files)
|
-H | --hooks)
|
||||||
_filesdir="${2:?}"; shift 2
|
hksdir="${2:?}"; shift 2
|
||||||
;;
|
;;
|
||||||
-d | --debug)
|
-d | --debug)
|
||||||
_debug=1; shift 1
|
debug=1; shift 1
|
||||||
;;
|
;;
|
||||||
-f | --force)
|
-f | --force)
|
||||||
_force=1; shift 1
|
force=1; shift 1
|
||||||
;;
|
;;
|
||||||
-h | --help)
|
-h | --help)
|
||||||
usage; exit 0
|
usage; exit 0
|
||||||
@ -64,370 +79,81 @@ parse_args()
|
|||||||
usage; exit 1
|
usage; exit 1
|
||||||
;;
|
;;
|
||||||
esac; done
|
esac; done
|
||||||
}
|
|
||||||
|
|
||||||
prepare_environment()
|
|
||||||
{
|
|
||||||
print "preparing environment"
|
print "preparing environment"
|
||||||
|
|
||||||
# false positive
|
. "${config:-/etc/tinyramfs/config}"
|
||||||
# shellcheck disable=1090
|
|
||||||
for _file in "$_config" /etc/tinyramfs/config; do
|
|
||||||
[ -f "$_file" ] && { . "$_file"; break; }
|
|
||||||
done || panic "failed to source config"
|
|
||||||
|
|
||||||
for _dir in "$_filesdir" /usr/share/tinyramfs; do
|
: "${kernel:=$(uname -r)}"
|
||||||
[ -d "$_dir" ] && { filesdir="$_dir"; break; }
|
: "${moddir:=/lib/modules}"
|
||||||
done || panic "failed to locate required files"
|
: "${srcdir:=/usr/share/tinyramfs}"
|
||||||
|
: "${output:=/boot/tinyramfs-${kernel}}"
|
||||||
|
|
||||||
# general variables
|
mkdir -p "${tmpdir:=${TMPDIR:-/tmp}/tinyramfs.$$}"
|
||||||
debug="${_debug:-${debug:-0}}"
|
|
||||||
force="${_force:-${force:-0}}"
|
|
||||||
moddir="${_moddir:-${moddir:-/lib/modules}}"
|
|
||||||
kernel="${_kernel:-${kernel:-$(uname -r)}}"
|
|
||||||
output="${_output:-${output:-/tmp/initramfs-${kernel}}}"
|
|
||||||
|
|
||||||
mkdir -p "${workdir=${XDG_CACHE_HOME:-${TMPDIR:-/tmp}}/initramfs.$$}"
|
|
||||||
|
|
||||||
# helpers variables
|
|
||||||
workdirbin="${workdir}/usr/bin/"
|
|
||||||
workdirlib="${workdir}/usr/lib/"
|
|
||||||
modker="${moddir}/${kernel}"
|
|
||||||
|
|
||||||
# false positive
|
# false positive
|
||||||
# shellcheck disable=2015
|
# shellcheck disable=2015
|
||||||
[ "$debug" = 1 ] && set -x || trap trap_helper EXIT INT
|
[ "$debug" = 1 ] && set -x || trap "rm -rf $tmpdir" EXIT INT
|
||||||
}
|
}
|
||||||
|
|
||||||
trap_helper()
|
prepare_initramfs()
|
||||||
{
|
{
|
||||||
[ "${ret=$?}" = 0 ] ||
|
print "preparing initramfs"
|
||||||
print "unexpected error occurred" \
|
|
||||||
"\033[1;31m!!\033[m" >&2
|
|
||||||
|
|
||||||
print "removing working directory"; rm -rf "$workdir"
|
|
||||||
exit "$ret"
|
|
||||||
}
|
|
||||||
|
|
||||||
populate_config()
|
|
||||||
{
|
|
||||||
printf "%s\n" "$@" >> "${workdir}/etc/tinyramfs/config"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_requirements()
|
|
||||||
{
|
|
||||||
print "installing requirements"
|
|
||||||
|
|
||||||
# install required binaries
|
|
||||||
for _binary in \[ sh ln kill mkdir env \
|
|
||||||
blkid sleep mount printf \
|
|
||||||
switch_root "${filesdir}/device-helper"
|
|
||||||
do
|
|
||||||
install_binary "$_binary"
|
|
||||||
done
|
|
||||||
|
|
||||||
# install user specified binaries
|
|
||||||
for _binary in $binaries; do
|
|
||||||
install_binary "$_binary"
|
|
||||||
done
|
|
||||||
|
|
||||||
# install init
|
|
||||||
install -m755 "${filesdir}/init" "${workdir}/init"
|
|
||||||
|
|
||||||
# fix ubase mount issue
|
|
||||||
: > "${workdir}/etc/fstab"
|
|
||||||
|
|
||||||
populate_config \
|
|
||||||
"root='$root'" \
|
|
||||||
"devmgr='$devmgr'" \
|
|
||||||
"root_type='$root_type'" \
|
|
||||||
"root_opts='$root_opts'"
|
|
||||||
}
|
|
||||||
|
|
||||||
create_structure()
|
|
||||||
{
|
|
||||||
print "creating directory structure"
|
|
||||||
|
|
||||||
|
# make directories
|
||||||
mkdir -p \
|
mkdir -p \
|
||||||
"${workdir}/dev" \
|
"${tmpdir}/dev" \
|
||||||
"${workdir}/sys" \
|
"${tmpdir}/sys" \
|
||||||
"${workdir}/tmp" \
|
"${tmpdir}/tmp" \
|
||||||
"${workdir}/run" \
|
"${tmpdir}/run" \
|
||||||
"${workdir}/var" \
|
"${tmpdir}/var" \
|
||||||
"${workdir}/proc" \
|
"${tmpdir}/proc" \
|
||||||
"${workdir}/root" \
|
"${tmpdir}/root" \
|
||||||
"${workdir}/usr/lib" \
|
"${tmpdir}/usr/lib" \
|
||||||
"${workdir}/usr/bin" \
|
"${tmpdir}/usr/bin" \
|
||||||
"${workdir}/mnt/root" \
|
"${tmpdir}/mnt/root" \
|
||||||
"${workdir}/etc/tinyramfs"
|
"${tmpdir}/etc/tinyramfs"
|
||||||
}
|
|
||||||
|
|
||||||
create_symlinks()
|
# make symlinks
|
||||||
{
|
ln -s usr/lib "${tmpdir}/lib"
|
||||||
print "creating symlinks"
|
ln -s usr/bin "${tmpdir}/bin"
|
||||||
|
ln -s usr/bin "${tmpdir}/sbin"
|
||||||
|
ln -s ../run "${tmpdir}/var/run"
|
||||||
|
ln -s ../run/lock "${tmpdir}/var/lock"
|
||||||
|
ln -s bin "${tmpdir}/usr/sbin"
|
||||||
|
|
||||||
ln -s usr/lib "${workdir}/lib"
|
# TODO make blkid optional
|
||||||
ln -s usr/lib "${workdir}/lib64"
|
# copy required binaries
|
||||||
ln -s usr/bin "${workdir}/bin"
|
for _binary in \
|
||||||
ln -s usr/bin "${workdir}/sbin"
|
\[ sh ln env kill mkdir \
|
||||||
ln -s ../run "${workdir}/var/run"
|
blkid sleep mount printf \
|
||||||
ln -s ../run/lock "${workdir}/var/lock"
|
switch_root "${srcdir}/device-helper"
|
||||||
ln -s bin "${workdir}/usr/sbin"
|
|
||||||
ln -s lib "${workdir}/usr/lib64"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_devmgr()
|
|
||||||
{
|
|
||||||
print "installing device manager"
|
|
||||||
|
|
||||||
# false positive
|
|
||||||
# shellcheck disable=2016
|
|
||||||
case "$devmgr" in
|
|
||||||
none)
|
|
||||||
# TODO implement mode without device manager using deprecated
|
|
||||||
# /sys/kernel/uevent_helper or /proc/sys/kernel/hotplug
|
|
||||||
;;
|
|
||||||
mdev)
|
|
||||||
for _binary in mdev find; do
|
|
||||||
install_binary "$_binary"
|
|
||||||
done
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'SUBSYSTEM=block;.* 0:0 660 @device-helper' \
|
|
||||||
> "${workdir}/etc/mdev.conf"
|
|
||||||
|
|
||||||
[ "$monolith" = 1 ] && return 0
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"' \
|
|
||||||
>> "${workdir}/etc/mdev.conf"
|
|
||||||
;;
|
|
||||||
mdevd)
|
|
||||||
for _binary in mdevd mdevd-coldplug; do
|
|
||||||
install_binary "$_binary"
|
|
||||||
done
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'SUBSYSTEM=block;.* 0:0 660 @device-helper' \
|
|
||||||
> "${workdir}/etc/mdev.conf"
|
|
||||||
|
|
||||||
[ "$monolith" = 1 ] && return 0
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"' \
|
|
||||||
>> "${workdir}/etc/mdev.conf"
|
|
||||||
;;
|
|
||||||
udev)
|
|
||||||
for _binary in udevd udevadm; do
|
|
||||||
install_binary "$_binary"
|
|
||||||
done
|
|
||||||
|
|
||||||
mkdir -p "${workdir}/usr/lib/udev/rules.d"
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'SUBSYSTEMS=="block", ACTION=="add", RUN+="/bin/device-helper"' \
|
|
||||||
> "${workdir}/usr/lib/udev/rules.d/device-helper.rules"
|
|
||||||
|
|
||||||
[ "$monolith" = 1 ] && return 0
|
|
||||||
|
|
||||||
printf "%s\n" \
|
|
||||||
'ENV{MODALIAS}=="?*", ACTION=="add", RUN+="/bin/modprobe %E{MODALIAS}"' \
|
|
||||||
>> "${workdir}/usr/lib/udev/rules.d/device-helper.rules"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
install_lvm()
|
|
||||||
{
|
|
||||||
print "installing LVM"
|
|
||||||
|
|
||||||
install_binary lvm
|
|
||||||
|
|
||||||
lvm_config="
|
|
||||||
devices {
|
|
||||||
write_cache_state = 0
|
|
||||||
}
|
|
||||||
backup {
|
|
||||||
backup = 0
|
|
||||||
archive = 0
|
|
||||||
}
|
|
||||||
global {
|
|
||||||
use_lvmetad = 0
|
|
||||||
}"
|
|
||||||
|
|
||||||
# word splitting is safe by design
|
|
||||||
# shellcheck disable=2086
|
|
||||||
{ IFS=,; set -- $lvm_opts; unset IFS; }
|
|
||||||
|
|
||||||
for opt; do case "$opt" in
|
|
||||||
config | config=1) embed_lvm_config=1 ;;
|
|
||||||
esac; done
|
|
||||||
|
|
||||||
mkdir -p "${workdir}/etc/lvm"
|
|
||||||
|
|
||||||
lvm config \
|
|
||||||
--config "$lvm_config" \
|
|
||||||
${embed_lvm_config+--mergedconfig} \
|
|
||||||
> "${workdir}/etc/lvm/lvm.conf"
|
|
||||||
|
|
||||||
populate_config "lvm='$lvm'" "lvm_opts='$lvm_opts'"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_luks()
|
|
||||||
{
|
|
||||||
print "installing LUKS"
|
|
||||||
|
|
||||||
install_binary cryptsetup
|
|
||||||
|
|
||||||
# fix libgcc_s.so.1 missing error
|
|
||||||
# see https://bugs.archlinux.org/task/56771
|
|
||||||
[ -e /usr/lib/libgcc_s.so.1 ] &&
|
|
||||||
install_library /usr/lib/libgcc_s.so.1
|
|
||||||
|
|
||||||
# word splitting is safe by design
|
|
||||||
# shellcheck disable=2086
|
|
||||||
{ IFS=,; set -- $luks_opts; unset IFS; }
|
|
||||||
|
|
||||||
for opt; do case "${opt%%=*}" in
|
|
||||||
key | header)
|
|
||||||
install -m400 "${opt##*=}" "${workdir}/root/${opt%%=*}" || panic
|
|
||||||
luks_opts=$(printf "%s" "$luks_opts" | sed "s|${opt##*=}|/root/${opt%%=*}|")
|
|
||||||
;;
|
|
||||||
esac; done
|
|
||||||
|
|
||||||
populate_config \
|
|
||||||
"luks='$luks'" \
|
|
||||||
"luks_root='$luks_root'" \
|
|
||||||
"luks_opts='$luks_opts'"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_module()
|
|
||||||
{
|
|
||||||
module="$1"
|
|
||||||
|
|
||||||
modprobe -S "$kernel" -D "$module" 2> /dev/null |
|
|
||||||
|
|
||||||
while read -r module || [ "$module" ]; do
|
|
||||||
|
|
||||||
# skip unneeded stuff
|
|
||||||
for _exclude_module in wmi gpu net builtin $modules_exclude; do
|
|
||||||
case "$module" in *"$_exclude_module"*) continue 2 ;; esac
|
|
||||||
done
|
|
||||||
|
|
||||||
module="${module#insmod }"
|
|
||||||
|
|
||||||
# check if module already installed
|
|
||||||
[ -e "${workdir}${module}" ] && continue
|
|
||||||
|
|
||||||
install -Dm644 "$module" "${workdir}${module}" || panic
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
install_hostonly_modules()
|
|
||||||
{
|
|
||||||
print "installing hostonly modules"
|
|
||||||
|
|
||||||
# perform autodetection of modules via /sys
|
|
||||||
find /sys -name modalias -exec sort -u {} + |
|
|
||||||
|
|
||||||
while read -r _module || [ "$_module" ]; do
|
|
||||||
install_module "$_module"
|
|
||||||
done
|
|
||||||
|
|
||||||
# install LVM modules
|
|
||||||
[ "$lvm" = 1 ] &&
|
|
||||||
for _module in dm-thin-pool dm-multipath \
|
|
||||||
dm-snapshot dm-cache dm-log dm-mirror
|
|
||||||
do
|
do
|
||||||
install_module "$_module"
|
copy_binary "$_binary"
|
||||||
done
|
done
|
||||||
|
|
||||||
# install LUKS modules
|
# copy init
|
||||||
[ "$luks" = 1 ] &&
|
cp "${srcdir}/init" "${tmpdir}/init"
|
||||||
for _module in aes dm-crypt sha256 sha512 \
|
chmod 755 "${tmpdir}/init"
|
||||||
wp512 ecb lrw xts twofish serpent
|
|
||||||
do
|
|
||||||
install_module "$_module"
|
|
||||||
done
|
|
||||||
|
|
||||||
# install root filesystem module
|
# copy config
|
||||||
if [ "$root_type" ]; then
|
cp "$config" "${tmpdir}/etc/tinyramfs/config"
|
||||||
install_module "$root_type"
|
chmod 600 "${tmpdir}/etc/tinyramfs/config"
|
||||||
else
|
|
||||||
while read -r _ _dir _type _; do
|
|
||||||
[ "$_dir" = / ] || continue
|
|
||||||
|
|
||||||
install_module "${root_type=$_type}"; break
|
|
||||||
done < /proc/mounts || panic
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
install_all_modules()
|
copy_binary()
|
||||||
{
|
|
||||||
print "installing all modules"
|
|
||||||
|
|
||||||
find \
|
|
||||||
"${modker}/kernel/fs" \
|
|
||||||
"${modker}/kernel/lib" \
|
|
||||||
"${modker}/kernel/arch" \
|
|
||||||
"${modker}/kernel/crypto" \
|
|
||||||
"${modker}/kernel/drivers/md" \
|
|
||||||
"${modker}/kernel/drivers/ata" \
|
|
||||||
"${modker}/kernel/drivers/scsi" \
|
|
||||||
"${modker}/kernel/drivers/block" \
|
|
||||||
"${modker}/kernel/drivers/virtio" \
|
|
||||||
"${modker}/kernel/drivers/usb/host" \
|
|
||||||
"${modker}/kernel/drivers/usb/storage" \
|
|
||||||
-type f 2> /dev/null |
|
|
||||||
|
|
||||||
while read -r _module || [ "$_module" ]; do
|
|
||||||
|
|
||||||
# strip path and extension
|
|
||||||
_module="${_module##*/}"
|
|
||||||
_module="${_module%%.*}"
|
|
||||||
|
|
||||||
install_module "$_module"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
install_modules()
|
|
||||||
{
|
|
||||||
if [ "$hostonly" = 1 ]; then
|
|
||||||
install_hostonly_modules
|
|
||||||
else
|
|
||||||
install_all_modules
|
|
||||||
fi
|
|
||||||
|
|
||||||
# install user specified modules if any
|
|
||||||
[ "$modules" ] && {
|
|
||||||
for _module in $modules; do
|
|
||||||
install_module "$_module"
|
|
||||||
done; populate_config "modules='$modules'"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_binary modprobe
|
|
||||||
|
|
||||||
install -m644 \
|
|
||||||
"${modker}/modules.builtin" \
|
|
||||||
"${modker}/modules.order" \
|
|
||||||
"${workdir}${modker}"
|
|
||||||
|
|
||||||
depmod -b "$workdir" "$kernel"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_binary()
|
|
||||||
{
|
{
|
||||||
binary=$(command -v "$1")
|
binary=$(command -v "$1")
|
||||||
|
|
||||||
# check if binary exist and builtin
|
# check if binary exist and builtin
|
||||||
case "$binary" in */*) ;;
|
case "$binary" in */*) ;;
|
||||||
"")
|
"")
|
||||||
panic "$1 doesn't exist"
|
panic "$1 does not exist"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# word splitting is safe by design
|
# word splitting is safe by design
|
||||||
# shellcheck disable=2086
|
# shellcheck disable=2086
|
||||||
{ IFS=:; set -- $PATH; unset IFS; }
|
IFS=:; set -- $PATH; unset IFS
|
||||||
|
|
||||||
# assume that `command -v` returned builtin command.
|
# assume that `command -v` returned builtin command.
|
||||||
# this behavior depends on shell implementation.
|
# this behavior depends on shell implementation.
|
||||||
@ -437,24 +163,27 @@ install_binary()
|
|||||||
[ -x "${_dir}/${binary}" ] || ! continue
|
[ -x "${_dir}/${binary}" ] || ! continue
|
||||||
|
|
||||||
binary="${_dir}/${binary}"; break
|
binary="${_dir}/${binary}"; break
|
||||||
done || panic "couldn't find external $1"
|
done || panic "$1 does not exist"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# check if binary already installed
|
# check if binary already exist
|
||||||
[ -e "${workdirbin}${binary##*/}" ] && return 0
|
[ -e "${tmpdir}/bin/${binary##*/}" ] && return 0
|
||||||
|
|
||||||
# iterate throught symlinks and copy them
|
# iterate throught symlinks and copy them
|
||||||
while [ -h "$binary" ]; do
|
while [ -h "$binary" ]; do symlink=$(ls -ld "$binary")
|
||||||
cp -P "$binary" "$workdirbin" || panic
|
cp -P "$binary" "${tmpdir}/bin" || panic
|
||||||
readlink_binary=$(readlink "$binary")
|
binary="${binary%/*}/${symlink##* ->*[ /]}"
|
||||||
binary="${binary%/*}/${readlink_binary##*/}"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
install -m755 "$binary" "${workdirbin}${binary##*/}" || panic
|
{
|
||||||
strip "${workdirbin}${binary##*/}" > /dev/null 2>&1 || :
|
cp "$binary" "${tmpdir}/bin"
|
||||||
|
chmod 755 "${tmpdir}/bin/${binary##*/}"
|
||||||
|
} || panic
|
||||||
|
|
||||||
# install binary dependencies if any
|
strip "${tmpdir}/bin/${binary##*/}" > /dev/null 2>&1 || :
|
||||||
|
|
||||||
|
# copy binary dependencies if any
|
||||||
ldd "$binary" 2> /dev/null |
|
ldd "$binary" 2> /dev/null |
|
||||||
|
|
||||||
while read -r _library || [ "$_library" ]; do
|
while read -r _library || [ "$_library" ]; do
|
||||||
@ -465,44 +194,229 @@ install_binary()
|
|||||||
_library="${_library#* => }"
|
_library="${_library#* => }"
|
||||||
_library="${_library% *}"
|
_library="${_library% *}"
|
||||||
|
|
||||||
install_library "$_library"
|
copy_library "$_library"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
install_library()
|
copy_library()
|
||||||
{
|
{
|
||||||
library="$1"
|
library="$1"
|
||||||
|
|
||||||
# check if library already installed
|
# check if library already exist
|
||||||
[ -e "${workdirlib}${library##*/}" ] && return 0
|
[ -e "${tmpdir}/lib/${library##*/}" ] && return 0
|
||||||
|
|
||||||
# iterate throught symlinks and copy them
|
# iterate throught symlinks and copy them
|
||||||
while [ -h "$library" ]; do
|
while [ -h "$library" ]; do symlink=$(ls -ld "$library")
|
||||||
cp -P "$library" "$workdirlib" || panic
|
cp -P "$library" "${tmpdir}/lib" || panic
|
||||||
readlink_library=$(readlink "$library")
|
library="${library%/*}/${symlink##* ->*[ /]}"
|
||||||
library="${library%/*}/${readlink_library##*/}"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
install -m755 "$library" "${workdirlib}${library##*/}" || panic
|
{
|
||||||
strip "${workdirlib}${library##*/}" > /dev/null 2>&1 || :
|
cp "$library" "${tmpdir}/lib"
|
||||||
|
chmod 755 "${tmpdir}/lib/${library##*/}"
|
||||||
|
} || panic
|
||||||
|
|
||||||
|
strip "${tmpdir}/lib/${library##*/}" > /dev/null 2>&1 || :
|
||||||
}
|
}
|
||||||
|
|
||||||
create_initramfs()
|
copy_module()
|
||||||
|
{
|
||||||
|
module="$1"
|
||||||
|
|
||||||
|
modprobe -S "$kernel" -D "$module" 2> /dev/null |
|
||||||
|
|
||||||
|
while read -r _ module || [ "$module" ]; do
|
||||||
|
|
||||||
|
# check if module contains full path(not builtin)
|
||||||
|
[ "${module##*/*}" ] && continue
|
||||||
|
|
||||||
|
# check if module already exist
|
||||||
|
[ -e "${tmpdir}${module}" ] && continue
|
||||||
|
|
||||||
|
{
|
||||||
|
mkdir -p "${tmpdir}${module%/*}"
|
||||||
|
cp "$module" "${tmpdir}${module}"
|
||||||
|
chmod 644 "${tmpdir}${module}"
|
||||||
|
} || panic
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_hook()
|
||||||
|
{
|
||||||
|
hook="$1"
|
||||||
|
|
||||||
|
for _dir in "$hksdir" /etc/tinyramfs/hooks /usr/share/tinyramfs/hooks; do
|
||||||
|
[ -f "${_dir}/${hook}/${hook}" ] || ! continue
|
||||||
|
|
||||||
|
print "running $hook hook"; . "${_dir}/${hook}/${hook}"
|
||||||
|
|
||||||
|
if [ -f "${_dir}/${hook}/${hook}.init" ]; then
|
||||||
|
mkdir -p "${tmpdir}/usr/share/tinyramfs/hooks/${hook##*/}"
|
||||||
|
cp "${_dir}/${hook}/${hook}.init" \
|
||||||
|
"${tmpdir}/usr/share/tinyramfs/hooks/${hook##*/}"
|
||||||
|
|
||||||
|
elif [ -f "${_dir}/${hook}/${hook}.init.early" ]; then
|
||||||
|
mkdir -p "${tmpdir}/usr/share/tinyramfs/hooks/${hook##*/}"
|
||||||
|
cp "${_dir}/${hook}/${hook}.init.early" \
|
||||||
|
"${tmpdir}/usr/share/tinyramfs/hooks/${hook##*/}"
|
||||||
|
fi || panic
|
||||||
|
|
||||||
|
break
|
||||||
|
done || panic "could not run $hook"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_modules()
|
||||||
|
{
|
||||||
|
# skip this function if kernel
|
||||||
|
# compiled with builtin modules
|
||||||
|
if [ "$monolith" = 1 ]; then
|
||||||
|
print "skipping modules"
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif [ "$hostonly" = 1 ]; then
|
||||||
|
print "copying hostonly modules"
|
||||||
|
|
||||||
|
# perform autodetection of modules via /sys
|
||||||
|
# see https://wiki.archlinux.org/index.php/Modalias
|
||||||
|
find /sys/devices -name modalias -exec sort -u {} + |
|
||||||
|
|
||||||
|
while read -r _module || [ "$_module" ]; do
|
||||||
|
|
||||||
|
# skip unneeded modules and skip modules which
|
||||||
|
# depends on them as well
|
||||||
|
case $(modprobe -S "$kernel" -D "$_module") in
|
||||||
|
*wmi* | *gpu* | *net*) continue ;;
|
||||||
|
esac 2> /dev/null
|
||||||
|
|
||||||
|
copy_module "$_module"
|
||||||
|
done
|
||||||
|
|
||||||
|
# copy root filesystem module
|
||||||
|
if [ "$root_type" ]; then
|
||||||
|
copy_module "$root_type"
|
||||||
|
else
|
||||||
|
while read -r _ _dir _type _; do
|
||||||
|
[ "$_dir" = / ] || ! continue
|
||||||
|
|
||||||
|
copy_module "$_type"; break
|
||||||
|
done < /proc/mounts ||
|
||||||
|
panic "could not copy root fs module"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print "copying all modules"
|
||||||
|
|
||||||
|
find \
|
||||||
|
"${moddir}/${kernel}/kernel/fs" \
|
||||||
|
"${moddir}/${kernel}/kernel/lib" \
|
||||||
|
"${moddir}/${kernel}/kernel/arch" \
|
||||||
|
"${moddir}/${kernel}/kernel/crypto" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/md" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/ata" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/scsi" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/block" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/virtio" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/usb/host" \
|
||||||
|
"${moddir}/${kernel}/kernel/drivers/usb/storage" \
|
||||||
|
-type f 2> /dev/null |
|
||||||
|
|
||||||
|
while read -r _module || [ "$_module" ]; do
|
||||||
|
|
||||||
|
# strip path and extension
|
||||||
|
_module="${_module##*/}"
|
||||||
|
_module="${_module%%.*}"
|
||||||
|
|
||||||
|
# skip unneeded modules and skip modules which
|
||||||
|
# depends on them as well
|
||||||
|
case $(modprobe -S "$kernel" -D "$_module") in
|
||||||
|
*wmi* | *gpu* | *net*) continue ;;
|
||||||
|
esac 2> /dev/null
|
||||||
|
|
||||||
|
copy_module "$_module"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
copy_binary modprobe
|
||||||
|
|
||||||
|
cp "${moddir}/${kernel}/modules.builtin" \
|
||||||
|
"${moddir}/${kernel}/modules.order" \
|
||||||
|
"${tmpdir}${moddir}/${kernel}"
|
||||||
|
|
||||||
|
chmod 644 \
|
||||||
|
"${tmpdir}${moddir}/${kernel}/modules.builtin" \
|
||||||
|
"${tmpdir}${moddir}/${kernel}/modules.order"
|
||||||
|
|
||||||
|
depmod -b "$tmpdir" "$kernel"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_devmgr()
|
||||||
|
{
|
||||||
|
print "configuring device manager"
|
||||||
|
|
||||||
|
# false positive
|
||||||
|
# shellcheck disable=2016
|
||||||
|
case "$devmgr" in
|
||||||
|
none)
|
||||||
|
# TODO implement mode without device manager using deprecated
|
||||||
|
# /sys/kernel/uevent_helper or /proc/sys/kernel/hotplug
|
||||||
|
;;
|
||||||
|
mdev)
|
||||||
|
for _binary in mdev find; do
|
||||||
|
copy_binary "$_binary"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "%s\n" \
|
||||||
|
'SUBSYSTEM=block;.* 0:0 660 @device-helper' \
|
||||||
|
> "${tmpdir}/etc/mdev.conf"
|
||||||
|
|
||||||
|
[ "$monolith" = 1 ] || printf "%s\n" \
|
||||||
|
'$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"' \
|
||||||
|
>> "${tmpdir}/etc/mdev.conf"
|
||||||
|
;;
|
||||||
|
mdevd)
|
||||||
|
for _binary in mdevd mdevd-coldplug; do
|
||||||
|
copy_binary "$_binary"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf "%s\n" \
|
||||||
|
'SUBSYSTEM=block;.* 0:0 660 @device-helper' \
|
||||||
|
> "${tmpdir}/etc/mdev.conf"
|
||||||
|
|
||||||
|
[ "$monolith" = 1 ] || printf "%s\n" \
|
||||||
|
'$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"' \
|
||||||
|
>> "${tmpdir}/etc/mdev.conf"
|
||||||
|
;;
|
||||||
|
udev)
|
||||||
|
# why systemd violates FHS and places daemon in /lib ?
|
||||||
|
udevd=$(command -v /lib/systemd/systemd-udevd) || udevd=udevd
|
||||||
|
|
||||||
|
for _binary in "$udevd" udevadm; do
|
||||||
|
copy_binary "$_binary"
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p "${tmpdir}/lib/udev/rules.d"
|
||||||
|
|
||||||
|
printf "%s\n" \
|
||||||
|
'SUBSYSTEMS=="block", ACTION=="add", RUN+="/bin/device-helper"' \
|
||||||
|
> "${tmpdir}/lib/udev/rules.d/device-helper.rules"
|
||||||
|
|
||||||
|
[ "$monolith" = 1 ] || printf "%s\n" \
|
||||||
|
'ENV{MODALIAS}=="?*", ACTION=="add", RUN+="/bin/modprobe %E{MODALIAS}"' \
|
||||||
|
>> "${tmpdir}/lib/udev/rules.d/device-helper.rules"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
make_initramfs()
|
||||||
(
|
(
|
||||||
print "creating initramfs image"
|
print "generating initramfs image"
|
||||||
|
|
||||||
# check if image already exist
|
# check if image already exist
|
||||||
[ "$force" != 1 ] && [ -e "$output" ] &&
|
[ "$force" != 1 ] && [ -e "$output" ] &&
|
||||||
panic "initramfs image already exist"
|
panic "initramfs image already exist"
|
||||||
|
|
||||||
cd "$workdir"; find . |
|
cd "$tmpdir"; find . |
|
||||||
|
cpio -oH newc 2> /dev/null |
|
||||||
if [ "$compress" = none ]; then
|
${compress:-cat} > "$output" ||
|
||||||
cpio -oH newc
|
|
||||||
else
|
|
||||||
cpio -oH newc | ${compress:-gzip -9}
|
|
||||||
fi \
|
|
||||||
> "$output" 2> /dev/null ||
|
|
||||||
panic "failed to generate initramfs image"
|
panic "failed to generate initramfs image"
|
||||||
|
|
||||||
print "done! check out $output"
|
print "done! check out $output"
|
||||||
@ -515,16 +429,15 @@ create_initramfs()
|
|||||||
# enable exit on error and disable globbing
|
# enable exit on error and disable globbing
|
||||||
set -ef
|
set -ef
|
||||||
|
|
||||||
parse_args "$@"
|
prepare_environment "$@"
|
||||||
prepare_environment
|
prepare_initramfs
|
||||||
create_structure
|
|
||||||
create_symlinks
|
|
||||||
|
|
||||||
[ "$lvm" = 1 ] && install_lvm
|
# copy and run hooks if any
|
||||||
[ "$luks" = 1 ] && install_luks
|
for _hook in $hooks; do
|
||||||
[ "$monolith" = 1 ] || install_modules
|
copy_hook "$_hook"
|
||||||
|
done
|
||||||
|
|
||||||
install_devmgr
|
copy_devmgr
|
||||||
install_requirements
|
copy_modules
|
||||||
create_initramfs
|
make_initramfs
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user