Skip to content

Commit 0a2142a

Browse files
committed
libbpftune: add support for json queries of tunables, state
this will be hepful in adding PCP support as JSON format is easier to parse. Two new queries are added: jtunables show list of tunables(json) jstatus show status of tunables(json) Signed-off-by: Alan Maguire <[email protected]>
1 parent 9192e70 commit 0a2142a

File tree

6 files changed

+172
-15
lines changed

6 files changed

+172
-15
lines changed

docs/bpftune.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,8 @@ OPTIONS
101101
summary - show summary of changes made by tuners
102102
tuners - show loaded tuners and their state
103103
tunables - show supported tunables for loaded tuners
104+
jtunables - show supported tunables in json format
105+
status - show current status of tunables
106+
jstatus - show current status of tunables in json format
107+
rollback - show changes needed to roll back changes made
108+
by bpftune

src/libbpftune.c

Lines changed: 151 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,24 @@ void bpftune_log_syslog(__attribute__((unused)) void *ctx, int level,
102102
syslog(level, buf, buflen + 1);
103103
}
104104

105-
/* log to ctx buffer as well as usual log destination */
105+
/* log to ctx buffer for specific thread, fall back to usual log destination */
106106
void bpftune_log_buf(void *ctx, int level, const char *fmt, va_list args)
107107
{
108108
struct bpftune_log_ctx_buf *c = ctx;
109109
va_list nextargs;
110+
pthread_t self;
110111

111112
if (!c || level > bpftune_loglevel)
112113
return;
113114
va_copy(nextargs, args);
114-
if (c->buf_thread == pthread_self() && c->buf_off <= c->buf_sz) {
115+
self = pthread_self();
116+
if (c->buf_thread == self && c->buf_off <= c->buf_sz) {
115117
c->buf_off += vsnprintf(c->buf + c->buf_off,
116118
c->buf_sz - c->buf_off, fmt, args);
119+
} else {
120+
if (c->buf_thread != self && c->nextlogfn)
121+
c->nextlogfn(ctx, level, fmt, nextargs);
117122
}
118-
c->nextlogfn(ctx, level, fmt, nextargs);
119123
va_end(nextargs);
120124
}
121125

@@ -2099,15 +2103,21 @@ struct bpftune_req {
20992103
static void bpftune_help_handler(const char *req, char *buf, size_t buf_sz);
21002104
static void bpftune_tuners_handler(const char *req, char *buf, size_t buf_sz);
21012105
static void bpftune_tunables_handler(const char *req, char *buf, size_t buf_sz);
2106+
static void bpftune_jtunables_handler(const char *req, char *buf, size_t buf_sz);
21022107
static void bpftune_summary_handler(const char *req, char *buf, size_t buf_sz);
2108+
static void bpftune_status_handler(const char *req, char *buf, size_t buf_sz);
2109+
static void bpftune_jstatus_handler(const char *req, char *buf, size_t buf_sz);
21032110
static void bpftune_rollback_handler(const char *req, char *buf, size_t buf_sz);
21042111

21052112
/* add bpftune server requests with handlers here */
21062113
struct bpftune_req bpftune_reqs[] = {
21072114
{ "help", "list supported queries", bpftune_help_handler },
21082115
{ "tuners", "show state of tuners", bpftune_tuners_handler },
21092116
{ "tunables", "show list of tunables", bpftune_tunables_handler },
2117+
{ "jtunables", "show list of tunables(json)", bpftune_jtunables_handler },
21102118
{ "summary", "show summary of changes", bpftune_summary_handler },
2119+
{ "status", "show status of tunables", bpftune_status_handler },
2120+
{ "jstatus", "show status of tunables(json)",bpftune_jstatus_handler },
21112121
{ "rollback", "show changes needed to roll back",
21122122
bpftune_rollback_handler }
21132123
};
@@ -2136,22 +2146,76 @@ static void bpftune_tuners_handler(__attribute__((unused)) const char *req,
21362146
}
21372147
}
21382148

2139-
static void bpftune_tunables_handler(__attribute__((unused)) const char *req,
2140-
char *buf, size_t buf_sz)
2149+
static void __bpftune_tunables_handler(__attribute__((unused)) const char *req,
2150+
char *buf, size_t buf_sz, bool json)
21412151
{
2152+
struct bpftune_log_ctx_buf ctx_buf;
21422153
struct bpftuner *t;
2143-
int off = 0;
2154+
bool first = true;
2155+
2156+
ctx_buf.nextlogfn = bpftune_logfn;
2157+
ctx_buf.buf = buf;
2158+
ctx_buf.buf_off = 0;
2159+
ctx_buf.buf_sz = buf_sz;
2160+
ctx_buf.buf_thread = pthread_self();
2161+
2162+
bpftune_set_log(bpftune_loglevel, bpftune_log_buf, &ctx_buf);
2163+
2164+
if (json)
2165+
bpftune_log(BPFTUNE_LOG_LEVEL, "{\n");
21442166

21452167
bpftune_for_each_tuner(t) {
21462168
struct bpftunable *u;
21472169
unsigned int i;
21482170

2171+
if (json) {
2172+
if (!first)
2173+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t},\n");
2174+
first = false;
2175+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\"%s\":{\n",
2176+
t->name);
2177+
}
21492178
for (i = 0; i < t->num_tunables; i++) {
21502179
u = bpftuner_tunable(t, i);
2151-
off += snprintf(buf + off, buf_sz - off, "%20s %50s\n",
2152-
t->name, u->desc.name);
2180+
if (json) {
2181+
if (i > 0)
2182+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\t},\n");
2183+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\t\"%s\":{\n",
2184+
u->desc.name);
2185+
bpftune_log(BPFTUNE_LOG_LEVEL,
2186+
"\t\t\t\"type\":\"%s\",\n",
2187+
u->desc.flags & BPFTUNABLE_STRING ?
2188+
"string" : "integer");
2189+
bpftune_log(BPFTUNE_LOG_LEVEL,
2190+
"\t\t\t\"num_values\":%d\n",
2191+
u->desc.num_values);
2192+
} else {
2193+
bpftune_log(BPFTUNE_LOG_LEVEL,
2194+
"%16s %50s %8s %2d\n",
2195+
t->name, u->desc.name,
2196+
u->desc.flags & BPFTUNABLE_STRING ?
2197+
"string" : "integer",
2198+
u->desc.num_values);
2199+
}
21532200
}
2201+
if (json && t->num_tunables > 0)
2202+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\t}\n");
21542203
}
2204+
if (json)
2205+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t}\n}\n");
2206+
bpftune_set_log(bpftune_loglevel, ctx_buf.nextlogfn, NULL);
2207+
}
2208+
2209+
static void bpftune_tunables_handler(__attribute__((unused)) const char *req,
2210+
char *buf, size_t buf_sz)
2211+
{
2212+
return __bpftune_tunables_handler(req, buf, buf_sz, false);
2213+
}
2214+
2215+
static void bpftune_jtunables_handler(__attribute__((unused)) const char *req,
2216+
char *buf, size_t buf_sz)
2217+
{
2218+
return __bpftune_tunables_handler(req, buf, buf_sz, true);
21552219
}
21562220

21572221
static void bpftune_summary_handler(__attribute__((unused)) const char *req,
@@ -2169,7 +2233,6 @@ static void bpftune_summary_handler(__attribute__((unused)) const char *req,
21692233
ctx_buf.buf_sz = buf_sz;
21702234
ctx_buf.buf_thread = pthread_self();
21712235

2172-
/* have summary log to buffer + usual log destination */
21732236
bpftune_set_log(bpftune_loglevel, bpftune_log_buf, &ctx_buf);
21742237

21752238
bpftune_for_each_tuner(t) {
@@ -2187,10 +2250,86 @@ static void bpftune_summary_handler(__attribute__((unused)) const char *req,
21872250
}
21882251
}
21892252
bpftune_set_log(bpftune_loglevel, ctx_buf.nextlogfn, NULL);
2190-
bpftune_log(LOG_DEBUG, "got the following sz %d off %d, orig off %d '%s'\n",
2191-
ctx_buf.buf_sz, ctx_buf.buf_off, off, buf);
21922253
}
21932254

2255+
static void __bpftune_status_handler(__attribute__((unused)) const char *req,
2256+
char *buf, size_t buf_sz, bool json)
2257+
{
2258+
struct bpftune_log_ctx_buf ctx_buf;
2259+
struct bpftuner *t;
2260+
bool first = true;
2261+
unsigned int i;
2262+
2263+
ctx_buf.nextlogfn = bpftune_logfn;
2264+
ctx_buf.buf = buf;
2265+
ctx_buf.buf_off = 0;
2266+
ctx_buf.buf_sz = buf_sz;
2267+
ctx_buf.buf_thread = pthread_self();
2268+
2269+
buf[0] = '\0';
2270+
/* have status log to buffer, fall back to usual destination for other threads */
2271+
bpftune_set_log(bpftune_loglevel, bpftune_log_buf, &ctx_buf);
2272+
2273+
if (json)
2274+
bpftune_log(BPFTUNE_LOG_LEVEL, "{\n");
2275+
bpftune_for_each_tuner(t) {
2276+
if (json) {
2277+
if (!first)
2278+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t},\n");
2279+
first = false;
2280+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\"%s\":{\n", t->name);
2281+
}
2282+
for (i = 0; i < t->num_tunables; i++) {
2283+
char s[PATH_MAX], vals[PATH_MAX] = {};
2284+
struct bpftunable *u;
2285+
unsigned int j;
2286+
2287+
u = bpftuner_tunable(t, i);
2288+
if (u->desc.type != BPFTUNABLE_SYSCTL)
2289+
continue;
2290+
2291+
if (u->desc.flags & BPFTUNABLE_STRING) {
2292+
snprintf(vals, sizeof(vals), "\"%s\"", u->current_str);
2293+
} else {
2294+
for (j = 0; j < u->desc.num_values; j++) {
2295+
snprintf(s, sizeof(s), "%s%ld",
2296+
j == 0 ? "" : json ? ", " : " ",
2297+
u->current_values[j]);
2298+
strcat(vals, s);
2299+
}
2300+
}
2301+
if (json) {
2302+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t\t\"%s\":%s %s %s%s\n",
2303+
u->desc.name,
2304+
u->desc.num_values > 1 ? "[" : "",
2305+
vals,
2306+
u->desc.num_values > 1 ? "]" : "",
2307+
i < t->num_tunables - 1 ? "," : "");
2308+
} else {
2309+
bpftune_log(BPFTUNE_LOG_LEVEL, "%16s %50s %34s\n",
2310+
t->name, u->desc.name, vals);
2311+
}
2312+
}
2313+
}
2314+
if (json)
2315+
bpftune_log(BPFTUNE_LOG_LEVEL, "\t}\n}\n");
2316+
2317+
bpftune_set_log(bpftune_loglevel, ctx_buf.nextlogfn, NULL);
2318+
}
2319+
2320+
static void bpftune_status_handler(__attribute__((unused)) const char *req,
2321+
char *buf, size_t buf_sz)
2322+
{
2323+
return __bpftune_status_handler(req, buf, buf_sz, false);
2324+
}
2325+
2326+
static void bpftune_jstatus_handler(__attribute__((unused)) const char *req,
2327+
char *buf, size_t buf_sz)
2328+
{
2329+
return __bpftune_status_handler(req, buf, buf_sz, true);
2330+
}
2331+
2332+
21942333
static void bpftune_rollback_handler(__attribute__((unused)) const char *req,
21952334
char *buf, size_t buf_sz)
21962335
{
@@ -2206,7 +2345,7 @@ static void bpftune_rollback_handler(__attribute__((unused)) const char *req,
22062345
ctx_buf.buf_sz = buf_sz;
22072346
ctx_buf.buf_thread = pthread_self();
22082347

2209-
/* have rollback log to buffer + usual log destination */
2348+
/* have rollback log to buffer, fall back to usual log destination for other threads */
22102349
bpftune_set_log(bpftune_loglevel, bpftune_log_buf, &ctx_buf);
22112350

22122351
bpftune_for_each_tuner(t) {

src/netns_tuner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct netns_tuner_bpf *skel;
2929

3030
static struct bpftunable_desc descs[] = {
3131
{
32-
NETNS, BPFTUNABLE_OTHER, "Network namespace", BPFTUNABLE_NAMESPACED, 0 },
32+
NETNS, BPFTUNABLE_OTHER, "network_namespace", BPFTUNABLE_NAMESPACED, 0 },
3333
};
3434

3535
static struct bpftunable_scenario scenarios[] = {

src/tcp_conn_tuner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
static struct bpftunable_desc descs[] = {
3636

37-
{ TCP_CONG, BPFTUNABLE_OTHER, "Per-socket TCP congestion control", 0, 0 },
37+
{ TCP_CONG, BPFTUNABLE_OTHER, "net.persock.tcp.congestion_control", 0, 0 },
3838
{ TCP_ALLOWED_CONG, BPFTUNABLE_SYSCTL, "net.ipv4.tcp_allowed_congestion_control",
3939
BPFTUNABLE_NAMESPACED | BPFTUNABLE_STRING, 1 },
4040
{ TCP_AVAILABLE_CONG, BPFTUNABLE_SYSCTL, "net.ipv4.tcp_available_congestion_control",

test/query_test.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ for QUERY in help tuners tunables ; do
3939
done
4040
test_cleanup
4141

42-
for QUERY in summary rollback ; do
42+
if [[ -n "$JQ_CMD" ]]; then
43+
test_setup true
44+
for JQUERY in jtunables jstatus ; do
45+
test_start "$0|query $JQUERY test"
46+
test_run_cmd_local "$BPFTUNE -s &" true
47+
sleep $SETUPTIME
48+
$BPFTUNE_CMD -q $JQUERY | $JQ_CMD
49+
test_pass
50+
done
51+
test_cleanup
52+
fi
53+
54+
for QUERY in summary rollback status ; do
4355
for FAMILY in ipv4 ; do
4456
for NS in global; do
4557
case $FAMILY in

test/test_lib.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export HPING=$(which hping3 2>/dev/null)
6666
check_prog "$HPING" hping3 hping3
6767
export FIREWALL_CMD=$(which firewall-cmd 2>/dev/null)
6868
export AUDIT_CMD=$(which auditctl 2>/dev/null)
69+
export JQ_CMD=$(which jq 2>/dev/null)
6970
export SYSLOGFILE=${SYSLOGFILE:-"/var/log/messages"}
7071
if [[ ! -f $SYSLOGFILE ]]; then
7172
export SYSLOGFILE="/var/log/syslog"

0 commit comments

Comments
 (0)