All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_shm_cluster.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2017 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_config.h>
20 #include <aerospike/as_partition.h>
21 #include <citrusleaf/cf_queue.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 // Concurrency kit needs to be under extern "C" when compiling C++.
28 #include <aerospike/ck/ck_spinlock.h>
29 #include <aerospike/ck/ck_swlock.h>
30 
31 /******************************************************************************
32  * TYPES
33  *****************************************************************************/
34 
35 /**
36  * @private
37  * Shared memory representation of node. 48 bytes.
38  */
39 typedef struct as_node_shm_s {
40  /**
41  * @private
42  * Node name.
43  */
44  char name[AS_NODE_NAME_SIZE];
45 
46  /**
47  * @private
48  * Lightweight node read/write lock.
49  */
50  ck_swlock_t lock;
51 
52  /**
53  * @private
54  * Socket address.
55  */
56  struct sockaddr_storage addr;
57 
58  /**
59  * @private
60  * TLS certificate name (needed for TLS only).
61  */
62  char tls_name[AS_HOSTNAME_SIZE];
63 
64  /**
65  * @private
66  * Features supported by server. Stored in bitmap.
67  */
68  uint32_t features;
69 
70  /**
71  * @private
72  * Is node currently active.
73  */
74  uint8_t active;
75 
76  /**
77  * @private
78  * Pad to 8 byte boundary.
79  */
80  char pad[3];
81 } as_node_shm;
82 
83 /**
84  * @private
85  * Shared memory representation of map of namespace data partitions to nodes. 8 bytes.
86  */
87 typedef struct as_partition_shm_s {
88  /**
89  * @private
90  * Master node index offset.
91  */
92  uint32_t master;
93 
94  /**
95  * @private
96  * Prole node index offset.
97  */
98  uint32_t prole;
99 
100  /**
101  * @private
102  * Current regime for CP mode.
103  */
104  uint32_t regime;
105 
106  /**
107  * @private
108  * Pad to 8 byte boundary.
109  */
110  uint32_t pad;
112 
113 /**
114  * @private
115  * Shared memory representation of map of namespace to data partitions. 32 bytes + partitions size.
116  */
117 typedef struct as_partition_table_shm_s {
118  /**
119  * @private
120  * Namespace name.
121  */
123 
124  /**
125  * @private
126  * Is namespace running in CP mode.
127  */
128  uint8_t cp_mode;
129 
130  /**
131  * @private
132  * Pad to 8 byte boundary.
133  */
134  char pad[7];
135 
136  /**
137  * @private
138  * Array of partitions for a given namespace.
139  */
140  as_partition_shm partitions[];
142 
143 /**
144  * @private
145  * Shared memory cluster map. The map contains fixed arrays of nodes and partition tables.
146  * Each partition table contains a fixed array of partitions. The shared memory segment will be
147  * sized on startup and never change afterwards. If the max nodes or max namespaces are reached,
148  * the tender client will ignore additional nodes/namespaces and log an error message that the
149  * corresponding array is full.
150  */
151 typedef struct as_cluster_shm_s {
152  /**
153  * @private
154  * Last time cluster was tended in milliseconds since epoch.
155  */
156  uint64_t timestamp;
157 
158  /**
159  * @private
160  * Cluster tend owner process id.
161  */
162  uint32_t owner_pid;
163 
164  /**
165  * @private
166  * Current size of nodes array.
167  */
168  uint32_t nodes_size;
169 
170  /**
171  * @private
172  * Maximum size of nodes array.
173  */
174  uint32_t nodes_capacity;
175 
176  /**
177  * @private
178  * Nodes generation count. Incremented whenever a node is added or removed from cluster.
179  */
180  uint32_t nodes_gen;
181 
182  /**
183  * @private
184  * Total number of data partitions used by cluster.
185  */
186  uint32_t n_partitions;
187 
188  /**
189  * @private
190  * Current size of partition tables array.
191  */
193 
194  /**
195  * @private
196  * Maximum size of partition tables array.
197  */
199 
200  /**
201  * @private
202  * Cluster offset to partition tables at the end of this structure.
203  */
205 
206  /**
207  * @private
208  * Bytes required to hold one partition_table.
209  */
211 
212  /**
213  * @private
214  * Spin lock for taking over from a dead cluster tender.
215  */
216  ck_spinlock_t take_over_lock;
217 
218  /**
219  * @private
220  * Shared memory master mutex lock. Used to determine cluster tend owner.
221  */
222  uint8_t lock;
223 
224  /**
225  * @private
226  * Has shared memory been fully initialized and populated.
227  */
228  uint8_t ready;
229 
230  /**
231  * @private
232  * Pad to 8 byte boundary.
233  */
234  char pad[6];
235 
236  /*
237  * @private
238  * Dynamically allocated node array.
239  */
240  as_node_shm nodes[];
241 
242  // This is where the dynamically allocated partition tables are located.
244 
245 /**
246  * @private
247  * Local data related to shared memory implementation.
248  */
249 typedef struct as_shm_info_s {
250  /**
251  * @private
252  * Pointer to cluster shared memory.
253  */
255 
256  /**
257  * @private
258  * Array of pointers to local nodes.
259  * Array index offsets are synchronized with shared memory node offsets.
260  */
262 
263  /**
264  * @private
265  * Shared memory identifier.
266  */
267  int shm_id;
268 
269  /**
270  * @private
271  * Take over shared memory cluster tending if the cluster hasn't been tended by this
272  * millisecond threshold.
273  */
275 
276  /**
277  * @private
278  * Is this process responsible for performing cluster tending.
279  */
280  volatile bool is_tend_master;
281 } as_shm_info;
282 
283 /******************************************************************************
284  * FUNCTIONS
285  ******************************************************************************/
286 
287 /**
288  * @private
289  * Create shared memory implementation of cluster.
290  */
291 as_status
292 as_shm_create(struct as_cluster_s* cluster, as_error* err, as_config* config);
293 
294 /**
295  * @private
296  * Destroy shared memory components.
297  */
298 void
299 as_shm_destroy(struct as_cluster_s* cluster);
300 
301 /**
302  * @private
303  * Add nodes to shared memory.
304  */
305 void
306 as_shm_add_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_add);
307 
308 /**
309  * @private
310  * Remove nodes from shared memory.
311  */
312 void
313 as_shm_remove_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_remove);
314 
315 /**
316  * @private
317  * Determine if node exists in shared memory partition map.
318  */
319 bool
321 
322 /**
323  * @private
324  * Find partition table for namespace in shared memory.
325  */
327 as_shm_find_partition_table(as_cluster_shm* cluster_shm, const char* ns);
328 
329 /**
330  * @private
331  * Update shared memory partition tables for given namespace.
332  */
333 void
334 as_shm_update_partitions(as_shm_info* shm_info, const char* ns, char* bitmap_b64, int64_t len, as_node* node, bool master, uint32_t regime);
335 
336 /**
337  * @private
338  * Get shared memory mapped node given digest key. If there is no mapped node, another node is used based on replica.
339  * If successful, as_nodes_release() must be called when done with node.
340  */
341 as_status
342 as_shm_cluster_get_node(struct as_cluster_s* cluster, as_error* err, const char* ns, const uint8_t* digest, as_policy_replica replica, bool use_master, as_node** node_pp);
343 
344 /**
345  * @private
346  * Get shared memory mapped node given partition.
347  * as_nodes_release() must be called when done with node.
348  */
349 as_node*
350 as_partition_shm_get_node(struct as_cluster_s* cluster, as_partition_shm* p, as_policy_replica replica, bool use_master, bool cp_mode);
351 
352 /**
353  * @private
354  * Get shared memory partition tables array.
355  */
356 static inline as_partition_table_shm*
358 {
359  return (as_partition_table_shm*) ((char*)cluster_shm + cluster_shm->partition_tables_offset);
360 }
361 
362 /**
363  * @private
364  * Get partition table identified by index.
365  */
366 static inline as_partition_table_shm*
368 {
369  return (as_partition_table_shm*) ((char*)tables + (cluster_shm->partition_table_byte_size * index));
370 }
371 
372 /**
373  * @private
374  * Get next partition table in array.
375  */
376 static inline as_partition_table_shm*
378 {
379  return (as_partition_table_shm*) ((char*)table + cluster_shm->partition_table_byte_size);
380 }
381 
382 #ifdef __cplusplus
383 } // end extern "C"
384 #endif