summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/generate/classify_test.go55
-rw-r--r--internal/generate/family_test.go12
2 files changed, 67 insertions, 0 deletions
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go
index 41e1bf8..92b6e58 100644
--- a/internal/generate/classify_test.go
+++ b/internal/generate/classify_test.go
@@ -368,6 +368,61 @@ func TestClassifyExitSyncfs(t *testing.T) {
}
}
+// TestClassifyFallocateEnterFd locks in that the fallocate enter tracepoint is
+// classified as KindFd with the fd captured at args[0].
+//
+// int fallocate(int fd, int mode, off_t offset, off_t len)
+//
+// fallocate(2) manipulates the allocated disk space for the file referred to
+// by fd (args[0]); the remaining mode/offset/len args are NOT captured, exactly
+// like its fd-based siblings fadvise64(2)/ftruncate(2)/sync_file_range(2) which
+// also carry trailing offset/len/advice args but only record args[0]. The
+// leading "fd" external field must select KindFd so the generated
+// handle_sys_enter_fallocate emits ev->fd = ctx->args[0] into a fd_event.
+func TestClassifyFallocateEnterFd(t *testing.T) {
+ f := &Format{
+ Name: "sys_enter_fallocate",
+ ExternalFields: []Field{
+ {Type: "long", Name: "__syscall_nr"},
+ {Type: "int", Name: "fd"},
+ {Type: "int", Name: "mode"},
+ {Type: "loff_t", Name: "offset"},
+ {Type: "loff_t", Name: "len"},
+ },
+ }
+ r := ClassifyFormat(f)
+ if r.Kind != KindFd {
+ t.Fatalf("enter_fallocate: got kind %d, want KindFd", r.Kind)
+ }
+ // fd is the first real argument (args[0]); FieldNumber skips __syscall_nr.
+ if got := f.FieldNumber("fd"); got != 0 {
+ t.Errorf("enter_fallocate: fd field number = %d, want 0 (args[0])", got)
+ }
+}
+
+// TestClassifyExitFallocateUnclassifiedRet locks in that the fallocate exit
+// tracepoint is classified as KindRet and Unclassified. fallocate(2) returns
+// int (0 on success, -1 on error) — that return is a status code, NOT a
+// transferred byte count, so its exit format carries a single "ret" field and
+// must map to a plain ret_event (KindRet) whose ret_type stays UNCLASSIFIED.
+// Misclassifying it as a READ/WRITE/TRANSFER byte count would be a real bug,
+// since fallocate allocates space but reports no transferred bytes.
+func TestClassifyExitFallocateUnclassifiedRet(t *testing.T) {
+ r := ClassifyFormat(&Format{
+ Name: "sys_exit_fallocate",
+ ExternalFields: []Field{
+ {Type: "long", Name: "__syscall_nr"},
+ {Type: "long", Name: "ret"},
+ },
+ })
+ if r.Kind != KindRet {
+ t.Fatalf("exit_fallocate: got kind %d, want KindRet", r.Kind)
+ }
+ if got := ClassifyRet("sys_exit_fallocate"); got != Unclassified {
+ t.Errorf("ClassifyRet(sys_exit_fallocate) = %q, want UNCLASSIFIED", got)
+ }
+}
+
// TestClassifyExitGetpeername locks in that the getpeername exit tracepoint is
// classified as KindRet. getpeername(2) returns int (0 on success, -1 on
// error), so its exit format carries a single "ret" field and must map to a
diff --git a/internal/generate/family_test.go b/internal/generate/family_test.go
index 827e592..af40e7d 100644
--- a/internal/generate/family_test.go
+++ b/internal/generate/family_test.go
@@ -86,6 +86,18 @@ func TestClassifySyscallFamily(t *testing.T) {
{"sys_enter_fsync", FamilyFS},
{"sys_enter_fdatasync", FamilyFS},
{"sys_enter_sync_file_range", FamilyFS},
+ // fallocate(2) manipulates the allocated disk space (preallocate,
+ // punch-hole, collapse, zero, insert) for the file referred to by its
+ // args[0] fd; it is a per-file space-management syscall and shares
+ // FamilyFS with its fd-based siblings fadvise64(2) (access-pattern
+ // advice), ftruncate(2) (resize by fd), and sync_file_range(2) (flush a
+ // byte range). Assert the group so a stray reclassification of any one
+ // trips this test. Keep in sync with the FS list in
+ // docs/syscall-tracing-plan.md.
+ {"sys_enter_fallocate", FamilyFS},
+ {"sys_exit_fallocate", FamilyFS},
+ {"sys_enter_fadvise64", FamilyFS},
+ {"sys_enter_ftruncate", FamilyFS},
{"sys_enter_epoll_wait", FamilyPolling},
{"sys_enter_io_uring_enter", FamilyAIO},
{"sys_enter_bpf", FamilySecurity},