1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      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,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 /***************************************************************************
19  * Description: Shared Memory object header file                           *
20  * Author:      Mladen Turk <mturk@jboss.com>                              *
21  * Author:      Rainer Jung <rjung@apache.org>                             *
22  ***************************************************************************/
23 #ifndef _JK_SHM_H
24 #define _JK_SHM_H
25 
26 #include "jk_global.h"
27 #include "jk_pool.h"
28 #include "jk_util.h"
29 
30 #ifdef __cplusplus
31 extern "C"
32 {
33 #endif                          /* __cplusplus */
34 
35 /**
36  * @file jk_shm.h
37  * @brief Jk shared memory management
38  *
39  *
40  */
41 
42 #define JK_SHM_MAJOR    '1'
43 #define JK_SHM_MINOR    '3'
44 #define JK_SHM_STR_SIZ  (JK_ALIGN(JK_MAX_NAME_LEN + 1, 8))
45 #define JK_SHM_MAGIC    '!', 'J', 'K', 'S', 'H', 'M', JK_SHM_MAJOR, JK_SHM_MINOR
46 #define JK_SHM_MAGIC_SIZ  8
47 
48 /* XXX: Check if adding struct members for overflow */
49 #define JK_SHM_SLOT_SIZE          384
50 /* Really huge numbers, but 64 workers should be enough */
51 #define JK_SHM_DEF_WORKERS        64
52 #define JK_SHM_ALIGNMENT          JK_SHM_SLOT_SIZE
53 #define JK_SHM_ALIGN(x)           JK_ALIGN((x), JK_SHM_ALIGNMENT)
54 #define JK_SHM_MIN_SIZE           ((JK_SHM_SLOT_SIZE * JK_SHM_DEF_WORKERS * 3) + JK_SHM_ALIGNMENT)
55 
56 /** jk shm generic worker record structure */
57 struct jk_shm_worker_header
58 {
59     /* Shared memory slot id */
60     int     id;
61     /* JK_XXX_WORKER_TYPE */
62     int     type;
63     /* worker name */
64     char    name[JK_SHM_STR_SIZ];
65     /* parent slot id.
66      * Zero in case worker does not belong to balancer.
67      */
68     int     parent_id;
69     /* Sequence counter starting at 0 and increasing
70      * every time we change the config.
71      */
72     volatile unsigned int sequence;
73 };
74 typedef struct jk_shm_worker_header jk_shm_worker_header_t;
75 
76 /** jk shm ajp13/ajp14 worker record structure */
77 struct jk_shm_ajp_worker
78 {
79     jk_shm_worker_header_t h;
80     char host[JK_SHM_STR_SIZ];
81     int port;
82     volatile int addr_sequence;
83 
84     /* Configuration data mirrored from ajp_worker */
85     int cache_timeout;
86     int connect_timeout;
87     int ping_timeout;
88     int reply_timeout;
89     int prepost_timeout;
90     unsigned int recovery_opts;
91     int retries;
92     int retry_interval;
93     int busy_limit;
94     unsigned int max_packet_size;
95     /* current error state (runtime) of the worker */
96     volatile int state;
97     /* Statistical data */
98     /* Number of currently connected channels */
99     volatile int connected;
100     /* Maximum number of connected channels */
101     volatile int max_connected;
102     /* Number of currently busy channels */
103     volatile int busy;
104     /* Maximum number of busy channels */
105     volatile int max_busy;
106     volatile time_t error_time;
107     /* Number of bytes read from remote */
108     volatile jk_uint64_t readed;
109     /* Number of bytes transferred to remote */
110     volatile jk_uint64_t transferred;
111     /* Number of times the worker was used */
112     volatile jk_uint64_t  used;
113     /* Number of times the worker was used - snapshot during maintenance */
114     volatile jk_uint64_t  used_snapshot;
115     /* Number of non 200 responses */
116     volatile jk_uint32_t  errors;
117     /* Decayed number of reply_timeout errors */
118     volatile jk_uint32_t  reply_timeouts;
119     /* Number of client errors */
120     volatile jk_uint32_t  client_errors;
121     /* Last reset time */
122     volatile time_t last_reset;
123     volatile time_t last_maintain_time;
124 };
125 typedef struct jk_shm_ajp_worker jk_shm_ajp_worker_t;
126 
127 /** jk shm lb sub worker record structure */
128 struct jk_shm_lb_sub_worker
129 {
130     jk_shm_worker_header_t h;
131 
132     /* route */
133     char    route[JK_SHM_STR_SIZ];
134     /* worker domain */
135     char    domain[JK_SHM_STR_SIZ];
136     /* worker redirect route */
137     char    redirect[JK_SHM_STR_SIZ];
138     /* worker distance */
139     volatile int distance;
140     /* current activation state (config) of the worker */
141     volatile int activation;
142     /* current error state (runtime) of the worker */
143     volatile int state;
144     /* Current lb factor */
145     volatile int lb_factor;
146     /* Current lb reciprocal factor */
147     volatile jk_uint64_t lb_mult;
148     /* Current lb value  */
149     volatile jk_uint64_t lb_value;
150     /* First consecutive error time */
151     volatile time_t first_error_time;
152     /* Last consecutive error time */
153     volatile time_t last_error_time;
154     /* Number of times the worker was elected - snapshot during maintenance */
155     volatile jk_uint64_t  elected_snapshot;
156     /* Number of non-sticky requests handled, that were not marked as stateless */
157     volatile jk_uint64_t  sessions;
158     /* Number of non 200 responses */
159     volatile jk_uint32_t  errors;
160 };
161 typedef struct jk_shm_lb_sub_worker jk_shm_lb_sub_worker_t;
162 
163 /** jk shm lb worker record structure */
164 struct jk_shm_lb_worker
165 {
166     jk_shm_worker_header_t h;
167 
168     /* Number of currently busy channels */
169     volatile int busy;
170     /* Maximum number of busy channels */
171     volatile int max_busy;
172     int     sticky_session;
173     int     sticky_session_force;
174     int     recover_wait_time;
175     int     error_escalation_time;
176     int     max_reply_timeouts;
177     int     retries;
178     int     retry_interval;
179     int     lbmethod;
180     int     lblock;
181     unsigned int max_packet_size;
182     /* Last reset time */
183     volatile time_t last_reset;
184     volatile time_t last_maintain_time;
185 };
186 typedef struct jk_shm_lb_worker jk_shm_lb_worker_t;
187 
188 const char *jk_shm_name(void);
189 
190 /* Calculate needed shm size */
191 int jk_shm_calculate_size(jk_map_t *init_data, jk_logger_t *l);
192 
193 /* Open the shared memory creating file if needed
194  */
195 int jk_shm_open(const char *fname, int sz, jk_logger_t *l);
196 
197 /* Close the shared memory
198  */
199 void jk_shm_close(jk_logger_t *l);
200 
201 /* Attach the shared memory in child process.
202  * File has to be opened in parent.
203  */
204 int jk_shm_attach(const char *fname, int sz, jk_logger_t *l);
205 
206 /* allocate shm ajp worker record
207  * If there is no shm present the pool will be used instead
208  */
209 jk_shm_ajp_worker_t *jk_shm_alloc_ajp_worker(jk_pool_t *p, const char *name,
210                                              jk_logger_t *l);
211 
212 /* allocate shm lb sub worker record
213  * If there is no shm present the pool will be used instead
214  */
215 jk_shm_lb_sub_worker_t *jk_shm_alloc_lb_sub_worker(jk_pool_t *p,
216                                                    int lb_id, const char *name,
217                                                    jk_logger_t *l);
218 
219 /* allocate shm lb worker record
220  * If there is no shm present the pool will be used instead
221  */
222 jk_shm_lb_worker_t *jk_shm_alloc_lb_worker(jk_pool_t *p, const char *name,
223                                            jk_logger_t *l);
224 
225 int jk_shm_check_maintain(time_t trigger);
226 
227 /* Lock shared memory for thread safe access */
228 int jk_shm_lock(void);
229 
230 /* Unlock shared memory for thread safe access */
231 int jk_shm_unlock(void);
232 
233 
234 #ifdef __cplusplus
235 }
236 #endif  /* __cplusplus */
237 #endif  /* _JK_SHM_H */
238