comparison src/core/ngx_garbage_collector.c @ 186:c1f3a3c7c5db

nginx-0.0.1-2003-11-17-00:49:42 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 16 Nov 2003 21:49:42 +0000
parents d5f50cefc322
children 02a715e85df1
comparison
equal deleted inserted replaced
185:d5f50cefc322 186:c1f3a3c7c5db
4 4
5 5
6 typedef struct ngx_gc_s ngx_gc_t; 6 typedef struct ngx_gc_s ngx_gc_t;
7 7
8 typedef int (*ngx_gc_handler_pt) (ngx_gc_t *ctx, ngx_str_t *name, 8 typedef int (*ngx_gc_handler_pt) (ngx_gc_t *ctx, ngx_str_t *name,
9 ngx_file_info_t *fi); 9 ngx_dir_t *dir);
10
11
12 static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name,
13 ngx_dir_t *dir);
10 14
11 struct ngx_gc_s { 15 struct ngx_gc_s {
12 ngx_path_t *path; 16 ngx_path_t *path;
13 u_int deleted; 17 u_int deleted;
14 off_t freed; 18 off_t freed;
76 path.level[1] = 2; 80 path.level[1] = 2;
77 path.level[2] = 0; 81 path.level[2] = 0;
78 82
79 ctx->path = &path; 83 ctx->path = &path;
80 ctx->log = log; 84 ctx->log = log;
85 ctx->handler = ngx_garbage_collector_temp_handler;
81 86
82 ngx_collect_garbage(ctx, &path.name, 0); 87 ngx_collect_garbage(ctx, &path.name, 0);
83 } 88 }
84 89
85 90
86 static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level) 91 static int ngx_collect_garbage(ngx_gc_t *ctx, ngx_str_t *dname, int level)
87 { 92 {
88 int nlen; 93 int rc, len;
89 char *last; 94 char *last;
90 ngx_str_t fname; 95 ngx_err_t err;
91 ngx_dir_t *dir; 96 ngx_str_t fname, buf;
92 ngx_dirent_t *de; 97 ngx_dir_t dir;
93 ngx_file_info_t fi; 98
94 99 buf.len = 0;
95 fname.len = 0; 100
96 101 ngx_log_debug(ctx->log, "dir '%s':%d" _ dname->data _ dname->len);
97 ngx_log_debug(ctx->log, "dir %s" _ dname->data); 102
98 103 if (ngx_open_dir(dname, &dir) == NGX_ERROR) {
99 dir = ngx_open_dir(dname->data); 104 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
100 105 ngx_open_dir_n " \"%s\" failed", dname->data);
101 if (dir == NULL) {
102 ngx_log_error(NGX_LOG_ERR, ctx->log, ngx_errno,
103 ngx_open_dir_n " \"%s\" failed", dname->data);
104 return NGX_ERROR; 106 return NGX_ERROR;
105 } 107 }
106 108
107 for ( ;; ) { 109 for ( ;; ) {
108 de = ngx_read_dir(dir); 110 ngx_set_errno(0);
109 111 if (ngx_read_dir(&dir) == NGX_ERROR) {
110 if (de == NULL) { 112 err = ngx_errno;
111 if (fname.len) { 113
112 ngx_free(fname.data); 114 if (err != NGX_ENOMOREFILES) {
113 } 115 ngx_log_error(NGX_LOG_CRIT, ctx->log, err,
116 ngx_read_dir_n " \"%s\" failed", dname->data);
117 rc = NGX_ERROR;
118
119 } else {
120 rc = NGX_OK;
121 }
122
114 break; 123 break;
115 } 124 }
116 125
117 ngx_log_debug(ctx->log, "file %s" _ de->d_name); 126 len = ngx_de_namelen(&dir);
118 127
119 #ifdef __FreeBSD__ 128 ngx_log_debug(ctx->log, "name '%s':%d" _ ngx_de_name(&dir) _ len);
120 nlen = de->d_namlen; 129
121 #else 130 if (len == 1 && ngx_de_name(&dir)[0] == '.') {
122 nlen = ngx_strlen(de->d_name);
123 #endif
124
125 if (nlen == 1 && de->d_name[0] == '.') {
126 continue; 131 continue;
127 } 132 }
128 133
129 if (nlen == 2 && de->d_name[0] == '.' && de->d_name[1] == '.') { 134 if (len == 2
135 && ngx_de_name(&dir)[0] == '.'
136 && ngx_de_name(&dir)[1] == '.')
137 {
130 continue; 138 continue;
131 } 139 }
132 140
133 if (dname->len + 1 + nlen > fname.len) { 141 fname.len = dname->len + 1+ len;
134 if (fname.len) { 142
135 ngx_free(fname.data); 143 if (fname.len + NGX_DIR_MASK_LEN > buf.len) {
136 } 144
137 145 if (buf.len) {
138 fname.len = dname->len + 1 + nlen; 146 ngx_free(buf.data);
139 147 }
140 if (!(fname.data = ngx_alloc(fname.len + 1, ctx->log))) { 148
149 buf.len = dname->len + 1 + len + NGX_DIR_MASK_LEN;
150
151 if (!(buf.data = ngx_alloc(buf.len + 1, ctx->log))) {
141 return NGX_ABORT; 152 return NGX_ABORT;
142 } 153 }
143 } 154 }
144 155
145 last = ngx_cpymem(fname.data, dname->data, dname->len); 156 last = ngx_cpymem(buf.data, dname->data, dname->len);
146 *last++ = '/'; 157 *last++ = '/';
147 ngx_memcpy(last, de->d_name, nlen + 1); 158 ngx_memcpy(last, ngx_de_name(&dir), len + 1);
148 159 fname.data = buf.data;
149 ngx_log_debug(ctx->log, "de %s" _ fname.data); 160
150 161 ngx_log_debug(ctx->log, "path %s" _ fname.data);
151 if (ngx_file_type(fname.data, &fi) == NGX_FILE_ERROR) { 162
152 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 163 if (!dir.info_valid) {
153 ngx_file_type_n " \"%s\" failed", fname.data); 164 if (ngx_de_info(fname.data, &dir) == NGX_FILE_ERROR) {
154 continue; 165 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
155 } 166 ngx_de_info_n " \"%s\" failed", fname.data);
156 167 continue;
157 if (ngx_is_dir((&fi))) { 168 }
169 }
170
171 if (ngx_de_is_dir(&dir)) {
158 172
159 ngx_log_debug(ctx->log, "enter %s" _ fname.data); 173 ngx_log_debug(ctx->log, "enter %s" _ fname.data);
160 174
161 if (level == -1 175 if (level == -1
162 /* there can not be directory on the last level */ 176 /* there can not be directory on the last level */
163 || level == NGX_MAX_PATH_LEVEL 177 || level == NGX_MAX_PATH_LEVEL
164 /* an directory from the old path hierarchy */ 178 /* an directory from the old path hierarchy */
165 || nlen != ctx->path->level[level]) 179 || len != ctx->path->level[level])
166 { 180 {
167 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) { 181 if (ngx_collect_garbage(ctx, &fname, -1) == NGX_ABORT) {
168 return NGX_ABORT; 182 return NGX_ABORT;
169 } 183 }
184
185 fname.data[fname.len] = '\0';
170 186
171 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, 187 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
172 "delete old hierachy directory \"%s\"", 188 "delete old hierachy directory \"%s\"",
173 fname.data); 189 fname.data);
174 190
176 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 192 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
177 ngx_delete_dir_n " \"%s\" failed", 193 ngx_delete_dir_n " \"%s\" failed",
178 fname.data); 194 fname.data);
179 } else { 195 } else {
180 ctx->deleted++; 196 ctx->deleted++;
181 ctx->freed += ngx_file_size((&fi)); 197 ctx->freed += ngx_de_size(&dir);
182 } 198 }
183 199
184 continue; 200 continue;
185 } 201 }
186 202
187 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) { 203 if (ngx_collect_garbage(ctx, &fname, level + 1) == NGX_ABORT) {
188 return NGX_ABORT; 204 return NGX_ABORT;
189 } 205 }
190 206
191 } else if (ngx_is_file((&fi))) { 207 } else if (ngx_de_is_file(&dir)) {
208
209 ngx_log_debug(ctx->log, "file %s" _ fname.data);
192 210
193 if (level == -1 211 if (level == -1
194 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0)) 212 || (level < NGX_MAX_PATH_LEVEL && ctx->path->level[level] != 0))
195 { 213 {
196 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { 214 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) {
197 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 215 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
198 ngx_delete_file_n " \"%s\" failed", 216 ngx_delete_file_n " \"%s\" failed",
199 fname.data); 217 fname.data);
200 } else { 218 } else {
201 ctx->deleted++; 219 ctx->deleted++;
202 ctx->freed += ngx_file_size((&fi)); 220 ctx->freed += ngx_de_size(&dir);
203 } 221 }
204 222
205 continue; 223 continue;
206 } 224 }
207 225
208 if (ctx->handler(ctx, &fname, &fi) == NGX_ABORT) { 226 if (ctx->handler(ctx, &fname, &dir) == NGX_ABORT) {
209 return NGX_ABORT; 227 return NGX_ABORT;
210 } 228 }
211 229
212 } else { 230 } else {
213 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 231 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
216 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) { 234 if (ngx_delete_file(fname.data) == NGX_FILE_ERROR) {
217 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 235 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
218 ngx_delete_file_n " \"%s\" failed", fname.data); 236 ngx_delete_file_n " \"%s\" failed", fname.data);
219 } else { 237 } else {
220 ctx->deleted++; 238 ctx->deleted++;
221 ctx->freed += ngx_file_size((&fi)); 239 ctx->freed += ngx_de_size(&dir);
222 } 240 }
223 } 241 }
224 } 242 }
225 243
226 return NGX_OK; 244 if (buf.len) {
227 } 245 ngx_free(buf.data);
228 246 }
229 247
230 int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, 248 if (ngx_close_dir(&dir) == NGX_ERROR) {
231 ngx_file_info_t *fi) 249 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
250 ngx_close_dir_n " \"%s\" failed", fname.data);
251 }
252
253 return rc;
254 }
255
256
257 static int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name,
258 ngx_dir_t *dir)
232 { 259 {
233 /* 260 /*
234 * we use mtime only and do not use atime because: 261 * we use mtime only and do not use atime because:
235 * on NTFS access time has a resolution of 1 hour, 262 * on NTFS access time has a resolution of 1 hour,
236 * on NT FAT access time has a resolution of 1 day, 263 * on NT FAT access time has a resolution of 1 day,
237 * Unices have mount option "noatime" 264 * Unices have mount option "noatime"
238 */ 265 */
239 266
240 if (ngx_cached_time - ngx_file_mtime(fi) < 3600) { 267 if (ngx_cached_time - ngx_de_mtime(dir) < 3600) {
241 return NGX_OK; 268 return NGX_OK;
242 } 269 }
243 270
244 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0, 271 ngx_log_error(NGX_LOG_NOTICE, ctx->log, 0,
245 "delete stale temporary \"%s\"", name->data); 272 "delete stale temporary \"%s\"", name->data);
249 ngx_delete_file_n " \"%s\" failed", name->data); 276 ngx_delete_file_n " \"%s\" failed", name->data);
250 return NGX_ERROR; 277 return NGX_ERROR;
251 } 278 }
252 279
253 ctx->deleted++; 280 ctx->deleted++;
254 ctx->freed += ngx_file_size(fi); 281 ctx->freed += ngx_de_size(dir);
255 return NGX_OK; 282 return NGX_OK;
256 } 283 }