Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 141 startup warnings in ebpf programs #145

Merged
merged 3 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/bpf-common/include/output.bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ struct {
__uint(max_entries, 1);
} temp_map SEC(".maps");

// The status map contains configuration status for the eBPF program:
// - The STATUS_INITIALIZED entry indicates the perf event array initialization
// status. On startup it's set to 0, when the userspace program opens the perf
// event array it's set to 1. The eBPF program emits events only when it's 1.
#define STATUS_INITIALIZED 0
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__type(key, u32);
__type(value, u32);
__uint(max_entries, 1);
} status_map SEC(".maps");
MatteoNardi marked this conversation as resolved.
Show resolved Hide resolved

// Get the temporary buffer inside temp_map as a void pointer, this can be cast
// to the required event type and filled before submitting it for output. The
// pointed at memory contiains BUFFER_MAX *2 bytes.
Expand All @@ -63,6 +75,13 @@ static __always_inline void *output_temp() {
static __always_inline void output_event(void *ctx, void *output_map,
void *event, int struct_len,
int buffer_len) {
u32 key = STATUS_INITIALIZED;
u32 *initialization_status = bpf_map_lookup_elem(&status_map, &key);
if (!initialization_status || !*initialization_status) {
// The userspace is not ready yet for events on the perf event array
return;
}

// The output size is the full struct length, minus the unused buffer len
unsigned int len = struct_len - (BUFFER_MAX - buffer_len);
if (len > 0 && len <= struct_len) {
Expand Down
16 changes: 15 additions & 1 deletion crates/bpf-common/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{convert::TryFrom, fmt::Display, mem::size_of, sync::Arc, time::Duratio
use aya::{
maps::{
perf::{AsyncPerfEventArray, PerfBufferError},
HashMap, MapData,
Array, HashMap, MapData,
},
programs::{KProbe, Lsm, RawTracePoint, TracePoint},
util::online_cpus,
Expand Down Expand Up @@ -338,6 +338,11 @@ impl Program {
.take_map(map_name)
.ok_or_else(|| ProgramError::MapNotFound(map_name.to_string()))?;
let mut perf_array: AsyncPerfEventArray<_> = AsyncPerfEventArray::try_from(map_resource)?;
let mut status_map = Array::try_from(
self.bpf
.take_map("status_map")
.ok_or_else(|| ProgramError::MapNotFound("status_map".to_string()))?,
)?;

let buffers = online_cpus()
.unwrap()
Expand Down Expand Up @@ -394,6 +399,15 @@ impl Program {
}
});
}

// Signal eBPF program we're ready by setting STATUS_INITIALIZED
if let Err(err) = status_map.set(0, 1_u32, 0) {
log::warn!(
"Error setting STATUS_INITIALIZED for {}: {:?}",
self.name,
err
);
};
Ok(())
}
}
Expand Down
2 changes: 0 additions & 2 deletions crates/modules/file-system-monitor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub async fn program(
// If LSM eBPF programs is not supported, we'll attach to the same kernel
// functions, but using kprobes.
if lsm_supported().await {
log::info!("Loading LSM programs");
builder = builder
.lsm("path_mknod")
.lsm("path_unlink")
Expand All @@ -29,7 +28,6 @@ pub async fn program(
.lsm("path_link")
.lsm("path_symlink");
} else {
log::info!("LSM programs not supported. Falling back to kprobes");
builder = builder
.kprobe("security_path_mknod")
.kprobe("security_path_unlink")
Expand Down
10 changes: 9 additions & 1 deletion src/pulsard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,15 @@ pub async fn pulsar_daemon_run(
server_handle.stop().await;

log::info!("Terminating Pulsar Daemon...");
drop(pulsar_daemon);
for module in pulsar_daemon.modules().await {
if let Err(err) = pulsar_daemon.stop(module.name.clone()).await {
log::warn!(
"Module {} didn't respond to shutdown signal. Forcing shutdown.\n{:?}",
module.name,
err
)
}
}

Ok(())
}
Expand Down
10 changes: 8 additions & 2 deletions src/pulsard/module_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,14 @@ impl ModuleManager {
let (tx_shutdown, task) = self.running_task.take().unwrap();
tx_shutdown.send_signal();
let result = task.await;
log::info!("Module {} exited: {:?}", self.task_launcher.name(), result);
// TODO: use this result and report errors
match result {
Ok(()) => log::info!("Module {} exited", self.task_launcher.name()),
Err(err) => log::warn!(
"Module {} exit failure: {:?}",
self.task_launcher.name(),
err
),
}
self.status = ModuleStatus::Stopped;
Ok(())
} else {
Expand Down