mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-07 05:56:09 +02:00
MINOR: ssl: Factorize ckch instance rebuild process
The ckch instances for a given ckch_store have to be rebuilt when a certificate is updated during runtime (via cli or lua). The code was duplicated in lua so factorizing the actual loop avoids future errors if the code changes. The new 'ckch_store_rebuild_instances' will have a dedicated 0 return code if it needs to be called again (because of the yielding logic since ckch instance rebuild might take some time).
This commit is contained in:
parent
efe6c97488
commit
53ecb81781
@ -50,6 +50,8 @@ void ckch_store_replace(struct ckch_store *old_ckchs, struct ckch_store *new_ckc
|
||||
int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, int cli, const char *file, int linenum, char **err);
|
||||
int ckch_store_create(char *path, char **err);
|
||||
int ckch_store_load_payload(char *path, char *payload, char **err);
|
||||
int ckch_store_rebuild_instances(struct ckch_store *old_ckchs, struct ckch_store *new_ckchs,
|
||||
struct ckch_inst **ckchi, int max, int *count, char **err);
|
||||
|
||||
/* ckch_conf functions */
|
||||
|
||||
|
||||
33
src/hlua.c
33
src/hlua.c
@ -13686,40 +13686,25 @@ __LJMP static int hlua_ckch_commit_yield(lua_State *L, int status, lua_KContext
|
||||
{
|
||||
struct ckch_inst **lua_ckchi = lua_touserdata(L, -1);
|
||||
struct ckch_store **lua_ckchs = lua_touserdata(L, -2);
|
||||
struct ckch_inst *ckchi = *lua_ckchi;
|
||||
struct ckch_store *old_ckchs = lua_ckchs[0];
|
||||
struct ckch_store *new_ckchs = lua_ckchs[1];
|
||||
struct hlua *hlua;
|
||||
char *err = NULL;
|
||||
int y = 1;
|
||||
int retval = 0;
|
||||
|
||||
hlua = hlua_gethlua(L);
|
||||
|
||||
/* get the first ckchi to copy */
|
||||
if (ckchi == NULL)
|
||||
ckchi = LIST_ELEM(old_ckchs->ckch_inst.n, typeof(ckchi), by_ckchs);
|
||||
|
||||
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
|
||||
list_for_each_entry_from(ckchi, &old_ckchs->ckch_inst, by_ckchs) {
|
||||
struct ckch_inst *new_inst;
|
||||
retval = ckch_store_rebuild_instances(old_ckchs, new_ckchs, lua_ckchi,
|
||||
hlua ? 10 : -1, &y, &err);
|
||||
|
||||
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every 10 CKCH instances
|
||||
* during runtime
|
||||
*/
|
||||
if (hlua && (y % 10) == 0) {
|
||||
|
||||
*lua_ckchi = ckchi;
|
||||
|
||||
task_wakeup(hlua->task, TASK_WOKEN_MSG);
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_ckch_commit_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
|
||||
if (ckch_inst_rebuild(new_ckchs, ckchi, &new_inst, &err))
|
||||
goto error;
|
||||
|
||||
/* link the new ckch_inst to the duplicate */
|
||||
LIST_APPEND(&new_ckchs->ckch_inst, &new_inst->by_ckchs);
|
||||
y++;
|
||||
if (retval < 0)
|
||||
goto error;
|
||||
else if (retval == 0) {
|
||||
/* yield */
|
||||
task_wakeup(hlua->task, TASK_WOKEN_MSG);
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_ckch_commit_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
|
||||
/* The generation is finished, we can insert everything */
|
||||
|
||||
@ -2900,6 +2900,51 @@ void ckch_store_replace(struct ckch_store *old_ckchs, struct ckch_store *new_ckc
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rebuild all the ckch instances from <old_ckchs> into <new_ckchs>, using
|
||||
* <ckchi> as the first instance to manage (in case of reentry), and process at
|
||||
* most <max> instances at a time. <count> will be the actual amount of
|
||||
* instances rebuilt.
|
||||
* Return -1 in case of error, 1 if all the instances were rebuilt, 0 if <max>
|
||||
* instances were built and the function should be called again.
|
||||
*/
|
||||
int ckch_store_rebuild_instances(struct ckch_store *old_ckchs, struct ckch_store *new_ckchs,
|
||||
struct ckch_inst **ckchi, int max, int *count, char **err)
|
||||
{
|
||||
|
||||
if (!count)
|
||||
return -1;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* we didn't start yet, set it to the first elem */
|
||||
if (*ckchi == NULL)
|
||||
*ckchi = LIST_ELEM(old_ckchs->ckch_inst.n, struct ckch_inst*, by_ckchs);
|
||||
|
||||
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
|
||||
list_for_each_entry_from((*ckchi), &old_ckchs->ckch_inst, by_ckchs) {
|
||||
struct ckch_inst *new_inst;
|
||||
|
||||
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every <max> CKCH instances */
|
||||
if (max > 0 && *count >= max) {
|
||||
/* yield */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ckch_inst_rebuild(new_ckchs, *ckchi, &new_inst, err)) {
|
||||
/* error */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* link the new ckch_inst to the duplicate */
|
||||
LIST_APPEND(&new_ckchs->ckch_inst, &new_inst->by_ckchs);
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function tries to create the new ckch_inst and their SNIs
|
||||
*
|
||||
@ -2910,7 +2955,7 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
|
||||
struct commit_cert_ctx *ctx = appctx->svcctx;
|
||||
int y = 0;
|
||||
struct ckch_store *old_ckchs, *new_ckchs = NULL;
|
||||
struct ckch_inst *ckchi;
|
||||
int retval = 0;
|
||||
|
||||
usermsgs_clr("CLI");
|
||||
while (1) {
|
||||
@ -2935,39 +2980,30 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
|
||||
old_ckchs = ctx->old_ckchs;
|
||||
new_ckchs = ctx->new_ckchs;
|
||||
|
||||
/* get the next ckchi to regenerate */
|
||||
ckchi = ctx->next_ckchi;
|
||||
/* we didn't start yet, set it to the first elem */
|
||||
if (ckchi == NULL)
|
||||
ckchi = LIST_ELEM(old_ckchs->ckch_inst.n, typeof(ckchi), by_ckchs);
|
||||
/* Rebuild at most 10 ckch instances before yielding */
|
||||
retval = ckch_store_rebuild_instances(old_ckchs, new_ckchs, &ctx->next_ckchi,
|
||||
10, &y, &ctx->err);
|
||||
|
||||
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
|
||||
list_for_each_entry_from(ckchi, &old_ckchs->ckch_inst, by_ckchs) {
|
||||
struct ckch_inst *new_inst;
|
||||
if (retval < 0) {
|
||||
ctx->state = CERT_ST_ERROR;
|
||||
goto error;
|
||||
} else {
|
||||
while (y != 0) {
|
||||
/* display one dot per new instance */
|
||||
if (applet_putstr(appctx, ".") == -1)
|
||||
/* We might not display the proper number of
|
||||
* dots but the instances were actually rebuilt. */
|
||||
goto yield;
|
||||
--y;
|
||||
}
|
||||
|
||||
/* save the next ckchi to compute in case of yield */
|
||||
ctx->next_ckchi = ckchi;
|
||||
|
||||
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every 10 CKCH instances */
|
||||
if (y >= 10) {
|
||||
if (retval == 0) {
|
||||
/* yield */
|
||||
applet_have_more_data(appctx); /* let's come back later */
|
||||
goto yield;
|
||||
}
|
||||
|
||||
/* display one dot per new instance */
|
||||
if (applet_putstr(appctx, ".") == -1)
|
||||
goto yield;
|
||||
|
||||
ctx->err = NULL;
|
||||
if (ckch_inst_rebuild(new_ckchs, ckchi, &new_inst, &ctx->err)) {
|
||||
ctx->state = CERT_ST_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* link the new ckch_inst to the duplicate */
|
||||
LIST_APPEND(&new_ckchs->ckch_inst, &new_inst->by_ckchs);
|
||||
y++;
|
||||
}
|
||||
|
||||
ctx->state = CERT_ST_INSERT;
|
||||
__fallthrough;
|
||||
case CERT_ST_INSERT:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user