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 #1

Updated by Pieter Steyn over 10 years ago

If struggling to reproduce, it seems like readdir() works directly after other access to the symlink, but only once.

Reproduce:

#Run readdir on normal directory
www-data@appserver:/mnt/ceph/tenants/0002$ /tmp/readdir data
.
..
generatedDocument
html
images

#Create symlink
www-data@appserver:/mnt/ceph/tenants/0002$ ln -s data/ linked_data

#Run readdir on symlinked directory
www-data@appserver:/mnt/ceph/tenants/0002$ /tmp/readdir linked_data
.
..
generatedDocument
html
images

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

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

#Now run ls on symlink

www-data@appserver:/mnt/ceph/tenants/0002$ ls linked_data
generatedDocument html images

#Run readdir again:

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

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

Perhaps some sort of caching issue?

Actions #2

Updated by Zheng Yan over 10 years ago

I can't reproduce this locally. Which kernel did you use? please try ceph-fuse and recent kernel.

Actions #3

Updated by Sage Weil over 10 years ago

  • Status changed from New to Need More Info
  • Source changed from other to Community (user)
Actions #4

Updated by Pieter Steyn over 10 years ago

I haven't been able to reproduce it again either since I remounted CephFS on the client a while ago. (And probably restarted the MDS due to high memory usage.)

I know the MDS was swapping heavily at the time, so maybe that could have caused this weird behavior?

I am confirming that it does work as expected now on latest Ubuntu Server 12.04.3 using:

Linux 3.2.0-45-generic #70-Ubuntu SMP x86_64 GNU/Linux
Thanks,
Pieter

Actions #5

Updated by Zheng Yan over 10 years ago

  • Status changed from Need More Info to Can't reproduce
Actions

Also available in: Atom PDF