This source file includes following definitions.
- pmix_gds_ds12_lock_init
- pmix_ds12_lock_finalize
- pmix_ds12_lock_rd_get
- pmix_ds12_lock_wr_get
- pmix_ds12_lock_rw_rel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <src/include/pmix_config.h>
17
18 #include <stdio.h>
19 #ifdef HAVE_UNISTD_H
20 #include <unistd.h>
21 #endif
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #ifdef HAVE_SYS_STAT_H
26 #include <sys/stat.h>
27 #endif
28
29 #include <pmix_common.h>
30
31 #include "src/mca/common/dstore/dstore_common.h"
32 #include "src/mca/gds/base/base.h"
33 #include "src/mca/pshmem/pshmem.h"
34
35 #include "src/util/error.h"
36 #include "src/util/output.h"
37
38 #include "gds_ds12_lock.h"
39 #include "src/mca/common/dstore/dstore_segment.h"
40
41 #define _ESH_12_PTHREAD_LOCK(rwlock, func) \
42 __pmix_attribute_extension__ ({ \
43 pmix_status_t ret = PMIX_SUCCESS; \
44 int rc; \
45 rc = pthread_rwlock_##func(rwlock); \
46 if (0 != rc) { \
47 switch (errno) { \
48 case EINVAL: \
49 ret = PMIX_ERR_INIT; \
50 break; \
51 case EPERM: \
52 ret = PMIX_ERR_NO_PERMISSIONS; \
53 break; \
54 } \
55 } \
56 if (ret) { \
57 pmix_output(0, "%s %d:%s lock failed: %s", \
58 __FILE__, __LINE__, __func__, strerror(errno)); \
59 } \
60 ret; \
61 })
62
63 typedef struct {
64 char *lockfile;
65 pmix_pshmem_seg_t *segment;
66 pthread_rwlock_t *rwlock;
67 } ds12_lock_pthread_ctx_t;
68
69 pmix_status_t pmix_gds_ds12_lock_init(pmix_common_dstor_lock_ctx_t *ctx, const char *base_path,
70 const char * name, uint32_t local_size, uid_t uid, bool setuid)
71 {
72 size_t size = pmix_common_dstor_getpagesize();
73 pmix_status_t rc = PMIX_SUCCESS;
74 pthread_rwlockattr_t attr;
75 ds12_lock_pthread_ctx_t *lock_ctx = (ds12_lock_pthread_ctx_t*)ctx;
76
77 if (*ctx != NULL) {
78 return PMIX_SUCCESS;
79 }
80
81 lock_ctx = (ds12_lock_pthread_ctx_t*)malloc(sizeof(ds12_lock_pthread_ctx_t));
82 if (NULL == lock_ctx) {
83 rc = PMIX_ERR_INIT;
84 PMIX_ERROR_LOG(rc);
85 goto error;
86 }
87 memset(lock_ctx, 0, sizeof(ds12_lock_pthread_ctx_t));
88 *ctx = (pmix_common_dstor_lock_ctx_t*)lock_ctx;
89
90 lock_ctx->segment = (pmix_pshmem_seg_t *)malloc(sizeof(pmix_pshmem_seg_t));
91 if (NULL == lock_ctx->segment) {
92 rc = PMIX_ERR_OUT_OF_RESOURCE;
93 PMIX_ERROR_LOG(rc);
94 goto error;
95 }
96
97
98
99
100 if(0 > asprintf(&lock_ctx->lockfile, "%s/dstore_sm.lock", base_path)) {
101 rc = PMIX_ERR_OUT_OF_RESOURCE;
102 PMIX_ERROR_LOG(rc);
103 goto error;
104 }
105 PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
106 "%s:%d:%s _lockfile_name: %s", __FILE__, __LINE__, __func__, lock_ctx->lockfile));
107
108 if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) {
109 if (PMIX_SUCCESS != (rc = pmix_pshmem.segment_create(lock_ctx->segment,
110 lock_ctx->lockfile, size))) {
111 PMIX_ERROR_LOG(rc);
112 goto error;
113 }
114 memset(lock_ctx->segment->seg_base_addr, 0, size);
115 if (0 != setuid) {
116 if (0 > chown(lock_ctx->lockfile, (uid_t) uid, (gid_t) -1)){
117 rc = PMIX_ERROR;
118 PMIX_ERROR_LOG(rc);
119 goto error;
120 }
121
122 if (0 > chmod(lock_ctx->lockfile, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP )) {
123 rc = PMIX_ERROR;
124 PMIX_ERROR_LOG(rc);
125 goto error;
126 }
127 }
128 lock_ctx->rwlock = (pthread_rwlock_t *)lock_ctx->segment->seg_base_addr;
129
130 if (0 != pthread_rwlockattr_init(&attr)) {
131 rc = PMIX_ERROR;
132 PMIX_ERROR_LOG(rc);
133 goto error;
134 }
135 if (0 != pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
136 pthread_rwlockattr_destroy(&attr);
137 rc = PMIX_ERR_INIT;
138 PMIX_ERROR_LOG(rc);
139 goto error;
140 }
141 #ifdef HAVE_PTHREAD_SETKIND
142 if (0 != pthread_rwlockattr_setkind_np(&attr,
143 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) {
144 pthread_rwlockattr_destroy(&attr);
145 PMIX_ERROR_LOG(PMIX_ERR_INIT);
146 goto error;
147 }
148 #endif
149 if (0 != pthread_rwlock_init(lock_ctx->rwlock, &attr)) {
150 pthread_rwlockattr_destroy(&attr);
151 PMIX_ERROR_LOG(PMIX_ERR_INIT);
152 goto error;
153 }
154 if (0 != pthread_rwlockattr_destroy(&attr)) {
155 PMIX_ERROR_LOG(PMIX_ERR_INIT);
156 goto error;
157 }
158
159 }
160 else {
161 lock_ctx->segment->seg_size = size;
162 snprintf(lock_ctx->segment->seg_name, PMIX_PATH_MAX, "%s", lock_ctx->lockfile);
163 if (PMIX_SUCCESS != (rc = pmix_pshmem.segment_attach(lock_ctx->segment,
164 PMIX_PSHMEM_RW))) {
165 PMIX_ERROR_LOG(rc);
166 goto error;
167 }
168 lock_ctx->rwlock = (pthread_rwlock_t *)lock_ctx->segment->seg_base_addr;
169 }
170
171 return PMIX_SUCCESS;
172
173 error:
174 if (NULL != lock_ctx) {
175 if (lock_ctx->segment) {
176
177 if (lock_ctx->segment->seg_cpid == getpid()) {
178 pmix_pshmem.segment_unlink(lock_ctx->segment);
179 }
180 pmix_pshmem.segment_detach(lock_ctx->segment);
181 lock_ctx->rwlock = NULL;
182 }
183 if (NULL != lock_ctx->lockfile) {
184 free(lock_ctx->lockfile);
185 }
186 free(lock_ctx);
187 *ctx = (pmix_common_dstor_lock_ctx_t*)NULL;
188 }
189
190 return rc;
191 }
192
193 void pmix_ds12_lock_finalize(pmix_common_dstor_lock_ctx_t *lock_ctx)
194 {
195 ds12_lock_pthread_ctx_t *pthread_lock =
196 (ds12_lock_pthread_ctx_t*)*lock_ctx;
197
198 if (NULL == pthread_lock) {
199 PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND);
200 return;
201 }
202 if (0 != pthread_rwlock_destroy(pthread_lock->rwlock)) {
203 PMIX_ERROR_LOG(PMIX_ERROR);
204 return;
205 }
206
207 if (NULL == pthread_lock->segment) {
208 PMIX_ERROR_LOG(PMIX_ERROR);
209 return;
210 }
211 if (NULL == pthread_lock->lockfile) {
212 PMIX_ERROR_LOG(PMIX_ERROR);
213 return;
214 }
215
216
217 if (pthread_lock->segment->seg_cpid == getpid()) {
218 pmix_pshmem.segment_unlink(pthread_lock->segment);
219 }
220 pmix_pshmem.segment_detach(pthread_lock->segment);
221
222 free(pthread_lock->segment);
223 pthread_lock->segment = NULL;
224 free(pthread_lock->lockfile);
225 pthread_lock->lockfile = NULL;
226 pthread_lock->rwlock = NULL;
227 free(pthread_lock);
228 *lock_ctx = NULL;
229 }
230
231 pmix_status_t pmix_ds12_lock_rd_get(pmix_common_dstor_lock_ctx_t lock_ctx)
232 {
233 ds12_lock_pthread_ctx_t *pthread_lock = (ds12_lock_pthread_ctx_t*)lock_ctx;
234 pmix_status_t rc;
235
236 if (NULL == pthread_lock) {
237 rc = PMIX_ERR_NOT_FOUND;
238 PMIX_ERROR_LOG(rc);
239 return rc;
240 }
241 rc = _ESH_12_PTHREAD_LOCK(pthread_lock->rwlock, rdlock);
242
243 return rc;
244 }
245
246 pmix_status_t pmix_ds12_lock_wr_get(pmix_common_dstor_lock_ctx_t lock_ctx)
247 {
248 ds12_lock_pthread_ctx_t *pthread_lock = (ds12_lock_pthread_ctx_t*)lock_ctx;
249 pmix_status_t rc;
250
251 if (NULL == pthread_lock) {
252 rc = PMIX_ERR_NOT_FOUND;
253 PMIX_ERROR_LOG(rc);
254 return rc;
255 }
256 rc = _ESH_12_PTHREAD_LOCK(pthread_lock->rwlock, wrlock);
257
258 return rc;
259 }
260
261 pmix_status_t pmix_ds12_lock_rw_rel(pmix_common_dstor_lock_ctx_t lock_ctx)
262 {
263 ds12_lock_pthread_ctx_t *pthread_lock = (ds12_lock_pthread_ctx_t*)lock_ctx;
264 pmix_status_t rc;
265
266 if (NULL == pthread_lock) {
267 rc = PMIX_ERR_NOT_FOUND;
268 PMIX_ERROR_LOG(rc);
269 return rc;
270 }
271 rc = _ESH_12_PTHREAD_LOCK(pthread_lock->rwlock, unlock);
272
273 return rc;
274 }