Re: mkdir -p doesn't work in busybox (#6)

13 views
Skip to first unread message

barret rhoden

unread,
Aug 26, 2015, 11:03:41 PM8/26/15
to reply+0003ac220407e925770e383e4701075379e7598...@reply.github.com, aka...@googlegroups.com
On 2015-08-26 at 16:40 Kevin Klues wrote:
> When trying to do a mkdir -p on a directory, we always get an error
> as:
>
> $ mkdir -p /tmp/a/b
> mkdir: can't create directory '/': Operation not permitted
>
> With the '-p' parameter, busybox will attempt a mkdir for every part
> of the path separately. So under the hood, it is trying a 'mkdir /',
> followed by a 'mkdir tmp', etc. It is on the 'mkdir /' that it is
> failing (which incidentally fails in the same way when typed in
> manually). Removing the leading '/' resolves the issue, but points to
> a potential kernel bug.
>
> The relevant code is in kern/src/vfs.c where we do a path_lookup for
> the current path's parent before we do a lookup on the path itself to
> see if the file already exists. If it does exist, we error out with
> an EEXIST, which busybox knows how to handle properly. Since '/'
> doesn't have a parent though, it errors out early with an error code
> of ENOENT instead of EEXIST.
>
> https://github.com/brho/akaros/blob/master/kern/src/vfs.c#L1653
>
> I was thinking it may be enough to just swap the order of these
> operations, but I figured @brho might have some input before I put a
> CL together.

That's definitely a problem. We also might have issues with rmdir of /
too, and maybe other stuff. Other things include anything that would
want to change a link when that link is a directory (I grab the parent
since that is where the link info is stored), and maybe also if the
process has a different / directory (say a chroot, which no one can set
up on Akaros but the nd stuff is built to handle).

As far as fixing it goes, just swapping those probably won't work,
since do_lookup() expects to start from an nd that was filled in by a
path_lookup(). o/w, nd->dentry is 0, etc.

I think we'd need a path_lookup(), maybe with nd->intent = LOOKUP_OPEN,
just to check for existence. If so, then we abort with EEXIST. Then
we do the existing parent path_lookup, etc. We can also remove the
later do_lookup / EEXIST check. Btw, the whole VFS stack is racy as
hell.

For rmdir, we ought to do some sort of "root directory detection",
probably before the parent's path_lookup (for similar reasons), and
return EBUSY. I have a TODO in there for that (L 1712). Though I'm
less concerned about rmdir. You'll fail, just for the wrong reason.
And if you don't fail, then oh well. Shouldn't have removed /. =)

I slapped a patch together that seems to do the trick:

/ $ mkdir -p /foobar
/ $ ls -a /foobar
. ..
/ $ mkdir /
mkdir: can't create directory '/': File exists

It's on origin/mkdir:
763c4ba24078 ("Fix do_mkdir on root directories")

Barret


Kevin Klues

unread,
Oct 18, 2015, 4:44:36 PM10/18/15
to Akaros, reply+0003ac220407e925770e383e4701075379e7598...@reply.github.com

brho

unread,
Oct 18, 2015, 4:44:42 PM10/18/15
to brho/akaros
Reply all
Reply to author
Forward
0 new messages