summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-10 22:43:47 +0300
committerPaul Buetow <paul@buetow.org>2026-05-10 22:43:47 +0300
commit74b551464c6daf87617fea550d2592e7c2e20be0 (patch)
tree7c878133bd5c56d44289a7f8c1090a8d1fe0e21b
parentecb5655a39a2f359fb147954b34323b6a50dcd05 (diff)
Update content for gemtext
-rw-r--r--gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi20
-rw-r--r--gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi.tpl11
-rw-r--r--gemfeed/atom.xml20
-rw-r--r--gemfeed/index.gmi2
-rw-r--r--index.gmi4
-rw-r--r--uptime-stats.gmi16
6 files changed, 52 insertions, 21 deletions
diff --git a/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi b/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi
index d41084df..c0cbb147 100644
--- a/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi
+++ b/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi
@@ -1,4 +1,6 @@
- (or Podman)# Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
+# Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
+
+> Published at 2026-05-10T22:43:39+03:00
This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, how the dashboard tabs work, how filtering and recording behave. This part is about the installation for Rocky Linux 8 and 9 and, more interestingly, why you only have to do that dance on a single machine: the resulting binary is portable to every other Linux box thanks to CO-RE (Compile Once, Run Everywhere) plus full static linking. Part 3 is the under-the-hood companion (per-event schema, async-syscall caveats, the syscall-coverage probe generator, and post-mortem SQL on the parquet output).
@@ -9,10 +11,7 @@ This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, ho
## Table of Contents
-> Published at 2026-05-10T22:41:23+03:00
-
-> Published at 2026-05-10T22:39:24+03:00
-
+* ⇢ Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
* ⇢ ⇢ Installing ior
* ⇢ ⇢ ⇢ Why native installation is a mess
* ⇢ ⇢ ⇢ What the Docker build is actually doing
@@ -27,6 +26,10 @@ This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, ho
## Installing ior
+> Published at 2026-05-10T22:41:23+03:00
+
+> Published at 2026-05-10T22:39:24+03:00
+
The short answer: Use Docker (or Podman). One command, no toolchain setup, works from any Docker-capable Linux host with BTF available:
```sh
@@ -112,6 +115,8 @@ If you see `Probing for 5s` followed by CSV rows, the build is good. `mage build
If you haven't touched eBPF before: it's a small in-kernel bytecode VM. You compile a tiny C program, the kernel verifies it can't crash or loop forever, and then it runs every time some hook fires — a syscall enter/exit, a kprobe, a tracepoint, a network packet. The program writes events into a ring buffer that userspace mmaps and drains. No kernel module, no patched kernel, no debug symbols required.
+=> https://ebpf.io eBPF — the project's umbrella site (docs, talks, ecosystem)
+
`ior` plugs into the syscall tracepoints (`sys_enter_openat`, `sys_exit_read`, etc.) and the BPF side does the bare minimum: timestamp the event, copy a few fields, push to a perf ring buffer. All the heavy lifting (string interning, latency math, aggregation, the dashboard) is in Go on the userspace side.
The shape of the data flow:
@@ -139,9 +144,14 @@ The shape of the data flow:
The kernel ships a C library called libbpf that handles loading the program, attaching it to hooks, managing maps, and reading the ring buffer. There are two well-known ways to drive that from Go:
+=> https://github.com/libbpf/libbpf libbpf — the upstream C library
+
* libbpfgo (Aqua Security): a thin cgo wrapper around libbpf. You ship libbpf along with your binary and call into the same C API that `bpftool` and `perf` use.
* cilium/ebpf: a from-scratch pure-Go reimplementation of everything libbpf does (ELF parser, BTF resolver, syscall layer, the lot).
+=> https://github.com/aquasecurity/libbpfgo libbpfgo — Aqua Security's cgo wrapper around libbpf
+=> https://github.com/cilium/ebpf cilium/ebpf — pure-Go reimplementation
+
I went with libbpfgo specifically because it's a wrapper, not a reimplementation.
## CO-RE — the part that makes the binary actually portable
diff --git a/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi.tpl b/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi.tpl
index 7539c969..b207fe39 100644
--- a/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi.tpl
+++ b/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi.tpl
@@ -1,4 +1,6 @@
- (or Podman)# Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
+# Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
+
+> Published at 2026-05-10T22:43:39+03:00
This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, how the dashboard tabs work, how filtering and recording behave. This part is about the installation for Rocky Linux 8 and 9 and, more interestingly, why you only have to do that dance on a single machine: the resulting binary is portable to every other Linux box thanks to CO-RE (Compile Once, Run Everywhere) plus full static linking. Part 3 is the under-the-hood companion (per-event schema, async-syscall caveats, the syscall-coverage probe generator, and post-mortem SQL on the parquet output).
@@ -99,6 +101,8 @@ If you see `Probing for 5s` followed by CSV rows, the build is good. `mage build
If you haven't touched eBPF before: it's a small in-kernel bytecode VM. You compile a tiny C program, the kernel verifies it can't crash or loop forever, and then it runs every time some hook fires — a syscall enter/exit, a kprobe, a tracepoint, a network packet. The program writes events into a ring buffer that userspace mmaps and drains. No kernel module, no patched kernel, no debug symbols required.
+=> https://ebpf.io eBPF — the project's umbrella site (docs, talks, ecosystem)
+
`ior` plugs into the syscall tracepoints (`sys_enter_openat`, `sys_exit_read`, etc.) and the BPF side does the bare minimum: timestamp the event, copy a few fields, push to a perf ring buffer. All the heavy lifting (string interning, latency math, aggregation, the dashboard) is in Go on the userspace side.
The shape of the data flow:
@@ -126,9 +130,14 @@ The shape of the data flow:
The kernel ships a C library called libbpf that handles loading the program, attaching it to hooks, managing maps, and reading the ring buffer. There are two well-known ways to drive that from Go:
+=> https://github.com/libbpf/libbpf libbpf — the upstream C library
+
* libbpfgo (Aqua Security): a thin cgo wrapper around libbpf. You ship libbpf along with your binary and call into the same C API that `bpftool` and `perf` use.
* cilium/ebpf: a from-scratch pure-Go reimplementation of everything libbpf does (ELF parser, BTF resolver, syscall layer, the lot).
+=> https://github.com/aquasecurity/libbpfgo libbpfgo — Aqua Security's cgo wrapper around libbpf
+=> https://github.com/cilium/ebpf cilium/ebpf — pure-Go reimplementation
+
I went with libbpfgo specifically because it's a wrapper, not a reimplementation.
## CO-RE — the part that makes the binary actually portable
diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml
index 794863a5..655f6c89 100644
--- a/gemfeed/atom.xml
+++ b/gemfeed/atom.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
- <updated>2026-05-10T22:41:22+03:00</updated>
+ <updated>2026-05-10T22:43:40+03:00</updated>
<title>foo.zone feed</title>
<subtitle>To be in the .zone!</subtitle>
<link href="gemini://foo.zone/gemfeed/atom.xml" rel="self" />
<link href="gemini://foo.zone/" />
<id>gemini://foo.zone/</id>
<entry>
- <title>1) Enable repos and install build dependencies. CRB ships zlib-static / glibc-static.</title>
+ <title>Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere</title>
<link href="gemini://foo.zone/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi" />
<id>gemini://foo.zone/gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi</id>
- <updated>2026-05-10T22:39:24+03:00</updated>
+ <updated>2026-05-10T22:43:39+03:00</updated>
<author>
<name>Paul Buetow aka snonux</name>
<email>paul@dev.buetow.org</email>
@@ -18,7 +18,7 @@
<summary>This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, how the dashboard tabs work, how filtering and recording behave. This part is about the installation for Rocky Linux 8 and 9 and, more interestingly, why you only have to do that dance on a single machine: the resulting binary is portable to every other Linux box thanks to CO-RE (Compile Once, Run Everywhere) plus full static linking. Part 3 is the under-the-hood companion (per-event schema, async-syscall caveats, the syscall-coverage probe generator, and post-mortem SQL on the parquet output).</summary>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
- <span> (or Podman)# Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere</span><br />
+ <h1 style='display: inline' id='unveiling-io-riot-ng--part-2-install-and-compile-once-run-everywhere'>Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere</h1><br />
<br />
<span>This is Part 2 of three. Part 1 is the demo-driven tour: what ior looks like, how the dashboard tabs work, how filtering and recording behave. This part is about the installation for Rocky Linux 8 and 9 and, more interestingly, why you only have to do that dance on a single machine: the resulting binary is portable to every other Linux box thanks to CO-RE (Compile Once, Run Everywhere) plus full static linking. Part 3 is the under-the-hood companion (per-event schema, async-syscall caveats, the syscall-coverage probe generator, and post-mortem SQL on the parquet output).</span><br />
<br />
@@ -30,6 +30,7 @@
<h2 style='display: inline' id='table-of-contents'>Table of Contents</h2><br />
<br />
<ul>
+<li><a href='#unveiling-io-riot-ng--part-2-install-and-compile-once-run-everywhere'>Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere</a></li>
<li>⇢ <a href='#installing-ior'>Installing ior</a></li>
<li>⇢ ⇢ <a href='#why-native-installation-is-a-mess'>Why native installation is a mess</a></li>
<li>⇢ ⇢ <a href='#what-the-docker-build-is-actually-doing'>What the Docker build is actually doing</a></li>
@@ -44,6 +45,10 @@
</ul><br />
<h2 style='display: inline' id='installing-ior'>Installing ior</h2><br />
<br />
+<span class='quote'>Published at 2026-05-10T22:41:23+03:00</span><br />
+<br />
+<span class='quote'>Published at 2026-05-10T22:39:24+03:00</span><br />
+<br />
<span>The short answer: Use Docker (or Podman). One command, no toolchain setup, works from any Docker-capable Linux host with BTF available:</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
@@ -135,6 +140,8 @@ sudo ./ior -plain -duration <font color="#000000">5</font>
<br />
<span>If you haven&#39;t touched eBPF before: it&#39;s a small in-kernel bytecode VM. You compile a tiny C program, the kernel verifies it can&#39;t crash or loop forever, and then it runs every time some hook fires — a syscall enter/exit, a kprobe, a tracepoint, a network packet. The program writes events into a ring buffer that userspace mmaps and drains. No kernel module, no patched kernel, no debug symbols required.</span><br />
<br />
+<a class='textlink' href='https://ebpf.io'>eBPF — the project&#39;s umbrella site (docs, talks, ecosystem)</a><br />
+<br />
<span><span class='inlinecode'>ior</span> plugs into the syscall tracepoints (<span class='inlinecode'>sys_enter_openat</span>, <span class='inlinecode'>sys_exit_read</span>, etc.) and the BPF side does the bare minimum: timestamp the event, copy a few fields, push to a perf ring buffer. All the heavy lifting (string interning, latency math, aggregation, the dashboard) is in Go on the userspace side.</span><br />
<br />
<span>The shape of the data flow:</span><br />
@@ -162,10 +169,15 @@ sudo ./ior -plain -duration <font color="#000000">5</font>
<br />
<span>The kernel ships a C library called libbpf that handles loading the program, attaching it to hooks, managing maps, and reading the ring buffer. There are two well-known ways to drive that from Go:</span><br />
<br />
+<a class='textlink' href='https://github.com/libbpf/libbpf'>libbpf — the upstream C library</a><br />
+<br />
<ul>
<li>libbpfgo (Aqua Security): a thin cgo wrapper around libbpf. You ship libbpf along with your binary and call into the same C API that <span class='inlinecode'>bpftool</span> and <span class='inlinecode'>perf</span> use.</li>
<li>cilium/ebpf: a from-scratch pure-Go reimplementation of everything libbpf does (ELF parser, BTF resolver, syscall layer, the lot).</li>
</ul><br />
+<a class='textlink' href='https://github.com/aquasecurity/libbpfgo'>libbpfgo — Aqua Security&#39;s cgo wrapper around libbpf</a><br />
+<a class='textlink' href='https://github.com/cilium/ebpf'>cilium/ebpf — pure-Go reimplementation</a><br />
+<br />
<span>I went with libbpfgo specifically because it&#39;s a wrapper, not a reimplementation.</span><br />
<br />
<h2 style='display: inline' id='co-re--the-part-that-makes-the-binary-actually-portable'>CO-RE — the part that makes the binary actually portable</h2><br />
diff --git a/gemfeed/index.gmi b/gemfeed/index.gmi
index f85262ca..6a5ca4c4 100644
--- a/gemfeed/index.gmi
+++ b/gemfeed/index.gmi
@@ -2,7 +2,7 @@
## To be in the .zone!
-=> ./2026-05-11-unveiling-ior-ng-part-2.gmi 2026-05-11 - 1) Enable repos and install build dependencies. CRB ships zlib-static / glibc-static.
+=> ./2026-05-11-unveiling-ior-ng-part-2.gmi 2026-05-11 - Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
=> ./2026-05-08-unveiling-ior-ng-part-1.gmi 2026-05-08 - Unveiling I/O Riot NG — Part 1: a guided tour
=> ./2026-04-02-f3s-kubernetes-with-freebsd-part-9.gmi 2026-04-02 - f3s: Kubernetes with FreeBSD - Part 9: GitOps with ArgoCD
=> ./2026-04-02-distributed-systems-simulator-part-3.gmi 2026-04-02 - Distributed Systems Simulator - Part 3: Advanced Examples and Protocol API
diff --git a/index.gmi b/index.gmi
index d7a3e99c..4214eec3 100644
--- a/index.gmi
+++ b/index.gmi
@@ -1,6 +1,6 @@
# Hello!
-> This site was generated at 2026-05-10T22:41:48+03:00 by `Gemtexter`
+> This site was generated at 2026-05-10T22:43:40+03:00 by `Gemtexter`
Welcome to the foo.zone!
@@ -20,7 +20,7 @@ Everything you read on this site is my personal opinion and experience. You can
### Posts
-=> ./gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi 2026-05-11 - 1) Enable repos and install build dependencies. CRB ships zlib-static / glibc-static.
+=> ./gemfeed/2026-05-11-unveiling-ior-ng-part-2.gmi 2026-05-11 - Unveiling I/O Riot NG — Part 2: install and compile once, run everywhere
=> ./gemfeed/2026-05-08-unveiling-ior-ng-part-1.gmi 2026-05-08 - Unveiling I/O Riot NG — Part 1: a guided tour
=> ./gemfeed/2026-04-02-f3s-kubernetes-with-freebsd-part-9.gmi 2026-04-02 - f3s: Kubernetes with FreeBSD - Part 9: GitOps with ArgoCD
=> ./gemfeed/2026-04-02-distributed-systems-simulator-part-3.gmi 2026-04-02 - Distributed Systems Simulator - Part 3: Advanced Examples and Protocol API
diff --git a/uptime-stats.gmi b/uptime-stats.gmi
index d230177a..7d3eacdd 100644
--- a/uptime-stats.gmi
+++ b/uptime-stats.gmi
@@ -1,6 +1,6 @@
# My machine uptime stats
-> This site was last updated at 2026-05-10T22:41:48+03:00
+> This site was last updated at 2026-05-10T22:43:40+03:00
The following stats were collected via `uptimed` on all of my personal computers over many years and the output was generated by `goprecords`, the global uptime records stats analyser of mine.
@@ -13,7 +13,7 @@ Also check out my blog post:
=> ./gemfeed/2023-05-01-unveiling-guprecords:-uptime-records-with-raku.gmi Unveiling `guprecords.raku`: Uptime records with Raku (and also there is a version in Go now)
-> Uptime stats were last updated Sun 10 May 22:41:48 EEST 2026
+> Uptime stats were last updated Sun 10 May 22:43:40 EEST 2026
## Top 20 Uptime's by Host
@@ -80,8 +80,8 @@ Boots is the total number of host boots over the entire lifespan.
| 1. | *f2 | 245 | FreeBSD 15.0-RELEASE-p4 |
| 2. | *f1 | 243 | FreeBSD 15.0-RELEASE-p4 |
| 3. | *f0 | 242 | FreeBSD 15.0-RELEASE-p4 |
-| 4. | *pi0 | 26 | Linux 6.1.31-v8.1.el9.altarch |
-| 5. | *pi2 | 26 | Linux 6.1.31-v8.1.el9.altarch |
+| 4. | *pi2 | 26 | Linux 6.1.31-v8.1.el9.altarch |
+| 5. | *pi0 | 26 | Linux 6.1.31-v8.1.el9.altarch |
| 6. | pi1 | 1 | Linux 6.1.31-v8.1.el9.altarch |
| 7. | pi3 | 1 | Linux 6.1.31-v8.1.el9.altarch |
+-----+------+-------+-------------------------------+
@@ -98,10 +98,10 @@ Score is calculated by combining all other metrics.
| 1. | *f1 | 75 | FreeBSD 15.0-RELEASE-p4 |
| 2. | *f2 | 75 | FreeBSD 15.0-RELEASE-p4 |
| 3. | *f0 | 74 | FreeBSD 15.0-RELEASE-p4 |
-| 4. | *pi2 | 8 | Linux 6.1.31-v8.1.el9.altarch |
-| 5. | *pi0 | 8 | Linux 6.1.31-v8.1.el9.altarch |
-| 6. | pi3 | 0 | Linux 6.1.31-v8.1.el9.altarch |
-| 7. | pi1 | 0 | Linux 6.1.31-v8.1.el9.altarch |
+| 4. | *pi0 | 8 | Linux 6.1.31-v8.1.el9.altarch |
+| 5. | *pi2 | 8 | Linux 6.1.31-v8.1.el9.altarch |
+| 6. | pi1 | 0 | Linux 6.1.31-v8.1.el9.altarch |
+| 7. | pi3 | 0 | Linux 6.1.31-v8.1.el9.altarch |
+-----+------+-------+-------------------------------+
```