1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2005 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2007-2015 Cisco Systems, Inc. All rights reserved.
14 * Copyright (c) 2010-2015 Los Alamos National Security, LLC. All rights
15 * reserved.
16 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
17 * Copyright (c) 2014 Research Organization for Information Science
18 * and Technology (RIST). All rights reserved.
19 * Copyright (c) 2016 Intel, Inc. All rights reserved.
20 * $COPYRIGHT$
21 *
22 * Additional copyrights may follow
23 *
24 * $HEADER$
25 *
26 * These symbols are in a file by themselves to provide nice linker
27 * semantics. Since linkers generally pull in symbols by object
28 * files, keeping these symbols as the only symbols in this file
29 * prevents utility programs such as "ompi_info" from having to import
30 * entire components just to query their version and parameters.
31 */
32
33 #include "opal_config.h"
34
35 #ifdef HAVE_SYS_MMAN_H
36 #include <sys/mman.h>
37 #endif /* HAVE_SYS_MMAN_H */
38 #include <string.h>
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif /* HAVE_UNISTD_H */
42
43 #ifdef HAVE_SYS_IPC_H
44 #include <sys/ipc.h>
45 #endif /* HAVE_SYS_IPC_H */
46 #if HAVE_SYS_SHM_H
47 #include <sys/shm.h>
48 #endif /* HAVE_SYS_SHM_H */
49 #if HAVE_SYS_STAT_H
50 #include <sys/stat.h>
51 #endif /* HAVE_SYS_STAT_H */
52
53 #include "opal/constants.h"
54 #include "opal/util/show_help.h"
55 #include "opal/util/output.h"
56 #include "opal/util/sys_limits.h"
57 #include "opal/mca/shmem/base/base.h"
58 #include "opal/mca/shmem/shmem.h"
59 #include "shmem_sysv.h"
60
61 /* public string showing the shmem ompi_sysv component version number */
62 const char *opal_shmem_sysv_component_version_string =
63 "OPAL sysv shmem MCA component version " OPAL_VERSION;
64
65 /* local functions */
66 static int sysv_register (void);
67 static int sysv_open(void);
68 static int sysv_query(mca_base_module_t **module, int *priority);
69 static int sysv_runtime_query(mca_base_module_t **module,
70 int *priority,
71 const char *hint);
72
73 /* instantiate the public struct with all of our public information
74 * and pointers to our public functions in it
75 */
76 opal_shmem_sysv_component_t mca_shmem_sysv_component = {
77 .super = {
78 /* common MCA component data */
79 {
80 OPAL_SHMEM_BASE_VERSION_2_0_0,
81
82 /* component name and version */
83 .mca_component_name = "sysv",
84 MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
85 OPAL_RELEASE_VERSION),
86
87 .mca_open_component = sysv_open,
88 .mca_query_component = sysv_query,
89 .mca_register_component_params = sysv_register
90 },
91 /* MCA v2.0.0 component meta data */
92 .base_data = {
93 /* the component is checkpoint ready */
94 MCA_BASE_METADATA_PARAM_CHECKPOINT
95 },
96 .runtime_query = sysv_runtime_query,
97 },
98 };
99
100 /* ////////////////////////////////////////////////////////////////////////// */
101 static int
102 sysv_register(void)
103 {
104 /* ////////////////////////////////////////////////////////////////////// */
105 /* (default) priority - set lower than mmap's priority */
106 mca_shmem_sysv_component.priority = 30;
107 (void) mca_base_component_var_register(&mca_shmem_sysv_component.super.base_version,
108 "priority", "Priority for the shmem sysv "
109 "component (default: 30)", MCA_BASE_VAR_TYPE_INT,
110 NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE,
111 OPAL_INFO_LVL_3,
112 MCA_BASE_VAR_SCOPE_ALL_EQ,
113 &mca_shmem_sysv_component.priority);
114
115 return OPAL_SUCCESS;
116 }
117
118 /* ////////////////////////////////////////////////////////////////////////// */
119 static int
120 sysv_open(void)
121 {
122 return OPAL_SUCCESS;
123 }
124
125 /* ////////////////////////////////////////////////////////////////////////// */
126 /**
127 * this routine performs a test that indicates whether or not sysv shared
128 * memory can safely be used during this run.
129 * note: that we want to run this test as few times as possible.
130 *
131 * @return OPAL_SUCCESS when sysv can safely be used.
132 */
133 static int
134 sysv_runtime_query(mca_base_module_t **module, int *priority, const char *hint)
135 {
136 char c = 'j';
137 int shmid = -1;
138 char *a = NULL;
139 char *addr = NULL;
140 struct shmid_ds tmp_buff;
141
142 *priority = 0;
143 *module = NULL;
144
145 /* if hint isn't null, then someone else already figured out who is the
146 * best runnable component is AND the caller is relaying that info so we
147 * don't have to perform a run-time query.
148 */
149 if (NULL != hint) {
150 OPAL_OUTPUT_VERBOSE(
151 (70, opal_shmem_base_framework.framework_output,
152 "shmem: sysv: runtime_query: "
153 "attempting to use runtime hint (%s)\n", hint)
154 );
155 /* was i selected? if so, then we are done.
156 * otherwise, disqualify myself.
157 */
158 if (0 == strcasecmp(hint,
159 mca_shmem_sysv_component.super.base_version.mca_component_name)) {
160 *priority = mca_shmem_sysv_component.priority;
161 *module = (mca_base_module_t *)&opal_shmem_sysv_module.super;
162 return OPAL_SUCCESS;
163 }
164 else {
165 *priority = 0;
166 *module = NULL;
167 return OPAL_SUCCESS;
168 }
169 }
170
171 /* if we are here, then let the run-time test games begin */
172 OPAL_OUTPUT_VERBOSE(
173 (70, opal_shmem_base_framework.framework_output,
174 "shmem: sysv: runtime_query: NO HINT PROVIDED:"
175 "starting run-time test...\n")
176 );
177
178 if (-1 == (shmid = shmget(IPC_PRIVATE, (size_t)(opal_getpagesize()),
179 IPC_CREAT | IPC_EXCL | S_IRWXU ))) {
180 goto out;
181 }
182 else if ((void *)-1 == (addr = shmat(shmid, NULL, 0))) {
183 goto out;
184 }
185
186 /* protect against lazy establishment - may not be needed, but can't hurt */
187 a = addr;
188 *a = c;
189
190 if (-1 == shmctl(shmid, IPC_RMID, NULL)) {
191 goto out;
192 }
193 else if (-1 == shmctl(shmid, IPC_STAT, &tmp_buff)) {
194 goto out;
195 }
196 /* all is well - rainbows and butterflies */
197 else {
198 *priority = mca_shmem_sysv_component.priority;
199 *module = (mca_base_module_t *)&opal_shmem_sysv_module.super;
200 }
201
202 out:
203 if (NULL != addr && (char *)-1 != addr) {
204 shmdt(addr);
205 }
206 return OPAL_SUCCESS;
207 }
208
209 /* ////////////////////////////////////////////////////////////////////////// */
210 static int
211 sysv_query(mca_base_module_t **module, int *priority)
212 {
213 *priority = mca_shmem_sysv_component.priority;
214 *module = (mca_base_module_t *)&opal_shmem_sysv_module.super;
215 return OPAL_SUCCESS;
216 }
217