diff --git a/Makefile b/Makefile index a359c00..e2b890b 100644 --- a/Makefile +++ b/Makefile @@ -35,13 +35,16 @@ INSTALLPATH = $(installprefix) .PHONY: all clean -all: srcdir docdir +all: srcdir docdir testdir srcdir: cd src; make docdir: cd docs; make man +testdir: srcdir + cd test; make + test: FORCE cd test; make test @@ -55,7 +58,7 @@ pkg: all FORCE: -clean: srcclean docclean +clean: srcclean docclean testclean distclean: clean distclean_src @@ -65,6 +68,8 @@ docclean: cd docs; make clean distclean_src: cd src; make distclean +testclean: + cd test; make clean install: srcinstall includeinstall docinstall diff --git a/README.md b/README.md index a94d87c..6a95445 100644 --- a/README.md +++ b/README.md @@ -93,14 +93,33 @@ The key components are from BPF programs to userspace via the shared ring buffer. Each tuner has an associated set of tunables that it manages. +- optional strategies: a tuner can specify multiple strategies; + after running for a while a strategy times out and we assess + if a better strategy is available. Each strategy specifies a + - name + - description + - timeout + - evaluation function + - set of BPF program names in tuner associated with strategy + + Strategies are optional and should be set in the tuner init() + method via bpftune_strategies_add(). See test/strategy + for a coded example. When a strategy times out, the various + evaluation functions are called and the highest-value evaluation + dictates the next stratgey. + + Strategies provide a way of providing multiple schemes for + auto-tuning the same set of tunables, where the choice is + guided by an evaluation of the effectiveness of the strategies. + - events specify a - tuner id: which tuner the event is destined for - a scenario: what happened - an associated netns (if supported) - information about the event (IP address etc) -- the tuner then responds to the event with a strategy; increase - or decrease a tunable value, etc. Describing the event +- the tuner then responds to the event guided by the active strategy; + increase or decrease a tunable value, etc. Describing the event in the log is key; this allows an admin to understand what changed and why. @@ -180,6 +199,12 @@ To build the following packages are needed (names may vary by distro); - llvm >= 11 - python3-docutils +From the kernel side, the kernel needs to support BPF ring buffer +(around the 5.6 kernel, though 5.4 is supported on Oracle Linux +as ring buffer support was backported), and kernel BTF is +required (CONFIG_DEBUG_INFO_BTF=y). Verify /sys/kernel/btf/vmlinux +is present. + To enable bpftune as a service ``` diff --git a/include/bpftune/bpftune.h b/include/bpftune/bpftune.h index 652b7f5..790b61a 100644 --- a/include/bpftune/bpftune.h +++ b/include/bpftune/bpftune.h @@ -138,6 +138,18 @@ struct bpftuner_netns { enum bpftune_state state; }; +struct bpftuner; + +struct bpftuner_strategy { + const char *name; + const char *description; + /* return a number to compare with other strategies */ + int (*evaluate)(struct bpftuner *tuner, struct bpftuner_strategy *strategy); + unsigned long timeout; /* time in seconds until evaluation */ + const char **bpf_progs; /* programs to load in BPF skeleton for this + * strategy; if NULL, all */ +}; + struct bpftuner { unsigned int id; enum bpftune_state state; @@ -151,6 +163,8 @@ struct bpftuner { void *obj; int (*init)(struct bpftuner *tuner); void (*fini)(struct bpftuner *tuner); + struct bpftuner_strategy **strategies; + struct bpftuner_strategy *strategy; void *ring_buffer_map; int ring_buffer_map_fd; void *corr_map; diff --git a/include/bpftune/libbpftune.h b/include/bpftune/libbpftune.h index 6273234..b1ec543 100644 --- a/include/bpftune/libbpftune.h +++ b/include/bpftune/libbpftune.h @@ -111,6 +111,9 @@ static inline const char *bpftuner_tunable_name(struct bpftuner *tuner, #define bpftuner_for_each_tunable(tuner, tunable) \ for (unsigned int __itun = 0; (tunable = bpftuner_tunable(tuner, __itun)); __itun++) +#define bpftuner_for_each_strategy(tuner, strategy) \ + for (unsigned int __s = 0; (strategy = tuner->strategies[__s]); __s++) + int bpftuner_tunable_sysctl_write(struct bpftuner *tuner, unsigned int tunable, unsigned int scenario, @@ -168,6 +171,7 @@ void bpftuner_tunables_fini(struct bpftuner *tuner); tuner->ring_buffer_map = __lskel->maps.ring_buffer_map;\ tuner->netns_map = __lskel->maps.netns_map; \ } \ + bpftuner_bpf_set_autoload(tuner); \ } while (0); \ bpftune_cap_drop(); \ if (__err) { \ @@ -291,4 +295,10 @@ int bpftuner_netns_fd_from_cookie(struct bpftuner *tuner, unsigned long cookie); int bpftune_module_load(const char *name); int bpftune_module_unload(const char *name); +int bpftuner_strategy_set(struct bpftuner *tuner, struct bpftuner_strategy *strategy); +int bpftuner_strategies_add(struct bpftuner *tuner, struct bpftuner_strategy **strategies, + struct bpftuner_strategy *default_strategy); +bool bpftuner_bpf_prog_in_strategy(struct bpftuner *tuner, const char *prog); +void bpftuner_bpf_set_autoload(struct bpftuner *tuner); + #endif /* __LIBBPFTUNE_H */ diff --git a/src/Makefile b/src/Makefile index 334d920..9a583f4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -59,7 +59,7 @@ CFLAGS = -fPIC -Wall -Wextra -march=native -g -I../include -std=c99 CFLAGS += -DBPFTUNE_VERSION='"$(BPFTUNE_VERSION)"' $(INCLUDES) -LDLIBS = -lbpf -ldl -lm -lcap -lnl-3 -lpthread -lnl-route-3 +LDLIBS = -lbpf -ldl -lm -lrt -lcap -lnl-3 -lpthread -lnl-route-3 LDFLAGS += -L. -L/usr/local/lib64 diff --git a/src/libbpftune.c b/src/libbpftune.c index ebd9244..8719437 100644 --- a/src/libbpftune.c +++ b/src/libbpftune.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include unsigned short bpftune_learning_rate; @@ -325,6 +327,10 @@ int bpftuner_cgroup_attach(struct bpftuner *tuner, const char *prog_name, struct bpf_program *prog; const char *cgroup_dir; + /* if cgroup prog is not in current strategy prog list, skip attach */ + if (!bpftuner_bpf_prog_in_strategy(tuner, prog_name)) + return 0; + err = bpftune_cap_add(); if (err) return err; @@ -364,6 +370,10 @@ void bpftuner_cgroup_detach(struct bpftuner *tuner, const char *prog_name, int prog_fd, cgroup_fd, err = 0; struct bpf_program *prog; + /* if cgroup prog is not in current strategy prog list, skip attach */ + if (!bpftuner_bpf_prog_in_strategy(tuner, prog_name)) + return; + err = bpftune_cap_add(); if (err) return; @@ -617,6 +627,7 @@ struct bpftuner *bpftuner_init(const char *path) bpftune_log(LOG_ERR, "could not allocate tuner\n"); return NULL; } + tuner->name = path; bpftune_cap_add(); /* if file appears via inotify we may get "file too short" errors; @@ -1503,3 +1514,130 @@ int bpftune_module_unload(const char *name) bpftune_cap_drop(); return ret; } + +static void bpftuner_strategy_update(struct bpftuner *tuner) +{ + struct bpftuner_strategy *strategy, *max_strategy = NULL; + int curr, max = 0; + + if (!tuner->strategies) + return; + + bpftune_log(LOG_DEBUG, "%s: updating strategy...\n", tuner->name); + + bpftuner_for_each_strategy(tuner, strategy) { + curr = strategy->evaluate(tuner, strategy); + if (curr < max) + continue; + max = curr; + max_strategy = strategy; + } + if (max_strategy && max_strategy != tuner->strategy) + bpftuner_strategy_set(tuner, max_strategy); +} + +static void bpftuner_strategy_timeout(sigval_t sigval) +{ + struct bpftuner *tuner = sigval.sival_ptr; + + if (tuner) + bpftuner_strategy_update(tuner); +} + +int bpftuner_strategy_set(struct bpftuner *tuner, + struct bpftuner_strategy *strategy) +{ + bpftune_log(LOG_DEBUG, "setting stragegy for tuner '%s' to '%s': %s\n", + tuner->name, strategy->name, strategy->description); + int err = 0; + + if (!strategy) + return 0; + + if (tuner->strategy) { + /* clean up for current strategy */ + bpftune_log(LOG_DEBUG, "%s: cleaning up current strategy '%s'\n", + tuner->name, strategy->name); + tuner->fini(tuner); + } + /* arm timer for timeout */ + if (strategy->timeout) { + struct sigevent sev = {}; + struct itimerspec its = {}; + timer_t tid; + + sev.sigev_notify = SIGEV_THREAD; + sev.sigev_notify_function = &bpftuner_strategy_timeout; + sev.sigev_value.sival_ptr = tuner; + + if (timer_create(CLOCK_REALTIME, &sev, &tid) + == -1) { + err = -errno; + bpftune_log(LOG_DEBUG, "%s: could not arm timer for strategy '%s'\n", + strerror(-err)); + return 0; + } + its.it_value.tv_sec = strategy->timeout; + if (timer_settime(tid, 0, &its, NULL)) { + err = -errno; + bpftune_log(LOG_DEBUG, "%s: could not arm timer for strategy '%s: %s'\n", + tuner->name, strategy->name, strerror(-err)); + return 0; + } + } + if (!err) { + tuner->strategy = strategy; + err = tuner->init(tuner); + } + return err; +} + +int bpftuner_strategies_add(struct bpftuner *tuner, struct bpftuner_strategy **strategies, + struct bpftuner_strategy *default_strategy) +{ + if (!strategies || tuner->strategies) + return 0; + tuner->strategies = strategies; + if (default_strategy) + return bpftuner_strategy_set(tuner, default_strategy); + bpftuner_strategy_update(tuner); + return 0; +} + +bool bpftuner_bpf_prog_in_strategy(struct bpftuner *tuner, const char *prog) +{ + const char **progs; + int i; + + if (!tuner->strategy || !tuner->strategy->bpf_progs) + return true; + progs = tuner->strategy->bpf_progs; + + for (i = 0; progs[i] != NULL; i++) { + if (strcmp(prog, progs[i]) == 0) + return true; + } + return false; +} + +void bpftuner_bpf_set_autoload(struct bpftuner *tuner) +{ + struct bpf_program *prog = NULL; + int err; + + if (!tuner->strategy || !tuner->strategy->bpf_progs) + return; + + bpf_object__for_each_program(prog, tuner->obj) { + const char *name = bpf_program__name(prog); + + if (bpftuner_bpf_prog_in_strategy(tuner, name)) + continue; + err = bpf_program__set_autoload(prog, false); + if (err) { + bpftune_log(LOG_ERR, "%s: could not disable autoload for prog '%s' for strategy '%s': %s\n", + tuner->name, name, + tuner->strategy->name, strerror(err)); + } + } +} diff --git a/src/libbpftune.map b/src/libbpftune.map index 26077d2..ef245f9 100644 --- a/src/libbpftune.map +++ b/src/libbpftune.map @@ -32,6 +32,8 @@ LIBBPFTUNE_0.1.1 { bpftuner_tunable_update; bpftuner_fini; bpftuner_bpf_fini; + bpftuner_bpf_set_autoload; + bpftuner_bpf_prog_in_strategy; bpftuner_tunables_fini; bpftune_netns_cookie_supported; bpftuner_netns_init; @@ -39,6 +41,8 @@ LIBBPFTUNE_0.1.1 { bpftuner_netns_from_cookie; bpftuner_netns_fd_from_cookie; bpftuner_ring_buffer_map_fd; + bpftuner_strategy_set; + bpftuner_strategies_add; bpftune_ring_buffer_init; bpftune_ring_buffer_poll; bpftune_ring_buffer_fini; diff --git a/test/Makefile b/test/Makefile index 656def5..2c85b4f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,10 +17,12 @@ # Boston, MA 021110-1307, USA. # + PERF_TESTS = iperf3_test qperf_test TUNER_TESTS = support_test log_test service_test inotify_test cap_test \ sample_test sample_legacy_test \ + strategy_test strategy_legacy_test \ sysctl_test sysctl_legacy_test sysctl_netns_test \ netns_test netns_legacy_test \ backlog_test backlog_legacy_test \ @@ -53,14 +55,20 @@ INSTALLPATH = $(installprefix)/lib/tcptune_test/ install_sh_PROGRAM = install install_sh_DIR = install -dv -all: $(PROGS) +all: strategydir $(PROGS) +strategydir: + cd strategy; make + PHONY: clean -clean: +clean: strategyclean rm -f $(PROGS) -test: $(TESTS) +strategyclean: + cd strategy; make clean + +test: all $(TESTS) test_perf: $(PERF_TESTS) diff --git a/test/strategy/Makefile b/test/strategy/Makefile new file mode 100644 index 0000000..6abf034 --- /dev/null +++ b/test/strategy/Makefile @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +# +# Copyright (c) 2023, Oracle and/or its affiliates. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License v2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 021110-1307, USA. +# + +SRCARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \ + -e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/aarch64.*/arm64/ ) + +CLANG ?= clang +LLC ?= llc +LLVM_STRIP ?= llvm-strip +BPFTOOL ?= bpftool +BPF_INCLUDE := ../../include +NL_INCLUDE := /usr/include/libnl3 +INCLUDES := -I$(BPF_INCLUDE) -I$(NL_INCLUDE) -I/usr/include/uapi + +INSTALL ?= install + +DESTDIR ?= +prefix ?= /usr +installprefix = $(DESTDIR)/$(prefix) + +INSTALLPATH = $(installprefix) + +CFLAGS = -fPIC -Wall -Wextra -march=native -g -I../include -std=c99 + +CFLAGS += -DBPFTUNE_VERSION='"$(BPFTUNE_VERSION)"' $(INCLUDES) + +LDLIBS = -lbpf -ldl -lm -lcap -lpthread + +LDFLAGS += -L../../src -L/usr/local/lib64 + +ifeq ($(V),1) +Q = +else +Q = @ +MAKEFLAGS += --no-print-directory +submake_extras := feature_display=0 +endif + +TUNERS = strategy_tuner + +TUNER_OBJS = $(patsubst %,%.o,$(TUNERS)) +TUNER_LIBS = $(patsubst %,%.so,$(TUNERS)) + +BPF_TUNERS = $(patsubst %,%.bpf.o,$(TUNERS)) + +BPF_OBJS = $(BPF_TUNERS) + +BPF_SKELS = $(patsubst %,%.skel.h,$(TUNERS)) + +.DELETE_ON_ERROR: + +.PHONY: clean + +all: $(TUNER_LIBS) + +clean: + $(Q)$(RM) *.o *.d *.so* + $(Q)$(RM) *.skel*.h + $(Q)$(RM) -r .output + +$(TUNER_LIBS): $(BPF_SKELS) $(TUNER_OBJS) + $(CC) $(CFLAGS) -shared -o $(@) $(patsubst %.so,%.c,$(@)) \ + $(LDLIBS) -lbpftune $(LDFLAGS) + +%.skel.h: %.bpf.o + $(QUIET_GEN)$(BPFTOOL) gen skeleton $< > $@ + +$(BPF_OBJS): $(patsubst %.o,%.c,$(BPF_OBJS)) + $(CLANG) -g -D__TARGET_ARCH_$(SRCARCH) -O2 -target bpf \ + $(INCLUDES) -c $(patsubst %.o,%.c,$(@)) -o $(@); + $(CLANG) -g -D__TARGET_ARCH_$(SRCARCH) -DBPFTUNE_LEGACY -O2 -target bpf \ + $(INCLUDES) -c $(patsubst %.o,%.c,$(@)) \ + -o $(patsubst %.o,%.legacy.o,$(@)) + +$(BPF_SKELS): $(BPF_OBJS) + $(BPFTOOL) gen skeleton $(subst .skel.h,.bpf.o,$@) > $@ ;\ + $(BPFTOOL) gen skeleton $(subst .skel.h,.bpf.legacy.o,$@) > $(subst .skel.h,.skel.legacy.h,$@) + diff --git a/test/strategy/README.md b/test/strategy/README.md new file mode 100644 index 0000000..1bd36f2 --- /dev/null +++ b/test/strategy/README.md @@ -0,0 +1,5 @@ +# strategy tuner + +simple example showing Makefile and bpf/userspace portions of a +tuner shared object that implements multiple strategies, switching +between them. diff --git a/test/strategy/strategy_tuner.bpf.c b/test/strategy/strategy_tuner.bpf.c new file mode 100644 index 0000000..91bb25a --- /dev/null +++ b/test/strategy/strategy_tuner.bpf.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include + +/* fire when coredump sysctls are read */ +/* strategy A uses this BPF prog. */ +BPF_FENTRY(proc_dostring_coredump, struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + struct bpftune_event event = {}; + int ret, scenario_id = 0; + + /* tuner id is a global declared in bpftune.bpf.h and set by bfttune + * when the tuner is added. + */ + event.tuner_id = tuner_id; + event.scenario_id = scenario_id; + ret = bpf_ringbuf_output(&ring_buffer_map, &event, sizeof(event), 0); + bpftune_debug("tuner [%d] scenario [%d]: event send: %d ", + tuner_id, scenario_id, ret); + return 0; +} + +/* strategy B uses this BPF prog. */ +BPF_FENTRY(proc_dostring, struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + struct bpftune_event event = {}; + int ret, scenario_id = 0; + + /* tuner id is a global declared in bpftune.bpf.h and set by bfttune + * when the tuner is added. + */ + event.tuner_id = tuner_id; + event.scenario_id = scenario_id; + ret = bpf_ringbuf_output(&ring_buffer_map, &event, sizeof(event), 0); + bpftune_debug("tuner [%d] scenario [%d]: event send: %d ", + tuner_id, scenario_id, ret); + return 0; +} + diff --git a/test/strategy/strategy_tuner.c b/test/strategy/strategy_tuner.c new file mode 100644 index 0000000..75610cb --- /dev/null +++ b/test/strategy/strategy_tuner.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include "strategy_tuner.skel.h" +#include "strategy_tuner.skel.legacy.h" + +static int evaluate_A(struct bpftuner *tuner, struct bpftuner_strategy *strategy) +{ + if (tuner->strategy == strategy) + return 0; + else + return 1; +} + +const char *progs_A[] = { "entry__proc_dostring_coredump", NULL }; + +struct bpftuner_strategy strategy_A = { + .name = "strategy_A", + .description = "first strategy", + .evaluate = evaluate_A, + .timeout = 30, + .bpf_progs = progs_A, +}; + +static int evaluate_B(struct bpftuner *tuner, struct bpftuner_strategy *strategy) +{ + if (tuner->strategy == strategy) + return 0; + else + return 1; +} + +const char *progs_B[] = { "entry__proc_dostring", NULL }; + +struct bpftuner_strategy strategy_B = { + .name = "strategy_B", + .description = "second strategy", + .evaluate = evaluate_B, + .timeout = 30, + .bpf_progs = progs_B, +}; + +struct bpftuner_strategy *strategies[] = { &strategy_A, &strategy_B, NULL }; + +int init(struct bpftuner *tuner) +{ + int err = bpftuner_strategies_add(tuner, strategies, &strategy_A); + + if (err) + return err; + return bpftuner_bpf_init(strategy, tuner, NULL); +} + +void fini(struct bpftuner *tuner) +{ + bpftuner_bpf_fini(tuner); +} + +void event_handler(struct bpftuner *tuner, struct bpftune_event *event, + __attribute__((unused))void *ctx) +{ + bpftune_log(LOG_DEBUG, "event (scenario %d) for tuner %s, strategy %s\n", + event->scenario_id, tuner->name, tuner->strategy->name); +} diff --git a/test/strategy_legacy_test.sh b/test/strategy_legacy_test.sh new file mode 100644 index 0000000..8360001 --- /dev/null +++ b/test/strategy_legacy_test.sh @@ -0,0 +1,48 @@ +#!/usr/bin/bash +# +# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +# +# Copyright (c) 2023, Oracle and/or its affiliates. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License v2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 021110-1307, USA. +# + +# run sysctl test + +. ./test_lib.sh + + +SLEEPTIME=10 + + +test_start "$0|strategy legacy test: does strategy tuner appear, trigger event and change strategies?" + +test_setup "true" + +sleep 1 +test_run_cmd_local "$BPFTUNE -dsLl ./strategy &" true +sleep $SETUPTIME +# trigger event +sysctl kernel.core_pattern +sleep $SLEEPTIME +grep -E "event .* for tuner strategy, strategy strategy_A" $TESTLOG_LAST +sleep 30 +# trigger event +sysctl kernel.core_pattern +sleep $SLEEPTIME +grep -E "event .* for tuner strategy, strategy strategy_B" $TESTLOG_LAST +test_pass +test_cleanup +test_exit diff --git a/test/strategy_test.sh b/test/strategy_test.sh new file mode 100644 index 0000000..ccbe0a2 --- /dev/null +++ b/test/strategy_test.sh @@ -0,0 +1,48 @@ +#!/usr/bin/bash +# +# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +# +# Copyright (c) 2023, Oracle and/or its affiliates. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License v2 as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 021110-1307, USA. +# + +# run sysctl test + +. ./test_lib.sh + + +SLEEPTIME=10 + + +test_start "$0|strategy test: does strategy tuner appear, trigger event and change strategies?" + +test_setup "true" + +sleep 1 +test_run_cmd_local "$BPFTUNE -dsl ./strategy &" true +sleep $SETUPTIME +# trigger event +sysctl kernel.core_pattern +sleep $SLEEPTIME +grep -E "event .* for tuner strategy, strategy strategy_A" $TESTLOG_LAST +sleep 30 +# trigger event +sysctl kernel.core_pattern +sleep $SLEEPTIME +grep -E "event .* for tuner strategy, strategy strategy_B" $TESTLOG_LAST +test_pass +test_cleanup +test_exit