summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-31 19:09:16 +0300
committerPaul Buetow <paul@buetow.org>2026-05-31 19:09:16 +0300
commit8a1bf6236f6a525881c647fd881093b393436411 (patch)
tree0fb537b847b6e5c72d2d3d98d7ce8fbc15330102 /internal
parentc3177bd82c16429c1bb246d19af76012479f0c01 (diff)
listxattrat: READ-classify return for xattr-list family consistency
listxattrat(2) (Linux 6.13+) returns the size in bytes of the list of extended attribute names, exactly like listxattr/llistxattr/flistxattr, 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). This mirrors the getxattrat fix (task ku, commit c3177bd) and completes xattr-family consistency: get-family and list-family are READ_CLASSIFIED while set-family and remove-family stay UNCLASSIFIED (they return 0/-1). Update the docs ReadClassified list and the retclassify expectation, and add an ioworkload scenario plus integration test: the workload sets a user xattr then lists names via the raw listxattrat(2) syscall with AT_FDCWD, and the test asserts enter_listxattrat captures the file path and accounts the returned name-list size as read bytes. Task: r20 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'internal')
-rw-r--r--internal/c/generated_tracepoints.c4
-rw-r--r--internal/c/generated_tracepoints_result.txt2
-rw-r--r--internal/generate/classify.go4
-rw-r--r--internal/generate/retclassify_test.go6
4 files changed, 12 insertions, 4 deletions
diff --git a/internal/c/generated_tracepoints.c b/internal/c/generated_tracepoints.c
index 8c76e7a..64d40db 100644
--- a/internal/c/generated_tracepoints.c
+++ b/internal/c/generated_tracepoints.c
@@ -6579,7 +6579,7 @@ int handle_sys_enter_listxattrat(struct syscall_trace_enter *ctx) {
return 0;
}
-/// sys_exit_listxattrat is a struct ret_event (UNCLASSIFIED) (kind=ret)
+/// sys_exit_listxattrat is a struct ret_event (READ_CLASSIFIED) (kind=ret)
SEC("tracepoint/syscalls/sys_exit_listxattrat")
int handle_sys_exit_listxattrat(struct syscall_trace_exit *ctx) {
__u32 pid, tid;
@@ -6599,7 +6599,7 @@ int handle_sys_exit_listxattrat(struct syscall_trace_exit *ctx) {
ev->tid = tid;
ev->time = bpf_ktime_get_boot_ns();
ev->ret = ctx->ret;
- ev->ret_type = UNCLASSIFIED;
+ ev->ret_type = READ_CLASSIFIED;
bpf_ringbuf_submit(ev, 0);
return 0;
diff --git a/internal/c/generated_tracepoints_result.txt b/internal/c/generated_tracepoints_result.txt
index 0842bda..e6cb4d3 100644
--- a/internal/c/generated_tracepoints_result.txt
+++ b/internal/c/generated_tracepoints_result.txt
@@ -510,7 +510,7 @@ sys_exit_listen is a struct ret_event (UNCLASSIFIED) (kind=ret)
sys_exit_listmount is a struct ret_event (UNCLASSIFIED) (kind=ret)
sys_exit_listns is a struct ret_event (UNCLASSIFIED) (kind=ret)
sys_exit_listxattr is a struct ret_event (READ_CLASSIFIED) (kind=ret)
-sys_exit_listxattrat is a struct ret_event (UNCLASSIFIED) (kind=ret)
+sys_exit_listxattrat is a struct ret_event (READ_CLASSIFIED) (kind=ret)
sys_exit_llistxattr is a struct ret_event (READ_CLASSIFIED) (kind=ret)
sys_exit_lremovexattr is a struct ret_event (UNCLASSIFIED) (kind=ret)
sys_exit_lseek is a struct ret_event (UNCLASSIFIED) (kind=ret)
diff --git a/internal/generate/classify.go b/internal/generate/classify.go
index 3746bd9..0735291 100644
--- a/internal/generate/classify.go
+++ b/internal/generate/classify.go
@@ -593,6 +593,10 @@ var retClassifications = map[string]RetClassification{
"getxattrat": ReadClassified,
"lgetxattr": ReadClassified,
"listxattr": ReadClassified,
+ // listxattrat (Linux 6.13+) returns the size in bytes of the list of
+ // extended attribute names, exactly like listxattr/llistxattr/flistxattr,
+ // so it is a read byte-count.
+ "listxattrat": ReadClassified,
"llistxattr": ReadClassified,
"pread64": ReadClassified,
"preadv": ReadClassified,
diff --git a/internal/generate/retclassify_test.go b/internal/generate/retclassify_test.go
index acd019b..4fc7501 100644
--- a/internal/generate/retclassify_test.go
+++ b/internal/generate/retclassify_test.go
@@ -8,7 +8,11 @@ func TestClassifyRetRead(t *testing.T) {
// getxattrat (Linux 6.13+) returns the xattr value size in bytes, the
// same read byte-count as getxattr/lgetxattr/fgetxattr.
"getxattrat",
- "lgetxattr", "listxattr", "llistxattr", "pread64", "preadv",
+ "lgetxattr", "listxattr",
+ // listxattrat (Linux 6.13+) returns the size in bytes of the xattr
+ // name list, the same read byte-count as listxattr/llistxattr/flistxattr.
+ "listxattrat",
+ "llistxattr", "pread64", "preadv",
"preadv2", "process_vm_readv", "read", "readlink", "readlinkat",
"readv", "recvmsg", "recvfrom", "syslog", "mq_timedreceive", "getrandom", "msgrcv",
}