Skip to content

Commit c6a6c25

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 <Edgar.Gabriel@amd.com>
1 parent ab4cd38 commit c6a6c25

File tree

3 files changed

+69
-39
lines changed

3 files changed

+69
-39
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: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,17 @@
3535
#include "ompi/mca/fs/base/base.h"
3636
#include "ompi/mca/common/ompio/common_ompio.h"
3737

38-
#ifdef HAVE_SYS_STATFS_H
39-
#include <sys/statfs.h> /* or <sys/vfs.h> */
40-
#endif
41-
#ifdef HAVE_SYS_PARAM_H
42-
#include <sys/param.h>
43-
#endif
44-
#ifdef HAVE_SYS_MOUNT_H
45-
#include <sys/mount.h>
46-
#endif
47-
#ifdef HAVE_SYS_STAT_H
48-
#include <sys/stat.h>
49-
#endif
50-
#ifdef HAVE_UNISTD_H
51-
#include <unistd.h>
52-
#endif
5338

5439
void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
5540
{
56-
int err;
5741
char *dir = NULL, *slash;
58-
struct stat statbuf;
5942

6043
if (strlen(filename) < 1) {
6144
opal_asprintf(dirnamep, ".%s", OPAL_PATH_SEP);
6245
return;
6346
}
6447

65-
err = lstat(filename, &statbuf);
66-
67-
if (err || (!S_ISLNK(statbuf.st_mode))) {
48+
if (!mca_fs_base_is_link(filename)) {
6849
/* no such file, or file is not a link; these are the "normal"
6950
* cases where we can just return the parent directory.
7051
*/
@@ -76,22 +57,7 @@ void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
7657
* but this code doesn't care if the target is really there
7758
* or not.
7859
*/
79-
int namelen;
80-
char linkbuf[PATH_MAX+1];
81-
82-
namelen = readlink(filename, linkbuf, PATH_MAX);
83-
if (namelen == -1) {
84-
/* something strange has happened between the time that
85-
* we determined that this was a link and the time that
86-
* we attempted to read it; punt and use the old name.
87-
*/
88-
dir = strdup(filename);
89-
}
90-
else {
91-
/* successfully read the link */
92-
linkbuf[namelen] = '\0'; /* readlink doesn't null terminate */
93-
dir = strdup(linkbuf);
94-
}
60+
mca_fs_base_get_real_filename(filename, &dir);
9561
}
9662

9763
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
opal_cstring_t *stripe_str;
73-
73+
char *rfilename = (char *)filename;
7474
struct lov_user_md *lump=NULL;
7575

7676
perm = mca_fs_base_get_file_perm(fh);
@@ -112,13 +112,25 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
112112
fs_lustre_stripe_width = mca_fs_lustre_stripe_width;
113113
}
114114

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

116126
/* Reset errno */
117127
errno = 0;
118128
if (OMPIO_ROOT == fh->f_rank) {
119129
if ( (fs_lustre_stripe_size>0 || fs_lustre_stripe_width>0) &&
120130
( amode&O_CREAT) &&
121131
( (amode&O_RDWR)|| amode&O_WRONLY) ) {
132+
/* this cannot be a soft-link since we are creating the file.
133+
Not using rfilename here */
122134
llapi_file_create(filename,
123135
fs_lustre_stripe_size,
124136
-1, /* MSC need to change that */
@@ -136,7 +148,7 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
136148
}
137149
}
138150

139-
comm->c_coll->coll_bcast ( &ret, 1, MPI_INT, 0, comm, comm->c_coll->coll_bcast_module);
151+
comm->c_coll->coll_bcast ( &ret, 1, MPI_INT, 0, comm, comm->c_coll->coll_bcast_module);
140152
if ( OMPI_SUCCESS != ret ) {
141153
fh->fd = -1;
142154
return ret;
@@ -154,7 +166,7 @@ mca_fs_lustre_file_open (struct ompi_communicator_t *comm,
154166
fprintf(stderr,"Cannot allocate memory for extracting stripe size\n");
155167
return OMPI_ERROR;
156168
}
157-
rc = llapi_file_get_stripe(filename, lump);
169+
rc = llapi_file_get_stripe(rfilename, lump);
158170
if (rc != 0) {
159171
opal_output(1, "get_stripe failed: %d (%s)\n", errno, strerror(errno));
160172
free(lump);

0 commit comments

Comments
 (0)