LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   How to mount initrd as aufs? (http://www.linuxquestions.org/questions/linux-general-1/how-to-mount-initrd-as-aufs-4175460485/)

AllenKll 05-02-2013 03:54 PM

How to mount initrd as aufs?
 
Hello all,
I'm working on an embedded project where I load the initial ramdisk and kernel from NV in the bootloader and run it from there. I am using u-boot.

I also have an SD card in the system. What I want to do is have the inital ramdisk mounted as an aufs union with a folder on the SD card. This is so that any changed made to the root file system will get written to the card and reloaded on a reboot.

I have seen tutorials about doing a switch_root that includes a mount --move. But these don't seem to work for my situation as there is no "dev"ice active as the root directory; as it was loaded by the u-boot and passed to the kernel.
I did a little digging to find that "stat /" gives me information that the kernel is using the /dev/ram0 device, but doing a mount --move using that doesn't seem to work.
Here's my latest attempt using mount --bind:

Here's my fstab:
Code:

tmpfs          /tmp            tmpfs  defaults,noexec,nosuid 0 0
proc            /proc          proc    nodev,noexec,nosuid 0 0
sys            /sys            sysfs  defaults,noexec,nosuid 0 0
/dev/mmcblk0p1  /card          ext3    rw

Here's my inittab:
Code:

::wait:/bin/root_switch
::restart:/bin/switch_root -c /dev/console /aufs /sbin/init

and the root_switch script
Code:

#!/bin/ash
mount /proc
mount /sys
mount /tmp

sleep 3
echo "*** ls / *** "
ls /

echo "*** mounting card ***"
mount /card

echo "*** ls /card *** "
ls /card

echo "*** mounting bind to root ***"
mount --bind / /ramdisk

echo "*** ls ramdisk ***"
ls /ramdisk

echo "*** mounting AUFS ***"
mount -t aufs -o br=/card/root_union:/ramdisk=ro none /aufs

echo "*** ls aufs ***"
ls /aufs

echo "*** Contents of mount ***"
mount

umount /proc
umount /sys
umount /tmp

# OK, switch the root now!
echo "********** Initiating rootfs switch **********"
kill -QUIT 1

output is:
Code:

*** ls / ***
aufs    card    etc      lib      proc    root    sys
bin      dev      init    mnt      ramdisk  sbin    tmp
*** mounting card ***
EXT3-fs: barriers not enabled
kjournald starting.  Commit interval 5 seconds
EXT3-fs (mmcblk0p1): using internal journal
EXT3-fs (mmcblk0p1): recovery complete
EXT3-fs (mmcblk0p1): mounted filesystem with writeback data mode
*** ls /card ***
config  lost+found  root_union
*** mounting bind to root ***
mount: mounting / on /ramdisk failed: Invalid argument
*** ls ramdisk ***
*** mounting AUFS ***
aufs test_add:231:mount[1211]: unsupported filesystem, /ramdisk (rootfs)
mount: mounting none on /aufs failed: Invalid argument
*** ls aufs ***
card  root
*** Contents of mount ***
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sys on /sys type sysfs (rw,nosuid,noexec,relatime)
tmpfs on /tmp type tmpfs (rw,nosuid,noexec,relatime)
/dev/mmcblk0p1 on /card type ext3 (rw,relatime,errors=continue,user_xattr,barrier=0,data=writeback)

Am I missing something obvious? Or is this not possible?

For those interested in the hardware, it's an arm based system by freescale, loosely based on the im51evk board.

AllenKll 05-03-2013 09:39 AM

I did a little more digging.
I booted to a shell, created two direcotries /a and /b and tried:
Code:

mount --bind /a /b
This failed. So I tried it on my desktop(ubuntu 12) and it worked. what is the difference? Well, I am using busybox on the target, so I built a real version of mount and added it to the target. It still fails:

Code:

/ # mkdir a
/ # mkdir b
/ # mount -o bind a b
mount: wrong fs type, bad option, bad superblock on /a,
      missing codepage or helper program, or other error
      In some cases useful info is found in syslog - try
      dmesg | tail  or so

dmesg is empty of anything regarding this error. Scouring the web, I found people asking for "strace" logs. So I built strace copied to target and ran:

Code:

/ # strace mount -o bind a b
It gave this output:
Code:

execve("/sbin/mount", ["mount", "-o", "bind", "a", "b"], [/* 7 vars */]) = 0
brk(0)                                  = 0x1f000
uname({sys="Linux", node="(none)", ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aac7000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = -1 ENOENT (No such file or directory)
open("/lib/tls/v7l/fast-mult/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/v7l/fast-mult/half", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/tls/v7l/fast-mult/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/v7l/fast-mult", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/tls/v7l/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/v7l/half", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/tls/v7l/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/v7l", 0x7eb094e8)      = -1 ENOENT (No such file or directory)
open("/lib/tls/fast-mult/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/fast-mult/half", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/tls/fast-mult/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/fast-mult", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/tls/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/half", 0x7eb094e8)    = -1 ENOENT (No such file or directory)
open("/lib/tls/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls", 0x7eb094e8)          = -1 ENOENT (No such file or directory)
open("/lib/v7l/fast-mult/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/v7l/fast-mult/half", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/v7l/fast-mult/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/v7l/fast-mult", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/v7l/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/v7l/half", 0x7eb094e8)    = -1 ENOENT (No such file or directory)
open("/lib/v7l/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/v7l", 0x7eb094e8)          = -1 ENOENT (No such file or directory)
open("/lib/fast-mult/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/fast-mult/half", 0x7eb094e8) = -1 ENOENT (No such file or directory)
open("/lib/fast-mult/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/fast-mult", 0x7eb094e8)    = -1 ENOENT (No such file or directory)
open("/lib/half/libblkid.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/half", 0x7eb094e8)        = -1 ENOENT (No such file or directory)
open("/lib/libblkid.so.1", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\\!\0\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=156354, ...}) = 0
mmap2(NULL, 72324, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aad0000
mprotect(0x2aad9000, 28672, PROT_NONE)  = 0
mmap2(0x2aae0000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8) = 0x2aae0000
close(3)                                = 0
open("/lib/libuuid.so.1", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\314\20\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=61167, ...}) = 0
mmap2(NULL, 49412, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aae2000
mprotect(0x2aae5000, 32768, PROT_NONE)  = 0
mmap2(0x2aaed000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3) = 0x2aaed000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0LV\1\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1491213, ...}) = 0
mmap2(NULL, 1217748, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aaef000
mprotect(0x2ac0c000, 28672, PROT_NONE)  = 0
mmap2(0x2ac13000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11c) = 0x2ac13000
mmap2(0x2ac16000, 9428, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2ac16000
close(3)                                = 0
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0|\'\0\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=166941, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aac8000
mmap2(NULL, 74068, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2ac19000
mprotect(0x2ac23000, 28672, PROT_NONE)  = 0
mmap2(0x2ac2a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x9) = 0x2ac2a000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aac9000
syscall_983045(0x2aac8b10, 0x2aac9217, 0x2aac9218, 0x2aac8b10, 0x2aacf000, 0x2aacf048, 0x2aacf048, 0xf0005, 0x41, 0, 0x48, 0x7eb09b94, 0, 0x7eb09a88, 0x2aabc140, 0x2aaad010, 0x20000010, 0x2aac8b10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = 0
mprotect(0x2ac2a000, 4096, PROT_READ)  = 0
mprotect(0x2ac13000, 8192, PROT_READ)  = 0
mprotect(0x2aaed000, 4096, PROT_READ)  = 0
mprotect(0x2aae0000, 4096, PROT_READ)  = 0
mprotect(0x1c000, 4096, PROT_READ)      = 0
mprotect(0x2aace000, 4096, PROT_READ)  = 0
brk(0)                                  = 0x1f000
brk(0x40000)                            = 0x40000
umask(022)                              = 022
open("/dev/null", O_RDWR|O_LARGEFILE)  = 3
close(3)                                = 0
getuid32()                              = 0
geteuid32()                            = 0
lstat64("/etc/mtab", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
getcwd("/", 4095)                      = 2
readlink("/a", 0x7eb07b74, 4096)        = -1 EINVAL (Invalid argument)
stat64("/a", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
rt_sigprocmask(SIG_BLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0
stat64("/sbin/mount.none", 0x7eb09958)  = -1 ENOENT (No such file or directory)
mount("/a", "b", 0x12e94, MS_MGC_VAL|MS_BIND, 0) = -1 EINVAL (Invalid argument)
rt_sigprocmask(SIG_UNBLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0
write(2, "mount: wrong fs type, bad option"..., 113mount: wrong fs type, bad option, bad superblock on /a,
      missing codepage or helper program, or other error) = 113
write(2, "\n", 1
)                      = 1
stat64("/a", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
write(2, "      In some cases useful info"..., 85      In some cases useful info is found in syslog - try
      dmesg | tail  or so
) = 85
write(2, "\n", 1
)                      = 1
io_submit(0x20, 0x93370, 0x8 <unfinished ... exit status 32>
Process 1207 detached

after running strace on the desktop I see that there are a few differences in the way that libraries are linked, but nothing major is jumping out at me as being the issue.

Anyone have any thoughts?

thanks,
-Allen

fotoguy 05-03-2013 03:28 PM

Hopefully I can help a bit, while I haven't made an embedded system, I have made a few live cd /dvd from scratch using squashfs and unionfs. Do you have any devices in your /dev directory, linux will need a few of these to be able to boot properly such as /dev/console, /dev/ram, and your SD card will need it's own device, probably something like /dev/sda1, and there are a few more I just can't think of at the moment, not sitting in front of my pc at the moment.

Another thing you can do is to disect the ubuntu initrd.gz/initrd.img file. I think it's called /sbin/init and will be a shell script and not the normal excutable, If not it maybe a file named /linuxrc. This will give you a good idea of how the script should boot and detect everything, if you have trouble I can post mine so you can take a look at it.

AllenKll 05-03-2013 04:24 PM

fotoguy,
Yes my /dev directory is full of things. I made sure to create console, ram(s), tty(s), ttyS(s), etc. The sd card is mounted through the sd card driver which connects to device /dev/mmcblk0 with /dev/mmcblk0p1 being the partition on the device. This is definitely mounted, this is not the problem.
To be clear the initrd is not loaded from a disk. I have the u-boot encased gzipped ext2 file system on a tftp server and the bootloader pulls it down and loads it to address 0x90c00000 in memory, eventually this will be put on a nand flash and loaded from there, but for the development, getting it from the tftpserver is faster.
I guess the part I'm not really understanding is how the linux kernel access this initrd. One would think it must be via the command line, but there is nothing in the command line that would indicate to me that the data of address 0x90c00000 is being passed to the kernel. here is my kernel command line parameters:
Code:

console=ttymxc0,115200 init=/init fixrtc rootwait rw di0_primary ip=off
I'll try to take a look at ubuntu initrd.gz/initrd.img this weekend and see what is going on there. My guess, however, is that the ubuntu initrd is being read from the cd (/dev/scd) and accessed in that way, so a switch_root or mount --move command can directly access /dev/scd.

thanks,


All times are GMT -5. The time now is 01:49 AM.