<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 14, 2021 at 12:11 AM Rob Landley <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 4/13/21 6:47 PM, enh via Toybox wrote:<br>
> Apparently this is a thing people like to do, and they use shell while<br>
> loops to do it (because cpio only reads one input file at a time from<br>
> stdin).<br>
> <br>
> To make this work, we need to (a) exit with a failure status rather than<br>
> success if we hit EOF (we should never normally hit EOF because we<br>
> should read a TRAILER!!! first), and (b) skip to the end of the<br>
> TRAILER!!! record rather than just exiting immediately (so that the<br>
> _next_ cpio to run can start reading stdin at the start of a record,<br>
> rather than partway through the TRAILER!!! record that caused this cpio<br>
> to stop).<br>
<br>
Sigh, this came up in a discussion with the people trying to extend cpio format<br>
to add xattrs to initramfs a year or so back. Most recently probably circa:<br>
<br>
<a href="http://lkml.iu.edu/hypermail/linux/kernel/1905.2/01956.html" rel="noreferrer" target="_blank">http://lkml.iu.edu/hypermail/linux/kernel/1905.2/01956.html</a><br>
<br>
What the TRAILER!!! entry _actually_ means is "flush hardlink context". Search<br>
for "handling of hardlinks" in:<br>
<br>
<a href="https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt" rel="noreferrer" target="_blank">https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt</a><br>
<br>
(I have a todo entry for this, but haven't cycled back around to it...)<br>
<br>
> (The error message change in x8u is for the usual "it's harder to debug<br>
> if two different failure cases in the code output the exact same error<br>
> message", in this case "bad header".)<br>
<br>
Could you read the linux doc thing and confirm that the behavior you want is<br>
still to stop at TRAILER instead of flushing hardlink context but otherwise<br>
continuing to extract like the kernel guys documented for initramfs? (Or am I<br>
misremembering? It's been a while...)<br></blockquote><div><br></div><div>in the thread you linked to, they say "I wonder how existing GNU or BSD cpio ... would deal with reading such a file". all i'm saying is "GNU cpio exits on the next record boundary, and people have scripts that rely on this".</div><div><br></div><div>the Linux docs say things like</div><div><br></div><div>  The cpio "TRAILER!!!" entry (cpio end-of-archive) is optional, but is<br>  not ignored; see "handling of hard links" below.<br></div><div><br></div><div>but that doesn't match what actual implementations of cpio do. (assuming you don't interpret optional as meaning "you don't have to have one, but if you don't, the tool will exit with an error complaining that you don't have one" :-) )</div><div><br></div><div>i think the most interesting thing for me in the docs was:</div><div><br></div><div>  When a "TRAILER!!!" end-of-archive marker is seen, the tuple buffer is<br>  reset.  This permits archives which are generated independently to be<br>  concatenated.<br></div><div> </div><div>because -- even if i haven't really understood _why_ people are concatenating cpio files -- at least this shows that the main consumers/producers agree that this is an expected use case.</div><div><br></div><div>i'm assuming the "exit when you see TRAILER!!! and let the next cpio instance worry about the rest" behavior is just the least-effort implementation of the hard-link flush stuff:</div><div><br></div><div>  To combine file data from different sources (without having to<br>  regenerate the (c_maj,c_min,c_ino) fields), therefore, either one of<br>  the following techniques can be used:<br><br>  a) Separate the different file data sources with a "TRAILER!!!"<br>     end-of-archive marker, or<br></div><div><br></div><div>exiting when you see TRAILER!!! implicitly loses any cpio state, and reporting an error if you hit EOF without seeing TRAILER!!! lets you know when to stop running a new cpio?</div><div><br></div><div>(i think the doc is trying to distinguish between a cpio file [where TRAILER!!! marks the end] and an "initramfs buffer" which can contain multiple concatenated cpio files [and hence more than one TRAILER!!!]. so things processing initramfs buffers need to be cleverer than cpio when it comes to TRAILER!!!, but cpio doesn't. [and in practice, isn't.])</div><div><br></div><div>i think that answers your question, but perhaps in excessive detail, so i'll re-quote you and try again:</div><div><br></div><div>> confirm that the behavior you want is</div>> still to stop at TRAILER instead of flushing hardlink context but otherwise<br>> continuing to extract</div><div class="gmail_quote"><br></div><div class="gmail_quote">i agree that based on the Linux docs it would be more sensible to flush but continue, but that's demonstrably not what GNU cpio does, so it doesn't seem particularly helpful for us to do it. callers already have to have the bash while loop nonsense, and implementing the better behavior in toybox would still be "broken" from that perspective because they'd loop forever --- toybox would at least have to consider the empty input as an error, at which point we haven't really reduced the ugliness much? (i'm also scared to suggest anything beyond "do what GNU does" because i don't personally know anything about cpio, and have never used it except to generate minimal repro cases for stuff that kernel folks bring up. i haven't looked at BSD, but they seem to interpret TRAILER!!! as end of archive too: <a href="https://www.freebsd.org/cgi/man.cgi?query=cpio&sektion=5">https://www.freebsd.org/cgi/man.cgi?query=cpio&sektion=5</a> ... and eighthly, carrying on past TRAILER!!! when no-one else does sounds like one of those security issues Android had back in the "zip master key" days; even if the format is stupid, it's safer when everyone interprets the format the same way... who knows what crap people are accidentally/deliberately ignoring past a TRAILER!!! that isn't actually at the end [because they _don't_ have the bash while loop]? i'd prefer not to find out :-) )</div><div class="gmail_quote"><br></div><div class="gmail_quote">hmm. my second attempt seems to have more words than my first. i'll stop here.</div><div class="gmail_quote"><br></div><div class="gmail_quote">(i noticed as well that everyone seems to actually deal in _compressed_ cpio files, so in an ideal world i suspect cpio should be as intelligent as tar when it comes to such things --- but i think cpio'ing is too niche to warrant doing anything better than GNU.)<br><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Rob<br>
</blockquote></div></div>