1 /*
2 * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2005 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved.
13 * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved.
14 * Copyright (c) 2010-2011 Los Alamos National Security, LLC.
15 * All rights reserved.
16 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
17 * Copyright (c) 2014 Intel, Inc. All rights reserved.
18 *
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 #include "opal_config.h"
27
28 #include <errno.h>
29 #ifdef HAVE_FCNTL_H
30 #include <fcntl.h>
31 #endif /* HAVE_FCNTL_H */
32 #include <string.h>
33 #if OPAL_HAVE_SOLARIS && !defined(_POSIX_C_SOURCE)
34 #define _POSIX_C_SOURCE 200112L /* Required for shm_{open,unlink} decls */
35 #include <sys/mman.h>
36 #undef _POSIX_C_SOURCE
37 #else
38 #ifdef HAVE_SYS_MMAN_H
39 #include <sys/mman.h>
40 #endif /* HAVE_SYS_MMAN_H */
41 #endif
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif /* HAVE_UNISTD_H */
45 #ifdef HAVE_SYS_TYPES_H
46 #include <sys/types.h>
47 #endif /* HAVE_SYS_TYPES_H */
48 #ifdef HAVE_NETDB_H
49 #include <netdb.h>
50 #endif /* HAVE_NETDB_H */
51
52 #include "opal/util/output.h"
53 #include "opal/util/show_help.h"
54 #include "opal/mca/shmem/base/base.h"
55 #include "opal/mca/shmem/shmem.h"
56
57 #include "shmem_posix.h"
58 #include "shmem_posix_common_utils.h"
59
60 /* ////////////////////////////////////////////////////////////////////////// */
61 int
62 shmem_posix_shm_open(char *posix_file_name_buff, size_t size)
63 {
64 int attempt = 0, fd = -1;
65
66 /* workaround for simultaneous posix shm_opens on the same node (e.g.
67 * multiple Open MPI jobs sharing a node). name collision during component
68 * runtime will happen, so protect against it by trying a few times.
69 */
70 do {
71 /* format: /open_mpi.nnnn
72 * see comment in shmem_posix.h that explains why we chose to do things
73 * this way.
74 */
75 snprintf(posix_file_name_buff, size, "%s%04d",
76 OPAL_SHMEM_POSIX_FILE_NAME_PREFIX, attempt++);
77 /* the check for the existence of the object and its creation if it
78 * does not exist are performed atomically.
79 */
80 if (-1 == (fd = shm_open(posix_file_name_buff,
81 O_CREAT | O_EXCL | O_RDWR, 0600))) {
82 int err = errno;
83 /* the object already exists, so try again with a new name */
84 if (EEXIST == err) {
85 continue;
86 }
87 /* a "real" error occurred. fd is already set to -1, so get out
88 * of here. we can't be selected :-(.
89 */
90 else {
91 char hn[OPAL_MAXHOSTNAMELEN];
92 gethostname(hn, sizeof(hn));
93 opal_output_verbose(10, opal_shmem_base_framework.framework_output,
94 "shmem_posix_shm_open: disqualifying posix because "
95 "shm_open(2) failed with error: %s (errno %d)\n",
96 strerror(err), err);
97 break;
98 }
99 }
100 /* we found an available file name */
101 else {
102 break;
103 }
104 } while (attempt < OPAL_SHMEM_POSIX_MAX_ATTEMPTS);
105
106 /* if we didn't find a name, let the user know that we tried and failed */
107 if (attempt >= OPAL_SHMEM_POSIX_MAX_ATTEMPTS) {
108 opal_output(0, "shmem: posix: file name search - max attempts exceeded."
109 "cannot continue with posix.\n");
110 }
111 return fd;
112 }
113