3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
12 ngx_int_t ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, ngx_int_t level)
22 #if (NGX_SUPPRESS_WARN)
27 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
28 "gc dir \"%s\":%d", dname->data, dname->len);
30 if (ngx_open_dir(dname, &dir) == NGX_ERROR) {
31 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
32 ngx_open_dir_n " \"%s\" failed", dname->data);
38 if (ngx_read_dir(&dir) == NGX_ERROR) {
41 if (err != NGX_ENOMOREFILES) {
42 ngx_log_error(NGX_LOG_CRIT, ctx->log, err,
43 ngx_read_dir_n " \"%s\" failed", dname->data);
53 len = ngx_de_namelen(&dir);
55 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
56 "gc name \"%s\":%d", ngx_de_name(&dir), len);
58 if (len == 1 && ngx_de_name(&dir)[0] == '.') {
63 && ngx_de_name(&dir)[0] == '.'
64 && ngx_de_name(&dir)[1] == '.')
69 fname.len = dname->len + 1+ len;
71 if (fname.len + NGX_DIR_MASK_LEN > buf.len) {
77 buf.len = dname->len + 1 + len + NGX_DIR_MASK_LEN;
79 buf.data = ngx_alloc(buf.len + 1, ctx->log);
80 if (buf.data == NULL) {
85 last = ngx_cpymem(buf.data, dname->data, dname->len);
87 ngx_memcpy(last, ngx_de_name(&dir), len + 1);
88 fname.data = buf.data;
90 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
91 "gc path: \"%s\"", fname.data);
93 if (!dir.valid_info) {
94 if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) {
95 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
96 ngx_de_info_n " \"%s\" failed", fname.data);
101 if (ngx_de_is_dir(&dir)) {
103 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
104 "gc enter dir \"%s\"", fname.data);
107 /* there can not be directory on the last level */
108 || level == NGX_MAX_PATH_LEVEL
109 /* an directory from the old path hierarchy */
110 || len != ctx->path->level[level])
112 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) {
116 fname.data[fname.len] = '\0';
118 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
119 "delete old hierachy directory \"%s\"",
122 if (ngx_delete_dir(fname.data) == NGX_FILE_ERROR) {
123 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
124 ngx_delete_dir_n " \"%s\" failed",
128 ctx->freed += ngx_de_size(&dir);
134 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) {
138 } else if (ngx_de_is_file(&dir)) {
140 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
141 "gc file \"%s\"", fname.data);
144 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0))
146 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) {
147 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
148 ngx_delete_file_n " \"%s\" failed",
152 ctx->freed += ngx_de_size(&dir);
158 if (ctx->handler(ctx, &fname, &dir) == NGX_ABORT) {
163 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
164 "the file \"%s\" has unknown type, deleting",
167 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) {
168 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
169 ngx_delete_file_n " \"%s\" failed", fname.data);
172 ctx->freed += ngx_de_size(&dir);
181 if (ngx_close_dir(&dir) == NGX_ERROR) {
182 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
183 ngx_close_dir_n " \"%s\" failed", fname.data);
190 ngx_int_t ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name,
194 * We use mtime only and do not use atime because:
195 * on NTFS access time has a resolution of 1 hour,
196 * on NT FAT access time has a resolution of 1 day,
197 * Unices have the mount option "noatime".
200 if (ngx_time() - ngx_de_mtime(dir) < 3600) {
204 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
205 "delete the stale temporary file \"%s\"", name->data);
207 if (ngx_delete_file(name->data) == NGX_FILE_ERROR) {
208 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
209 ngx_delete_file_n " \"%s\" failed", name->data);
214 ctx->freed += ngx_de_size(dir);