Inspect and Safely Edit eBPF Maps with bpftool
By the end of this guide you will be able to identify an eBPF map, inspect its entries, address it by ID or pinned path, and make a controlled update. The examples use the bpftool-map(8) interface shipped by linux-tools-common 6.8.0-139.139 on this host.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Check the local command before touching a map
- 2. List maps and record their shape
- Checkpoint: choose a stable map reference
- 3. Read entries before changing them
- 4. Update one entry with explicit bytes
- 5. Pin a map when another command needs it
- 6. Treat special map operations as application actions
- 7. Freeze only when you mean it
Allow 15 to 30 minutes if the map already exists. You need a Linux host with a running BPF workload, the bpftool command, and permission to inspect or change the map. Commands that inspect ordinary system maps may need elevated privileges, and creating, pinning, updating or deleting maps commonly requires root or equivalent BPF capabilities.
1. Check the local command before touching a map
Start by checking the command and its version. This catches a surprisingly common trap: linux-tools-common can install a wrapper without installing the executable matching the running kernel.
$ command -v bpftool
/usr/sbin/bpftool
$ bpftool version
WARNING: bpftool not found for kernel 6.8.0-139
On this host, the wrapper reports that linux-tools-6.8.0-139-generic may also be required. Install the matching kernel tools through your normal package-management process, then repeat bpftool version. Do not treat the warning as a successful version check, and do not guess a different binary from another kernel release.
The rest of this guide describes the map syntax documented by the installed manpage. Stop here if the command still only prints the warning: there is no useful map output to verify yet.
2. List maps and record their shape
List every loaded map, or ask for one by ID, name or pinned path. Begin with a read-only listing so that you know the key and value sizes before preparing bytes.
# bpftool map show
10: hash name some_map flags 0x0
key 4B value 8B max_entries 2048 memlock 167936B
The first number is the map ID. The listing also tells you the map type, name, key size, value size and capacity. Those sizes are a hard boundary: a four-byte key is not interchangeable with an eight-byte key. The exact attributes vary with the kernel version, and a process holding a map file descriptor may be shown on kernels with the relevant support.
For scripts, request JSON and let a JSON parser consume it instead of scraping columns:
# bpftool -j map show
--pretty implies JSON and makes it easier to read interactively. --bpffs adds pinned file names when available. --nomount prevents bpftool from attempting automatic virtual-filesystem mounts, which is useful when a diagnostic command must not change mount state.
Checkpoint: choose a stable map reference
An ID such as 10 can change after a map is destroyed and recreated. A pinned path is usually clearer for repeatable administration:
# bpftool map show id 10
# bpftool map show name some_map
# bpftool map show pinned /sys/fs/bpf/example_map
A name can match more than one map. If that matters, use the returned ID or an exact pinned path before writing anything.
3. Read entries before changing them
Dump a map to see all entries, or look up one known key. The output is byte-oriented, so interpret it using the map's own key and value layout, not by assuming that the displayed bytes are text or host-order integers.
# bpftool map dump id 10
key: 00 01 02 03 value: 00 01 02 03 04 05 06 07
Found 1 element
# bpftool map lookup id 10 key 0 1 2 3
key: 00 01 02 03 value: 00 01 02 03 04 05 06 07
To walk keys, omit the key to request the first one, then supply a returned key to request the next:
# bpftool map getnext id 10
# bpftool map getnext id 10 key 0 1 2 3
An empty dump is a valid result for an empty map. A failed lookup is different: check the key length, map reference and byte values before trying again.
4. Update one entry with explicit bytes
Take a fresh dump, confirm the target key and value sizes, then update one entry. The safest example uses hex, because it removes ambiguity about whether a byte such as 0c is decimal or hexadecimal.
# bpftool map update id 10 \
key hex 20 c4 b7 00 \
value hex 0f ff ff ab 01 02 03 4c \
exist
The exist flag refuses to create a new key. Use noexist when creation is the only acceptable result, or any when either creation or replacement is intended. Without an update flag, the documented default is the permissive update-or-create behaviour.
Do not paste the example into an unrelated map. The four key bytes and eight value bytes are valid only for a map with those exact sizes and an application layout that gives them the intended meaning. If you omit hex, bpftool reads unprefixed values as decimal; 0x selects hexadecimal and a leading 0 selects octal.
5. Pin a map when another command needs it
A pinned map keeps a filesystem reference after the creating process exits. The destination must be on a mounted BPF filesystem, and the path must not contain a dot.
# mount -t bpf none /sys/fs/bpf
# bpftool map pin id 10 /sys/fs/bpf/example_map
# bpftool map dump pinned /sys/fs/bpf/example_map
Mounting BPF filesystem state and pinning changes the host, so record the intended path first. To undo the pin without destroying the map, remove the pinned path during a maintenance window using the normal filesystem command, for example rm -- /sys/fs/bpf/example_map. Removing the last reference can allow the kernel to destroy an otherwise unreferenced map, so check that no program or service still needs it before removing anything.
6. Treat special map operations as application actions
Queue and stack maps have dedicated operations: peek, push, pop, enqueue and dequeue. These consume or add entries, so they are not harmless inspection commands. A perf-event array's event_pipe operation installs perf rings and silently replaces an existing ring at the selected location; another consumer can stop receiving events. Use it only when you own that map's event pipeline.
Program-array maps can change tail-call targets with map update, but the map must be pinned or the update can disappear when bpftool exits. Verify the target program reference and rollback plan before changing live packet or tracing behaviour.
7. Freeze only when you mean it
freeze makes a map read-only to user space. Entries can no longer be updated or deleted through the BPF system call, and the operation is not reversible for that map. BPF programs retain their existing read and write permissions.
# bpftool map freeze pinned /sys/fs/bpf/example_map
# bpftool map lookup pinned /sys/fs/bpf/example_map key 0 1 2 3
There is no undo command. The recovery is to destroy the frozen map after all users have stopped, then create and populate a replacement. Plan that as a service change, not as routine cleanup.
Done means
bpftool versionidentifies a usable executable for the running kernel.- You recorded the map type, key size, value size and reference used.
- You performed a read-only lookup or dump before editing.
- Your update used byte values and an explicit
any,existornoexistpolicy. - You know whether a pin, queue operation, event pipe or program-array update changes shared system state.
- You did not use
freezeunless permanent user-space immutability was deliberate and recoverable through replacement.