OpenDNSSEC-signer
1.3.4
|
00001 /* 00002 * $Id: task.c 4613 2011-03-22 07:54:50Z rb $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "config.h" 00035 #include "scheduler/task.h" 00036 #include "shared/allocator.h" 00037 #include "shared/duration.h" 00038 #include "shared/file.h" 00039 #include "shared/log.h" 00040 #include "signer/backup.h" 00041 00042 static const char* task_str = "task"; 00043 00044 00049 task_type* 00050 task_create(task_id what, time_t when, const char* who, void* zone) 00051 { 00052 allocator_type* allocator = NULL; 00053 task_type* task = NULL; 00054 00055 if (!who || !zone) { 00056 ods_log_error("[%s] cannot create: missing zone info", task_str); 00057 return NULL; 00058 } 00059 ods_log_assert(who); 00060 ods_log_assert(zone); 00061 00062 allocator = allocator_create(malloc, free); 00063 if (!allocator) { 00064 ods_log_error("[%s] cannot create: create allocator failed", task_str); 00065 return NULL; 00066 } 00067 ods_log_assert(allocator); 00068 00069 task = (task_type*) allocator_alloc(allocator, sizeof(task_type)); 00070 if (!task) { 00071 ods_log_error("[%s] cannot create: allocator failed", task_str); 00072 allocator_cleanup(allocator); 00073 return NULL; 00074 } 00075 task->allocator = allocator; 00076 task->what = what; 00077 task->interrupt = TASK_NONE; 00078 task->halted = TASK_NONE; 00079 task->when = when; 00080 task->backoff = 0; 00081 task->who = allocator_strdup(allocator, who); 00082 task->dname = ldns_dname_new_frm_str(who); 00083 task->flush = 0; 00084 task->zone = zone; 00085 return task; 00086 } 00087 00088 00093 task_type* 00094 task_recover_from_backup(const char* filename, void* zone) 00095 { 00096 task_type* task = NULL; 00097 FILE* fd = NULL; 00098 const char* who = NULL; 00099 int what = 0; 00100 time_t when = 0; 00101 int flush = 0; 00102 time_t backoff = 0; 00103 00104 ods_log_assert(zone); 00105 fd = ods_fopen(filename, NULL, "r"); 00106 if (fd) { 00107 if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC) || 00108 !backup_read_check_str(fd, ";who:") || 00109 !backup_read_str(fd, &who) || 00110 !backup_read_check_str(fd, ";what:") || 00111 !backup_read_int(fd, &what) || 00112 !backup_read_check_str(fd, ";when:") || 00113 !backup_read_time_t(fd, &when) || 00114 !backup_read_check_str(fd, ";flush:") || 00115 !backup_read_int(fd, &flush) || 00116 !backup_read_check_str(fd, ";backoff:") || 00117 !backup_read_time_t(fd, &backoff) || 00118 !backup_read_check_str(fd, ODS_SE_FILE_MAGIC)) 00119 { 00120 ods_log_error("[%s] unable to recover task from file %s: file corrupted", 00121 task_str, filename?filename:"(null)"); 00122 task = NULL; 00123 } else { 00124 task = task_create((task_id) what, when, who, (void*) zone); 00125 task->flush = flush; 00126 task->backoff = backoff; 00127 } 00128 free((void*)who); 00129 ods_fclose(fd); 00130 return task; 00131 } 00132 00133 ods_log_debug("[%s] unable to recover task from file %s: no such file or directory", 00134 task_str, filename?filename:"(null)"); 00135 return NULL; 00136 } 00137 00138 00143 void 00144 task_backup(FILE* fd, task_type* task) 00145 { 00146 if (!fd || !task) { 00147 return; 00148 } 00149 ods_log_assert(fd); 00150 ods_log_assert(task); 00151 00152 fprintf(fd, ";;Task: when %u what %i interrupt %i halted %i backoff %i " 00153 "flush %i\n", 00154 (unsigned) task->when, 00155 (int) task->what, 00156 (int) task->interrupt, 00157 (int) task->halted, 00158 (unsigned) task->backoff, 00159 task->flush); 00160 return; 00161 } 00162 00163 00168 void 00169 task_cleanup(task_type* task) 00170 { 00171 allocator_type* allocator; 00172 00173 if (!task) { 00174 return; 00175 } 00176 allocator = task->allocator; 00177 if (task->dname) { 00178 ldns_rdf_deep_free(task->dname); 00179 task->dname = NULL; 00180 } 00181 allocator_deallocate(allocator, (void*) task->who); 00182 allocator_deallocate(allocator, (void*) task); 00183 allocator_cleanup(allocator); 00184 return; 00185 } 00186 00187 00192 int 00193 task_compare(const void* a, const void* b) 00194 { 00195 task_type* x = (task_type*)a; 00196 task_type* y = (task_type*)b; 00197 00198 ods_log_assert(x); 00199 ods_log_assert(y); 00200 00201 if (!ldns_dname_compare((const void*) x->dname, (const void*) y->dname)) { 00202 /* if dname is the same, consider the same task */ 00203 return 0; 00204 } 00205 00206 /* order task on time, what to do, dname */ 00207 if (x->when != y->when) { 00208 return (int) x->when - y->when; 00209 } 00210 if (x->what != y->what) { 00211 return (int) x->what - y->what; 00212 } 00213 return ldns_dname_compare((const void*) x->dname, (const void*) y->dname); 00214 } 00215 00216 00221 const char* 00222 task_what2str(int what) 00223 { 00224 switch (what) { 00225 case TASK_NONE: 00226 return "[do nothing with]"; 00227 break; 00228 case TASK_SIGNCONF: 00229 return "[load signconf for]"; 00230 break; 00231 case TASK_READ: 00232 return "[read]"; 00233 break; 00234 case TASK_NSECIFY: 00235 return "[nsecify]"; 00236 break; 00237 case TASK_SIGN: 00238 return "[sign]"; 00239 break; 00240 case TASK_AUDIT: 00241 return "[audit]"; 00242 break; 00243 case TASK_WRITE: 00244 return "[write]"; 00245 break; 00246 default: 00247 return "[???]"; 00248 break; 00249 } 00250 return "[???]"; 00251 } 00252 00253 00258 const char* 00259 task_who2str(const char* who) 00260 { 00261 if (who) { 00262 return who; 00263 } 00264 return "(null)"; 00265 } 00266 00267 00272 char* 00273 task2str(task_type* task, char* buftask) 00274 { 00275 char* strtime = NULL; 00276 char* strtask = NULL; 00277 00278 if (task) { 00279 strtime = ctime(&task->when); 00280 if (strtime) { 00281 strtime[strlen(strtime)-1] = '\0'; 00282 } 00283 if (buftask) { 00284 (void)snprintf(buftask, ODS_SE_MAXLINE, "%s %s I will %s zone %s" 00285 "\n", task->flush?"Flush":"On", strtime?strtime:"(null)", 00286 task_what2str(task->what), task_who2str(task->who)); 00287 return buftask; 00288 } else { 00289 strtask = (char*) calloc(ODS_SE_MAXLINE, sizeof(char)); 00290 snprintf(strtask, ODS_SE_MAXLINE, "%s %s I will %s zone %s\n", 00291 task->flush?"Flush":"On", strtime?strtime:"(null)", 00292 task_what2str(task->what), task_who2str(task->who)); 00293 return strtask; 00294 } 00295 } 00296 return NULL; 00297 } 00298 00299 00304 void 00305 task_print(FILE* out, task_type* task) 00306 { 00307 char* strtime = NULL; 00308 00309 if (out && task) { 00310 strtime = ctime(&task->when); 00311 if (strtime) { 00312 strtime[strlen(strtime)-1] = '\0'; 00313 } 00314 fprintf(out, "%s %s I will %s zone %s\n", 00315 task->flush?"Flush":"On", strtime?strtime:"(null)", 00316 task_what2str(task->what), task_who2str(task->who)); 00317 } 00318 return; 00319 } 00320 00321 00326 void 00327 task_log(task_type* task) 00328 { 00329 char* strtime = NULL; 00330 00331 if (task) { 00332 strtime = ctime(&task->when); 00333 if (strtime) { 00334 strtime[strlen(strtime)-1] = '\0'; 00335 } 00336 ods_log_debug("[%s] %s %s I will %s zone %s", task_str, 00337 task->flush?"Flush":"On", strtime?strtime:"(null)", 00338 task_what2str(task->what), task_who2str(task->who)); 00339 } 00340 return; 00341 }