From 3200b2da25fde1fa4ead02c12753069a817ee9eb Mon Sep 17 00:00:00 2001 From: illiliti Date: Tue, 28 Jan 2020 18:13:42 +0300 Subject: [PATCH] busybox mdev and mdevd support --- config | 9 ++++ generate | 122 ++++++++++++++++++++++++-------------------- init | 65 ++++++++++++++++++----- mdev.conf | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ storage-device | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 392 insertions(+), 68 deletions(-) create mode 100644 mdev.conf create mode 100755 storage-device diff --git a/config b/config index 26623fa..ed8f5af 100644 --- a/config +++ b/config @@ -14,6 +14,15 @@ root="UUID=07729c48-25d8-4096-acaf-ce5322915680" # root mount options #root_args="" +# mdevd support +use_mdevd=0 + +# busybox mdev support +use_mdev=1 + +# udev support +use_udev=0 + # drivers #drivers="" diff --git a/generate b/generate index 06acc55..aaaa284 100755 --- a/generate +++ b/generate @@ -28,87 +28,97 @@ fi tmpdir="$(mktemp -d /tmp/initramfs.XXXXXXXX)" kernel="$(uname -r)" moddir="/lib/modules" -binaries="./busybox findfs blkid udevd udevadm mount modprobe umount $binaries" +binaries="./busybox findfs blkid mount modprobe umount $binaries" # structure -for d in dev var run etc usr/lib usr/bin mnt/root proc root sys; do +for d in dev tmp var run etc usr/lib usr/bin mnt/root proc root sys; do mkdir -p "$tmpdir/$d" done # symlinks ( cd "$tmpdir" && { - ln -s "usr/lib" "lib" - ln -s "usr/lib" "lib64" - ln -s "usr/bin" "bin" - ln -s "usr/bin" "sbin" + ln -s usr/lib lib + ln -s usr/lib lib64 + ln -s usr/bin bin + ln -s usr/bin sbin + ln -s ../run var/run cd "$tmpdir/usr" - ln -s "bin" "sbin" - ln -s "lib" "lib64" + ln -s bin sbin + ln -s lib lib64 } ) # TODO parse fstab | crypttab #while [ "$use_fstab" -eq 1 ] && read fs dir type opts; do thing; done < /etc/fstab -# TODO implement busybox mdev/mdevd -# install mdev -#mkdir "$tmpdir/usr/lib/mdev" -#cp ./mdev/mdev.conf ./mdev/passwd ./mdev/group "$tmpdir/etc" -#cp ./mdev/usbdev ./mdev/usbdisk_link ./mdev/ide_links "$tmpdir/usr/lib/mdev" -#chmod +x $tmpdir/usr/lib/mdev/* +# handle device managers +if [ "$use_mdevd" = 1 ]; then + # install mdevd + binaries="mdevd mdevd-coldplug $binaries" + mkdir "$tmpdir/lib/mdev" + cp mdev.conf "$tmpdir/etc" + cp storage-device "$tmpdir/lib/mdev" + chmod +x "$tmpdir/lib/mdev/storage-device" +elif [ "$use_mdev" = 1 ]; then + # install mdev + mkdir "$tmpdir/lib/mdev" + cp mdev.conf "$tmpdir/etc" + cp storage-device "$tmpdir/lib/mdev" + chmod +x "$tmpdir/lib/mdev/storage-device" +elif [ "$use_udev" = 1 ]; then + # install udev + binaries="udevd udevadm dmsetup $binaries" + find /usr/lib/udev -type f | grep -v "rc_keymaps\|hwdb.d" | cpio -pd "$tmpdir" +fi -# install udev -find "/usr/lib/udev" -type f | grep -v "rc_keymaps\|hwdb.d" | cpio -pd "$tmpdir" +cat < "$tmpdir/etc/group" +root:x:0: +tty:x:5: +dialout:x:11: +uucp:x:14: +kmem:x:3: +input:x:25: +video:x:13: +audio:x:12: +lp:x:10: +disk:x:9: +cdrom:x:16: +tape:x:6: +kvm:x:24: +floppy:x:8: +EOF -#cat < "$tmpdir/etc/group" -#root:x:0: -#tty:x:5: -#dialout:x:11: -#kmem:x:3: -#input:x:25: -#video:x:13: -#audio:x:12: -#lp:x:10: -#disk:x:9: -#cdrom:x:16: -#tape:x:6: -#kvm:x:24: -#floppy:x:8: -#EOF - -#cat < "$tmpdir/etc/passwd" -#root:x:0:0::/root:/bin/sh -#nobody:x:99:99::/dev/null:/bin/false -#EOF +cat < "$tmpdir/etc/passwd" +root:x:0:0::/root:/bin/sh +nobody:x:99:99::/:/bin/false +EOF # handle lvm if [ "$use_lvm" = 1 ] && [ -x "$(command -v lvm)" ]; then - binaries="lvm dmsetup $binaries" - mkdir "$tmpdir/etc/lvm" + binaries="lvm $binaries" + #mkdir "$tmpdir/etc/lvm" - # avoid lvmetad warning message - echo "use_lvmetad = 0" >> "$tmpdir/etc/lvm/lvm.conf" - - if [ "$lvm_discard" = 1 ]; then - echo "issue_discards = 1" >> "$tmpdir/etc/lvm/lvm.conf" - fi + # use_lvmetad = 0 - avoid lvmetad missing warning message + #cat < "$tmpdir/etc/lvm/lvmlocal.conf" + #local { + # issue_discards = ${lvm_discard:-0} + # use_lvmetad = 0 + #} + #EOF # TODO implement use_lvmconf fi # handle luks if [ "$use_luks" = 1 ] && [ -x "$(command -v cryptsetup)" ]; then - binaries="cryptsetup dmsetup $binaries" + binaries="cryptsetup $binaries" # avoid locking directory missing warning message mkdir "$tmpdir/run/cryptsetup" # TODO get rid of this workaround # workaround for luks2 - cp "$(readlink -f libgcc_s.so.1)" "$tmpdir/usr/lib" - cp -a /usr/lib/libgcc_s.so.1 "$tmpdir/usr/lib" + cp /usr/lib/libgcc_s.so.1 "$tmpdir/usr/lib" - if [ "$luks_discard" = 1 ]; then - luks_args="--allow-discards $luks_args" - fi + [ "$luks_discard" = 1 ] && luks_args="--allow-discards $luks_args" # TODO detached header # TODO keyfile @@ -158,10 +168,13 @@ for b in $(echo $binaries); do # check symlink if [ -h "$l" ]; then # check lib already existence - if [ ! -e "$tmpdir/usr/lib/${l##*/}" ] && [ ! -e "$tmpdir/usr/lib/$(readlink $l)" ]; then + if [ ! -e "$tmpdir/usr/lib/${l##*/}" ] && [ ! -e "$tmpdir$(readlink -f $l)" ]; then # regular cp "$(readlink -f $l)" "$tmpdir/usr/lib" - strip -s "$tmpdir/usr/lib/$(readlink $l)" + strip -s "$tmpdir$(readlink -f $l)" + # TODO handle all symlinks + # symlink may link to symlink + [ -h "/usr/lib/$(readlink $l)" ] && cp -a "/usr/lib/$(readlink $l)" "$tmpdir/usr/lib" # symlink cp -a "$l" "$tmpdir/usr/lib" fi @@ -183,14 +196,15 @@ cat < "$tmpdir/config" root="$root" root_type="$root_type" root_args="$root_args" +use_mdevd="$use_mdevd" +use_mdev="$use_mdev" +use_udev="$use_udev" #drivers="$drivers" use_lvm="$use_lvm" -lvm_discard="$lvm_discard" use_luks="$use_luks" luks_root="$luks_root" luks_header="$luks_header" luks_keyfile="$luks_keyfile" -luks_discard="$luks_discard" luks_args="$luks_args" EOF diff --git a/init b/init index 2ba1ab8..9aa3490 100644 --- a/init +++ b/init @@ -9,7 +9,9 @@ set -x panic() { echo "bruh moment :(" && sh; } # silence is golden -#echo 0 > /proc/sys/kernel/printk +#echo 0 >/proc/sys/kernel/printk + +# TODO parse /proc/cmdline # check config [ -f /config ] && . /config || panic @@ -19,18 +21,49 @@ mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none /dev -# TODO implement busybox mdev/mdevd -# setup mdev -#echo /sbin/mdev >/proc/sys/kernel/hotplug -#mdev -s +# handle device managers +if [ "$use_mdevd" = 1 ]; then + # setup mdevd + mdevd & + # trigger uevents + mdevd-coldplug -# setup udev -udevd --daemon -udevadm trigger --action=add --type=subsystems -udevadm trigger --action=add --type=devices -udevadm settle + # TODO investigate this + # avoid race condition + sleep 1.5 +elif [ "$use_mdev" = 1 ]; then + # setup mdev + if [ -e /proc/sys/kernel/hotplug ]; then + echo /sbin/mdev >/proc/sys/kernel/hotplug + else + uevent mdev & + fi -# TODO parse /proc/cmdline + # trigger mdev + mdev -s + + # trigger uevent for usb devices + for u in /sys/bus/usb/devices/*; do + case ${u##*/} in + [0-9]*-[0-9]*) + echo add > "$u/uevent" + ;; + esac + done + + # load drivers + find /sys -name 'modalias' -type f -exec cat '{}' + | sort -u | xargs modprobe -ba +elif [ "$use_udev" = 1 ]; then + # setup udev + udevd --daemon + udevadm trigger --action=add --type=subsystems + udevadm trigger --action=add --type=devices + udevadm settle +else + panic +fi + +# TODO handle situations when LUKS on LVM # unlock cryptsetup container [ "$use_luks" = 1 ] && { @@ -39,8 +72,10 @@ udevadm settle cryptsetup $luks_args luksOpen "$luks_root" luks_root || panic } -# load drivers -#modprobe -a $drivers +# manually trigger LVM if udev disabled +[ "$use_lvm" = 1 ] && [ "$use_udev" = 0 ] && { + lvm vgchange --sysinit -a y +} # merge mount flags [ -n "$root_args" ] && mount_args="$root_args" @@ -50,7 +85,9 @@ udevadm settle mount $mount_args "$root" /mnt/root || panic # clean up -udevadm control --exit +[ "$use_mdevd" = 1 ] && killall mdevd +[ "$use_mdev" = 1 ] && { echo "" >/proc/sys/kernel/hotplug || killall uevent; } +[ "$use_udev" = 1 ] && udevadm control --exit umount /dev /sys /proc # boot system diff --git a/mdev.conf b/mdev.conf new file mode 100644 index 0000000..1d296df --- /dev/null +++ b/mdev.conf @@ -0,0 +1,136 @@ +# Copyright (c) 2012-2019, Piotr Karbowski +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list +# of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# * Neither the name of the Piotr Karbowski nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# mdev-like-a-boss + +# Syntax: +# [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# +# [-]: do not stop on this match, continue reading mdev.conf +# =: move, >: move and create a symlink +# !: do not create device node +# @|$|*: run cmd if $ACTION=remove, @cmd if $ACTION=add, *cmd in all cases + +# support module loading on hotplug +$MODALIAS=.* 0:0 660 @modprobe -b "$MODALIAS" + +# null may already exist; therefore ownership has to be changed with command +null 0:0 666 @chmod 666 $MDEV +zero 0:0 666 +full 0:0 666 +random 0:0 444 +urandom 0:0 444 +hwrandom 0:0 444 +grsec 0:0 660 + +# Kernel-based Virtual Machine. +#kvm root:kvm 660 + +# vhost-net, to be used with kvm. +#vhost-net root:kvm 660 + +kmem 0:0 640 +mem 0:0 640 +port 0:0 640 +# console may already exist; therefore ownership has to be changed with command +console 0:5 600 @chmod 600 $MDEV +ptmx 0:5 666 +pty.* 0:5 660 + +# Typical devices +tty 0:5 666 +tty[0-9]* 0:5 660 +vcsa*[0-9]* 0:5 660 +ttyS[0-9]* 0:14 660 + +# block devices +ram([0-9]*) 0:9 660 >rd/%1 +loop([0-9]+) 0:9 660 >loop/%1 +sr[0-9]* 0:16 660 @ln -sf $MDEV cdrom +fd[0-9]* 0:8 660 +SUBSYSTEM=block;.* 0:9 660 */lib/mdev/storage-device + +# Run settle-nics every time new NIC appear. +# If you don't want to auto-populate /etc/mactab with NICs, run 'settle-nis' without '--write-mactab' param. +#-SUBSYSTEM=net;DEVPATH=.*/net/.*;.* 0:0 600 @/lib/mdev/settle-nics --write-mactab + +#net/tun[0-9]* root:kvm 660 +#net/tap[0-9]* 0:0 600 + +# alsa sound devices and audio stuff +#SUBSYSTEM=sound;.* root:audio 660 @/lib/mdev/sound-control + +#adsp root:audio 660 >sound/ +#audio root:audio 660 >sound/ +#dsp root:audio 660 >sound/ +#mixer root:audio 660 >sound/ +#sequencer.* root:audio 660 >sound/ + + +# raid controllers +cciss!(.*) 0:9 660 =cciss/%1 +ida!(.*) 0:9 660 =ida/%1 +rd!(.*) 0:9 660 =rd/%1 + + +#fuse 0:0 666 + +card[0-9] 0:13 660 =dri/ + +agpgart 0:0 660 >misc/ +psaux 0:0 660 >misc/ +rtc 0:0 664 >misc/ + +# input stuff +SUBSYSTEM=input;.* 0:25 660 + +# v4l stuff +#vbi[0-9] 0:13 660 >v4l/ +#video[0-9] 0:13 660 >v4l/ + +# dvb stuff +#dvb.* 0:13 660 + +# drm etc +dri/.* 0:13 660 + +# Don't create old usbdev* devices. +usbdev[0-9].[0-9]* 0:0 660 ! + +# Stop creating x:x:x:x which looks like /dev/dm-* +[0-9]+\:[0-9]+\:[0-9]+\:[0-9]+ 0:0 660 ! + +# /dev/cpu support. +microcode 0:0 600 =cpu/ +cpu([0-9]+) 0:0 600 =cpu/%1/cpuid +msr([0-9]+) 0:0 600 =cpu/%1/msr + +# Populate /dev/bus/usb. +#SUBSYSTEM=usb;DEVTYPE=usb_device;.* 0:0 660 */lib/mdev/dev-bus-usb + +# Catch-all other devices, Right now useful only for debuging. +#.* 0:0 660 */opt/mdev/helpers/catch-all diff --git a/storage-device b/storage-device new file mode 100755 index 0000000..4e74670 --- /dev/null +++ b/storage-device @@ -0,0 +1,128 @@ +#!/bin/sh +# Copyright (c) 2012-2019, Piotr Karbowski +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list +# of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# * Neither the name of the Piotr Karbowski nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This script meant to create /dev/disk/by-* and /dev/mapper/* symlinks. +# and remove them after storage device is removed. +# the /dev/disk/by-* handling based on the idea and proof of concept from BitJam. + +# debug +#exec >> /run/debug-mdev 2>&1 +#set -x +#echo '### ENV:' +#env +#echo '### CODE:' +# + +umask 077 + +storage_dir="/dev/.mdev-like-a-boss" +[ -d "${storage_dir}" ] || mkdir "${storage_dir}" + +[ "${MDEV}" ] || exit 2 + +create_uuid_label_symlink() { + local target_dir="/dev/disk/by-${1}" + local target_symlink="${target_dir}/${2}" + [ -e "${target_symlink}" ] && return + mkdir -p "${target_dir}" + ln -snf "/dev/${MDEV}" "${target_symlink}" + echo "${target_symlink}" >"${storage_dir}/storage_symlink_${1}_${MDEV}" +} + +add_symlinks() { + # Skip temp cryptsetup nodes. + case "${MDEV}" in + 'dm-'[0-9]*) + case "$(cat "/sys/block/${MDEV}/dm/name")" in + 'temporary-cryptsetup-'[0-9]*) + return 0 + ;; + esac + ;; + esac + + if command -v blkid >/dev/null 2>&1; then + local field name value UUID LABEL TYPE PTTYPE PARTUUID + local blkid_output="$(blkid "/dev/${MDEV}")" + eval "${blkid_output#*: }" + + [ "${UUID}" ] && create_uuid_label_symlink 'uuid' "${UUID}" + [ "${LABEL}" ] && create_uuid_label_symlink 'label' "${LABEL}" + [ "${PARTUUID}" ] && create_uuid_label_symlink 'partuuid' "${PARTUUID}" + fi + + if [ -f "/sys/block/${MDEV}/dm/name" ]; then + [ -d '/dev/mapper' ] || mkdir '/dev/mapper' + if ! [ -c '/dev/mapper/control' ]; then + awk '$2 == "device-mapper" { foo = system("mknod /dev/mapper/control c 10 " $1); exit foo }' /proc/misc || exit 1 + fi + local dmname="$(cat "/sys/block/${MDEV}/dm/name")" + if [ "${dmname}" ]; then + local target_symlink="/dev/mapper/${dmname}" + [ -e "${target_symlink}" ] && return + ln -snf "/dev/${MDEV}" "${target_symlink}" + echo "${target_symlink}" >"${storage_dir}/storage_symlink_mapper_${MDEV}" + fi + fi +} + +set_readahead() { + read_ahead_kb_control="/sys/class/block/${MDEV}/queue/read_ahead_kb" + new_read_ahead_kb="2048" + if [ -f "${read_ahead_kb_control}" ]; then + read_ahead_kb="$(cat "${read_ahead_kb_control}")" + if [ "${read_ahead_kb}" -lt "${new_read_ahead_kb}" ]; then + logger -t mdev "Changing ${MDEV} read_ahead_kb from ${read_ahead_kb} to ${new_read_ahead_kb}" + echo -n "${new_read_ahead_kb}" >"${read_ahead_kb_control}" + fi + fi +} + +drop_symlinks() { + local type + for type in uuid label mapper; do + [ -f "${storage_dir}/storage_symlink_${type}_${MDEV}" ] || continue + local target_symlink="$(cat "${storage_dir}/storage_symlink_${type}_${MDEV}" 2>/dev/null)" + [ "${target_symlink}" ] || continue + + local target_symlink_device="$(readlink "${target_symlink}")" + if [ "${target_symlink_device}" = "/dev/${MDEV}" ]; then + rm "${target_symlink}" + fi + rm "${storage_dir}/storage_symlink_${type}_${MDEV}" + done +} + +case "${ACTION}" in + 'add'|'') + add_symlinks + set_readahead + ;; + 'remove') + drop_symlinks + ;; +esac +