From: Kevin Webb Date: Wed, 19 Nov 2008 04:52:10 +0000 (+0000) Subject: Added a handler for SIGUSR1, which toggles off/on the enforcement calls to tc. X-Git-Tag: DistributedRateLimiting-0.1-0~45 X-Git-Url: http://git.onelab.eu/?p=distributedratelimiting.git;a=commitdiff_plain;h=a3ef11b996352e66f4031c684c7dcda536bc3bf1 Added a handler for SIGUSR1, which toggles off/on the enforcement calls to tc. Added several more statistics variables to the common accounting type. Print the stats to the log regularly to make sure that everything is working. --- diff --git a/drl/common_accounting.h b/drl/common_accounting.h index d656d8a..0fbcdbe 100644 --- a/drl/common_accounting.h +++ b/drl/common_accounting.h @@ -74,6 +74,26 @@ typedef struct { /** The number of bytes sent since the last_update time. */ uint32_t bytes_since; + /* Statistics below. */ + + /** The current number of flows. */ + uint32_t num_flows; + + /** The number of flows sending above 5KB/s. */ + uint32_t num_flows_5k; + + /** The number of flows sending above 10KB/s. */ + uint32_t num_flows_10k; + + /** The number of flows sending above 20KB/s. */ + uint32_t num_flows_20k; + + /** The number of flows sending above 50KB/s. */ + uint32_t num_flows_50k; + + /** The average flow rate. */ + uint32_t avg_rate; + } common_accounting_t; /** Determines the difference between two timeval structs (in seconds, with diff --git a/drl/drl_state.c b/drl/drl_state.c index eba79ba..fed3326 100644 --- a/drl/drl_state.c +++ b/drl/drl_state.c @@ -214,6 +214,7 @@ void *limiter_receive_thread(void *unused) { sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGHUP); + sigaddset(&signal_mask, SIGUSR1); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); diff --git a/drl/estimate.c b/drl/estimate.c index 17a0fd8..29704be 100644 --- a/drl/estimate.c +++ b/drl/estimate.c @@ -18,8 +18,12 @@ #include "ratetypes.h" /* needs util and pthread.h */ #include "logging.h" +#define PRINT_COUNTER_RESET (7) + extern uint8_t system_loglevel; -static int printcounter = 8; +static int printcounter = PRINT_COUNTER_RESET - 1; + +uint8_t do_enforcement = 0; /** * Called for each identity each estimate interval. Uses flow table information @@ -233,8 +237,10 @@ static uint32_t allocate_fps(identity_t *ident, double total_weight) { } if (printcounter <= 0) { - printlog(LOG_WARN, "%d %.1f %.1f %.1f\n", local_rate, idealweight, ident->localweight, total_weight); - printcounter = 8; + printlog(LOG_WARN, "%d %.1f %.1f %.1f %d %d %d %d %d %d ", local_rate, idealweight, + ident->localweight, total_weight, ftable->num_flows, ftable->num_flows_5k, ftable->num_flows_10k, + ftable->num_flows_20k, ftable->num_flows_50k, ftable->avg_rate); + printcounter = PRINT_COUNTER_RESET; } else { printcounter -= 1; } @@ -370,16 +376,22 @@ static void enforce(limiter_t *limiter, identity_t *ident) { printf("FPS: Setting local limit to %d\n", ident->locallimit); } printlog(LOG_DEBUG, "%d Limit ID:%d\n", ident->locallimit, ident->id); - printlog(LOG_WARN, "%d\n", ident->locallimit); + + if (printcounter == PRINT_COUNTER_RESET) { + printlog(LOG_WARN, "%d\n", ident->locallimit); + } snprintf(cmd, CMD_BUFFER_SIZE, "/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil %dbps quantum 1600", ident->htb_parent, ident->htb_node, ident->locallimit); - ret = system(cmd); + if (do_enforcement) { + ret = system(cmd); - if (ret) { - /* FIXME: call failed. What to do? */ + if (ret) { + /* FIXME: call failed. What to do? */ + printlog(LOG_CRITICAL, "***TC call failed?***\n"); + } } break; @@ -423,10 +435,13 @@ static void enforce(limiter_t *limiter, identity_t *ident) { ident->leaves[i]->xid, ident->leaves[i]->xid, (100 * ident->leaves[i]->drop_prob)); #endif - ret = system(cmd); + if (do_enforcement) { + ret = system(cmd); - if (ret) { - /* FIXME: call failed. What to do? */ + if (ret) { + /* FIXME: call failed. What to do? */ + printlog(LOG_CRITICAL, "***TC call failed?***\n"); + } } } @@ -496,6 +511,7 @@ void handle_estimation(void *arg) { sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGHUP); + sigaddset(&signal_mask, SIGUSR1); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); /* Determine the number of intervals we should wait before hitting the diff --git a/drl/standard.c b/drl/standard.c index 93cb663..ba1fcc7 100644 --- a/drl/standard.c +++ b/drl/standard.c @@ -244,6 +244,15 @@ void standard_table_update_flows(standard_flow_table table, struct timeval now, struct in_addr src, dst; char sip[22], dip[22]; + /* Reset statistics. */ + table->common->num_flows = 0; + table->common->num_flows_5k = 0; + table->common->num_flows_10k = 0; + table->common->num_flows_20k = 0; + table->common->num_flows_50k = 0; + table->common->avg_rate = 0; + /* End statistics. */ + time_delta = timeval_subtract(now, table->common->last_update); if (time_delta <= 0) { @@ -295,6 +304,28 @@ void standard_table_update_flows(standard_flow_table table, struct timeval now, maxflowrate = current->rate; } + if (current->rate > 51200) { + table->common->num_flows_50k += 1; + table->common->num_flows_20k += 1; + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + table->common->num_flows += 1; + } else if (current->rate > 20480) { + table->common->num_flows_20k += 1; + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + table->common->num_flows += 1; + } else if (current->rate > 10240) { + table->common->num_flows_10k += 1; + table->common->num_flows_5k += 1; + table->common->num_flows += 1; + } else if (current->rate > 5120) { + table->common->num_flows_5k += 1; + table->common->num_flows += 1; + } else { + table->common->num_flows += 1; + } + src.s_addr = ntohl(current->source_ip); dst.s_addr = ntohl(current->dest_ip); strcpy(sip, inet_ntoa(src)); @@ -305,6 +336,10 @@ void standard_table_update_flows(standard_flow_table table, struct timeval now, current->rate); } + if (table->common->num_flows > 0) { + table->common->avg_rate = table->common->rate / table->common->num_flows; + } + printlog(LOG_DEBUG, "FLOW:--\n--\n"); table->common->max_flow_rate = maxflowrate; diff --git a/drl/ulogd_DRL.c b/drl/ulogd_DRL.c index ef5cf20..b87b96e 100644 --- a/drl/ulogd_DRL.c +++ b/drl/ulogd_DRL.c @@ -229,6 +229,7 @@ uint32_t local_ip = 0; limiter_t limiter; extern FILE *logfile; extern uint8_t system_loglevel; +extern uint8_t do_enforcement; /* functions */ @@ -1468,6 +1469,33 @@ static void time_reconfig(int iterations) { // Seems to take about 85ms / iteration } +static int stop_enforcement(drl_instance_t *instance) { + char cmd[300]; + int i; + + for (i = 0; i < instance->machine_count; ++i) { + sprintf(cmd, "/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil 100mbit", + instance->machines[i]->htb_parent, + instance->machines[i]->htb_node); + + if (execute_cmd(cmd)) { + return 1; + } + } + + for (i = 0; i < instance->set_count; ++i) { + sprintf(cmd, "/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil 100mbit", + instance->sets[i]->htb_parent, + instance->sets[i]->htb_node); + + if (execute_cmd(cmd)) { + return 1; + } + } + + return 0; +} + static void *signal_thread_func(void *args) { int sig; int err; @@ -1475,11 +1503,13 @@ static void *signal_thread_func(void *args) { sigemptyset(&sigs); sigaddset(&sigs, SIGHUP); + sigaddset(&sigs, SIGUSR1); pthread_sigmask(SIG_BLOCK, &sigs, NULL); while (1) { sigemptyset(&sigs); sigaddset(&sigs, SIGHUP); + sigaddset(&sigs, SIGUSR1); err = sigwait(&sigs, &sig); @@ -1492,11 +1522,23 @@ static void *signal_thread_func(void *args) { case SIGHUP: printlog(LOG_WARN, "Caught SIGHUP - re-reading XML file.\n"); reconfig(); - //time_reconfig(1000); //instrumentation + //time_reconfig(1000); /* instrumentation */ flushlog(); break; + case SIGUSR1: + pthread_rwlock_wrlock(&limiter.limiter_lock); + if (do_enforcement) { + do_enforcement = 0; + stop_enforcement(&limiter.stable_instance); + printlog(LOG_CRITICAL, "--Switching enforcement off.--\n"); + } else { + do_enforcement = 1; + printlog(LOG_CRITICAL, "--Switching enforcement on.--\n"); + } + pthread_rwlock_unlock(&limiter.limiter_lock); + break; default: - /* Should be impossible... */ + /* Intentionally blank. */ break; } } @@ -1511,6 +1553,7 @@ static void _drl_reg_op(void) sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGHUP); + sigaddset(&signal_mask, SIGUSR1); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); if (pthread_create(&signal_thread, NULL, &signal_thread_func, NULL) != 0) {