[Toybox] Test pondering.

Rob Landley rob at landley.net
Tue Jul 25 14:06:10 PDT 2017


Taking half a day to catch up on some toybox stuff (and looking at the
cp --parents thing), led to commit 105595524ead which has me wondering
if I should have a variable that overrides SKIP_HOST.

Backstory: my rm -rf can chmod things to delete them (it only does it
with -f), but the host's won't do that. The failure mode isn't
necessarily "this is read only" (normal rm -f can do that on files) but
"can't read contents of this directory without +x". (Ok, it won't delete
files out of a read-only directory but will delete files out of
writeable subdirectories under them.)

That commit tests this behavior, which the host doesn't do. So I added
SKIP_HOST, making this one of the tests I skip because I know ubuntu
will fail them (sometimes for dumb reasons, the "echo hello | sed '' -
-" segfault was clearly an ubuntu bug, they seem to have fixed it since
and I can yank that).

But sometimes you're testing on a host that has toybox, or sometimes you
_want_ to see the failures. Should I make TEST_HOST run the test anyway
and print SKIP only if the test _fails_? Should I add a TEST_HOST=fail
to run those tests when doing test host (analogous to VERBOSE=fail to
stop at first error, only just ignoring SKIP_HOST so you'd have to
VERBOSE=FAIL on top of that if you wanted both behaviors; and no I'm not
looking forward to trying to fit that extra explanation into "make help"
section for make tests...) I pondered autodetecting with "which toybox"
but that's just not a good idea...

Speaking of rm, one todo item for rm is "should this chmod behavior be
-F instead of -f". Another is "document my --no-preserve-root decision"
(I didn't implement that flag, instead if you try to rm -r /" it gives
an error message telling you /. would work, a name which is not gonna
wildcard itself into existence due to a typo... but I dunno how to
explain that in the help text. Maybe I need "deviations from ubuntu"
under deviations from posix. :). Another is I think -one-file-system
should be the _default_ and require a flag to override it. (Possibly
that same -F :) Oh, and the big one is doing the infinite recursion
test, something like:

X = 0;
mkdir a
while [ $X -lt 1000 ]
do
  X=$(($X+1))
  mkdir b/a/a/a &&  mv a b/a/a/a && mv b a || exit 1
done

Which is mostly still on my todo list because:

A) I'm not sure I actually implemented all the plumbing to do that
right. (Notice how that not only blows out $PATH_MAX but also exhausts
available filehandles for the naieve dirtree implementation that keeps
one open per level. Yes, posix requires handling this, and no you can't
test at creation time, notice I mv long path into short path so if long
path's fallen out of dentry cache and only on backing store how do you
know how many directories are under it? You can't "remember it" if there
was a reboot in between, you'd need either a full disk scan at boot time
or space for it in the on-disk format, and then what do you do if you
inherit a filesystem on removable media with different assumptions?)

B) how does your test code clean up after that if rm does fail to delete
it? (Query: does bash let you cd beneath $PATH_MAX? It's gonna try to
set $PWD and quite possibly get unhappy. Haven't tried it. That's
something toysh should handle gracefully, but that's 6 months of focus
when I haven't had _one_ in the past year...)

C) If such directories are going to exist, "find" should also handle
them, which means dirtree needs to automatically do this in a generic
manner. I did some work towards this a year ago in 8d95074b7d03 and then
$DAYJOB went feral and I've been kinda distracted. The design is you can
discard any non-symlink directory filehandle because you can
openat("..") and then compare the dev/inode info in your stored stat and
barf if they don't match because somebody clever did a "mv" while you
were traversing, and the recovery is to drill back down from the top and
see how far back here you can get and resume from there, except you can
ONLY do that with breadth-first traversal, because depth-first can't
restart. Well, it can if you check your existing parent->child entry
chain and skip entries you've seen but that's slow/expensive especially
since they're not guaranteed a consistent sort order so it goes O(N^2)
on directory length but I need a hash table solution for hardlink
detection in zip/cpio/tar _anyway_ except I can half-ass my way around
that because most things AREN'T multiply linked so I can check the link
count and not save entries with 1 link and speaking of cpio I still half
a half-finished initramfs xattr support patch also addressing y2038 and
-ERATHOLE stopping now...)

You see why this is still on my todo list? Not the kind of thing you
work thorugh in 15 minute increments. Maybe work will stabilize enough
to give me vacation time someday, and then I could tackle this...

Rob

P.S. Ordinarily this kind of pondering goes in The Blog Nobody Reads but
I need to spend some focus to catch _that_ up, as I lamented/begged
forgiveness in https://www.patreon.com/posts/tagged-mkroot-12624892 ...


More information about the Toybox mailing list