root/eaccelerator/trunk/ea_info.c

Revision 338, 14.8 kB (checked in by hans, 1 year ago)

missed a gc call

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2007 eAccelerator                               |
6    | http://eaccelerator.net                                                      |
7    +----------------------------------------------------------------------+
8    | This program is free software; you can redistribute it and/or        |
9    | modify it under the terms of the GNU General Public License          |
10    | as published by the Free Software Foundation; either version 2       |
11    | of the License, or (at your option) any later version.               |
12    |                                                                      |
13    | This program is distributed in the hope that it will be useful,      |
14    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
15    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
16    | GNU General Public License for more details.                         |
17    |                                                                      |
18    | You should have received a copy of the GNU General Public License    |
19    | along with this program; if not, write to the Free Software          |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
21    | MA  02111-1307, USA.                                                 |
22    |                                                                      |
23    | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
24    +----------------------------------------------------------------------+
25    $Id$
26 */
27
28 #include "eaccelerator.h"
29 #include "eaccelerator_version.h"
30 #include "ea_info.h"
31 #include "mm.h"
32 #include "cache.h"
33 #include "zend.h"
34 #include "fopen_wrappers.h"
35 #include "debug.h"
36 #include <fcntl.h>
37
38 #ifndef O_BINARY
39 #  define O_BINARY 0
40 #endif
41
42 #ifdef WITH_EACCELERATOR_INFO
43
44 #define NOT_ADMIN_WARNING "This script isn't in the allowed_admin_path setting!"
45
46 extern eaccelerator_mm *eaccelerator_mm_instance;
47
48 /* for checking if shm_only storage */
49 extern zend_bool eaccelerator_scripts_shm_only;
50
51 /* {{{ isAdminAllowed(): check if the admin functions are allowed for the calling script */
52 static int isAdminAllowed(TSRMLS_D) {
53     const char *filename = zend_get_executed_filename(TSRMLS_C);
54     if (EAG(allowed_admin_path) && *EAG(allowed_admin_path)) {
55         char *path;
56         char *p;
57         char *next;
58
59         path = estrdup(EAG(allowed_admin_path));
60         p = path;
61
62         while (p && *p) {
63             next = strchr(p, DEFAULT_DIR_SEPARATOR);
64             if (next != NULL) {
65                 *next = '\0';
66                 ++next;
67             }
68            
69             if (!php_check_specific_open_basedir(p, filename TSRMLS_CC)) {
70                 efree(path);
71                 return 1;
72             }
73
74             p = next;
75         }
76         efree(path);
77         return 0;
78     }
79     return 0;
80 }
81 /* }}} */
82
83 /* {{{ clear_filecache(): Helper function to eaccelerator_clear which finds diskcache entries in the hashed dirs and removes them */
84 static void clear_filecache(const char* dir)
85 #ifndef ZEND_WIN32
86 {
87         DIR *dp;
88         struct dirent *entry;
89         char s[MAXPATHLEN];
90         struct stat dirstat;
91        
92         if ((dp = opendir(dir)) != NULL) {
93                 while ((entry = readdir(dp)) != NULL) {
94                         strncpy(s, dir, MAXPATHLEN - 1);
95                         strlcat(s, "/", MAXPATHLEN);
96                         strlcat(s, entry->d_name, MAXPATHLEN);
97                         if (strstr(entry->d_name, "eaccelerator") == entry->d_name) {
98                                 unlink(s);
99                         }
100                         if (stat(s, &dirstat) != -1) {
101                                 if (strcmp(entry->d_name, ".") == 0)
102                                         continue;
103                                 if (strcmp(entry->d_name, "..") == 0)
104                                         continue;
105                                 if (S_ISDIR(dirstat.st_mode)) {
106                                         clear_filecache(s);
107                                 }
108                         }
109                 }
110                 closedir (dp);
111         } else {
112                 ea_debug_error("[%s] Could not open cachedir %s\n", EACCELERATOR_EXTENSION_NAME, dir);
113         }
114 }
115 #else
116 {
117         HANDLE  hFind;
118     WIN32_FIND_DATA wfd;
119     char path[MAXPATHLEN];
120     size_t dirlen = strlen(dir);
121  
122     memcpy(path, dir, dirlen);
123     strcpy(path + dirlen++, "\\eaccelerator*");
124
125     hFind = FindFirstFile(path, &wfd);
126         if (hFind == INVALID_HANDLE_VALUE) {
127                 do {
128                         strcpy(path + dirlen, wfd.cFileName);
129                         if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) {
130                                 clear_filecache(path);
131                         } else if (!DeleteFile(path)) {
132                                 ea_debug_error("[%s] Can't delete file %s: error %d\n", EACCELERATOR_EXTENSION_NAME, path, GetLastError());
133                         }
134                 } while (FindNextFile(hFind, &wfd));
135         }
136     FindClose (hFind);
137 }
138 #endif
139 /* }}} */
140
141 /* {{{  clean_file: check if the given file is expired */
142 static inline void clean_file(char *file, time_t t)
143 {
144         int f;
145
146         if ((f = open(file, O_RDONLY | O_BINARY)) > 0) {
147                 ea_file_header hdr;
148                 EACCELERATOR_FLOCK (f, LOCK_SH);
149                 if (read(f, &hdr, sizeof(hdr)) != sizeof(hdr)
150                                 || strncmp (hdr.magic, EA_MAGIC,        8) != 0
151                                 || (hdr.mtime != 0 && hdr.mtime < t)) {
152                         EACCELERATOR_FLOCK (f, LOCK_UN);
153                         close (f);
154                         unlink (file);
155                 } else {
156                         EACCELERATOR_FLOCK (f, LOCK_UN);
157                         close (f);
158                 }
159         }
160 }
161 /* }}} */
162
163 /* {{{ clean_filecache(): Helper function for eaccelerator_clean, it will remove all expired entries from the user cache */
164 static void clean_filecache(const char* dir, time_t t)
165 #ifndef ZEND_WIN32
166 {
167         DIR *dp;
168         struct dirent *entry;
169         char s[MAXPATHLEN];
170         struct stat dirstat;
171        
172         if ((dp = opendir(dir)) != NULL) {
173                 while ((entry = readdir(dp)) != NULL) {
174                         strncpy(s, dir, MAXPATHLEN - 1);
175                         strlcat(s, "/", MAXPATHLEN);
176                         strlcat(s, entry->d_name, MAXPATHLEN);
177                         if (strstr(entry->d_name, "eaccelerator-user") == entry->d_name) {
178                                 clean_file(s, t);
179                         }
180                         if (stat(s, &dirstat) != -1) {
181                                 if (strcmp(entry->d_name, ".") == 0)
182                                         continue;
183                                 if (strcmp(entry->d_name, "..") == 0)
184                                         continue;
185                                 if (S_ISDIR(dirstat.st_mode)) {
186                                         clean_filecache(s, t);
187                                 }
188                         }
189                 }
190                 closedir (dp);
191         } else {
192                 ea_debug_error("[%s] Could not open cachedir %s\n", EACCELERATOR_EXTENSION_NAME, dir);
193         }
194 }
195 #else
196 {
197         HANDLE  hFind;
198     WIN32_FIND_DATA wfd;
199     char path[MAXPATHLEN];
200     size_t dirlen = strlen(dir);
201  
202     memcpy(path, dir, dirlen);
203     strcpy(path + dirlen++, "\\eaccelerator-user*");
204
205     hFind = FindFirstFile(path, &wfd);
206         if (hFind == INVALID_HANDLE_VALUE) {
207                 do {
208                         strcpy(path + dirlen, wfd.cFileName);
209                         if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) {
210                                 clear_filecache(path);
211                         } else {
212                                 clean_file(path, t);
213                         }
214                 } while (FindNextFile(hFind, &wfd));
215         }
216     FindClose (hFind);
217 }
218 #endif
219 /* }}} */
220
221 /* {{{ PHP_FUNCTION(eaccelerator_caching): enable or disable caching */
222 PHP_FUNCTION(eaccelerator_caching)
223 {
224     zend_bool enable;
225
226         if (eaccelerator_mm_instance == NULL) {
227                 RETURN_NULL();
228         }
229
230         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &enable) == FAILURE)
231                 return;
232
233     if (isAdminAllowed(TSRMLS_C)) {
234         EACCELERATOR_UNPROTECT();
235         if (enable) {
236             eaccelerator_mm_instance->enabled = 1;
237         } else {
238             eaccelerator_mm_instance->enabled = 0;
239         }
240         EACCELERATOR_PROTECT();
241     } else {
242         zend_error(E_WARNING, NOT_ADMIN_WARNING);
243     }
244    
245     RETURN_NULL();
246 }
247 /* }}} */
248
249 /* {{{ PHP_FUNCTION(eaccelerator_optimizer): enable or disable optimizer */
250 #ifdef WITH_EACCELERATOR_OPTIMIZER
251 PHP_FUNCTION(eaccelerator_optimizer)
252 {
253     zend_bool enable;
254    
255         if (eaccelerator_mm_instance == NULL) {
256                 RETURN_NULL();
257         }
258
259         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &enable) == FAILURE)
260                 return;
261
262     if (isAdminAllowed(TSRMLS_C)) {
263         EACCELERATOR_UNPROTECT();
264         if (enable) {
265             eaccelerator_mm_instance->optimizer_enabled = 1;
266         } else {
267             eaccelerator_mm_instance->optimizer_enabled = 0;
268         }
269         EACCELERATOR_PROTECT();
270     } else {
271         zend_error(E_WARNING, NOT_ADMIN_WARNING);
272     }
273    
274     RETURN_NULL();
275 }
276 #endif
277 /* }}} */
278
279 /* {{{ PHP_FUNCTION(eaccelerator_clean): remove all expired scripts and data from shared memory and disk cache */
280 PHP_FUNCTION(eaccelerator_clean)
281 {
282         time_t t;
283
284         if (eaccelerator_mm_instance == NULL) {
285                 RETURN_NULL();
286         }
287
288         if (!isAdminAllowed(TSRMLS_C)) {
289                 zend_error(E_WARNING, NOT_ADMIN_WARNING);
290                 RETURN_NULL();
291         }
292
293         t = time (NULL);
294
295         /* Remove expired scripts from shared memory */
296         eaccelerator_prune (t);
297
298         /* Remove expired keys (session data, content) from disk cache */
299         if(!eaccelerator_scripts_shm_only) {
300                 clean_filecache(EAG(cache_dir), t);
301         }
302
303 #if defined(WITH_EACCELERATOR_CONTENT_CACHING) || defined(WITH_EACCELERATOR_SESSIONS) || defined(WITH_EACCELERATOR_SHM)
304         /* Remove expired keys (session data, content) from shared memory */
305         eaccelerator_gc (TSRMLS_C);
306 #endif
307 }
308 /* }}} */
309
310 /* {{{ PHP_FUNCTION(eaccelerator_clear): remove all unused scripts and data from shared memory and disk cache */
311 PHP_FUNCTION(eaccelerator_clear)
312 {
313         unsigned int i;
314         ea_cache_entry *p;
315
316         if (eaccelerator_mm_instance == NULL) {
317                 RETURN_NULL();
318         }
319
320     if (!isAdminAllowed(TSRMLS_C)) {
321         zend_error(E_WARNING, NOT_ADMIN_WARNING);
322         RETURN_NULL();
323     }
324
325         EACCELERATOR_UNPROTECT ();
326         EACCELERATOR_LOCK_RW ();
327         for (i = 0; i < EA_HASH_SIZE; i++) {
328                 p = eaccelerator_mm_instance->hash[i];
329                 while (p != NULL) {
330                         ea_cache_entry *r = p;
331                         p = p->next;
332                         eaccelerator_mm_instance->hash_cnt--;
333                         if (r->use_cnt <= 0) {
334                                 eaccelerator_free_nolock (r);
335                         } else {
336                                 r->removed = 1;
337                                 r->next = eaccelerator_mm_instance->removed;
338                                 eaccelerator_mm_instance->removed = r;
339                                 eaccelerator_mm_instance->rem_cnt++;
340                         }
341                 }
342                 eaccelerator_mm_instance->hash[i] = NULL;
343         }
344         for (i = 0; i < EA_USER_HASH_SIZE; i++) {
345                 ea_user_cache_entry *p = eaccelerator_mm_instance->user_hash[i];
346                 while (p != NULL) {
347                         ea_user_cache_entry *r = p;
348                         p = p->next;
349                         eaccelerator_mm_instance->user_hash_cnt--;
350                         eaccelerator_free_nolock (r);
351                 }
352                 eaccelerator_mm_instance->user_hash[i] = NULL;
353         }
354         EACCELERATOR_UNLOCK_RW ();
355         EACCELERATOR_PROTECT ();
356
357         if(!eaccelerator_scripts_shm_only) {
358                 clear_filecache(EAG(cache_dir));
359         }
360
361     RETURN_NULL();
362 }
363 /* }}} */
364
365 /* {{{ PHP_FUNCTION(eaccelerator_purge): remove all 'removed' scripts from shared memory */
366 PHP_FUNCTION(eaccelerator_purge)
367 {
368
369     if (!isAdminAllowed(TSRMLS_C)) {
370         zend_error(E_WARNING, NOT_ADMIN_WARNING);
371         RETURN_NULL();
372     }
373
374         if (eaccelerator_mm_instance != NULL) {
375                 ea_cache_entry *p, *q;
376                 EACCELERATOR_UNPROTECT();
377                 EACCELERATOR_LOCK_RW();
378                 p = eaccelerator_mm_instance->removed;
379                 eaccelerator_mm_instance->rem_cnt = 0;
380                 eaccelerator_mm_instance->removed = NULL;
381                 while (p != NULL) {
382                         q = p->next;
383                         eaccelerator_free_nolock(p);
384                         p = q;
385                 }
386                 EACCELERATOR_UNLOCK_RW();
387                 EACCELERATOR_PROTECT();
388         }
389     RETURN_NULL();
390 }
391 /* }}} */
392
393 /* {{{ PHP_FUNCTION(eaccelerator_info): get info about eaccelerator */
394 // returns info about eaccelerator as an array
395 // returhs the same as eaccelerator section in phpinfo
396 PHP_FUNCTION (eaccelerator_info)
397 {
398         unsigned int available;
399     char *shm, *sem;
400
401     shm = (char *)mm_shm_type();
402     sem = (char *)mm_sem_type();
403
404         if (eaccelerator_mm_instance == NULL) {
405                 RETURN_NULL();
406         }
407
408         available = mm_available (eaccelerator_mm_instance->mm);
409
410         // init return table
411         array_init(return_value);
412        
413         // put eaccelerator information
414         add_assoc_string(return_value, "version", EACCELERATOR_VERSION, 1);
415         add_assoc_string(return_value, "shm_type", shm, 1);
416     add_assoc_string(return_value, "sem_type", sem, 1);
417     add_assoc_string(return_value, "logo", EACCELERATOR_LOGO_GUID, 1);
418         add_assoc_bool(return_value, "cache", (EAG (enabled)
419                 && (eaccelerator_mm_instance != NULL)
420                 && eaccelerator_mm_instance->enabled) ? 1 : 0);
421         add_assoc_bool(return_value, "optimizer", (EAG (optimizer_enabled)
422                 && (eaccelerator_mm_instance != NULL)
423                 && eaccelerator_mm_instance->optimizer_enabled) ? 1 : 0);
424         add_assoc_long(return_value, "memorySize", eaccelerator_mm_instance->total);
425         add_assoc_long(return_value, "memoryAvailable", available);
426         add_assoc_long(return_value, "memoryAllocated", eaccelerator_mm_instance->total - available);
427         add_assoc_long(return_value, "cachedScripts", eaccelerator_mm_instance->hash_cnt);
428         add_assoc_long(return_value, "removedScripts", eaccelerator_mm_instance->rem_cnt);
429     add_assoc_long(return_value, "cachedKeys", eaccelerator_mm_instance->user_hash_cnt);
430
431         return;
432 }
433 /* }}} */
434
435 /* {{{ PHP_FUNCTION(eaccelerator_cached_scripts): Get an array with information about all cached scripts */
436 PHP_FUNCTION(eaccelerator_cached_scripts)
437 {
438     ea_cache_entry *p;
439     int i;
440
441         if (eaccelerator_mm_instance == NULL) {
442                 RETURN_NULL();
443         }
444
445         if (!isAdminAllowed(TSRMLS_C)) {
446         zend_error(E_WARNING, NOT_ADMIN_WARNING);
447         RETURN_NULL();
448     }
449
450     array_init(return_value);
451    
452     for (i = 0; i < EA_HASH_SIZE; i++) {
453         p = eaccelerator_mm_instance->hash[i];
454         while (p != NULL) {
455             zval *script;
456             MAKE_STD_ZVAL(script);
457             array_init(script);
458             add_assoc_string(script, "file", p->realfilename, 1);
459             add_assoc_long(script, "mtime", p->mtime);
460             add_assoc_long(script, "ts", p->ts);
461             add_assoc_long(script, "ttl", p->ttl);
462             add_assoc_long(script, "size", p->size);
463             add_assoc_long(script, "reloads", p->nreloads);
464             add_assoc_long(script, "usecount", p->use_cnt);
465             add_assoc_long(script, "hits", p->nhits);
466             add_next_index_zval(return_value, script);
467             p = p->next;
468         }
469     }
470     return;
471 }
472 /* }}} */
473
474 /* {{{ PHP_FUNCTION(eaccelerator_removed_scripts): Get a list of removed scripts */
475 PHP_FUNCTION(eaccelerator_removed_scripts)
476 {
477     ea_cache_entry *p;
478     zval *script;
479
480         if (eaccelerator_mm_instance == NULL) {
481                 RETURN_NULL();
482         }
483
484     if (!isAdminAllowed(TSRMLS_C)) {
485         zend_error(E_WARNING, NOT_ADMIN_WARNING);
486         RETURN_NULL();
487     }
488
489     MAKE_STD_ZVAL(script);
490     array_init(return_value);
491
492     p = eaccelerator_mm_instance->removed;
493     while (p != NULL) {
494         array_init(script);
495         add_assoc_string(script, "file", p->realfilename, 1);
496         add_assoc_long(script, "mtime", p->mtime);
497         add_assoc_long(script, "size", p->size);
498         add_assoc_long(script, "reloads", p->nreloads);
499         add_assoc_long(script, "usecount", p->use_cnt);
500         add_assoc_long(script, "hits", p->nhits);
501         add_next_index_zval(return_value, script);
502         p = p->next;
503     }
504     return;
505 }
506 /* }}} */
507
508 #if defined (WITH_EACCELERATOR_CONTENT_CACHING) || defined(WITH_EACCELERATOR_SESSIONS) || defined(WITH_EACCELERATOR_SHM)
509 /* {{{ PHP_FUNCTION(eaccelerator_list_keys): returns list of keys in shared memory that matches actual hostname or namespace */
510 PHP_FUNCTION(eaccelerator_list_keys)
511 {
512         if (eaccelerator_mm_instance != NULL && eaccelerator_list_keys(return_value TSRMLS_CC)) {
513                 return;
514         } else {
515         RETURN_NULL ();
516         }
517 }
518 /* }}} */
519 #endif
520
521 #endif  /* WITH_EACCELERATOR_INFO */
522
523 /*
524  * Local variables:
525  * tab-width: 4
526  * c-basic-offset: 4
527  * End:
528  * vim600: noet sw=4 ts=4 fdm=marker
529  * vim<600: noet sw=4 ts=4
530  */
531
Note: See TracBrowser for help on using the browser.