We''ve just stumbled across an interesting problem in one of our applications that fails when run on a ZFS filesystem. I don''t have the code, so I can''t fix it at source, but it''s relying on the fact that if you do readdir() on a directory, the files come back in the order they were added to the directory. This appears to be true (within certain limitations) on UFS, but certainly isn''t true on ZFS. Is there any way to force readdir() to return files in a specific order? (On UFS, we have a scipt that creates symlinks in the correct order. Ugly, but seems to have worked for many years.) If not, I was looking at interposing my own readdir() (that''s assuming the application is using readdir()) that actually returns the entries in the desired order. However, I''m having a bit of trouble hacking this together (the current source doesn''t compile in isolation on my S10 machine). -- -Peter Tribble http://www.petertribble.co.uk/ - http://ptribble.blogspot.com/
Casper.Dik at Sun.COM
2009-Jul-02 13:15 UTC
[zfs-discuss] Interposing on readdir and friends
>We''ve just stumbled across an interesting problem in one of our >applications that fails when run on a ZFS filesystem. > >I don''t have the code, so I can''t fix it at source, but it''s relying >on the fact that if you do readdir() on a directory, the files come >back in the order they were added to the directory. This appears >to be true (within certain limitations) on UFS, but certainly isn''t >true on ZFS. > >Is there any way to force readdir() to return files in a specific order? >(On UFS, we have a scipt that creates symlinks in the correct order. >Ugly, but seems to have worked for many years.)No. In UFs a readdir is a "file" and all new files are added at the end unless there''s room before the end. ZFS uses Btrees and returns them in btree order.>If not, I was looking at interposing my own readdir() (that''s assuming >the application is using readdir()) that actually returns the entries in >the desired order. However, I''m having a bit of trouble hacking this >together (the current source doesn''t compile in isolation on my S10 >machine).I think this is going to be rather difficult; I think you want to interposing opendir() also and read all the files first before you start returning them. Casper
On Thu, Jul 2, 2009 at 8:07 AM, Peter Tribble<peter.tribble at gmail.com> wrote:> We''ve just stumbled across an interesting problem in one of our > applications that fails when run on a ZFS filesystem. > > I don''t have the code, so I can''t fix it at source, but it''s relying > on the fact that if you do readdir() on a directory, the files come > back in the order they were added to the directory. This appears > to be true (within certain limitations) on UFS, but certainly isn''t > true on ZFS. > > Is there any way to force readdir() to return files in a specific order? > (On UFS, we have a scipt that creates symlinks in the correct order. > Ugly, but seems to have worked for many years.) > > If not, I was looking at interposing my own readdir() (that''s assuming > the application is using readdir()) that actually returns the entries in > the desired order. However, I''m having a bit of trouble hacking this > together (the current source doesn''t compile in isolation on my S10 > machine).Is one of these your starting point? What errors are you seeing? http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/readdir.c http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/libc/gen/common/readdir.c The libbc version hasn''t changed since the code became public. You can get to an older libc variant of it by clicking on the history link or using the appropriate hg command to get a specific changeset. -- Mike Gerdts http://mgerdts.blogspot.com/
On Thu, Jul 2, 2009 at 2:22 PM, Mike Gerdts<mgerdts at gmail.com> wrote:> On Thu, Jul 2, 2009 at 8:07 AM, Peter Tribble<peter.tribble at gmail.com> wrote: >> We''ve just stumbled across an interesting problem in one of our >> applications that fails when run on a ZFS filesystem. >> >> I don''t have the code, so I can''t fix it at source, but it''s relying >> on the fact that if you do readdir() on a directory, the files come >> back in the order they were added to the directory. This appears >> to be true (within certain limitations) on UFS, but certainly isn''t >> true on ZFS. >> >> Is there any way to force readdir() to return files in a specific order? >> (On UFS, we have a scipt that creates symlinks in the correct order. >> Ugly, but seems to have worked for many years.) >> >> If not, I was looking at interposing my own readdir() (that''s assuming >> the application is using readdir()) that actually returns the entries in >> the desired order. However, I''m having a bit of trouble hacking this >> together (the current source doesn''t compile in isolation on my S10 >> machine). > > Is one of these your starting point? ?What errors are you seeing? > > http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/readdir.c > http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libbc/libc/gen/common/readdir.c > > The libbc version hasn''t changed since the code became public. ?You > can get to an older libc variant of it by clicking on the history link > or using the appropriate hg command to get a specific changeset.OpenGrok pointed me at the second one, which doesn''t seem to want to play. I''m having some success with the first one though. Thanks! -- -Peter Tribble http://www.petertribble.co.uk/ - http://ptribble.blogspot.com/
Peter Tribble <peter.tribble at gmail.com> wrote:> We''ve just stumbled across an interesting problem in one of our > applications that fails when run on a ZFS filesystem. > > I don''t have the code, so I can''t fix it at source, but it''s relying > on the fact that if you do readdir() on a directory, the files come > back in the order they were added to the directory. This appears > to be true (within certain limitations) on UFS, but certainly isn''t > true on ZFS.It seems that you found a software that is not POSIX compliant as it expects a behavior that is not granted by POSIX.> Is there any way to force readdir() to return files in a specific order? > (On UFS, we have a scipt that creates symlinks in the correct order. > Ugly, but seems to have worked for many years.)You could write a readdir() replacement that calls struct dirent * (*readdir_real)() = dlsym(RTLD_NEXT, "readdir"); and enforce it via LDPRELOAD ...but how would you retrieve the creation order? Also note that you would need to read in the whole directory into allocated storage first. BTW: If you like to fix the software, you should know that Linux has at least one filesystem that returns the entries for "." and ".." out of order. J?rg -- EMail:joerg at schily.isdn.cs.tu-berlin.de (home) J?rg Schilling D-13353 Berlin js at cs.tu-berlin.de (uni) joerg.schilling at fokus.fraunhofer.de (work) Blog: http://schily.blogspot.com/ URL: http://cdrecord.berlios.de/private/ ftp://ftp.berlios.de/pub/schily
On Thu, Jul 2, 2009 at 9:21 AM, Joerg Schilling<Joerg.Schilling at fokus.fraunhofer.de> wrote:> Peter Tribble <peter.tribble at gmail.com> wrote: > >> We''ve just stumbled across an interesting problem in one of our >> applications that fails when run on a ZFS filesystem. >> >> I don''t have the code, so I can''t fix it at source, but it''s relying >> on the fact that if you do readdir() on a directory, the files come >> back in the order they were added to the directory. This appears >> to be true (within certain limitations) on UFS, but certainly isn''t >> true on ZFS. > > It seems that you found a software that is not POSIX compliant as it expects a > behavior that is not granted by POSIX. > >> Is there any way to force readdir() to return files in a specific order? >> (On UFS, we have a scipt that creates symlinks in the correct order. >> Ugly, but seems to have worked for many years.) > > You could write a readdir() replacement that calls > > struct dirent * (*readdir_real)() = dlsym(RTLD_NEXT, "readdir");I don''t think this part is necessary - it seems as though readdir needs to be replaced, not wrapped. As such, readdir_real would never be called.> > and enforce it via LDPRELOAD> > ...but how would you retrieve the creation order?Sort on crtime? $ ls -l -% all .bashrc -rw-r--r-- 1 mgerdts other 4674 Jul 2 06:18 .bashrc timestamp: atime Jul 2 09:51:44 2009 timestamp: ctime Jul 2 06:18:06 2009 timestamp: mtime Jul 2 06:18:06 2009 timestamp: crtime May 14 09:24:35 2009 getattrat(3C) seems to be the man page to look at for this value. My guess is that this is going to be extremely slow on the first call to readdir with the need to read the entire directory contents, call getattrat on every entry, then sort. However, slow is often better than broke.> Also note that you would need to read in the whole directory into allocated > storage first.It seems as though readdir will already do this for smallish (8KB) directories.> > > BTW: If you like to fix the software, you should know that Linux has at least > one filesystem that returns the entries for "." and ".." out of order.-- Mike Gerdts http://mgerdts.blogspot.com/
On Thu, 2 Jul 2009, Peter Tribble wrote:> We''ve just stumbled across an interesting problem in one of our > applications that fails when run on a ZFS filesystem. > > I don''t have the code, so I can''t fix it at source, but it''s relying > on the fact that if you do readdir() on a directory, the files come > back in the order they were added to the directory. This appears > to be true (within certain limitations) on UFS, but certainly isn''t > true on ZFS. > > Is there any way to force readdir() to return files in a specific order? > (On UFS, we have a scipt that creates symlinks in the correct order. > Ugly, but seems to have worked for many years.)Oops! The only solution is to add some code to sort the results. You can use qsort() for that. Depending on existing directory order is an error. Bob -- Bob Friesenhahn bfriesen at simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
I am no expert, but I recently wrote a wrapper for my Media players, that expands .RAR archives, and presents files inside as regular contents of the directory. It may give you a starting point; wiki http://lundman.net/wiki/index.php/Librarchy tarball http://www.lundman.net/ftp/librarcy/librarcy-1.0.3.tar.gz CVSweb http://www.lundman.net/cvs/viewvc.cgi/lundman/librarcy/ Lund Peter Tribble wrote:> We''ve just stumbled across an interesting problem in one of our > applications that fails when run on a ZFS filesystem. > > I don''t have the code, so I can''t fix it at source, but it''s relying > on the fact that if you do readdir() on a directory, the files come > back in the order they were added to the directory. This appears > to be true (within certain limitations) on UFS, but certainly isn''t > true on ZFS. > > Is there any way to force readdir() to return files in a specific order? > (On UFS, we have a scipt that creates symlinks in the correct order. > Ugly, but seems to have worked for many years.) > > If not, I was looking at interposing my own readdir() (that''s assuming > the application is using readdir()) that actually returns the entries in > the desired order. However, I''m having a bit of trouble hacking this > together (the current source doesn''t compile in isolation on my S10 > machine). >-- Jorgen Lundman | <lundman at lundman.net> Unix Administrator | +81 (0)3 -5456-2687 ext 1017 (work) Shibuya-ku, Tokyo | +81 (0)90-5578-8500 (cell) Japan | +81 (0)3 -3375-1767 (home)