#-----------------------------------------------------------------------------
Summary:	mkinitramfs creates images for use as initial ramdisk (initrd) images.
Name:		mkinitramfs
Version:	8.2
Release:	1
License:	Any
URL:		www.linuxfromscratch.org/blfs
Group:		LFS/Base
Vendor:	Elizabeth
#Source:	%%{name}-%%{version}
Requires:	filesystem
Requires:	cpio
%description
The only purpose of an initramfs is to mount the root filesystem.
The initramfs is a complete set of directories that you would find on a normal
root filesystem. It is bundled into a single cpio archive and compressed
with one of several compression algorithms.

At boot time, the boot loader loads the kernel and the initramfs image into
memory and starts the kernel. The kernel checks for the presence of the
initramfs and, if found, mounts it as / and runs /init. The init program is
typically a shell script. Note that the boot process takes longer, possibly
significantly longer, if an initramfs is used.

For most distributions, kernel modules are the biggest reason to have an
initramfs. In a general distribution, there are many unknowns such as
file system types and disk layouts. In a way, this is the opposite of LFS
where the system capabilities and layout are known and a custom kernel is
normally built. In this situation, an initramfs is rarely needed.

There are only four primary reasons to have an initramfs in the 
LFS environment: loading the rootfs from a network, loading it from an
LVM logical volume, having an encrypted rootfs where a password is required,
or for the convenience of specifying the rootfs as a LABEL or UUID.
Anything else usually means that the kernel was not configured properly. 
#-----------------------------------------------------------------------------
%prep
#	rm -rf %{buildroot}/*
%build
%install
#-----------------------------------------------------------------------------
	install -vdm 755 %{buildroot}/sbin
	cat > %{buildroot}/sbin/mkinitramfs <<- "EOF"
		#!/bin/bash
		# This file based in part on the mkinitramfs script for the LFS LiveCD
		# written by Alexander E. Patrakov and Jeremy Huntwork.
		#	set -o errexit		# exit if error...insurance ;)
		#	set -o nounset		# exit if variable not initalized
		#	set +h				# disable hashall
		copy() {
			local file
			if [ "$2" == "lib" ]; then
				file=$(PATH=/lib:/usr/lib type -p $1)
			else
				file=$(type -p $1)
			fi
			if [ -n $file ] ; then
				cp $file $WDIR/$2
			else
				echo "Missing required file: $1 for directory $2"
				rm -rf $WDIR
				exit 1
			fi
		}
		if [ -z $1 ] ; then
			INITRAMFS_FILE=initrd.img-no-kmods
		else
			KERNEL_VERSION=$1
			INITRAMFS_FILE=initrd.img-$KERNEL_VERSION
		fi
		if [ -n "$KERNEL_VERSION" ] && [ ! -d "/lib/modules/$1" ] ; then
			echo "No modules directory named $1"
			exit 1
		fi
		printf "Creating $INITRAMFS_FILE... "
		binfiles="sh cat cp dd killall ls mkdir mknod mount "
		binfiles="$binfiles umount sed sleep ln rm uname"
		binfiles="$binfiles readlink basename"
		#
		# Systemd installs udevadm in /bin. Other udev implementations have it in /sbin
		if [ -x /bin/udevadm ] ; then binfiles="$binfiles udevadm"; fi
		sbinfiles="modprobe blkid switch_root"
		#
		#Optional files and locations
		for f in mdadm mdmon udevd udevadm; do
			if [ -x /sbin/$f ] ; then sbinfiles="$sbinfiles $f"; fi
		done
		unsorted=$(mktemp /tmp/unsorted.XXXXXXXXXX)
		DATADIR=/usr/share/mkinitramfs
		INITIN=init.in
		#
		# Create a temporary working directory
		WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)
		#
		# Create base directory structure
		mkdir -p $WDIR/{bin,dev,lib/firmware,run,sbin,sys,proc,usr}
		mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
		touch $WDIR/etc/modprobe.d/modprobe.conf
		ln -s lib $WDIR/lib64
		ln -s ../bin $WDIR/usr/bin
		#
		# Create necessary device nodes
		mknod -m 640 $WDIR/dev/console c 5 1
		mknod -m 664 $WDIR/dev/null    c 1 3
		#
		# Install the udev configuration files
		if [ -f /etc/udev/udev.conf ]; then cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf; fi
		for file in $(find /etc/udev/rules.d/ -type f) ; do
			cp $file $WDIR/etc/udev/rules.d
		done
		#
		# Install any firmware present
		cp -a /lib/firmware $WDIR/lib
		#
		# Copy the RAID configuration file if present
		if [ -f /etc/mdadm.conf ]; then cp /etc/mdadm.conf $WDIR/etc; fi
		#
		# Install the init file
		install -m0755 $DATADIR/$INITIN $WDIR/init
		if [  -n "$KERNEL_VERSION" ] ; then
			if [ -x /bin/kmod ] ; then
				binfiles="$binfiles kmod"
			else
				binfiles="$binfiles lsmod"
				sbinfiles="$sbinfiles insmod"
			fi
		fi
		#
		# Install basic binaries
		for f in $binfiles ; do
			if [ -e /bin/$f ]; then d="/bin"; else d="/usr/bin"; fi
			ldd $d/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted
			copy $d/$f bin
		done
		#
		# Add lvm if present
		if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi
		for f in $sbinfiles ; do
			ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted
			copy $f sbin
		done
		#
		# Add udevd libraries if not in /sbin
		if [ -x /lib/udev/udevd ] ; then
			ldd /lib/udev/udevd | sed "s/\t//" | cut -d " " -f1 >> $unsorted
		elif [ -x /lib/systemd/systemd-udevd ] ; then
			ldd /lib/systemd/systemd-udevd | sed "s/\t//" | cut -d " " -f1 >> $unsorted
		fi
		#
		# Add module symlinks if appropriate
		if [ -n "$KERNEL_VERSION" ] && [ -x /bin/kmod ] ; then
			ln -s kmod $WDIR/bin/lsmod
			ln -s kmod $WDIR/bin/insmod
		fi
		#
		# Add lvm symlinks if appropriate
		# Also copy the lvm.conf file
		if  [ -x /sbin/lvm ] ; then
			ln -s lvm $WDIR/sbin/lvchange
			ln -s lvm $WDIR/sbin/lvrename
			ln -s lvm $WDIR/sbin/lvextend
			ln -s lvm $WDIR/sbin/lvcreate
			ln -s lvm $WDIR/sbin/lvdisplay
			ln -s lvm $WDIR/sbin/lvscan
			ln -s lvm $WDIR/sbin/pvchange
			ln -s lvm $WDIR/sbin/pvck
			ln -s lvm $WDIR/sbin/pvcreate
			ln -s lvm $WDIR/sbin/pvdisplay
			ln -s lvm $WDIR/sbin/pvscan
			ln -s lvm $WDIR/sbin/vgchange
			ln -s lvm $WDIR/sbin/vgcreate
			ln -s lvm $WDIR/sbin/vgscan
			ln -s lvm $WDIR/sbin/vgrename
			ln -s lvm $WDIR/sbin/vgck
			# Conf file(s)
			cp -a /etc/lvm $WDIR/etc
		fi
		#
		# Install libraries
		sort $unsorted | uniq | while read library ; do
			if [ "$library" == "linux-vdso.so.1" ] ||
				[ "$library" == "linux-gate.so.1" ]; then
				continue
			fi
			copy $library lib
		done
		if [ -d /lib/udev ]; then cp -a /lib/udev $WDIR/lib; fi
		if [ -d /lib/systemd ]; then  cp -a /lib/systemd $WDIR/lib; fi
		#
		# Install the kernel modules if requested
		if [ -n "$KERNEL_VERSION" ]; then
			find \
				/lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib} \
				/lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire} \
				/lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio} \
				/lib/modules/$KERNEL_VERSION/kernel/drivers/usb/{host,storage} \
				-type f 2> /dev/null | cpio --make-directories -p --quiet $WDIR
			cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order} $WDIR/lib/modules/$KERNEL_VERSION
			depmod -b $WDIR $KERNEL_VERSION
		fi
		( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) > $INITRAMFS_FILE
		#
		# Remove the temporary directory and file
		rm -rf $WDIR $unsorted
		printf "done.\n"
	EOF
	chmod 0755 %{buildroot}/sbin/mkinitramfs
#-----------------------------------------------------------------------------
	install -vdm 755 %{buildroot}/usr/share/mkinitramfs
	cat > %{buildroot}/usr/share/mkinitramfs/init.in <<- "EOF"
		#!/bin/sh
		PATH=/bin:/usr/bin:/sbin:/usr/sbin
		export PATH
		problem() {
			printf "Encountered a problem!\n\nDropping you to a shell.\n\n"
			sh
		}
		no_device() {
			printf "The device %s, which is supposed to contain the\n" $1
			printf "root file system, does not exist.\n"
			printf "Please fix this problem and exit this shell.\n\n"
		}
		no_mount() {
			printf "Could not mount device %s\n" $1
			printf "Sleeping forever. Please reboot and fix the kernel command line.\n\n"
			printf "Maybe the device is formatted with an unsupported file system?\n\n"
			printf "Or maybe filesystem type autodetection went wrong, in which case\n"
			printf "you should add the rootfstype=... parameter to the kernel command line.\n\n"
			printf "Available partitions:\n"
		}
		do_mount_root() {
			mkdir /.root
			[ -n "$rootflags" ] && rootflags="$rootflags,"
			rootflags="$rootflags$ro"
			case "$root" in
				/dev/* ) device=$root ;;
				UUID=* ) eval $root; device="/dev/disk/by-uuid/$UUID"  ;;
				LABEL=*) eval $root; device="/dev/disk/by-label/$LABEL" ;;
				""     ) echo "No root device specified." ; problem    ;;
			esac
			while [ ! -b "$device" ] ; do
				no_device $device
				problem
			done
			if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then
				no_mount $device
				cat /proc/partitions
				while true ; do sleep 10000 ; done
			else
				echo "Successfully mounted device $root"
			fi
		}
		init=/sbin/init
		root=
		rootdelay=
		rootfstype=auto
		ro="ro"
		rootflags=
		device=
		mount -n -t devtmpfs devtmpfs /dev
		mount -n -t proc     proc     /proc
		mount -n -t sysfs    sysfs    /sys
		mount -n -t tmpfs    tmpfs    /run
		read -r cmdline < /proc/cmdline
		for param in $cmdline ; do
			case $param in
				init=*      ) init=${param#init=}             ;;
				root=*      ) root=${param#root=}             ;;
				rootdelay=* ) rootdelay=${param#rootdelay=}   ;;
				rootfstype=*) rootfstype=${param#rootfstype=} ;;
				rootflags=* ) rootflags=${param#rootflags=}   ;;
				ro          ) ro="ro"                         ;;
				rw          ) ro="rw"                         ;;
				esac
		done
		#
		# udevd location depends on version
		if [ -x /sbin/udevd ]; then
			UDEVD=/sbin/udevd
		elif [ -x /lib/udev/udevd ]; then
			UDEVD=/lib/udev/udevd
		elif [ -x /lib/systemd/systemd-udevd ]; then
			UDEVD=/lib/systemd/systemd-udevd
		else
			echo "Cannot find udevd nor systemd-udevd"
			problem
		fi
		${UDEVD} --daemon --resolve-names=never
		udevadm trigger
		udevadm settle
		if [ -f /etc/mdadm.conf ]; then mdadm -As; fi
		if [ -x /sbin/vgchange  ]; then /sbin/vgchange -a y > /dev/null; fi
		if [ -n "$rootdelay"    ]; then sleep "$rootdelay"; fi
		do_mount_root
		killall -w ${UDEVD##*/}
		exec switch_root /.root "$init" "$@"
	EOF
#-----------------------------------------------------------------------------
#	Copy license/copying file
#	install -D -m644 LICENSE %{buildroot}/usr/share/licenses/%{name}/LICENSE
#	install -D -m644 COPYING %{buildroot}/usr/share/licenses/%{name}/LICENSE
#-----------------------------------------------------------------------------
#	Create file list
#	rm  %{buildroot}%{_infodir}/dir
#	find %{buildroot} -name '*.la' -delete
	find "${RPM_BUILD_ROOT}" -not -type d -print > filelist.rpm
	sed -i "s|^${RPM_BUILD_ROOT}||" filelist.rpm
#	sed -i '/man\/man/d' filelist.rpm
#	sed -i '/\/usr\/share\/info/d' filelist.rpm
#-----------------------------------------------------------------------------
%files -f filelist.rpm
	%defattr(-,root,root)
#	%%{_infodir}/*
#	%%{_mandir}/man1/*
#-----------------------------------------------------------------------------
%post
%postun
#-----------------------------------------------------------------------------
%changelog
*	Sun Sep 09 2018 baho-utot <baho-utot@columbus.rr.com> 8.2-1
-	Initial build.	First version
