- auth-load-thread, add num auth transfers and wait_transfer list.

This commit is contained in:
W.C.A. Wijngaards
2026-10-05 16:44:10 +02:00
parent 8942d11bb3
commit bb408e503c
4 changed files with 209 additions and 0 deletions
+128
View File
@@ -880,6 +880,15 @@ struct auth_load_general_info* auth_load_info_create(void)
lock_protect(&auth_load_info->lock,
&auth_load_info->num_auth_load_threads,
sizeof(auth_load_info->num_auth_load_threads));
lock_protect(&auth_load_info->lock,
&auth_load_info->num_auth_transfers,
sizeof(auth_load_info->num_auth_transfers));
lock_protect(&auth_load_info->lock,
&auth_load_info->wait_transfer_list,
sizeof(auth_load_info->wait_transfer_list));
lock_protect(&auth_load_info->lock,
&auth_load_info->wait_transfer_last,
sizeof(auth_load_info->wait_transfer_last));
return auth_load_info;
}
@@ -919,3 +928,122 @@ void auth_load_info_release_thread(struct module_env* env)
}
lock_basic_unlock(&auth_load_info->lock);
}
int auth_load_info_grab_transfer_in_progress(struct module_env* env)
{
struct auth_load_general_info* auth_load_info =
env->worker->daemon->auth_load_info;
struct config_file* cfg = env->cfg;
int ret = 0;
lock_basic_lock(&auth_load_info->lock);
if(auth_load_info->num_auth_transfers < cfg->auth_task_threads) {
ret = 1;
auth_load_info->num_auth_transfers++;
}
lock_basic_unlock(&auth_load_info->lock);
return ret;
}
void auth_load_info_release_transfer_in_progress(struct module_env* env)
{
struct auth_load_general_info* auth_load_info =
env->worker->daemon->auth_load_info;
lock_basic_lock(&auth_load_info->lock);
if(auth_load_info->num_auth_transfers == 0) {
verbose(VERB_ALGO, "release of auth load transfer, but "
"num_auth_transfers not > 0.");
} else {
auth_load_info->num_auth_transfers--;
}
lock_basic_unlock(&auth_load_info->lock);
}
int
xfr_transfer_grab_active(struct auth_xfer* xfr)
{
if(xfr->task_transfer->active_transfer) {
char zname[LDNS_MAX_DOMAINLEN];
dname_str(xfr->name, zname);
log_err("task transfer already active when activated transfer "
"%s", zname);
return 1;
}
xfr->task_transfer->active_transfer = 1;
return auth_load_info_grab_transfer_in_progress(
xfr->task_transfer->env);
}
/** Schedule pick up of waiting transfers. */
static void
xfr_transfer_schedule_waiting_pickup(struct auth_xfer* xfr)
{
struct auth_load_general_info* auth_load_info =
env->worker->daemon->auth_load_info;
int waiting = 0;
lock_basic_lock(&auth_load_info->lock);
if(auth_load_info->wait_transfer_list)
waiting = 1;
lock_basic_unlock(&auth_load_info->lock);
if(waiting) {
}
}
void
xfr_transfer_release_active(struct auth_xfer* xfr)
{
if(!xfr->task_transfer->active_transfer)
return;
auth_load_info_release_transfer_in_progress(xfr->task_transfer->env);
xfr->task_transfer->active_transfer = 0;
/* Since a transfer is no longer in progress, see if there are
* waiting transfers. If so, schedule them to get picked up. */
xfr_transfer_schedule_waiting_pickup(xfr);
}
void
xfr_transfer_wait_active(struct auth_xfer* xfr)
{
struct auth_load_general_info* auth_load_info =
xfr->task_transfer->env->worker->daemon->auth_load_info;
if(xfr->task_transfer->on_wait_transfer_list)
return;
lock_basic_lock(&auth_load_info->lock);
xfr->task_transfer->wait_transfer_prev =
auth_load_info->wait_transfer_last;
xfr->task_transfer->wait_transfer_next = NULL;
if(auth_load_info->wait_transfer_last)
auth_load_info->wait_transfer_last->task_transfer->
wait_transfer_next = xfr;
else auth_load_info->wait_transfer_list = xfr;
auth_load_info->wait_transfer_last = xfr;
lock_basic_unlock(&auth_load_info->lock);
xfr->task_transfer->on_wait_transfer_list = 1;
}
void
xfr_transfer_remove_wait_transfer_list(struct auth_xfer* xfr)
{
struct auth_load_general_info* auth_load_info =
xfr->task_transfer->env->worker->daemon->auth_load_info;
if(!xfr->task_transfer->on_wait_transfer_list)
return;
lock_basic_lock(&auth_load_info->lock);
if(xfr->task_transfer->wait_transfer_prev)
xfr->task_transfer->wait_transfer_prev->task_transfer->
wait_transfer_next =
xfr->task_transfer->wait_transfer_next;
else auth_load_info->wait_transfer_list =
xfr->task_transfer->wait_transfer_next;
if(xfr->task_transfer->wait_transfer_next)
xfr->task_transfer->wait_transfer_next->task_transfer->
wait_transfer_prev =
xfr->task_transfer->wait_transfer_prev;
else auth_load_info->wait_transfer_last =
xfr->task_transfer->wait_transfer_prev;
lock_basic_unlock(&auth_load_info->lock);
xfr->task_transfer->wait_transfer_prev = NULL;
xfr->task_transfer->wait_transfer_next = NULL;
xfr->task_transfer->on_wait_transfer_list = 0;
}
+47
View File
@@ -57,6 +57,14 @@ struct auth_load_general_info {
lock_basic_type lock;
/** The number of active auth load threads. */
int num_auth_load_threads;
/** The number of active downloads, zone transfers in progress.
* These are going to need an auth load thread when done. The counter
* is decremented when the thread and transfer have completed. */
int num_auth_transfers;
/** The auth zone xfer transfer wait list */
struct auth_xfer* wait_transfer_list;
/** The last item of the wait_transfer list. */
struct auth_xfer* wait_transfer_last;
};
/**
@@ -200,4 +208,43 @@ int auth_load_info_grab_thread(struct module_env* env);
*/
void auth_load_info_release_thread(struct module_env* env);
/**
* Grab a new transfer in progress, this is limited by the auth load count.
* @param env: with auth_load_info with the active transfer number.
* and config file, with configured maximum.
* @return false on failure, like too many active, true if successful.
*/
int auth_load_info_grab_transfer_in_progress(struct module_env* env);
/**
* Release transfer from active count. It is done.
* @param env: with auth_load_info with the active transfer count.
*/
void auth_load_info_release_transfer_in_progress(struct module_env* env);
/**
* Make transfer active in the in progress transfer count.
* @param xfr: the xfr is in progress
* @return false if not possible.
*/
int xfr_transfer_grab_active(struct auth_xfer* xfr);
/**
* Release active transfer from in progress transfer count.
* @param xfr: the xfr is no longer in progress.
*/
void xfr_transfer_release_active(struct auth_xfer* xfr);
/**
* Add transfer to wait_transfer list. It can not become active right now.
* @param xfr: the xfr is put on the wait_transfer list.
*/
void xfr_transfer_wait_active(struct auth_xfer* xfr);
/**
* Remove xfr from wait_transfer list
* @param xfr: the xfr is removed from the wait_transfer list.
*/
void xfr_transfer_remove_wait_transfer_list(struct auth_xfer* xfr);
#endif /* SERVICES_AUTHLOAD_H */
+25
View File
@@ -5716,6 +5716,8 @@ xfr_transfer_disown(struct auth_xfer* xfr)
xfr->task_transfer->lookup_aaaa, xfr->dclass,
xfr->task_transfer->env->mesh,
&auth_xfer_transfer_lookup_callback, xfr);
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
/* we don't own this item anymore */
xfr->task_transfer->worker = NULL;
xfr->task_transfer->env = NULL;
@@ -5934,11 +5936,26 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
/* and set timeout on it */
while(!xfr_transfer_end_of_list(xfr)) {
xfr->task_transfer->master = xfr_transfer_current_master(xfr);
if(xfr->task_transfer->master &&
!xfr->task_transfer->master->allow_notify &&
env->cfg->auth_task_threads != 0) {
if(!xfr_transfer_grab_active(xfr)) {
/* Can not get another transfer to have in
* progress, wait to do this later, when other
* transfers are done. */
xfr_transfer_wait_active(xfr);
lock_basic_unlock(&xfr->lock);
return;
}
}
if(xfr_transfer_init_fetch(xfr, env)) {
/* successfully started, wait for callback */
lock_basic_unlock(&xfr->lock);
return;
}
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
/* failed to fetch, next master */
xfr_transfer_nextmaster(xfr);
}
@@ -6522,6 +6539,8 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
}
/* when done, delete data from list */
auth_chunks_delete(xfr->task_transfer);
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
xfr_process_transfer_failed(xfr, env, ixfr_fail);
}
@@ -6674,6 +6693,8 @@ void xfr_process_load_end_transfer(struct auth_xfer* xfr,
/* the zone is gone from the authzones. */
lock_basic_unlock(&xfr->lock);
auth_chunks_delete(xfr->task_transfer);
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
return;
}
}
@@ -6689,6 +6710,8 @@ void xfr_process_load_end_transfer(struct auth_xfer* xfr,
}
/* The transfer failed */
verbose(VERB_ALGO, "xfr_process_load_end_transfer: failed");
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
xfr_process_transfer_failed(xfr, env, ixfr_fail);
}
@@ -6785,6 +6808,8 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
auth_chunks_delete(xfr->task_transfer);
comm_point_delete(xfr->task_transfer->cp);
xfr->task_transfer->cp = NULL;
xfr_transfer_remove_wait_transfer_list(xfr);
xfr_transfer_release_active(xfr);
if(gonextonfail)
xfr_transfer_nextmaster(xfr);
xfr_transfer_nexttarget_or_end(xfr, env);
+9
View File
@@ -405,6 +405,15 @@ struct auth_transfer {
size_t chunks_total;
/** start time of the transfer */
struct timeval start_time;
/** if the transfer is active and in the in progress count. */
int active_transfer;
/** if the transfer is on the wait_transfer list (it waits to
* become active). */
int on_wait_transfer_list;
/** If on the wait_transfer list, the previous list item. */
struct auth_xfer* wait_transfer_prev;
/** If on the wait_transfer list, the next list item. */
struct auth_xfer* wait_transfer_next;
/** list of upstream masters for this zone, from config */
struct auth_master* masters;