Odd behavior with folderitem.Directory

I am working on a Linux program that need to know if given path is a file or a directory, and if it is a directory it gets a count of the number of files in that directory.

This works 99% of the time, on both my development sandbox and on another test server that I have access to. However, when I run the program on a mounted storage device (I’m assuming it is NAS), then folderitem.directory always returns false even if the path truly is a directory. Below is the code I’m using to check:

Sub fileExists (path As String)

Dim test As FolderItem
test = GetFolderItem(path)

  If test <> Nil Then
    
    numEntries = test.Count
    
      App.writeLocalLog("(fileExists) Debug - Count of entries in path, " + test.ShellPath + ": " + Str(numEntries))

      If test.Directory Then
        App.writeLocalLog("(fileExists) Debug - Is directory: " + test.ShellPath)
        type = "Directory"
      Else
        App.writeLocalLog("(fileExists) Debug - Is file: " + test.ShellPath)
        type = "File"
      End If

End If

End Sub

Note that this does work when testing against local Linux storage. It only seems to have an issue when dealing with the mounted directory mentioned above.

Any suggestions would be greatly appreciated.

Thanks!

Here is a stat on the directory that is failing the test:

bash-3.2$ stat /mnt/ifsbackup11001/mysql/vm/full
  File: `/mnt/ifsbackup11001/mysql/vm/full'
  Size: 111             Blocks: 4          IO Block: 4096   directory
Device: 19h/25d Inode: 4717623089  Links: 5
Access: (0777/drwxrwxrwx)  Uid: (  103/   mysql)   Gid: (24157/mysql)
Access: 2013-09-05 19:21:29.104558541 -0500
Modify: 2013-09-05 19:52:55.201820509 -0500
Change: 2013-09-05 19:52:55.201820509 -0500

I have a little more information concerning this. The mount point I’m having issues reading is an EMC NFS share. Permissions are correct, and from the Linux terminal I have complete access to the directory and all files within it. Linux reports the mount point as a directory, and everything looks and works exactly as it should.

When using RS however, this path isn’t recognized as a directory at all, and as such all further operations fail (such as a count of the items, exists, etc). To make sure that RS can work with NFS mounts, I set up a Linux NFS share on a sandbox, and RS could read it just fine!

Below is debug output showing the number of items in the directory, /mnt/ ifsbackup11001:

Item Count: 0
Absolute Path: /mnt/ifsbackup11001
Path is NOT a directory

Notice it said the path is NOT a directory. This IS a directory, and there are hundreds of files within!

When I ran the same program on a sandbox VM with a NFS mount, it reported correctly. It shows two items in the directory:

Item Count: 2
Absolute Path: /mnt/exports
/mnt/exports/file2.txt
/mnt/exports/file1.txt

So, that seems to rule out that it’s a problem with RS working with mounted volumes. Any ideas why it would not see this particular NFS mount as a directory? Is there an incompatibility between EMC NFS mounts and RS?

More diagnostic information below.

  1. The program I’m writing calls “mysqldump” which writes text based backup files for MySQL. The “mysqldump” binary is written in C, and it can write to the NFS mount just fine.
  2. Another program I use is XtraBackup, which uses a Perl wrapper to create directories to store the binary backups. Perl is able to write to the NFS mount just fine.
  3. All standard Linux tools (mkdir, etc) all write to the NFS mount just fine.

Only RealStudio seems to be having issues with this mountpoint. As mentioned above, for some reason RS doesn’t recognize my path as a directory, and thinks it is a file. Could this be a RS bug?

OK, so I went back to investigate more on the folderitem issue. I ran the following snippet of code and got an error code returned:

Dim f As FolderItem
f = TestFolderItem(SpecialFolder.Mount)
test = TestFolderItem(f.TrueChild("ifscwybackup11001"))

The TestFolderItem method is something I wrote which spits out a lot of info on the folder item. I went child by child with the test program and found the following error code (in red):

[user@vm11111 test]$ ./test
(Volumes)
0: /: /: True
1: proc: /proc/: True
2: sys: /sys/: True
3: pts: /dev/pts/: True
4: shm: /dev/shm/: True
5: u01: /u01/: True
6: binfmt_misc: /proc/sys/fs/binfmt_misc/: True
7: rpc_pipefs: /var/lib/nfs/rpc_pipefs/: True
8: ifs10001: /mnt/ifs10001: False
9: datasets: /mnt/datasets: False
10: ifsbackup11001: /mnt/ifsbackup11001: False

Folderitem is not Nil
Display Name: mnt
Name: mnt
Count: 4
Is readable?:True
Length: 4096
Exists: True
Absolute Path: /mnt/
Shell Path: /mnt/
Type:
URL Path: file:///mnt/
Visible: True
Error Code: 0
Error Msg (if known):
------------------------------------------
(Items in directory)
1:ifs10001
2:ifsbackup11001
3:datagrid0001
4:datasets
------------------------------------------
Path is a directory

============================================

Folderitem is not Nil
Display Name: ifsbackup11001
Name: ifsbackup11001
Count: 0
Is readable?:True
Length: 27
Exists: True
Absolute Path: /mnt/ifsbackup11001
Shell Path: /mnt/ifsbackup11001
Type:
URL Path: file:///mnt/ifsbackup11001
Visible: True
Error Code: 75
Error Msg (if known): Unexpected error code #75
Path is NOT a directory

As soon as I try to reference the NAS volume, I get error code 75. No Google searches turned up anything related to Xojo or RB. So, I did more reading and it turns out that the error code is likely an OS error code. According to the C documentation (which Xojo said to look at for Linux), it is the following:

#define EOVERFLOW   75  /* Value too large for defined data type */

Could it be that the NAS is so big it overflows RB’s buffer?

While I have no time to look in your issue, I can suggest that you could work around this by not relying on the FolderItem class for this (i.e. it may be a bug in there).
Instead, use the “declare” instruction to call the native Linux functions directly.

You can find some code in my class “TTsFolderItem”, which works around a known bug in Linux where FolderItem reports the wrong value for the Exists property for symlinks. This class is inside my Zip code: http://www.tempel.org/RB/ZipPackage
It contains code to call the stat function, for instance (inside TTsFolderItem.update).

Good luck

Thank you for the information and code, Thomas! Literally a few hours after you responded, I ended up on a tech support call with EMC to discuss this issue. Turns out their NFS system defaults to 64 bit file handles, and once this was configured to provide 32 bit file handles the issue magically went away! How about that? LOL.

It looks like the 64 bit file handles were overflowing the 32 bit folderitem class in RealBasic causing the “EOVERFLOW 75” error.

Wow, I’m impressed that you could figure this out this way.

Please, do us others a favor and submit a bug report on your findings via the Feedback app.