In any situation in which being root is possible this is an overcomplicated solution to a simple problem. However not always being root is possible and in that few cases having an automatic tool which converts a tarball in a loop/ext2 images is very useful. I am going to explain how to create this automatic tool which you can modify to adapt your needs.
Introducing the problem
The fastest way to do a initrd image is mount a loop and populate it:
dd if=/dev/zero of=initrd.img bs=1 count=1 seek=2M
yes | mke2fs initrd.img
mkdir -p /mnt/loop
mount -o loop -t ext2 initrd.img /mnt/loop
but this require root password and to avoid being root /etc/tab should allow it:
/tmp/image /tmp/loop ext2 users,loop,dev 0 0
apart security risks this solution should not work fine for a multi-users enviroment.
In a single user enviroment being root could not a problem but Linux Embedded hackers working in a big company environments could proficiently operate in multi users server environments too. In order to make /etc/fstab multi-user friendly could be changed as follows:
for USER in $ALL-USERS; do
sudo - $USER mkdir -p /tmp/image-$USER /tmp/loop-$USER
echo "/tmp/image-$USER /tmp/loop-$USER ext2 users,loop,dev 0 0" »/etc/fstab
Server admin should append one of this row for each $USER it would enable to made initrd images and users should not delete their directories otherwise others could re-create their directories and interfere with their privileges. Even system admin accept this solution, it does not one user but multi task safe. In facts a user could not mount two loops but just one. Finally loop device are finite and could be less than users needs.
Introducing a solution
Linux User Mode could solve all problems related to previous situations and needs. Linux User Mode allow to launch another kernel and create a running jail where user could be a local root. Automation of this process could be done with four parts and two scripts.
user land script
The first is following:
mkdir -p tar2loop
cat > tar2loop.sh « EOF
#!/bin/bash # # (C) 2008, Roberto A. Foglietta <email@example.com> # tar2loop and this script are released under GPL v2 only terms # unset DISPLAY XTERM T2LP=$(dirname $0)/tar2loop test -d $T2LP/bin || T2LP=$(dirname $0) export PATH=$PATH:$T2LP/bin copts="expert noprobe text mem=16M ubda=$T2LP/tar2loop.rootfs" case "x$1" in x--editrc) shift chmod u+w tar2loop.rootfs umlinux $copts ubdb="$1" ubdc="$2" ;; x--dumpfs) test -e "$2" || cat tar2loop.rootfs > "$2.tar" chmod a-w tar2loop.rootfs umlinux ro halt dump $copts ubdc="$2.tar" bzip2 -9 "$2.tar"; ls -al "$2.tar.bz2" ;; *) test -e "$1" || exit 1 test -e "$2" || exit 2 chmod a-w tar2loop.rootfs time umlinux ro halt $copts ubdb="$1" ubdc="$2" ;; esac
chmod 755 tar2loop.sh
user mode linux kernel and tools
After that go to downloads page and download the User Mode Linux kernel and User Mode Linux utilities. Kernel could be used in pre compiled form or could be compiled from sources following this manual. Another possibilities is to install User Mode Linux kernel and tools from server distribution package system but this last solution requires your system administrator collaborate.
In order to not annoy the sysadmin with its prime-role dute, serving the users, it is better do it by yourself. Following this always working policy the Use Mode Linux kernel should be copied in file tar2tool/bin/umlinux and make it executable:
wget -c http://user-mode-linux.sourceforge.net/linux-2.6.24-rc7.bz2
mv -f linux-2.6.24-rc7 umlinux
chmod 755 umlinux
User Mode Linux tools could not be retrieved just compiled and compile it is necessary, after that copy them in tar2loop/bin directory:
tar xvjf uml_utilities_20070815.tar.bz2
make DESTDIR=_install install
cp -f $(find _install -type f) ../bin
user mode linux root file system
User Mode Linux needs to run on a root file system which itself a initrd image. This compressed root file system image contains all the utilities busybox and mk2efs and a script /etc/rc.sh which automagically let it able to transform a tarball file into a initrd image. Download and explode it with bunzip2 and save in tar2loop directory together tar2loop.sh script.
If you like to build by yourself this rootfs you need to download busybox and e2fsprogs. About the frist package this config is enought for the purpose and about the second just compiling mke2fs are needed. Please note both of these two packages are needed to be compiled statically linked.
User Mode Linux root file system structure:
- root directory trees in particular:
- /etc, /root, /tmp. /proc, /mnt/loop. /var/log
- devices nodes which populates /dev
- busybox which populates these:
- /bin, /sbin. /usr/sbin, /usr/bin and /linuxrc
- /etc/fstab soft linked to /proc/mounts
- /etc/inittab and /etc/shutdown (optional)
#!/bin/sh echo echo "(C) 2008, Roberto A. Foglietta <firstname.lastname@example.org>" echo " tar2loop and this script are released under GPL v2 only terms" echo mount -t proc proc /proc mount -t tmpfs tmpfs /tmp mount -o remount,rw / busybox --install if cat /proc/mounts 2>/dev/null >/etc/mtab; then df rm -f /dev/ubd* for i in 0 1 2 3 4 5 6 7; do mknod /dev/ubd$i b 98 `expr $i \* 16` done else echo "**** WARNING: rootfs is in read-only mode" fi cat /dev/zero >/dev/ubd2 2>/dev/null if grep -q " dump " /proc/cmdline; then mkdir /tmp/root cd /tmp/root mkdir -p proc tmp mnt/loop tar cvf /tmp/rootfs.tar.bz2 /bin /dev /etc /linuxrc /root /sbin /usr /var proc tmp mnt cat /tmp/rootfs.tar.bz2 >/dev/ubd2 else if mke2fs /dev/ubd2 2>/dev/null; then mkdir -p /mnt/loop if mount -t ext2 /dev/ubd2 /mnt/loop; then n=0 for i in x xz xj; do cat /dev/ubd1 | tar -C /mnt/loop -$i 2>/tmp/tar.err && break n=`expr $n + 1` done if [ $n -ge 3 ]; then grep -v "magic" /tmp/tar.err echo "**** ERROR: tar /dev/ubd1 in /mnt/loop fails" else ls -al /mnt/loop fi df -k | grep -v -e "^rootfs" -e "^/dev/root" -e "^tmpfs" umount /mnt/loop else echo "**** ERROR: mount /dev/ubd2 fails" fi else echo "**** ERROR: mke2fs /dev/ubd2 fails" fi fi grep -q " halt " /proc/cmdline && halt
how to build a proper tarball for tar2loop
Once prepared the tar2loop environment there is another problem: build up a tarball contains proper files with proper permission and ownership. In particular it is impossible for any non root user create or manipulate /dev directory content. To do that there are two ways:
- enter in tar2loop in —editrc mode in order to produce a tarball containing a /dev structure exits and use tar —append to add others files and directories;
- use fakeroot to produce a tarball containing a /dev structure and to manipulate ownership and permission in a proper way.
The second way has been suggested by Alessandro Rubini who explained me that fakeroot is used for making debian packages. This is the best of two and fakeroot worth the time of compiling and installing it on your system. He shown me also genext2fs which is able to produce EXT2 loop image without being root and also to populate /dev at the same time! However tar2loop approach, as any other solution based on virtualization, allows to create a loop file using any kind of filesystem the kernel supports and exactly the same version you would use and debug. Apart these very special requirements fakeroot combined with genext2fs would solve any others needs and probably suck much lesser.
Hey, you may have learned three things: the existence of two nice tools and to read the whole recipe before put your hands on cooking for yourself!!!