summaryrefslogtreecommitdiff
path: root/integrationtests
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-31 19:04:44 +0300
committerPaul Buetow <paul@buetow.org>2026-05-31 19:04:44 +0300
commitc3177bd82c16429c1bb246d19af76012479f0c01 (patch)
treef71fc68ce009295690a723b49881eed74bae0c48 /integrationtests
parentc6a89452bd6872a380d4ce0dc9ec35ea0c66ef9e (diff)
getxattrat: READ-classify return for xattr-get family consistency
getxattrat(2) (Linux 6.13+) returns the xattr value size in bytes, exactly like getxattr/lgetxattr/fgetxattr, but its exit was classified UNCLASSIFIED, so its read bytes were dropped from I/O totals. Classify it as ReadClassified and regenerate the BPF handler (ret_type now READ_CLASSIFIED). Path extraction (args[1], after the dirfd) and the name-not-captured-as-path behaviour were already correct. Update the docs ReadClassified list and the retclassify expectation, and add the first xattr integration coverage: an ioworkload scenario that sets then getxattrat-reads a user xattr on tmpfs, plus a test that asserts enter_getxattrat captures the file path (not the xattr name) and accounts the returned value size as read bytes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'integrationtests')
-rw-r--r--integrationtests/xattr_test.go37
1 files changed, 37 insertions, 0 deletions
diff --git a/integrationtests/xattr_test.go b/integrationtests/xattr_test.go
new file mode 100644
index 0000000..d36043c
--- /dev/null
+++ b/integrationtests/xattr_test.go
@@ -0,0 +1,37 @@
+package integrationtests
+
+import "testing"
+
+// xattrTraceArgs restricts tracing to the getxattrat tracepoints so the test is
+// not perturbed by unrelated xattr/open traffic.
+var xattrTraceArgs = []string{"-trace-syscalls", "getxattrat,setxattr,openat"}
+
+// TestXattrGetxattrat verifies ior traces getxattrat(2) (Linux 6.13+)
+// end-to-end. getxattrat takes a dirfd plus a real filesystem path at args[1]
+// (NOT args[0]=dfd) and an xattr NAME at args[3]; only the path must be
+// captured. The path is read on syscall entry, so enter_getxattrat must carry
+// the file path "xattrfile.txt" and never the xattr name "user.ior".
+func TestXattrGetxattrat(t *testing.T) {
+ result, _ := runScenarioResultWithIorArgs(t, "xattr-getxattrat", []ExpectedEvent{
+ {
+ PathContains: "xattrfile.txt",
+ Tracepoint: "enter_getxattrat",
+ Comm: "ioworkload",
+ MinCount: 1,
+ },
+ }, xattrTraceArgs)
+
+ // The captured path must be the filesystem path, never the xattr name.
+ for _, rec := range result.Records {
+ if rec.TraceID.String() == "enter_getxattrat" && rec.Path == "user.ior" {
+ t.Errorf("getxattrat captured xattr name %q as path instead of file path", rec.Path)
+ }
+ }
+
+ // getxattrat returns the xattr value size in bytes; ior READ-classifies the
+ // exit, so the recorded byte count must reflect the 16-byte value written by
+ // the workload (consistent with getxattr/lgetxattr/fgetxattr).
+ exp := ExpectedEvent{Tracepoint: "enter_getxattrat", Comm: "ioworkload"}
+ assertEventBytesAtLeast(t, result, exp, uint64(len("getxattrat-value")))
+ assertEventDurationPositive(t, result, exp)
+}