This source file includes following definitions.
- _mmap_init
- _mmap_finalize
- _mmap_segment_create
- _mmap_segment_attach
- _mmap_segment_detach
- _mmap_segment_unlink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <unistd.h>
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <errno.h>
23
24 #include <src/include/pmix_config.h>
25 #include <pmix_common.h>
26 #include "src/include/pmix_globals.h"
27
28
29 #include <src/mca/pshmem/pshmem.h>
30 #include "pshmem_mmap.h"
31
32 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
33 # define MAP_ANONYMOUS MAP_ANON
34 #endif
35
36 static int _mmap_init(void);
37 static void _mmap_finalize(void);
38 static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size);
39 static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode);
40 static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg);
41 static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg);
42
43 pmix_pshmem_base_module_t pmix_mmap_module = {
44 "mmap",
45 _mmap_init,
46 _mmap_finalize,
47 _mmap_segment_create,
48 _mmap_segment_attach,
49 _mmap_segment_detach,
50 _mmap_segment_unlink
51 };
52
53 static int _mmap_init(void)
54 {
55 return PMIX_SUCCESS;
56 }
57
58 static void _mmap_finalize(void)
59 {
60 ;
61 }
62
63 static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size)
64 {
65 int rc = PMIX_SUCCESS;
66 void *seg_addr = MAP_FAILED;
67 pid_t my_pid = getpid();
68
69 _segment_ds_reset(sm_seg);
70
71 if (-1 == (sm_seg->seg_id = open(file_name, O_CREAT | O_RDWR, 0600))) {
72 pmix_output_verbose(2, pmix_globals.debug_output,
73 "sys call open(2) fail\n");
74 rc = PMIX_ERROR;
75 goto out;
76 }
77
78 #ifdef HAVE_POSIX_FALLOCATE
79 if (0 != (rc = posix_fallocate(sm_seg->seg_id, 0, size))) {
80 pmix_output_verbose(2, pmix_globals.debug_output,
81 "sys call posix_fallocate(2) fail\n");
82 if (ENOSPC == rc) {
83 rc = PMIX_ERR_OUT_OF_RESOURCE;
84 goto out;
85 } else if ((ENOTSUP != rc)
86 #ifdef EOPNOTSUPP
87 && (EOPNOTSUPP != rc)
88 #endif
89 ){
90 rc = PMIX_ERROR;
91 goto out;
92 }
93
94
95
96
97 } else {
98 goto map_memory;
99 }
100 #endif
101 if (0 != ftruncate(sm_seg->seg_id, size)) {
102 pmix_output_verbose(2, pmix_globals.debug_output,
103 "sys call ftruncate(2) fail\n");
104 rc = PMIX_ERROR;
105 goto out;
106 } else {
107 rc = PMIX_SUCCESS;
108 }
109
110 #ifdef HAVE_POSIX_FALLOCATE
111 map_memory:
112 #endif
113 if (MAP_FAILED == (seg_addr = mmap(NULL, size,
114 PROT_READ | PROT_WRITE, MAP_SHARED,
115 sm_seg->seg_id, 0))) {
116 pmix_output_verbose(2, pmix_globals.debug_output,
117 "sys call mmap(2) fail\n");
118 rc = PMIX_ERROR;
119 goto out;
120 }
121 sm_seg->seg_cpid = my_pid;
122 sm_seg->seg_size = size;
123 sm_seg->seg_base_addr = (unsigned char *)seg_addr;
124 pmix_strncpy(sm_seg->seg_name, file_name, PMIX_PATH_MAX);
125
126 out:
127 if (-1 != sm_seg->seg_id) {
128 if (0 != close(sm_seg->seg_id)) {
129 pmix_output_verbose(2, pmix_globals.debug_output,
130 "sys call close(2) fail\n");
131 rc = PMIX_ERROR;
132 }
133 }
134
135 if (PMIX_SUCCESS != rc) {
136 if (MAP_FAILED != seg_addr) {
137 munmap((void *)seg_addr, size);
138 }
139 _segment_ds_reset(sm_seg);
140 }
141 return rc;
142 }
143
144 static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode)
145 {
146 mode_t mode = O_RDWR;
147 int mmap_prot = PROT_READ | PROT_WRITE;
148
149 if (sm_mode == PMIX_PSHMEM_RONLY) {
150 mode = O_RDONLY;
151 mmap_prot = PROT_READ;
152 }
153
154 if (-1 == (sm_seg->seg_id = open(sm_seg->seg_name, mode))) {
155 return PMIX_ERROR;
156 }
157 if (MAP_FAILED == (sm_seg->seg_base_addr = (unsigned char *)
158 mmap(NULL, sm_seg->seg_size,
159 mmap_prot, MAP_SHARED,
160 sm_seg->seg_id, 0))) {
161
162
163
164 pmix_output_verbose(2, pmix_globals.debug_output,
165 "sys call mmap(2) fail\n");
166 close(sm_seg->seg_id);
167 return PMIX_ERROR;
168 }
169
170
171
172
173 if (0 != close(sm_seg->seg_id)) {
174 pmix_output_verbose(2, pmix_globals.debug_output,
175 "sys call close(2) fail\n");
176 }
177 sm_seg->seg_cpid = 0;
178 return PMIX_SUCCESS;
179 }
180
181 static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg)
182 {
183 int rc = PMIX_SUCCESS;
184
185 if (0 != munmap((void *)sm_seg->seg_base_addr, sm_seg->seg_size)) {
186 pmix_output_verbose(2, pmix_globals.debug_output,
187 "sys call munmap(2) fail\n");
188 rc = PMIX_ERROR;
189 }
190
191
192
193 _segment_ds_reset(sm_seg);
194 return rc;
195 }
196
197 static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg)
198 {
199 if (-1 == unlink(sm_seg->seg_name)) {
200 pmix_output_verbose(2, pmix_globals.debug_output,
201 "sys call unlink(2) fail\n");
202 return PMIX_ERROR;
203 }
204
205 sm_seg->seg_id = PMIX_SHMEM_DS_ID_INVALID;
206 return PMIX_SUCCESS;
207 }