On Mon, Aug 08, 2005 at 12:04:44AM +0100, Colm MacCarthaigh wrote: > Well that's a pretty each race to solve within httpd. It won't be able > to create the headers, or the body. The patch I've submitted cleans up > that slight race. The file won't be cached on that serve, but I don't > think that's a big deal :-)
And since nothing says it like code, here's a patch to htcacheclean which adds a -t option to clean out empty directories. -- Colm MacCárthaigh Public Key: [EMAIL PROTECTED]
Index: docs/man/htcacheclean.8 =================================================================== --- docs/man/htcacheclean.8 (revision 230717) +++ docs/man/htcacheclean.8 (working copy) @@ -19,7 +19,7 @@ .el .ne 3 .IP "\\$1" \\$2 .. -.TH "HTCACHECLEAN" 8 "2004-11-10" "Apache HTTP Server" "htcacheclean" +.TH "HTCACHECLEAN" 8 "2005-08-08" "Apache HTTP Server" "htcacheclean" .SH NAME htcacheclean \- Clean up the disk cache @@ -27,10 +27,10 @@ .SH "SYNOPSIS" .PP -\fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBr\fR ] [ -\fBn\fR ] -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR +\fBhtcacheclean\fR [ -\fBD\fR ] [ -\fBv\fR ] [ -\fBt\fR ] [ -\fBr\fR ] [ -\fBn\fR ] -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR .PP -\fBhtcacheclean\fR -\fBb\fR [ -\fBn\fR ] [ -\fBi\fR ] -\fBd\fR\fIinterval\fR -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR +\fBhtcacheclean\fR -\fBb\fR [ -\fBn\fR ] [ -\fBt\fR ] [ -\fBi\fR ] -\fBd\fR\fIinterval\fR -\fBp\fR\fIpath\fR -\fBl\fR\fIlimit\fR .SH "SUMMARY" @@ -53,11 +53,14 @@ Be verbose and print statistics\&. This option is mutually exclusive with the -d option\&. .TP -r -Clean thoroughly\&. This assumes that the Apache web server is not running (otherwise you may get garbage in the cache)\&. This option is mutually exclusive with the -d option\&. +Clean thoroughly\&. This assumes that the Apache web server is not running (otherwise you may get garbage in the cache)\&. This option is mutually exclusive with the -d option and implies the -t option\&. .TP -n Be nice\&. This causes slower processing in favour of other processes\&. htcacheclean will sleep from time to time so that (a) the disk IO will be delayed and (b) the kernel can schedule other processes in the meantime\&. .TP +-t +Delete all empty directories\&. By default only cache files are removed, however with some configurations the large number of directories created may require attention\&. If your configuration requires a very large number of directories, to the point that inode or file allocation table exhaustion may become an issue, use of this option is advised\&. +.TP -p\fIpath\fR Specify \fIpath\fR as the root directory of the disk cache\&. This should be the same value as specified with the CacheRoot directive\&. .TP Index: docs/manual/programs/htcacheclean.html.en =================================================================== --- docs/manual/programs/htcacheclean.html.en (revision 230717) +++ docs/manual/programs/htcacheclean.html.en (working copy) @@ -39,6 +39,7 @@ <p><code><strong>htcacheclean</strong> [ -<strong>D</strong> ] [ -<strong>v</strong> ] + [ -<strong>t</strong> ] [ -<strong>r</strong> ] [ -<strong>n</strong> ] -<strong>p</strong><var>path</var> @@ -46,6 +47,7 @@ <p><code><strong>htcacheclean</strong> -<strong>b</strong> [ -<strong>n</strong> ] + [ -<strong>t</strong> ] [ -<strong>i</strong> ] -<strong>d</strong><var>interval</var> -<strong>p</strong><var>path</var> @@ -71,7 +73,8 @@ <dt><code>-r</code></dt> <dd>Clean thoroughly. This assumes that the Apache web server is not running (otherwise you may get garbage in the cache). This option - is mutually exclusive with the <code>-d</code> option.</dd> + is mutually exclusive with the <code>-d</code> option and implies + the <code>-t</code> option.</dd> <dt><code>-n</code></dt> <dd>Be nice. This causes slower processing in favour of other @@ -79,6 +82,14 @@ so that (a) the disk IO will be delayed and (b) the kernel can schedule other processes in the meantime.</dd> + <dt><code>-t</code></dt> + <dd>Delete all empty directories. By default only cache files are + removed, however with some configurations the large number of + directories created may require attention. If your configuration + requires a very large number of directories, to the point that + inode or file allocation table exhaustion may become an issue, use + of this option is advised.</dd> + <dt><code>-p<var>path</var></code></dt> <dd>Specify <var>path</var> as the root directory of the disk cache. This should be the same value as specified with the <code class="directive"><a href="../mod/mod_disk_cache.html#cacheroot">CacheRoot</a></code> directive.</dd> Index: docs/manual/programs/htcacheclean.xml =================================================================== --- docs/manual/programs/htcacheclean.xml (revision 230717) +++ docs/manual/programs/htcacheclean.xml (working copy) @@ -39,6 +39,7 @@ <p><code><strong>htcacheclean</strong> [ -<strong>D</strong> ] [ -<strong>v</strong> ] + [ -<strong>t</strong> ] [ -<strong>r</strong> ] [ -<strong>n</strong> ] -<strong>p</strong><var>path</var> @@ -46,6 +47,7 @@ <p><code><strong>htcacheclean</strong> -<strong>b</strong> [ -<strong>n</strong> ] + [ -<strong>t</strong> ] [ -<strong>i</strong> ] -<strong>d</strong><var>interval</var> -<strong>p</strong><var>path</var> @@ -71,7 +73,8 @@ <dt><code>-r</code></dt> <dd>Clean thoroughly. This assumes that the Apache web server is not running (otherwise you may get garbage in the cache). This option - is mutually exclusive with the <code>-d</code> option.</dd> + is mutually exclusive with the <code>-d</code> option and implies + the <code>-t</code> option.</dd> <dt><code>-n</code></dt> <dd>Be nice. This causes slower processing in favour of other @@ -79,6 +82,14 @@ so that (a) the disk IO will be delayed and (b) the kernel can schedule other processes in the meantime.</dd> + <dt><code>-t</code></dt> + <dd>Delete all empty directories. By default only cache files are + removed, however with some configurations the large number of + directories created may require attention. If your configuration + requires a very large number of directories, to the point that + inode or file allocation table exhaustion may become an issue, use + of this option is advised.</dd> + <dt><code>-p<var>path</var></code></dt> <dd>Specify <var>path</var> as the root directory of the disk cache. This should be the same value as specified with the <directive Index: support/htcacheclean.c =================================================================== --- support/htcacheclean.c (revision 230717) +++ support/htcacheclean.c (working copy) @@ -143,6 +143,7 @@ static int benice; /* flag: true means nice mode is activated */ static int dryrun; /* flag: true means dry run, don't actually delete anything */ +static int deldirs; /* flag: true means directories should be deleted */ static int baselen; /* string length of the path to the proxy directory */ static apr_time_t now; /* start time of this processing run */ @@ -319,6 +320,32 @@ } /* + * Determine if a directory is empty + */ +static int directory_empty(char *path, apr_pool_t *pool) +{ + apr_dir_t *dir; + apr_finfo_t info; + + if (apr_dir_open(&dir, path, pool) != APR_SUCCESS) { + return 0; + } + + while (apr_dir_read(&info, 0, dir) == APR_SUCCESS && !interrupted) { + if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) { + continue; + } + + /* If we're here, the directory is not empty */ + apr_dir_close(dir); + return 0; + } + + apr_dir_close(dir); + return 1; +} + +/* * walk the cache directory tree */ static int process_dir(char *path, apr_pool_t *pool) @@ -332,7 +359,7 @@ apr_finfo_t info; apr_size_t len; apr_time_t current, deviation; - char *nextpath, *base, *ext; + char *nextpath, *base, *ext, *orig_basename; APR_RING_ENTRY(_direntry) anchor; DIRENTRY *d, *t, *n; ENTRY *e; @@ -413,9 +440,18 @@ } if (info.filetype == APR_DIR) { + /* Make a copy of the basename, as process_dir modifies it */ + orig_basename = apr_pstrdup(pool, d->basename); if (process_dir(d->basename, pool)) { return 1; } + + /* If, after processing this directory, it is empty. Delete the + * directory also. + */ + if (deldirs && !dryrun && directory_empty(orig_basename, pool)) { + apr_dir_remove(orig_basename, pool); + } continue; } @@ -740,8 +776,8 @@ { apr_file_printf(errfile, "%s -- program for cleaning the disk cache." NL - "Usage: %s [-Dvrn] -pPATH -lLIMIT" NL - " %s [-ni] -dINTERVAL -pPATH -lLIMIT" NL + "Usage: %s [-Dvtrn] -pPATH -lLIMIT" NL + " %s [-nti] -dINTERVAL -pPATH -lLIMIT" NL NL "Options:" NL " -d Daemonize and repeat cache cleaning every INTERVAL minutes." NL @@ -756,11 +792,15 @@ NL " -r Clean thoroughly. This assumes that the Apache web server is " NL " not running. This option is mutually exclusive with the -d" NL - " option." NL + " option and implies -t." NL NL " -n Be nice. This causes slower processing in favour of other" NL " processes." NL NL + " -t Delete all empty directories. By default only cache files are" NL + " removed, however with some configurations the large number of" NL + " directories created may require attention." NL + NL " -p Specify PATH as the root directory of the disk cache." NL NL " -l Specify LIMIT as the total disk cache size limit. Attach 'K'" NL @@ -803,6 +843,7 @@ verbose = 0; realclean = 0; benice = 0; + deldirs = 0; intelligent = 0; previous = 0; /* avoid compiler warning */ proxypath = NULL; @@ -827,7 +868,7 @@ apr_getopt_init(&o, pool, argc, argv); while (1) { - status = apr_getopt(o, "iDnvrd:l:L:p:", &opt, &arg); + status = apr_getopt(o, "iDnvrtd:l:L:p:", &opt, &arg); if (status == APR_EOF) { break; } @@ -856,6 +897,13 @@ } benice = 1; break; + + case 't': + if (deldirs) { + usage(); + } + deldirs = 1; + break; case 'v': if (verbose) { @@ -869,6 +917,7 @@ usage(); } realclean = 1; + deldirs = 1; break; case 'd':