bug-coreutils
[Top][All Lists]
Advanced

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

Re: Correct semantics in rm -rf ?


From: shailesh jain
Subject: Re: Correct semantics in rm -rf ?
Date: Wed, 26 Aug 2009 13:23:31 -0700

I have attached a log file. Note I have ran this on local file system where
rm -rf works not on Network file system (I was running into some issues
which I am trying to resolve ..).  However, this run also gives us lot of
information and demonstrates that even though rm -rf works, it is does not
seem to be POSIX compliant.

Thus any filesystem that reflects updates only on open() will break. If you
also want me to run on a filesystem that breaks rm -rf, I will go through
the pain of setting it up ?

Let me know if you need any other information. (Btw. The file system that I
was talking about is Hgfs (Host/ Guest file system) located at
http://open-vm-tools.sourceforge.net/)


lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
newfstatat(AT_FDCWD, "parent", {st_mode=03, st_size=343597383680, ...},
AT_SYMLINK_NOFOLLOW) = 0
unlinkat(AT_FDCWD, "parent", 0)         = -1 EISDIR (Is a directory)
openat(AT_FDCWD, "parent", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
fcntl(3, F_GETFL)                       = 0x28800 (flags
O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
getdents(3, /* 3 entries */, 8192)      = 80
openat(3, "Child", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW) = 4
fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
fcntl(4, F_GETFL)                       = 0x28800 (flags
O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
close(3)                                = 0
fcntl(4, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
getdents(4, /* 2 entries */, 8192)      = 48
getdents(4, /* 0 entries */, 8192)      = 0
fcntl(4, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)


/* Open 'parent' directory */
openat(4, "..", O_RDONLY)               = 3

/* Close 'Child' directory */
close(4)                                = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0

/* Remove 'Child' directory*/
unlinkat(3, "Child", AT_REMOVEDIR)      = 0

fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0
fcntl(3, F_GETFL)                       = 0x8000 (flags
O_RDONLY|O_LARGEFILE)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0

/* Now get directory entries of 'parent'. There are no guarantees that
updates should have been reflected here, but rm -rf assumes this! Updates
are guaranteed to be reflects only on next openat() */

getdents(3, /* 2 entries */, 8192)      = 48
getdents(3, /* 0 entries */, 8192)      = 0
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(3)                                = 0
unlinkat(AT_FDCWD, "parent", AT_REMOVEDIR) = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?

On Wed, Aug 26, 2009 at 11:09 AM, Jim Meyering <address@hidden> wrote:

> shailesh jain wrote:
> > On Wed, Aug 26, 2009 at 2:36 AM, Jim Meyering <address@hidden> wrote:
> ...
> >> If you can demonstrate an actual failure, or even that rm is
> >> merely performing unnecessary unlinkat calls, please provide details.
> >
> > Thanks for consideration. I will describe how 'rm -rf parent' fails:
> > ---
> > mkdir parent
> > cd parent
> > mkdir Child
> > cd ..
> > cd ..
> ...
> >
> > Now, unlinkat() will delete child directory on unlinkat() and then do
> dirp =
> > fdopendir(parent_fd). Then it will perform readdir() calls on parent just
> to
> > find out that  'Child' directory is still present and it will mark
> 'Child'
> > directory is unremovable... (and I think it subsequently tries to remove
> > 'Child' and doesn't find 'Child' and terminates with ENOENT when I use rm
> > -riv)
> >
> > I read from the posix semantics that fdopendir() should behave same as
> > opendir(), however given that the VFS layer and the underlying filesystem
> > cannot distinguish between open() and opendir(), I do not see any
> reasonable
> > way to do that. Thus relying on readdir() to reflect updates made by
> > unlinkat() is broken (although local file systems tend to reflect this
> very
> > well).
>
> I understood your theoretical description the first time.
> Please provide details showing precisely how GNU rm is misbehaving.
> Either step through with a debugger or show the system calls e.g., from
> strace:
>
> Please describe your file system (client and server system types, if
> they're different) and give the output of your "strace -o log rm -riv
> parent"
> command as well as the "log" file that creates.
>
> If rm fails in a way that is contrary to POSIX, we'd
> all like to know.
>
> Also, please be sure to use rm from coreutils-7.5.
>

Attachment: log
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]