mirror of https://gitee.com/openkylin/linux.git
rcutorture: Add initrd support for systems lacking dracut
The support for creating initrd directories using dracut is a great improvement over having to always hand-create them, it is a bit annoying to have to install some otherwise irrelevant package just to be able to run rcutorture. This commit therefore adds support for creating initrd directories on systems innocent of dracut. You do need gcc, but then again you need that to build the kernel (or to build llvm) in any case. The idea is to create an initrd directory containing nothing but a statically linked binary having a for-loop over a long-term sleep(). The result is a Linux kernel with almost no userspace: even the time-honored /dev, /lib, /tmp, and /usr directories are gone. In fact, the only directory present is "/", but only because I don't know how to get rid of it, at least short of not having an initrd in the first place. Although statically linked binaries are much maligned, and rightly so, their disadvantages seem to be irrelevant for this particular use case. From https://www.akkadia.org/drepper/no_static_linking.html: 1. Fixes are difficult to apply to hordes of widely scattered statically linked binaries. But in this case, there is only one binary, but there would otherwise be no fewer than four libraries. 2. Security measures like local address randomization cannot be used. Prudence prevents me from asserting that it is impossible to base a remote attack on a networking-free rcutorture instance. Nevertheless, bonus points to the first person who comes up with such an attack! 3. More efficient use of physical memory. Not in this case, given that libc is 1.8MB and the statically linked binary "only" 800K. 4. Features such as locales, name service switch (NSS), internationalized domain names (IDN) tool, and so on require dynamic linking. Bonus points to the first person coming up with a valid rcutorture use case requiring these features in its initrd. 5. Accidental violations of (L)GPL. Actually, this change actually helps -avoid- such violations by reducing the temptation to pass around tarballs of rcutorture-ready initrd directories. After all, the rcutorture scripts automatically create an initrd directory for you, so why bother with the tarballs? 6. Tools and hacks like ltrace, LD_PRELOAD, LD_PROFILE, and LD_AUDIT don't work. Again, bonus points to the first person coming up with a valid rcutorture use case requiring these features in its initrd. Nevertheless, the script will use dracut if available, and will create the statically linked binary only when dracut are missing. Those preferring the smaller initrd directory resulting from the statically linked binary (like me) are free to hand-edit mkinitrd.sh to remove the code using dracut. ;-) Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
parent
8f15c682ac
commit
38e630424b
|
@ -46,15 +46,41 @@ done
|
|||
__EOF___
|
||||
|
||||
# Try using dracut to create initrd
|
||||
command -v dracut >/dev/null 2>&1 || { echo >&2 "Dracut not installed"; exit 1; }
|
||||
echo Creating $D/initrd using dracut.
|
||||
if command -v dracut >/dev/null 2>&1
|
||||
then
|
||||
echo Creating $D/initrd using dracut.
|
||||
# Filesystem creation
|
||||
dracut --force --no-hostonly --no-hostonly-cmdline --module "base" $T/initramfs.img
|
||||
cd $D
|
||||
mkdir initrd
|
||||
cd initrd
|
||||
zcat $T/initramfs.img | cpio -id
|
||||
cp $T/init init
|
||||
chmod +x init
|
||||
echo Done creating $D/initrd using dracut
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Filesystem creation
|
||||
dracut --force --no-hostonly --no-hostonly-cmdline --module "base" $T/initramfs.img
|
||||
# No dracut, so create a C-language initrd/init program and statically
|
||||
# link it. This results in a very small initrd, but might be a bit less
|
||||
# future-proof than dracut.
|
||||
echo "Could not find dracut, attempting C initrd"
|
||||
cd $D
|
||||
mkdir initrd
|
||||
cd initrd
|
||||
zcat $T/initramfs.img | cpio -id
|
||||
cp $T/init init
|
||||
echo Done creating $D/initrd using dracut
|
||||
cat > init.c << '___EOF___'
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, int argv[])
|
||||
{
|
||||
for (;;)
|
||||
sleep(1000*1000*1000); /* One gigasecond is ~30 years. */
|
||||
return 0;
|
||||
}
|
||||
___EOF___
|
||||
gcc -static -Os -o init init.c
|
||||
strip init
|
||||
rm init.c
|
||||
echo "Done creating a statically linked C-language initrd"
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
This document describes one way to create the initrd directory hierarchy
|
||||
in order to allow an initrd to be built into your kernel. The trick
|
||||
here is to steal the initrd file used on your Linux laptop, Ubuntu in
|
||||
this case. There are probably much better ways of doing this.
|
||||
The rcutorture scripting tools automatically create the needed initrd
|
||||
directory using dracut. Failing that, this tool will create an initrd
|
||||
containing a single statically linked binary named "init" that loops
|
||||
over a very long sleep() call. In both cases, this creation is done
|
||||
by tools/testing/selftests/rcutorture/bin/mkinitrd.sh.
|
||||
|
||||
That said, here are the commands:
|
||||
However, if you are attempting to run rcutorture on a system that does
|
||||
not have dracut installed, and if you don't like the notion of static
|
||||
linking, you might wish to press an existing initrd into service:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
cd tools/testing/selftests/rcutorture
|
||||
|
@ -11,22 +14,7 @@ zcat /initrd.img > /tmp/initrd.img.zcat
|
|||
mkdir initrd
|
||||
cd initrd
|
||||
cpio -id < /tmp/initrd.img.zcat
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Another way to create an initramfs image is using "dracut"[1], which is
|
||||
available on many distros, however the initramfs dracut generates is a cpio
|
||||
archive with another cpio archive in it, so an extra step is needed to create
|
||||
the initrd directory hierarchy.
|
||||
|
||||
Here are the commands to create a initrd directory for rcutorture using
|
||||
dracut:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
dracut --no-hostonly --no-hostonly-cmdline --module "base bash shutdown" /tmp/initramfs.img
|
||||
cd tools/testing/selftests/rcutorture
|
||||
mkdir initrd
|
||||
cd initrd
|
||||
/usr/lib/dracut/skipcpio /tmp/initramfs.img | zcat | cpio -id < /tmp/initramfs.img
|
||||
# Manually verify that initrd contains needed binaries and libraries.
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Interestingly enough, if you are running rcutorture, you don't really
|
||||
|
@ -39,75 +27,12 @@ with 0755 mode.
|
|||
------------------------------------------------------------------------
|
||||
#!/bin/sh
|
||||
|
||||
[ -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 -t sysfs -o nodev,noexec,nosuid sysfs /sys
|
||||
mount -t proc -o nodev,noexec,nosuid proc /proc
|
||||
# Some things don't work properly without /etc/mtab.
|
||||
ln -sf /proc/mounts /etc/mtab
|
||||
|
||||
# Note that this only becomes /dev on the real filesystem if udev's scripts
|
||||
# are used; which they will be, but it's worth pointing out
|
||||
if ! mount -t devtmpfs -o mode=0755 udev /dev; then
|
||||
echo "W: devtmpfs not available, falling back to tmpfs for /dev"
|
||||
mount -t tmpfs -o mode=0755 udev /dev
|
||||
[ -e /dev/console ] || mknod --mode=600 /dev/console c 5 1
|
||||
[ -e /dev/kmsg ] || mknod --mode=644 /dev/kmsg c 1 11
|
||||
[ -e /dev/null ] || mknod --mode=666 /dev/null c 1 3
|
||||
fi
|
||||
|
||||
mkdir /dev/pts
|
||||
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
|
||||
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
|
||||
mkdir /run/initramfs
|
||||
# compatibility symlink for the pre-oneiric locations
|
||||
ln -s /run/initramfs /dev/.initramfs
|
||||
|
||||
# Export relevant variables
|
||||
export ROOT=
|
||||
export ROOTDELAY=
|
||||
export ROOTFLAGS=
|
||||
export ROOTFSTYPE=
|
||||
export IP=
|
||||
export BOOT=
|
||||
export BOOTIF=
|
||||
export UBIMTD=
|
||||
export break=
|
||||
export init=/sbin/init
|
||||
export quiet=n
|
||||
export readonly=y
|
||||
export rootmnt=/root
|
||||
export debug=
|
||||
export panic=
|
||||
export blacklist=
|
||||
export resume=
|
||||
export resume_offset=
|
||||
export recovery=
|
||||
|
||||
for i in /sys/devices/system/cpu/cpu*/online
|
||||
do
|
||||
case $i in
|
||||
'/sys/devices/system/cpu/cpu0/online')
|
||||
;;
|
||||
'/sys/devices/system/cpu/cpu*/online')
|
||||
;;
|
||||
*)
|
||||
echo 1 > $i
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
while :
|
||||
do
|
||||
sleep 10
|
||||
done
|
||||
------------------------------------------------------------------------
|
||||
|
||||
References:
|
||||
[1]: https://dracut.wiki.kernel.org/index.php/Main_Page
|
||||
[2]: http://blog.elastocloud.org/2015/06/rapid-linux-kernel-devtest-with-qemu.html
|
||||
[3]: https://www.centos.org/forums/viewtopic.php?t=51621
|
||||
This approach also allows most of the binaries and libraries in the
|
||||
initrd filesystem to be dispensed with, which can save significant
|
||||
space in rcutorture's "res" directory.
|
||||
|
|
Loading…
Reference in New Issue