Merge branch 'ondrej-cleanup-extra-memory-context-in-dns_zone' into 'main'

Cleanup the tasks and memory contexts in dns_zone

Closes #3226 and #3159

See merge request isc-projects/bind9!6004
This commit is contained in:
Ondřej Surý 2022-04-01 21:54:55 +00:00
commit 0519a5bfe9
20 changed files with 277 additions and 1478 deletions

View file

@ -1,3 +1,10 @@
5846. [func] In dns_zonemgr, create per-thread task, zonetask, and
loadtask and pin the zones to individual threads,
instead of having "many", spreading the zones among
them and hoping for the best. This also removes any
need to dynamically reallocate the pools with memory
contexts and tasks. [GL #3226]
5845. [bug] Refactor the timer to keep track of posted events
as to use isc_task_purgeevent() instead of using
isc_task_purgerange(). The isc_task_purgeevent()

View file

@ -593,7 +593,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
zonename, filename, classname);
}
CHECK(dns_zone_create(&zone, mctx));
CHECK(dns_zone_create(&zone, mctx, 0));
dns_zone_settype(zone, dns_zone_primary);

View file

@ -137,11 +137,9 @@
#ifdef HAVE_LMDB
#include <lmdb.h>
#define count_newzones count_newzones_db
#define configure_newzones configure_newzones_db
#define dumpzone dumpzone_db
#else /* HAVE_LMDB */
#define count_newzones count_newzones_file
#define configure_newzones configure_newzones_file
#define dumpzone dumpzone_file
#endif /* HAVE_LMDB */
@ -433,7 +431,7 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
const cfg_obj_t *vconfig, dns_view_t *view,
dns_viewlist_t *viewlist, dns_kasplist_t *kasplist,
cfg_aclconfctx_t *aclconf, bool added, bool old_rpz_ok,
bool modify);
@ -444,7 +442,7 @@ configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig,
static isc_result_t
configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
isc_mem_t *mctx, cfg_aclconfctx_t *actx);
cfg_aclconfctx_t *actx);
static isc_result_t
add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
@ -467,13 +465,7 @@ putuint8(isc_buffer_t **b, uint8_t val);
static isc_result_t
putnull(isc_buffer_t **b);
static int
count_zones(const cfg_obj_t *conf);
#ifdef HAVE_LMDB
static isc_result_t
migrate_nzf(dns_view_t *view);
static isc_result_t
nzd_writable(dns_view_t *view);
@ -488,14 +480,14 @@ nzd_env_close(dns_view_t *view);
static isc_result_t
nzd_close(MDB_txn **txnp, bool commit);
static isc_result_t
nzd_count(dns_view_t *view, int *countp);
#else /* ifdef HAVE_LMDB */
static isc_result_t
nzf_append(dns_view_t *view, const cfg_obj_t *zconfig);
#endif /* ifdef HAVE_LMDB */
static isc_result_t
load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg);
/*%
* Configure a single view ACL at '*aclp'. Get its configuration from
* 'vconfig' (for per-view configuration) and maybe from 'config'
@ -1959,7 +1951,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
isc_buffer_constinit(&b, reverse, strlen(reverse));
isc_buffer_add(&b, strlen(reverse));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
CHECK(dns_zone_create(&zone, mctx));
CHECK(dns_zone_create(&zone, mctx, 0));
CHECK(dns_zone_setorigin(zone, name));
dns_zone_setview(zone, view);
CHECK(dns_zonemgr_managezone(named_g_server->zonemgr, zone));
@ -2781,10 +2773,10 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) {
result = isc_task_beginexclusive(task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_view_thaw(ev->view);
result = configure_zone(
cfg->config, zoneobj, cfg->vconfig, ev->cbd->server->mctx,
ev->view, &ev->cbd->server->viewlist,
&ev->cbd->server->kasplist, cfg->actx, true, false, ev->mod);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig, ev->view,
&ev->cbd->server->viewlist,
&ev->cbd->server->kasplist, cfg->actx, true,
false, ev->mod);
dns_view_freeze(ev->view);
isc_task_endexclusive(task);
@ -3628,7 +3620,7 @@ create_ipv4only_zone(dns_zone_t *pzone, dns_view_t *view,
/*
* Create the actual zone.
*/
CHECK(dns_zone_create(&zone, mctx));
CHECK(dns_zone_create(&zone, mctx, 0));
CHECK(dns_zone_setorigin(zone, name));
CHECK(dns_zonemgr_managezone(named_g_server->zonemgr, zone));
dns_zone_setclass(zone, view->rdclass);
@ -4147,9 +4139,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
element = cfg_list_next(element))
{
const cfg_obj_t *zconfig = cfg_listelt_value(element);
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
viewlist, kasplist, actx, false,
old_rpz_ok, false));
CHECK(configure_zone(config, zconfig, vconfig, view, viewlist,
kasplist, actx, false, old_rpz_ok, false));
}
zones_configured = true;
@ -4185,7 +4176,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
* from the newzone file for zones that were added during previous
* runs.
*/
CHECK(configure_newzones(view, config, vconfig, mctx, actx));
CHECK(configure_newzones(view, config, vconfig, actx));
/*
* Create Dynamically Loadable Zone driver.
@ -6420,7 +6411,7 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
*/
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
const cfg_obj_t *vconfig, dns_view_t *view,
dns_viewlist_t *viewlist, dns_kasplist_t *kasplist,
cfg_aclconfctx_t *aclconf, bool added, bool old_rpz_ok,
bool modify) {
@ -6804,7 +6795,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
if (inline_signing) {
dns_zone_getraw(zone, &raw);
if (raw == NULL) {
CHECK(dns_zone_create(&raw, mctx));
CHECK(dns_zone_create(&raw, dns_zone_getmem(zone),
dns_zone_gettid(zone)));
CHECK(dns_zone_setorigin(raw, origin));
dns_zone_setview(raw, view);
dns_zone_setstats(raw, named_g_server->zonestats);
@ -7714,94 +7706,9 @@ cleanup:
return (result);
}
#ifndef HAVE_LMDB
static isc_result_t
count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) {
isc_result_t result;
/* The new zone file may not exist. That is OK. */
if (!isc_file_exists(view->new_zone_file)) {
*num_zonesp = 0;
return (ISC_R_SUCCESS);
}
/*
* In the case of NZF files, we also parse the configuration in
* the file at this stage.
*
* This may be called in multiple views, so we reset
* the parser each time.
*/
cfg_parser_reset(named_g_addparser);
result = cfg_parse_file(named_g_addparser, view->new_zone_file,
&cfg_type_addzoneconf, &nzcfg->nzf_config);
if (result == ISC_R_SUCCESS) {
int num_zones;
num_zones = count_zones(nzcfg->nzf_config);
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"NZF file '%s' contains %d zones",
view->new_zone_file, num_zones);
if (num_zonesp != NULL) {
*num_zonesp = num_zones;
}
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error parsing NZF file '%s': %s",
view->new_zone_file, isc_result_totext(result));
}
return (result);
}
#else /* HAVE_LMDB */
static isc_result_t
count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, int *num_zonesp) {
isc_result_t result;
int n;
UNUSED(nzcfg);
REQUIRE(num_zonesp != NULL);
LOCK(&view->new_zone_lock);
CHECK(migrate_nzf(view));
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"loading NZD zone count from '%s' "
"for view '%s'",
view->new_zone_db, view->name);
CHECK(nzd_count(view, &n));
*num_zonesp = n;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"NZD database '%s' contains %d zones", view->new_zone_db,
n);
cleanup:
if (result != ISC_R_SUCCESS) {
*num_zonesp = 0;
}
UNLOCK(&view->new_zone_lock);
return (ISC_R_SUCCESS);
}
#endif /* HAVE_LMDB */
static isc_result_t
setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_parser_t *conf_parser, cfg_aclconfctx_t *actx,
int *num_zones) {
cfg_parser_t *conf_parser, cfg_aclconfctx_t *actx) {
isc_result_t result = ISC_R_SUCCESS;
bool allow = false;
ns_cfgctx_t *nzcfg = NULL;
@ -7899,28 +7806,29 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
if (!allow) {
dns_view_setnewzones(view, false, NULL, NULL, 0ULL);
if (num_zones != NULL) {
*num_zones = 0;
}
return (ISC_R_SUCCESS);
}
nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg));
*nzcfg = (ns_cfgctx_t){ 0 };
/*
* We attach the parser that was used for config as well
* as the one that will be used for added zones, to avoid
* a shutdown race later.
*/
memset(nzcfg, 0, sizeof(*nzcfg));
isc_mem_attach(view->mctx, &nzcfg->mctx);
cfg_parser_attach(conf_parser, &nzcfg->conf_parser);
cfg_parser_attach(named_g_addparser, &nzcfg->add_parser);
isc_mem_attach(view->mctx, &nzcfg->mctx);
cfg_aclconfctx_attach(actx, &nzcfg->actx);
result = dns_view_setnewzones(view, true, nzcfg, newzone_cfgctx_destroy,
mapsize);
if (result != ISC_R_SUCCESS) {
cfg_aclconfctx_detach(&nzcfg->actx);
cfg_parser_destroy(&nzcfg->add_parser);
cfg_parser_destroy(&nzcfg->conf_parser);
isc_mem_putanddetach(&nzcfg->mctx, nzcfg, sizeof(*nzcfg));
dns_view_setnewzones(view, false, NULL, NULL, 0ULL);
return (result);
}
@ -7930,7 +7838,7 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_obj_attach(vconfig, &nzcfg->vconfig);
}
result = count_newzones(view, nzcfg, num_zones);
result = load_nzf(view, nzcfg);
return (result);
}
@ -7978,7 +7886,7 @@ configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig,
static isc_result_t
configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
isc_mem_t *mctx, cfg_aclconfctx_t *actx) {
cfg_aclconfctx_t *actx) {
isc_result_t result;
ns_cfgctx_t *nzctx;
const cfg_obj_t *zonelist;
@ -8000,7 +7908,7 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
element = cfg_list_next(element))
{
const cfg_obj_t *zconfig = cfg_listelt_value(element);
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
CHECK(configure_zone(config, zconfig, vconfig, view,
&named_g_server->viewlist,
&named_g_server->kasplist, actx, true,
false, false));
@ -8097,7 +8005,7 @@ cleanup:
*/
typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj_t *zconfig,
cfg_obj_t *config, cfg_obj_t *vconfig,
isc_mem_t *mctx, dns_view_t *view,
dns_view_t *view,
cfg_aclconfctx_t *actx);
/*%
@ -8113,7 +8021,7 @@ typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj_t *zconfig,
*/
static isc_result_t
for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config,
cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
cfg_obj_t *vconfig, dns_view_t *view,
cfg_aclconfctx_t *actx, MDB_txn *txn, MDB_dbi dbi) {
const cfg_obj_t *zconfig, *zlist;
isc_result_t result = ISC_R_SUCCESS;
@ -8156,7 +8064,7 @@ for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config,
/*
* Invoke callback.
*/
result = callback(zconfig, config, vconfig, mctx, view, actx);
result = callback(zconfig, config, vconfig, view, actx);
if (result != ISC_R_SUCCESS) {
break;
}
@ -8183,10 +8091,10 @@ for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config,
*/
static isc_result_t
configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config,
cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
cfg_obj_t *vconfig, dns_view_t *view,
cfg_aclconfctx_t *actx) {
return (configure_zone(
config, zconfig, vconfig, mctx, view, &named_g_server->viewlist,
config, zconfig, vconfig, view, &named_g_server->viewlist,
&named_g_server->kasplist, actx, true, false, false));
}
@ -8195,11 +8103,10 @@ configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config,
*/
static isc_result_t
configure_newzone_revert(const cfg_obj_t *zconfig, cfg_obj_t *config,
cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
cfg_obj_t *vconfig, dns_view_t *view,
cfg_aclconfctx_t *actx) {
UNUSED(config);
UNUSED(vconfig);
UNUSED(mctx);
UNUSED(actx);
configure_zone_setviewcommit(ISC_R_FAILURE, zconfig, view);
@ -8209,7 +8116,7 @@ configure_newzone_revert(const cfg_obj_t *zconfig, cfg_obj_t *config,
static isc_result_t
configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
isc_mem_t *mctx, cfg_aclconfctx_t *actx) {
cfg_aclconfctx_t *actx) {
isc_result_t result;
MDB_txn *txn = NULL;
MDB_dbi dbi;
@ -8232,8 +8139,8 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
"for view '%s'",
view->new_zone_db, view->name);
result = for_all_newzone_cfgs(configure_newzone, config, vconfig, mctx,
view, actx, txn, dbi);
result = for_all_newzone_cfgs(configure_newzone, config, vconfig, view,
actx, txn, dbi);
if (result != ISC_R_SUCCESS) {
/*
* An error was encountered while attempting to configure zones
@ -8244,7 +8151,7 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
* terms of trying to make things right.
*/
(void)for_all_newzone_cfgs(configure_newzone_revert, config,
vconfig, mctx, view, actx, txn, dbi);
vconfig, view, actx, txn, dbi);
}
(void)nzd_close(&txn, false);
@ -8320,24 +8227,6 @@ cleanup:
#endif /* HAVE_LMDB */
static int
count_zones(const cfg_obj_t *conf) {
const cfg_obj_t *zonelist = NULL;
const cfg_listelt_t *element;
int n = 0;
REQUIRE(conf != NULL);
cfg_map_get(conf, "zone", &zonelist);
for (element = cfg_list_first(zonelist); element != NULL;
element = cfg_list_next(element))
{
n++;
}
return (n);
}
static isc_result_t
check_lockfile(named_server_t *server, const cfg_obj_t *config,
bool first_time) {
@ -8443,7 +8332,6 @@ load_configuration(const char *filename, named_server_t *server,
dns_viewlist_t viewlist, builtin_viewlist;
in_port_t listen_port, udpport_low, udpport_high;
int i, backlog;
int num_zones = 0;
bool exclusive = false;
isc_interval_t interval;
isc_logconfig_t *logc = NULL;
@ -9185,19 +9073,14 @@ load_configuration(const char *filename, named_server_t *server,
element = cfg_list_next(element))
{
cfg_obj_t *vconfig = cfg_listelt_value(element);
const cfg_obj_t *voptions = cfg_tuple_get(vconfig, "options");
int nzf_num_zones;
view = NULL;
CHECK(create_view(vconfig, &viewlist, &view));
INSIST(view != NULL);
num_zones += count_zones(voptions);
CHECK(setup_newzones(view, config, vconfig, conf_parser,
named_g_aclconfctx, &nzf_num_zones));
num_zones += nzf_num_zones;
named_g_aclconfctx));
dns_view_detach(&view);
}
@ -9207,28 +9090,15 @@ load_configuration(const char *filename, named_server_t *server,
* view here.
*/
if (views == NULL) {
int nzf_num_zones;
CHECK(create_view(NULL, &viewlist, &view));
INSIST(view != NULL);
num_zones = count_zones(config);
CHECK(setup_newzones(view, config, NULL, conf_parser,
named_g_aclconfctx, &nzf_num_zones));
num_zones += nzf_num_zones;
named_g_aclconfctx));
dns_view_detach(&view);
}
/*
* Zones have been counted; set the zone manager task pool size.
*/
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"sizing zone task pool based on %d zones", num_zones);
CHECK(dns_zonemgr_setsize(named_g_server->zonemgr, num_zones));
/*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
@ -10194,8 +10064,6 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
named_g_timermgr, named_g_netmgr,
&server->zonemgr),
"dns_zonemgr_create");
CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), "dns_zonemgr_"
"setsize");
server->statsfile = isc_mem_strdup(server->mctx, "named.stats");
CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
@ -13099,7 +12967,32 @@ cleanup:
return (result);
}
#else /* HAVE_LMDB */
static isc_result_t
load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
isc_result_t result;
/* The new zone file may not exist. That is OK. */
if (!isc_file_exists(view->new_zone_file)) {
return (ISC_R_SUCCESS);
}
/*
* Parse the configuration in the NZF file. This may be called in
* multiple views, so we reset the parser each time.
*/
cfg_parser_reset(named_g_addparser);
result = cfg_parse_file(named_g_addparser, view->new_zone_file,
&cfg_type_addzoneconf, &nzcfg->nzf_config);
if (result != ISC_R_SUCCESS) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error parsing NZF file '%s': %s",
view->new_zone_file, isc_result_totext(result));
}
return (result);
}
#else /* HAVE_LMDB */
static void
nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen) {
@ -13424,52 +13317,16 @@ nzd_close(MDB_txn **txnp, bool commit) {
}
/*
* Count the zones configured in the new zone database for 'view' and store the
* result in 'countp'.
* If there's an existing NZF file, load it and migrate its data
* to the NZD.
*
* Caller must hold 'view->new_zone_lock'.
*/
static isc_result_t
nzd_count(dns_view_t *view, int *countp) {
isc_result_t result;
int status;
MDB_txn *txn = NULL;
MDB_dbi dbi;
MDB_stat statbuf;
REQUIRE(countp != NULL);
result = nzd_open(view, MDB_RDONLY, &txn, &dbi);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
status = mdb_stat(txn, dbi, &statbuf);
if (status != MDB_SUCCESS) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
"mdb_stat: %s", mdb_strerror(status));
result = ISC_R_FAILURE;
goto cleanup;
}
*countp = statbuf.ms_entries;
cleanup:
(void)nzd_close(&txn, false);
return (result);
}
/*
* Migrate zone configuration from an NZF file to an NZD database.
* Caller must hold view->new_zone_lock.
*/
static isc_result_t
migrate_nzf(dns_view_t *view) {
load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
isc_result_t result;
cfg_obj_t *nzf_config = NULL;
int status, n;
int status;
isc_buffer_t *text = NULL;
bool commit = false;
const cfg_obj_t *zonelist;
@ -13480,6 +13337,8 @@ migrate_nzf(dns_view_t *view) {
MDB_val key, data;
ns_dzarg_t dzarg;
UNUSED(nzcfg);
/*
* If NZF file doesn't exist, or NZD DB exists and already
* has data, return without attempting migration.
@ -13489,12 +13348,6 @@ migrate_nzf(dns_view_t *view) {
goto cleanup;
}
result = nzd_count(view, &n);
if (result == ISC_R_SUCCESS && n > 0) {
result = ISC_R_SUCCESS;
goto cleanup;
}
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"Migrating zones from NZF file '%s' to "
@ -13572,7 +13425,7 @@ migrate_nzf(dns_view_t *view) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error writing zone config to "
"buffer in migrate_nzf(): %s",
"buffer in load_nzf(): %s",
isc_result_totext(result));
result = dzarg.result;
goto cleanup;
@ -13625,7 +13478,6 @@ cleanup:
return (result);
}
#endif /* HAVE_LMDB */
static isc_result_t
@ -13880,10 +13732,9 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
/* Mark view unfrozen and configure zone */
dns_view_thaw(view);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
server->mctx, view, &server->viewlist,
&server->kasplist, cfg->actx, true, false,
false);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig, view,
&server->viewlist, &server->kasplist, cfg->actx,
true, false, false);
dns_view_freeze(view);
isc_task_endexclusive(server->task);
@ -14068,10 +13919,9 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
/* Reconfigure the zone */
dns_view_thaw(view);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
server->mctx, view, &server->viewlist,
&server->kasplist, cfg->actx, true, false,
true);
result = configure_zone(cfg->config, zoneobj, cfg->vconfig, view,
&server->viewlist, &server->kasplist, cfg->actx,
true, false, true);
dns_view_freeze(view);
exclusive = false;

View file

@ -67,7 +67,7 @@ create_zone(sample_instance_t *const inst, dns_name_t *const name,
zone_argv[0] = inst->db_name;
result = dns_zone_create(&raw, inst->mctx);
result = dns_zone_create(&raw, inst->mctx, 0); /* FIXME */
if (result != ISC_R_SUCCESS) {
log_write(ISC_LOG_ERROR, "create_zone: dns_zone_create -> %s\n",
isc_result_totext(result));

View file

@ -58,7 +58,9 @@
#include <isc/commandline.h>
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/netmgr.h>
#include <isc/once.h>
#include <isc/random.h>
#include <isc/rwlock.h>
#include <isc/string.h>
#include <isc/util.h>
@ -454,7 +456,7 @@ dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb,
INSIST(dupzone == NULL);
/* Create it */
result = dns_zone_create(&zone, view->mctx);
result = dns_zone_create(&zone, view->mctx, 0);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}

View file

@ -147,7 +147,7 @@ ISC_LANG_BEGINDECLS
***/
isc_result_t
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx);
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid);
/*%<
* Creates a new empty zone and attach '*zonep' to it.
*
@ -1479,16 +1479,6 @@ dns_zone_getredirecttype(dns_zone_t *zone);
*\li 'dns_zone_secondary'
*/
void
dns_zone_settask(dns_zone_t *zone, isc_task_t *task);
/*%<
* Give a zone a task to work with. Any current task will be detached.
*
* Requires:
*\li 'zone' to be valid.
*\li 'task' to be valid.
*/
void
dns_zone_gettask(dns_zone_t *zone, isc_task_t **target);
/*%<
@ -1785,8 +1775,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, isc_nm_t *netmgr,
dns_zonemgr_t **zmgrp);
/*%<
* Create a zone manager. Note: the zone manager will not be able to
* manage any zones until dns_zonemgr_setsize() has been run.
* Create a zone manager.
*
* Requires:
*\li 'mctx' to be a valid memory context.
@ -1795,18 +1784,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
*\li 'zmgrp' to point to a NULL pointer.
*/
isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones);
/*%<
* Set the size of the zone manager task pool. This must be run
* before zmgr can be used for managing zones. Currently, it can only
* be run once; the task pool cannot be resized.
*
* Requires:
*\li zmgr is a valid zone manager.
*\li zmgr->zonetasks has been initialized.
*/
isc_result_t
dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep);
/*%<
@ -2764,3 +2741,23 @@ dns_zonetype_name(dns_zonetype_t type);
/*%<
* Return the name of the zone type 'type'.
*/
isc_mem_t *
dns_zone_getmem(dns_zone_t *zone);
/**<
* \brief Return memory context associated with the zone.
*
* \param zone valid dns_zone_t object.
*
* \return memory context associated with the zone
*/
unsigned int
dns_zone_gettid(dns_zone_t *zone);
/**<
* \brief Return thread-id associated with the zone.
*
* \param valid dns_zone_t object
*
* \return thread id associated with the zone
*/

View file

@ -39,6 +39,7 @@
#include <isc/netmgr.h>
#include <isc/os.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/stdio.h>
#include <isc/string.h>
@ -236,7 +237,7 @@ dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view,
/*
* Create the zone structure.
*/
result = dns_zone_create(&zone, dt_mctx);
result = dns_zone_create(&zone, dt_mctx, 0);
if (result != ISC_R_SUCCESS) {
return (result);
}
@ -292,7 +293,8 @@ dns_test_setupzonemgr(void) {
isc_result_t result;
REQUIRE(zonemgr == NULL);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL, &zonemgr);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, netmgr,
&zonemgr);
return (result);
}
@ -301,11 +303,6 @@ dns_test_managezone(dns_zone_t *zone) {
isc_result_t result;
REQUIRE(zonemgr != NULL);
result = dns_zonemgr_setsize(zonemgr, 1);
if (result != ISC_R_SUCCESS) {
return (result);
}
result = dns_zonemgr_managezone(zonemgr, zone);
return (result);
}

View file

@ -64,7 +64,7 @@ zonemgr_create(void **state) {
UNUSED(state);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, netmgr,
&myzonemgr);
assert_int_equal(result, ISC_R_SUCCESS);
@ -82,22 +82,15 @@ zonemgr_managezone(void **state) {
UNUSED(state);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, netmgr,
&myzonemgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makezone("foo", &zone, NULL, false);
assert_int_equal(result, ISC_R_SUCCESS);
/* This should not succeed until the dns_zonemgr_setsize() is run */
result = dns_zonemgr_managezone(myzonemgr, zone);
assert_int_equal(result, ISC_R_FAILURE);
assert_int_equal(dns_zonemgr_getcount(myzonemgr, DNS_ZONESTATE_ANY), 0);
result = dns_zonemgr_setsize(myzonemgr, 1);
assert_int_equal(result, ISC_R_SUCCESS);
/* Now it should succeed */
result = dns_zonemgr_managezone(myzonemgr, zone);
assert_int_equal(result, ISC_R_SUCCESS);
@ -123,18 +116,10 @@ zonemgr_createzone(void **state) {
UNUSED(state);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, netmgr,
&myzonemgr);
assert_int_equal(result, ISC_R_SUCCESS);
/* This should not succeed until the dns_zonemgr_setsize() is run */
result = dns_zonemgr_createzone(myzonemgr, &zone);
assert_int_equal(result, ISC_R_FAILURE);
result = dns_zonemgr_setsize(myzonemgr, 1);
assert_int_equal(result, ISC_R_SUCCESS);
/* Now it should succeed */
result = dns_zonemgr_createzone(myzonemgr, &zone);
assert_int_equal(result, ISC_R_SUCCESS);
assert_non_null(zone);
@ -162,16 +147,13 @@ zonemgr_unreachable(void **state) {
TIME_NOW(&now);
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, NULL,
result = dns_zonemgr_create(dt_mctx, taskmgr, timermgr, netmgr,
&myzonemgr);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_test_makezone("foo", &zone, NULL, false);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_zonemgr_setsize(myzonemgr, 1);
assert_int_equal(result, ISC_R_SUCCESS);
result = dns_zonemgr_managezone(myzonemgr, zone);
assert_int_equal(result, ISC_R_SUCCESS);
@ -224,7 +206,6 @@ zonemgr_unreachable(void **state) {
* - dns_zonemgr_forcemaint
* - dns_zonemgr_resumexfrs
* - dns_zonemgr_shutdown
* - dns_zonemgr_setsize
* - dns_zonemgr_settransfersin
* - dns_zonemgr_getttransfersin
* - dns_zonemgr_settransfersperns

View file

@ -26,7 +26,6 @@
#include <isc/stats.h>
#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/taskpool.h>
#include <isc/time.h>
#include <isc/util.h>

View file

@ -23,7 +23,6 @@
#include <isc/hex.h>
#include <isc/md.h>
#include <isc/mutex.h>
#include <isc/pool.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/ratelimiter.h>
@ -35,7 +34,7 @@
#include <isc/stdtime.h>
#include <isc/strerr.h>
#include <isc/string.h>
#include <isc/taskpool.h>
#include <isc/task.h>
#include <isc/thread.h>
#include <isc/timer.h>
#include <isc/tls.h>
@ -234,6 +233,8 @@ struct dns_zone {
isc_rwlock_t dblock;
dns_db_t *db; /* Locked by dblock */
unsigned int tid;
/* Locked */
dns_zonemgr_t *zmgr;
ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
@ -595,10 +596,11 @@ struct dns_zonemgr {
isc_taskmgr_t *taskmgr;
isc_timermgr_t *timermgr;
isc_nm_t *netmgr;
isc_taskpool_t *zonetasks;
isc_taskpool_t *loadtasks;
uint32_t workers;
isc_task_t *task;
isc_pool_t *mctxpool;
isc_task_t **zonetasks;
isc_task_t **loadtasks;
isc_mem_t **mctxpool;
isc_ratelimiter_t *checkdsrl;
isc_ratelimiter_t *notifyrl;
isc_ratelimiter_t *refreshrl;
@ -1099,48 +1101,50 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
***/
isc_result_t
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) {
isc_result_t result;
isc_time_t now;
dns_zone_t *zone = NULL;
dns_zone_t z = { .masterformat = dns_masterformat_none,
.journalsize = -1,
.rdclass = dns_rdataclass_none,
.type = dns_zone_none,
.refresh = DNS_ZONE_DEFAULTREFRESH,
.retry = DNS_ZONE_DEFAULTRETRY,
.maxrefresh = DNS_ZONE_MAXREFRESH,
.minrefresh = DNS_ZONE_MINREFRESH,
.maxretry = DNS_ZONE_MAXRETRY,
.minretry = DNS_ZONE_MINRETRY,
.notifytype = dns_notifytype_yes,
.zero_no_soa_ttl = true,
.check_names = dns_severity_ignore,
.idlein = DNS_DEFAULT_IDLEIN,
.idleout = DNS_DEFAULT_IDLEOUT,
.notifysrc4dscp = -1,
.notifysrc6dscp = -1,
.parentalsrc4dscp = -1,
.parentalsrc6dscp = -1,
.xfrsource4dscp = -1,
.xfrsource6dscp = -1,
.altxfrsource4dscp = -1,
.altxfrsource6dscp = -1,
.maxxfrin = MAX_XFER_TIME,
.maxxfrout = MAX_XFER_TIME,
.sigvalidityinterval = 30 * 24 * 3600,
.sigresigninginterval = 7 * 24 * 3600,
.statlevel = dns_zonestat_none,
.notifydelay = 5,
.signatures = 10,
.nodes = 100,
.privatetype = (dns_rdatatype_t)0xffffU,
.rpz_num = DNS_RPZ_INVALID_NUM,
.requestixfr = true,
.ixfr_ratio = 100,
.requestexpire = true,
.updatemethod = dns_updatemethod_increment,
.magic = ZONE_MAGIC };
dns_zone_t z = {
.masterformat = dns_masterformat_none,
.journalsize = -1,
.rdclass = dns_rdataclass_none,
.type = dns_zone_none,
.refresh = DNS_ZONE_DEFAULTREFRESH,
.retry = DNS_ZONE_DEFAULTRETRY,
.maxrefresh = DNS_ZONE_MAXREFRESH,
.minrefresh = DNS_ZONE_MINREFRESH,
.maxretry = DNS_ZONE_MAXRETRY,
.minretry = DNS_ZONE_MINRETRY,
.notifytype = dns_notifytype_yes,
.zero_no_soa_ttl = true,
.check_names = dns_severity_ignore,
.idlein = DNS_DEFAULT_IDLEIN,
.idleout = DNS_DEFAULT_IDLEOUT,
.notifysrc4dscp = -1,
.notifysrc6dscp = -1,
.parentalsrc4dscp = -1,
.parentalsrc6dscp = -1,
.xfrsource4dscp = -1,
.xfrsource6dscp = -1,
.altxfrsource4dscp = -1,
.altxfrsource6dscp = -1,
.maxxfrin = MAX_XFER_TIME,
.maxxfrout = MAX_XFER_TIME,
.sigvalidityinterval = 30 * 24 * 3600,
.sigresigninginterval = 7 * 24 * 3600,
.statlevel = dns_zonestat_none,
.notifydelay = 5,
.signatures = 10,
.nodes = 100,
.privatetype = (dns_rdatatype_t)0xffffU,
.rpz_num = DNS_RPZ_INVALID_NUM,
.requestixfr = true,
.ixfr_ratio = 100,
.requestexpire = true,
.updatemethod = dns_updatemethod_increment,
.tid = tid,
};
REQUIRE(zonep != NULL && *zonep == NULL);
REQUIRE(mctx != NULL);
@ -1202,6 +1206,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
goto free_refs;
}
zone->magic = ZONE_MAGIC;
/* Must be after magic is set. */
dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
@ -16238,23 +16244,6 @@ dns_zone_getorigin(dns_zone_t *zone) {
return (&zone->origin);
}
void
dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
if (zone->task != NULL) {
isc_task_detach(&zone->task);
}
isc_task_attach(task, &zone->task);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
if (zone->db != NULL) {
dns_db_settask(zone->db, zone->task);
}
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
}
void
dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
REQUIRE(DNS_ZONE_VALID(zone));
@ -18802,22 +18791,25 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
dns_zonemgr_t *zmgr;
isc_result_t result;
REQUIRE(mctx != NULL);
REQUIRE(taskmgr != NULL);
REQUIRE(timermgr != NULL);
REQUIRE(netmgr != NULL);
zmgr = isc_mem_get(mctx, sizeof(*zmgr));
zmgr->mctx = NULL;
*zmgr = (dns_zonemgr_t){
.taskmgr = taskmgr,
.timermgr = timermgr,
.netmgr = netmgr,
.workers = isc_nm_getnworkers(netmgr),
.transfersin = 10,
.transfersperns = 2,
};
isc_refcount_init(&zmgr->refs, 1);
isc_mem_attach(mctx, &zmgr->mctx);
zmgr->taskmgr = taskmgr;
zmgr->timermgr = timermgr;
zmgr->netmgr = netmgr;
zmgr->zonetasks = NULL;
zmgr->loadtasks = NULL;
zmgr->mctxpool = NULL;
zmgr->task = NULL;
zmgr->checkdsrl = NULL;
zmgr->notifyrl = NULL;
zmgr->refreshrl = NULL;
zmgr->startupnotifyrl = NULL;
zmgr->startuprefreshrl = NULL;
ISC_LIST_INIT(zmgr->zones);
ISC_LIST_INIT(zmgr->waiting_for_xfrin);
ISC_LIST_INIT(zmgr->xfrin_in_progress);
@ -18827,9 +18819,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
}
isc_rwlock_init(&zmgr->rwlock, 0, 0);
zmgr->transfersin = 10;
zmgr->transfersperns = 2;
/* Unreachable lock. */
isc_rwlock_init(&zmgr->urlock, 0, 0);
@ -18870,6 +18859,39 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
goto free_startupnotifyrl;
}
zmgr->zonetasks = isc_mem_get(
zmgr->mctx, zmgr->workers * sizeof(zmgr->zonetasks[0]));
memset(zmgr->zonetasks, 0, zmgr->workers * sizeof(zmgr->zonetasks[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
result = isc_task_create_bound(zmgr->taskmgr, 2,
&zmgr->zonetasks[i], i);
if (result != ISC_R_SUCCESS) {
goto free_zonetasks;
}
isc_task_setname(zmgr->zonetasks[i], "zonemgr-zonetasks", NULL);
}
zmgr->loadtasks = isc_mem_get(
zmgr->mctx, zmgr->workers * sizeof(zmgr->loadtasks[0]));
memset(zmgr->loadtasks, 0, zmgr->workers * sizeof(zmgr->loadtasks[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
result = isc_task_create_bound(zmgr->taskmgr, UINT_MAX,
&zmgr->loadtasks[i], i);
if (result != ISC_R_SUCCESS) {
goto free_loadtasks;
}
isc_task_setname(zmgr->loadtasks[i], "zonemgr-loadtasks", NULL);
isc_task_setprivilege(zmgr->loadtasks[i], true);
}
zmgr->mctxpool = isc_mem_get(zmgr->mctx,
zmgr->workers * sizeof(zmgr->mctxpool[0]));
memset(zmgr->mctxpool, 0, zmgr->workers * sizeof(zmgr->mctxpool[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
isc_mem_create(&zmgr->mctxpool[i]);
isc_mem_setname(zmgr->mctxpool[i], "zonemgr-mctxpool");
}
/* Key file I/O locks. */
zonemgr_keymgmt_init(zmgr);
@ -18900,6 +18922,25 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
free_iolock:
isc_mutex_destroy(&zmgr->iolock);
#endif /* if 0 */
free_loadtasks:
for (size_t i = 0; i < zmgr->workers; i++) {
if (zmgr->loadtasks[i] != NULL) {
isc_task_detach(&zmgr->loadtasks[i]);
}
}
isc_mem_put(zmgr->mctx, zmgr->loadtasks,
zmgr->workers * sizeof(zmgr->loadtasks[0]));
free_zonetasks:
for (size_t i = 0; i < zmgr->workers; i++) {
if (zmgr->zonetasks[i] != NULL) {
isc_task_detach(&zmgr->zonetasks[i]);
}
}
isc_mem_put(zmgr->mctx, zmgr->zonetasks,
zmgr->workers * sizeof(zmgr->zonetasks[0]));
isc_ratelimiter_detach(&zmgr->startuprefreshrl);
free_startupnotifyrl:
isc_ratelimiter_detach(&zmgr->startupnotifyrl);
free_refreshrl:
@ -18923,7 +18964,7 @@ dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
isc_result_t result;
isc_mem_t *mctx = NULL;
dns_zone_t *zone = NULL;
void *item;
unsigned int tid;
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
REQUIRE(zonep != NULL && *zonep == NULL);
@ -18932,14 +18973,14 @@ dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
return (ISC_R_FAILURE);
}
item = isc_pool_get(zmgr->mctxpool);
if (item == NULL) {
tid = isc_random_uniform(zmgr->workers);
mctx = zmgr->mctxpool[tid];
if (mctx == NULL) {
return (ISC_R_FAILURE);
}
isc_mem_attach((isc_mem_t *)item, &mctx);
result = dns_zone_create(&zone, mctx);
isc_mem_detach(&mctx);
result = dns_zone_create(&zone, mctx, tid);
if (result == ISC_R_SUCCESS) {
*zonep = zone;
@ -18963,8 +19004,8 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
REQUIRE(zone->timer == NULL);
REQUIRE(zone->zmgr == NULL);
isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
isc_task_attach(zmgr->zonetasks[zone->tid], &zone->task);
isc_task_attach(zmgr->loadtasks[zone->tid], &zone->loadtask);
/*
* Set the task name. The tag will arbitrarily point to one
@ -19096,15 +19137,28 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
if (zmgr->task != NULL) {
isc_task_destroy(&zmgr->task);
}
if (zmgr->zonetasks != NULL) {
isc_taskpool_destroy(&zmgr->zonetasks);
for (size_t i = 0; i < zmgr->workers; i++) {
isc_mem_detach(&zmgr->mctxpool[i]);
}
if (zmgr->loadtasks != NULL) {
isc_taskpool_destroy(&zmgr->loadtasks);
isc_mem_put(zmgr->mctx, zmgr->mctxpool,
zmgr->workers * sizeof(zmgr->mctxpool[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
if (zmgr->loadtasks[i] != NULL) {
isc_task_detach(&zmgr->loadtasks[i]);
}
}
if (zmgr->mctxpool != NULL) {
isc_pool_destroy(&zmgr->mctxpool);
isc_mem_put(zmgr->mctx, zmgr->loadtasks,
zmgr->workers * sizeof(zmgr->loadtasks[0]));
for (size_t i = 0; i < zmgr->workers; i++) {
if (zmgr->zonetasks[i] != NULL) {
isc_task_detach(&zmgr->zonetasks[i]);
}
}
isc_mem_put(zmgr->mctx, zmgr->zonetasks,
zmgr->workers * sizeof(zmgr->zonetasks[0]));
RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
@ -19117,101 +19171,6 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
}
static isc_result_t
mctxinit(void **target, void *arg) {
isc_mem_t *mctx = NULL;
UNUSED(arg);
REQUIRE(target != NULL && *target == NULL);
isc_mem_create(&mctx);
isc_mem_setname(mctx, "zonemgr-pool");
*target = mctx;
return (ISC_R_SUCCESS);
}
static void
mctxfree(void **target) {
isc_mem_t *mctx = *(isc_mem_t **)target;
isc_mem_detach(&mctx);
*target = NULL;
}
#define ZONES_PER_TASK 100
#define ZONES_PER_MCTX 1000
isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
isc_result_t result;
int ntasks = num_zones / ZONES_PER_TASK;
int nmctx = num_zones / ZONES_PER_MCTX;
isc_taskpool_t *pool = NULL;
isc_pool_t *mctxpool = NULL;
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
/*
* For anything fewer than 1000 zones we use 10 tasks in
* the task pools. More than that, and we'll scale at one
* task per 100 zones. Similarly, for anything smaller than
* 2000 zones we use 2 memory contexts, then scale at 1:1000.
*/
if (ntasks < 10) {
ntasks = 10;
}
if (nmctx < 2) {
nmctx = 2;
}
/* Create or resize the zone task pools. */
if (zmgr->zonetasks == NULL) {
result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
2, false, &pool);
} else {
result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, false,
&pool);
}
if (result == ISC_R_SUCCESS) {
zmgr->zonetasks = pool;
}
/*
* We always set all tasks in the zone-load task pool to
* privileged. This prevents other tasks in the system from
* running while the server task manager is in privileged
* mode.
*/
pool = NULL;
if (zmgr->loadtasks == NULL) {
result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
UINT_MAX, true, &pool);
} else {
result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, true,
&pool);
}
if (result == ISC_R_SUCCESS) {
zmgr->loadtasks = pool;
}
/* Create or resize the zone memory context pool. */
if (zmgr->mctxpool == NULL) {
result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit,
NULL, &mctxpool);
} else {
result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
}
if (result == ISC_R_SUCCESS) {
zmgr->mctxpool = mctxpool;
}
return (result);
}
static void
zonemgr_free(dns_zonemgr_t *zmgr) {
isc_mem_t *mctx;
@ -23685,3 +23644,13 @@ dns_zonemgr_set_tlsctx_cache(dns_zonemgr_t *zmgr,
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
}
isc_mem_t *
dns_zone_getmem(dns_zone_t *zone) {
return (zone->mctx);
}
unsigned int
dns_zone_gettid(dns_zone_t *zone) {
return (zone->tid);
}

View file

@ -63,7 +63,6 @@ libisc_la_HEADERS = \
include/isc/once.h \
include/isc/os.h \
include/isc/parseint.h \
include/isc/pool.h \
include/isc/portset.h \
include/isc/print.h \
include/isc/quota.h \
@ -90,7 +89,6 @@ libisc_la_HEADERS = \
include/isc/symtab.h \
include/isc/syslog.h \
include/isc/task.h \
include/isc/taskpool.h \
include/isc/thread.h \
include/isc/time.h \
include/isc/timer.h \
@ -168,7 +166,6 @@ libisc_la_SOURCES = \
os.c \
os_p.h \
parseint.c \
pool.c \
portset.c \
quota.c \
radix.c \
@ -191,7 +188,6 @@ libisc_la_SOURCES = \
syslog.c \
task.c \
task_p.h \
taskpool.c \
thread.c \
time.c \
timer.c \

View file

@ -1,138 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*****
***** Module Info
*****/
/*! \file isc/pool.h
* \brief An object pool is a mechanism for sharing a small pool of
* fungible objects among a large number of objects that depend on them.
*
* This is useful, for example, when it causes performance problems for
* large number of zones to share a single memory context or task object,
* but it would create a different set of problems for them each to have an
* independent task or memory context.
*/
/***
*** Imports.
***/
#include <isc/lang.h>
#include <isc/mem.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
/*****
***** Types.
*****/
typedef void (*isc_pooldeallocator_t)(void **object);
typedef isc_result_t (*isc_poolinitializer_t)(void **target, void *arg);
typedef struct isc_pool isc_pool_t;
/*****
***** Functions.
*****/
isc_result_t
isc_pool_create(isc_mem_t *mctx, unsigned int count, isc_pooldeallocator_t free,
isc_poolinitializer_t init, void *initarg, isc_pool_t **poolp);
/*%<
* Create a pool of "count" object pointers. If 'free' is not NULL,
* it points to a function that will detach the objects. 'init'
* points to a function that will initialize the arguments, and
* 'arg' to an argument to be passed into that function (for example,
* a relevant manager or context object).
*
* Requires:
*
*\li 'mctx' is a valid memory context.
*
*\li init != NULL
*
*\li poolp != NULL && *poolp == NULL
*
* Ensures:
*
*\li On success, '*poolp' points to the new object pool.
*
* Returns:
*
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
*\li #ISC_R_UNEXPECTED
*/
void *
isc_pool_get(isc_pool_t *pool);
/*%<
* Returns a pointer to an object from the pool. Currently the object
* is chosen from the pool at random. (This may be changed in the future
* to something that guaratees balance.)
*/
int
isc_pool_count(isc_pool_t *pool);
/*%<
* Returns the number of objcts in the pool 'pool'.
*/
isc_result_t
isc_pool_expand(isc_pool_t **sourcep, unsigned int count, isc_pool_t **targetp);
/*%<
* If 'size' is larger than the number of objects in the pool pointed to by
* 'sourcep', then a new pool of size 'count' is allocated, the existing
* objects are copied into it, additional ones created to bring the
* total number up to 'count', and the resulting pool is attached to
* 'targetp'.
*
* If 'count' is less than or equal to the number of objects in 'source', then
* 'sourcep' is attached to 'targetp' without any other action being taken.
*
* In either case, 'sourcep' is detached.
*
* Requires:
*
* \li 'sourcep' is not NULL and '*source' is not NULL
* \li 'targetp' is not NULL and '*source' is NULL
*
* Ensures:
*
* \li On success, '*targetp' points to a valid task pool.
* \li On success, '*sourcep' points to NULL.
*
* Returns:
*
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOMEMORY
*/
void
isc_pool_destroy(isc_pool_t **poolp);
/*%<
* Destroy a task pool. The tasks in the pool are detached but not
* shut down.
*
* Requires:
* \li '*poolp' is a valid task pool.
*/
ISC_LANG_ENDDECLS

View file

@ -1,135 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
/*****
***** Module Info
*****/
/*! \file isc/taskpool.h
* \brief A task pool is a mechanism for sharing a small number of tasks
* among a large number of objects such that each object is
* assigned a unique task, but each task may be shared by several
* objects.
*
* Task pools are used to let objects that can exist in large
* numbers (e.g., zones) use tasks for synchronization without
* the memory overhead and unfair scheduling competition that
* could result from creating a separate task for each object.
*/
/***
*** Imports.
***/
#include <stdbool.h>
#include <isc/lang.h>
#include <isc/task.h>
ISC_LANG_BEGINDECLS
/*****
***** Types.
*****/
typedef struct isc_taskpool isc_taskpool_t;
/*****
***** Functions.
*****/
isc_result_t
isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
unsigned int quantum, bool priv, isc_taskpool_t **poolp);
/*%<
* Create a task pool of "ntasks" tasks, each with quantum
* "quantum".
*
* Requires:
*
*\li 'tmgr' is a valid task manager.
*
*\li 'mctx' is a valid memory context.
*
*\li poolp != NULL && *poolp == NULL
*
* Ensures:
*
*\li On success, '*taskp' points to the new task pool.
*
* Returns:
*
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
*\li #ISC_R_UNEXPECTED
*/
void
isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp);
/*%<
* Attach to a task from the pool. Currently the next task is chosen
* from the pool at random. (This may be changed in the future to
* something that guaratees balance.)
*/
int
isc_taskpool_size(isc_taskpool_t *pool);
/*%<
* Returns the number of tasks in the task pool 'pool'.
*/
isc_result_t
isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, bool priv,
isc_taskpool_t **targetp);
/*%<
* If 'size' is larger than the number of tasks in the pool pointed to by
* 'sourcep', then a new taskpool of size 'size' is allocated, the existing
* tasks from are moved into it, additional tasks are created to bring the
* total number up to 'size', and the resulting pool is attached to
* 'targetp'.
*
* If 'size' is less than or equal to the tasks in pool 'source', then
* 'sourcep' is attached to 'targetp' without any other action being taken.
*
* In either case, 'sourcep' is detached.
*
* Requires:
*
* \li 'sourcep' is not NULL and '*source' is not NULL
* \li 'targetp' is not NULL and '*source' is NULL
*
* Ensures:
*
* \li On success, '*targetp' points to a valid task pool.
* \li On success, '*sourcep' points to NULL.
*
* Returns:
*
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOMEMORY
*/
void
isc_taskpool_destroy(isc_taskpool_t **poolp);
/*%<
* Destroy a task pool. The tasks in the pool are detached but not
* shut down.
*
* Requires:
* \li '*poolp' is a valid task pool.
*/
ISC_LANG_ENDDECLS

View file

@ -1,163 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <string.h>
#include <isc/mem.h>
#include <isc/pool.h>
#include <isc/random.h>
#include <isc/util.h>
/***
*** Types.
***/
struct isc_pool {
isc_mem_t *mctx;
unsigned int count;
isc_pooldeallocator_t free;
isc_poolinitializer_t init;
void *initarg;
void **pool;
};
/***
*** Functions.
***/
static isc_result_t
alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) {
isc_pool_t *pool;
pool = isc_mem_get(mctx, sizeof(*pool));
pool->count = count;
pool->free = NULL;
pool->init = NULL;
pool->initarg = NULL;
pool->mctx = NULL;
isc_mem_attach(mctx, &pool->mctx);
pool->pool = isc_mem_get(mctx, count * sizeof(void *));
memset(pool->pool, 0, count * sizeof(void *));
*poolp = pool;
return (ISC_R_SUCCESS);
}
isc_result_t
isc_pool_create(isc_mem_t *mctx, unsigned int count,
isc_pooldeallocator_t release, isc_poolinitializer_t init,
void *initarg, isc_pool_t **poolp) {
isc_pool_t *pool = NULL;
isc_result_t result;
unsigned int i;
INSIST(count > 0);
/* Allocate the pool structure */
result = alloc_pool(mctx, count, &pool);
if (result != ISC_R_SUCCESS) {
return (result);
}
pool->free = release;
pool->init = init;
pool->initarg = initarg;
/* Populate the pool */
for (i = 0; i < count; i++) {
result = init(&pool->pool[i], initarg);
if (result != ISC_R_SUCCESS) {
isc_pool_destroy(&pool);
return (result);
}
}
*poolp = pool;
return (ISC_R_SUCCESS);
}
void *
isc_pool_get(isc_pool_t *pool) {
return (pool->pool[isc_random_uniform(pool->count)]);
}
int
isc_pool_count(isc_pool_t *pool) {
REQUIRE(pool != NULL);
return (pool->count);
}
isc_result_t
isc_pool_expand(isc_pool_t **sourcep, unsigned int count,
isc_pool_t **targetp) {
isc_result_t result;
isc_pool_t *pool;
REQUIRE(sourcep != NULL && *sourcep != NULL);
REQUIRE(targetp != NULL && *targetp == NULL);
pool = *sourcep;
*sourcep = NULL;
if (count > pool->count) {
isc_pool_t *newpool = NULL;
unsigned int i;
/* Allocate a new pool structure */
result = alloc_pool(pool->mctx, count, &newpool);
if (result != ISC_R_SUCCESS) {
return (result);
}
newpool->free = pool->free;
newpool->init = pool->init;
newpool->initarg = pool->initarg;
/* Populate the new entries */
for (i = pool->count; i < count; i++) {
result = newpool->init(&newpool->pool[i],
newpool->initarg);
if (result != ISC_R_SUCCESS) {
isc_pool_destroy(&newpool);
return (result);
}
}
/* Copy over the objects from the old pool */
for (i = 0; i < pool->count; i++) {
newpool->pool[i] = pool->pool[i];
pool->pool[i] = NULL;
}
isc_pool_destroy(&pool);
pool = newpool;
}
*targetp = pool;
return (ISC_R_SUCCESS);
}
void
isc_pool_destroy(isc_pool_t **poolp) {
unsigned int i;
isc_pool_t *pool = *poolp;
*poolp = NULL;
for (i = 0; i < pool->count; i++) {
if (pool->free != NULL && pool->pool[i] != NULL) {
pool->free(&pool->pool[i]);
}
}
isc_mem_put(pool->mctx, pool->pool, pool->count * sizeof(void *));
isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
}

View file

@ -1,157 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <stdbool.h>
#include <isc/mem.h>
#include <isc/random.h>
#include <isc/taskpool.h>
#include <isc/util.h>
/***
*** Types.
***/
struct isc_taskpool {
isc_mem_t *mctx;
isc_taskmgr_t *tmgr;
unsigned int ntasks;
unsigned int quantum;
isc_task_t **tasks;
};
/***
*** Functions.
***/
static void
alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
unsigned int quantum, isc_taskpool_t **poolp) {
isc_taskpool_t *pool;
unsigned int i;
pool = isc_mem_get(mctx, sizeof(*pool));
pool->mctx = NULL;
isc_mem_attach(mctx, &pool->mctx);
pool->ntasks = ntasks;
pool->quantum = quantum;
pool->tmgr = tmgr;
pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
for (i = 0; i < ntasks; i++) {
pool->tasks[i] = NULL;
}
*poolp = pool;
}
isc_result_t
isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
unsigned int quantum, bool priv, isc_taskpool_t **poolp) {
unsigned int i;
isc_taskpool_t *pool = NULL;
INSIST(ntasks > 0);
/* Allocate the pool structure */
alloc_pool(tmgr, mctx, ntasks, quantum, &pool);
/* Create the tasks */
for (i = 0; i < ntasks; i++) {
isc_result_t result = isc_task_create_bound(tmgr, quantum,
&pool->tasks[i], i);
if (result != ISC_R_SUCCESS) {
isc_taskpool_destroy(&pool);
return (result);
}
isc_task_setprivilege(pool->tasks[i], priv);
isc_task_setname(pool->tasks[i], "taskpool", NULL);
}
*poolp = pool;
return (ISC_R_SUCCESS);
}
void
isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
isc_task_attach(pool->tasks[isc_random_uniform(pool->ntasks)], targetp);
}
int
isc_taskpool_size(isc_taskpool_t *pool) {
REQUIRE(pool != NULL);
return (pool->ntasks);
}
isc_result_t
isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size, bool priv,
isc_taskpool_t **targetp) {
isc_taskpool_t *pool;
REQUIRE(sourcep != NULL && *sourcep != NULL);
REQUIRE(targetp != NULL && *targetp == NULL);
pool = *sourcep;
*sourcep = NULL;
if (size > pool->ntasks) {
isc_taskpool_t *newpool = NULL;
unsigned int i;
/* Allocate a new pool structure */
alloc_pool(pool->tmgr, pool->mctx, size, pool->quantum,
&newpool);
/* Copy over the tasks from the old pool */
for (i = 0; i < pool->ntasks; i++) {
newpool->tasks[i] = pool->tasks[i];
pool->tasks[i] = NULL;
}
/* Create new tasks */
for (i = pool->ntasks; i < size; i++) {
isc_result_t result =
isc_task_create_bound(pool->tmgr, pool->quantum,
&newpool->tasks[i], i);
if (result != ISC_R_SUCCESS) {
*sourcep = pool;
isc_taskpool_destroy(&newpool);
return (result);
}
isc_task_setprivilege(newpool->tasks[i], priv);
isc_task_setname(newpool->tasks[i], "taskpool", NULL);
}
isc_taskpool_destroy(&pool);
pool = newpool;
}
*targetp = pool;
return (ISC_R_SUCCESS);
}
void
isc_taskpool_destroy(isc_taskpool_t **poolp) {
unsigned int i;
isc_taskpool_t *pool = *poolp;
*poolp = NULL;
for (i = 0; i < pool->ntasks; i++) {
if (pool->tasks[i] != NULL) {
isc_task_detach(&pool->tasks[i]);
}
}
isc_mem_put(pool->mctx, pool->tasks,
pool->ntasks * sizeof(isc_task_t *));
isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
}

View file

@ -30,7 +30,6 @@ check_PROGRAMS = \
netaddr_test \
netmgr_test \
parse_test \
pool_test \
quota_test \
radix_test \
random_test \
@ -42,7 +41,6 @@ check_PROGRAMS = \
stats_test \
symtab_test \
task_test \
taskpool_test \
time_test \
timer_test

View file

@ -1,194 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#if HAVE_CMOCKA
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/mem.h>
#include <isc/pool.h>
#include <isc/util.h>
#include "isctest.h"
static int
_setup(void **state) {
isc_result_t result;
UNUSED(state);
result = isc_test_begin(NULL, true, 0);
assert_int_equal(result, ISC_R_SUCCESS);
return (0);
}
static int
_teardown(void **state) {
UNUSED(state);
isc_test_end();
return (0);
}
static isc_result_t
poolinit(void **target, void *arg) {
isc_result_t result;
isc_taskmgr_t *mgr = (isc_taskmgr_t *)arg;
isc_task_t *task = NULL;
result = isc_task_create(mgr, 0, &task);
if (result != ISC_R_SUCCESS) {
return (result);
}
*target = (void *)task;
return (ISC_R_SUCCESS);
}
static void
poolfree(void **target) {
isc_task_t *task = *(isc_task_t **)target;
isc_task_destroy(&task);
*target = NULL;
}
/* Create a pool */
static void
create_pool(void **state) {
isc_result_t result;
isc_pool_t *pool = NULL;
UNUSED(state);
result = isc_pool_create(test_mctx, 8, poolfree, poolinit, taskmgr,
&pool);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool), 8);
isc_pool_destroy(&pool);
assert_null(pool);
}
/* Resize a pool */
static void
expand_pool(void **state) {
isc_result_t result;
isc_pool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL;
UNUSED(state);
result = isc_pool_create(test_mctx, 10, poolfree, poolinit, taskmgr,
&pool1);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool1), 10);
/* resizing to a smaller size should have no effect */
hold = pool1;
result = isc_pool_expand(&pool1, 5, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool2), 10);
assert_ptr_equal(pool2, hold);
assert_null(pool1);
pool1 = pool2;
pool2 = NULL;
/* resizing to the same size should have no effect */
hold = pool1;
result = isc_pool_expand(&pool1, 10, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool2), 10);
assert_ptr_equal(pool2, hold);
assert_null(pool1);
pool1 = pool2;
pool2 = NULL;
/* resizing to larger size should make a new pool */
hold = pool1;
result = isc_pool_expand(&pool1, 20, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool2), 20);
assert_ptr_not_equal(pool2, hold);
assert_null(pool1);
isc_pool_destroy(&pool2);
assert_null(pool2);
}
/* Get objects */
static void
get_objects(void **state) {
isc_result_t result;
isc_pool_t *pool = NULL;
void *item;
isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
UNUSED(state);
result = isc_pool_create(test_mctx, 2, poolfree, poolinit, taskmgr,
&pool);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_pool_count(pool), 2);
item = isc_pool_get(pool);
assert_non_null(item);
isc_task_attach((isc_task_t *)item, &task1);
item = isc_pool_get(pool);
assert_non_null(item);
isc_task_attach((isc_task_t *)item, &task2);
item = isc_pool_get(pool);
assert_non_null(item);
isc_task_attach((isc_task_t *)item, &task3);
isc_task_detach(&task1);
isc_task_detach(&task2);
isc_task_detach(&task3);
isc_pool_destroy(&pool);
assert_null(pool);
}
int
main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(create_pool, _setup, _teardown),
cmocka_unit_test_setup_teardown(expand_pool, _setup, _teardown),
cmocka_unit_test_setup_teardown(get_objects, _setup, _teardown),
};
return (cmocka_run_group_tests(tests, NULL, NULL));
}
#else /* HAVE_CMOCKA */
#include <stdio.h>
int
main(void) {
printf("1..0 # Skipped: cmocka not available\n");
return (SKIPPED_TEST_EXIT_CODE);
}
#endif /* if HAVE_CMOCKA */

View file

@ -1,204 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#if HAVE_CMOCKA
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/task.h>
#include <isc/taskpool.h>
#include <isc/util.h>
#include "isctest.h"
#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K')
#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC)
static int
_setup(void **state) {
isc_result_t result;
UNUSED(state);
result = isc_test_begin(NULL, true, 0);
assert_int_equal(result, ISC_R_SUCCESS);
return (0);
}
static int
_teardown(void **state) {
UNUSED(state);
isc_test_end();
return (0);
}
/* Create a taskpool */
static void
create_pool(void **state) {
isc_result_t result;
isc_taskpool_t *pool = NULL;
UNUSED(state);
result = isc_taskpool_create(taskmgr, test_mctx, 8, 2, false, &pool);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool), 8);
isc_taskpool_destroy(&pool);
assert_null(pool);
}
/* Resize a taskpool */
static void
expand_pool(void **state) {
isc_result_t result;
isc_taskpool_t *pool1 = NULL, *pool2 = NULL, *hold = NULL;
UNUSED(state);
result = isc_taskpool_create(taskmgr, test_mctx, 10, 2, false, &pool1);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool1), 10);
/* resizing to a smaller size should have no effect */
hold = pool1;
result = isc_taskpool_expand(&pool1, 5, false, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool2), 10);
assert_ptr_equal(pool2, hold);
assert_null(pool1);
pool1 = pool2;
pool2 = NULL;
/* resizing to the same size should have no effect */
hold = pool1;
result = isc_taskpool_expand(&pool1, 10, false, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool2), 10);
assert_ptr_equal(pool2, hold);
assert_null(pool1);
pool1 = pool2;
pool2 = NULL;
/* resizing to larger size should make a new pool */
hold = pool1;
result = isc_taskpool_expand(&pool1, 20, false, &pool2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool2), 20);
assert_ptr_not_equal(pool2, hold);
assert_null(pool1);
isc_taskpool_destroy(&pool2);
assert_null(pool2);
}
/* Get tasks */
static void
get_tasks(void **state) {
isc_result_t result;
isc_taskpool_t *pool = NULL;
isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
UNUSED(state);
result = isc_taskpool_create(taskmgr, test_mctx, 2, 2, false, &pool);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool), 2);
/* two tasks in pool; make sure we can access them more than twice */
isc_taskpool_gettask(pool, &task1);
assert_true(VALID_TASK(task1));
isc_taskpool_gettask(pool, &task2);
assert_true(VALID_TASK(task2));
isc_taskpool_gettask(pool, &task3);
assert_true(VALID_TASK(task3));
isc_task_destroy(&task1);
isc_task_destroy(&task2);
isc_task_destroy(&task3);
isc_taskpool_destroy(&pool);
assert_null(pool);
}
/* Set privileges */
static void
set_privilege(void **state) {
isc_result_t result;
isc_taskpool_t *pool = NULL;
isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;
UNUSED(state);
result = isc_taskpool_create(taskmgr, test_mctx, 2, 2, true, &pool);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_taskpool_size(pool), 2);
isc_taskpool_gettask(pool, &task1);
isc_taskpool_gettask(pool, &task2);
isc_taskpool_gettask(pool, &task3);
assert_true(VALID_TASK(task1));
assert_true(VALID_TASK(task2));
assert_true(VALID_TASK(task3));
assert_true(isc_task_getprivilege(task1));
assert_true(isc_task_getprivilege(task2));
assert_true(isc_task_getprivilege(task3));
isc_task_destroy(&task1);
isc_task_destroy(&task2);
isc_task_destroy(&task3);
isc_taskpool_destroy(&pool);
assert_null(pool);
}
int
main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(create_pool, _setup, _teardown),
cmocka_unit_test_setup_teardown(expand_pool, _setup, _teardown),
cmocka_unit_test_setup_teardown(get_tasks, _setup, _teardown),
cmocka_unit_test_setup_teardown(set_privilege, _setup,
_teardown),
};
return (cmocka_run_group_tests(tests, NULL, NULL));
}
#else /* HAVE_CMOCKA */
#include <stdio.h>
int
main(void) {
printf("1..0 # Skipped: cmocka not available\n");
return (SKIPPED_TEST_EXIT_CODE);
}
#endif /* if HAVE_CMOCKA */

View file

@ -412,7 +412,7 @@ ns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view,
zone = *zonep;
if (zone == NULL) {
CHECK(dns_zone_create(&zone, mctx));
CHECK(dns_zone_create(&zone, mctx, 0));
}
isc_buffer_constinit(&buffer, name, strlen(name));
@ -448,7 +448,7 @@ ns_test_setupzonemgr(void) {
isc_result_t result;
REQUIRE(zonemgr == NULL);
result = dns_zonemgr_create(mctx, taskmgr, timermgr, NULL, &zonemgr);
result = dns_zonemgr_create(mctx, taskmgr, timermgr, netmgr, &zonemgr);
return (result);
}
@ -457,11 +457,6 @@ ns_test_managezone(dns_zone_t *zone) {
isc_result_t result;
REQUIRE(zonemgr != NULL);
result = dns_zonemgr_setsize(zonemgr, 1);
if (result != ISC_R_SUCCESS) {
return (result);
}
result = dns_zonemgr_managezone(zonemgr, zone);
return (result);
}

View file

@ -19,7 +19,6 @@
#include <isc/serial.h>
#include <isc/stats.h>
#include <isc/string.h>
#include <isc/taskpool.h>
#include <isc/util.h>
#include <dns/db.h>