1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
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"}
// xattrListTraceArgs restricts tracing to the listxattrat tracepoints so the
// test is not perturbed by unrelated xattr/open traffic.
var xattrListTraceArgs = []string{"-trace-syscalls", "listxattrat,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)
}
// TestXattrListxattrat verifies ior traces listxattrat(2) (Linux 6.13+)
// end-to-end. listxattrat takes a dirfd plus a real filesystem path at args[1]
// (NOT args[0]=dfd); only the path must be captured. The path is read on
// syscall entry, so enter_listxattrat must carry the file path "xattrfile.txt".
func TestXattrListxattrat(t *testing.T) {
result, _ := runScenarioResultWithIorArgs(t, "xattr-listxattrat", []ExpectedEvent{
{
PathContains: "xattrfile.txt",
Tracepoint: "enter_listxattrat",
Comm: "ioworkload",
MinCount: 1,
},
}, xattrListTraceArgs)
// listxattrat returns the size in bytes of the xattr name list; ior
// READ-classifies the exit, so the recorded byte count must reflect at least
// the NUL-terminated "user.ior" name set by the workload (consistent with
// listxattr/llistxattr/flistxattr).
exp := ExpectedEvent{Tracepoint: "enter_listxattrat", Comm: "ioworkload"}
assertEventBytesAtLeast(t, result, exp, uint64(len("user.ior")+1))
assertEventDurationPositive(t, result, exp)
}
|