Browse Source

Begin SHM support implementation for stats server process

Yann Weber 4 years ago
parent
commit
21acb49751
7 changed files with 144 additions and 28 deletions
  1. 19
    1
      include/conf.h
  2. 3
    1
      include/ipc.h
  3. 7
    0
      include/stats.h
  4. 99
    16
      src/ipc.c
  5. 3
    3
      src/main.c
  6. 12
    6
      src/monitor.c
  7. 1
    1
      src/responder.c

+ 19
- 1
include/conf.h View File

46
 typedef struct pyfcgi_conf_logger_s pyfcgi_conf_logger_t;
46
 typedef struct pyfcgi_conf_logger_s pyfcgi_conf_logger_t;
47
 typedef struct pyfcgi_context_s pyfcgi_context_t;
47
 typedef struct pyfcgi_context_s pyfcgi_context_t;
48
 typedef struct pyfcgi_semdata_s pyfcgi_semdata_t;
48
 typedef struct pyfcgi_semdata_s pyfcgi_semdata_t;
49
+typedef struct pyfcgi_shmdata_s pyfcgi_shmdata_t;
49
 
50
 
50
 /**@brief Configuration globals, inherited from parent to childs
51
 /**@brief Configuration globals, inherited from parent to childs
51
  * @ingroup conf_internal
52
  * @ingroup conf_internal
141
 #define PYENTRY_DEFAULT_FUN "application"
142
 #define PYENTRY_DEFAULT_FUN "application"
142
 
143
 
143
 /**@brief Stores a semaphore name and pointer */
144
 /**@brief Stores a semaphore name and pointer */
144
-struct pyfcgi_semdata_s {
145
+struct pyfcgi_semdata_s
146
+{
145
 	/**@brief Semaphore names. Set by master process */
147
 	/**@brief Semaphore names. Set by master process */
146
 	char name[NAME_MAX - 4];
148
 	char name[NAME_MAX - 4];
147
 	/**@brief Semaphore pointer. */
149
 	/**@brief Semaphore pointer. */
148
 	sem_t *sem;
150
 	sem_t *sem;
149
 };
151
 };
150
 
152
 
153
+/**@brief Stores an SHM name and pointer */
154
+struct pyfcgi_shmdata_s
155
+{
156
+	/**@brief SHM name. Set by master process */
157
+	char name[NAME_MAX];
158
+	/**@brief SHM file descriptor */
159
+	int fd;
160
+	/**@brief SHM size */
161
+	size_t len;
162
+
163
+	/**@brief SHM pointer */
164
+	void *ptr;
165
+};
166
+
151
 
167
 
152
 /**@brief Stores contextual informations about current process */
168
 /**@brief Stores contextual informations about current process */
153
 struct pyfcgi_context_s {
169
 struct pyfcgi_context_s {
252
 	 * - sems[2] is the stats/status SHM semaphore
268
 	 * - sems[2] is the stats/status SHM semaphore
253
 	 */
269
 	 */
254
 	pyfcgi_semdata_t sems[PYFCGI_NSEM];
270
 	pyfcgi_semdata_t sems[PYFCGI_NSEM];
271
+	/**@brief Shared memory informations */
272
+	pyfcgi_shmdata_t shm;
255
 
273
 
256
 	/**@brief Stores a copy of the specified socket URL to listen to. */
274
 	/**@brief Stores a copy of the specified socket URL to listen to. */
257
 	char *mon_socket;
275
 	char *mon_socket;

+ 3
- 1
include/ipc.h View File

28
 
28
 
29
 #include <fcntl.h>
29
 #include <fcntl.h>
30
 #include <semaphore.h>
30
 #include <semaphore.h>
31
+#include <sys/mman.h>
31
 #include <sys/stat.h>
32
 #include <sys/stat.h>
32
 
33
 
33
 /**@brief Format for sem and shm */
34
 /**@brief Format for sem and shm */
64
 typedef unsigned short pyfcgi_ipc_flag_t;
65
 typedef unsigned short pyfcgi_ipc_flag_t;
65
 
66
 
66
 #include "conf.h"
67
 #include "conf.h"
68
+#include "stats.h" //to get SHM size
67
 
69
 
68
 /**@brief Set semaphore names using master process PID as uniq key
70
 /**@brief Set semaphore names using master process PID as uniq key
69
  * @param pid_t master process PID
71
  * @param pid_t master process PID
70
  */
72
  */
71
-void pyfcgi_name_sems(pid_t master_pid);
73
+void pyfcgi_name_IPC(pid_t master_pid);
72
 
74
 
73
 /**@brief Do shm_open & sem_open given component indicated by flag
75
 /**@brief Do shm_open & sem_open given component indicated by flag
74
  * @param pyfcgi_ipc_flah_t flag a binary or combination of component flags
76
  * @param pyfcgi_ipc_flah_t flag a binary or combination of component flags

+ 7
- 0
include/stats.h View File

31
 #define PYFCGI_STATS_SZ (900)
31
 #define PYFCGI_STATS_SZ (900)
32
 
32
 
33
 typedef struct pyfcgi_stats_s pyfcgi_stats_t;
33
 typedef struct pyfcgi_stats_s pyfcgi_stats_t;
34
+typedef struct pyfcgi_stats_shm_s pyfcgi_stats_shm_t;
34
 
35
 
35
 #include "conf.h"
36
 #include "conf.h"
36
 #include "logger.h"
37
 #include "logger.h"
54
 	size_t buff_len;
55
 	size_t buff_len;
55
 };
56
 };
56
 
57
 
58
+struct pyfcgi_stats_shm_s
59
+{
60
+	int nworker;
61
+	int pool_load;
62
+};
63
+
57
 /**@brief Starts collecting statistics
64
 /**@brief Starts collecting statistics
58
  *
65
  *
59
  * Set an handler for SIGALRM and set a repeating alarm each seconds
66
  * Set an handler for SIGALRM and set a repeating alarm each seconds

+ 99
- 16
src/ipc.c View File

4
 static const pyfcgi_ipc_flag_t semflg[PYFCGI_NSEM] = {
4
 static const pyfcgi_ipc_flag_t semflg[PYFCGI_NSEM] = {
5
 	IPC_WSTATE, IPC_WREQS, IPC_SEMST};
5
 	IPC_WSTATE, IPC_WREQS, IPC_SEMST};
6
 
6
 
7
-void pyfcgi_name_sems(pid_t master_pid)
7
+void pyfcgi_name_IPC(pid_t master_pid)
8
 {
8
 {
9
 	short i;
9
 	short i;
10
 	for(i=0; i<PYFCGI_NSEM; i++)
10
 	for(i=0; i<PYFCGI_NSEM; i++)
16
 			exit(PYFCGI_FATAL);
16
 			exit(PYFCGI_FATAL);
17
 		}
17
 		}
18
 	}
18
 	}
19
+	if(snprintf(PyFCGI_conf.shm.name, NAME_MAX, PYFCGI_IPCNAME_FMT,
20
+		master_pid, "SHMstats") < 0)
21
+	{
22
+		perror("Error setting shm name");
23
+		exit(PYFCGI_FATAL);
24
+	}
25
+	PyFCGI_conf.shm.len = sizeof(pyfcgi_stats_shm_t);
19
 }
26
 }
20
 
27
 
21
 int pyfcgi_IPC_create(pyfcgi_ipc_flag_t flag)
28
 int pyfcgi_IPC_create(pyfcgi_ipc_flag_t flag)
29
 		if(flag & semflg[i])
36
 		if(flag & semflg[i])
30
 		{
37
 		{
31
 			flag ^= semflg[i];
38
 			flag ^= semflg[i];
32
-			PyFCGI_SEM(i).sem = sem_open(PyFCGI_SEM(i).name, O_CREAT | O_EXCL,
33
-				0770, 0);
39
+			PyFCGI_SEM(i).sem = sem_open(PyFCGI_SEM(i).name,
40
+				O_CREAT | O_EXCL, 0770, 0);
34
 			if(PyFCGI_SEM(i).sem == SEM_FAILED)
41
 			if(PyFCGI_SEM(i).sem == SEM_FAILED)
35
 			{
42
 			{
36
 				err = errno;
43
 				err = errno;
37
 				pyfcgi_log(LOG_ALERT,
44
 				pyfcgi_log(LOG_ALERT,
38
-					"Unable to open semaphore %s(named '%s') : %s",
45
+					"Unable to create semaphore %s(named '%s') : %s",
39
 					semnames[i], PyFCGI_SEM(i).name,
46
 					semnames[i], PyFCGI_SEM(i).name,
40
 					strerror(err));
47
 					strerror(err));
41
 				PyFCGI_SEM(i).sem = NULL;
48
 				PyFCGI_SEM(i).sem = NULL;
50
 	if(flag & IPC_SHMST)
57
 	if(flag & IPC_SHMST)
51
 	{
58
 	{
52
 		flag ^= IPC_SHMST;
59
 		flag ^= IPC_SHMST;
53
-dprintf(2, "SHM not yet implemented...\n");
54
-res = -1;
55
-		//PyFCGI_conf.context.ipc_flag |= IPC_SHMST;
60
+		PyFCGI_conf.shm.fd = shm_open(PyFCGI_conf.shm.name,
61
+			O_RDWR | O_CREAT | O_EXCL, 0770);
62
+		if(PyFCGI_conf.shm.fd == -1)
63
+		{
64
+			err = errno;
65
+			pyfcgi_log(LOG_ALERT,
66
+				"Unable to create SHM '%s' : %s",
67
+				PyFCGI_conf.shm.name, strerror(errno));
68
+			PyFCGI_conf.shm.fd = 0;
69
+			return -1;
70
+		}
71
+		PyFCGI_conf.context.ipc_flag |= IPC_SHMST;
72
+		if(ftruncate(PyFCGI_conf.shm.fd,
73
+			sizeof(pyfcgi_stats_shm_t)) < 0)
74
+		{
75
+			pyfcgi_log(LOG_ALERT,
76
+				"Unable to truncate SHM to wanted size %ld : %s",
77
+				sizeof(pyfcgi_stats_shm_t),
78
+				strerror(errno));
79
+			pyfcgi_IPC_destroy(IPC_SHMST);
80
+			return -1;
81
+		}
82
+pyfcgi_log(LOG_INFO, "MMAP LENGHt : %ld", PyFCGI_conf.shm.len);
83
+		PyFCGI_conf.shm.ptr = mmap(NULL, PyFCGI_conf.shm.len,
84
+			PROT_READ | PROT_WRITE, MAP_SHARED, PyFCGI_conf.shm.fd,
85
+			0);
86
+		if(PyFCGI_conf.shm.ptr == (void*)-1)
87
+		{
88
+			pyfcgi_log(LOG_ALERT,
89
+				"Unable to mmap SHM : %s", strerror(errno));
90
+			pyfcgi_IPC_destroy(IPC_SHMST);
91
+			return -1;
92
+		}
56
 	}
93
 	}
57
 	return res;
94
 	return res;
58
 }
95
 }
88
 	if(flag & IPC_SHMST)
125
 	if(flag & IPC_SHMST)
89
 	{
126
 	{
90
 		flag ^= IPC_SHMST;
127
 		flag ^= IPC_SHMST;
91
-dprintf(2, "SHM not yet implemented...\n");
92
-res = -1;
93
-		//PyFCGI_conf.context.ipc_flag |= IPC_SHMST;
128
+		PyFCGI_conf.shm.fd = shm_open(PyFCGI_conf.shm.name, O_RDONLY, 0);
129
+		if(PyFCGI_conf.shm.fd == -1)
130
+		{
131
+			err = errno;
132
+			pyfcgi_log(LOG_ALERT,
133
+				"Unable to open SHM '%s' : %s",
134
+				PyFCGI_conf.shm.name, strerror(errno));
135
+			PyFCGI_conf.shm.fd = 0;
136
+			return -1;
137
+		}
138
+
139
+		PyFCGI_conf.context.ipc_flag |= IPC_SHMST;
140
+		PyFCGI_conf.shm.ptr = mmap(NULL, PyFCGI_conf.shm.len,
141
+			PROT_READ, MAP_SHARED, PyFCGI_conf.shm.fd, 0);
142
+		if(PyFCGI_conf.shm.ptr == (void*)-1)
143
+		{
144
+			pyfcgi_log(LOG_ALERT,
145
+				"Unable to mmap SHM : %s", strerror(errno));
146
+			pyfcgi_IPC_destroy(IPC_SHMST);
147
+			return -1;
148
+		}
94
 	}
149
 	}
95
 	return res;
150
 	return res;
96
 }
151
 }
121
 	}
176
 	}
122
 	if(flag & IPC_SHMST)
177
 	if(flag & IPC_SHMST)
123
 	{
178
 	{
124
-dprintf(2, "SHM not yet implemented...\n");
125
-res = -1;
126
-		//PyFCGI_conf.context.ipc_flag ^= IPC_SHMST;
179
+		if(PyFCGI_conf.shm.ptr &&
180
+			munmap(PyFCGI_conf.shm.ptr, PyFCGI_conf.shm.len) < 0)
181
+		{
182
+			pyfcgi_log(LOG_WARNING, "Unable to unmap SHM : %s",
183
+				strerror(errno));
184
+		}
185
+		if(close(PyFCGI_conf.shm.fd) < 0)
186
+		{
187
+			pyfcgi_log(LOG_WARNING, "Unable to close SHM : %s",
188
+				strerror(errno));
189
+		}
190
+		PyFCGI_conf.shm.fd = 0;
191
+		PyFCGI_conf.shm.ptr = NULL;
192
+		PyFCGI_conf.context.ipc_flag ^= IPC_SHMST;
127
 	}
193
 	}
128
 
194
 
129
 	return res;
195
 	return res;
153
 	}
219
 	}
154
 	if(flag & IPC_SHMST)
220
 	if(flag & IPC_SHMST)
155
 	{
221
 	{
156
-dprintf(2, "SHM not yet implemented...\n");
157
-res = -1;
158
-		//PyFCGI_conf.context.ipc_flag ^= IPC_SHMST;
222
+
223
+		if(PyFCGI_conf.shm.ptr &&
224
+			munmap(PyFCGI_conf.shm.ptr, PyFCGI_conf.shm.len) < 0)
225
+		{
226
+			pyfcgi_log(LOG_WARNING, "Unable to unmap SHM : %s",
227
+				strerror(errno));
228
+		}
229
+		if(close(PyFCGI_conf.shm.fd) < 0)
230
+		{
231
+			pyfcgi_log(LOG_WARNING, "Unable to close SHM : %s",
232
+				strerror(errno));
233
+		}
234
+		if(shm_unlink(PyFCGI_conf.shm.name) < 0)
235
+		{
236
+			pyfcgi_log(LOG_WARNING, "Unabe to unlink SHM : %s",
237
+				strerror(errno));
238
+		}
239
+		PyFCGI_conf.shm.fd = 0;
240
+		PyFCGI_conf.shm.ptr = NULL;
241
+		PyFCGI_conf.context.ipc_flag ^= IPC_SHMST;
159
 	}
242
 	}
160
 	return res;
243
 	return res;
161
 }
244
 }

+ 3
- 3
src/main.c View File

179
 	pool_handler_pid = 0;
179
 	pool_handler_pid = 0;
180
 	monitor_serv_pid = 0;
180
 	monitor_serv_pid = 0;
181
 	default_conf();
181
 	default_conf();
182
-	pyfcgi_name_sems(getpid()); //name semaphore using master proc PID
182
+	pyfcgi_name_IPC(getpid()); //name semaphore using master proc PID
183
 
183
 
184
 	pyfcgi_logger_init();
184
 	pyfcgi_logger_init();
185
 	pyfcgi_logger_set_ident("MainProc");
185
 	pyfcgi_logger_set_ident("MainProc");
271
 		if(child_ret)
271
 		if(child_ret)
272
 		{
272
 		{
273
 
273
 
274
-			pyfcgi_log(LOG_ERR, "%s exits with error code '%d'",
275
-				child_name, WEXITSTATUS(child_ret));
274
+			pyfcgi_log(LOG_ERR, "%s exits with error code : %s",
275
+				child_name, status2str(WEXITSTATUS(child_ret)));
276
 			if(WIFSIGNALED(child_ret))
276
 			if(WIFSIGNALED(child_ret))
277
 			{
277
 			{
278
 				pyfcgi_log(LOG_ERR, "%s terminated by sig %s(%d)",
278
 				pyfcgi_log(LOG_ERR, "%s terminated by sig %s(%d)",

+ 12
- 6
src/monitor.c View File

98
 	ret = 0;
98
 	ret = 0;
99
 	if(!PyFCGI_SEM_OPEN(SEM_WREQS))
99
 	if(!PyFCGI_SEM_OPEN(SEM_WREQS))
100
 	{
100
 	{
101
-		pyfcgi_IPC_init(IPC_WREQS);
102
-		ret = -1;
101
+		if(pyfcgi_IPC_init(IPC_WREQS)) { ret = -1; }
103
 	}
102
 	}
104
 	if(!PyFCGI_SEM_OPEN(SEM_STATS))
103
 	if(!PyFCGI_SEM_OPEN(SEM_STATS))
105
 	{
104
 	{
106
-		pyfcgi_IPC_init(IPC_SEMST);
107
-		ret = -1;
105
+		if(pyfcgi_IPC_init(IPC_SEMST)) { ret = -1; }
106
+	}
107
+	if(!PyFCGI_conf.shm.ptr)
108
+	{
109
+		if(pyfcgi_IPC_init(IPC_SHMST)) { ret = -1; }
108
 	}
110
 	}
109
-	//pyfcgi_IPC_init(IPC_SHMST);
110
 	return ret;
111
 	return ret;
111
 }
112
 }
112
 
113
 
168
 	pyfcgi_log(LOG_INFO, "Listening on %s", PyFCGI_conf.mon_socket);
169
 	pyfcgi_log(LOG_INFO, "Listening on %s", PyFCGI_conf.mon_socket);
169
 
170
 
170
 	//bind successfull, sending to appropriate response loop
171
 	//bind successfull, sending to appropriate response loop
171
-	pyfcgi_monitor_IPC_init(); //check returned value !
172
+	if(pyfcgi_monitor_IPC_init() < 0)
173
+	{
174
+		pyfcgi_log(LOG_ERR, "Unable to initialize IPC");
175
+		sleep(1);
176
+		exit(PYFCGI_ERR);
177
+	}
172
 	pyfcgi_stats_init();
178
 	pyfcgi_stats_init();
173
 
179
 
174
 	if(pyfcgi_mon.sockargs[1] == SOCK_DGRAM)
180
 	if(pyfcgi_mon.sockargs[1] == SOCK_DGRAM)

+ 1
- 1
src/responder.c View File

63
 	PyFCGI_conf.context.pid = getpid();
63
 	PyFCGI_conf.context.pid = getpid();
64
 	PyFCGI_conf.context.ppid = getppid();
64
 	PyFCGI_conf.context.ppid = getppid();
65
 
65
 
66
-	if(pyfcgi_IPC_create(IPC_WSTATE | IPC_WREQS | IPC_SEMST) < 0)
66
+	if(pyfcgi_IPC_create(IPC_WSTATE | IPC_WREQS | IPC_SEMST | IPC_SHMST) < 0)
67
 	{
67
 	{
68
 		pyfcgi_log(LOG_ALERT, "Pool handler process is unable to init IPC components");
68
 		pyfcgi_log(LOG_ALERT, "Pool handler process is unable to init IPC components");
69
 		sleep(1);
69
 		sleep(1);

Loading…
Cancel
Save