[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#573940: coreutils: rm -r doesn't work on kfreebsd-i386



Hi all,

to provide better picture I slightly played with order of lines from original message.

I'd like to draw your attention to this coreutils bug, which happens to trigger on kFreeBSD 7:

| $ mkdir -p a/b/{c,d}
| $ rm -Rf a/
| rm: cannot remove `a/b': Operation not permitted

Also, it might be interesting that:
- Despite fstatat() being not detected at configure time, rm uses the __fxstatat symbol.

This seems to be the key point.

The FreeBSD 7.x kernel does not have the *at syscalls, only limited emulation is available in our glibc in this case.
Under 8.x kernel *at syscalls are native and are used directly,
we have runtime detection in our glibc.
As we still want to support both kernel versions (7.x and 8.x) for now, all *at syscalls are marked as stubs in glibc (see i.e. <gnu/stubs-32.h>). Therefore the coreutils (and any gnulib user) should not use them at all.

Unfortunately the *stat{,at} functions are in glibc implemented via *xstat{,at} and the *stat{,at} functions are inline's which calls *xstat{,at},
see * <sys/stat.h> on any glibc system :-(

The "rm" ended up using the glibc one's even iff they are marked as stubs :-(.

The "rm" part of coreutils have been rewritten in 8.x series
and the gnulib replacement are not used.

Also, it might be interesting that:
- The problem goes away if coreutils is compiled with -O0.

The inline-ing does not happen in this case and the used fstatat() comes from gnulib, i.e. no native ENOSYS call ...

My not entirely fruitful debugging showed that something icky happens in line 75 of src/remove.c:

if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0)

The relevant part of ktrace output, which does make no sense at all to me, is:

For the code under it see
http://svn.debian.org/wsvn/glibc-bsd/trunk/glibc-ports/kfreebsd/fxstatat.c

|  2676 rm       CALL  __sysctl(0xbfbfe628,0x4,0,0xbfbfe638,0,0)
|  2676 rm       RET   __sysctl 0
|  2676 rm       CALL  __sysctl(0xbfbfe628,0x4,0xbfbfdce0,0xbfbfe638,0,0)
|  2676 rm       RET   __sysctl 0
|  2676 rm       CALL  lstat(0xbfbfe5a8,0xbfbfdc50)
|  2676 rm       NAMI  "-/b"
|  2676 rm       RET   lstat -1 errno 2 No such file or directory

(Note, that it's "-/b", not "a/b".)

I am unsure what can be done about it.

Ideally, we could just switch to kfreebsd-8 only, but just now we have problem with build
of some big packages (namely gcc-4.3) under kfreebsd-8. So far it looks like race condition in scheduler/memory manager/pagedaemon/...,
so It is rather hard to give an estimate of time to solve the kfreebsd-8 problem.
Well, dot zero is dot zero :-(

Sorry

Petr


Reply to: