Skip to content

Commit ac31454

Browse files
committed
fs/lustre: recognize soft-links on file open
the llapi_file_get_stripe() function does not accept as an input file a soft-link. Check therefore whether the filename provided in File_open is a soft-link, retrieve the real file name in case it is, make sure it is also on a Lustre file system, and use the real filename in the llapi_file_get_stripe() function call instead. Fixes issue #12141 Signed-off-by: Edgar Gabriel <[email protected]> (cherry picked from commit c6a6c25)
1 parent d9bc607 commit ac31454

File tree

3 files changed

+73
-38
lines changed

3 files changed

+73
-38
lines changed

ompi/mca/fs/base/base.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@
3737
#include "ompi/mca/fs/fs.h"
3838

3939

40+
#ifdef HAVE_SYS_STATFS_H
41+
#include <sys/statfs.h> /* or <sys/vfs.h> */
42+
#endif
43+
#ifdef HAVE_SYS_PARAM_H
44+
#include <sys/param.h>
45+
#endif
46+
#ifdef HAVE_SYS_MOUNT_H
47+
#include <sys/mount.h>
48+
#endif
49+
#ifdef HAVE_SYS_STAT_H
50+
#include <sys/stat.h>
51+
#endif
52+
#ifdef HAVE_UNISTD_H
53+
#include <unistd.h>
54+
#endif
55+
4056
BEGIN_C_DECLS
4157

4258
OMPI_DECLSPEC int mca_fs_base_file_select(struct ompio_file_t *file,
@@ -62,6 +78,42 @@ OMPI_DECLSPEC int mca_fs_base_file_get_size (ompio_file_t *fh, OMPI_MPI_OFFSET_T
6278
OMPI_DECLSPEC int mca_fs_base_file_set_size (ompio_file_t *fh, OMPI_MPI_OFFSET_TYPE size);
6379
OMPI_DECLSPEC int mca_fs_base_file_close (ompio_file_t *fh);
6480

81+
82+
static inline bool mca_fs_base_is_link (const char *filename)
83+
{
84+
int err;
85+
bool ret = true;
86+
struct stat statbuf;
87+
88+
err = lstat(filename, &statbuf);
89+
90+
if (err || (!S_ISLNK(statbuf.st_mode))) {
91+
ret = false;
92+
}
93+
94+
return ret;
95+
}
96+
97+
static inline void mca_fs_base_get_real_filename (const char *filename, char **rfilename)
98+
{
99+
int namelen;
100+
char linkbuf[PATH_MAX+1];
101+
102+
namelen = readlink(filename, linkbuf, PATH_MAX);
103+
if (namelen == -1) {
104+
/* something strange has happened between the time that
105+
* we determined that this was a link and the time that
106+
* we attempted to read it; punt and use the old name.
107+
*/
108+
*rfilename = strdup(filename);
109+
}
110+
else {
111+
/* successfully read the link */
112+
linkbuf[namelen] = '\0'; /* readlink doesn't null terminate */
113+
*rfilename = strdup(linkbuf);
114+
}
115+
}
116+
65117
/*
66118
* Globals
67119
*/

ompi/mca/fs/base/fs_base_get_parent_dir.c

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,17 @@
3131
#include "ompi/mca/fs/base/base.h"
3232
#include "ompi/mca/common/ompio/common_ompio.h"
3333

34-
#ifdef HAVE_SYS_STATFS_H
35-
#include <sys/statfs.h> /* or <sys/vfs.h> */
36-
#endif
37-
#ifdef HAVE_SYS_PARAM_H
38-
#include <sys/param.h>
39-
#endif
40-
#ifdef HAVE_SYS_MOUNT_H
41-
#include <sys/mount.h>
42-
#endif
43-
#ifdef HAVE_SYS_STAT_H
44-
#include <sys/stat.h>
45-
#endif
46-
#ifdef HAVE_UNISTD_H
47-
#include <unistd.h>
48-
#endif
4934

5035
void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
5136
{
52-
int err;
5337
char *dir = NULL, *slash;
54-
struct stat statbuf;
5538

56-
err = lstat(filename, &statbuf);
39+
if (strlen(filename) < 1) {
40+
asprintf(dirnamep, ".%s", OPAL_PATH_SEP);
41+
return;
42+
}
5743

58-
if (err || (!S_ISLNK(statbuf.st_mode))) {
44+
if (!mca_fs_base_is_link(filename)) {
5945
/* no such file, or file is not a link; these are the "normal"
6046
* cases where we can just return the parent directory.
6147
*/
@@ -67,22 +53,7 @@ void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
6753
* but this code doesn't care if the target is really there
6854
* or not.
6955
*/
70-
int namelen;
71-
char linkbuf[PATH_MAX+1];
72-
73-
namelen = readlink(filename, linkbuf, PATH_MAX);
74-
if (namelen == -1) {
75-
/* something strange has happened between the time that
76-
* we determined that this was a link and the time that
77-
* we attempted to read it; punt and use the old name.
78-
*/
79-
dir = strdup(filename);
80-
}
81-
else {
82-
/* successfully read the link */
83-
linkbuf[namelen] = '\0'; /* readlink doesn't null terminate */
84-
dir = strdup(linkbuf);
85-
}
56+
mca_fs_base_get_real_filename(filename, &dir);
8657
}
8758

8859
slash = strrchr(dir, '/');

ompi/mca/fs/lustre/fs_lustre_file_open.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
7070
int fs_lustre_stripe_size = -1;
7171
int fs_lustre_stripe_width = -1;
7272
char char_stripe[MPI_MAX_INFO_KEY];
73-
73+
char *rfilename = (char *)filename;
7474
struct lov_user_md *lump=NULL;
7575

7676
perm = mca_fs_base_get_file_perm(fh);
@@ -108,13 +108,25 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
108108
fs_lustre_stripe_width = mca_fs_lustre_stripe_width;
109109
}
110110

111+
/* Check for soft links and replace filename by the actual
112+
file used in case it is a soft link */
113+
if (mca_fs_base_is_link(filename)) {
114+
mca_fs_base_get_real_filename(filename, &rfilename);
115+
/* make sure the real file is also on a Lustre file system */
116+
if (LUSTRE != mca_fs_base_get_fstype(rfilename)) {
117+
opal_output(1, "cannot use a soft-link between a LUSTRE and non-LUSTRE file system\n");
118+
return OPAL_ERROR;
119+
}
120+
}
111121

112122
/* Reset errno */
113123
errno = 0;
114124
if (OMPIO_ROOT == fh->f_rank) {
115125
if ( (fs_lustre_stripe_size>0 || fs_lustre_stripe_width>0) &&
116126
( amode&O_CREAT) &&
117127
( (amode&O_RDWR)|| amode&O_WRONLY) ) {
128+
/* this cannot be a soft-link since we are creating the file.
129+
Not using rfilename here */
118130
llapi_file_create(filename,
119131
fs_lustre_stripe_size,
120132
-1, /* MSC need to change that */
@@ -132,7 +144,7 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
132144
}
133145
}
134146

135-
comm->c_coll->coll_bcast ( &ret, 1, MPI_INT, 0, comm, comm->c_coll->coll_bcast_module);
147+
comm->c_coll->coll_bcast ( &ret, 1, MPI_INT, 0, comm, comm->c_coll->coll_bcast_module);
136148
if ( OMPI_SUCCESS != ret ) {
137149
fh->fd = -1;
138150
return ret;
@@ -150,7 +162,7 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
150162
fprintf(stderr,"Cannot allocate memory for extracting stripe size\n");
151163
return OMPI_ERROR;
152164
}
153-
rc = llapi_file_get_stripe(filename, lump);
165+
rc = llapi_file_get_stripe(rfilename, lump);
154166
if (rc != 0) {
155167
opal_output(1, "get_stripe failed: %d (%s)\n", errno, strerror(errno));
156168
free(lump);

0 commit comments

Comments
 (0)