Skip to content

Commit ec9d195

Browse files
authored
Merge pull request #12171 from edgargabriel/pr/lustre-link-fix-v4.1
fs/lustre: recognize soft-links on file open
2 parents d9bc607 + 9d54ef2 commit ec9d195

File tree

3 files changed

+75
-35
lines changed

3 files changed

+75
-35
lines changed

ompi/mca/fs/base/base.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@
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_STAT_H
47+
#include <sys/stat.h>
48+
#endif
49+
#ifdef HAVE_UNISTD_H
50+
#include <unistd.h>
51+
#endif
52+
4053
BEGIN_C_DECLS
4154

4255
OMPI_DECLSPEC int mca_fs_base_file_select(struct ompio_file_t *file,
@@ -62,6 +75,42 @@ OMPI_DECLSPEC int mca_fs_base_file_get_size (ompio_file_t *fh, OMPI_MPI_OFFSET_T
6275
OMPI_DECLSPEC int mca_fs_base_file_set_size (ompio_file_t *fh, OMPI_MPI_OFFSET_TYPE size);
6376
OMPI_DECLSPEC int mca_fs_base_file_close (ompio_file_t *fh);
6477

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

ompi/mca/fs/base/fs_base_get_parent_dir.c

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,25 @@
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
34+
/*
35+
* Be careful moving this include.
36+
* It's easy to hit problems similar to that reported in
37+
* https://github.com/systemd/systemd/issues/8507
38+
*/
4039
#ifdef HAVE_SYS_MOUNT_H
4140
#include <sys/mount.h>
4241
#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
4942

5043
void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
5144
{
52-
int err;
5345
char *dir = NULL, *slash;
54-
struct stat statbuf;
5546

56-
err = lstat(filename, &statbuf);
47+
if (strlen(filename) < 1) {
48+
asprintf(dirnamep, ".%s", OPAL_PATH_SEP);
49+
return;
50+
}
5751

58-
if (err || (!S_ISLNK(statbuf.st_mode))) {
52+
if (!mca_fs_base_is_link(filename)) {
5953
/* no such file, or file is not a link; these are the "normal"
6054
* cases where we can just return the parent directory.
6155
*/
@@ -67,22 +61,7 @@ void mca_fs_base_get_parent_dir ( char *filename, char **dirnamep)
6761
* but this code doesn't care if the target is really there
6862
* or not.
6963
*/
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-
}
64+
mca_fs_base_get_real_filename(filename, &dir);
8665
}
8766

8867
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)