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 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif
21 #ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
23 #endif
24 #ifdef HAVE_SYS_STAT_H
25 #include <sys/stat.h>
26 #endif
27 #ifdef HAVE_FCNTL_H
28 #include <fcntl.h>
29 #endif
30
31 #include <pmix_common.h>
32
33 #include "src/mca/common/dstore/dstore_common.h"
34 #include "src/mca/gds/base/base.h"
35
36 #include "src/util/error.h"
37 #include "src/util/output.h"
38
39 #include "gds_ds12_lock.h"
40
41 #define _ESH_12_FCNTL_LOCK(lockfd, operation) \
42 __pmix_attribute_extension__ ({ \
43 pmix_status_t ret = PMIX_SUCCESS; \
44 int i; \
45 struct flock fl = {0}; \
46 fl.l_type = operation; \
47 fl.l_whence = SEEK_SET; \
48 for(i = 0; i < 10; i++) { \
49 if( 0 > fcntl(lockfd, F_SETLKW, &fl) ) { \
50 switch( errno ){ \
51 case EINTR: \
52 continue; \
53 case ENOENT: \
54 case EINVAL: \
55 ret = PMIX_ERR_NOT_FOUND; \
56 break; \
57 case EBADF: \
58 ret = PMIX_ERR_BAD_PARAM; \
59 break; \
60 case EDEADLK: \
61 case EFAULT: \
62 case ENOLCK: \
63 ret = PMIX_ERR_RESOURCE_BUSY; \
64 break; \
65 default: \
66 ret = PMIX_ERROR; \
67 break; \
68 } \
69 } \
70 break; \
71 } \
72 if (ret) { \
73 pmix_output(0, "%s %d:%s lock failed: %s", \
74 __FILE__, __LINE__, __func__, strerror(errno)); \
75 } \
76 ret; \
77 })
78
79 typedef struct {
80 char *lockfile;
81 int lockfd;
82 } ds12_lock_fcntl_ctx_t;
83
84 pmix_status_t pmix_gds_ds12_lock_init(pmix_common_dstor_lock_ctx_t *ctx, const char *base_path,
85 const char *name, uint32_t local_size, uid_t uid, bool setuid)
86 {
87 pmix_status_t rc = PMIX_SUCCESS;
88 ds12_lock_fcntl_ctx_t *lock_ctx;
89
90 if (*ctx != NULL) {
91 return PMIX_SUCCESS;
92 }
93
94 lock_ctx = (ds12_lock_fcntl_ctx_t*)malloc(sizeof(ds12_lock_fcntl_ctx_t));
95 if (NULL == lock_ctx) {
96 rc = PMIX_ERR_INIT;
97 PMIX_ERROR_LOG(rc);
98 goto error;
99 }
100 *ctx = lock_ctx;
101 memset(lock_ctx, 0, sizeof(ds12_lock_fcntl_ctx_t));
102 lock_ctx->lockfd = -1;
103
104
105
106
107 if(0 > asprintf(&lock_ctx->lockfile, "%s/dstore_sm.lock", base_path)) {
108 rc = PMIX_ERR_OUT_OF_RESOURCE;
109 PMIX_ERROR_LOG(rc);
110 goto error;
111 }
112 PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
113 "%s:%d:%s _lockfile_name: %s", __FILE__, __LINE__, __func__, lock_ctx->lockfile));
114
115 if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) {
116 lock_ctx->lockfd = open(lock_ctx->lockfile, O_CREAT | O_RDWR | O_EXCL, 0600);
117
118
119
120 if (lock_ctx->lockfd < 0) {
121 unlink(lock_ctx->lockfile);
122 lock_ctx->lockfd = open(lock_ctx->lockfile, O_CREAT | O_RDWR, 0600);
123 if (lock_ctx->lockfd < 0) {
124 rc = PMIX_ERROR;
125 PMIX_ERROR_LOG(rc);
126 goto error;
127 }
128 }
129 if (0 != setuid) {
130 if (0 > chown(lock_ctx->lockfile, uid, (gid_t) -1)) {
131 rc = PMIX_ERROR;
132 PMIX_ERROR_LOG(rc);
133 goto error;
134 }
135 if (0 > chmod(lock_ctx->lockfile, S_IRUSR | S_IWGRP | S_IRGRP)) {
136 rc = PMIX_ERROR;
137 PMIX_ERROR_LOG(rc);
138 goto error;
139 }
140 }
141 }
142 else {
143 lock_ctx->lockfd = open(lock_ctx->lockfile, O_RDONLY);
144 if (0 > lock_ctx->lockfd) {
145 rc = PMIX_ERROR;
146 PMIX_ERROR_LOG(rc);
147 goto error;
148 }
149 }
150
151 return rc;
152
153 error:
154 if (NULL != lock_ctx) {
155 if (NULL != lock_ctx->lockfile) {
156 free(lock_ctx->lockfile);
157 }
158 if (0 > lock_ctx->lockfd) {
159 close(lock_ctx->lockfd);
160 if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) {
161 unlink(lock_ctx->lockfile);
162 }
163 }
164 free(lock_ctx);
165 lock_ctx = NULL;
166 }
167 *ctx = NULL;
168
169 return rc;
170 }
171
172 void pmix_ds12_lock_finalize(pmix_common_dstor_lock_ctx_t *lock_ctx)
173 {
174 ds12_lock_fcntl_ctx_t *fcntl_lock = (ds12_lock_fcntl_ctx_t*)*lock_ctx;
175
176 if (NULL == fcntl_lock) {
177 PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND);
178 return;
179 }
180
181 close(fcntl_lock->lockfd);
182
183 if (PMIX_PROC_IS_SERVER(pmix_globals.mypeer)) {
184 unlink(fcntl_lock->lockfile);
185 }
186 free(fcntl_lock);
187 *lock_ctx = NULL;
188 }
189
190 pmix_status_t pmix_ds12_lock_rd_get(pmix_common_dstor_lock_ctx_t lock_ctx)
191 { ds12_lock_fcntl_ctx_t *fcntl_lock = (ds12_lock_fcntl_ctx_t*)lock_ctx;
192 pmix_status_t rc;
193
194 if (NULL == fcntl_lock) {
195 rc = PMIX_ERR_NOT_FOUND;
196 PMIX_ERROR_LOG(rc);
197 return rc;
198 }
199 rc = _ESH_12_FCNTL_LOCK(fcntl_lock->lockfd, F_RDLCK);
200
201 return rc;
202
203 }
204
205 pmix_status_t pmix_ds12_lock_wr_get(pmix_common_dstor_lock_ctx_t lock_ctx)
206 { ds12_lock_fcntl_ctx_t *fcntl_lock = (ds12_lock_fcntl_ctx_t*)lock_ctx;
207 pmix_status_t rc;
208
209 if (NULL == fcntl_lock) {
210 rc = PMIX_ERR_NOT_FOUND;
211 PMIX_ERROR_LOG(rc);
212 return rc;
213 }
214 rc = _ESH_12_FCNTL_LOCK(fcntl_lock->lockfd, F_WRLCK);
215
216 return rc;
217
218 }
219
220 pmix_status_t pmix_ds12_lock_rw_rel(pmix_common_dstor_lock_ctx_t lock_ctx)
221 { ds12_lock_fcntl_ctx_t *fcntl_lock = (ds12_lock_fcntl_ctx_t*)lock_ctx;
222 pmix_status_t rc;
223
224 if (NULL == fcntl_lock) {
225 rc = PMIX_ERR_NOT_FOUND;
226 PMIX_ERROR_LOG(rc);
227 return rc;
228 }
229 rc = _ESH_12_FCNTL_LOCK(fcntl_lock->lockfd, F_UNLCK);
230
231 return rc;
232
233 }