static void* xfr_query_axfr_load_thread(void *data) { axfr_query_axfr_load_param *aqalp = (axfr_query_axfr_load_param*) data; ya_result return_value; /* * Now that the access has been cut, this could be done in background, with the loading */ /* * Load the zone again * (other thread, with no zone visible until the very end) */ zdb_zone *newzone = NULL; log_info("slave: zone %{dnsname} transferred", aqalp->origin); /** * Behaviour change : loading an zone file (axfr file) into memory will now drop (invalidate) the zone before * loading it. Else loading a zone like .com would lead to potentially twice the amount of memory made readily * available to yadifa when most of it will remain untouched. * * so: * * invalidate the zone * drop the zone * load the zone */ if(ISOK(return_value = zdb_zone_load((zdb*)aqalp->db, &aqalp->zr, &newzone, g_config->xfr_path, aqalp->origin, ZDB_ZONE_DESTROY_JOURNAL|ZDB_ZONE_IS_SLAVE))) { zassert(newzone != NULL); log_info("slave: zone %{dnsname} loaded", aqalp->origin); aqalp->new_zone = newzone; } else { log_err("slave: zone %{dnsname} failed to load: %r", aqalp->origin, return_value); if(return_value == DNSSEC_ERROR_NSEC3_INVALIDZONESTATE) { /** @todo don't try for a while */ } } zone_reader_close(&aqalp->zr); /* * At this point, since we are a slave, we need to start the alarm again. */ scheduler_schedule_task(xfr_query_final_callback, aqalp); return NULL; }
void scheduler_schedule_thread(scheduler_task_callback* init_function, thread_pool_function* thread_function, void* args, const char* categoryname) { #ifndef NDEBUG log_debug("scheduler: scheduler_schedule_thread(%P, %P, %p, %s)", init_function, thread_function, args, categoryname); #endif pthread_mutex_lock(&scheduler_delayed_queue_mutex); scheduler_thread* thread; MALLOC_OR_DIE(scheduler_thread*, thread, sizeof (scheduler_thread), SCHDTHRD_TAG); thread->task = thread_function; thread->task_init = init_function; thread->args = args; thread->categoryname = categoryname; #ifndef NDEBUG thread->debug_count = debug_count_current++; log_debug("scheduler: enqueue thread %s::(%p, %P, %P, %p@%u)", categoryname, init_function, thread_function, args, thread, thread->debug_count); #endif scheduler_thread_queue_enqueue(&scheduler_delayed_queue, thread); // refire if(!scheduler_thread_running) { scheduler_schedule_task(scheduler_task_dequeue_delayed, NULL); } pthread_mutex_unlock(&scheduler_delayed_queue_mutex); }
static void* scheduler_queue_nsec3_update_thread(void* data_) { zdb_zone *zone = (zdb_zone*)data_; log_info("nsec3: update %{dnsname} NSEC3", zone->origin); zdb_zone_lock(zone, ZDB_ZONE_MUTEX_NSEC3_UPDATER); nsec3_update_zone(zone); zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_NSEC3_UPDATER); log_info("nsec3: update %{dnsname} RRSIG", zone->origin); //zdb_zone_lock(zone, ZDB_ZONE_MUTEX_RRSIG_UPDATER|0x80); zdb_update_zone_signatures(zone, FALSE); //zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_RRSIG_UPDATER|0x80); //zdb_zone_write_text_file(zone, "eu-zone.txt.signed", FALSE); scheduler_schedule_task(scheduler_queue_nsec3_update_callback, zone); /* WARNING: From this point forward, 'zone' cannot be used anymore */ return NULL; }
void battery_init() { //Configure pin for measuring battery voltage BATTERY_VOLTAGE_TRIS = 1; BATTERY_VOLTAGE_DIGITAL = 0; //Configure charger controller for open drain output SOLAR_VOLTAGE_LATCH = 1; SOLAR_VOLTAGE_OD = 1; SOLAR_VOLTAGE_TRIS = 0; SOLAR_VOLTAGE_DIGITAL = 1; //Store ADC configuration batt_adc_config.output_format = kUIntegerFormat; batt_adc_config.trigger = kInternalCounter; batt_adc_config.reference = kVDDVSS; batt_adc_config.enable_in_idle = 0; batt_adc_config.sample_autostart = 1; batt_adc_config.scan_input = 0; batt_adc_config.alternate_muxes = 0; batt_adc_config.autosample_wait = 0b11111; batt_adc_config.oneshot = 1; batt_adc_config.num_samples = 1; charging_allowed = 1; scheduler_schedule_task(battery_callback, kEvery10Seconds, kScheduleForever, &battery_task); }
static void* scheduler_queue_dnskey_create_thread(void* data_) { scheduler_dnskey_create *data = (scheduler_dnskey_create*)data_; ya_result return_value; log_info("dnssec: key create (%{dnsname} %hd %hhd %hd)", data->zone->origin, data->flags, data->algorithm, data->size); char origin[MAX_DOMAIN_LENGTH]; dnsname_to_cstr(origin, data->zone->origin); dnssec_key* key; if(ISOK(return_value = dnssec_key_createnew(DNSKEY_ALGORITHM_RSASHA1_NSEC3, data->size, data->flags, origin, &key))) { if(ISOK(return_value = dnssec_key_store_private(key))) { if(ISOK(return_value = dnssec_key_store_dnskey(key))) { log_info("dnssec: key created (%{dnsname} %hd %hhd %hd)", data->zone->origin, data->flags, data->algorithm, data->size); } else { log_err("dnssec: key store public (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value); } } else { log_err("dnssec: key store private (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value); } } else { log_err("dnssec: key create failed (%{dnsname} %hd %hhd %hd): %r", data->zone->origin, data->flags, data->algorithm, data->size, return_value); } if(ISOK(return_value)) { data->key = key; } else { dnssec_key_free(key); data->key = NULL; } scheduler_schedule_task(scheduler_queue_dnskey_create_callback, data); /* WARNING: From this point forward, 'data' cannot be used anymore */ /* * The key is still in the keystore. * */ return NULL; }
void scheduler_task_nsec3_rrsig_update_commit(zdb_packed_ttlrdata *removed_rrsig_sll, zdb_packed_ttlrdata *added_rrsig_sll, nsec3_zone_item *item, zdb_zone *zone, void *context_to_destroy) { schedule_nsec3_rrsig_update *nsec3_rrsig_update; MALLOC_OR_DIE(schedule_nsec3_rrsig_update*, nsec3_rrsig_update, sizeof(schedule_nsec3_rrsig_update), GENERIC_TAG); nsec3_rrsig_update->removed_rrsig_sll = removed_rrsig_sll; nsec3_rrsig_update->added_rrsig_sll = added_rrsig_sll; nsec3_rrsig_update->item = item; nsec3_rrsig_update->zone = zone; nsec3_rrsig_update->context = context_to_destroy; scheduler_schedule_task(scheduler_task_nsec3_rrsig_update_commit_task, nsec3_rrsig_update); /* WARNING: From this point forward, 'rrsig_update' cannot be used anymore */ }
void scheduler_task_rrsig_update_commit(zdb_packed_ttlrdata* removed_rrsig_sll, zdb_packed_ttlrdata* added_rrsig_sll, zdb_rr_label* label, zdb_zone* zone, dnsname_stack* name, void* context_to_destroy) { schedule_rrsig_update *rrsig_update; MALLOC_OR_DIE(schedule_rrsig_update*, rrsig_update, sizeof(schedule_rrsig_update), GENERIC_TAG); rrsig_update->removed_rrsig_sll = removed_rrsig_sll; /* owned (to destroy) */ rrsig_update->added_rrsig_sll = added_rrsig_sll; /* owned (to destroy) */ rrsig_update->label = label; /* owned by the zone */ rrsig_update->zone = zone; /* the zone */ rrsig_update->name = name; /* this has to be handled somehow ... */ rrsig_update->context = context_to_destroy; /* ... and that's how */ scheduler_schedule_task(scheduler_task_rrsig_update_commit_task, rrsig_update); /* WARNING: From this point forward, 'rrsig_update' cannot be used anymore */ }
static void* scheduler_queue_zone_write_thread(void* data_) { char fullname_tmp[MAX_PATH]; zone_write_param *zwp = (zone_write_param*)data_; zdb_zone *zone = zwp->zone; u32 serial; log_info("zone write text: writing %{dnsname} zone file", zone->origin); if(ZDB_ZONE_INVALID(zone)) { log_err("zone write text: zone %{dnsname} marked as invalid", zone->origin); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); return NULL; } if(FAIL(zdb_zone_getserial(zone, &serial))) { log_err("zone write text: no SOA in %{dnsname}", zone->origin); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); return NULL; } if(FAIL(snformat(fullname_tmp, sizeof (fullname_tmp), "%s.%d.tmp", zwp->file_path, serial))) { log_err("zone write text: path '%s.%d.tmp' is too big", zwp->file_path, serial); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); /* WARNING: From this point forward, 'zone' cannot be used anymore */ return NULL; } /** * @todo check there is not already a zone file writer working here ... * */ /* * delete the temp file if it exists already */ if(unlink(fullname_tmp) < 0) { int err = errno; if(err != ENOENT) { log_err("zone write text: cannot cleanup '%s': %r", MAKE_ERRNO_ERROR(err)); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); /* WARNING: From this point forward, 'zone' cannot be used anymore */ return NULL; } } log_info("zone write text: writing '%s'", fullname_tmp); zdb_zone_lock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER); zdb_zone_write_text_file(zone, fullname_tmp, FALSE); zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER); log_info("zone write text: renaming '%s' to '%s'", fullname_tmp, zwp->file_path); if(rename(fullname_tmp, zwp->file_path) < 0) { log_err("zone write text: unable to rename tmp zone file into '%s': %r", zwp->file_path, ERRNO_ERROR); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); /** @note Calling this so the scheduler gets a SCHEDULER_TASK_FINISHED is mandatory. */ return NULL; } log_info("zone write text: %{dnsname} zone file written", zone->origin); scheduler_schedule_task(scheduler_queue_zone_write_callback, zwp); /* WARNING: From this point forward, 'zwp' cannot be used anymore */ return NULL; }