2 Commits

Author SHA1 Message Date
Jay Larson
dcf90f69d6 The following changes were made:
* Added URL, REPO, and BRIEF to Makefile
  * usher now uses /bin/sh
  * Removed TARGET from usher
2018-04-04 14:20:41 -05:00
Jay Larson
0a7a028b03 The following changes were made:
* Re-wrote mkinitramfs in Perl
  * Re-wrote substantial portions of /init ZFS root in initrd
  * Version is now retreived from mkinitramfs VERSION
  * Updated dependencies
  * Added usher to add default bins and mods
2017-06-15 16:44:42 -05:00
11 changed files with 432 additions and 786 deletions

View File

@@ -8,16 +8,19 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
DEPENDS = gawk,cpio,eudev,findutils,kmod,psmisc,sed
DEPENDS = coreutils,cpio,eudev,gzip,perl,psmisc,sed,util-linux
ARCH = x86_64
URL =
URL = http://snaplinux.org
REPO = core
BRIEF = Scripts to build initrd image
DESC = This package includes scripts to build an initrd image
SNAPVER = 1
SNAPVER = 0
ARCHIVE := ''
SRCDIR := $(PWD)/SRC/mkinitramfs-*
SRCDIR := $(PWD)/SRC/mkinitramfs
PATCHDIR := $(PWD)/SRC/patches
VERSION := $(shell echo $(SRCDIR)|egrep -o '\-[0-9].*'|sed 's/^-//')-$(SNAPVER)
VERSION := $(shell grep 'VERSION =>' $(SRCDIR)/mkinitramfs| \
sed "s/.*=>\s\+'\|'.*//g")-$(SNAPVER)
include /usr/share/snap/Makefile.snaplinux

26
SNAP/usher Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
set -e
case $1 in
preinst)
exit 0
;;
postinst)
if [ ! -f /usr/share/mkinitramfs/bins/default ]; then
cp /usr/share/mkinitramfs/default-bins \
/usr/share/mkinitramfs/bins/default
fi
if [ ! -f /usr/share/mkinitramfs/mods/default ]; then
cp /usr/share/mkinitramfs/default-mods \
/usr/share/mkinitramfs/mods/default
fi
;;
prerm)
exit 0
;;
postrm)
exit 0
;;
esac

View File

@@ -1,12 +0,0 @@
dirs:
install -d -m 755 $(DESTDIR)/sbin
install -d -m 755 $(DESTDIR)/usr/share/mkinitramfs/modules
files:
install -m 755 sbin/mkinitramfs $(DESTDIR)/sbin/mkinitramfs
install -m 755 default-modules \
$(DESTDIR)/usr/share/mkinitramfs/default-modules
install -m 755 usr/share/mkinitramfs/init.in \
$(DESTDIR)/usr/share/mkinitramfs/init.in
install: dirs files

View File

@@ -1,205 +0,0 @@
#!/bin/bash
# This file based in part on the mkinitrafms script for the LFS LiveCD
# written by Alexander E. Patrakov and Jeremy Huntwork.
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
KERNEL_VERSION=`uname -r`
else
KERNEL_VERSION=$1
fi
INITRAMFS_FILE=initrd.img-$KERNEL_VERSION
if [ -n "$KERNEL_VERSION" ] && [ ! -d "/lib/modules/$1" ] ; then
echo "No modules directory named $1"
exit 1
fi
printf "Creating $INITRAMFS_FILE...\n"
binfiles="dmesg sh cat cp dd killall ls mkdir mknod mount"
binfiles="$binfiles umount sed sleep ln rm uname"
# 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 zfs zpool"
#Optional files and locations
for f in mdadm 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 temporrary working directory
WDIR=$(mktemp -d /tmp/initrd-work.XXXXXXXXXX)
# Create base directory structure
mkdir -p $WDIR/{bin,dev,lib/firmware,run,sbin,sys,proc}
mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
touch $WDIR/etc/modprobe.d/modprobe.conf
cp /etc/modprobe.d/* $WDIR/etc/modprobe.d
ln -s lib $WDIR/lib64
# 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
if [ -d /lib/firmware ]; then
cp -a /lib/firmware $WDIR/lib
fi
# 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 [ -x /bin/$f ]; then
ldd /bin/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted
copy $f bin
fi
done
# Add lvm if present
if [ -x /sbin/lvm ] ; then sbinfiles="$sbinfiles lvm dmsetup"; fi
for f in $sbinfiles ; do
if [ -x /sbin/$f ]; then
ldd /sbin/$f | sed "s/\t//" | cut -d " " -f1 >> $unsorted
copy $f sbin
fi
done
# 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
# Add mtab symlink for zfs
ln -s /proc/mounts $WDIR/etc/mtab
# 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
#ls -lR $WDIR
mkdir -p $WDIR/lib/modules/$KERNEL_VERSION
touch $WDIR/lib/modules/$KERNEL_VERSION/modules.{builtin,order}
# Install kernel modules
printf "Copying modules...\n"
if [ $(find /usr/share/mkinitramfs/modules -type f|wc -l) -gt 0 ]; then
for file in /usr/share/mkinitramfs/modules/*; do
while read name; do
module=`modinfo -k $KERNEL_VERSION -F filename $name 2>/dev/null`
if [ $? -eq 0 ]; then
cp --parents $module $WDIR/;
fi
done < $file
done
else
while read name; do
module=`modinfo -k $KERNEL_VERSION -F filename $name 2>/dev/null`
if [ $? -eq 0 ]; then
cp --parents $module $WDIR/;
fi
done < /usr/share/mkinitramfs/default-modules
fi
cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order} \
$WDIR/lib/modules/$KERNEL_VERSION
depmod -b $WDIR $KERNEL_VERSION
printf "Creating gzipped cpio...\n";
( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) > /boot/$INITRAMFS_FILE
# Remove the temporary directory and file
rm -rf $WDIR $unsorted
printf "done.\n"

View File

@@ -1,456 +0,0 @@
3c574_cs
3c589_cs
3c59x
3w-9xxx
3w-sas
3w-xxxx
8139cp
8139too
8390
a100u2w
aacraid
acard-ahci
acenic
advansys
aha152x_cs
ahci
aic79xx
aic7xxx
aic7xxx_old
aic94xx
alx
amd8111e
aoe
arcmsr
ata_generic
ata_piix
aten
atl1
atl1c
atl1e
atl2
atp
atp870u
auth_rpcgss
axnet_cs
b44
be2iscsi
be2net
bfa
bna
bnx2
bnx2fc
bnx2i
bnx2x
bpck
brd
broadcom
bsd_comp
btrfs
BusLogic
cassini
cb710
cb710-mmc
cciss
cdrom
ch
cicada
cnic
comm
configfs
cpqarray
crc16
crc32c
crc7
crc-ccitt
crc-itu-t
crc-t10dif
cxgb
cxgb3
cxgb3i
cxgb4
cxgb4i
cxgb4vf
DAC960
davicom
dc395x
dca
de2104x
de600
de620
defxx
dl2k
dmfe
dm-log
dm-mirror
dm-mod
dm-region-hash
dm-snapshot
dmx3191d
dnet
dpt_i2o
drbd
dstr
dummy
e100
e1000
e1000e
eata
ehci-hcd
enc28j60
enclosure
enic
epat
epia
epic100
eql
et1011c
ethoc
ext2
ext3
ext4
fan
fcoe
fdomain
fdomain_cs
fealnx
ff-memless
firewire-core
firewire-ohci
firewire-sbp2
fit2
fit3
floppy
fmvj18x_cs
fnic
forcedeth
friq
frpw
fscache
fuse
gdth
gre
hamachi
hid
hid-apple
hid-belkin
hid-cherry
hid-chicony
hid-ezkey
hid-hyperv
hid-keytouch
hid-logitech
hid-logitech-dj
hid-microsoft
hid-monterey
hid-ortek
hid-primax
hid-prodikeys
hid-roccat
hid-roccat-arvo
hid-roccat-common
hid-samsung
hid-sjoy
hid-sunplus
hid-topseed
hp100
hpsa
hptiop
hv_netvsc
hv_storvsc
hv_vmbus
i2c-algo-bit
i2c-core
i2o_block
i2o_core
icplus
ifb
igb
igbvf
imm
inet_lro
initio
ipg
ipr
ips
isci
iscsi_boot_sysfs
iscsi_tcp
isofs
ixgb
ixgbe
ixgbevf
jbd
jbd2
jfs
jme
kbic
ks8842
ks8851
ks8851_mll
ksz884x
ktti
libahci
libata
libceph
libcrc32c
libcxgbi
libfc
libfcoe
libiscsi
libiscsi_tcp
libosd
libphy
libsas
libsrp
lockd
loop
lpfc
lru_cache
lxt
macvlan
macvtap
marvell
mbcache
mdio
mdio-bitbang
megaraid
megaraid_mbox
megaraid_mm
megaraid_sas
micrel
mii
mlx4_core
mlx4_en
mmc_block
mmc_core
mmc_spi
mpt2sas
mptbase
mptfc
mptsas
mptscsih
mptspi
mtd
mvsas
mvumi
myri10ge
national
natsemi
nbd
ne2k-pci
netconsole
netxen_nic
nfs
nfs_acl
niu
nmclan_cs
ns83820
ohci-hcd
on20
on26
osd
osdblk
osst
paride
parport
pata_ali
pata_amd
pata_arasan_cf
pata_artop
pata_atiixp
pata_atp867x
pata_cmd64x
pata_cs5520
pata_cs5530
pata_efar
pata_hpt366
pata_hpt37x
pata_it8213
pata_it821x
pata_jmicron
pata_marvell
pata_mpiix
pata_netcell
pata_ninja32
pata_ns87410
pata_ns87415
pata_oldpiix
pata_pcmcia
pata_pdc2027x
pata_pdc202xx_old
pata_piccolo
pata_rdc
pata_rz1000
pata_sc1200
pata_sch
pata_serverworks
pata_sil680
pata_sis
pata_triflex
pata_via
pcd
pch_gbe
pcmcia
pcmcia_core
pcnet32
pcnet_cs
pd
pdc_adma
pf
pg
pktcdvd
plip
pm8001
pmcraid
ppa
ppp_async
ppp_deflate
ppp_generic
ppp_mppe
pppoe
pppox
ppp_synctty
pptp
pt
qla1280
qla2xxx
qla3xxx
qla4xxx
qlcnic
qlge
qlogic_cs
qlogicfas408
qsemi
r6040
r8169
raid_class
rbd
realtek
reiserfs
rrunner
s2io
sata_mv
sata_nv
sata_promise
sata_qstor
sata_sil
sata_sil24
sata_sis
sata_svw
sata_sx4
sata_uli
sata_via
sata_vsc
sb1000
sc92031
scsi_debug
scsi_dh
scsi_dh_alua
scsi_dh_emc
scsi_dh_hp_sw
scsi_dh_rdac
scsi_mod
scsi_tgt
scsi_transport_fc
scsi_transport_iscsi
scsi_transport_sas
scsi_transport_spi
scsi_transport_srp
scsi_wait_scan
sdhci
sdhci-pci
sdhci-pltfm
sdio_uart
sd_mod
sdricoh_cs
ses
sfc
sg
sis190
sis900
skfp
skge
sky2
slhc
slip
smc91c92_cs
smsc
smsc9420
snd-seq-device
soundcore
sr_mod
ssb
st
starfire
ste10Xp
stex
sundance
sungem
sungem_phy
sunhme
sunrpc
sx8
sym53c500_cs
sym53c8xx
tehuti
tg3
thermal
thermal_sys
tifm_core
tifm_sd
tlan
tmscsim
tulip
tun
typhoon
udf
uhci-hcd
uio
uli526x
umem
ums-alauda
ums-cypress
ums-datafab
ums-eneub6250
ums-freecom
ums-isd200
ums-jumpshot
ums-karma
ums-onetouch
ums-realtek
ums-sddr09
ums-sddr55
ums-usbat
usb-common
usbcore
usbhid
usb-storage
ushc
veth
via-rhine
via-sdmmc
via-velocity
virtio
virtio_blk
virtio_net
virtio_pci
virtio_ring
virtio_scsi
vitesse
vmw_pvscsi
vmxnet3
vub300
vxge
wbsd
winbond-840
xen-blkback
xen-blkfront
xen-netback
xen-netfront
xfs
xhci-hcd
xirc2ps_cs
xircom_cb
yellowfin
zlib_deflate

View File

@@ -1,108 +0,0 @@
#!/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" ;;
ZFS=*) eval $root; device="$ZFS"; zfs=true; rootfstype=zfs ;;
"" ) echo "No root device specified." ; problem ;;
esac
if [ "$zfs" == 'true' ] ; then
zpool import -N -a
else
while [ ! -b "$device" ] ; do
no_device $device
problem
done
fi
if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" /.root ; then
no_mount $device
cat /proc/partitions
while true ; do sleep 10000 ; done
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
else
echo "Cannot find 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" "$@"

14
SRC/mkinitramfs/Makefile Normal file
View File

@@ -0,0 +1,14 @@
dirs:
install -d -m 755 $(DESTDIR)/sbin
install -d -m 755 $(DESTDIR)/usr/share/mkinitramfs/mods
install -d -m 755 $(DESTDIR)/usr/share/mkinitramfs/bins
files:
install -m 755 mkinitramfs $(DESTDIR)/sbin/mkinitramfs
install -m 644 default-bins \
$(DESTDIR)/usr/share/mkinitramfs/default-bins
install -m 644 default-mods \
$(DESTDIR)/usr/share/mkinitramfs/default-mods
install -m 755 init $(DESTDIR)/usr/share/mkinitramfs/init
install: dirs files

View File

@@ -0,0 +1,24 @@
/bin/cat
/bin/cp
/bin/dd
/bin/dmesg
/bin/killall
/bin/kmod
/bin/ln
/bin/ls
/bin/mkdir
/bin/mknod
/bin/mount
/bin/rm
/bin/sed
/bin/sh
/bin/sleep
/bin/umount
/bin/uname
/sbin/blkid
/sbin/insmod
/sbin/lsmod
/sbin/modprobe
/sbin/switch_root
/sbin/udevadm
/sbin/udevd

108
SRC/mkinitramfs/init Executable file
View File

@@ -0,0 +1,108 @@
#!/bin/sh
PATH=/bin:/sbin
export PATH
error() {
echo "ERROR: $@"
echo "Dropping to shell"
echo
sh
}
init=/sbin/init
root=
rootdelay=
rootfstype=auto
rorw="ro"
rootflags=
rootdev=
[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mkdir -p /var/lock
mount -n -t devtmpfs devtmpfs /dev
mount -t proc -o nodev,noexec,nosuid proc /proc
mount -t sysfs -o nodev,noexec,nosuid 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=}
;;
rw)
rorw="rw"
;;
esac
done
case "$root" in
/dev/*)
rootdev=$root
;;
UUID=*)
eval $root
rootdev="/dev/disk/by-uuid/$UUID"
;;
LABEL=*)
eval $root
rootdev="/dev/disk/by-label/$LABEL"
;;
ZFS=*)
eval $root
zfs=true
rootdev="$ZFS"
rootfstype=zfs
;;
"")
error "No root device found"
;;
esac
echo > /sys/kernel/uevent_helper
/sbin/udevd --daemon --resolve-names=never
udevadm trigger
udevadm settle
[ -n "$rootdelay" ] && sleep "$rootdelay"
[ -f /etc/mdadm.conf ] && mdadm -As
[ -x /sbin/vgchange ] && /sbin/vgchange --sysinit -a y
if [ -n "$zfs" ]; then
zpool import rpool -N || error "Failed importing rpool"
fi
if [ -n "$rootflags" ]; then
rootflags="$rootflags,$rorw"
else
rootflags="$rorw"
fi
mkdir /.root
if ! mount -n -t "$rootfstype" -o "$rootflags" "$rootdev" /.root ; then
error "Failed to mount root filesystem"
fi
udevadm control --exit
exec switch_root /.root "$init" "$@"

252
SRC/mkinitramfs/mkinitramfs Executable file
View File

@@ -0,0 +1,252 @@
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw( uname );
use Data::Dumper;
use constant VERSION => '0.5';
sub build {
my $kernel = shift;
my $bins = shift;
my $mods = shift;
my $libs = shift;
my $tmpdir = '/tmp/initrd-' . randstr();
mkdir( $tmpdir, 0700 ) || die( "mkdir(): $tmpdir: $!" );
foreach ( qw( bin dev etc etc/modprobe.d etc/udev etc/udev/rules.d
lib proc run sys ) ) {
mkdir( "$tmpdir/$_", 0755 ) || die( "mkdir(): $tmpdir/$_: $!" );
}
if ( -f '/etc/hostid' ) {
if ( system( "cp -p /etc/hostid $tmpdir/etc" ) ) {
die( "Failed copying hostid" );
}
}
symlink( 'lib', "$tmpdir/lib64" ) ||
die( "symlynk(): $tmpdir/lib64: $!" );
symlink( '/proc/mounts', "$tmpdir/etc/mtab" ) ||
die( "symlynk(): $tmpdir/etc/mtab: $!" );
symlink( '/bin', "$tmpdir/sbin" ) ||
die( "symlynk(): $tmpdir/sbin: $!" );
if ( system( "cp -p /usr/share/mkinitramfs/init $tmpdir" ) ) {
die( "Failed copying init" );
}
foreach ( @$bins ) {
if ( system( "cp -p $_ $tmpdir/bin" ) ) {
die( "Failed copying $_\n" );
}
}
foreach ( @$mods ) {
my $file = modinfo( $_, $kernel->{'version'} ) || next;
my @patharr = split( '/', $file );
my $path;
shift( @patharr );
pop( @patharr );
$path = join( '/', @patharr );
if ( ! -d "$tmpdir/$path" ) {
mkdirp( "$tmpdir/$path", 0755 );
}
if ( system( "cp -p $file $tmpdir/$path" ) ) {
die( "Failed copying $file\n" );
}
}
foreach ( @$libs ) {
if ( system( "cp -p $_ $tmpdir/lib" ) ) {
die( "Failed copying $_\n" );
}
}
if ( system( "cp -rp /lib/firmware $tmpdir/lib/firmware" ) ) {
die( "Failed copying firmware\n" );
}
if ( system( "cp -p /etc/modprobe.d/* $tmpdir/etc/modprobe.d" ) ) {
die( "Failed copying data from modprobe.d\n" );
}
if ( system( "cp -rp /etc/udev/rules.d /etc/udev/udev.conf"
. " $tmpdir/etc/udev" ) ) {
die( "Failed copying udev data\n" );
}
if ( system( "cp -rp /lib/udev $tmpdir/lib/udev" ) ) {
die( "Failed copying udev lib data\n" );
}
if ( system( "mknod -m 640 $tmpdir/dev/console c 5 1" ) ) {
die( "Failed to create console device node\n" );
}
if ( system( "mknod -m 640 $tmpdir/dev/null c 1 3" ) ) {
die( "Failed to create null device node\n" );
}
if ( system( "cp /lib/modules/$kernel->{'version'}/"
. "modules.builtin /lib/modules/$kernel->{'version'}/modules.order"
. " $tmpdir/lib/modules/$kernel->{'version'}" ) ) {
die( "Failed copying module data\n" );
}
if ( system( "depmod -b $tmpdir $kernel->{'version'}" ) ) {
die( "Failed to execute depmod\n" );
}
print "Building cpio image\n";
if ( system( "cd $tmpdir && find . | cpio -o -H newc --quiet |"
. " gzip -9 > $kernel->{'initrd'}" ) ) {
die( "Failed building cpio\n" );
}
}
sub getkern {
my $dir = '/boot';
my $kernels = {};
opendir( DIR, $dir ) || die( "opendir(): $dir: $!" );
foreach ( sort( readdir( DIR ) ) ) {
if ( $_ =~ /^vmlinuz-(\S+)/ ) {
$kernels->{$1}{'version'} = $1;
$kernels->{$1}{'path'} = "$dir/$_";
$kernels->{$1}{'initrd'} = "$dir/initrd.img-$1";
}
}
return( $kernels );
}
sub ldd {
my $file = shift;
my $libs = [];
open( LDD, "ldd -v $file|" );
while ( <LDD> ) {
if ( $_ =~ /(\S+)\s+=>\s+(\S+)/ ) {
if ( -e $1 ) {
push( @$libs, $1 );
}
push( @$libs, $2 );
}
}
close( LDD );
return( $libs );
}
sub mkdirp{
( my $dir = shift ) =~ s/\/^//;
my $mode = shift;
( my $parent = $dir ) =~ s/\/[^\/]+$//;
if ( -d $dir ){
return;
}
mkdirp( $parent, $mode );
mkdir( $dir, $mode ) || die( "mkdir(): $dir: $!" );
}
sub modinfo {
my $module = shift;
my $kernver = shift;
my $file;
open( INFO, "modinfo -k $kernver -F filename $module 2>/dev/null|" ) ||
die( "open(): modinfo: $!" );
$file = <INFO>;
close( INFO );
if ( $file ) {
chomp( $file );
}
return( $file );
}
sub randstr {
my $num = shift || 8;
my @chars = ('a'..'z','A'..'Z',0..9);
my $str = '';
for ( my $i = 0; $i < $num; $i++ ) {
$str .= $chars[rand( $#chars )];
}
return( $str );
}
sub readlines {
my $dir = '/usr/share/mkinitramfs/' . shift;
my $lines = [];
opendir( DIR, $dir ) || die( "opendir(): $dir: $!" );
while ( readdir( DIR ) ) {
if ( ! -f "$dir/$_" ) {
next;
}
open( FILE, "<$dir/$_" ) || die( "open(): $dir/$_: $!" );
while ( my $line = <FILE> ) {
chomp( $line );
push( @$lines, $line );
}
close( FILE );
}
close( DIR );
return( $lines );
}
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-v' || $ARGV[$i] eq '--version' ) {
print VERSION . "\n";
exit 0;
}
}
my $kernver = $ARGV[0] || ( uname() )[2];
my $kernels = getkern();
my $bins = readlines( 'bins' );
my $mods = readlines( 'mods' );
my $libs = [];
foreach my $bin ( @$bins ) {
my $ldd = ldd( $bin );
foreach my $lib ( @$ldd ) {
if ( ! grep( $_ eq $lib, @$libs ) ) {
push( @$libs, $lib );
}
}
}
if ( ! $kernels->{$kernver} ) {
print STDERR "Unable to locate kernel version $kernver\n";
exit 1;
}
print "Generating $kernels->{$kernver}{'initrd'}\n";
build( $kernels->{$kernver}, $bins, $mods, $libs );
print "Done\n";