[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#9823: request for more correct error reporting of mv
From: |
Voelker, Bernhard |
Subject: |
bug#9823: request for more correct error reporting of mv |
Date: |
Tue, 25 Oct 2011 08:39:07 +0200 |
Eric Blake wrote:
> On 10/24/2011 02:06 AM, address@hidden wrote:
> > Hello Eric,
> >
> > This is a sequence which reproduces my situation.
> >
> >> rm -rf ?
> >> mkdir -p a b/a
> >> touch b/a/file1 a/file2
> >> mv a b
> > mv: cannot move `a' to `b/a': Directory not empty
>
> Thanks for your formula. In fact, you don't even have to touch a/file2;
> simply touching b/a/file1 is enough to reproduce the setup (and even
> makes it more confusing, as then ./a is empty). The problem is that the
> recursion ends up trying to move the directory ./a (empty or otherwise)
> from the source, and rename(2) it onto the existing directory ./b/a/ on
> the destination; but rename(2) can only succeed if the destination
> directory is empty.
> >
> > Ok, in this example it's very clear.
> > However in my situation it was power play with an account of 120GiB.
> > When mv says "Directory not empty" you interpret the error message
> > as that of rmdir, and you go looking at dir a, which of course isn't
> > empty. It's not immediatly apparent that you have to go looking
> > after the dir b/a.
> >
> > This is the problem I want to address. Would it not be possible
> > to add to the error image the following message: "Dir b/a already
> > exists" or something similar making the real problem clear right
> > from the start?
>
> Like I said earlier, POSIX allows either ENOTEMPTY or EEXIST, and Linux
> happened to choose ENOTEMPTY. Maybe special-casing that error and
> converting to EEXIST would produce better output. But someone would
> have to submit a patch.
I think mv is right to say "Directory not empty". Let's look at
the opposite example, i.e. where the destination _is_ empty:
rm -rf a b
mkdir -p a b/a
strace -e trace=file ../src/mv a b
...
stat("b", {st_mode=S_IFDIR|0750, st_size=4096, ...}) = 0
lstat("a", {st_mode=S_IFDIR|0750, st_size=4096, ...}) = 0
lstat("b/a", {st_mode=S_IFDIR|0750, st_size=4096, ...}) = 0
access("b/a", W_OK) = 0
rename("a", "b/a") = 0
The kernel returns success.
Have a nice day,
Berny