[Toybox] [PATCH] cpio: support reading concatenated cpio files.
Yi-yo Chiang
yochiang at google.com
Sat Apr 17 02:43:56 PDT 2021
On Sat, Apr 17, 2021 at 2:56 PM Rob Landley <rob at landley.net> wrote:
> On 4/16/21 1:44 PM, Yi-yo Chiang wrote:
> > I'm not sure what Elliot's goal is? I assume he's trying to extract a
> > concatenated ramdisk, and I still see a problem in the current solution.
> >
> > The buffer-format
> > (
> https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt)
> says:
> >
> > initramfs := ("\0" | cpio_archive | cpio_gzip_archive)*
> >
> > In other words, both `cat a.cpio b.cpio >merged.cpio` and `(cat a.cpio
> && echo
> > -n -e '\0\0\0' && cat b.cpio) >merged.cpio` are valid initramfs.
>
> It also implies that two compressed files can be concatenated and
> separated by
> arbirary runs of nulls, or you can have a compressed file and a
> non-compressed
> file concatenated, or...
>
Correct. Upon further inspection, it's actually "arbitrary NULLs could
prepend a GZIP(cpio_archive)", "arbitrary 4-aligned NULLS prepend a
*uncompressed* cpio_archive" and "cpio_file/cpio_trailer within a
cpio_archive have to be 4-aligned with arbitrary NULLs". initramfs.c seems
to try very hard to respect the alignment requirement, but I guess we could
just skip *ANY* extra NULLs for simplicity?
>
> Grrr. I need to test this. And possibly genericize the tar.c code to detect
> compression type and run it through a decompressor so cpio can do it too...
>
Sounds like another can of worms... :/
The buffer-format.txt seems to be a bit outdated, as Linux now supports a
lot of compression types besides gzip, and all of which are configurable (
https://elixir.bootlin.com/linux/latest/source/lib/decompress.c#L52). So
the initramfs grammar implemented by initramfs.c is in reality:
initramfs := ("\0" | cpio_archive | compressed_cpio_archive)*
compressed_cpio_archive := CONFIG_COMPRESSION_ALGORITHM(cpio_archive)
CONFIG_COMPRESSION_ALGORITHM := GZIP | BZIP2 | LZMA | XZ | LZO | LZ4 |
ZSTD
where the exact set of compression algorithms are decided by the kernel
config.
>
> > btw gen_init_cpio.c also pads initramfs to 512-byte boundary
> > (
> https://github.com/torvalds/linux/blob/6fbd6cf85a3be127454a1ad58525a3adcf8612ab/usr/gen_init_cpio.c#L97
> )
>
> *blink* *blink* Why...? (cpio doesn't have a 512 stride in the file
> format? It
> has a 4-byte stride for padding strings with NUL bytes, but that's about
> it?)
>
> > If we're viewing buffer-format.txt as the "right" cpio spec, then I
> think we
> > should implement this too. We should skip arbitrary extra NUL-bytes
> padded
> > between cpio file frames
>
> Skipping arbitrary extra null bytes at the start is easy enough to do. I
> guess
> the hardwired trailing read was expecting the 512 padding...
>
> I'm gonna need add a _lot_ more test suite entries for this command.
>
> Ok, skip arbitrary leading NUL bytes after each entry, pad last record to
> 512
> byte alignment with NUL bytes, autodetect compression type at each record
> start,
> implement hardlinks and have TRAILER!!! flush hardlink context...
>
>
I'm not so sure about padding the last entry to 512-byte boundary. 512
looks like a random value to me? (Or an implementation detail of GNU cpio
and gen_init_cpio). Nonetheless I think we should pad the last record to
4-byte boundary, so that both
cat a.cpio.gz b.cpio.gz >c.cpio.gz
and
zcat a.cpio.gz b.cpio.gz >c.cpio
are valid initramfs/cpio?
Rob
>
--
Yi-yo Chiang
Software Engineer
yochiang at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20210417/5fa6cfda/attachment.html>
More information about the Toybox
mailing list