Hi, first, thanks to Daniel for the patch! I have exactly the same problem with our automatic Apport crash bug retracers (which operate in a data center where I don't have (and want) root). rm failures drove me up the wall...
On amd64, rm seems to call __fxstat() instead of __fxstatat64(), so I
did a copy&paste of Daniel's __fxstatat64() wrapping (with struct
stat64 -> stat, of course), and now it works great again!
To demonstrate this easily, I modified the test script a bit:
--- fakechroot-2.6.orig/test/fakechroot.sh
+++ fakechroot-2.6/test/fakechroot.sh
@@ -32,6 +32,7 @@
/bin/ls \
/bin/pwd \
/bin/sh \
+ /bin/rm \
/usr/bin/id \
/usr/bin/find \
/usr/bin/perl \
@@ -63,5 +64,5 @@
if [ -n "$*" ]; then
HOME=/root /usr/sbin/chroot `pwd`/testtree "$@"
else
- HOME=/root /usr/sbin/chroot `pwd`/testtree /bin/sh
+ HOME=/root /usr/sbin/chroot `pwd`/testtree /bin/bash
Then this can be reproduced with
strace -f ./fakechroot.sh sh -c 'echo hi > bin/foo; ls /bin/foo; rm /bin/foo'
[...]
[pid 29432] newfstatat(AT_FDCWD, "/bin/foo", 0x7fff9b659860,
AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
With the patch applied, you get the correct
[pid 3699] newfstatat(AT_FDCWD,
"/home/martin/ubuntu/fakechroot/fakechroot-2.6/test/testtree/bin/foo",
{st_mode=S_IFREG|0644, st_size=3, ...}, AT_SYMLINK_NOFOLLOW) = 0
[...]
[pid 3699] unlinkat(AT_FDCWD,
"/home/martin/ubuntu/fakechroot/fakechroot-2.6/test/testtree/bin/foo", 0) = 0
instead.
FYI, I attach the complete debdiff which I uploaded to Ubuntu.
Thanks,
Martin
--
Martin Pitt | http://www.piware.de
Ubuntu Developer (www.ubuntu.com) | Debian Developer (www.debian.org)
diff -u fakechroot-2.6/debian/changelog fakechroot-2.6/debian/changelog
--- fakechroot-2.6/debian/changelog
+++ fakechroot-2.6/debian/changelog
@@ -1,3 +1,14 @@
+fakechroot (2.6-1.3ubuntu1) intrepid; urgency=low
+
+ * src/libfakechroot.c: Provide wrapping of unlinkat(), __fxstatat(), and
+ __fxstatat64() to unbreak rm'ing absolute directories. This extends the
+ original patch from Daniel Kahn Gillmor in Debian #473682. Still
+ incomplete, since other *at() functions are still missing, but those are
+ the most pressing which cause the Apport retracers to fail so badly.
+ * test/fakechroot.sh: Add /bin/rm, and call bash instead of sh.
+
+ -- Martin Pitt <[EMAIL PROTECTED]> Thu, 08 May 2008 20:45:48 +0200
+
fakechroot (2.6-1.3) unstable; urgency=low
* Non-maintainer upload to fix the fix for the fix for #422586
diff -u fakechroot-2.6/src/libfakechroot.c fakechroot-2.6/src/libfakechroot.c
--- fakechroot-2.6/src/libfakechroot.c
+++ fakechroot-2.6/src/libfakechroot.c
@@ -463,6 +463,9 @@
static int (*next_truncate64) (const char *path, off64_t length) = NULL;
#endif
static int (*next_unlink) (const char *pathname) = NULL;
+static int (*next_unlinkat) (int dirfd, const char *pathname, int flags) =
NULL;
+static int (*next___fxstatat) (int ver, int dirfd, const char *pathname,
struct stat *buf, int flags) = NULL;
+static int (*next___fxstatat64) (int ver, int dirfd, const char *pathname,
struct stat64 *buf, int flags) = NULL;
#ifdef HAVE_ULCKPWDF
/* static int (*next_ulckpwdf) (void) = NULL; */
#endif
@@ -678,6 +681,9 @@
nextsym(truncate64, "truncate64");
#endif
nextsym(unlink, "unlink");
+ nextsym(unlinkat, "unlinkat");
+ nextsym(__fxstatat, "__fxstatat");
+ nextsym(__fxstatat64, "__fxstatat64");
#ifdef HAVE_ULCKPWDF
/* nextsym(ulckpwdf, "ulckpwdf"); */
#endif
@@ -2222,6 +2228,31 @@
return next_unlink(pathname);
}
+/* #include <fcntl.h> */
+int unlinkat (int dirfd, const char *pathname, int flags)
+{
+ char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH];
+ expand_chroot_path(pathname, fakechroot_path, fakechroot_ptr,
fakechroot_buf);
+ if (next_unlinkat == NULL) fakechroot_init();
+ return next_unlinkat(dirfd, pathname, flags);
+}
+
+/* #include <fcntl.h> */
+/* #include <sys/stat.h> */
+int __fxstatat (int ver, int dirfd, const char *pathname, struct stat *buf,
int flags)
+{
+ char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH];
+ expand_chroot_path(pathname, fakechroot_path, fakechroot_ptr,
fakechroot_buf);
+ if (next___fxstatat == NULL) fakechroot_init();
+ return next___fxstatat(ver, dirfd, pathname, buf, flags);
+}
+int __fxstatat64 (int ver, int dirfd, const char *pathname, struct stat64
*buf, int flags)
+{
+ char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH];
+ expand_chroot_path(pathname, fakechroot_path, fakechroot_ptr,
fakechroot_buf);
+ if (next___fxstatat64 == NULL) fakechroot_init();
+ return next___fxstatat64(ver, dirfd, pathname, buf, flags);
+}
/* #include <sys/types.h> */
/* #include <utime.h> */
only in patch2:
unchanged:
--- fakechroot-2.6.orig/test/fakechroot.sh
+++ fakechroot-2.6/test/fakechroot.sh
@@ -32,6 +32,7 @@
/bin/ls \
/bin/pwd \
/bin/sh \
+ /bin/rm \
/usr/bin/id \
/usr/bin/find \
/usr/bin/perl \
@@ -63,5 +64,5 @@
if [ -n "$*" ]; then
HOME=/root /usr/sbin/chroot `pwd`/testtree "$@"
else
- HOME=/root /usr/sbin/chroot `pwd`/testtree /bin/sh
+ HOME=/root /usr/sbin/chroot `pwd`/testtree /bin/bash
fi
signature.asc
Description: Digital signature

