1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9
10
11
12 ngx_int_t ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, ngx_int_t level)
13 {
14 int rc;
15 u_char *last;
16 size_t len;
17 ngx_err_t err;
18 ngx_str_t fname, buf;
19 ngx_dir_t dir;
20
21 buf.len = 0;
22 #if (NGX_SUPPRESS_WARN)
23 buf.data = NULL;
24 fname.data = NULL;
25 #endif
26
27 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
28 "gc dir \"%s\":%d", dname->data, dname->len);
29
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);
33 return NGX_ERROR;
34 }
35
36 for ( ;; ) {
37 ngx_set_errno(0);
38 if (ngx_read_dir(&dir) == NGX_ERROR) {
39 err = ngx_errno;
40
41 if (err != NGX_ENOMOREFILES) {
42 ngx_log_error(NGX_LOG_CRIT, ctx->log, err,
43 ngx_read_dir_n " \"%s\" failed", dname->data);
44 rc = NGX_ERROR;
45
46 } else {
47 rc = NGX_OK;
48 }
49
50 break;
51 }
52
53 len = ngx_de_namelen(&dir);
54
55 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
56 "gc name \"%s\":%d", ngx_de_name(&dir), len);
57
58 if (len == 1 && ngx_de_name(&dir)[0] == '.') {
59 continue;
60 }
61
62 if (len == 2
63 && ngx_de_name(&dir)[0] == '.'
64 && ngx_de_name(&dir)[1] == '.')
65 {
66 continue;
67 }
68
69 fname.len = dname->len + 1+ len;
70
71 if (fname.len + NGX_DIR_MASK_LEN > buf.len) {
72
73 if (buf.len) {
74 ngx_free(buf.data);
75 }
76
77 buf.len = dname->len + 1 + len + NGX_DIR_MASK_LEN;
78
79 buf.data = ngx_alloc(buf.len + 1, ctx->log);
80 if (buf.data == NULL) {
81 return NGX_ABORT;
82 }
83 }
84
85 last = ngx_cpymem(buf.data, dname->data, dname->len);
86 *last++ = '/';
87 ngx_memcpy(last, ngx_de_name(&dir), len + 1);
88 fname.data = buf.data;
89
90 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
91 "gc path: \"%s\"", fname.data);
92
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);
97 continue;
98 }
99 }
100
101 if (ngx_de_is_dir(&dir)) {
102
103 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
104 "gc enter dir \"%s\"", fname.data);
105
106 if (level == -1
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])
111 {
112 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) {
113 return NGX_ABORT;
114 }
115
116 fname.data[fname.len] = '\0';
117
118 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
119 "delete old hierachy directory \"%s\"",
120 fname.data);
121
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",
125 fname.data);
126 } else {
127 ctx->deleted++;
128 ctx->freed += ngx_de_size(&dir);
129 }
130
131 continue;
132 }
133
134 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) {
135 return NGX_ABORT;
136 }
137
138 } else if (ngx_de_is_file(&dir)) {
139
140 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
141 "gc file \"%s\"", fname.data);
142
143 if (level == -1
144 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0))
145 {
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",
149 fname.data);
150 } else {
151 ctx->deleted++;
152 ctx->freed += ngx_de_size(&dir);
153 }
154
155 continue;
156 }
157
158 if (ctx->handler(ctx, &fname, &dir) == NGX_ABORT) {
159 return NGX_ABORT;
160 }
161
162 } else {
163 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
164 "the file \"%s\" has unknown type, deleting",
165 fname.data);
166
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);
170 } else {
171 ctx->deleted++;
172 ctx->freed += ngx_de_size(&dir);
173 }
174 }
175 }
176
177 if (buf.len) {
178 ngx_free(buf.data);
179 }
180
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);
184 }
185
186 return rc;
187 }
188
189
190 ngx_int_t ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name,
191 ngx_dir_t *dir)
192 {
193 /*
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".
198 */
199
200 if (ngx_time() - ngx_de_mtime(dir) < 3600) {
201 return NGX_OK;
202 }
203
204 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
205 "delete the stale temporary file \"%s\"", name->data);
206
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);
210 return NGX_ERROR;
211 }
212
213 ctx->deleted++;
214 ctx->freed += ngx_de_size(dir);
215
216 return NGX_OK;
217 }
218
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.