OpenDNSSEC-signer  1.3.16
worker.c
Go to the documentation of this file.
1 /*
2  * $Id: worker.c 7298 2013-09-11 11:26:35Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "adapter/adapi.h"
35 #include "daemon/engine.h"
36 #include "daemon/worker.h"
37 #include "shared/allocator.h"
38 #include "scheduler/schedule.h"
39 #include "scheduler/task.h"
40 #include "shared/hsm.h"
41 #include "shared/locks.h"
42 #include "shared/log.h"
43 #include "shared/status.h"
44 #include "shared/util.h"
45 #include "signer/tools.h"
46 #include "signer/zone.h"
47 #include "signer/zonedata.h"
48 
49 #include <time.h> /* time() */
50 
52  { WORKER_WORKER, "worker" },
53  { WORKER_DRUDGER, "drudger" },
54  { 0, NULL }
55 };
56 
57 
64 {
65  worker_type* worker;
66 
67  if (!allocator) {
68  return NULL;
69  }
70  ods_log_assert(allocator);
71 
72  worker = (worker_type*) allocator_alloc(allocator, sizeof(worker_type));
73  if (!worker) {
74  return NULL;
75  }
76 
77  ods_log_debug("create worker[%i]", num +1);
78  lock_basic_init(&worker->worker_lock);
79  lock_basic_set(&worker->worker_alarm);
80  lock_basic_lock(&worker->worker_lock);
82  worker->allocator = allocator;
83  worker->thread_num = num +1;
84  worker->engine = NULL;
85  worker->task = NULL;
86  worker->working_with = TASK_NONE;
87  worker->need_to_exit = 0;
88  worker->type = type;
89  worker->clock_in = 0;
90  worker->jobs_appointed = 0;
91  worker->jobs_completed = 0;
92  worker->jobs_failed = 0;
93  worker->sleeping = 0;
94  worker->waiting = 0;
95  worker->worker_locked = 0;
97  return worker;
98 }
99 
100 
105 static const char*
106 worker2str(worker_id type)
107 {
108  ods_lookup_table *lt = ods_lookup_by_id(worker_str, type);
109  if (lt) {
110  return lt->name;
111  }
112  return NULL;
113 }
114 
115 
120 static int
121 worker_fulfilled(worker_type* worker)
122 {
123  return (worker->jobs_completed + worker->jobs_failed) ==
124  worker->jobs_appointed;
125 }
126 
127 
132 static ods_status
133 worker_check_jobs(worker_type* worker, task_type* task)
134 {
135  ods_status status = ODS_STATUS_OK;
136  ods_log_assert(worker);
137  ods_log_assert(task);
138  lock_basic_lock(&worker->worker_lock);
140  if (worker->jobs_failed) {
141  ods_log_error("[%s[%i]] sign zone %s failed: %u RRsets failed",
142  worker2str(worker->type), worker->thread_num,
143  task_who2str(task->who), worker->jobs_failed);
144  status = ODS_STATUS_ERR;
145  } else if (worker->jobs_completed != worker->jobs_appointed) {
146  ods_log_error("[%s[%i]] sign zone %s failed: processed %u of %u RRsets",
147  worker2str(worker->type), worker->thread_num, task_who2str(task->who),
148  worker->jobs_completed, worker->jobs_appointed);
149  status = ODS_STATUS_ERR;
150  } else if (worker->need_to_exit) {
151  ods_log_warning("[%s[%i]] sign zone %s failed: worker needs to exit",
152  worker2str(worker->type), worker->thread_num,
153  task_who2str(task->who));
154  status = ODS_STATUS_ERR;
155  } else {
156  ods_log_debug("[%s[%i]] sign zone %s ok: %u of %u RRsets succeeded",
157  worker2str(worker->type), worker->thread_num, task_who2str(task->who),
158  worker->jobs_completed, worker->jobs_appointed);
159  ods_log_assert(worker->jobs_appointed == worker->jobs_completed);
160  }
161  worker->worker_locked = 0;
162  lock_basic_unlock(&worker->worker_lock);
163  return status;
164 }
165 
166 
171 static void
172 worker_perform_task(worker_type* worker)
173 {
174  engine_type* engine = NULL;
175  zone_type* zone = NULL;
176  task_type* task = NULL;
177  task_id what = TASK_NONE;
178  time_t when = 0;
179  time_t never = (3600*24*365);
180  ods_status status = ODS_STATUS_OK;
181  int fallthrough = 0;
182  int backup = 0;
183  char* working_dir = NULL;
184  char* cfg_filename = NULL;
185  uint32_t tmpserial = 0;
186  time_t start = 0;
187  time_t end = 0;
188 
189  /* sanity checking */
190  if (!worker || !worker->task || !worker->task->zone || !worker->engine) {
191  return;
192  }
193  ods_log_assert(worker);
194  ods_log_assert(worker->task);
195  ods_log_assert(worker->task->zone);
196 
197  engine = (engine_type*) worker->engine;
198  task = (task_type*) worker->task;
199  zone = (zone_type*) worker->task->zone;
200  ods_log_debug("[%s[%i]] perform task %s for zone %s at %u",
201  worker2str(worker->type), worker->thread_num, task_what2str(task->what),
202  task_who2str(task->who), (uint32_t) worker->clock_in);
203 
204  /* do what you have been told to do */
205  switch (task->what) {
206  case TASK_SIGNCONF:
207  worker->working_with = TASK_SIGNCONF;
208  /* perform 'load signconf' task */
209  ods_log_verbose("[%s[%i]] load signconf for zone %s",
210  worker2str(worker->type), worker->thread_num,
211  task_who2str(task->who));
212  status = zone_load_signconf(zone, &what);
213  if (status == ODS_STATUS_UNCHANGED) {
214  if (!zone->signconf->last_modified) {
215  ods_log_debug("[%s[%i]] no signconf.xml for zone %s yet",
216  worker2str(worker->type), worker->thread_num,
217  task_who2str(task->who));
218  status = ODS_STATUS_ERR;
219  }
220  }
221 
222  /* what to do next */
223  when = time_now();
224  if (status == ODS_STATUS_UNCHANGED) {
225  if (task->halted != TASK_NONE && task->halted != TASK_SIGNCONF) {
226  goto task_perform_continue;
227  } else {
228  status = ODS_STATUS_OK;
229  }
230  }
231 
232  if (status == ODS_STATUS_OK) {
237  lhsm_check_connection((void*)engine);
238  status = zone_publish_dnskeys(zone, 0);
239  }
240  if (status == ODS_STATUS_OK) {
241  status = zone_prepare_nsec3(zone, 0);
242  }
243  if (status == ODS_STATUS_OK) {
244  status = zonedata_commit(zone->zonedata);
245  }
246 
247  if (status == ODS_STATUS_OK) {
248  zone->prepared = 1;
249  task->interrupt = TASK_NONE;
250  task->halted = TASK_NONE;
251  } else {
252  if (task->halted == TASK_NONE) {
253  goto task_perform_fail;
254  }
255  goto task_perform_continue;
256  }
257  fallthrough = 0;
258  break;
259  case TASK_READ:
260  worker->working_with = TASK_READ;
261  /* perform 'read input adapter' task */
262  ods_log_verbose("[%s[%i]] read zone %s",
263  worker2str(worker->type), worker->thread_num,
264  task_who2str(task->who));
265  if (!zone->prepared) {
266  ods_log_debug("[%s[%i]] no valid signconf.xml for zone %s yet",
267  worker2str(worker->type), worker->thread_num,
268  task_who2str(task->who));
269  status = ODS_STATUS_ERR;
270  } else {
271  status = tools_input(zone);
272  }
273 
274  /* what to do next */
275  what = TASK_NSECIFY;
276  when = time_now();
277  if (status != ODS_STATUS_OK) {
278  if (task->halted == TASK_NONE) {
279  goto task_perform_fail;
280  }
281  goto task_perform_continue;
282  }
283  fallthrough = 1;
284  case TASK_NSECIFY:
285  worker->working_with = TASK_NSECIFY;
286  ods_log_verbose("[%s[%i]] nsecify zone %s",
287  worker2str(worker->type), worker->thread_num,
288  task_who2str(task->who));
289  status = tools_nsecify(zone);
290 
291  /* what to do next */
292  what = TASK_SIGN;
293  when = time_now();
294  if (status == ODS_STATUS_OK) {
295  if (task->interrupt > TASK_SIGNCONF) {
296  task->interrupt = TASK_NONE;
297  task->halted = TASK_NONE;
298  }
299  } else {
300  if (task->halted == TASK_NONE) {
301  goto task_perform_fail;
302  }
303  goto task_perform_continue;
304  }
305  fallthrough = 1;
306  case TASK_SIGN:
307  worker->working_with = TASK_SIGN;
308  ods_log_verbose("[%s[%i]] sign zone %s",
309  worker2str(worker->type), worker->thread_num,
310  task_who2str(task->who));
311  tmpserial = zone->zonedata->internal_serial;
312  status = zone_update_serial(zone);
313  if (status != ODS_STATUS_OK) {
314  ods_log_error("[%s[%i]] unable to sign zone %s: "
315  "failed to increment serial",
316  worker2str(worker->type), worker->thread_num,
317  task_who2str(task->who));
318  } else {
319  /* start timer */
320  start = time(NULL);
321  if (zone->stats) {
324  if (!zone->stats->start_time) {
325  zone->stats->start_time = start;
326  }
327  zone->stats->sig_count = 0;
328  zone->stats->sig_soa_count = 0;
329  zone->stats->sig_reuse = 0;
330  zone->stats->sig_time = 0;
331  zone->stats->stats_locked = 0;
333  }
334  /* check the HSM connection before queuing sign operations */
335  lhsm_check_connection((void*)engine);
336  /* prepare keys */
337  status = zone_prepare_keys(zone);
338  if (status == ODS_STATUS_OK) {
339  /* queue menial, hard signing work */
340  status = zonedata_queue(zone->zonedata, engine->signq,
341  worker);
342  ods_log_debug("[%s[%i]] wait until drudgers are finished "
343  "signing zone %s, %u signatures queued",
344  worker2str(worker->type), worker->thread_num,
345  task_who2str(task->who), worker->jobs_appointed);
346  /* sleep until work is done */
347  if (!worker->need_to_exit) {
348  worker_sleep_unless(worker, 0);
349  }
350  }
351  if (status == ODS_STATUS_OK) {
352  status = worker_check_jobs(worker, task);
353  }
354  worker->jobs_appointed = 0;
355  worker->jobs_completed = 0;
356  worker->jobs_failed = 0;
357  /* stop timer */
358  end = time(NULL);
359  if (status == ODS_STATUS_OK && zone->stats) {
362  zone->stats->sig_time = (end-start);
363  zone->stats->stats_locked = 0;
365  }
366  }
367 
368  /* what to do next */
369  if (status != ODS_STATUS_OK) {
370  /* rollback serial */
371  zone->zonedata->internal_serial = tmpserial;
372  if (task->halted == TASK_NONE) {
373  goto task_perform_fail;
374  }
375  goto task_perform_continue;
376  } else {
377  if (task->interrupt > TASK_SIGNCONF) {
378  task->interrupt = TASK_NONE;
379  task->halted = TASK_NONE;
380  }
381  }
382  what = TASK_AUDIT;
383  when = time_now();
384  fallthrough = 1;
385  case TASK_AUDIT:
386  worker->working_with = TASK_AUDIT;
387  if (zone->signconf->audit) {
388  ods_log_verbose("[%s[%i]] audit zone %s",
389  worker2str(worker->type), worker->thread_num,
390  task_who2str(task->who));
391  working_dir = strdup(engine->config->working_dir);
392  cfg_filename = strdup(engine->config->cfg_filename);
393  status = tools_audit(zone, working_dir, cfg_filename);
394  if (working_dir) { free((void*)working_dir); }
395  if (cfg_filename) { free((void*)cfg_filename); }
396  working_dir = NULL;
397  cfg_filename = NULL;
398  } else {
399  status = ODS_STATUS_OK;
400  }
401 
402  /* what to do next */
403  if (status != ODS_STATUS_OK) {
404  if (task->halted == TASK_NONE) {
405  goto task_perform_fail;
406  }
407  goto task_perform_continue;
408  }
409  what = TASK_WRITE;
410  when = time_now();
411  fallthrough = 1;
412  case TASK_WRITE:
413  worker->working_with = TASK_WRITE;
414  ods_log_verbose("[%s[%i]] write zone %s",
415  worker2str(worker->type), worker->thread_num,
416  task_who2str(task->who));
417 
418  status = tools_output(zone);
419  zone->processed = 1;
420 
421  /* what to do next */
422  if (status != ODS_STATUS_OK) {
423  if (task->halted == TASK_NONE) {
424  goto task_perform_fail;
425  }
426  goto task_perform_continue;
427  } else {
428  if (task->interrupt > TASK_SIGNCONF) {
429  task->interrupt = TASK_NONE;
430  task->halted = TASK_NONE;
431  }
432  }
434  what = TASK_SIGN;
435  when = time_now() +
437  } else {
438  what = TASK_NONE;
439  when = time_now() + never;
440  }
441  backup = 1;
442  fallthrough = 0;
443  break;
444  case TASK_NONE:
445  worker->working_with = TASK_NONE;
446  ods_log_warning("[%s[%i]] none task for zone %s",
447  worker2str(worker->type), worker->thread_num,
448  task_who2str(task->who));
449  when = time_now() + never;
450  fallthrough = 0;
451  break;
452  default:
453  ods_log_warning("[%s[%i]] unknown task, trying full sign zone %s",
454  worker2str(worker->type), worker->thread_num,
455  task_who2str(task->who));
456  what = TASK_SIGNCONF;
457  when = time_now();
458  fallthrough = 0;
459  break;
460  }
461 
462  /* no error, reset backoff */
463  task->backoff = 0;
464 
465  /* set next task */
466  if (fallthrough == 0 && task->interrupt != TASK_NONE &&
467  task->interrupt != what) {
468  ods_log_debug("[%s[%i]] interrupt task %s for zone %s",
469  worker2str(worker->type), worker->thread_num,
470  task_what2str(what), task_who2str(task->who));
471 
472  task->what = task->interrupt;
473  task->when = time_now();
474  task->halted = what;
475  } else {
476  ods_log_debug("[%s[%i]] next task %s for zone %s",
477  worker2str(worker->type), worker->thread_num,
478  task_what2str(what), task_who2str(task->who));
479 
480  task->what = what;
481  task->when = when;
482  if (!fallthrough) {
483  task->interrupt = TASK_NONE;
484  task->halted = TASK_NONE;
485  }
486  }
487 
488  /* backup the last successful run */
489  if (backup) {
490  status = zone_backup(zone);
491  if (status != ODS_STATUS_OK) {
492  ods_log_warning("[%s[%i]] unable to backup zone %s: %s",
493  worker2str(worker->type), worker->thread_num,
494  task_who2str(task->who), ods_status2str(status));
495  /* just a warning */
496  status = ODS_STATUS_OK;
497  }
498  backup = 0;
499  }
500  return;
501 
502 task_perform_fail:
503  /* in case of failure, also mark zone processed (for single run usage) */
504  zone->processed = 1;
505 
506  if (task->backoff) {
507  task->backoff *= 2;
508  } else {
509  task->backoff = 60;
510  }
511  if (task->backoff > ODS_SE_MAX_BACKOFF) {
512  task->backoff = ODS_SE_MAX_BACKOFF;
513  }
514  ods_log_info("[%s[%i]] backoff task %s for zone %s with %u seconds",
515  worker2str(worker->type), worker->thread_num,
516  task_what2str(task->what), task_who2str(task->who), task->backoff);
517 
518  task->when = time_now() + task->backoff;
519  return;
520 
521 task_perform_continue:
522  ods_log_info("[%s[%i]] continue task %s for zone %s",
523  worker2str(worker->type), worker->thread_num,
524  task_what2str(task->halted), task_who2str(task->who));
525 
526  what = task->halted;
527  task->what = what;
528  task->when = time_now();
529  task->interrupt = TASK_NONE;
530  task->halted = TASK_NONE;
531  if (zone->processed) {
533  }
534  return;
535 }
536 
537 
542 static void
543 worker_work(worker_type* worker)
544 {
545  time_t now, timeout = 1;
546  zone_type* zone = NULL;
547 
548  ods_log_assert(worker);
549  ods_log_assert(worker->type == WORKER_WORKER);
550 
551  while (worker->need_to_exit == 0) {
552  ods_log_debug("[%s[%i]] report for duty", worker2str(worker->type),
553  worker->thread_num);
554  now = time_now();
557  worker->task = schedule_pop_task(worker->engine->taskq);
558  if (worker->task) {
559  worker->working_with = worker->task->what;
560  worker->engine->taskq->schedule_locked = 0;
562 
563  zone = worker->task->zone;
564  lock_basic_lock(&zone->zone_lock);
565  zone->zone_locked = LOCKED_ZONE_WORKER(worker->thread_num);
566  ods_log_debug("[%s[%i]] start working on zone %s",
567  worker2str(worker->type), worker->thread_num, zone->name);
568 
569  worker->clock_in = time(NULL);
570  worker_perform_task(worker);
571 
572  zone->task = worker->task;
573 
574  ods_log_debug("[%s[%i]] finished working on zone %s",
575  worker2str(worker->type), worker->thread_num, zone->name);
576 
579  worker->task = NULL;
580  worker->working_with = TASK_NONE;
581  (void) schedule_task(worker->engine->taskq, zone->task, 1);
582  worker->engine->taskq->schedule_locked = 0;
584  zone->zone_locked = 0;
586 
587  timeout = 1;
588  } else {
589  ods_log_debug("[%s[%i]] nothing to do", worker2str(worker->type),
590  worker->thread_num);
591  worker->task = schedule_get_first_task(worker->engine->taskq);
592  worker->engine->taskq->schedule_locked = 0;
594  if (worker->task && !worker->engine->taskq->loading) {
595  timeout = (worker->task->when - now);
596  } else {
597  timeout *= 2;
598  }
599  if (timeout > ODS_SE_MAX_BACKOFF) {
600  timeout = ODS_SE_MAX_BACKOFF;
601  }
602  worker->task = NULL;
603  worker_sleep(worker, timeout);
604  }
605  }
606  /* stop worker, wipe queue */
607  fifoq_wipe(worker->engine->signq);
608  return;
609 }
610 
611 
616 static void
617 worker_drudge(worker_type* worker)
618 {
619  engine_type* engine = NULL;
620  zone_type* zone = NULL;
621  task_type* task = NULL;
622  rrset_type* rrset = NULL;
623  ods_status status = ODS_STATUS_OK;
624  worker_type* chief = NULL;
625  hsm_ctx_t* ctx = NULL;
626 
627  ods_log_assert(worker);
628  ods_log_assert(worker->type == WORKER_DRUDGER);
629 
630  engine = (engine_type*) worker->engine;
631  while (worker->need_to_exit == 0) {
632  ods_log_debug("[%s[%i]] report for duty", worker2str(worker->type),
633  worker->thread_num);
634  chief = NULL;
635  zone = NULL;
636  task = NULL;
637 
638  lock_basic_lock(&worker->engine->signq->q_lock);
639  worker->engine->signq->q_locked = LOCKED_Q_DRUDGER(worker->thread_num);
640  rrset = (rrset_type*) fifoq_pop(worker->engine->signq, &chief);
641  if (!rrset) {
642  ods_log_deeebug("[%s[%i]] nothing to do", worker2str(worker->type),
643  worker->thread_num);
644  worker->engine->signq->q_locked =
646  worker_wait_locked(&engine->signq->q_lock,
647  &engine->signq->q_threshold);
648  worker->engine->signq->q_locked = LOCKED_Q_DRUDGER(worker->thread_num);
649  rrset = (rrset_type*) fifoq_pop(engine->signq, &chief);
650  }
651  worker->engine->signq->q_locked = 0;
652  lock_basic_unlock(&worker->engine->signq->q_lock);
653  if (rrset) {
654  ods_log_assert(chief);
655  ods_log_debug("[%s[%i]] create hsm context",
656  worker2str(worker->type), worker->thread_num);
657  if (!ctx) {
658  ctx = hsm_create_context();
659  }
660  if (!ctx) {
661  ods_log_crit("[%s[%i]] error creating libhsm context",
662  worker2str(worker->type), worker->thread_num);
663  engine->need_to_reload = 1;
664  chief->jobs_failed++;
665  } else {
666  ods_log_assert(ctx);
667  lock_basic_lock(&chief->worker_lock);
669  task = chief->task;
670  ods_log_assert(task);
671  zone = task->zone;
672  chief->worker_locked = 0;
674  ods_log_assert(zone);
675  ods_log_assert(zone->signconf);
676  ods_log_assert(rrset);
677 
678  worker->clock_in = time(NULL);
679  status = rrset_sign(ctx, rrset, zone->dname, zone->signconf,
680  chief->clock_in, zone->stats);
681  lock_basic_lock(&chief->worker_lock);
683  if (status == ODS_STATUS_OK) {
684  chief->jobs_completed += 1;
685  } else {
686  chief->jobs_failed += 1;
687  }
688  worker->worker_locked = 0;
690  }
691  if (worker_fulfilled(chief) && chief->sleeping) {
692  ods_log_debug("[%s[%i]] wake up chief[%u], work is done",
693  worker2str(worker->type), worker->thread_num,
694  chief->thread_num);
695  worker_wakeup(chief);
696  }
697  }
698  }
699  /* stop drudger */
700 
701  if (chief && chief->sleeping) {
702  /* wake up chief */
703  ods_log_debug("[%s[%i]] wake up chief[%u], i am exiting",
704  worker2str(worker->type), worker->thread_num, chief->thread_num);
705  worker_wakeup(chief);
706  }
707  if (ctx) {
708  /* cleanup open HSM sessions */
709  ods_log_debug("[%s[%i]] destroy hsm context",
710  worker2str(worker->type), worker->thread_num);
711  hsm_destroy_context(ctx);
712  }
713  return;
714 }
715 
716 
721 void
723 {
724  ods_log_assert(worker);
725  switch (worker->type) {
726  case WORKER_DRUDGER:
727  worker_drudge(worker);
728  break;
729  case WORKER_WORKER:
730  worker_work(worker);
731  break;
732  default:
733  ods_log_error("[worker] illegal worker (id=%i)", worker->type);
734  return;
735  }
736  return;
737 }
738 
739 
744 void
745 worker_sleep(worker_type* worker, time_t timeout)
746 {
747  ods_log_assert(worker);
748  lock_basic_lock(&worker->worker_lock);
750  worker->sleeping = 1;
751  lock_basic_sleep(&worker->worker_alarm, &worker->worker_lock,
752  timeout);
753  worker->worker_locked = 0;
754  lock_basic_unlock(&worker->worker_lock);
755  return;
756 }
757 
758 
763 void
764 worker_sleep_unless(worker_type* worker, time_t timeout)
765 {
766  ods_log_assert(worker);
767  lock_basic_lock(&worker->worker_lock);
769  while (!worker->need_to_exit && !worker_fulfilled(worker)) {
770  worker->sleeping = 1;
771  lock_basic_sleep(&worker->worker_alarm, &worker->worker_lock,
772  timeout);
773 
774  ods_log_debug("[%s[%i]] somebody poked me, check completed jobs %u "
775  "appointed, %u completed, %u failed", worker2str(worker->type),
776  worker->thread_num, worker->jobs_appointed, worker->jobs_completed,
777  worker->jobs_failed);
778  }
779  worker->worker_locked = 0;
780  lock_basic_unlock(&worker->worker_lock);
781  return;
782 }
783 
784 
789 void
791 {
792  ods_log_assert(worker);
793  if (worker->sleeping) {
794  ods_log_debug("[%s[%i]] wake up", worker2str(worker->type),
795  worker->thread_num);
796  lock_basic_lock(&worker->worker_lock);
798  lock_basic_alarm(&worker->worker_alarm);
799  worker->sleeping = 0;
800  worker->worker_locked = 0;
801  lock_basic_unlock(&worker->worker_lock);
802  }
803  return;
804 }
805 
806 
811 void
812 worker_wait_timeout(lock_basic_type* lock, cond_basic_type* condition,
813  time_t timeout)
814 {
815  lock_basic_lock(lock);
816  lock_basic_sleep(condition, lock, timeout);
817  lock_basic_unlock(lock);
818  return;
819 }
820 
821 
826 void
827 worker_wait_timeout_locked(lock_basic_type* lock, cond_basic_type* condition,
828  time_t timeout)
829 {
830  lock_basic_sleep(condition, lock, timeout);
831  return;
832 }
833 
834 
839 void
840 worker_wait(lock_basic_type* lock, cond_basic_type* condition)
841 {
842  worker_wait_timeout(lock, condition, 0);
843  return;
844 }
845 
846 
851 void
852 worker_wait_locked(lock_basic_type* lock, cond_basic_type* condition)
853 {
854  worker_wait_timeout_locked(lock, condition, 0);
855  return;
856 }
857 
858 
863 void
864 worker_notify(lock_basic_type* lock, cond_basic_type* condition)
865 {
866  lock_basic_lock(lock);
867  lock_basic_alarm(condition);
868  lock_basic_unlock(lock);
869  return;
870 }
871 
872 
877 void
878 worker_notify_all(lock_basic_type* lock, cond_basic_type* condition)
879 {
880  lock_basic_lock(lock);
881  lock_basic_broadcast(condition);
882  lock_basic_unlock(lock);
883  return;
884 }
885 
886 
891 void
893 {
895  cond_basic_type worker_cond;
896  lock_basic_type worker_lock;
897 
898  if (!worker) {
899  return;
900  }
901  allocator = worker->allocator;
902  worker_cond = worker->worker_alarm;
903  worker_lock = worker->worker_lock;
904 
905  allocator_deallocate(allocator, (void*) worker);
906  lock_basic_destroy(&worker_lock);
907  lock_basic_off(&worker_cond);
908  return;
909 }
int prepared
Definition: zone.h:74
#define lock_basic_off(cond)
Definition: locks.h:161
Definition: task.h:43
int waiting
Definition: worker.h:66
size_t jobs_completed
Definition: worker.h:63
const char * cfg_filename
Definition: cfg.h:53
#define LOCKED_WORKER_SIGN
Definition: locks.h:84
task_type * schedule_get_first_task(schedule_type *schedule)
Definition: schedule.c:271
void ods_log_debug(const char *format,...)
Definition: log.c:285
time_t when
Definition: task.h:62
uint32_t internal_serial
Definition: zonedata.h:67
size_t jobs_appointed
Definition: worker.h:62
lock_basic_type worker_lock
Definition: worker.h:69
#define lock_basic_destroy(lock)
Definition: locks.h:153
cond_basic_type q_threshold
Definition: fifoq.h:68
task_id interrupt
Definition: task.h:60
int schedule_locked
Definition: schedule.h:66
#define LOCKED_WORKER_SLEEP
Definition: locks.h:85
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:67
void lhsm_check_connection(void *engine)
Definition: hsm.c:114
lock_basic_type q_lock
Definition: fifoq.h:67
time_t sig_time
Definition: stats.h:65
#define LOCKED_WORKER_INIT
Definition: locks.h:83
ods_status schedule_task(schedule_type *schedule, task_type *task, int log)
Definition: schedule.c:154
void ods_log_info(const char *format,...)
Definition: log.c:317
allocator_type * allocator
Definition: engine.h:56
enum ods_enum_status ods_status
Definition: status.h:64
void worker_start(worker_type *worker)
Definition: worker.c:722
lock_basic_type zone_lock
Definition: zone.h:93
time_t backoff
Definition: task.h:63
int worker_locked
Definition: worker.h:70
int need_to_exit
Definition: worker.h:67
ldns_rdf * dname
Definition: zone.h:59
ods_status zone_backup(zone_type *zone)
Definition: zone.c:709
ods_status zone_publish_dnskeys(zone_type *zone, int recover)
Definition: zone.c:510
ods_status tools_audit(zone_type *zone, char *working_dir, char *cfg_filename)
Definition: tools.c:263
void ods_log_error(const char *format,...)
Definition: log.c:349
lock_basic_type stats_lock
Definition: stats.h:69
const char * ods_status2str(ods_status status)
Definition: status.c:84
Definition: task.h:47
#define LOCKED_WORKER_DRUDGER(x)
Definition: locks.h:96
void * zone
Definition: task.h:67
ods_lookup_table * ods_lookup_by_id(ods_lookup_table *table, int id)
Definition: status.c:67
ods_status rrset_sign(hsm_ctx_t *ctx, rrset_type *rrset, ldns_rdf *owner, signconf_type *sc, time_t signtime, stats_type *stats)
Definition: rrset.c:957
#define LOCKED_SCHEDULE_WORKER(x)
Definition: locks.h:94
void worker_cleanup(worker_type *worker)
Definition: worker.c:892
int q_locked
Definition: fifoq.h:70
void worker_wait_timeout_locked(lock_basic_type *lock, cond_basic_type *condition, time_t timeout)
Definition: worker.c:827
#define lock_basic_set(cond)
Definition: locks.h:157
enum task_id_enum task_id
Definition: task.h:51
struct engine_struct * engine
Definition: worker.h:57
#define LOCKED_Q_DRUDGER(x)
Definition: locks.h:93
ods_status zone_load_signconf(zone_type *zone, task_id *tbs)
Definition: zone.c:371
void ods_log_crit(const char *format,...)
Definition: log.c:365
size_t jobs_failed
Definition: worker.h:64
void worker_wait(lock_basic_type *lock, cond_basic_type *condition)
Definition: worker.c:840
ods_status tools_input(zone_type *zone)
Definition: tools.c:49
task_type * task
Definition: worker.h:58
#define lock_basic_lock(lock)
Definition: locks.h:154
engineconfig_type * config
Definition: engine.h:57
#define LOCKED_SLEEP_DRUDGER(x)
Definition: locks.h:100
Definition: task.h:45
void worker_sleep(worker_type *worker, time_t timeout)
Definition: worker.c:745
#define lock_basic_sleep(cond, lock, sleep)
Definition: locks.h:158
time_t clock_in
Definition: worker.h:61
int lock_basic_type
Definition: locks.h:151
task_type * schedule_pop_task(schedule_type *schedule)
Definition: schedule.c:316
void worker_notify_all(lock_basic_type *lock, cond_basic_type *condition)
Definition: worker.c:878
signconf_type * signconf
Definition: zone.h:81
time_t start_time
Definition: stats.h:67
ods_status zone_update_serial(zone_type *zone)
Definition: zone.c:1207
task_id halted
Definition: task.h:61
const char * who
Definition: task.h:65
#define LOCKED_WORKER_SLEEP_UNLESS
Definition: locks.h:86
int processed
Definition: zone.h:73
#define LOCKED_WORKER_WAKEUP
Definition: locks.h:87
void worker_wakeup(worker_type *worker)
Definition: worker.c:790
uint32_t sig_reuse
Definition: stats.h:64
int zone_locked
Definition: zone.h:94
void fifoq_wipe(fifoq_type *q)
Definition: fifoq.c:82
enum worker_enum worker_id
Definition: worker.h:48
const char * task_what2str(int what)
Definition: task.c:222
void worker_sleep_unless(worker_type *worker, time_t timeout)
Definition: worker.c:764
time_t duration2time(duration_type *duration)
Definition: duration.c:340
const char * task_who2str(const char *who)
Definition: task.c:259
const char * working_dir
Definition: cfg.h:60
void ods_log_verbose(const char *format,...)
Definition: log.c:301
time_t last_modified
Definition: signconf.h:78
const char * name
Definition: status.h:69
void worker_wait_locked(lock_basic_type *lock, cond_basic_type *condition)
Definition: worker.c:852
ods_status tools_output(zone_type *zone)
Definition: tools.c:362
task_id what
Definition: task.h:59
#define lock_basic_init(lock)
Definition: locks.h:152
int thread_num
Definition: worker.h:55
const char * name
Definition: zone.h:67
ods_status zonedata_commit(zonedata_type *zd)
Definition: zonedata.c:687
schedule_type * taskq
Definition: engine.h:61
uint32_t sig_soa_count
Definition: stats.h:63
ods_status zone_prepare_keys(zone_type *zone)
Definition: zone.c:1164
duration_type * sig_resign_interval
Definition: signconf.h:56
cond_basic_type worker_alarm
Definition: worker.h:68
void ods_log_deeebug(const char *format,...)
Definition: log.c:269
int sleeping
Definition: worker.h:65
worker_type * worker_create(allocator_type *allocator, int num, worker_id type)
Definition: worker.c:63
ods_status zone_prepare_nsec3(zone_type *zone, int recover)
Definition: zone.c:616
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:136
uint32_t sig_count
Definition: stats.h:62
int stats_locked
Definition: stats.h:70
task_id working_with
Definition: worker.h:59
lock_basic_type schedule_lock
Definition: schedule.h:65
worker_id type
Definition: worker.h:60
void worker_wait_timeout(lock_basic_type *lock, cond_basic_type *condition, time_t timeout)
Definition: worker.c:812
ods_status tools_nsecify(zone_type *zone)
Definition: tools.c:174
void * task
Definition: zone.h:88
fifoq_type * signq
Definition: engine.h:62
zonedata_type * zonedata
Definition: zone.h:85
#define ods_log_assert(x)
Definition: log.h:141
#define LOCKED_STATS_WORKER(x)
Definition: locks.h:98
int need_to_reload
Definition: engine.h:73
#define LOCKED_ZONE_WORKER(x)
Definition: locks.h:97
#define lock_basic_alarm(cond)
Definition: locks.h:159
#define lock_basic_unlock(lock)
Definition: locks.h:155
void ods_log_warning(const char *format,...)
Definition: log.c:333
allocator_type * allocator
Definition: worker.h:54
void worker_notify(lock_basic_type *lock, cond_basic_type *condition)
Definition: worker.c:864
ods_status zonedata_queue(zonedata_type *zd, fifoq_type *q, worker_type *worker)
Definition: zonedata.c:1295
time_t time_now(void)
Definition: duration.c:479
ods_lookup_table worker_str[]
Definition: worker.c:51
stats_type * stats
Definition: zone.h:91
#define lock_basic_broadcast(cond)
Definition: locks.h:160
void * fifoq_pop(fifoq_type *q, worker_type **worker)
Definition: fifoq.c:100