From: Mateusz Majewski Date: Fri, 26 Mar 2021 14:20:36 +0000 (+0100) Subject: Make the limiter a self-contained struct X-Git-Tag: accepted/tizen/unified/20210623.125322~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=96f01945530c450796b86aac538d1b45d93a1272;p=platform%2Fcore%2Fsystem%2Fdlog.git Make the limiter a self-contained struct Change-Id: Ic2abf2da2b9e51b596e5612d9ac65044cf4540c4 --- diff --git a/include/dynamic_config.h b/include/dynamic_config.h index 3027056..de1fb63 100644 --- a/include/dynamic_config.h +++ b/include/dynamic_config.h @@ -1,5 +1,7 @@ #pragma once +#include + /* MIT License * * Copyright (c) 2018-2020 Samsung Electronics Co., Ltd @@ -35,7 +37,7 @@ extern "C" { bool __dynamic_config_create(struct log_config *config); void __dynamic_config_destroy(void); -void __dynamic_config_update(void); +void __dynamic_config_update(struct limiter_data *limiter_data);; #ifdef __cplusplus } diff --git a/include/loglimiter-internal.h b/include/loglimiter-internal.h index c89dcb2..f0effbd 100644 --- a/include/loglimiter-internal.h +++ b/include/loglimiter-internal.h @@ -21,7 +21,31 @@ struct rule { enum rule_type type; }; -int __log_limiter_initialize(struct rule *rules_table); +typedef int (*hash_cmp_func_t)(struct rule *, struct rule *); +typedef int (*hash_match_func_t)(struct rule *, unsigned, const char *, int); + +struct hashmap { + hash_cmp_func_t cmp; + hash_match_func_t match; + int size; + void *bucket[]; +}; + +struct limiter_data { + pid_t prev_pid; + size_t sent_by_me; + bool already_exceeded; + time_t last_pid_time; + struct pid_limit *cached_pid_rule; + list_head pid_rules; + time_t refresh_rate_s; + struct rule *current_rules_table; + struct rule *original_rules_table; + struct hashmap *rules_hashmap; + +}; + +int __log_limiter_initialize(struct limiter_data *limiter_data, struct rule *rules_table); uint32_t util_hash_key(const char *s, int c); #endif // LOGLIMITER_INTERNAL_H_ diff --git a/include/loglimiter.h b/include/loglimiter.h index bb41008..d66c6a6 100644 --- a/include/loglimiter.h +++ b/include/loglimiter.h @@ -37,6 +37,7 @@ extern "C" { #include struct rule; +struct limiter_data; struct limiter_limits { int tag_and_prio; @@ -50,7 +51,7 @@ struct pid_limit { size_t limit; }; -void __log_limiter_destroy(void); +void __log_limiter_destroy(struct limiter_data *limiter_data); struct pass_log_result { enum { @@ -64,18 +65,18 @@ struct pass_log_result { int period_s; }; -struct pass_log_result __log_limiter_pass_log(const char *tag, int prio); +struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio); -int __log_limiter_create(const struct log_config *config); +struct limiter_data *__log_limiter_create(const struct log_config *config); -struct limiter_limits __log_limiter_get_limits(const char *tag, int prio); +struct limiter_limits __log_limiter_get_limits(struct limiter_data *limiter_data, const char *tag, int prio); -void __log_limiter_update(const struct log_config *config); +void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config); -int __log_limiter_dump_rule(struct rule **, char *, const size_t); +int __log_limiter_dump_rule(struct limiter_data *limiter_data, struct rule **r, char *buf, const size_t size); // Note: result only valid until next __log_limiter_{update,destroy} -list_head __log_limiter_get_pid_limits(void); +list_head __log_limiter_get_pid_limits(struct limiter_data *limiter_data); #ifdef __cplusplus } diff --git a/src/libdlog/dynamic_config.c b/src/libdlog/dynamic_config.c index c17471b..b8f217c 100644 --- a/src/libdlog/dynamic_config.c +++ b/src/libdlog/dynamic_config.c @@ -67,7 +67,7 @@ static bool __setup_runtime_watch(char const *path) return true; } -static void __apply_update(void) +static void __apply_update(struct limiter_data *limiter_data) { assert(inotify_path); @@ -83,7 +83,7 @@ static void __apply_update(void) const int l = pthread_rwlock_wrlock(&log_limiter_lock); assert(!l); // we should never have a read lock at this point so wrlock() cannot fail - __log_limiter_update(&config); + __log_limiter_update(limiter_data, &config); pthread_rwlock_unlock(&log_limiter_lock); } } @@ -141,7 +141,7 @@ void __dynamic_config_destroy(void) inotify_fd = -1; } -void __dynamic_config_update(void) +void __dynamic_config_update(struct limiter_data *limiter_data) { if (inotify_fd < 0) return; @@ -187,7 +187,7 @@ void __dynamic_config_update(void) if (lock_r < 0) return; - __apply_update(); + __apply_update(limiter_data); pthread_mutex_unlock(&log_dynamic_config_lock); } diff --git a/src/libdlog/log.c b/src/libdlog/log.c index 98488d6..9469e02 100644 --- a/src/libdlog/log.c +++ b/src/libdlog/log.c @@ -73,6 +73,7 @@ extern void __dlog_init_pipe(const struct log_config *conf); extern void __dlog_init_android(const struct log_config *conf); bool limiter; +struct limiter_data *limiter_data; static bool dynamic_config; static bool plog[LOG_ID_MAX]; static bool plog_default_values[LOG_ID_MAX]; @@ -98,9 +99,10 @@ static void __configure_limiter(struct log_config *static_config, struct log_con if (!limiter) return; - limiter = __log_limiter_create(static_config); - if (limiter && dynamic_config) - __log_limiter_update(both_config); + limiter_data = __log_limiter_create(static_config); + if (limiter_data && dynamic_config) + __log_limiter_update(limiter_data, both_config); + limiter = (bool)limiter_data; } static int __configure_backend(struct log_config *config) @@ -349,12 +351,12 @@ static int dlog_check_limiter(log_id_t log_id, int prio, const char *tag) return DLOG_ERROR_NOT_PERMITTED; if (dynamic_config) - __dynamic_config_update(); + __dynamic_config_update(limiter_data); if (limiter) { struct pass_log_result should_log = { .decision = DECISION_DENIED }; if (!pthread_rwlock_rdlock(&log_limiter_lock)) { - should_log = __log_limiter_pass_log(tag, prio); + should_log = __log_limiter_pass_log(limiter_data, tag, prio); pthread_rwlock_unlock(&log_limiter_lock); } @@ -750,7 +752,7 @@ void __dlog_fini(void) enable_secure_logs = true; enable_critical = false; __deduplicate_destroy(); - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); limiter = false; __dynamic_config_destroy(); } diff --git a/src/logctl/logctl.c b/src/logctl/logctl.c index 64a28af..c3a7c47 100644 --- a/src/logctl/logctl.c +++ b/src/logctl/logctl.c @@ -586,24 +586,24 @@ static void get_pid_rule(void *prerule, void *prepid) printf("%zu logs/min\n", rule->limit); } -static void get_pid_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf) +static void get_pid_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf) { log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply - __log_limiter_update(conf); + __log_limiter_update(limiter_data, conf); pid_t pid_to_find = params->pid; - list_head pidrules = __log_limiter_get_pid_limits(); + list_head pidrules = __log_limiter_get_pid_limits(limiter_data); if (pidrules) list_foreach(pidrules, &pid_to_find, get_pid_rule); } -static void get_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf) +static void get_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf) { - struct limiter_limits lims_static = __log_limiter_get_limits(params->tag, params->prio); + struct limiter_limits lims_static = __log_limiter_get_limits(limiter_data, params->tag, params->prio); log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply - __log_limiter_update(conf); - struct limiter_limits lims_dynamic = __log_limiter_get_limits(params->tag, params->prio); + __log_limiter_update(limiter_data, conf); + struct limiter_limits lims_dynamic = __log_limiter_get_limits(limiter_data, params->tag, params->prio); bool shadowed = false; if (strcmp(params->tag, "*")) { @@ -657,20 +657,20 @@ static void print_limits_for_prio(const struct parsed_params *params, const char } } -static void get_prio_limits(const struct parsed_params *params, const char *config_path, struct log_config *conf) +static void get_prio_limits(struct limiter_data *limiter_data, const struct parsed_params *params, const char *config_path, struct log_config *conf) { static const char prio_list[] = {'V', 'D', 'I', 'W', 'E', 'F' , 'S' , '*'}; struct prio_applies_to applies_dynamic = { .count = 0 }; struct prio_applies_to applies_static = { .count = 0 }; for (size_t i = 0; i < NELEMS(prio_list); i++) - applies_static.lims[i] = __log_limiter_get_limits(params->tag, prio_list[i]); + applies_static.lims[i] = __log_limiter_get_limits(limiter_data, params->tag, prio_list[i]); log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply - __log_limiter_update(conf); + __log_limiter_update(limiter_data, conf); for (size_t i = 0; i < NELEMS(prio_list); i++) { - applies_dynamic.lims[i] = __log_limiter_get_limits(params->tag, prio_list[i]); + applies_dynamic.lims[i] = __log_limiter_get_limits(limiter_data, params->tag, prio_list[i]); bool shadowed = false; print_limits_for_prio(params, prio_list, &applies_dynamic, i, &shadowed, true); @@ -681,19 +681,20 @@ static void get_prio_limits(const struct parsed_params *params, const char *conf int handle_get(const struct parsed_params *params, const char *config_path, struct log_config *conf) { - if (!__log_limiter_create(conf)) { + struct limiter_data *limiter_data = __log_limiter_create(conf); + if (!limiter_data) { ERR("error creating limiter\n"); return EXIT_FAILURE; } if (params->pid != 0) - get_pid_limits(params, config_path, conf); + get_pid_limits(limiter_data, params, config_path, conf); else if (params->prio == '\0') - get_prio_limits(params, config_path, conf); + get_prio_limits(limiter_data, params, config_path, conf); else - get_limits(params, config_path, conf); + get_limits(limiter_data, params, config_path, conf); - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); return EXIT_SUCCESS; } @@ -713,27 +714,28 @@ void dump_pid_rule(void *prerule, void *_garbage) int handle_dump(const struct parsed_params *params, const char *config_path, struct log_config *conf) { (void) params; - if (!__log_limiter_create(conf)) { + struct limiter_data *limiter_data = __log_limiter_create(conf); + if (!limiter_data) { ERR("error creating limiter\n"); return EXIT_FAILURE; } char buf[1024]; log_config_read_file(conf, config_path); // not an error on failure - config still valid if missing, static rules apply - __log_limiter_update(conf); + __log_limiter_update(limiter_data, conf); struct rule *r = NULL; do { - int ret = __log_limiter_dump_rule(&r, buf, sizeof buf); + int ret = __log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf); if (ret < 0) { ERR("Error dumping rule\n"); - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); return EXIT_FAILURE; } printf("%s\n", buf); } while (r); - list_head pidrules = __log_limiter_get_pid_limits(); + list_head pidrules = __log_limiter_get_pid_limits(limiter_data); if (pidrules) list_foreach(pidrules, NULL, dump_pid_rule); @@ -758,7 +760,7 @@ int handle_dump(const struct parsed_params *params, const char *config_path, str ret != 0 ? "UNKNOWN" : stdout_enabled ? "ENABLED" : "DISABLED"); } - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); return EXIT_SUCCESS; } diff --git a/src/shared/loglimiter.c b/src/shared/loglimiter.c index de9ce71..dd4832f 100644 --- a/src/shared/loglimiter.c +++ b/src/shared/loglimiter.c @@ -42,88 +42,74 @@ #include #include -typedef int (*hash_cmp_func_t)(struct rule *, struct rule *); -typedef int (*hash_match_func_t)(struct rule *, unsigned, const char *, int); - -struct hashmap { - hash_cmp_func_t cmp; - hash_match_func_t match; - int size; - void *bucket[]; -}; - -static list_head pid_rules = NULL; - -static struct hashmap *rules_hashmap = NULL; - -/* Keep rules table as single-linked list */ -static struct rule *current_rules_table = NULL; -static struct rule *original_rules_table = NULL; - #define HASHMAP_MASK(hm) ((int)(hm->size - 1)) #define HASHMAP_LINEAR_PROBE_LEAP 1 -static struct pid_limit *cached_pid_rule = NULL; static struct pid_limit no_limit_rule = { .pid = -1, .limit = SIZE_MAX }; -static size_t sent_by_me = 0; -static time_t last_pid_time = -1; -static time_t refresh_rate_s = -1; -static pid_t prev_pid = -1; -static bool already_exceeded = false; + +struct find_my_rule_data { + pid_t my_pid; + struct limiter_data *limiter_data; +}; void find_my_rule(elem_value value, void *userdata) { - const pid_t my_pid = *(pid_t *)userdata; + struct find_my_rule_data *find_my_rule_data = userdata; struct pid_limit *const p = (struct pid_limit *) value; - if (p->pid == my_pid) - cached_pid_rule = p; + if (p->pid == find_my_rule_data->my_pid) + find_my_rule_data->limiter_data->cached_pid_rule = p; } -static struct pass_log_result block_by_pid(void) +static struct pass_log_result block_by_pid(struct limiter_data *limiter_data) { + assert(limiter_data); + pid_t my_pid = getpid(); /* We cache the rule relevant to our pid since * our pid doesn't usually change. Fork exists * though so we have to pay attention lest we * use an obsolete value. */ - if (!cached_pid_rule || ((cached_pid_rule->pid != -1 || prev_pid != my_pid) && cached_pid_rule->pid != my_pid)) { + if (!limiter_data->cached_pid_rule || ((limiter_data->cached_pid_rule->pid != -1 || limiter_data->prev_pid != my_pid) && limiter_data->cached_pid_rule->pid != my_pid)) { /* Forking resets the counter (mostly so that launcher * log usage does not get inherited by innocent apps, * since forking is otherwise fairly rare as far as * typical dlog clients go). */ - if (prev_pid != my_pid) { - last_pid_time = -1; - already_exceeded = false; - sent_by_me = 0; + if (limiter_data->prev_pid != my_pid) { + limiter_data->last_pid_time = -1; + limiter_data->already_exceeded = false; + limiter_data->sent_by_me = 0; } - cached_pid_rule = &no_limit_rule; - list_foreach(pid_rules, &my_pid, find_my_rule); + limiter_data->cached_pid_rule = &no_limit_rule; + list_foreach(limiter_data->pid_rules, &(struct find_my_rule_data) { + .my_pid = my_pid, + .limiter_data = limiter_data, + }, find_my_rule); } const time_t now = time(NULL); - if (now >= last_pid_time + refresh_rate_s) { - last_pid_time = now; - already_exceeded = false; - sent_by_me = 1; + if (now >= limiter_data->last_pid_time + limiter_data->refresh_rate_s) { + limiter_data->last_pid_time = now; + limiter_data->already_exceeded = false; + limiter_data->sent_by_me = 1; } else - sent_by_me += 1; + limiter_data->sent_by_me += 1; - if (cached_pid_rule->limit > __LOG_LIMITER_LIMIT_MAX) + if (limiter_data->cached_pid_rule->limit > __LOG_LIMITER_LIMIT_MAX) return (struct pass_log_result) { .decision = DECISION_ALLOWED, }; - prev_pid = my_pid; - if (sent_by_me <= cached_pid_rule->limit) + limiter_data->prev_pid = my_pid; + if (limiter_data->sent_by_me <= limiter_data->cached_pid_rule->limit) return (struct pass_log_result) { .decision = DECISION_ALLOWED, }; - else if (!already_exceeded) { - already_exceeded = true; + else if (!limiter_data->already_exceeded) { + limiter_data->already_exceeded = true; return (struct pass_log_result) { .decision = DECISION_PID_LIMIT_EXCEEDED_MESSAGE, - .logs_per_period = cached_pid_rule->limit, - .period_s = refresh_rate_s, + .logs_per_period = limiter_data->cached_pid_rule->limit, + .period_s = limiter_data->refresh_rate_s, }; } else return (struct pass_log_result) { .decision = DECISION_DENIED, }; @@ -308,7 +294,7 @@ static struct rule *hashmap_search(struct hashmap *hm, } /* Must be always executed after __log_config_read() */ -int __log_limiter_initialize(struct rule *rules_table) +int __log_limiter_initialize(struct limiter_data *limiter_data, struct rule *rules_table) { int hm_size; struct rule *rlist = NULL; @@ -326,35 +312,40 @@ int __log_limiter_initialize(struct rule *rules_table) } /* Allocate hashmap */ - rules_hashmap = (struct hashmap *) hashmap_create(hm_size, + limiter_data->rules_hashmap = (struct hashmap *) hashmap_create(hm_size, &rule_compare, &rule_match); - if (NULL == rules_hashmap || !rules_hashmap->size) { - hashmap_destroy(&rules_hashmap); + if (NULL == limiter_data->rules_hashmap || !limiter_data->rules_hashmap->size) { + hashmap_destroy(&limiter_data->rules_hashmap); return -1; } /* Add rule to hashmap */ rlist = rules_table; while (rlist) { - hashmap_add(rules_hashmap, rlist); + hashmap_add(limiter_data->rules_hashmap, rlist); rlist = rlist->prev; } return 0; } -static void destroy_hashmap_etc(void) +static void destroy_hashmap_etc(struct limiter_data *limiter_data) { - hashmap_destroy(&rules_hashmap); - rules_destroy(&original_rules_table); + assert(limiter_data); + + hashmap_destroy(&limiter_data->rules_hashmap); + rules_destroy(&limiter_data->original_rules_table); } -void __log_limiter_destroy(void) +void __log_limiter_destroy(struct limiter_data *limiter_data) { - cached_pid_rule = NULL; - list_clear_free_contents(&pid_rules); - destroy_hashmap_etc(); + if (!limiter_data) + return; + + list_clear_free_contents(&limiter_data->pid_rules); + destroy_hashmap_etc(limiter_data); + free(limiter_data); } struct rule *__log_limiter_add_rule(struct rule **rules_table, const char *tag, int prio, int limit) @@ -394,16 +385,16 @@ struct rule *__log_limiter_add_rule(struct rule **rules_table, const char *tag, return r; } -struct limiter_limits __log_limiter_get_limits(const char *tag, int prio) +struct limiter_limits __log_limiter_get_limits(struct limiter_data *limiter_data, const char *tag, int prio) { const struct rule fallback = { .limit = -1 }; const char prio_c = util_prio_to_char(prio); return (struct limiter_limits) { - .tag_and_prio = (hashmap_search(rules_hashmap, tag, prio_c) ?: &fallback)->limit, - .tag = (hashmap_search(rules_hashmap, tag, '*') ?: &fallback)->limit, - .prio = (hashmap_search(rules_hashmap, "*", prio_c) ?: &fallback)->limit, - .global = (hashmap_search(rules_hashmap, "*", '*') ?: &fallback)->limit, + .tag_and_prio = (hashmap_search(limiter_data->rules_hashmap, tag, prio_c) ?: &fallback)->limit, + .tag = (hashmap_search(limiter_data->rules_hashmap, tag, '*') ?: &fallback)->limit, + .prio = (hashmap_search(limiter_data->rules_hashmap, "*", prio_c) ?: &fallback)->limit, + .global = (hashmap_search(limiter_data->rules_hashmap, "*", '*') ?: &fallback)->limit, }; } @@ -414,13 +405,15 @@ struct limiter_limits __log_limiter_get_limits(const char *tag, int prio) * On first time being blocked, it will return *_LIMIT_EXCEEDED_MESSAGE in the decision field, * which allows the callee to write a relevant message to logs. */ -struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) +struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio) { - struct pass_log_result pid_result = block_by_pid(); + assert(limiter_data); + + struct pass_log_result pid_result = block_by_pid(limiter_data); if (pid_result.decision != DECISION_ALLOWED) return pid_result; - if (!rules_hashmap) + if (!limiter_data->rules_hashmap) return (struct pass_log_result) { .decision = DECISION_ALLOWED, }; /* allow empty-tagged messages and make it easy to catch an application that does that */ @@ -429,10 +422,10 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) const char prio_c = util_prio_to_char(prio); struct rule *r = - hashmap_search(rules_hashmap, tag, prio_c) ?: - hashmap_search(rules_hashmap, tag, '*') ?: - hashmap_search(rules_hashmap, "*", prio_c) ?: - hashmap_search(rules_hashmap, "*", '*'); + hashmap_search(limiter_data->rules_hashmap, tag, prio_c) ?: + hashmap_search(limiter_data->rules_hashmap, tag, '*') ?: + hashmap_search(limiter_data->rules_hashmap, "*", prio_c) ?: + hashmap_search(limiter_data->rules_hashmap, "*", '*'); if (!r) return (struct pass_log_result) { .decision = DECISION_ALLOWED, }; @@ -447,7 +440,7 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) if (0 > now) return (struct pass_log_result) { .decision = DECISION_ALLOWED, }; - if (now - r->start <= refresh_rate_s) { + if (now - r->start <= limiter_data->refresh_rate_s) { if (r->hit >= 0) { if (r->hit < r->limit) { r->hit++; @@ -457,7 +450,7 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) return (struct pass_log_result) { .decision = DECISION_TAG_LIMIT_EXCEEDED_MESSAGE, .logs_per_period = r->limit, - .period_s = refresh_rate_s, + .period_s = limiter_data->refresh_rate_s, }; } else { r->hit++; @@ -470,6 +463,11 @@ struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) } } +struct iteration_data { + struct rule **rules_table; + struct limiter_data *limiter_data; +}; + /** * @brief Limiter rule from config * @details Adds a limiter rule from a config entry, if one exists inside @@ -481,8 +479,8 @@ static void regular_limiter_iteration(const char *key, const char *value, void * { assert(key); assert(value); - struct rule **rules_table = (struct rule **)userdata; - assert(rules_table); + assert(userdata); + struct iteration_data *data = userdata; static const int prefix_len = sizeof("limiter|") - 1; char * delimiter_pos; @@ -505,11 +503,16 @@ static void regular_limiter_iteration(const char *key, const char *value, void * else limit = atoi(value); - __log_limiter_add_rule(rules_table, limiter_tag, *(delimiter_pos + 1), limit); + __log_limiter_add_rule(data->rules_table, limiter_tag, *(delimiter_pos + 1), limit); } static void pid_limiter_iteration(const char *key, const char *value, void *userdata) { + assert(key); + assert(value); + assert(userdata); + struct iteration_data *data = userdata; + if (strncmp(key, "pidlimit|", sizeof "pidlimit|" - 1)) return; @@ -529,7 +532,7 @@ static void pid_limiter_iteration(const char *key, const char *value, void *user p->limit = limit; p->pid = pid; - list_add(&pid_rules, p); + list_add(&data->limiter_data->pid_rules, p); } static void __config_iteration(const char *key, const char *value, void *userdata) @@ -538,24 +541,41 @@ static void __config_iteration(const char *key, const char *value, void *userdat pid_limiter_iteration(key, value, userdata); } -int __log_limiter_create(const struct log_config *config) +struct limiter_data *__log_limiter_create(const struct log_config *config) { assert(config); - assert(!original_rules_table); - assert(!rules_hashmap); - last_pid_time = time(NULL); - cached_pid_rule = NULL; - log_config_foreach(config, __config_iteration, &original_rules_table); - refresh_rate_s = log_config_get_int(config, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S); + struct limiter_data *ret = calloc(1, sizeof(struct limiter_data)); + if (!ret) + return NULL; - const int r = __log_limiter_initialize(original_rules_table); + ret->original_rules_table = NULL; + ret->current_rules_table = NULL; + ret->prev_pid = -1; + ret->sent_by_me = 0; + ret->already_exceeded = false; + ret->last_pid_time = time(NULL); + ret->cached_pid_rule = NULL; + ret->pid_rules = NULL; + log_config_foreach(config, __config_iteration, &(struct iteration_data) { + .rules_table = &ret->original_rules_table, + .limiter_data = ret, + }); + ret->refresh_rate_s = log_config_get_int(config, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S); + ret->rules_hashmap = NULL; + + const int r = __log_limiter_initialize(ret, ret->original_rules_table); if (r) { - rules_destroy(&original_rules_table); - return pid_rules != NULL; + rules_destroy(&ret->original_rules_table); + if (ret->pid_rules != NULL) + return ret; + else { + free(ret); + return NULL; + } } - for (struct rule *i = original_rules_table; i; i = i->prev) + for (struct rule *i = ret->original_rules_table; i; i = i->prev) i->type = RULE_STATIC; /* The following makes sure that the current ruleset is initialized. @@ -563,32 +583,36 @@ int __log_limiter_create(const struct log_config *config) * at this point. In general, whoever calls this function also calls * __log_limiter_update, so this shouldn't be needed. However, it's * a good idea to do this, and also this was needed for some tests. */ - __log_limiter_update(&(struct log_config) { }); + __log_limiter_update(ret, &(struct log_config) { }); - return 1; + return ret; } -void __log_limiter_update(const struct log_config *config) +void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { assert(config); - assert(!original_rules_table || rules_hashmap); + assert(!limiter_data->original_rules_table || limiter_data->rules_hashmap); + assert(limiter_data); struct rule *rules_table = NULL; - for (struct rule *i = original_rules_table; i; i = i->prev) { + for (struct rule *i = limiter_data->original_rules_table; i; i = i->prev) { struct rule *r = __log_limiter_add_rule(&rules_table, i->tag, i->prio, i->limit); if (!r) continue; r->type = RULE_STATIC; } - cached_pid_rule = NULL; - list_clear_free_contents(&pid_rules); - log_config_foreach(config, __config_iteration, &rules_table); + limiter_data->cached_pid_rule = NULL; + list_clear_free_contents(&limiter_data->pid_rules); + log_config_foreach(config, __config_iteration, &(struct iteration_data) { + .rules_table = &rules_table, + .limiter_data = limiter_data, + }); - if (rules_hashmap) { + if (limiter_data->rules_hashmap) { for (struct rule *i = rules_table; i; i = i->prev) { const char prio_c = util_prio_to_char(i->prio); - const struct rule *const prev_rule = hashmap_search(rules_hashmap, i->tag, prio_c); + const struct rule *const prev_rule = hashmap_search(limiter_data->rules_hashmap, i->tag, prio_c); if (!prev_rule) continue; @@ -597,14 +621,14 @@ void __log_limiter_update(const struct log_config *config) } } - hashmap_destroy(&rules_hashmap); - if (__log_limiter_initialize(rules_table) < 0) { - destroy_hashmap_etc(); + hashmap_destroy(&limiter_data->rules_hashmap); + if (__log_limiter_initialize(limiter_data, rules_table) < 0) { + destroy_hashmap_etc(limiter_data); return; } - rules_destroy(¤t_rules_table); - current_rules_table = rules_table; + rules_destroy(&limiter_data->current_rules_table); + limiter_data->current_rules_table = rules_table; } /** @@ -615,9 +639,9 @@ void __log_limiter_update(const struct log_config *config) * @param[in] size The size of the buffer * @returns 0 on success, -1 on failure */ -int __log_limiter_dump_rule(struct rule **r, char *buf, const size_t size) +int __log_limiter_dump_rule(struct limiter_data *limiter_data, struct rule **r, char *buf, const size_t size) { - struct rule *ruleptr = *r ? : current_rules_table; + struct rule *ruleptr = *r ? : limiter_data->current_rules_table; int s = 0; if (!ruleptr) { @@ -646,7 +670,7 @@ int __log_limiter_dump_rule(struct rule **r, char *buf, const size_t size) return 0; } -list_head __log_limiter_get_pid_limits(void) +list_head __log_limiter_get_pid_limits(struct limiter_data *limiter_data) { - return pid_rules; + return limiter_data->pid_rules; } diff --git a/src/tests/dynamic_config.c b/src/tests/dynamic_config.c index 4c84526..524d928 100644 --- a/src/tests/dynamic_config.c +++ b/src/tests/dynamic_config.c @@ -14,6 +14,7 @@ // DLog #include +#include pthread_rwlock_t log_limiter_lock = PTHREAD_RWLOCK_INITIALIZER; bool limiter; @@ -95,8 +96,9 @@ void __update_plog(const struct log_config *conf) } static bool limiter_update_called = false; -void __log_limiter_update(struct log_config *config) +void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { + assert(limiter_data == (struct limiter_data *)0x12345); limiter_update_called = true; } @@ -128,9 +130,9 @@ int __wrap_pthread_mutex_trylock(pthread_mutex_t *mutex) int main(void) { // check whether these blow up when called before init - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); __dynamic_config_destroy(); - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); struct log_config conf = {NULL, NULL}; assert(!__dynamic_config_create(&conf)); @@ -156,32 +158,32 @@ int main(void) assert(!critical_failure_detected); limiter = false; - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); assert(update_plog_called); assert(!limiter_update_called); update_plog_called = false; limiter = true; - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); assert(update_plog_called); assert(limiter_update_called); update_plog_called = false; limiter_update_called = false; fail_read = true; - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); assert(!update_plog_called); assert(!limiter_update_called); fail_read = false; empty_read = true; - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); assert(!update_plog_called); assert(!limiter_update_called); empty_read = false; pretend_the_mutex_is_locked = true; - __dynamic_config_update(); + __dynamic_config_update((struct limiter_data *)0x12345); assert(!update_plog_called); assert(!limiter_update_called); pretend_the_mutex_is_locked = false; diff --git a/src/tests/libdlog_base_wrap.c b/src/tests/libdlog_base_wrap.c index 8978656..f9c8954 100644 --- a/src/tests/libdlog_base_wrap.c +++ b/src/tests/libdlog_base_wrap.c @@ -25,9 +25,10 @@ #include #include #include +#include -void __log_limiter_update(const struct log_config *config) { } -void __log_limiter_destroy(void) { } +void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { } +void __log_limiter_destroy(struct limiter_data *limiter_data) { } void __dynamic_config_destroy(void) { } static bool destroyed; @@ -62,20 +63,21 @@ int __wrap_log_config_read(struct log_config *config) } struct pass_log_result limiter_ret; -struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) { return limiter_ret; } +struct pass_log_result __log_limiter_pass_log(struct limiter_data *limiter_data, const char *tag, int prio) { return limiter_ret; } static bool limiter_created; -int __log_limiter_create(const struct log_config *config) +static struct limiter_data limiter_data_ret; +struct limiter_data *__log_limiter_create(const struct log_config *config) { limiter_created = true; - return 1; + return &limiter_data_ret; } static bool use_dynamic_conf; bool __dynamic_config_create(struct log_config *config) { return use_dynamic_conf; } static bool dynamic_config_called; -void __dynamic_config_update(void) { dynamic_config_called = true; } +void __dynamic_config_update(struct limiter_data *limiter_data) { dynamic_config_called = true; } bool fail_snprintf; int __wrap_snprintf(char *str, size_t size, const char *format, ...) diff --git a/src/tests/libdlog_prio_filter_pos.c b/src/tests/libdlog_prio_filter_pos.c index e564943..f5672bc 100644 --- a/src/tests/libdlog_prio_filter_pos.c +++ b/src/tests/libdlog_prio_filter_pos.c @@ -23,6 +23,7 @@ #include #include #include +#include int wtl(log_id_t buf_id, log_priority pri, const char *tag, const char *msg, struct timespec *tp_mono) { return 0xABCD; } void __dlog_init_pipe(const struct log_config *conf) { write_to_log = wtl; } @@ -36,13 +37,14 @@ int __wrap_log_config_read(struct log_config *config) } // lobotomize various mechanisms I don't want to deal with -void __log_limiter_update(const struct log_config *config) { } -void __log_limiter_destroy(void) { } +void __log_limiter_update(struct limiter_data *limiter_data, const struct log_config *config) { } +void __log_limiter_destroy(struct limiter_data *limiter_data) { } void __dynamic_config_destroy(void) { } -struct pass_log_result __log_limiter_pass_log(const char *tag, int prio) { return (struct pass_log_result) { .decision = DECISION_ALLOWED }; } -int __log_limiter_create(const struct log_config *config) { return 1; } +struct pass_log_result __log_limiter_pass_log(struct limiter_data *data, const char *tag, int prio) { return (struct pass_log_result) { .decision = DECISION_ALLOWED }; } +static struct limiter_data limiter_data_ret; +struct limiter_data *__log_limiter_create(const struct log_config *config) { return &limiter_data_ret; } bool __dynamic_config_create(struct log_config *config) { return false; } -void __dynamic_config_update(void) { } +void __dynamic_config_update(struct limiter_data *limiter_data) { } void __dlog_init_android(const struct log_config *conf) { } diff --git a/src/tests/limiter_neg.c b/src/tests/limiter_neg.c index 8edeb71..8de59ec 100644 --- a/src/tests/limiter_neg.c +++ b/src/tests/limiter_neg.c @@ -18,56 +18,60 @@ int main(void) { - __log_limiter_destroy(); // check whether it explodes if called before init + __log_limiter_destroy(NULL); // check whether it explodes if called before init struct log_config conf = {NULL, NULL}; assert(!__log_limiter_create(&conf)); + /* TODO struct rule *r = NULL; char buffer[10]; assert(!__log_limiter_dump_rule(&r, buffer, sizeof buffer)); assert(r == NULL); + */ log_config_set(&conf, "limiter|*|*" , "allow"); log_config_set(&conf, "limiter|FOO|*", "deny"); log_config_set(&conf, "limiter|*|E" , "deny"); log_config_set(&conf, "limiter|FOO|E", "7"); - assert(__log_limiter_create(&conf)); + struct limiter_data *limiter_data = __log_limiter_create(&conf); + assert(limiter_data); fail_malloc = 1; - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); for (int i = 0; i < 100; ++i) { - assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_ALLOWED); } fail_malloc = 2; - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); for (int i = 0; i < 100; ++i) { - assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_ALLOWED); } fail_malloc = 0; - __log_limiter_destroy(); - assert(__log_limiter_create(&conf)); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); fail_time = true; - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED); fail_time = false; - int rule_count = get_rulecount(); + int rule_count = get_rulecount(limiter_data); log_config_set(&conf, "irrelevant", "entry"); - assert(rule_count == get_rulecount()); - __log_limiter_update(&conf); + assert(rule_count == get_rulecount(limiter_data)); + __log_limiter_update(limiter_data, &conf); for (int i = 1; i <= 2; ++i) { struct rule *r = NULL; char buf[128]; fail_snprintf = i; - assert(__log_limiter_dump_rule(&r, buf, sizeof buf) == -1); + assert(__log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf) == -1); } fail_snprintf = 0; diff --git a/src/tests/limiter_pos.c b/src/tests/limiter_pos.c index 9b616a2..a427c38 100644 --- a/src/tests/limiter_pos.c +++ b/src/tests/limiter_pos.c @@ -25,66 +25,68 @@ int main(void) log_config_set(&conf, "limiter|FOO|*", "deny"); log_config_set(&conf, "limiter|*|E" , "deny"); log_config_set(&conf, "limiter|FOO|E", "7"); - assert(__log_limiter_create(&conf)); - __log_limiter_update(&conf); + struct limiter_data *limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_update(limiter_data, &conf); for (int i = 0; i < 100; ++i) { - assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_DENIED); - assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_DENIED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'F').decision == DECISION_DENIED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'F').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "BAR", 'E').decision == DECISION_DENIED); } - __log_limiter_destroy(); - assert(__log_limiter_create(&conf)); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); for (int i = 0; i < 7; ++i) - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED); - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_TAG_LIMIT_EXCEEDED_MESSAGE); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_TAG_LIMIT_EXCEEDED_MESSAGE); for (int i = 0; i < 2; ++i) - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_DENIED); fail_time = false; - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_DENIED); future_time = true; - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED); future_time = false; - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED); - int rulecount = get_rulecount(); + int rulecount = get_rulecount(limiter_data); assert(rulecount == 4); - const struct limiter_limits limits = __log_limiter_get_limits("FOO", 'E'); + const struct limiter_limits limits = __log_limiter_get_limits(limiter_data, "FOO", 'E'); assert(limits.tag_and_prio == 7); assert(limits.tag == 0); assert(limits.prio == 0); assert(limits.global == __LOG_LIMITER_LIMIT_MAX + 1); - const struct limiter_limits lim_lowercase = __log_limiter_get_limits("FOO", 'e'); - const struct limiter_limits lim_enum = __log_limiter_get_limits("FOO", DLOG_ERROR); - const struct limiter_limits lim_numerical = __log_limiter_get_limits("FOO", '6'); + const struct limiter_limits lim_lowercase = __log_limiter_get_limits(limiter_data, "FOO", 'e'); + const struct limiter_limits lim_enum = __log_limiter_get_limits(limiter_data, "FOO", DLOG_ERROR); + const struct limiter_limits lim_numerical = __log_limiter_get_limits(limiter_data, "FOO", '6'); assert(!memcmp(&limits, &lim_lowercase, sizeof limits)); assert(!memcmp(&limits, &lim_enum , sizeof limits)); assert(!memcmp(&limits, &lim_numerical, sizeof limits)); log_config_set(&conf, "limiter|FOO|E", "12"); - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); - const struct limiter_limits limits_updated = __log_limiter_get_limits("FOO", 'E'); + const struct limiter_limits limits_updated = __log_limiter_get_limits(limiter_data, "FOO", 'E'); assert(limits_updated.tag_and_prio == 12); - assert(get_rulecount() == rulecount); + assert(get_rulecount(limiter_data) == rulecount); log_config_set(&conf, "limiter", "1"); log_config_set(&conf, "limiter||E", "2"); log_config_set(&conf, "limiter|QUUX|", "3"); log_config_set(&conf, "limiter|", "4"); log_config_set(&conf, "limiter||", "5"); - __log_limiter_update(&conf); - assert(get_rulecount() == rulecount); + __log_limiter_update(limiter_data, &conf); + assert(get_rulecount(limiter_data) == rulecount); log_config_set(&conf, "limiter|ABC|?", "13"); - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); - const struct limiter_limits lim_unknown = __log_limiter_get_limits("ABC", DLOG_UNKNOWN); + const struct limiter_limits lim_unknown = __log_limiter_get_limits(limiter_data, "ABC", DLOG_UNKNOWN); assert(lim_unknown.tag_and_prio == 13); // bulk tests to test hashing and buckets @@ -100,12 +102,12 @@ int main(void) S(BAC); S(ACB); #undef S - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); #define A(T) \ - assert(__log_limiter_get_limits(#T, 'D').tag_and_prio == 73); \ - assert(__log_limiter_get_limits(#T, 'E').tag_and_prio == 74); \ - assert(__log_limiter_get_limits(#T, 'F').tag_and_prio == 75) + assert(__log_limiter_get_limits(limiter_data, #T, 'D').tag_and_prio == 73); \ + assert(__log_limiter_get_limits(limiter_data, #T, 'E').tag_and_prio == 74); \ + assert(__log_limiter_get_limits(limiter_data, #T, 'F').tag_and_prio == 75) A(ABC); A(BCA); @@ -128,10 +130,12 @@ int main(void) .tag = "QWE", .limit = 0, }; - __log_limiter_destroy(); - __log_limiter_initialize(&r1); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_initialize(limiter_data, &r1); - assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED); + assert(__log_limiter_pass_log(limiter_data, "FOO", 'E').decision == DECISION_ALLOWED); /* Searching a hashmap kinda doesn't work if you * fake hashes (esp. identical ones) so this just @@ -151,8 +155,10 @@ int main(void) .limit = 0, }; - __log_limiter_destroy(); - __log_limiter_initialize(&r3); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_initialize(limiter_data, &r3); struct rule r5 = { .prev = &r4, @@ -168,8 +174,10 @@ int main(void) .limit = 0, }; - __log_limiter_destroy(); - __log_limiter_initialize(&r6); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_initialize(limiter_data, &r6); // empty tag never gets blocked struct rule block_all = { @@ -178,11 +186,13 @@ int main(void) .tag = "*", .limit = 0, }; - __log_limiter_destroy(); - __log_limiter_initialize(&block_all); - assert(__log_limiter_pass_log("tag", 'W').decision == DECISION_DENIED); - assert(__log_limiter_pass_log("", 'W').decision == DECISION_ALLOWED); + __log_limiter_destroy(limiter_data); + limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_initialize(limiter_data, &block_all); + assert(__log_limiter_pass_log(limiter_data, "tag", 'W').decision == DECISION_DENIED); + assert(__log_limiter_pass_log(limiter_data, "", 'W').decision == DECISION_ALLOWED); log_config_free(&conf); - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); } diff --git a/src/tests/limiter_wrap.c b/src/tests/limiter_wrap.c index 45f71b7..6dbd6ee 100644 --- a/src/tests/limiter_wrap.c +++ b/src/tests/limiter_wrap.c @@ -26,13 +26,13 @@ #include #include -static size_t get_rulecount(void) +static size_t get_rulecount(struct limiter_data *limiter_data) { size_t cnt = 0; struct rule *r = NULL; do { char buf[128]; - assert(!__log_limiter_dump_rule(&r, buf, sizeof buf)); + assert(!__log_limiter_dump_rule(limiter_data, &r, buf, sizeof buf)); ++cnt; } while (r); return cnt; diff --git a/src/tests/pid_limiter.c b/src/tests/pid_limiter.c index b258c65..9a96339 100644 --- a/src/tests/pid_limiter.c +++ b/src/tests/pid_limiter.c @@ -32,18 +32,19 @@ int main(void) log_config_set(&conf, "pidlimit|77", "7"); log_config_set(&conf, "pidlimit|88", "0"); log_config_set(&conf, "pidlimit|55", "125"); - assert(__log_limiter_create(&conf)); - __log_limiter_update(&conf); + struct limiter_data *limiter_data = __log_limiter_create(&conf); + assert(limiter_data); + __log_limiter_update(limiter_data, &conf); -#define PASS assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_ALLOWED) -#define MSG assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_PID_LIMIT_EXCEEDED_MESSAGE) -#define BLOCK assert(__log_limiter_pass_log("FOO", 'W').decision == DECISION_DENIED) +#define PASS assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_ALLOWED) +#define MSG assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_PID_LIMIT_EXCEEDED_MESSAGE) +#define BLOCK assert(__log_limiter_pass_log(limiter_data, "FOO", 'W').decision == DECISION_DENIED) pid_ret = 77; for (int i = 0; i < 7; ++i) PASS; for (int i = 7; i < 8; ++i) MSG; for (int i = 8; i < 100; ++i) BLOCK; - __log_limiter_update(&conf); // shouldn't have any effect + __log_limiter_update(limiter_data, &conf); // shouldn't have any effect for (int i = 100; i < 200; ++i) BLOCK; advance_clock(); @@ -63,7 +64,7 @@ int main(void) for (int i = 126; i < 333; ++i) BLOCK; log_config_remove(&conf, "pidlimit|55"); - __log_limiter_update(&conf); + __log_limiter_update(limiter_data, &conf); advance_clock(); for (int i = 0; i < 1936; ++i) PASS; @@ -76,5 +77,5 @@ int main(void) #undef BLOCK #undef PASS - __log_limiter_destroy(); + __log_limiter_destroy(limiter_data); }