add a new package to personal repository package/teha: ROCKLinux initial ram-fs - creates a cpio archive which can be passed to boot loader (via initrd) as initramfs git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@8606 c5f82cb5-29bc-0310-9cd0-bff59a50e3bcrocklinux
@ -0,0 +1,46 @@ |
|||||
|
|
||||
|
# beware! kernel wants to have directories in cpio |
||||
|
# (e.g. it does not auto-create them on extraction) |
||||
|
|
||||
|
cat <<EOF |
||||
|
dir /dev 0755 0 0 |
||||
|
dir /dev/bus 0755 0 0 |
||||
|
dir /dev/bus/usb 0755 0 0 |
||||
|
dir /dev/pts 0755 0 0 |
||||
|
dir /dev/shm 0755 0 0 |
||||
|
|
||||
|
nod /dev/null 0666 0 0 c 1 3 |
||||
|
nod /dev/zero 0644 0 0 c 1 5 |
||||
|
nod /dev/tty 0644 0 0 c 5 0 |
||||
|
nod /dev/console 0644 0 0 c 5 1 |
||||
|
pipe /dev/initctl 644 0 0 |
||||
|
|
||||
|
slink /dev/core /proc/kcore 755 0 0 |
||||
|
slink /dev/fd /proc/self/fd 755 0 0 |
||||
|
slink /dev/stdin /proc/self/fd/0 755 0 0 |
||||
|
slink /dev/stdout /proc/self/fd/1 755 0 0 |
||||
|
slink /dev/stderr /proc/self/fd/2 755 0 0 |
||||
|
|
||||
|
dir /bin 0755 0 0 |
||||
|
dir /sbin 0755 0 0 |
||||
|
dir /etc 0755 0 0 |
||||
|
dir /lib 0755 0 0 |
||||
|
dir /media 0755 0 0 |
||||
|
dir /mnt 0755 0 0 |
||||
|
dir /proc 0755 0 0 |
||||
|
dir /sys 0755 0 0 |
||||
|
dir /tmp 0755 0 0 |
||||
|
dir /usr 0755 0 0 |
||||
|
dir /usr/bin 0755 0 0 |
||||
|
dir /usr/sbin 0755 0 0 |
||||
|
|
||||
|
slink /bin/sh /bin/bash 755 0 0 |
||||
|
|
||||
|
file /etc/nsswitch.conf $filesdir/etc/nsswitch.conf 0644 0 0 |
||||
|
file /etc/ld.so.conf $filesdir/etc/ld.so.conf 0644 0 0 |
||||
|
file /etc/profile $filesdir/etc/profile 0644 0 0 |
||||
|
file /etc/passwd $filesdir/etc/passwd 0644 0 0 |
||||
|
file /etc/shadow $filesdir/etc/shadow 0600 0 0 |
||||
|
file /etc/group $filesdir/etc/group 0644 0 0 |
||||
|
file /etc/gshadow $filesdir/etc/gshadow 0600 0 0 |
||||
|
EOF |
||||
@ -0,0 +1,19 @@ |
|||||
|
|
||||
|
BINLIST=" |
||||
|
bin/tar bin/bzip2 bin/gzip |
||||
|
bin/bash usr/bin/awk usr/bin/basename bin/cat bin/cp bin/cut usr/bin/find |
||||
|
bin/ls bin/grep bin/ln usr/bin/readlink bin/rm bin/sed bin/sleep usr/bin/tr |
||||
|
sbin/insmod bin/mount bin/umount sbin/modprobe sbin/depmod |
||||
|
usr/bin/killall |
||||
|
|
||||
|
bin/ps bin/df bin/mkdir bin/more |
||||
|
bin/chmod |
||||
|
usr/bin/chroot |
||||
|
" |
||||
|
|
||||
|
for x in $BINLIST |
||||
|
do |
||||
|
add_with_deps $rootdir/$x /$x |
||||
|
done |
||||
|
|
||||
|
echo slink /bin/sh /bin/bash 755 0 0 |
||||
@ -0,0 +1,6 @@ |
|||||
|
for x in $rootdir/lib/libnss_{dns,files}*.so.* |
||||
|
do |
||||
|
[ -e "$x" ] || continue |
||||
|
echo "file /lib/`readlink $x` $rootdir/lib/`readlink $x` 0755 0 0" |
||||
|
echo "slink /lib/`basename $x` `readlink $x` 755 0 0" |
||||
|
done |
||||
@ -0,0 +1,49 @@ |
|||||
|
|
||||
|
|
||||
|
BINLIST=" |
||||
|
sbin/udevd |
||||
|
sbin/udevcontrol |
||||
|
sbin/udevsettle |
||||
|
sbin/udevtrigger |
||||
|
usr/bin/udevinfo |
||||
|
usr/bin/udevtest |
||||
|
" |
||||
|
|
||||
|
for x in $BINLIST |
||||
|
do |
||||
|
add_with_deps $rootdir/$x /$x |
||||
|
done |
||||
|
|
||||
|
cat <<EOF |
||||
|
dir /etc/udev 0755 0 0 |
||||
|
dir /etc/udev/rules.d 0755 0 0 |
||||
|
file /etc/udev/udev.conf $rootdir/etc/udev/udev.conf 644 0 0 |
||||
|
|
||||
|
dir /lib/udev 0755 0 0 |
||||
|
dir /lib/udev/devices 0755 0 0 |
||||
|
dir /lib/udev/devices/bus 0755 0 0 |
||||
|
dir /lib/udev/devices/bus/usb 0755 0 0 |
||||
|
dir /lib/udev/devices/pts 0755 0 0 |
||||
|
dir /lib/udev/devices/shm 0755 0 0 |
||||
|
nod /lib/udev/devices/console 0600 0 0 c 5 1 |
||||
|
nod /lib/udev/devices/null 0666 0 0 c 1 3 |
||||
|
pipe /lib/udev/devices/initctl 600 0 0 |
||||
|
slink /lib/udev/devices/fd /proc/self/fd 755 0 0 |
||||
|
slink /lib/udev/devices/core /proc/kcore 755 0 0 |
||||
|
slink /lib/udev/devices/stdin /proc/self/fd/0 755 0 0 |
||||
|
slink /lib/udev/devices/stdout /proc/self/fd/1 755 0 0 |
||||
|
slink /lib/udev/devices/stderr /proc/self/fd/2 755 0 0 |
||||
|
EOF |
||||
|
|
||||
|
( |
||||
|
cd $rootdir |
||||
|
find etc/udev/rules.d -maxdepth 1 -type f | while read x |
||||
|
do |
||||
|
echo "file $x $rootdir/$x 644 0 0" |
||||
|
done |
||||
|
|
||||
|
find lib/udev -maxdepth 1 -type f | while read x |
||||
|
do |
||||
|
add_with_deps $rootdir/$x /$x |
||||
|
done |
||||
|
) |
||||
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
# file /init $rootdir/bin/bash 755 0 0 |
||||
|
|
||||
|
echo file /linuxrc.sh $filesdir/linuxrc.sh 0755 0 0 |
||||
|
|
||||
|
cat <<EOF |
||||
|
slink /init /linuxrc.sh 755 0 0 |
||||
|
EOF |
||||
@ -0,0 +1,8 @@ |
|||||
|
|
||||
|
mkdir -p $TMPDIR/run_init |
||||
|
gcc -c $filesdir/run_init/run-init.c -o $TMPDIR/run_init/run-init.o |
||||
|
gcc -c $filesdir/run_init/runinitlib.c -o $TMPDIR/run_init/runinitlib.o |
||||
|
gcc $TMPDIR/run_init/*.o -o $TMPDIR/run_init/run_init |
||||
|
|
||||
|
echo dir /real-root 0755 0 0 |
||||
|
echo file /sbin/run_init $TMPDIR/run_init/run_init 0755 0 0 |
||||
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
for x in sbin/mdadm sbin/lvm sbin/dmsetup |
||||
|
do |
||||
|
if [ -e $rootdir/$x ] |
||||
|
then |
||||
|
add_with_deps $rootdir/$x /$x |
||||
|
else |
||||
|
echo "# $rootdir/$x not found. skipping $x binary." |
||||
|
fi |
||||
|
done |
||||
@ -0,0 +1,12 @@ |
|||||
|
# we want our own cwd and environment. so we open a subshell |
||||
|
( |
||||
|
[ -d $mod_origin/kernel/ ] || exit |
||||
|
MODTMP="$TMPDIR/modules-$k_ver" |
||||
|
mkdir -p $MODTMP/lib/modules/$k_ver |
||||
|
cp -r $mod_origin/kernel/ $MODTMP/lib/modules/$k_ver/ |
||||
|
for x in sound drivers/telephony drivers/media drivers/isdn \ |
||||
|
drivers/input/joystick drivers/input/mouse |
||||
|
do |
||||
|
rm -rf $MODTMP/lib/modules/$k_ver/kernel/$x |
||||
|
done |
||||
|
) |
||||
@ -0,0 +1,23 @@ |
|||||
|
# we want our own cwd and environment. so we open a subshell |
||||
|
( |
||||
|
[ -d $mod_origin/kernel/ ] || exit |
||||
|
MODTMP="$TMPDIR/modules-$k_ver" |
||||
|
depmod -b $MODTMP $k_ver |
||||
|
|
||||
|
cd $MODTMP |
||||
|
|
||||
|
echo "dir /lib/modules 0755 0 0" |
||||
|
echo "dir /lib/modules/$k_ver 0755 0 0" |
||||
|
|
||||
|
find lib/modules/$k_ver/{kernel,misc} -type d \ |
||||
|
| while read dir ; do |
||||
|
echo "dir $dir 0755 0 0" |
||||
|
find "$dir" -name \*.ko | while read ko ; do |
||||
|
echo "file $ko `pwd`/$ko 0644 0 0" |
||||
|
done |
||||
|
done |
||||
|
find lib/modules/$k_ver -maxdepth 1 -name modules.\* | while read x |
||||
|
do |
||||
|
echo "file $x `pwd`/$x 0644 0 0" |
||||
|
done |
||||
|
) |
||||
@ -0,0 +1,20 @@ |
|||||
|
|
||||
|
|
||||
|
BINLIST=" |
||||
|
bin/ps bin/df bin/mkdir bin/more usr/bin/less sbin/fdisk usr/sbin/disktype |
||||
|
bin/cpio bin/gzip usr/bin/wc usr/bin/od sbin/mkfs.xfs bin/rmdir usr/bin/lsmod sbin/depmod |
||||
|
usr/sbin/lspci sbin/ip bin/dmesg |
||||
|
usr/bin/mkfifo |
||||
|
sbin/ldconfig |
||||
|
usr/bin/id |
||||
|
|
||||
|
usr/sbin/groupadd |
||||
|
" |
||||
|
|
||||
|
for x in $BINLIST |
||||
|
do |
||||
|
add_with_deps $rootdir/$x /$x |
||||
|
done |
||||
|
|
||||
|
echo "dir /usr/share 0755 0 0" |
||||
|
echo "file /usr/share/pci.ids $rootdir/usr/share/pci.ids 0644 0 0" |
||||
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
echo "file /etc/fstab $filesdir/empty 644 0 0" |
||||
|
echo "file /etc/mtab $filesdir/empty 644 0 0" |
||||
|
|
||||
|
echo "dir /init.d 0755 0 0" |
||||
|
for x in $filesdir/init.d/[0-9]* |
||||
|
do |
||||
|
echo "file /init.d/`basename $x` $x 755 0 0" |
||||
|
done |
||||
@ -0,0 +1,13 @@ |
|||||
|
|
||||
|
all NN-XXXXX scripts in this directory will be sourced |
||||
|
by ../build-list.sh |
||||
|
|
||||
|
output must be gen_init_cpio compatible list of cpio-elements |
||||
|
|
||||
|
example: |
||||
|
# A simple initramfs |
||||
|
dir /dev 0755 0 0 |
||||
|
nod /dev/console 0600 0 0 c 5 1 |
||||
|
dir /root 0700 0 0 |
||||
|
dir /sbin 0755 0 0 |
||||
|
file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0 |
||||
@ -0,0 +1 @@ |
|||||
|
|
||||
@ -0,0 +1,15 @@ |
|||||
|
root:x:0: |
||||
|
bin:x:1: |
||||
|
daemon:x:2: |
||||
|
shadow:x:3: |
||||
|
games:x:4: |
||||
|
tty:x:5: |
||||
|
disk:x:6: |
||||
|
kmem:x:7: |
||||
|
users:x:100: |
||||
|
nogroup:x:65534: |
||||
|
nobody:x:65534: |
||||
|
video:x:16: |
||||
|
sound:x:17: |
||||
|
sshd:x:19: |
||||
|
cdrom:x:29: |
||||
@ -0,0 +1,2 @@ |
|||||
|
root:!:: |
||||
|
distcc:!:: |
||||
@ -0,0 +1,2 @@ |
|||||
|
/lib |
||||
|
/usr/lib |
||||
@ -0,0 +1,13 @@ |
|||||
|
passwd: files |
||||
|
group: files |
||||
|
shadow: files |
||||
|
|
||||
|
hosts: files dns |
||||
|
networks: files dns |
||||
|
|
||||
|
protocols: files |
||||
|
services: files |
||||
|
ethers: files |
||||
|
rpc: files |
||||
|
|
||||
|
netgroup: files |
||||
@ -0,0 +1,5 @@ |
|||||
|
root:x:0:0:root:/root:/bin/bash |
||||
|
bin:x:1:1:bin:/bin:/bin/false |
||||
|
daemon:x:2:2:daemon:/sbin:/bin/false |
||||
|
nobody:x:65534:65534:nobody:/var/empty:/bin/false |
||||
|
sshd:x:19:19:sshd privsep:/var/empty:/bin/false |
||||
@ -0,0 +1 @@ |
|||||
|
export PATH=/sbin:/bin:/usr/sbin:/usr/bin |
||||
@ -0,0 +1,6 @@ |
|||||
|
root::13235:::::: |
||||
|
toor:*::::::: |
||||
|
bin:*::::::: |
||||
|
daemon:*::::::: |
||||
|
nobody:*::::::: |
||||
|
sshd:*::::::: |
||||
@ -0,0 +1,4 @@ |
|||||
|
|
||||
|
mount -t proc none /proc |
||||
|
mount -t sysfs none /sys |
||||
|
|
||||
@ -0,0 +1,10 @@ |
|||||
|
mount -t tmpfs none /dev |
||||
|
udevd --daemon |
||||
|
udevtrigger |
||||
|
sleep 2 |
||||
|
udevsettle |
||||
|
echo "sleeping another 3 seconds after udevsettle ran..." |
||||
|
sleep 3 |
||||
|
mkdir -p /dev/pts |
||||
|
mkdir -p /dev/shm |
||||
|
mkdir -p /dev/bus/usb |
||||
@ -0,0 +1,27 @@ |
|||||
|
|
||||
|
# read root parameter from cmdline |
||||
|
root=$(sed 's/.*\<root=\([^ ]*\).*/\1/' /proc/cmdline) |
||||
|
# set $(< /proc/cmdline ) ; for arg ; do [[ ${arg} == root=* ]] && root=${arg#root=} |
||||
|
|
||||
|
if [ ! -e "$root" ] |
||||
|
then |
||||
|
echo "your root <$root> does not exist." |
||||
|
else |
||||
|
mount $root /real-root |
||||
|
fi |
||||
|
|
||||
|
# thanks udevd. you did a great job. |
||||
|
# now go away and let the real system do its work. |
||||
|
echo "terminating udevd..." |
||||
|
killall udevd |
||||
|
sleep 1 |
||||
|
rm -rf /dev/.udev |
||||
|
|
||||
|
if [ -e /real-root/dev ] |
||||
|
then |
||||
|
mount --move /dev /real-root/dev |
||||
|
mount --move /sys /real-root/sys |
||||
|
mount --move /proc /real-root/proc |
||||
|
else |
||||
|
echo "outch. /real-root/dev does not exist." |
||||
|
fi |
||||
@ -0,0 +1,14 @@ |
|||||
|
#!/bin/sh |
||||
|
. /etc/profile |
||||
|
for x in /init.d/* |
||||
|
do |
||||
|
. $x |
||||
|
done |
||||
|
echo "going real..." |
||||
|
if [ -x /real-root/sbin/init ] |
||||
|
then |
||||
|
exec /sbin/run_init /real-root /sbin/init |
||||
|
else |
||||
|
echo "no /real-root/sbin/init found. spawning /bin/bash..." |
||||
|
exec /bin/bash --login |
||||
|
fi |
||||
@ -0,0 +1,95 @@ |
|||||
|
/* ----------------------------------------------------------------------- * |
||||
|
* |
||||
|
* Copyright 2004-2006 H. Peter Anvin - All Rights Reserved |
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person |
||||
|
* obtaining a copy of this software and associated documentation |
||||
|
* files (the "Software"), to deal in the Software without |
||||
|
* restriction, including without limitation the rights to use, |
||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or |
||||
|
* sell copies of the Software, and to permit persons to whom |
||||
|
* the Software is furnished to do so, subject to the following |
||||
|
* conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall |
||||
|
* be included in all copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||
|
* |
||||
|
* ----------------------------------------------------------------------- */ |
||||
|
|
||||
|
/* |
||||
|
* run-init.c |
||||
|
* |
||||
|
* Usage: exec run-init [-c /dev/console] /real-root /sbin/init "$@" |
||||
|
* |
||||
|
* This program should be called as the last thing in a shell script |
||||
|
* acting as /init in an initramfs; it does the following: |
||||
|
* |
||||
|
* - Delete all files in the initramfs; |
||||
|
* - Remounts /real-root onto the root filesystem; |
||||
|
* - Chroots; |
||||
|
* - Opens /dev/console; |
||||
|
* - Spawns the specified init program (with arguments.) |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <stdio.h> |
||||
|
#include <unistd.h> |
||||
|
#include <string.h> |
||||
|
#include <errno.h> |
||||
|
#include "run-init.h" |
||||
|
|
||||
|
static const char *program; |
||||
|
|
||||
|
void __attribute__((noreturn)) die(const char *msg) |
||||
|
{ |
||||
|
fprintf(stderr, "%s: %s: %s\n", program, msg, strerror(errno)); |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
static void __attribute__((noreturn)) usage(void) |
||||
|
{ |
||||
|
fprintf(stderr, "Usage: exec %s [-c consoledev] /real-root /sbin/init [args]\n", program); |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
int main(int argc, char *argv[]) |
||||
|
{ |
||||
|
/* Command-line options and defaults */ |
||||
|
const char *console = "/dev/console"; |
||||
|
const char *realroot; |
||||
|
const char *init; |
||||
|
char **initargs; |
||||
|
|
||||
|
/* Variables... */ |
||||
|
int o; |
||||
|
|
||||
|
/* Parse the command line */ |
||||
|
program = argv[0]; |
||||
|
|
||||
|
while ( (o = getopt(argc, argv, "c:")) != -1 ) { |
||||
|
if ( o == 'c' ) { |
||||
|
console = optarg; |
||||
|
} else { |
||||
|
usage(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ( argc-optind < 2 ) |
||||
|
usage(); |
||||
|
|
||||
|
realroot = argv[optind]; |
||||
|
init = argv[optind+1]; |
||||
|
initargs = argv+optind+1; |
||||
|
|
||||
|
return run_init(realroot, console, init, initargs); |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
/* ----------------------------------------------------------------------- * |
||||
|
* |
||||
|
* Copyright 2004-2006 H. Peter Anvin - All Rights Reserved |
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person |
||||
|
* obtaining a copy of this software and associated documentation |
||||
|
* files (the "Software"), to deal in the Software without |
||||
|
* restriction, including without limitation the rights to use, |
||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or |
||||
|
* sell copies of the Software, and to permit persons to whom |
||||
|
* the Software is furnished to do so, subject to the following |
||||
|
* conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall |
||||
|
* be included in all copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||
|
* |
||||
|
* ----------------------------------------------------------------------- */ |
||||
|
|
||||
|
/* |
||||
|
* run-init.h |
||||
|
*/ |
||||
|
|
||||
|
#ifndef RUN_INIT_H |
||||
|
#define RUN_INIT_H |
||||
|
|
||||
|
void __attribute__((noreturn)) die(const char *msg); |
||||
|
|
||||
|
int run_init(const char *realroot, const char *console, |
||||
|
const char *init, char **initargs); |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,214 @@ |
|||||
|
/* ----------------------------------------------------------------------- * |
||||
|
* |
||||
|
* Copyright 2004-2006 H. Peter Anvin - All Rights Reserved |
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person |
||||
|
* obtaining a copy of this software and associated documentation |
||||
|
* files (the "Software"), to deal in the Software without |
||||
|
* restriction, including without limitation the rights to use, |
||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or |
||||
|
* sell copies of the Software, and to permit persons to whom |
||||
|
* the Software is furnished to do so, subject to the following |
||||
|
* conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall |
||||
|
* be included in all copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
|
* OTHER DEALINGS IN THE SOFTWARE. |
||||
|
* |
||||
|
* ----------------------------------------------------------------------- */ |
||||
|
|
||||
|
/* |
||||
|
* runinitlib.c |
||||
|
* |
||||
|
* run_init(consoledev, realroot, init, initargs) |
||||
|
* |
||||
|
* This function should be called as the last thing in kinit, |
||||
|
* from initramfs, it does the following: |
||||
|
* |
||||
|
* - Delete all files in the initramfs; |
||||
|
* - Remounts /real-root onto the root filesystem; |
||||
|
* - Chroots; |
||||
|
* - Opens /dev/console; |
||||
|
* - Spawns the specified init program (with arguments.) |
||||
|
*/ |
||||
|
|
||||
|
#include <alloca.h> |
||||
|
#include <assert.h> |
||||
|
#include <dirent.h> |
||||
|
#include <errno.h> |
||||
|
#include <fcntl.h> |
||||
|
#include <string.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <stdio.h> |
||||
|
#include <unistd.h> |
||||
|
#include <sys/mount.h> |
||||
|
#include <sys/stat.h> |
||||
|
#include <sys/types.h> |
||||
|
#include <sys/vfs.h> |
||||
|
#include "run-init.h" |
||||
|
|
||||
|
/* Make it possible to compile on glibc by including constants that the |
||||
|
always-behind shipped glibc headers may not include. Classic example |
||||
|
on why the lack of ABI headers screw us up. */ |
||||
|
#ifndef TMPFS_MAGIC |
||||
|
# define TMPFS_MAGIC 0x01021994 |
||||
|
#endif |
||||
|
#ifndef RAMFS_MAGIC |
||||
|
# define RAMFS_MAGIC 0x858458f6 |
||||
|
#endif |
||||
|
#ifndef MS_MOVE |
||||
|
# define MS_MOVE 8192 |
||||
|
#endif |
||||
|
|
||||
|
static int nuke(const char *what); |
||||
|
|
||||
|
static int nuke_dirent(int len, const char *dir, const char *name, dev_t me) |
||||
|
{ |
||||
|
int bytes = len+strlen(name)+2; |
||||
|
char path[bytes]; |
||||
|
int xlen; |
||||
|
struct stat st; |
||||
|
|
||||
|
xlen = snprintf(path, bytes, "%s/%s", dir, name); |
||||
|
assert(xlen < bytes); |
||||
|
|
||||
|
if ( lstat(path, &st) ) |
||||
|
return ENOENT; /* Return 0 since already gone? */ |
||||
|
|
||||
|
if ( st.st_dev != me ) |
||||
|
return 0; /* DO NOT recurse down mount points!!!!! */ |
||||
|
|
||||
|
return nuke(path); |
||||
|
} |
||||
|
|
||||
|
/* Wipe the contents of a directory, but not the directory itself */ |
||||
|
static int nuke_dir(const char *what) |
||||
|
{ |
||||
|
int len = strlen(what); |
||||
|
DIR *dir; |
||||
|
struct dirent *d; |
||||
|
int err = 0; |
||||
|
struct stat st; |
||||
|
|
||||
|
if ( lstat(what, &st) ) |
||||
|
return errno; |
||||
|
|
||||
|
if ( !S_ISDIR(st.st_mode) ) |
||||
|
return ENOTDIR; |
||||
|
|
||||
|
if ( !(dir = opendir(what)) ) { |
||||
|
/* EACCES means we can't read it. Might be empty and removable; |
||||
|
if not, the rmdir() in nuke() will trigger an error. */ |
||||
|
return (errno == EACCES) ? 0 : errno; |
||||
|
} |
||||
|
|
||||
|
while ( (d = readdir(dir)) ) { |
||||
|
/* Skip . and .. */ |
||||
|
if ( d->d_name[0] == '.' && |
||||
|
(d->d_name[1] == '\0' || |
||||
|
(d->d_name[1] == '.' && d->d_name[2] == '\0')) ) |
||||
|
continue; |
||||
|
|
||||
|
err = nuke_dirent(len, what, d->d_name, st.st_dev); |
||||
|
if ( err ) { |
||||
|
closedir(dir); |
||||
|
return err; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
closedir(dir); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static int nuke(const char *what) |
||||
|
{ |
||||
|
int rv; |
||||
|
int err = 0; |
||||
|
|
||||
|
rv = unlink(what); |
||||
|
if ( rv < 0 ) { |
||||
|
if ( errno == EISDIR ) { |
||||
|
/* It's a directory. */ |
||||
|
err = nuke_dir(what); |
||||
|
if ( !err ) err = rmdir(what) ? errno : err; |
||||
|
} else { |
||||
|
err = errno; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ( err ) { |
||||
|
errno = err; |
||||
|
die(what); |
||||
|
} else { |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
int run_init(const char *realroot, const char *console, |
||||
|
const char *init, char **initargs) |
||||
|
{ |
||||
|
struct stat rst, cst, ist; |
||||
|
struct statfs sfs; |
||||
|
int confd; |
||||
|
|
||||
|
/* First, change to the new root directory */ |
||||
|
if ( chdir(realroot) ) |
||||
|
die("chdir to new root"); |
||||
|
|
||||
|
/* This is a potentially highly destructive program. Take some |
||||
|
extra precautions. */ |
||||
|
|
||||
|
/* Make sure the current directory is not on the same filesystem |
||||
|
as the root directory */ |
||||
|
if ( stat("/", &rst) || stat(".", &cst) ) |
||||
|
die("stat"); |
||||
|
|
||||
|
if ( rst.st_dev == cst.st_dev ) |
||||
|
die("current directory on the same filesystem as the root"); |
||||
|
|
||||
|
/* The initramfs should have /init */ |
||||
|
if ( stat("/init", &ist) || !S_ISREG(ist.st_mode) ) |
||||
|
die("can't find /init on initramfs"); |
||||
|
|
||||
|
/* Make sure we're on a ramfs */ |
||||
|
if ( statfs("/", &sfs) ) |
||||
|
die("statfs /"); |
||||
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) |
||||
|
die("rootfs not a ramfs or tmpfs"); |
||||
|
|
||||
|
/* Okay, I think we should be safe... */ |
||||
|
|
||||
|
/* Delete rootfs contents */ |
||||
|
if ( nuke_dir("/") ) |
||||
|
die("nuking initramfs contents"); |
||||
|
|
||||
|
/* Overmount the root */ |
||||
|
if ( mount(".", "/", NULL, MS_MOVE, NULL) ) |
||||
|
die("overmounting root"); |
||||
|
|
||||
|
/* chroot, chdir */ |
||||
|
if ( chroot(".") || chdir("/") ) |
||||
|
die("chroot"); |
||||
|
|
||||
|
/* Open /dev/console */ |
||||
|
if ( (confd = open(console, O_RDWR)) < 0 ) |
||||
|
die("opening console"); |
||||
|
dup2(confd, 0); |
||||
|
dup2(confd, 1); |
||||
|
dup2(confd, 2); |
||||
|
close(confd); |
||||
|
|
||||
|
/* Spawn init */ |
||||
|
execv(init, initargs); |
||||
|
die(init); /* Failed to spawn init */ |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
#!/bin/sh |
||||
|
|
||||
|
targetdir="`pwd`" |
||||
|
|
||||
|
find . -mindepth 1 -printf "%y %P %#m %U %G %l\n" \ |
||||
|
| while read type name filemod uid gid slink ; do |
||||
|
case "$type" in |
||||
|
b|c) |
||||
|
majorminor="$( file $name | sed -e "s,.*(\([0-9]*\)/\([0-9]*\))$,\1 \2," )" |
||||
|
echo "nod /$name $filemod $uid $gid $type $majorminor" |
||||
|
;; |
||||
|
d) |
||||
|
echo "dir /$name $filemod $uid $gid" |
||||
|
;; |
||||
|
f) |
||||
|
echo "file /$name $targetdir/$name $filemod $uid $gid" |
||||
|
;; |
||||
|
l) |
||||
|
echo "slink /$name $slink $filemod $uid $gid" |
||||
|
;; |
||||
|
p) |
||||
|
echo "pipe /$name $filemod $uid $gid" |
||||
|
;; |
||||
|
esac |
||||
|
done |
||||
@ -0,0 +1,2 @@ |
|||||
|
#!/bin/sh |
||||
|
exec /lib/rock_initramfs/libexec/mkinitramfs.sh $* |
||||
@ -0,0 +1,78 @@ |
|||||
|
#!/bin/sh |
||||
|
# create the list for cpio-entries to be used by gen_cpio_init |
||||
|
# shall be called by mkinitramfs.sh only. |
||||
|
# sources each file in ./build.d/ |
||||
|
|
||||
|
|
||||
|
#!/bin/sh |
||||
|
# |
||||
|
# find dynamic (share library) dependencies for a binary |
||||
|
# courtesy of rockinitrd package. |
||||
|
# |
||||
|
|
||||
|
libdirs="" |
||||
|
for N in ${rootdir}/lib `sed -e"s,^,${rootdir}," ${rootdir}/etc/ld.so.conf | tr '\n' ' '` ; do |
||||
|
[ -d "$N" ] && libdirs="$libdirs $N" |
||||
|
done |
||||
|
needed_libs() { |
||||
|
local x y z library libqueue liblist |
||||
|
|
||||
|
libqueue="$( mktemp -t libqueue-XXXXXX )" |
||||
|
liblist="$( mktemp -d -t liblist-XXXXXX )" |
||||
|
|
||||
|
# initialize the queue |
||||
|
for x ; do |
||||
|
echo "$x" |
||||
|
done > "$libqueue" |
||||
|
|
||||
|
# get the required libraries of each file |
||||
|
while read y ; do |
||||
|
${cross_compile}readelf -d "${y}" 2>/dev/null | grep "(NEEDED)" | |
||||
|
sed -e "s,.*Shared library: \[\(.*\)\],\1," | |
||||
|
while read library ; do |
||||
|
[ -e "$liblist/$library" ] && continue |
||||
|
|
||||
|
# use the first library with this name |
||||
|
find ${libdirs} -maxdepth 1 -name "${library}" 2>/dev/null | |
||||
|
head -n1 | |
||||
|
while read z ; do |
||||
|
# put the libraries found into the queue, because they might |
||||
|
# require other libraries themselves |
||||
|
echo "$z" >> "$libqueue" |
||||
|
echo "$z" |
||||
|
done |
||||
|
|
||||
|
# list this library as processed |
||||
|
touch "$liblist/$library" |
||||
|
done |
||||
|
done < "$libqueue" |
||||
|
rm -f "$libqueue" ; rm -rf "$liblist" |
||||
|
} |
||||
|
|
||||
|
# add a file ($1) to the contents-list of initramfs |
||||
|
# optionally you can give a different destination filename |
||||
|
# in $2 |
||||
|
# the output is a gen_init_cpio compatible list including all |
||||
|
# dynamic dependencies and the file itself. |
||||
|
add_with_deps() { |
||||
|
srcname=$1 ; shift |
||||
|
dstname=$srcname |
||||
|
[ -n "$1" ] && dstname=$1 |
||||
|
|
||||
|
echo "file $dstname $srcname 755 0 0" |
||||
|
needed_libs $srcname | while read lib |
||||
|
do |
||||
|
echo "file /lib/`basename $lib` $lib 755 0 0" |
||||
|
done |
||||
|
} |
||||
|
|
||||
|
mkdir -pv $TMPDIR/targetdir |
||||
|
|
||||
|
# now go through the build.d directory |
||||
|
for x in $builddir/[0-9][0-9]* |
||||
|
do |
||||
|
echo |
||||
|
echo "sourcing $x ($scriptopt)" >&2 |
||||
|
# use the same environment for each script |
||||
|
( cd $TMPDIR/targetdir ; eval $scriptopt ; . $x ) |
||||
|
done | sort -u |
||||
@ -0,0 +1,512 @@ |
|||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <sys/types.h> |
||||
|
#include <sys/stat.h> |
||||
|
#include <string.h> |
||||
|
#include <unistd.h> |
||||
|
#include <time.h> |
||||
|
#include <fcntl.h> |
||||
|
#include <errno.h> |
||||
|
#include <ctype.h> |
||||
|
#include <limits.h> |
||||
|
|
||||
|
/* |
||||
|
* Original work by Jeff Garzik |
||||
|
* |
||||
|
* External file lists, symlink, pipe and fifo support by Thayne Harbaugh |
||||
|
*/ |
||||
|
|
||||
|
#define xstr(s) #s |
||||
|
#define str(s) xstr(s) |
||||
|
|
||||
|
static unsigned int offset; |
||||
|
static unsigned int ino = 721; |
||||
|
|
||||
|
struct file_handler { |
||||
|
const char *type; |
||||
|
int (*handler)(const char *line); |
||||
|
}; |
||||
|
|
||||
|
static void push_string(const char *name) |
||||
|
{ |
||||
|
unsigned int name_len = strlen(name) + 1; |
||||
|
|
||||
|
fputs(name, stdout); |
||||
|
putchar(0); |
||||
|
offset += name_len; |
||||
|
} |
||||
|
|
||||
|
static void push_pad (void) |
||||
|
{ |
||||
|
while (offset & 3) { |
||||
|
putchar(0); |
||||
|
offset++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static void push_rest(const char *name) |
||||
|
{ |
||||
|
unsigned int name_len = strlen(name) + 1; |
||||
|
unsigned int tmp_ofs; |
||||
|
|
||||
|
fputs(name, stdout); |
||||
|
putchar(0); |
||||
|
offset += name_len; |
||||
|
|
||||
|
tmp_ofs = name_len + 110; |
||||
|
while (tmp_ofs & 3) { |
||||
|
putchar(0); |
||||
|
offset++; |
||||
|
tmp_ofs++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static void push_hdr(const char *s) |
||||
|
{ |
||||
|
fputs(s, stdout); |
||||
|
offset += 110; |
||||
|
} |
||||
|
|
||||
|
static void cpio_trailer(void) |
||||
|
{ |
||||
|
char s[256]; |
||||
|
const char name[] = "TRAILER!!!"; |
||||
|
|
||||
|
sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX" |
||||
|
"%08X%08X%08X%08X%08X%08X%08X", |
||||
|
"070701", /* magic */ |
||||
|
0, /* ino */ |
||||
|
0, /* mode */ |
||||
|
(long) 0, /* uid */ |
||||
|
(long) 0, /* gid */ |
||||
|
1, /* nlink */ |
||||
|
(long) 0, /* mtime */ |
||||
|
0, /* filesize */ |
||||
|
0, /* major */ |
||||
|
0, /* minor */ |
||||
|
0, /* rmajor */ |
||||
|
0, /* rminor */ |
||||
|
(unsigned)strlen(name)+1, /* namesize */ |
||||
|
0); /* chksum */ |
||||
|
push_hdr(s); |
||||
|
push_rest(name); |
||||
|
|
||||
|
while (offset % 512) { |
||||
|
putchar(0); |
||||
|
offset++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkslink(const char *name, const char *target, |
||||
|
unsigned int mode, uid_t uid, gid_t gid) |
||||
|
{ |
||||
|
char s[256]; |
||||
|
time_t mtime = time(NULL); |
||||
|
|
||||
|
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" |
||||
|
"%08X%08X%08X%08X%08X%08X%08X", |
||||
|
"070701", /* magic */ |
||||
|
ino++, /* ino */ |
||||
|
S_IFLNK | mode, /* mode */ |
||||
|
(long) uid, /* uid */ |
||||
|
(long) gid, /* gid */ |
||||
|
1, /* nlink */ |
||||
|
(long) mtime, /* mtime */ |
||||
|
(unsigned)strlen(target)+1, /* filesize */ |
||||
|
3, /* major */ |
||||
|
1, /* minor */ |
||||
|
0, /* rmajor */ |
||||
|
0, /* rminor */ |
||||
|
(unsigned)strlen(name) + 1,/* namesize */ |
||||
|
0); /* chksum */ |
||||
|
push_hdr(s); |
||||
|
push_string(name); |
||||
|
push_pad(); |
||||
|
push_string(target); |
||||
|
push_pad(); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkslink_line(const char *line) |
||||
|
{ |
||||
|
char name[PATH_MAX + 1]; |
||||
|
char target[PATH_MAX + 1]; |
||||
|
unsigned int mode; |
||||
|
int uid; |
||||
|
int gid; |
||||
|
int rc = -1; |
||||
|
|
||||
|
if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) { |
||||
|
fprintf(stderr, "Unrecognized dir format '%s'", line); |
||||
|
goto fail; |
||||
|
} |
||||
|
rc = cpio_mkslink(name, target, mode, uid, gid); |
||||
|
fail: |
||||
|
return rc; |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkgeneric(const char *name, unsigned int mode, |
||||
|
uid_t uid, gid_t gid) |
||||
|
{ |
||||
|
char s[256]; |
||||
|
time_t mtime = time(NULL); |
||||
|
|
||||
|
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" |
||||
|
"%08X%08X%08X%08X%08X%08X%08X", |
||||
|
"070701", /* magic */ |
||||
|
ino++, /* ino */ |
||||
|
mode, /* mode */ |
||||
|
(long) uid, /* uid */ |
||||
|
(long) gid, /* gid */ |
||||
|
2, /* nlink */ |
||||
|
(long) mtime, /* mtime */ |
||||
|
0, /* filesize */ |
||||
|
3, /* major */ |
||||
|
1, /* minor */ |
||||
|
0, /* rmajor */ |
||||
|
0, /* rminor */ |
||||
|
(unsigned)strlen(name) + 1,/* namesize */ |
||||
|
0); /* chksum */ |
||||
|
push_hdr(s); |
||||
|
push_rest(name); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
enum generic_types { |
||||
|
GT_DIR, |
||||
|
GT_PIPE, |
||||
|
GT_SOCK |
||||
|
}; |
||||
|
|
||||
|
struct generic_type { |
||||
|
const char *type; |
||||
|
mode_t mode; |
||||
|
}; |
||||
|
|
||||
|
static struct generic_type generic_type_table[] = { |
||||
|
[GT_DIR] = { |
||||
|
.type = "dir", |
||||
|
.mode = S_IFDIR |
||||
|
}, |
||||
|
[GT_PIPE] = { |
||||
|
.type = "pipe", |
||||
|
.mode = S_IFIFO |
||||
|
}, |
||||
|
[GT_SOCK] = { |
||||
|
.type = "sock", |
||||
|
.mode = S_IFSOCK |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
static int cpio_mkgeneric_line(const char *line, enum generic_types gt) |
||||
|
{ |
||||
|
char name[PATH_MAX + 1]; |
||||
|
unsigned int mode; |
||||
|
int uid; |
||||
|
int gid; |
||||
|
int rc = -1; |
||||
|
|
||||
|
if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) { |
||||
|
fprintf(stderr, "Unrecognized %s format '%s'", |
||||
|
line, generic_type_table[gt].type); |
||||
|
goto fail; |
||||
|
} |
||||
|
mode |= generic_type_table[gt].mode; |
||||
|
rc = cpio_mkgeneric(name, mode, uid, gid); |
||||
|
fail: |
||||
|
return rc; |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkdir_line(const char *line) |
||||
|
{ |
||||
|
return cpio_mkgeneric_line(line, GT_DIR); |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkpipe_line(const char *line) |
||||
|
{ |
||||
|
return cpio_mkgeneric_line(line, GT_PIPE); |
||||
|
} |
||||
|
|
||||
|
static int cpio_mksock_line(const char *line) |
||||
|
{ |
||||
|
return cpio_mkgeneric_line(line, GT_SOCK); |
||||
|
} |
||||
|
|
||||
|
static int cpio_mknod(const char *name, unsigned int mode, |
||||
|
uid_t uid, gid_t gid, char dev_type, |
||||
|
unsigned int maj, unsigned int min) |
||||
|
{ |
||||
|
char s[256]; |
||||
|
time_t mtime = time(NULL); |
||||
|
|
||||
|
if (dev_type == 'b') |
||||
|
mode |= S_IFBLK; |
||||
|
else |
||||
|
mode |= S_IFCHR; |
||||
|
|
||||
|
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" |
||||
|
"%08X%08X%08X%08X%08X%08X%08X", |
||||
|
"070701", /* magic */ |
||||
|
ino++, /* ino */ |
||||
|
mode, /* mode */ |
||||
|
(long) uid, /* uid */ |
||||
|
(long) gid, /* gid */ |
||||
|
1, /* nlink */ |
||||
|
(long) mtime, /* mtime */ |
||||
|
0, /* filesize */ |
||||
|
3, /* major */ |
||||
|
1, /* minor */ |
||||
|
maj, /* rmajor */ |
||||
|
min, /* rminor */ |
||||
|
(unsigned)strlen(name) + 1,/* namesize */ |
||||
|
0); /* chksum */ |
||||
|
push_hdr(s); |
||||
|
push_rest(name); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static int cpio_mknod_line(const char *line) |
||||
|
{ |
||||
|
char name[PATH_MAX + 1]; |
||||
|
unsigned int mode; |
||||
|
int uid; |
||||
|
int gid; |
||||
|
char dev_type; |
||||
|
unsigned int maj; |
||||
|
unsigned int min; |
||||
|
int rc = -1; |
||||
|
|
||||
|
if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u", |
||||
|
name, &mode, &uid, &gid, &dev_type, &maj, &min)) { |
||||
|
fprintf(stderr, "Unrecognized nod format '%s'", line); |
||||
|
goto fail; |
||||
|
} |
||||
|
rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min); |
||||
|
fail: |
||||
|
return rc; |
||||
|
} |
||||
|
|
||||
|
/* Not marked static to keep the compiler quiet, as no one uses this yet... */ |
||||
|
static int cpio_mkfile(const char *name, const char *location, |
||||
|
unsigned int mode, uid_t uid, gid_t gid) |
||||
|
{ |
||||
|
char s[256]; |
||||
|
char *filebuf = NULL; |
||||
|
struct stat buf; |
||||
|
int file = -1; |
||||
|
int retval; |
||||
|
int rc = -1; |
||||
|
|
||||
|
mode |= S_IFREG; |
||||
|
|
||||
|
retval = stat (location, &buf); |
||||
|
if (retval) { |
||||
|
fprintf (stderr, "File %s could not be located\n", location); |
||||
|
goto error; |
||||
|
} |
||||
|
|
||||
|
file = open (location, O_RDONLY); |
||||
|
if (file < 0) { |
||||
|
fprintf (stderr, "File %s could not be opened for reading\n", location); |
||||
|
goto error; |
||||
|
} |
||||
|
|
||||
|
filebuf = malloc(buf.st_size); |
||||
|
if (!filebuf) { |
||||
|
fprintf (stderr, "out of memory\n"); |
||||
|
goto error; |
||||
|
} |
||||
|
|
||||
|
retval = read (file, filebuf, buf.st_size); |
||||
|
if (retval < 0) { |
||||
|
fprintf (stderr, "Can not read %s file\n", location); |
||||
|
goto error; |
||||
|
} |
||||
|
|
||||
|
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" |
||||
|
"%08X%08X%08X%08X%08X%08X%08X", |
||||
|
"070701", /* magic */ |
||||
|
ino++, /* ino */ |
||||
|
mode, /* mode */ |
||||
|
(long) uid, /* uid */ |
||||
|
(long) gid, /* gid */ |
||||
|
1, /* nlink */ |
||||
|
(long) buf.st_mtime, /* mtime */ |
||||
|
(int) buf.st_size, /* filesize */ |
||||
|
3, /* major */ |
||||
|
1, /* minor */ |
||||
|
0, /* rmajor */ |
||||
|
0, /* rminor */ |
||||
|
(unsigned)strlen(name) + 1,/* namesize */ |
||||
|
0); /* chksum */ |
||||
|
push_hdr(s); |
||||
|
push_string(name); |
||||
|
push_pad(); |
||||
|
|
||||
|
fwrite(filebuf, buf.st_size, 1, stdout); |
||||
|
offset += buf.st_size; |
||||
|
push_pad(); |
||||
|
rc = 0; |
||||
|
|
||||
|
error: |
||||
|
if (filebuf) free(filebuf); |
||||
|
if (file >= 0) close(file); |
||||
|
return rc; |
||||
|
} |
||||
|
|
||||
|
static int cpio_mkfile_line(const char *line) |
||||
|
{ |
||||
|
char name[PATH_MAX + 1]; |
||||
|
char location[PATH_MAX + 1]; |
||||
|
unsigned int mode; |
||||
|
int uid; |
||||
|
int gid; |
||||
|
int rc = -1; |
||||
|
|
||||
|
if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) { |
||||
|
fprintf(stderr, "Unrecognized file format '%s'", line); |
||||
|
goto fail; |
||||
|
} |
||||
|
rc = cpio_mkfile(name, location, mode, uid, gid); |
||||
|
fail: |
||||
|
return rc; |
||||
|
} |
||||
|
|
||||
|
void usage(const char *prog) |
||||
|
{ |
||||
|
fprintf(stderr, "Usage:\n" |
||||
|
"\t%s <cpio_list>\n" |
||||
|
"\n" |
||||
|
"<cpio_list> is a file containing newline separated entries that\n" |
||||
|
"describe the files to be included in the initramfs archive:\n" |
||||
|
"\n" |
||||
|
"# a comment\n" |
||||
|
"file <name> <location> <mode> <uid> <gid>\n" |
||||
|
"dir <name> <mode> <uid> <gid>\n" |
||||
|
"nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n" |
||||
|
"slink <name> <target> <mode> <uid> <gid>\n" |
||||
|
"pipe <name> <mode> <uid> <gid>\n" |
||||
|
"sock <name> <mode> <uid> <gid>\n" |
||||
|
"\n" |
||||
|
"<name> name of the file/dir/nod/etc in the archive\n" |
||||
|
"<location> location of the file in the current filesystem\n" |
||||
|
"<target> link target\n" |
||||
|
"<mode> mode/permissions of the file\n" |
||||
|
"<uid> user id (0=root)\n" |
||||
|
"<gid> group id (0=root)\n" |
||||
|
"<dev_type> device type (b=block, c=character)\n" |
||||
|
"<maj> major number of nod\n" |
||||
|
"<min> minor number of nod\n" |
||||
|
"\n" |
||||
|
"example:\n" |
||||
|
"# A simple initramfs\n" |
||||
|
"dir /dev 0755 0 0\n" |
||||
|
"nod /dev/console 0600 0 0 c 5 1\n" |
||||
|
"dir /root 0700 0 0\n" |
||||
|
"dir /sbin 0755 0 0\n" |
||||
|
"file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n", |
||||
|
prog); |
||||
|
} |
||||
|
|
||||
|
struct file_handler file_handler_table[] = { |
||||
|
{ |
||||
|
.type = "file", |
||||
|
.handler = cpio_mkfile_line, |
||||
|
}, { |
||||
|
.type = "nod", |
||||
|
.handler = cpio_mknod_line, |
||||
|
}, { |
||||
|
.type = "dir", |
||||
|
.handler = cpio_mkdir_line, |
||||
|
}, { |
||||
|
.type = "slink", |
||||
|
.handler = cpio_mkslink_line, |
||||
|
}, { |
||||
|
.type = "pipe", |
||||
|
.handler = cpio_mkpipe_line, |
||||
|
}, { |
||||
|
.type = "sock", |
||||
|
.handler = cpio_mksock_line, |
||||
|
}, { |
||||
|
.type = NULL, |
||||
|
.handler = NULL, |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
#define LINE_SIZE (2 * PATH_MAX + 50) |
||||
|
|
||||
|
int main (int argc, char *argv[]) |
||||
|
{ |
||||
|
FILE *cpio_list; |
||||
|
char line[LINE_SIZE]; |
||||
|
char *args, *type; |
||||
|
int ec = 0; |
||||
|
int line_nr = 0; |
||||
|
|
||||
|
if (2 != argc) { |
||||
|
usage(argv[0]); |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
if (! (cpio_list = fopen(argv[1], "r"))) { |
||||
|
fprintf(stderr, "ERROR: unable to open '%s': %s\n\n", |
||||
|
argv[1], strerror(errno)); |
||||
|
usage(argv[0]); |
||||
|
exit(1); |
||||
|
} |
||||
|
|
||||
|
while (fgets(line, LINE_SIZE, cpio_list)) { |
||||
|
int type_idx; |
||||
|
size_t slen = strlen(line); |
||||
|
|
||||
|
line_nr++; |
||||
|
|
||||
|
if ('#' == *line) { |
||||
|
/* comment - skip to next line */ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (! (type = strtok(line, " \t"))) { |
||||
|
fprintf(stderr, |
||||
|
"ERROR: incorrect format, could not locate file type line %d: '%s'\n", |
||||
|
line_nr, line); |
||||
|
ec = -1; |
||||
|
} |
||||
|
|
||||
|
if ('\n' == *type) { |
||||
|
/* a blank line */ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (slen == strlen(type)) { |
||||
|
/* must be an empty line */ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (! (args = strtok(NULL, "\n"))) { |
||||
|
fprintf(stderr, |
||||
|
"ERROR: incorrect format, newline required line %d: '%s'\n", |
||||
|
line_nr, line); |
||||
|
ec = -1; |
||||
|
} |
||||
|
|
||||
|
for (type_idx = 0; file_handler_table[type_idx].type; type_idx++) { |
||||
|
int rc; |
||||
|
if (! strcmp(line, file_handler_table[type_idx].type)) { |
||||
|
if ((rc = file_handler_table[type_idx].handler(args))) { |
||||
|
ec = rc; |
||||
|
fprintf(stderr, " line %d\n", line_nr); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (NULL == file_handler_table[type_idx].type) { |
||||
|
fprintf(stderr, "unknown file type line %d: '%s'\n", |
||||
|
line_nr, line); |
||||
|
} |
||||
|
} |
||||
|
cpio_trailer(); |
||||
|
|
||||
|
exit(ec); |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
#!/bin/sh |
||||
|
# |
||||
|
# find dynamic (share library) dependencies for a binary |
||||
|
# courtesy of rockinitrd package. |
||||
|
# |
||||
|
export rootdir="" |
||||
|
|
||||
|
export libdirs="${rootdir}/lib ${rootdir}/usr/lib" |
||||
|
|
||||
|
for x in $* |
||||
|
do |
||||
|
readelf -d $x 2>/dev/null | grep "(NEEDED)" | |
||||
|
sed -e"s,.*Shared library: \[\(.*\)\],\1," | |
||||
|
while read library ; do |
||||
|
find $libdirs -maxdepth 1 -name "$library" | |
||||
|
sed -e "s,^$rootdir,,g" |
||||
|
done |
||||
|
done |
||||
@ -0,0 +1,149 @@ |
|||||
|
#!/bin/sh |
||||
|
|
||||
|
# create initramfs image by using gen_cpio_init |
||||
|
# (we do not need root privileges for this!) |
||||
|
# |
||||
|
# see ./build.d/ to see how the content is created! |
||||
|
|
||||
|
export PATH=$PATH:/sbin:/bin:/usr/bin:/usr/sbin |
||||
|
|
||||
|
k_ver=`uname -r` |
||||
|
|
||||
|
usage() { |
||||
|
cat <<-EOF |
||||
|
mkinitramfs - create initramfs image by using gen_cpio_init |
||||
|
|
||||
|
mkinitramfs [ -r KERNEL_VERSION ] [ -m MODULES_DIR ] [ -o OUTPUT_FILE ] |
||||
|
|
||||
|
If no options are given the following defaults apply: |
||||
|
mkinitramfs -r $k_ver -m $mod_origin -o $outfile |
||||
|
|
||||
|
Options: |
||||
|
-r Specify kernel version to use for modules dir |
||||
|
-m Specify directory where to search for kernel modules |
||||
|
-o Specify location of output file |
||||
|
|
||||
|
--root-dir |
||||
|
--build-dir |
||||
|
--files-dir |
||||
|
|
||||
|
EOF |
||||
|
} |
||||
|
|
||||
|
rootdir="" |
||||
|
|
||||
|
while [ ${#} -gt 0 ] |
||||
|
do |
||||
|
case "$1" in |
||||
|
-v) verbose=yes |
||||
|
;; |
||||
|
-r) |
||||
|
k_ver=$2 |
||||
|
shift |
||||
|
;; |
||||
|
-m) |
||||
|
mod_origin=$2 |
||||
|
shift |
||||
|
;; |
||||
|
-o) |
||||
|
outfile=$2 |
||||
|
shift |
||||
|
;; |
||||
|
-p) |
||||
|
scriptopt="$scriptopt ${2%%=*}='${2#*=}'" |
||||
|
shift |
||||
|
;; |
||||
|
--root-dir) |
||||
|
rootdir="$2" |
||||
|
shift |
||||
|
;; |
||||
|
--build-dir) |
||||
|
builddir="$2" |
||||
|
shift |
||||
|
;; |
||||
|
--files-dir) |
||||
|
filesdir="$2" |
||||
|
shift |
||||
|
;; |
||||
|
--add-gen-line) |
||||
|
additional_gen_lines="$additional_gen_lines;$2" |
||||
|
shift |
||||
|
;; |
||||
|
*) |
||||
|
usage=1 |
||||
|
;; |
||||
|
esac |
||||
|
shift |
||||
|
done |
||||
|
|
||||
|
[ -n "${rootdir}" -a "${rootdir:0:1}" != "/" ] && rootdir="`pwd`/$rootdir" |
||||
|
|
||||
|
[ -z "$mod_origin" ] && mod_origin=$rootdir/lib/modules/$k_ver |
||||
|
[ -z "$outfile" ] && outfile=$rootdir/boot/initramfs-$k_ver.cpio.gz |
||||
|
|
||||
|
if [ "$usage" = "1" ] |
||||
|
then |
||||
|
usage |
||||
|
exit |
||||
|
fi |
||||
|
|
||||
|
export BASE=$rootdir/lib/rock_initramfs |
||||
|
export LIBEXEC=${BASE}/libexec |
||||
|
|
||||
|
[ -z "$builddir" ] && builddir="$BASE/build.d" |
||||
|
[ -z "$filesdir" ] && filesdir="$BASE/files" |
||||
|
[ "${builddir:0:1}" = "/" ] || builddir="$rootdir/$builddir" |
||||
|
[ "${filesdir:0:1}" = "/" ] || filesdir="$rootdir/$filesdir" |
||||
|
|
||||
|
[ ${outfile:0:1} = "/" ] || outfile="`pwd`/$outfile" |
||||
|
[ ${mod_origin:0:1} = "/" ] || mod_origin="`pwd`/$mod_origin" |
||||
|
|
||||
|
|
||||
|
cat << EOF |
||||
|
kernel version: $k_ver |
||||
|
module origin: $mod_origin |
||||
|
output file: $outfile |
||||
|
|
||||
|
root dir: $rootdir |
||||
|
build dir: $builddir |
||||
|
files dir: $filesdir |
||||
|
EOF |
||||
|
|
||||
|
export rootdir |
||||
|
export builddir |
||||
|
export filesdir |
||||
|
export verbose |
||||
|
|
||||
|
export k_ver mod_origin scriptopt |
||||
|
|
||||
|
# provide a tmpdir to our helpers |
||||
|
export TMPDIR="/tmp/irfs-`date +%s`.$$" |
||||
|
mkdir -pv $TMPDIR |
||||
|
|
||||
|
# compile our list of cpio-content |
||||
|
${LIBEXEC}/build-list.sh > ${TMPDIR}/list |
||||
|
echo "$additional_gen_lines" | tr ';' '\n' >> ${TMPDIR}/list |
||||
|
|
||||
|
if [ -n "$verbose" ] |
||||
|
then |
||||
|
echo "compiled list:" |
||||
|
echo "=======================" |
||||
|
cat ${TMPDIR}/list |
||||
|
echo "=======================" |
||||
|
fi |
||||
|
|
||||
|
# create and compress cpio archive |
||||
|
${LIBEXEC}/${cross_compile}gen_init_cpio ${TMPDIR}/list | gzip -9 > $outfile |
||||
|
|
||||
|
if [ -n "$verbose" ] |
||||
|
then |
||||
|
echo "contents of TMPDIR=$TMPDIR:" |
||||
|
echo "=======================" |
||||
|
find $TMPDIR |
||||
|
echo "=======================" |
||||
|
fi |
||||
|
# remove the tmpdir |
||||
|
rm -rf $TMPDIR |
||||
|
|
||||
|
# can be extracted with: |
||||
|
# gzip -dc ../irfs.cpio.gz | ( rm -rf ./root ; mkdir root ; cd root ; cpio -i -d -H newc --no-absolute-filenames ) |
||||
@ -0,0 +1,54 @@ |
|||||
|
# |
||||
|
# [COPY] --- ROCK-COPYRIGHT-NOTE-BEGIN --- |
||||
|
# [COPY] |
||||
|
# [COPY] This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
||||
|
# [COPY] Please add additional copyright information _after_ the line containing |
||||
|
# [COPY] the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by |
||||
|
# [COPY] the ./scripts/Create-CopyPatch script. Do not edit this copyright text! |
||||
|
# [COPY] |
||||
|
# [COPY] ROCK Linux: rock-src/package/teha/rescue-stage1-init/rescue-stage1-init.desc |
||||
|
# [COPY] ROCK Linux is Copyright (C) 1998 - 2007 Clifford Wolf |
||||
|
# [COPY] |
||||
|
# [COPY] This program is free software; you can redistribute it and/or modify |
||||
|
# [COPY] it under the terms of the GNU General Public License as published by |
||||
|
# [COPY] the Free Software Foundation; either version 2 of the License, or |
||||
|
# [COPY] (at your option) any later version. A copy of the GNU General Public |
||||
|
# [COPY] License can be found at Documentation/COPYING. |
||||
|
# [COPY] |
||||
|
# [COPY] Many people helped and are helping developing ROCK Linux. Please |
||||
|
# [COPY] have a look at http://www.rocklinux.org/ and the Documentation/TEAM |
||||
|
# [COPY] file for details. |
||||
|
# [COPY] |
||||
|
# [COPY] --- ROCK-COPYRIGHT-NOTE-END --- |
||||
|
|
||||
|
build_main() { |
||||
|
INST_DIR=$root/lib/rock_initramfs |
||||
|
|
||||
|
mkdir -p $INST_DIR/libexec/ |
||||
|
|
||||
|
$CC ${confdir}/libexec/gen_init_cpio.c -o $INST_DIR/libexec/gen_init_cpio |
||||
|
|
||||
|
install -m 755 ${confdir}/libexec/build-list.sh ${INST_DIR}/libexec/ |
||||
|
install -m 755 ${confdir}/libexec/list-deps.sh ${INST_DIR}/libexec/ |
||||
|
install -m 755 ${confdir}/libexec/99-finish ${INST_DIR}/libexec/ |
||||
|
|
||||
|
install -m 755 ${confdir}/libexec/mkinitramfs.sh ${root}/usr/sbin/mkinitramfs |
||||
|
|
||||
|
# copy $confdir/build.d/* into running system... |
||||
|
mkdir -p ${INST_DIR}/build.d |
||||
|
for x in ${confdir}/build.d/* |
||||
|
do |
||||
|
install -m 644 ${x} ${INST_DIR}/build.d/ |
||||
|
done |
||||
|
|
||||
|
( |
||||
|
# copy $confdir/files into the running system... |
||||
|
cd ${confdir}/files |
||||
|
find . -name .svn -prune -o -type d -exec mkdir -p ${INST_DIR}/files/{} ';' |
||||
|
find . -name .svn -prune -o -type f -exec cp -v {} ${INST_DIR}/files/{} ';' |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
autoextract=0 |
||||
|
srctar="none" |
||||
|
custmain="build_main" |
||||
@ -0,0 +1,39 @@ |
|||||
|
|
||||
|
[COPY] --- ROCK-COPYRIGHT-NOTE-BEGIN --- |
||||
|
[COPY] |
||||
|
[COPY] This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
||||
|
[COPY] Please add additional copyright information _after_ the line containing |
||||
|
[COPY] the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by |
||||
|
[COPY] the ./scripts/Create-CopyPatch script. Do not edit this copyright text! |
||||
|
[COPY] |
||||
|
[COPY] ROCK Linux: rock-src/package/teha/rescue-stage1-init/rescue-stage1-init.desc |
||||
|
[COPY] ROCK Linux is Copyright (C) 1998 - 2007 Clifford Wolf |
||||
|
[COPY] |
||||
|
[COPY] This program is free software; you can redistribute it and/or modify |
||||
|
[COPY] it under the terms of the GNU General Public License as published by |
||||
|
[COPY] the Free Software Foundation; either version 2 of the License, or |
||||
|
[COPY] (at your option) any later version. A copy of the GNU General Public |
||||
|
[COPY] License can be found at Documentation/COPYING. |
||||
|
[COPY] |
||||
|
[COPY] Many people helped and are helping developing ROCK Linux. Please |
||||
|
[COPY] have a look at http://www.rocklinux.org/ and the Documentation/TEAM |
||||
|
[COPY] file for details. |
||||
|
[COPY] |
||||
|
[COPY] --- ROCK-COPYRIGHT-NOTE-END --- |
||||
|
|
||||
|
[I] ROCKLinux initial-ram-fs factory |
||||
|
|
||||
|
[T] ROCKLinux initial-ram-fs |
||||
|
[T] - creates a cpio archive which can be passed to |
||||
|
[T] boot loader (via initrd) as initramfs |
||||
|
|
||||
|
[A] Tobias Hintze <th@rocklinux.org> |
||||
|
[M] Tobias Hintze <th@rocklinux.org> |
||||
|
|
||||
|
[C] base/system |
||||
|
|
||||
|
[L] GPL |
||||
|
[S] Stable |
||||
|
[V] 2 |
||||
|
[P] X ---3-----9 236.500 |
||||
|
|
||||