Project

General

Profile

Actions

Bug #6655

closed

readdir() fails on CephFS mount symlinked directories

Added by Pieter Steyn over 10 years ago. Updated over 10 years ago.

Status:
Can't reproduce
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
% Done:

0%

Source:
Community (user)
Tags:
Backport:
Regression:
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Component(FS):
Labels (FS):
Pull request ID:
Crash signature (v1):
Crash signature (v2):

Description

Background:

  • Ubuntu Server 12.04 64bit.
  • CephFS Dumpling 0.67.4
  • We moved from local filesystem to CephFS for web data.
  • Webserver mounts CephFS on /mnt/ceph
  • In order to reduce some CephFS I/O, and without wanting to change code, I've symlinked some directories within /mnt/ceph back to local filesystem.

Problem:

We use PHP's readdir() function within our code, and noticed that it has a problem with symlinks on CephFS.

Given the following situation:

/mnt/ceph/ -- CephFS mount
/mnt/ceph/tenants/0002/data -- Real CephFS directory
/mnt/ceph/tenants/0002/testing -- Symlink to /mnt/ceph/tenants/0002/data

www-data@appserver:/mnt/ceph/tenants/0002$ ls -lha
total 1,5K
drwxr-xr-x 1 www-data www-data 567G Oct 26 07:14 .
drwxr-xr-x 1 www-data www-data 567G Oct 21 18:58 ..
drwxr-xr-x 1 www-data www-data 567G Oct 26 07:10 data
lrwxrwxrwx 1 www-data www-data 4 Oct 26 07:14 testing -> data

#PHP Code:

www-data@appserver:/mnt/ceph/tenants/0002$ cat /var/tmp/test.php

$dirName = $argv[1];
$dir = opendir($dirName);
while (($dirEntry = readdir($dir)) !== false) {
echo $dirEntry . "\n";
}
?>

The following works:

www-data@appserver:/mnt/ceph/tenants/0002$ php /var/tmp/test.php /mnt/ceph/tenants/0002/data/
.
..
generatedDocument
html
images

But the following results in infinite loop:

www-data@appserver:/mnt/ceph/tenants/0002$ php /var/tmp/test.php /mnt/ceph/tenants/0002/testing/

--- infinite loop ---

I've run the same test successfully on the local file system with symlinks, causing me to suspect CephFS instead of readdir().

I've also tested in C, using readdir(), resulting in failure:

Code: /tmp/readdir.c

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main ( int argc, char *argv[] ) {
DIR *dp;
struct dirent *ep;
dp = opendir (argv1);

if (dp != NULL)                                                                                                                                                                   
{                                                                                                                                                                                 
while (ep = readdir (dp))
puts (ep->d_name);
(void) closedir (dp);                                                                                                                                                           
}
else
perror ("Couldn't open the directory");
return 0;
}

www-data@appserver:/mnt/ceph/tenants/0002$ /tmp/readdir data/
.
..
generatedDocument
html
images

www-data@appserver:/mnt/ceph/tenants/0002$ /tmp/readdir testing/
Couldn't open the directory: Invalid argument

Keep in mind that the above does work with symlinks on local filesystem.

For interest sake, we've found that PHP readdir() on CephFS symlinks will behave if calling is_dir() before readdir():

www-data@appserver:/mnt/ceph/tenants/0002$ cat /var/tmp/workaround.php

$dirName = $argv[1];
if (is_dir($dirName)) {
$dir = opendir($dirName);
while (($dirEntry = readdir($dir)) !== false) {
echo $dirEntry . "\n";
}
}
?>

www-data@appserver:/mnt/ceph/tenants/0002$ php /var/tmp/workaround.php /mnt/ceph/tenants/0002/testing/
.
..
generatedDocument
html
images

Actions

Also available in: Atom PDF