Skip to content

Commit a5e3ac9

Browse files
chenyuan0001Kernel Patches Daemon
authored andcommitted
bpftool: Refactor kernel config reading into common helper
Extract the kernel configuration file parsing logic from feature.c into a new read_kernel_config() function in common.c. This includes: 1. Moving the config file handling and option parsing code 2. Adding required headers and struct definition 3. Keeping all existing functionality The refactoring enables sharing this logic with other components while maintaining current behavior. This will be used by subsequent patches that need to check kernel config options. Signed-off-by: Yuan Chen <[email protected]>
1 parent 2842450 commit a5e3ac9

File tree

3 files changed

+106
-82
lines changed

3 files changed

+106
-82
lines changed

tools/bpf/bpftool/common.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/resource.h>
2222
#include <sys/stat.h>
2323
#include <sys/vfs.h>
24+
#include <sys/utsname.h>
2425

2526
#include <linux/filter.h>
2627
#include <linux/limits.h>
@@ -31,6 +32,7 @@
3132
#include <bpf/hashmap.h>
3233
#include <bpf/libbpf.h> /* libbpf_num_possible_cpus */
3334
#include <bpf/btf.h>
35+
#include <zlib.h>
3436

3537
#include "main.h"
3638

@@ -1208,3 +1210,94 @@ int pathname_concat(char *buf, int buf_sz, const char *path,
12081210

12091211
return 0;
12101212
}
1213+
1214+
static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n,
1215+
char **value)
1216+
{
1217+
char *sep;
1218+
1219+
while (gzgets(file, buf, n)) {
1220+
if (strncmp(buf, "CONFIG_", 7))
1221+
continue;
1222+
1223+
sep = strchr(buf, '=');
1224+
if (!sep)
1225+
continue;
1226+
1227+
/* Trim ending '\n' */
1228+
buf[strlen(buf) - 1] = '\0';
1229+
1230+
/* Split on '=' and ensure that a value is present. */
1231+
*sep = '\0';
1232+
if (!sep[1])
1233+
continue;
1234+
1235+
*value = sep + 1;
1236+
return true;
1237+
}
1238+
1239+
return false;
1240+
}
1241+
1242+
int read_kernel_config(const struct kernel_config_option *requested_options,
1243+
size_t num_options, char **out_values,
1244+
const char *define_prefix)
1245+
{
1246+
struct utsname utsn;
1247+
char path[PATH_MAX];
1248+
gzFile file = NULL;
1249+
char buf[4096];
1250+
char *value;
1251+
size_t i;
1252+
int ret = 0;
1253+
1254+
if (!requested_options || !out_values || num_options == 0)
1255+
return -1;
1256+
1257+
if (!uname(&utsn)) {
1258+
snprintf(path, sizeof(path), "/boot/config-%s", utsn.release);
1259+
1260+
/* gzopen also accepts uncompressed files. */
1261+
file = gzopen(path, "r");
1262+
}
1263+
1264+
if (!file) {
1265+
/* Some distributions build with CONFIG_IKCONFIG=y and put the
1266+
* config file at /proc/config.gz.
1267+
*/
1268+
file = gzopen("/proc/config.gz", "r");
1269+
}
1270+
1271+
if (!file) {
1272+
p_info("skipping kernel config, can't open file: %s",
1273+
strerror(errno));
1274+
return -1;
1275+
}
1276+
1277+
if (!gzgets(file, buf, sizeof(buf)) || !gzgets(file, buf, sizeof(buf))) {
1278+
p_info("skipping kernel config, can't read from file: %s",
1279+
strerror(errno));
1280+
ret = -1;
1281+
goto end_parse;
1282+
}
1283+
1284+
if (strcmp(buf, "# Automatically generated file; DO NOT EDIT.\n")) {
1285+
p_info("skipping kernel config, can't find correct file");
1286+
ret = -1;
1287+
goto end_parse;
1288+
}
1289+
1290+
while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) {
1291+
for (i = 0; i < num_options; i++) {
1292+
if ((define_prefix && !requested_options[i].macro_dump) ||
1293+
out_values[i] || strcmp(buf, requested_options[i].name))
1294+
continue;
1295+
1296+
out_values[i] = strdup(value);
1297+
}
1298+
}
1299+
1300+
end_parse:
1301+
gzclose(file);
1302+
return ret;
1303+
}

tools/bpf/bpftool/feature.c

Lines changed: 4 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010
#ifdef USE_LIBCAP
1111
#include <sys/capability.h>
1212
#endif
13-
#include <sys/utsname.h>
1413
#include <sys/vfs.h>
1514

1615
#include <linux/filter.h>
1716
#include <linux/limits.h>
1817

1918
#include <bpf/bpf.h>
2019
#include <bpf/libbpf.h>
21-
#include <zlib.h>
2220

2321
#include "main.h"
2422

@@ -327,40 +325,9 @@ static void probe_jit_limit(void)
327325
}
328326
}
329327

330-
static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n,
331-
char **value)
332-
{
333-
char *sep;
334-
335-
while (gzgets(file, buf, n)) {
336-
if (strncmp(buf, "CONFIG_", 7))
337-
continue;
338-
339-
sep = strchr(buf, '=');
340-
if (!sep)
341-
continue;
342-
343-
/* Trim ending '\n' */
344-
buf[strlen(buf) - 1] = '\0';
345-
346-
/* Split on '=' and ensure that a value is present. */
347-
*sep = '\0';
348-
if (!sep[1])
349-
continue;
350-
351-
*value = sep + 1;
352-
return true;
353-
}
354-
355-
return false;
356-
}
357-
358328
static void probe_kernel_image_config(const char *define_prefix)
359329
{
360-
static const struct {
361-
const char * const name;
362-
bool macro_dump;
363-
} options[] = {
330+
struct kernel_config_option options[] = {
364331
/* Enable BPF */
365332
{ "CONFIG_BPF", },
366333
/* Enable bpf() syscall */
@@ -435,63 +402,18 @@ static void probe_kernel_image_config(const char *define_prefix)
435402
{ "CONFIG_HZ", true, }
436403
};
437404
char *values[ARRAY_SIZE(options)] = { };
438-
struct utsname utsn;
439-
char path[PATH_MAX];
440-
gzFile file = NULL;
441-
char buf[4096];
442-
char *value;
443405
size_t i;
444406

445-
if (!uname(&utsn)) {
446-
snprintf(path, sizeof(path), "/boot/config-%s", utsn.release);
447-
448-
/* gzopen also accepts uncompressed files. */
449-
file = gzopen(path, "r");
450-
}
451-
452-
if (!file) {
453-
/* Some distributions build with CONFIG_IKCONFIG=y and put the
454-
* config file at /proc/config.gz.
455-
*/
456-
file = gzopen("/proc/config.gz", "r");
457-
}
458-
if (!file) {
459-
p_info("skipping kernel config, can't open file: %s",
460-
strerror(errno));
461-
goto end_parse;
462-
}
463-
/* Sanity checks */
464-
if (!gzgets(file, buf, sizeof(buf)) ||
465-
!gzgets(file, buf, sizeof(buf))) {
466-
p_info("skipping kernel config, can't read from file: %s",
467-
strerror(errno));
468-
goto end_parse;
469-
}
470-
if (strcmp(buf, "# Automatically generated file; DO NOT EDIT.\n")) {
471-
p_info("skipping kernel config, can't find correct file");
472-
goto end_parse;
473-
}
474-
475-
while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) {
476-
for (i = 0; i < ARRAY_SIZE(options); i++) {
477-
if ((define_prefix && !options[i].macro_dump) ||
478-
values[i] || strcmp(buf, options[i].name))
479-
continue;
480-
481-
values[i] = strdup(value);
482-
}
483-
}
407+
if (read_kernel_config(options, ARRAY_SIZE(options), values,
408+
define_prefix))
409+
return;
484410

485411
for (i = 0; i < ARRAY_SIZE(options); i++) {
486412
if (define_prefix && !options[i].macro_dump)
487413
continue;
488414
print_kernel_option(options[i].name, values[i], define_prefix);
489415
free(values[i]);
490416
}
491-
492-
end_parse:
493-
if (file)
494-
gzclose(file);
495417
}
496418

497419
static bool probe_bpf_syscall(const char *define_prefix)

tools/bpf/bpftool/main.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,13 @@ int pathname_concat(char *buf, int buf_sz, const char *path,
275275
/* print netfilter bpf_link info */
276276
void netfilter_dump_plain(const struct bpf_link_info *info);
277277
void netfilter_dump_json(const struct bpf_link_info *info, json_writer_t *wtr);
278+
279+
struct kernel_config_option {
280+
const char *name;
281+
bool macro_dump;
282+
};
283+
284+
int read_kernel_config(const struct kernel_config_option *requested_options,
285+
size_t num_options, char **out_values,
286+
const char *define_prefix);
278287
#endif

0 commit comments

Comments
 (0)