blob: c04982de85a0c37c9766c90863b40caf288e657d [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "ssvm.h"
Dave Wallace19296112017-08-31 15:54:11 -040016#include "svm_common.h"
Ed Warnickecb9cada2015-12-08 15:45:58 -070017
Dave Barach8a7fb0c2016-07-08 14:44:23 -040018int
19ssvm_master_init (ssvm_private_t * ssvm, u32 master_index)
Ed Warnickecb9cada2015-12-08 15:45:58 -070020{
Dave Wallace19296112017-08-31 15:54:11 -040021 svm_main_region_t *smr = svm_get_root_rp ()->data_base;
Ed Warnickecb9cada2015-12-08 15:45:58 -070022 int ssvm_fd;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040023 u8 *ssvm_filename;
Ed Warnickecb9cada2015-12-08 15:45:58 -070024 u8 junk = 0;
25 int flags;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040026 ssvm_shared_header_t *sh;
27 u64 ticks = clib_cpu_time_now ();
Ed Warnickecb9cada2015-12-08 15:45:58 -070028 u64 randomize_baseva;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040029 void *oldheap;
Ed Warnickecb9cada2015-12-08 15:45:58 -070030
31 if (ssvm->ssvm_size == 0)
32 return SSVM_API_ERROR_NO_SIZE;
33
Dave Wallaced756b352017-07-03 13:11:38 -040034 if (CLIB_DEBUG > 1)
35 clib_warning ("[%d] creating segment '%s'", getpid (), ssvm->name);
36
Dave Wallaceb8856642017-07-31 13:33:11 -040037 ASSERT (vec_c_string_is_terminated (ssvm->name));
Ed Warnickecb9cada2015-12-08 15:45:58 -070038 ssvm_filename = format (0, "/dev/shm/%s%c", ssvm->name, 0);
39
40 unlink ((char *) ssvm_filename);
41
Dave Barach8a7fb0c2016-07-08 14:44:23 -040042 vec_free (ssvm_filename);
Ed Warnickecb9cada2015-12-08 15:45:58 -070043
Dave Barach8a7fb0c2016-07-08 14:44:23 -040044 ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR | O_CREAT | O_EXCL, 0777);
Ed Warnickecb9cada2015-12-08 15:45:58 -070045
46 if (ssvm_fd < 0)
47 {
48 clib_unix_warning ("create segment '%s'", ssvm->name);
49 return SSVM_API_ERROR_CREATE_FAILURE;
50 }
51
Dave Wallace19296112017-08-31 15:54:11 -040052 if (fchmod (ssvm_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
53 clib_unix_warning ("ssvm segment chmod");
54 if (fchown (ssvm_fd, smr->uid, smr->gid) < 0)
55 clib_unix_warning ("ssvm segment chown");
56
Dave Barach56faee82016-08-04 18:58:05 -040057 if (lseek (ssvm_fd, ssvm->ssvm_size, SEEK_SET) < 0)
58 {
59 clib_unix_warning ("lseek");
60 close (ssvm_fd);
61 return SSVM_API_ERROR_SET_SIZE;
62 }
Ed Warnicke853e7202016-08-12 11:42:26 -070063
Dave Barach8a7fb0c2016-07-08 14:44:23 -040064 if (write (ssvm_fd, &junk, 1) != 1)
Ed Warnickecb9cada2015-12-08 15:45:58 -070065 {
66 clib_unix_warning ("set ssvm size");
Dave Barach8a7fb0c2016-07-08 14:44:23 -040067 close (ssvm_fd);
Ed Warnickecb9cada2015-12-08 15:45:58 -070068 return SSVM_API_ERROR_SET_SIZE;
69 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -040070
Ed Warnickecb9cada2015-12-08 15:45:58 -070071 flags = MAP_SHARED;
72 if (ssvm->requested_va)
73 flags |= MAP_FIXED;
74
75 randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;
76
77 if (ssvm->requested_va)
78 ssvm->requested_va += randomize_baseva;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040079
80 sh = ssvm->sh =
81 (ssvm_shared_header_t *) mmap ((void *) ssvm->requested_va,
82 ssvm->ssvm_size, PROT_READ | PROT_WRITE,
83 flags, ssvm_fd, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -070084
Christophe Fontainefef15b42016-04-09 12:38:49 +090085 if (ssvm->sh == MAP_FAILED)
Ed Warnickecb9cada2015-12-08 15:45:58 -070086 {
87 clib_unix_warning ("mmap");
Dave Barach8a7fb0c2016-07-08 14:44:23 -040088 close (ssvm_fd);
Ed Warnickecb9cada2015-12-08 15:45:58 -070089 return SSVM_API_ERROR_MMAP;
90 }
91
Dave Barach8a7fb0c2016-07-08 14:44:23 -040092 close (ssvm_fd);
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Dave Barach8a7fb0c2016-07-08 14:44:23 -040094 ssvm->my_pid = getpid ();
Ed Warnickecb9cada2015-12-08 15:45:58 -070095 sh->master_pid = ssvm->my_pid;
96 sh->ssvm_size = ssvm->ssvm_size;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040097 sh->heap = mheap_alloc_with_flags
98 (((u8 *) sh) + MMAP_PAGESIZE, ssvm->ssvm_size - MMAP_PAGESIZE,
Ed Warnickecb9cada2015-12-08 15:45:58 -070099 MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE);
100
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400101 sh->ssvm_va = pointer_to_uword (sh);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 sh->master_index = master_index;
103
104 oldheap = ssvm_push_heap (sh);
105 sh->name = format (0, "%s%c", ssvm->name, 0);
106 ssvm_pop_heap (oldheap);
107
108 ssvm->i_am_master = 1;
109
110 /* The application has to set set sh->ready... */
111 return 0;
112}
113
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400114int
115ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400117 struct stat stat;
118 int ssvm_fd = -1;
119 ssvm_shared_header_t *sh;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120
Dave Wallaceb8856642017-07-31 13:33:11 -0400121 ASSERT (vec_c_string_is_terminated (ssvm->name));
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400122 ssvm->i_am_master = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400124 while (timeout_in_seconds-- > 0)
125 {
126 if (ssvm_fd < 0)
127 ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR, 0777);
128 if (ssvm_fd < 0)
129 {
130 sleep (1);
131 continue;
132 }
133 if (fstat (ssvm_fd, &stat) < 0)
134 {
135 sleep (1);
136 continue;
137 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700138
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400139 if (stat.st_size > 0)
140 goto map_it;
141 }
142 clib_warning ("slave timeout");
143 return SSVM_API_ERROR_SLAVE_TIMEOUT;
144
145map_it:
146 sh = (void *) mmap (0, MMAP_PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
147 ssvm_fd, 0);
148 if (sh == MAP_FAILED)
149 {
150 clib_unix_warning ("slave research mmap");
151 close (ssvm_fd);
152 return SSVM_API_ERROR_MMAP;
153 }
154
155 while (timeout_in_seconds-- > 0)
156 {
157 if (sh->ready)
158 goto re_map_it;
159 }
160 close (ssvm_fd);
161 munmap (sh, MMAP_PAGESIZE);
162 clib_warning ("slave timeout 2");
163 return SSVM_API_ERROR_SLAVE_TIMEOUT;
164
165re_map_it:
166 ssvm->requested_va = (u64) sh->ssvm_va;
167 ssvm->ssvm_size = sh->ssvm_size;
168 munmap (sh, MMAP_PAGESIZE);
169
170 sh = ssvm->sh = (void *) mmap ((void *) ssvm->requested_va, ssvm->ssvm_size,
171 PROT_READ | PROT_WRITE,
172 MAP_SHARED | MAP_FIXED, ssvm_fd, 0);
173
174 if (sh == MAP_FAILED)
175 {
176 clib_unix_warning ("slave final mmap");
177 close (ssvm_fd);
178 return SSVM_API_ERROR_MMAP;
179 }
180 sh->slave_pid = getpid ();
181 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182}
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400183
Dave Barach68b0fb02017-02-28 15:15:56 -0500184void
185ssvm_delete (ssvm_private_t * ssvm)
186{
187 u8 *fn;
188
189 fn = format (0, "/dev/shm/%s%c", ssvm->name, 0);
190
Dave Wallaced756b352017-07-03 13:11:38 -0400191 if (CLIB_DEBUG > 1)
192 clib_warning ("[%d] unlinking ssvm (%s) backing file '%s'", getpid (),
193 ssvm->name, fn);
194
Dave Barach68b0fb02017-02-28 15:15:56 -0500195 /* Throw away the backing file */
196 if (unlink ((char *) fn) < 0)
197 clib_unix_warning ("unlink segment '%s'", ssvm->name);
198
Dave Barach68b0fb02017-02-28 15:15:56 -0500199 vec_free (fn);
Dave Wallaced756b352017-07-03 13:11:38 -0400200 vec_free (ssvm->name);
201
202 munmap ((void *) ssvm->requested_va, ssvm->ssvm_size);
Dave Barach68b0fb02017-02-28 15:15:56 -0500203}
204
205
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400206/*
207 * fd.io coding-style-patch-verification: ON
208 *
209 * Local Variables:
210 * eval: (c-set-style "gnu")
211 * End:
212 */