00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00203 return 0;
00204 }
00205
00206
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 }