Re: [PATCH v4 0/3] initramfs: add support for xattrs in the initial ram disk

From: Rob Landley
Date: Tue Jul 19 2022 - 07:27:00 EST




On 7/18/22 13:08, Jim Baxter wrote:
>
>
> Best regards,
>
> *Jim Baxter*
>
> Siemens Digital Industries Software
> Automotive Business Unit
> DI SW STS ABU
> UK
> Tel.: +44 (161) 926-1656
> mailto:jim.baxter@xxxxxxxxxxx <mailto:jim.baxter@xxxxxxxxxxx>
> sw.siemens.com <https://sw.siemens.com/>
>
> On 18/07/2022 17:49, Roberto Sassu wrote:
>>> From: Jim Baxter [mailto:jim_baxter@xxxxxxxxxx]
>>> Sent: Monday, July 18, 2022 6:36 PM
>>>
>>>
>>> Hello,
>>>
>>> I have been testing these patches and do not see the xattr information when
>>> trying to retrieve it within the initramfs, do you have an example of how
>>> you tested this originally?
>>
>> Hi Jim, all
>>
>> apologies, I didn't find yet the time to look at this.
>
> Hello Roberto,
>
> Thank you for your response, I can wait until you have looked at the patches,
> I asked the question to make sure it was not something wrong in my
> configuration.
>
>>
>> Uhm, I guess this could be solved with:
>>
>> https://github.com/openeuler-mirror/kernel/commit/18a502f7e3b1de7b9ba0c70896ce08ee13d052da
>>
>> and adding initramtmpfs to the kernel command line. You are
>> probably using ramfs, which does not have xattr support.
>>
>
>
> Thank you, I have tested that patch but the problem remained. Here is my
> command line, I wonder if there is something wrong.
>
> Kernel command line: rw rootfstype=initramtmpfs root=/dev/ram0 initrd=0x500000000 rootwait

/dev/ram0 is a block device. Trying to provide it to tmpfs is like trying to say:

mount -t proc /dev/sda1 /proc

There's nowhere for the block device to GO because it's not a block backed
filesystem.

There's four types of filesystem: block back, pipe backed, ram backed, and
synthetic.

- Only block backed filesystems take a block device argument. Block backed
filesystems require two drivers: one to handle I/O to the block device and one
to interpret the filesystem format with the block device. You do not "format"
any other kind of filesystem. (There's no mkfs.nfs or mkfs.proc: it doesn't work
that way.)

- Pipe backed ones include network filesystems (nfs, samba), FUSE filesystems,
or hybrid weirdness like https://wiki.qemu.org/Documentation/9psetup . These
drivers talk a protocol over a pipe (or network socket, or char device, or...)
to a server at the far end that serves up the filesystem contents. Usually their
source argument is a server address plus filesystem identification plus login
credentials. Often they have a wrapper program that assembles this argument for you.

- Ram backed filesystems (ramfs, tmpfs) treat the "source" argument to mount(2)
as basically a comment, and ignore it. When you're adding things like size
limitations, it goes in the "data" argument (I.E. mount -o thingy).

- synthetic filesystems are just interfaces to the kernel that make up their
contents programmatically (proc, sys, cgroup...) and no two are alike, although
they generally ignore their "source" argument and look at "data" too.

I wrote up documention about this many years ago...

https://landley.net/toybox/doc/mount.html

> I also found that root is always mounted as rootfs in my initramfs system
> which I understood to be tmpfs, is that incorrect?

Yes, although the kernel tries to hide this by lying in /proc/mounts for bad
reasons.
> I modified the file before packing. To pack I use the following commands:
>
> $ ./usr/gen_initramfs.sh -l initramfs.list -e xattr ../rootfs > initramfs.cpio
> $ gzip initramfs.cpio
> $ mkimage -A arm64 -O linux -T ramdisk -d initramfs.cpio.gz uRamdisk
>
> The kernel is loaded using:
> booti ${kernaddr} ${initramaddr} ${dtbaddr}

Remove the root= argument from your kernel command line. It is explicitly
telling the kernel "we will not be staying in rootfs" and thus it doesn't use
tmpfs for it. In your case, you're saying "we're going to overmount the initial
ramfs with a ram disk block device", which is nonsensical because nothing can
have populated it so it will be all zeroes (unformatted) and thus the filesystem
type detection staircase in
https://github.com/torvalds/linux/blob/v5.18/init/do_mounts_rd.c#L38 won't be
able to find a filesystem type to mount on it and it's guaranteed to fail.

Note: initramfs was introduced in the early 2000s, and back in the 1990s there
was an older "initrd" mechanism that DID use ramdisks (which are a chunk of ram
used as a block device). I wrote documention about THAT too:

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

Basically the mechanism you're feeding init.cpio.gz in through was originally
written to populate a ramdisk, and you'd make an ext2 image or something and
gzip that. These days, the kernel decompresses the first few bytes of the file
and if the result is a cpio signature it calls the initramfs plumbing
(extracting the archive into the ram backed filesystem) and if not it extracts
it into the /dev/ram0 block device and treats it as an initial ram disk. In
NEITHER case do you need root= because that's used AFTER initramfs and initrd
have both failed to find an /init program. (Well initrd looks for /linuxrc
instead of /init because historical cruft, and then there was pivot_root...
Don't go there.)

Rob