mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
ipa-extdom-exop: add instance counter and limit
The user and group lookups done by the extdom plugin might need some time depending on the state of the service (typically SSSD) handling the requests. To avoid that all worker threads are busy waiting on a connect or a reply from SSSD and no other request can be handled this patch adds an instance counter and an instance limit for the extdom plugin. By default the limit will be around 80% of the number of worker threads. It can be tuned further with the plugin option ipaExtdomMaxInstances which must in set in ipaextdommaxinstances and should have an integer value larger than 0 and lesser than the number of worker threads. If the instance limit is reached the extdom plugin will return LDAP_BUSY for every new request until the number of instance is again below the limit. Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
parent
2e73c964e5
commit
33af8c75b3
@ -157,6 +157,8 @@ struct ipa_extdom_ctx {
|
||||
char *base_dn;
|
||||
size_t max_nss_buf_size;
|
||||
struct nss_ops_ctx *nss_ctx;
|
||||
Slapi_Counter *extdom_instance_counter;
|
||||
size_t extdom_max_instances;
|
||||
};
|
||||
|
||||
struct domain_info {
|
||||
|
@ -62,8 +62,112 @@ static char *ipa_extdom_name_list[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#define NSSLAPD_THREADNUMBER "nsslapd-threadnumber"
|
||||
static int ipa_get_threadnumber(Slapi_ComponentId *plugin_id, size_t *threadnumber)
|
||||
{
|
||||
Slapi_PBlock *search_pb = NULL;
|
||||
int search_result;
|
||||
Slapi_Entry **search_entries = NULL;
|
||||
int ret;
|
||||
char *attrs[] = { NSSLAPD_THREADNUMBER, NULL };
|
||||
|
||||
search_pb = slapi_pblock_new();
|
||||
if (search_pb == NULL) {
|
||||
LOG_FATAL("Failed to create new pblock.\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
slapi_search_internal_set_pb(search_pb, "cn=config",
|
||||
LDAP_SCOPE_BASE, "objectclass=*",
|
||||
attrs, 0, NULL, NULL, plugin_id, 0);
|
||||
|
||||
ret = slapi_search_internal_pb(search_pb);
|
||||
if (ret != 0) {
|
||||
LOG_FATAL("Starting internal search failed.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT,
|
||||
&search_result);
|
||||
if (ret != 0 || search_result != LDAP_SUCCESS) {
|
||||
LOG_FATAL("Internal search failed [%d][%d].\n", ret, search_result);
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
|
||||
&search_entries);
|
||||
if (ret != 0) {
|
||||
LOG_FATAL("Failed to read searched entries.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (search_entries == NULL || search_entries[0] == NULL) {
|
||||
LOG("No existing entries.\n");
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (search_entries[1] != NULL) {
|
||||
LOG("Too many results found.\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*threadnumber = slapi_entry_attr_get_uint(search_entries[0],
|
||||
NSSLAPD_THREADNUMBER);
|
||||
|
||||
if (threadnumber <= 0) {
|
||||
LOG_FATAL("No thread number found.\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
LOG("Found thread number [%zu].\n", *threadnumber);
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
slapi_free_search_results_internal(search_pb);
|
||||
slapi_pblock_destroy(search_pb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ipa_extdom_start(Slapi_PBlock *pb)
|
||||
{
|
||||
int ret;
|
||||
struct ipa_extdom_ctx *ctx;
|
||||
size_t threadnumber;
|
||||
|
||||
ret = slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &ctx);
|
||||
if (ret != 0) {
|
||||
return LDAP_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = ipa_get_threadnumber(ctx->plugin_id, &threadnumber);
|
||||
if (ret != 0) {
|
||||
LOG("Unable to get thread number [%d]!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctx->extdom_max_instances >= threadnumber) {
|
||||
LOG("Option ipaExtdomMaxInstances [%zu] is larger or equal the number "
|
||||
"of worker threads [%zu], using defaults.\n",
|
||||
ctx->extdom_max_instances, threadnumber);
|
||||
ctx->extdom_max_instances = 0;
|
||||
}
|
||||
|
||||
if (ctx->extdom_max_instances == 0) {
|
||||
ctx->extdom_max_instances = (size_t)(threadnumber * 0.8);
|
||||
if (ctx->extdom_max_instances == 0) {
|
||||
ctx->extdom_max_instances = 1;
|
||||
}
|
||||
}
|
||||
|
||||
LOG("Using maximal [%zu] extdom instances for [%zu] threads.\n",
|
||||
ctx->extdom_max_instances, threadnumber);
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -78,6 +182,7 @@ static int ipa_extdom_extop(Slapi_PBlock *pb)
|
||||
struct extdom_req *req = NULL;
|
||||
struct ipa_extdom_ctx *ctx;
|
||||
enum extdom_version version;
|
||||
bool counter_set = false;
|
||||
|
||||
ret = slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &oid);
|
||||
if (ret != 0) {
|
||||
@ -109,6 +214,16 @@ static int ipa_extdom_extop(Slapi_PBlock *pb)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (slapi_counter_get_value(ctx->extdom_instance_counter)
|
||||
> ctx->extdom_max_instances) {
|
||||
rc = LDAP_BUSY;
|
||||
err_msg = "Too many extdom instances running.\n";
|
||||
goto done;
|
||||
}
|
||||
|
||||
slapi_counter_increment(ctx->extdom_instance_counter);
|
||||
counter_set = true;
|
||||
|
||||
ret = parse_request_data(req_val, &req);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||
@ -151,6 +266,14 @@ static int ipa_extdom_extop(Slapi_PBlock *pb)
|
||||
rc = LDAP_SUCCESS;
|
||||
|
||||
done:
|
||||
if (counter_set) {
|
||||
if (slapi_counter_get_value(ctx->extdom_instance_counter) == 0) {
|
||||
LOG("Instance counter already 0, this is unexpected.\n");
|
||||
} else {
|
||||
slapi_counter_decrement(ctx->extdom_instance_counter);
|
||||
}
|
||||
}
|
||||
|
||||
if ((req != NULL) && (req->err_msg != NULL)) {
|
||||
err_msg = req->err_msg;
|
||||
}
|
||||
@ -219,6 +342,16 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
|
||||
back_extdom_set_timeout(ctx->nss_ctx, timeout);
|
||||
LOG("Maximal nss timeout (in ms) set to [%u]!\n", timeout);
|
||||
|
||||
ctx->extdom_max_instances = slapi_entry_attr_get_uint(e, "ipaExtdomMaxInstances");
|
||||
LOG("Maximal instances from config [%zu]!\n", ctx->extdom_max_instances);
|
||||
|
||||
ctx->extdom_instance_counter = slapi_counter_new();
|
||||
if (ctx->extdom_instance_counter == NULL) {
|
||||
LOG("Unable to initialize instance counter!\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
|
Loading…
Reference in New Issue
Block a user