Skip to content

Commit dafebd5

Browse files
committed
[OpenMP] Create a temp file in /tmp if /dev/shm is not accessible
When `libomp` is initialized, it creates a temp file in `/dev/shm` to store registration flag. Some systems, like Android, don't have `/dev/shm`, then this feature is disabled by the macro `KMP_USE_SHM`, though most Linux distributions have that. However, some customized distribution, such as the one reported in #53955, doesn't support it either. It causes a core dump. In this patch, if it is the case, we will try to create a temporary file in `/tmp`, and if it still doesn't make it, then we error out. Note that we don't consider in this patch if the temporary directory has been set to `TMPDIR` in this patch. If `/tmp` is not accessible, we error out. Fix #53955. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D142175
1 parent 56313f6 commit dafebd5

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

openmp/runtime/src/kmp_runtime.cpp

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "kmp_wait_release.h"
2525
#include "kmp_wrapper_getpid.h"
2626
#include "kmp_dispatch.h"
27+
#include <cstdio>
2728
#if KMP_USE_HIER_SCHED
2829
#include "kmp_dispatch_hier.h"
2930
#endif
@@ -6739,6 +6740,11 @@ static inline char *__kmp_reg_status_name() {
67396740
#endif
67406741
} // __kmp_reg_status_get
67416742

6743+
#if defined(KMP_USE_SHM)
6744+
// If /dev/shm is not accessible, we will create a temporary file under /tmp.
6745+
char *temp_reg_status_file_name = nullptr;
6746+
#endif
6747+
67426748
void __kmp_register_library_startup(void) {
67436749

67446750
char *name = __kmp_reg_status_name(); // Name of the environment variable.
@@ -6780,11 +6786,19 @@ void __kmp_register_library_startup(void) {
67806786
// able to open existing file
67816787
shm_preexist = 1;
67826788
}
6783-
} else if (fd1 == -1) { // SHM didn't open; it was due to error other than
6784-
// already exists.
6785-
// error out here.
6786-
__kmp_fatal(KMP_MSG(FunctionError, "Can't open SHM2"), KMP_ERR(errno),
6787-
__kmp_msg_null);
6789+
} else if (fd1 == -1) {
6790+
// SHM didn't open; it was due to error other than already exists. Try to
6791+
// create a temp file under /tmp.
6792+
// TODO: /tmp might not always be the temporary directory. For now we will
6793+
// not consider TMPDIR. If /tmp is not accessible, we simply error out.
6794+
char *temp_file_name = __kmp_str_format("/tmp/%sXXXXXX", name);
6795+
fd1 = mkstemp(temp_file_name);
6796+
if (fd1 == -1) {
6797+
// error out here.
6798+
__kmp_fatal(KMP_MSG(FunctionError, "Can't open TEMP"), KMP_ERR(errno),
6799+
__kmp_msg_null);
6800+
}
6801+
temp_reg_status_file_name = temp_file_name;
67886802
}
67896803
if (shm_preexist == 0) {
67906804
// we created SHM now set size
@@ -6896,11 +6910,19 @@ void __kmp_unregister_library(void) {
68966910
char *value = NULL;
68976911

68986912
#if defined(KMP_USE_SHM)
6913+
bool use_shm = true;
68996914
char *shm_name = __kmp_str_format("/%s", name);
69006915
int fd1 = shm_open(shm_name, O_RDONLY, 0666);
69016916
if (fd1 == -1) {
6902-
// file did not open. return.
6903-
return;
6917+
// File did not open. Try the temporary file.
6918+
use_shm = false;
6919+
KMP_DEBUG_ASSERT(temp_reg_status_file_name);
6920+
FILE *tf = fopen(temp_reg_status_file_name, O_RDONLY);
6921+
if (!tf) {
6922+
// give it up now.
6923+
return;
6924+
}
6925+
fd1 = fileno(tf);
69046926
}
69056927
char *data1 = (char *)mmap(0, SHM_SIZE, PROT_READ, MAP_SHARED, fd1, 0);
69066928
if (data1 != MAP_FAILED) {
@@ -6917,14 +6939,23 @@ void __kmp_unregister_library(void) {
69176939
if (value != NULL && strcmp(value, __kmp_registration_str) == 0) {
69186940
// Ok, this is our variable. Delete it.
69196941
#if defined(KMP_USE_SHM)
6920-
shm_unlink(shm_name); // this removes file in /dev/shm
6942+
if (use_shm) {
6943+
shm_unlink(shm_name); // this removes file in /dev/shm
6944+
} else {
6945+
KMP_DEBUG_ASSERT(temp_reg_status_file_name);
6946+
unlink(temp_reg_status_file_name); // this removes the temp file
6947+
}
69216948
#else
69226949
__kmp_env_unset(name);
69236950
#endif
69246951
}
69256952

69266953
#if defined(KMP_USE_SHM)
69276954
KMP_INTERNAL_FREE(shm_name);
6955+
if (!use_shm) {
6956+
KMP_DEBUG_ASSERT(temp_reg_status_file_name);
6957+
KMP_INTERNAL_FREE(temp_reg_status_file_name);
6958+
}
69286959
#endif
69296960

69306961
KMP_INTERNAL_FREE(__kmp_registration_str);

0 commit comments

Comments
 (0)