4

I set up a small LAMP virtual machine for PHP development.

It works fine, excepted that when an image which has already been served is modified on disk, then requested again, the "old" image is still being served (I get a 304 Not Modified answer from apache2). This caching behaviour is desirable on a server, but is a pain on a development environment where files are frequently edited.

The only (inconvenient) ways I found to access the new file content are:

  1. rebooting the VM,
  2. or issuing sync; echo 3 > /proc/sys/vm/drop_caches

Is there an apache directive I can use to ensure that apache will check if a file has changed on disk each time it is requested?

Update : Loaded Apache modules:

# apache2ctl -t -D DUMP_MODULES
Loaded Modules:
 core_module (static)
 log_config_module (static)
 logio_module (static)
 mpm_prefork_module (static)
 http_module (static)
 so_module (static)
 alias_module (shared)
 auth_basic_module (shared)
 authn_file_module (shared)
 authz_default_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 php5_module (shared)
 setenvif_module (shared)
 status_module (shared)
Syntax OK

Edit: actually, my DocumentRoot is stored on a shared VirtualBox folder. It seems like when a file is overwritten, the virtualbox module does not notify linux to invalidate its cache. Hence the counterintuitive behavior. When I perform the same overwriting operation on a "regular" linux directory, no such thing happen.

oparisy
  • 181
  • 6

3 Answers3

4

OK, I found the explanation on a VirtualBox ticket: the "sendfile" optimization seems not to be implemented by the vboxsf module.

Until this issue is fixed, a workaround is to use this Apache directive :

EnableSendfile Off 

Using this, server-side images changes are taken into account immediately.

oparisy
  • 181
  • 6
  • Wish I could ++5000. My manifestation of this issue has been driving me absolutely bananas since - like - forever! Till now. Omg I'm so incredibly and finally relieved and grateful I made this over-the-top gushing comment ;-D – John Mee Sep 13 '11 at 06:04
1

Since this is a development server only, where files changes often, the easiest solution is to disable caching entirely for the server (or at least for the VirtualHost responsible for the website being modified). You can use the CacheDisable Directive to instruct mod_cache in Apache to handle this.

The CacheDisable directive instructs mod_cache to not cache urls at or below url-string.

CacheDisable /local_files

Other options include looking at the available directives for mod_disk_cache and mod_mem_cache and using them to control caching on your server. You can also run htcacheclean as a daemon to control/limit the disk cache used by mod_disk_cache.

Update: If mod_cache is not enabled, then the above directives will not work. It also means that any caching is being done at the operating system level instead of Apache - as far as I know only mod_cache (with mod_mem_cache/mod_disk_cache) or mod_file_cache are the only two ways to accomplish caching in Apache. You can see more information about this by reading the Operating System Caching section in Apache's Caching Guide.

You could also see the answers to this question (Disable all disk caching for apache2 on linux) also posted on ServerFault. It does not provide a way to disable caching at the Linux level but it does indicate that you could constantly run the following:

watch -n 1 `sync; echo 3 > /proc/sys/vm/drop_caches`

This can be used to flush the contents of everything cached in memory.

runlevelsix
  • 2,609
  • 21
  • 19
  • Well, it actually seems like `mod_cache` is not enabled (see modules list in the updated question). Will the CacheDisable directive have any effect then? – oparisy Jul 25 '10 at 17:09
  • No, those directives are tied to mod_cache. I updated the answer to provide some additional information regarding caching at the OS level. Hope that helps some. – runlevelsix Jul 25 '10 at 18:30
  • I already read the other answer, but you helped me understand that nothing could be done at the Apache level. I am still baffled by the fact that Linux does not invalidate the cache when a file is overwritten, tough! – oparisy Jul 25 '10 at 20:01
  • You're mixing up two different caching layers - Linux's disk block cache vs. Apache's cache. The only change in behaviour that writing to `drop_caches` will cause will be that when Apache asks for a particular file from the OS, it'll have to go back to disk rather than using its disk cache. – MikeyB Jul 26 '10 at 17:47
  • The behaviour I noticed is that when overwriting a file, Apache will only serve the new content (on my LAMP environment) when flushing the Linux cache. Strangely, when using a directory listing, I can see the proper, new file size and modification time. So the meta informations were modified, but Apache will still serve the old content. Please understand that this is actually rather confusing with respect to which cache keeps what :-) – oparisy Jul 26 '10 at 19:42
  • OK, I think this is a VirtualBox shared folder bug. Please see my edit. – oparisy Jul 26 '10 at 20:04
1

Apache does check - sounds like the timestamps are not being set to the current time when the file is deployed.

See my answer here. Basically, conditional request are a PITA and usual worsen performance rather than improving them. Although that answer is in relation to caching performance it will also solve your problem.

C.

symcbean
  • 19,931
  • 1
  • 29
  • 49
  • When using an ls -l or an Apache directory listing, I can definitely see that the timestamp was updated. I will try your suggestions, but I am still baffled by this default, counterintuitive behavior. – oparisy Jul 26 '10 at 19:43
  • Please see my edit; I think the VirtualBox shared folder module (vboxsf) is misleading the linux kernel in thinking that its cache is still valid. – oparisy Jul 26 '10 at 20:05
  • Quite possibly, and if that's the case then what I'm suggesting may not fix anything (if the directory is not updated then the file won't be either). Should be easy to check by using a filesystem inside the vm and scp'ing the file into it. If that works you should probably log a bug with Sun (see link on VirtualBox website) – symcbean Jul 27 '10 at 08:12