已有数据同步功能完成

This commit is contained in:
1iaan
2026-01-29 10:47:24 +00:00
parent fe257cafec
commit 2bdb48d63d
27 changed files with 1134 additions and 139 deletions

18
ebpf/c/.gitignore vendored Normal file
View File

@@ -0,0 +1,18 @@
/.output
/bootstrap
/bootstrap_legacy
/minimal
/minimal_legacy
/minimal_ns
/uprobe
/kprobe
/fentry
/profile
/usdt
/sockfilter
/tc
/ksyscall
/task_iter
/lsm
/cmake-build-debug/
/cmake-build-release/

133
ebpf/c/CMakeLists.txt Normal file
View File

@@ -0,0 +1,133 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(examples C)
# Tell cmake where to find BpfObject module
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../tools/cmake)
# Build vendored libbpf
include(ExternalProject)
ExternalProject_Add(libbpf
PREFIX libbpf
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../libbpf/src
CONFIGURE_COMMAND ""
BUILD_COMMAND make
CC=${CMAKE_C_COMPILER}
BUILD_STATIC_ONLY=1
OBJDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf
DESTDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf
INCLUDEDIR=
LIBDIR=
UAPIDIR=
install install_uapi_headers
BUILD_IN_SOURCE TRUE
INSTALL_COMMAND ""
STEP_TARGETS build
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a
)
ExternalProject_Add(bpftool
PREFIX bpftool
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../bpftool/src
CONFIGURE_COMMAND ""
BUILD_COMMAND make bootstrap
OUTPUT=${CMAKE_CURRENT_BINARY_DIR}/bpftool/
BUILD_IN_SOURCE TRUE
INSTALL_COMMAND ""
STEP_TARGETS build
)
find_program(CARGO_EXISTS cargo)
if(CARGO_EXISTS)
if(CMAKE_CROSSCOMPILING)
# Determine target triple
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
set(CARGO_TARGET "x86_64-unknown-linux-gnu")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(CARGO_TARGET "aarch64-unknown-linux-gnu")
else()
message(FATAL_ERROR "Unsupported processor for Linux: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
if(CMAKE_CXX_COMPILER)
set(RUST_LINKER ${CMAKE_CXX_COMPILER})
else()
set(RUST_LINKER ${CMAKE_C_COMPILER})
endif()
else()
message((FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}"))
endif()
ExternalProject_Add(blazesym
PREFIX blazesym
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../blazesym
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMAKE_COMMAND} -E env
RUSTFLAGS=-C\ linker=${RUST_LINKER}
cargo build --package=blazesym-c --release --target=${CARGO_TARGET}
BUILD_IN_SOURCE TRUE
INSTALL_COMMAND ""
STEP_TARGETS build
)
else() # Host
ExternalProject_Add(blazesym
PREFIX blazesym
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../blazesym
CONFIGURE_COMMAND ""
BUILD_COMMAND
cargo build --package=blazesym-c --release
BUILD_IN_SOURCE TRUE
INSTALL_COMMAND ""
STEP_TARGETS build
)
endif()
endif()
# Set BpfObject input parameters -- note this is usually not necessary unless
# you're in a highly vendored environment (like libbpf-bootstrap)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(ARCH "arm")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
set(ARCH "arm64")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le")
set(ARCH "powerpc")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "mips")
set(ARCH "mips")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64")
set(ARCH "riscv")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64")
set(ARCH "loongarch")
endif()
set(BPFOBJECT_BPFTOOL_EXE ${CMAKE_CURRENT_BINARY_DIR}/bpftool/bootstrap/bpftool)
set(BPFOBJECT_VMLINUX_H ${CMAKE_CURRENT_SOURCE_DIR}/../../vmlinux.h/include/${ARCH}/vmlinux.h)
set(LIBBPF_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/libbpf)
set(LIBBPF_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a)
find_package(BpfObject REQUIRED)
# Create an executable for each application
file(GLOB apps *.bpf.c)
if(NOT CARGO_EXISTS)
list(REMOVE_ITEM apps ${CMAKE_CURRENT_SOURCE_DIR}/profile.bpf.c)
endif()
foreach(app ${apps})
get_filename_component(app_stem ${app} NAME_WE)
# Build object skeleton and depend skeleton on libbpf build
bpf_object(${app_stem} ${app_stem}.bpf.c)
add_dependencies(${app_stem}_skel libbpf bpftool)
add_executable(${app_stem} ${app_stem}.c)
target_link_libraries(${app_stem} ${app_stem}_skel)
if(${app_stem} STREQUAL profile)
target_include_directories(${app_stem} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../blazesym/capi/include)
target_link_libraries(${app_stem}
${CMAKE_CURRENT_SOURCE_DIR}/../../blazesym/target/${CARGO_TARGET}/release/libblazesym_c.a -lpthread -lrt -ldl)
add_dependencies(${app_stem} blazesym)
endif()
endforeach()

139
ebpf/c/Makefile Normal file
View File

@@ -0,0 +1,139 @@
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
OUTPUT := .output
CLANG ?= clang
LIBBPF_SRC := $(abspath ../../libbpf/src)
BPFTOOL_SRC := $(abspath ../../bpftool/src)
LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a)
BPFTOOL_OUTPUT ?= $(abspath $(OUTPUT)/bpftool)
BPFTOOL ?= $(BPFTOOL_OUTPUT)/bootstrap/bpftool
LIBBLAZESYM_SRC := $(abspath ../../blazesym/)
LIBBLAZESYM_INC := $(abspath $(LIBBLAZESYM_SRC)/capi/include)
LIBBLAZESYM_OBJ := $(abspath $(OUTPUT)/libblazesym_c.a)
ARCH ?= $(shell uname -m | sed 's/x86_64/x86/' \
| sed 's/arm.*/arm/' \
| sed 's/aarch64/arm64/' \
| sed 's/ppc64le/powerpc/' \
| sed 's/mips.*/mips/' \
| sed 's/riscv64/riscv/' \
| sed 's/loongarch64/loongarch/')
VMLINUX := ../../vmlinux.h/include/$(ARCH)/vmlinux.h
# Use our own libbpf API headers and Linux UAPI headers distributed with
# libbpf to avoid dependency on system-wide headers, which could be missing or
# outdated
INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(LIBBLAZESYM_INC)
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)
# APPS = minimal minimal_legacy minimal_ns bootstrap bootstrap_legacy uprobe kprobe fentry \
usdt sockfilter tc ksyscall task_iter lsm
APPS = replica
CARGO ?= $(shell which cargo)
ifeq ($(strip $(CARGO)),)
BZS_APPS :=
else
BZS_APPS := profile
APPS += $(BZS_APPS)
# Required by libblazesym
ALL_LDFLAGS += -lrt -ldl -lpthread -lm
endif
# Get Clang's default includes on this system. We'll explicitly add these dirs
# to the includes list when compiling with `-target bpf` because otherwise some
# architecture-specific dirs will be "missing" on some architectures/distros -
# headers such as asm/types.h, asm/byteorder.h, asm/socket.h, asm/sockios.h,
# sys/cdefs.h etc. might be missing.
#
# Use '-idirafter': Don't interfere with include mechanics except where the
# build would have failed anyways.
CLANG_BPF_SYS_INCLUDES ?= $(shell $(CLANG) -v -E - </dev/null 2>&1 \
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }')
ifeq ($(V),1)
Q =
msg =
else
Q = @
msg = @printf ' %-8s %s%s\n' \
"$(1)" \
"$(patsubst $(abspath $(OUTPUT))/%,%,$(2))" \
"$(if $(3), $(3))";
MAKEFLAGS += --no-print-directory
endif
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
$(call allow-override,CC,$(CROSS_COMPILE)cc)
$(call allow-override,LD,$(CROSS_COMPILE)ld)
.PHONY: all
all: $(APPS)
.PHONY: clean
clean:
$(call msg,CLEAN)
$(Q)rm -rf $(OUTPUT) $(APPS)
$(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT):
$(call msg,MKDIR,$@)
$(Q)mkdir -p $@
# Build libbpf
$(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf
$(call msg,LIB,$@)
$(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \
OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \
INCLUDEDIR= LIBDIR= UAPIDIR= \
install
# Build bpftool
$(BPFTOOL): | $(BPFTOOL_OUTPUT)
$(call msg,BPFTOOL,$@)
$(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap
$(LIBBLAZESYM_SRC)/target/release/libblazesym_c.a::
$(Q)cd $(LIBBLAZESYM_SRC) && $(CARGO) build --package=blazesym-c --release
$(LIBBLAZESYM_OBJ): $(LIBBLAZESYM_SRC)/target/release/libblazesym_c.a | $(OUTPUT)
$(call msg,LIB, $@)
$(Q)cp $(LIBBLAZESYM_SRC)/target/release/libblazesym_c.a $@
# Build BPF code
$(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL)
$(call msg,BPF,$@)
$(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) \
$(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) \
-c $(filter %.c,$^) -o $(patsubst %.bpf.o,%.tmp.bpf.o,$@)
$(Q)$(BPFTOOL) gen object $@ $(patsubst %.bpf.o,%.tmp.bpf.o,$@)
# Generate BPF skeletons
$(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL)
$(call msg,GEN-SKEL,$@)
$(Q)$(BPFTOOL) gen skeleton $< > $@
# Build user-space code
$(patsubst %,$(OUTPUT)/%.o,$(APPS)): %.o: %.skel.h
$(OUTPUT)/%.o: %.c $(wildcard %.h) | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@
$(patsubst %,$(OUTPUT)/%.o,$(BZS_APPS)): $(LIBBLAZESYM_OBJ)
$(BZS_APPS): $(LIBBLAZESYM_OBJ)
# Build application binary
$(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $(CFLAGS) $^ $(ALL_LDFLAGS) -lelf -lz -o $@
# delete failed targets
.DELETE_ON_ERROR:
# keep intermediate (.skel.h, .bpf.o, etc) targets
.SECONDARY:

103
ebpf/c/replica.bpf.c Normal file
View File

@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright (c) 2020 Facebook */
#include <linux/bpf.h>
#include <linux/ptrace.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "replica.h"
char LICENSE[] SEC("license") = "Dual BSD/GPL";
int my_pid = 0;
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
} channel SEC(".maps");
SEC("uprobe/kvs_create_snapshot_async")
int uprobe_create_snapshot_async(struct pt_regs *ctx)
{
struct event ev;
__builtin_memset(&ev, 0, sizeof(ev));
const char *ip;
__u32 port;
ev.type = EVENT_CREATE_SNAPSHOT_ASYNC;
ip = (const char *)PT_REGS_PARM1(ctx);
port = (__u32)PT_REGS_PARM2(ctx);
bpf_probe_read_user_str(ev.data.sync.ip,
sizeof(ev.data.sync.ip),
ip);
ev.data.sync.port = port;
bpf_perf_event_output(ctx, &channel,
BPF_F_CURRENT_CPU,
&ev, sizeof(ev));
return 0;
}
SEC("uprobe/__compeleted_cmd")
int uprobe_completed_cmd(struct pt_regs *ctx)
{
struct event ev;
__builtin_memset(&ev, 0, sizeof(ev));
const __u8 *cmd;
__u32 len;
ev.type = EVENT_COMPLETED_CMD;
cmd = (const __u8 *)PT_REGS_PARM1(ctx);
len = (__u32)PT_REGS_PARM2(ctx);
if (len > sizeof(ev.data.cmd.cmd))
len = sizeof(ev.data.cmd.cmd);
ev.data.cmd.len = len;
bpf_probe_read_user(ev.data.cmd.cmd, len, cmd);
bpf_perf_event_output(ctx, &channel,
BPF_F_CURRENT_CPU,
&ev, sizeof(ev));
return 0;
}
SEC("uprobe/__create_snapshot_ok")
int uprobe_create_snapshot_ok(struct pt_regs *ctx)
{
struct event ev;
__builtin_memset(&ev, 0, sizeof(ev));
const char *array_file;
const char *rbtree_file;
const char *hash_file;
ev.type = EVENT_CREATE_SNAPSHOT_OK;
array_file = (const char *)PT_REGS_PARM1(ctx);
rbtree_file = (const char *)PT_REGS_PARM2(ctx);
hash_file = (const char *)PT_REGS_PARM3(ctx);
bpf_probe_read_user_str(ev.data.ok.array_file,
sizeof(ev.data.ok.array_file),
array_file);
bpf_probe_read_user_str(ev.data.ok.rbtree_file,
sizeof(ev.data.ok.rbtree_file),
rbtree_file);
bpf_probe_read_user_str(ev.data.ok.hash_file,
sizeof(ev.data.ok.hash_file),
hash_file);
bpf_perf_event_output(ctx, &channel,
BPF_F_CURRENT_CPU,
&ev, sizeof(ev));
return 0;
}

257
ebpf/c/replica.c Normal file
View File

@@ -0,0 +1,257 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/* Copyright (c) 2020 Facebook */
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "replica.skel.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "replica.h"
struct cmd_node {
uint8_t *cmd;
size_t len;
struct cmd_node *next;
};
struct pending_queue {
struct cmd_node *head;
struct cmd_node *tail;
int count;
};
static void queue_init(struct pending_queue *q) {
q->head = q->tail = NULL;
q->count = 0;
}
static void queue_push(struct pending_queue *q, const uint8_t *cmd, size_t len) {
struct cmd_node *node = malloc(sizeof(*node));
if (!node) return;
node->cmd = malloc(len);
if (!node->cmd) { free(node); return; }
memcpy(node->cmd, cmd, len);
node->len = len;
node->next = NULL;
if (q->tail) q->tail->next = node;
else q->head = node;
q->tail = node;
q->count++;
}
static void queue_send_and_clear(struct pending_queue *q, int sock) {
struct cmd_node *node = q->head;
int sent_count = 0;
while (node) {
if (send(sock, node->cmd, node->len, 0) > 0) {
sent_count++;
}
struct cmd_node *tmp = node;
node = node->next;
free(tmp->cmd);
free(tmp);
}
if (sent_count > 0) {
printf("[QUEUE] Sent %d commands to slave\n", sent_count);
}
queue_init(q);
}
static void queue_free(struct pending_queue *q) {
struct cmd_node *node = q->head;
while (node) {
struct cmd_node *tmp = node;
node = node->next;
free(tmp->cmd);
free(tmp);
}
queue_init(q);
}
static int send_file(int sock, const char *path) {
FILE *fp = fopen(path, "rb");
if (!fp) {
printf("[ERROR] Failed to open file: %s\n", path);
return -1;
}
char buf[4096];
size_t n, total = 0;
while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
if (send(sock, buf, n, 0) < 0) {
fclose(fp);
printf("[ERROR] Failed to send file: %s (sent %zu bytes)\n", path, total);
return -1;
}
total += n;
}
fclose(fp);
printf("[FILE] Sent %s (%zu bytes)\n", path, total);
return 0;
}
// 全局状态(单 Slave 简化)
static enum state current_state = NOSLAVE;
static char slave_ip[16] = {0};
static int slave_port = 0;
static char array_file[128] = {0};
static char rbtree_file[128] = {0};
static char hash_file[128] = {0};
static struct pending_queue pending;
static int slave_sock = -1; // 连接 Slave 的 socket
// 连接 Slave
static int connect_slave() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) return -1;
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(slave_port);
inet_pton(AF_INET, slave_ip, &addr.sin_addr);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(sock);
return -1;
}
return sock;
}
static void handle_event(void *ctx, int cpu, void *data, __u32 size) {
struct event *ev = (struct event *)data;
switch (ev->type) {
case EVENT_CREATE_SNAPSHOT_ASYNC:
printf("[EVENT] Type: CREATE_SNAPSHOT_ASYNC\n");
printf("[EVENT] Slave IP: %s, Port: %u\n", ev->data.sync.ip, ev->data.sync.port);
if (current_state == NOSLAVE) {
current_state = START;
strncpy(slave_ip, ev->data.sync.ip, sizeof(slave_ip));
slave_port = ev->data.sync.port;
queue_init(&pending);
slave_sock = connect_slave(); // 连接 Slave
if (slave_sock < 0) {
printf("Failed to connect to Slave %s:%d\n", slave_ip, slave_port);
current_state = NOSLAVE;
}
}
break;
case EVENT_COMPLETED_CMD:
printf("[EVENT] Type: COMPLETED_CMD\n");
printf("[EVENT] Command length: %llu bytes\n", ev->data.cmd.len);
if (current_state != NOSLAVE) {
queue_push(&pending, ev->data.cmd.cmd, ev->data.cmd.len);
}
break;
case EVENT_CREATE_SNAPSHOT_OK:
printf("[EVENT] Type: CREATE_SNAPSHOT_OK\n");
printf("[EVENT] Array file: %s\n", ev->data.ok.array_file);
printf("[EVENT] RBTree file: %s\n", ev->data.ok.rbtree_file);
printf("[EVENT] Hash file: %s\n", ev->data.ok.hash_file);
if (current_state == START) {
current_state = DONE;
strncpy(array_file, ev->data.ok.array_file, sizeof(array_file));
strncpy(rbtree_file, ev->data.ok.rbtree_file, sizeof(rbtree_file));
strncpy(hash_file, ev->data.ok.hash_file, sizeof(hash_file));
}
break;
}
}
static void lost_event(void *ctx, int cpu, __u64 cnt) {
printf("Lost %llu events\n", cnt);
}
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}
int main(int argc, char **argv)
{
struct replica_bpf *skel;
int err;
/* Set up libbpf errors and debug info callback */
libbpf_set_print(libbpf_print_fn);
/* Open BPF application */
skel = replica_bpf__open();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}
/* ensure BPF program only handles write() syscalls from our process */
skel->bss->my_pid = getpid();
/* Load & verify BPF programs */
err = replica_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup;
}
/* Attach tracepoint handler */
err = replica_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}
printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` "
"to see output of the BPF programs.\n");
struct perf_buffer *pb = perf_buffer__new(bpf_map__fd(skel->maps.channel), 8, handle_event, lost_event, NULL, NULL);
if(!pb){
goto cleanup;
}
#if 0
while(1){
perf_buffer__poll(pb, 1000);
}
#else
while (1) {
perf_buffer__poll(pb, 1000); // 处理事件
// 循环中检查状态并发送
if (current_state == DONE && slave_sock >= 0) {
// 发送快照文件
if (send_file(slave_sock, array_file) == 0 &&
send_file(slave_sock, rbtree_file) == 0 &&
send_file(slave_sock, hash_file) == 0) {
current_state = ONLINE;
printf("Snapshot sent, state to ONLINE\n");
} else {
printf("Failed to send snapshot\n");
current_state = NOSLAVE;
close(slave_sock);
slave_sock = -1;
}
}
if (current_state == ONLINE && slave_sock >= 0) {
// 发送 pending
queue_send_and_clear(&pending, slave_sock);
}
}
#endif
perf_buffer__free(pb);
cleanup:
queue_free(&pending);
if (slave_sock >= 0) close(slave_sock);
replica_bpf__destroy(skel);
return -err;
}

36
ebpf/c/replica.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef __REPLICA_H__
#define __REPLICA_H__
enum event_type {
EVENT_CREATE_SNAPSHOT_ASYNC,
EVENT_CREATE_SNAPSHOT_OK,
EVENT_CREATE_SNAPSHOT_READY,
EVENT_COMPLETED_CMD
};
struct event {
enum event_type type;
union {
struct {
char ip[16];
__u32 port;
} sync;
struct {
__u8 cmd[256];
__u64 len;
} cmd;
struct {
char array_file[128];
char rbtree_file[128];
char hash_file[128];
} ok;
} data;
};
enum state {
NOSLAVE,
PREPARING,
ONLINE
};
#endif

126
ebpf/c/xmake.lua Normal file
View File

@@ -0,0 +1,126 @@
add_rules("mode.release", "mode.debug")
add_rules("platform.linux.bpf")
set_license("GPL-2.0")
if xmake.version():satisfies(">=2.5.7 <=2.5.9") then
on_load(function (target)
raise("xmake(%s) has a bug preventing BPF source code compilation. Please run `xmake update -f 2.5.6` to revert to v2.5.6 version or upgrade to xmake v2.6.1 that fixed the issue.", xmake.version())
end)
end
option("system-libbpf", {showmenu = true, default = false, description = "Use system-installed libbpf"})
option("require-bpftool", {showmenu = true, default = false, description = "Require bpftool package"})
add_requires("elfutils", "zlib")
if is_plat("android") then
add_requires("ndk >=22.x <26", "argp-standalone")
set_toolchains("@ndk", {sdkver = "23"})
else
add_requires("llvm >=10.x")
set_toolchains("@llvm")
add_requires("linux-headers")
end
-- fix error: libbpf: map 'my_pid_map': unsupported map linkage static. for bpftool >= 7.2.0
-- we cannot add `"-fvisibility=hidden"` when compiling *.bpf.c
set_symbols("none")
if is_arch("arm64", "arm64-v8a") then
add_includedirs("../../vmlinux.h/include/arm64")
elseif is_arch("arm.*") then
add_includedirs("../../vmlinux.h/include/arm")
elseif is_arch("riscv32", "riscv64") then
add_includedirs("../../vmlinux.h/include/riscv")
elseif is_arch("loongarch") then
add_includedirs("../../vmlinux.h/include/loongarch")
elseif is_arch("ppc", "powerpc") then
add_includedirs("../../vmlinux.h/include/powerpc")
elseif is_arch("x86_64", "i386") then
add_includedirs("../../vmlinux.h/include/x86")
else
add_includedirs("../../vmlinux.h/include")
end
-- we can run `xmake f --require-bpftool=y` to pull bpftool from xmake-repo repository
if has_config("require-bpftool") then
add_requires("linux-tools", {configs = {bpftool = true}})
add_packages("linux-tools")
else
before_build(function (target)
os.addenv("PATH", path.join(os.scriptdir(), "..", "..", "tools"))
end)
end
-- we use the vendored libbpf sources for libbpf-bootstrap.
-- for some projects you may want to use the system-installed libbpf, so you can run `xmake f --system-libbpf=y`
if has_config("system-libbpf") then
add_requires("libbpf", {system = true})
else
target("libbpf")
set_kind("static")
set_basename("bpf")
add_files("../../libbpf/src/*.c")
add_includedirs("../../libbpf/include")
add_includedirs("../../libbpf/include/uapi", {public = true})
add_includedirs("$(buildir)", {interface = true})
add_configfiles("../../libbpf/src/(*.h)", {prefixdir = "bpf"})
add_packages("elfutils", "zlib")
if is_plat("android") then
add_defines("__user=", "__force=", "__poll_t=uint32_t")
end
end
target("minimal")
set_kind("binary")
add_files("minimal.c", "minimal.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
target("minimal_legacy")
set_kind("binary")
add_files("minimal_legacy.c", "minimal_legacy.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
target("bootstrap")
set_kind("binary")
add_files("bootstrap.c", "bootstrap.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
if is_plat("android") then
add_packages("argp-standalone")
end
target("fentry")
set_kind("binary")
add_files("fentry.c", "fentry.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
target("uprobe")
set_kind("binary")
add_files("uprobe.c", "uprobe.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
target("kprobe")
set_kind("binary")
add_files("kprobe.c", "kprobe.bpf.c")
add_packages("linux-headers")
if not has_config("system-libbpf") then
add_deps("libbpf")
end
if is_plat("android") then
-- TODO we need fix vmlinux.h to support android
set_default(false)
end