mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch 'ondrej-remove-task-privileged-mode' into 'main'
Remove task privileged mode Closes #3253 See merge request isc-projects/bind9!6049
This commit is contained in:
commit
635fbc7f93
8 changed files with 19 additions and 407 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
5847. [cleanup] Remove task privileged mode in favor of processing
|
||||
all events in the loadzone task in a single run
|
||||
by setting the quantum to UINT_MAX. [GL #3253]
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -9697,9 +9697,8 @@ view_loaded(void *arg) {
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
load_zones(named_server_t *server, bool init, bool reconfig) {
|
||||
load_zones(named_server_t *server, bool reconfig) {
|
||||
isc_result_t result;
|
||||
isc_taskmgr_t *taskmgr = dns_zonemgr_gettaskmgr(server->zonemgr);
|
||||
ns_zoneload_t *zl = NULL;
|
||||
dns_view_t *view = NULL;
|
||||
|
||||
|
|
@ -9755,25 +9754,7 @@ cleanup:
|
|||
isc_mem_put(server->mctx, zl, sizeof(*zl));
|
||||
}
|
||||
|
||||
if (init) {
|
||||
/*
|
||||
* If we're setting up the server for the first time, set
|
||||
* the task manager into privileged mode; this ensures
|
||||
* that no other tasks will begin to run until after zone
|
||||
* loading is complete. We won't return from exclusive mode
|
||||
* until the loading is finished; we can then drop out of
|
||||
* privileged mode.
|
||||
*
|
||||
* We do *not* want to do this in the case of reload or
|
||||
* reconfig, as loading a large zone could cause the server
|
||||
* to be inactive for too long a time.
|
||||
*/
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
isc_task_endexclusive(server->task);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal);
|
||||
} else {
|
||||
isc_task_endexclusive(server->task);
|
||||
}
|
||||
isc_task_endexclusive(server->task);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -9830,7 +9811,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
|
|||
CHECKFATAL(load_configuration(named_g_conffile, server, true),
|
||||
"loading configuration");
|
||||
|
||||
CHECKFATAL(load_zones(server, true, false), "loading zones");
|
||||
CHECKFATAL(load_zones(server, false), "loading zones");
|
||||
#ifdef ENABLE_AFL
|
||||
named_g_run_done = true;
|
||||
#endif /* ifdef ENABLE_AFL */
|
||||
|
|
@ -10330,7 +10311,7 @@ reload(named_server_t *server) {
|
|||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
result = load_zones(server, false, false);
|
||||
result = load_zones(server, false);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
|
|
@ -10704,7 +10685,7 @@ named_server_reconfigcommand(named_server_t *server) {
|
|||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
result = load_zones(server, false, true);
|
||||
result = load_zones(server, true);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
|
|
|
|||
|
|
@ -18881,7 +18881,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -81,11 +81,6 @@ ISC_LANG_BEGINDECLS
|
|||
*** Types
|
||||
***/
|
||||
|
||||
typedef enum {
|
||||
isc_taskmgrmode_normal = 0,
|
||||
isc_taskmgrmode_privileged
|
||||
} isc_taskmgrmode_t;
|
||||
|
||||
isc_result_t
|
||||
isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
|
||||
isc_task_t **taskp);
|
||||
|
|
@ -450,42 +445,6 @@ isc_task_exiting(isc_task_t *t);
|
|||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_task_setprivilege(isc_task_t *task, bool priv);
|
||||
/*%<
|
||||
* Set or unset the task's "privileged" flag depending on the value of
|
||||
* 'priv'.
|
||||
*
|
||||
* Under normal circumstances this flag has no effect on the task behavior,
|
||||
* but when the task manager has been set to privileged execution mode via
|
||||
* isc_taskmgr_setmode(), only tasks with the flag set will be executed,
|
||||
* and all other tasks will wait until they're done. Once all privileged
|
||||
* tasks have finished executing, the task manager resumes running
|
||||
* non-privileged tasks.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_task_getprivilege(isc_task_t *task);
|
||||
/*%<
|
||||
* Returns the current value of the task's privilege flag.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_task_privileged(isc_task_t *task);
|
||||
/*%<
|
||||
* Returns true if the task's privilege flag is set *and* the task
|
||||
* manager is currently in privileged mode.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
/*****
|
||||
***** Task Manager.
|
||||
*****/
|
||||
|
|
@ -498,27 +457,6 @@ isc_taskmgr_detach(isc_taskmgr_t **);
|
|||
* Attach/detach the task manager.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
|
||||
isc_taskmgrmode_t
|
||||
isc_taskmgr_mode(isc_taskmgr_t *manager);
|
||||
/*%<
|
||||
* Set/get the operating mode of the task manager. Valid modes are:
|
||||
*
|
||||
*\li isc_taskmgrmode_normal
|
||||
*\li isc_taskmgrmode_privileged
|
||||
*
|
||||
* In privileged execution mode, only tasks that have had the "privilege"
|
||||
* flag set via isc_task_setprivilege() can be executed. When all such
|
||||
* tasks are complete, non-privileged tasks resume running. The task calling
|
||||
* this function should be in task-exclusive mode; the privileged tasks
|
||||
* will be run after isc_task_endexclusive() is called.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'manager' is a valid task manager.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -202,10 +202,9 @@ isc__nm_dump_active(isc_nm_t *nm);
|
|||
*/
|
||||
typedef enum {
|
||||
NETIEVENT_PRIORITY = 0,
|
||||
NETIEVENT_PRIVILEGED = 1,
|
||||
NETIEVENT_TASK = 2,
|
||||
NETIEVENT_NORMAL = 3,
|
||||
NETIEVENT_MAX = 4,
|
||||
NETIEVENT_TASK = 1,
|
||||
NETIEVENT_NORMAL = 2,
|
||||
NETIEVENT_MAX = 3,
|
||||
} netievent_type_t;
|
||||
|
||||
typedef struct isc__nm_uvreq isc__nm_uvreq_t;
|
||||
|
|
@ -332,7 +331,6 @@ typedef enum isc__netievent_type {
|
|||
netievent_sendcb,
|
||||
|
||||
netievent_task,
|
||||
netievent_privilegedtask,
|
||||
|
||||
/*
|
||||
* event type values higher than this will be treated
|
||||
|
|
@ -1961,7 +1959,6 @@ NETIEVENT_TYPE(shutdown);
|
|||
NETIEVENT_TYPE(stop);
|
||||
|
||||
NETIEVENT_TASK_TYPE(task);
|
||||
NETIEVENT_TASK_TYPE(privilegedtask);
|
||||
|
||||
/* Now declared the helper functions */
|
||||
|
||||
|
|
@ -2029,7 +2026,6 @@ NETIEVENT_DECL(shutdown);
|
|||
NETIEVENT_DECL(stop);
|
||||
|
||||
NETIEVENT_TASK_DECL(task);
|
||||
NETIEVENT_TASK_DECL(privilegedtask);
|
||||
|
||||
void
|
||||
isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
|
||||
|
|
|
|||
|
|
@ -442,8 +442,6 @@ isc_nm_resume(isc_nm_t *mgr) {
|
|||
}
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
drain_queue(&mgr->workers[isc_nm_tid()], NETIEVENT_PRIVILEGED);
|
||||
|
||||
atomic_fetch_sub(&mgr->workers_paused, 1);
|
||||
isc_barrier_wait(&mgr->resuming);
|
||||
}
|
||||
|
|
@ -608,19 +606,11 @@ isc_nm_gettimeouts(isc_nm_t *mgr, uint32_t *initial, uint32_t *idle,
|
|||
* is needed to properly start listening on the interfaces, free
|
||||
* resources on shutdown, or resume from a pause.
|
||||
*
|
||||
* 2. privileged task queue - only privileged tasks are queued here and
|
||||
* this is the first queue that gets processed when network manager
|
||||
* is unpaused using isc_nm_resume(). All netmgr workers need to
|
||||
* clean the privileged task queue before they all proceed to normal
|
||||
* operation. Both task queues are processed when the workers are
|
||||
* shutting down.
|
||||
* 2. task queue - only (traditional) tasks are scheduled here, and this queue
|
||||
* is processed when the netmgr workers are finishing. This is needed to
|
||||
* process the task shutdown events.
|
||||
*
|
||||
* 3. task queue - only (traditional) tasks are scheduled here, and this
|
||||
* queue and the privileged task queue are both processed when the
|
||||
* netmgr workers are finishing. This is needed to process the task
|
||||
* shutdown events.
|
||||
*
|
||||
* 4. normal queue - this is the queue with netmgr events, e.g. reading,
|
||||
* 3. normal queue - this is the queue with netmgr events, e.g. reading,
|
||||
* sending, callbacks, etc.
|
||||
*/
|
||||
|
||||
|
|
@ -635,8 +625,8 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
/*
|
||||
* uv_run() runs async_cb() in a loop, which processes
|
||||
* all four event queues until a "pause" or "stop" event
|
||||
* is encountered. On pause, we process only priority and
|
||||
* privileged events until resuming.
|
||||
* is encountered. On pause, we process only priority
|
||||
* events until resuming.
|
||||
*/
|
||||
int r = uv_run(&worker->loop, UV_RUN_DEFAULT);
|
||||
INSIST(r > 0 || worker->finished);
|
||||
|
|
@ -655,12 +645,6 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
wait_for_priority_queue(worker);
|
||||
}
|
||||
|
||||
/*
|
||||
* All workers must drain the privileged event
|
||||
* queue before we resume from pause.
|
||||
*/
|
||||
drain_queue(worker, NETIEVENT_PRIVILEGED);
|
||||
|
||||
atomic_fetch_sub(&mgr->workers_paused, 1);
|
||||
if (isc_barrier_wait(&mgr->resuming) != 0) {
|
||||
LOCK(&mgr->lock);
|
||||
|
|
@ -680,7 +664,6 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
/*
|
||||
* We are shutting down. Drain the queues.
|
||||
*/
|
||||
drain_queue(worker, NETIEVENT_PRIVILEGED);
|
||||
drain_queue(worker, NETIEVENT_TASK);
|
||||
|
||||
for (size_t type = 0; type < NETIEVENT_MAX; type++) {
|
||||
|
|
@ -761,20 +744,11 @@ isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int tid) {
|
|||
|
||||
worker = &nm->workers[tid];
|
||||
|
||||
if (isc_task_privileged(task)) {
|
||||
event = (isc__netievent_t *)
|
||||
isc__nm_get_netievent_privilegedtask(nm, task);
|
||||
} else {
|
||||
event = (isc__netievent_t *)isc__nm_get_netievent_task(nm,
|
||||
task);
|
||||
}
|
||||
event = (isc__netievent_t *)isc__nm_get_netievent_task(nm, task);
|
||||
|
||||
isc__nm_enqueue_ievent(worker, event);
|
||||
}
|
||||
|
||||
#define isc__nm_async_privilegedtask(worker, ev0) \
|
||||
isc__nm_async_task(worker, ev0)
|
||||
|
||||
static void
|
||||
isc__nm_async_task(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_task_t *ievent = (isc__netievent_task_t *)ev0;
|
||||
|
|
@ -853,7 +827,6 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
|
|||
/* Don't process more ievents when we are stopping */
|
||||
NETIEVENT_CASE_NOMORE(stop);
|
||||
|
||||
NETIEVENT_CASE(privilegedtask);
|
||||
NETIEVENT_CASE(task);
|
||||
|
||||
NETIEVENT_CASE(udpconnect);
|
||||
|
|
@ -1044,7 +1017,6 @@ NETIEVENT_DEF(shutdown);
|
|||
NETIEVENT_DEF(stop);
|
||||
|
||||
NETIEVENT_TASK_DEF(task);
|
||||
NETIEVENT_TASK_DEF(privilegedtask);
|
||||
|
||||
void
|
||||
isc__nm_maybe_enqueue_ievent(isc__networker_t *worker,
|
||||
|
|
@ -1072,9 +1044,6 @@ isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event) {
|
|||
case netievent_prio:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case netievent_privilegedtask:
|
||||
type = NETIEVENT_PRIVILEGED;
|
||||
break;
|
||||
case netievent_task:
|
||||
type = NETIEVENT_TASK;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -117,13 +117,11 @@ struct isc_task {
|
|||
bool bound;
|
||||
/* Protected by atomics */
|
||||
atomic_bool shuttingdown;
|
||||
atomic_bool privileged;
|
||||
/* Locked by task manager lock. */
|
||||
LINK(isc_task_t) link;
|
||||
};
|
||||
|
||||
#define TASK_SHUTTINGDOWN(t) (atomic_load_acquire(&(t)->shuttingdown))
|
||||
#define TASK_PRIVILEGED(t) (atomic_load_acquire(&(t)->privileged))
|
||||
|
||||
#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M')
|
||||
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)
|
||||
|
|
@ -240,7 +238,6 @@ isc_task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
|||
task->nevents = 0;
|
||||
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
|
||||
atomic_init(&task->shuttingdown, false);
|
||||
atomic_init(&task->privileged, false);
|
||||
task->now = 0;
|
||||
isc_time_settoepoch(&task->tnow);
|
||||
memset(task->name, 0, sizeof(task->name));
|
||||
|
|
@ -854,7 +851,6 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
|||
}
|
||||
|
||||
INIT_LIST(manager->tasks);
|
||||
atomic_init(&manager->mode, isc_taskmgrmode_normal);
|
||||
atomic_init(&manager->exclusive_req, false);
|
||||
atomic_init(&manager->tasks_count, 0);
|
||||
|
||||
|
|
@ -1044,37 +1040,6 @@ isc_task_endexclusive(isc_task_t *task) {
|
|||
&(bool){ true }, false));
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) {
|
||||
atomic_store(&manager->mode, mode);
|
||||
}
|
||||
|
||||
isc_taskmgrmode_t
|
||||
isc_taskmgr_mode(isc_taskmgr_t *manager) {
|
||||
return (atomic_load(&manager->mode));
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_setprivilege(isc_task_t *task, bool priv) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
atomic_store_release(&task->privileged, priv);
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_getprivilege(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
return (TASK_PRIVILEGED(task));
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_privileged(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
return (isc_taskmgr_mode(task->manager) && TASK_PRIVILEGED(task));
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_exiting(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
|
|
|||
|
|
@ -123,18 +123,6 @@ set(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
#include <isc/thread.h>
|
||||
|
||||
static void
|
||||
set_and_drop(isc_task_t *task, isc_event_t *event) {
|
||||
atomic_int_fast32_t *value = (atomic_int_fast32_t *)event->ev_arg;
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
isc_event_free(&event);
|
||||
LOCK(&lock);
|
||||
atomic_store(value, atomic_fetch_add(&counter, 1));
|
||||
UNLOCK(&lock);
|
||||
}
|
||||
|
||||
/* Create a task */
|
||||
static void
|
||||
create_task(void **state) {
|
||||
|
|
@ -194,230 +182,6 @@ all_events(void **state) {
|
|||
assert_null(task);
|
||||
}
|
||||
|
||||
/* Privileged events */
|
||||
static void
|
||||
privileged_events(void **state) {
|
||||
isc_result_t result;
|
||||
isc_task_t *task1 = NULL, *task2 = NULL;
|
||||
isc_event_t *event = NULL;
|
||||
atomic_int_fast32_t a, b, c, d, e;
|
||||
int i = 0;
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
atomic_init(&counter, 1);
|
||||
atomic_init(&a, -1);
|
||||
atomic_init(&b, -1);
|
||||
atomic_init(&c, -1);
|
||||
atomic_init(&d, -1);
|
||||
atomic_init(&e, -1);
|
||||
|
||||
/*
|
||||
* Pause the net/task manager so we can fill up the work
|
||||
* queue without things happening while we do it.
|
||||
*/
|
||||
isc_nm_pause(netmgr);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task1, "privileged", NULL);
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
isc_task_setprivilege(task1, true);
|
||||
assert_true(isc_task_getprivilege(task1));
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task2);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task2, "normal", NULL);
|
||||
assert_false(isc_task_getprivilege(task2));
|
||||
|
||||
/* First event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set,
|
||||
&a, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&a), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Second event: not privileged */
|
||||
event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, set,
|
||||
&b, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&b), -1);
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
/* Third event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set,
|
||||
&c, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&c), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Fourth event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set,
|
||||
&d, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&d), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Fifth event: not privileged */
|
||||
event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST, set,
|
||||
&e, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&e), -1);
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
isc_nm_resume(netmgr);
|
||||
|
||||
/* We're waiting for *all* variables to be set */
|
||||
while ((atomic_load(&a) < 0 || atomic_load(&b) < 0 ||
|
||||
atomic_load(&c) < 0 || atomic_load(&d) < 0 ||
|
||||
atomic_load(&e) < 0) &&
|
||||
i++ < 5000)
|
||||
{
|
||||
isc_test_nap(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't guarantee what order the events fire, but
|
||||
* we do know the privileged tasks that set a, c, and d
|
||||
* would have fired first.
|
||||
*/
|
||||
assert_true(atomic_load(&a) <= 3);
|
||||
assert_true(atomic_load(&c) <= 3);
|
||||
assert_true(atomic_load(&d) <= 3);
|
||||
|
||||
/* ...and the non-privileged tasks that set b and e, last */
|
||||
assert_true(atomic_load(&b) > 3);
|
||||
assert_true(atomic_load(&e) > 3);
|
||||
|
||||
assert_int_equal(atomic_load(&counter), 6);
|
||||
|
||||
isc_task_setprivilege(task1, false);
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
|
||||
isc_task_destroy(&task1);
|
||||
assert_null(task1);
|
||||
isc_task_destroy(&task2);
|
||||
assert_null(task2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Edge case: this tests that the task manager behaves as expected when
|
||||
* we explicitly set it into normal mode *while* running privileged.
|
||||
*/
|
||||
static void
|
||||
privilege_drop(void **state) {
|
||||
isc_result_t result;
|
||||
isc_task_t *task1 = NULL, *task2 = NULL;
|
||||
isc_event_t *event = NULL;
|
||||
atomic_int_fast32_t a, b, c, d, e; /* non valid states */
|
||||
int i = 0;
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
atomic_init(&counter, 1);
|
||||
atomic_init(&a, -1);
|
||||
atomic_init(&b, -1);
|
||||
atomic_init(&c, -1);
|
||||
atomic_init(&d, -1);
|
||||
atomic_init(&e, -1);
|
||||
|
||||
/*
|
||||
* Pause the net/task manager so we can fill up the work queue
|
||||
* without things happening while we do it.
|
||||
*/
|
||||
isc_nm_pause(netmgr);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task1, "privileged", NULL);
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
isc_task_setprivilege(task1, true);
|
||||
assert_true(isc_task_getprivilege(task1));
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task2);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task2, "normal", NULL);
|
||||
assert_false(isc_task_getprivilege(task2));
|
||||
|
||||
/* First event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST,
|
||||
set_and_drop, &a, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&a), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Second event: not privileged */
|
||||
event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST,
|
||||
set_and_drop, &b, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&b), -1);
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
/* Third event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST,
|
||||
set_and_drop, &c, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&c), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Fourth event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST,
|
||||
set_and_drop, &d, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&d), -1);
|
||||
isc_task_send(task1, &event);
|
||||
|
||||
/* Fifth event: not privileged */
|
||||
event = isc_event_allocate(test_mctx, task2, ISC_TASKEVENT_TEST,
|
||||
set_and_drop, &e, sizeof(isc_event_t));
|
||||
assert_non_null(event);
|
||||
|
||||
assert_int_equal(atomic_load(&e), -1);
|
||||
isc_task_send(task2, &event);
|
||||
|
||||
isc_nm_resume(netmgr);
|
||||
|
||||
/* We're waiting for all variables to be set. */
|
||||
while ((atomic_load(&a) == -1 || atomic_load(&b) == -1 ||
|
||||
atomic_load(&c) == -1 || atomic_load(&d) == -1 ||
|
||||
atomic_load(&e) == -1) &&
|
||||
i++ < 5000)
|
||||
{
|
||||
isc_test_nap(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to check that all privilege mode events were fired
|
||||
* in privileged mode, and non privileged in non-privileged.
|
||||
*/
|
||||
assert_true(atomic_load(&a) <= 3);
|
||||
assert_true(atomic_load(&c) <= 3);
|
||||
assert_true(atomic_load(&d) <= 3);
|
||||
|
||||
/* ...and neither of the non-privileged tasks did... */
|
||||
assert_true(atomic_load(&b) > 3);
|
||||
assert_true(atomic_load(&e) > 3);
|
||||
|
||||
/* ...but all five of them did run. */
|
||||
assert_int_equal(atomic_load(&counter), 6);
|
||||
|
||||
isc_task_destroy(&task1);
|
||||
assert_null(task1);
|
||||
isc_task_destroy(&task2);
|
||||
assert_null(task2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic task functions:
|
||||
*/
|
||||
|
|
@ -1089,10 +853,6 @@ main(int argc, char **argv) {
|
|||
cmocka_unit_test_setup_teardown(create_task, _setup, _teardown),
|
||||
cmocka_unit_test_setup_teardown(post_shutdown, _setup2,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(privilege_drop, _setup,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(privileged_events, _setup,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(purgeevent, _setup2, _teardown),
|
||||
cmocka_unit_test_setup_teardown(task_shutdown, _setup4,
|
||||
_teardown),
|
||||
|
|
|
|||
Loading…
Reference in a new issue