From f601dc90fcef3f270c55a9612c5f0326dbd0f391 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 9 Jun 2026 22:24:30 +0300 Subject: feat(parquet): export rename/link oldname + assert oldname capture end-to-end rename-family (rename/renameat/renameat2) and link-family (link/linkat/ symlink/symlinkat) capture BOTH paths in BPF (name_event.oldname at args[1] for the AT-variants, after a dirfd, plus newname), but only newname reached any persisted output. event.Pair.FileName() resolves to oldnameNewnameFile.Name() == Newname, so the parquet `file` column, CSV, and flamegraph Path all carried newname; the captured oldname survived only in the TUI stream String() repr ("old:... ->new:..."). The oldname capture (and its args[1] index for the AT-variants) was therefore never validated end-to-end, and a wrong-oldname-index regression would surface in no persisted output or test. Surface oldname as one additive, backward-compatible column, mirroring the dedicated optional-column convention (address_space_bytes, requested_sleep_ns, epoll_*): - old_file (String): source/old path for rename/link syscalls; empty for every other syscall. The existing `file` column keeps its semantics (newname for rename/link). Data flows name_event.oldname -> event.Pair.Oldname (populated in handleNameExit alongside the existing File) -> streamrow.Row.OldName -> parquet.Record.OldFile. Docs (docs/parquet-querying.md) and the Magefile parquetValidate column list updated in lockstep. The new TestRenameRenameatOldnameInParquet integration test exercises the renameat AT-variant (oldname at args[1] after the olddfd dirfd) and asserts the parquet old_file column carries renameat-old.txt while file carries renameat-new.txt, and that old_file stays empty for non-rename/ link rows -- locking in the args[1] oldname capture end-to-end. Co-Authored-By: Claude Opus 4.8 --- internal/eventloop_exit.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'internal/eventloop_exit.go') diff --git a/internal/eventloop_exit.go b/internal/eventloop_exit.go index 105d9ac..9802a6f 100644 --- a/internal/eventloop_exit.go +++ b/internal/eventloop_exit.go @@ -81,7 +81,12 @@ func (e *eventLoop) handleExecExit(ep *event.Pair, execEv *types.ExecEvent) bool } func (e *eventLoop) handleNameExit(ep *event.Pair, nameEv *types.NameEvent) bool { + // File.Name() resolves to the "new" path (newname); surface the captured + // source path (oldname, at args[1] for the AT-variants) separately on the + // Pair so it reaches the output schema rather than living only in the + // TUI String() repr ("old:... ->new:..."). ep.File = file.NewOldnameNewname(nameEv.Oldname[:], nameEv.Newname[:]) + ep.Oldname = types.StringValue(nameEv.Oldname[:]) ep.Comm = e.comm(nameEv.GetTid()) return true } -- cgit v1.2.3