root/eaccelerator/branches/0.9.5/ea_info.c

Revision 268, 14.4 kB (checked in by hans, 2 years ago)

Skip disk cache creation and clean/clear actions when operating in shm_only mode. This fixes ticket #165

  • Property svn:keywords set to svn:eol-style
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2006 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                 mm_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 (0);
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         /* Remove expired keys (session data, content) from shared memory */
304         eaccelerator_gc (TSRMLS_C);
305 }
306 /* }}} */
307
308 /* {{{ PHP_FUNCTION(eaccelerator_clear): remove all unused scripts and data from shared memory and disk cache */
309 PHP_FUNCTION(eaccelerator_clear)
310 {
311         unsigned int i;
312         mm_cache_entry *p;
313
314         if (eaccelerator_mm_instance == NULL) {
315                 RETURN_NULL();
316         }
317
318     if (!isAdminAllowed(TSRMLS_C)) {
319         zend_error(E_WARNING, NOT_ADMIN_WARNING);
320         RETURN_NULL();
321     }
322
323         EACCELERATOR_UNPROTECT ();
324         EACCELERATOR_LOCK_RW ();
325         for (i = 0; i < EA_HASH_SIZE; i++) {
326                 p = eaccelerator_mm_instance->hash[i];
327                 while (p != NULL) {
328                         mm_cache_entry *r = p;
329                         p = p->next;
330                         eaccelerator_mm_instance->hash_cnt--;
331                         if (r->use_cnt <= 0) {
332                                 eaccelerator_free_nolock (r);
333                         } else {
334                                 r->removed = 1;
335                                 r->next = eaccelerator_mm_instance->removed;
336                                 eaccelerator_mm_instance->removed = r;
337                                 eaccelerator_mm_instance->rem_cnt++;
338                         }
339                 }
340                 eaccelerator_mm_instance->hash[i] = NULL;
341         }
342         for (i = 0; i < EA_USER_HASH_SIZE; i++) {
343                 mm_user_cache_entry *p = eaccelerator_mm_instance->user_hash[i];
344                 while (p != NULL) {
345                         mm_user_cache_entry *r = p;
346                         p = p->next;
347                         eaccelerator_mm_instance->user_hash_cnt--;
348                         eaccelerator_free_nolock (r);
349                 }
350                 eaccelerator_mm_instance->user_hash[i] = NULL;
351         }
352         EACCELERATOR_UNLOCK_RW ();
353         EACCELERATOR_PROTECT ();
354
355         if(!eaccelerator_scripts_shm_only) {
356                 clear_filecache(EAG(cache_dir));
357         }
358
359     RETURN_NULL();
360 }
361 /* }}} */
362
363 /* {{{ PHP_FUNCTION(eaccelerator_purge): remove all 'removed' scripts from shared memory */
364 PHP_FUNCTION(eaccelerator_purge)
365 {
366
367     if (!isAdminAllowed(TSRMLS_C)) {
368         zend_error(E_WARNING, NOT_ADMIN_WARNING);
369         RETURN_NULL();
370     }
371
372         if (eaccelerator_mm_instance != NULL) {
373                 mm_cache_entry *p, *q;
374                 EACCELERATOR_UNPROTECT();
375                 EACCELERATOR_LOCK_RW();
376                 p = eaccelerator_mm_instance->removed;
377                 eaccelerator_mm_instance->rem_cnt = 0;
378                 eaccelerator_mm_instance->removed = NULL;
379                 while (p != NULL) {
380                         q = p->next;
381                         eaccelerator_free_nolock(p);
382                         p = q;
383                 }
384                 EACCELERATOR_UNLOCK_RW();
385                 EACCELERATOR_PROTECT();
386         }
387     RETURN_NULL();
388 }
389 /* }}} */
390
391 /* {{{ PHP_FUNCTION(eaccelerator_info): get info about eaccelerator */
392 // returns info about eaccelerator as an array
393 // returhs the same as eaccelerator section in phpinfo
394 PHP_FUNCTION (eaccelerator_info)
395 {
396         unsigned int available;
397     char *shm, *sem;
398
399     shm = (char *)mm_shm_type();
400     sem = (char *)mm_sem_type();
401
402         if (eaccelerator_mm_instance == NULL) {
403                 RETURN_NULL();
404         }
405
406         available = mm_available (eaccelerator_mm_instance->mm);
407
408         // init return table
409         array_init(return_value);
410        
411         // put eaccelerator information
412         add_assoc_string(return_value, "version", EACCELERATOR_VERSION, 1);
413         add_assoc_string(return_value, "shm_type", shm, 1);
414     add_assoc_string(return_value, "sem_type", sem, 1);
415     add_assoc_string(return_value, "logo", EACCELERATOR_LOGO_GUID, 1);
416         add_assoc_bool(return_value, "cache", (EAG (enabled)
417                 && (eaccelerator_mm_instance != NULL)
418                 && eaccelerator_mm_instance->enabled) ? 1 : 0);
419         add_assoc_bool(return_value, "optimizer", (EAG (optimizer_enabled)
420                 && (eaccelerator_mm_instance != NULL)
421                 && eaccelerator_mm_instance->optimizer_enabled) ? 1 : 0);
422         add_assoc_long(return_value, "memorySize", eaccelerator_mm_instance->total);
423         add_assoc_long(return_value, "memoryAvailable", available);
424         add_assoc_long(return_value, "memoryAllocated", eaccelerator_mm_instance->total - available);
425         add_assoc_long(return_value, "cachedScripts", eaccelerator_mm_instance->hash_cnt);
426         add_assoc_long(return_value, "removedScripts", eaccelerator_mm_instance->rem_cnt);
427     add_assoc_long(return_value, "cachedKeys", eaccelerator_mm_instance->user_hash_cnt);
428
429         return;
430 }
431 /* }}} */
432
433 /* {{{ PHP_FUNCTION(eaccelerator_cached_scripts): Get an array with information about all cached scripts */
434 PHP_FUNCTION(eaccelerator_cached_scripts)
435 {
436     mm_cache_entry *p;
437     int i;
438
439         if (eaccelerator_mm_instance == NULL) {
440                 RETURN_NULL();
441         }
442
443         if (!isAdminAllowed(TSRMLS_C)) {
444         zend_error(E_WARNING, NOT_ADMIN_WARNING);
445         RETURN_NULL();
446     }
447
448     array_init(return_value);
449    
450     for (i = 0; i < EA_HASH_SIZE; i++) {
451         p = eaccelerator_mm_instance->hash[i];
452         while (p != NULL) {
453             zval *script;
454             MAKE_STD_ZVAL(script);
455             array_init(script);
456             add_assoc_string(script, "file", p->realfilename, 1);
457             add_assoc_long(script, "mtime", p->mtime);
458             add_assoc_long(script, "size", p->size);
459             add_assoc_long(script, "reloads", p->nreloads);
460             add_assoc_long(script, "usecount", p->use_cnt);
461             add_assoc_long(script, "hits", p->nhits);
462             add_next_index_zval(return_value, script);
463             p = p->next;
464         }
465     }
466     return;
467 }
468 /* }}} */
469
470 /* {{{ PHP_FUNCTION(eaccelerator_removed_scripts): Get a list of removed scripts */
471 PHP_FUNCTION(eaccelerator_removed_scripts)
472 {
473     mm_cache_entry *p;
474     zval *script;
475
476         if (eaccelerator_mm_instance == NULL) {
477                 RETURN_NULL();
478         }
479
480     if (!isAdminAllowed(TSRMLS_C)) {
481         zend_error(E_WARNING, NOT_ADMIN_WARNING);
482         RETURN_NULL();
483     }
484
485     MAKE_STD_ZVAL(script);
486     array_init(return_value);
487
488     p = eaccelerator_mm_instance->removed;
489     while (p != NULL) {
490         array_init(script);
491         add_assoc_string(script, "file", p->realfilename, 1);
492         add_assoc_long(script, "mtime", p->mtime);
493         add_assoc_long(script, "size", p->size);
494         add_assoc_long(script, "reloads", p->nreloads);
495         add_assoc_long(script, "usecount", p->use_cnt);
496         add_assoc_long(script, "hits", p->nhits);
497         add_next_index_zval(return_value, script);
498         p = p->next;
499     }
500     return;
501 }
502 /* }}} */
503
504 /* {{{ PHP_FUNCTION(eaccelerator_list_keys): returns list of keys in shared memory that matches actual hostname or namespace */
505 PHP_FUNCTION(eaccelerator_list_keys)
506 {
507         if (eaccelerator_mm_instance != NULL && eaccelerator_list_keys(return_value TSRMLS_CC)) {
508                 return;
509         } else {
510         RETURN_NULL ();
511         }
512 }
513 /* }}} */
514
515 #endif
516
517 /*
518  * Local variables:
519  * tab-width: 4
520  * c-basic-offset: 4
521  * End:
522  * vim600: noet sw=4 ts=4 fdm=marker
523  * vim<600: noet sw=4 ts=4
524  */
525
Note: See TracBrowser for help on using the browser.