| Age | Commit message (Collapse) | Author |
|
variants
Extend the xattr scenario + integration test to exercise end-to-end the
xattr syscall variants that previously had no coverage (only setxattr and
the -at get/list/remove variants were tested). Classifications were already
verified correct by inspection; this is pure coverage hardening.
READ-classified variants (assert enter path/fd + bytes>=1):
- getxattr(path,name,...) READ, KindPathname@arg0 (ej0)
- lgetxattr(path,name,...) READ, KindPathname@arg0 (oj0)
- listxattr(path,...) READ, KindPathname@arg0 (rj0)
- llistxattr(path,...) READ, KindPathname@arg0 (rj0)
- fgetxattr(fd,...) READ, KindFd@arg0 (8i0)
- flistxattr(fd,...) READ, KindFd@arg0 (8i0)
UNCLASSIFIED variants (assert enter path/fd + bytes==0):
- lsetxattr(path,...) KindPathname@arg0 (cl0)
- setxattrat(dirfd,path,...) KindPathname@arg1 (vj0)
- removexattr(path,name) KindPathname@arg0 (kj0)
- lremovexattr(path,name) KindPathname@arg0 (kj0)
- fsetxattr(fd,...) KindFd@arg0 (8i0)
- fremovexattr(fd,...) KindFd@arg0 (8i0)
The l* GET/LIST/SET/REMOVE variants target a regular file (not a bare
symlink) so they fire deterministically: user.* xattrs on a symlink itself
are kernel-restricted (EPERM). setxattrat uses the raw syscall (nr 463,
Linux 6.13+) since Go does not export it; this kernel (7.0.9) supports it.
New scenarios use golang.org/x/sys/unix (raw syscalls, no glibc redirect)
so the exact tracepoints fire. New tests scope -trace-syscalls to exactly
the variant under test to avoid substring-match cross-contamination.
All 13 TestXattr* integration tests PASS under root (mage testWithName).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
removexattrat(2) (Linux 6.13+) was the one xattr *at-variant lacking
integration coverage: xattr_test.go exercised getxattrat/listxattrat
(READ-classified byte counts) and the path-based setxattr, but never the
REMOVE *at variant. Unlike its getxattrat/listxattrat siblings,
removexattrat returns a 0/-1 status (not a byte count), so its exit must
be UNCLASSIFIED — matching removexattr/lremovexattr/fremovexattr.
Add an ioworkload scenario (xattr-removexattrat) that setxattr's a
user.* attribute via a real path then removes it via raw
removexattrat(AT_FDCWD, path, 0, name), plus TestXattrRemovexattrat
asserting the path (args[1], after the dirfd) is captured (never the
xattr name at args[3]) and that accounted bytes are exactly zero
(guarding against wrongly READ-classifying it like getxattrat/
listxattrat). Distinct from the fd-based fremovexattr gap (task 8i0).
Classification verified by inspection: FamilyFS (xattr marker),
KindPathname at the pathname field (ctx->args[1]), and absent from the
ret-classification table => UNCLASSIFIED. No generator change needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
The xattr integration tests previously only asserted on getxattrat/
listxattrat (path/dirfd READ-classified variants). The path-based
setxattr(2) was traced by the existing xattr-getxattrat scenario
(workload calls syscall.Setxattr; xattrTraceArgs includes setxattr) but
never asserted. Add TestXattrSetxattr to verify end-to-end that:
- enter_setxattr captures the filesystem PATH at args[0] (kind=pathname),
never the xattr NAME at args[1];
- exit_setxattr is UNCLASSIFIED: setxattr returns a 0/-1 status, not a
byte count (the size arg is the INPUT value length), so accounted
bytes must be exactly zero. This guards against the msgsnd-style bug
of treating a status return as bytes written, and contrasts with
getxattr/listxattr which DO return byte counts (READ-classified).
This is the PATH-based set complement to filed task 8i0 (fd-based
fsetxattr/fgetxattr/flistxattr/fremovexattr); it does not duplicate it.
Classification (FamilyFS, KindPathname enter, UNCLASSIFIED ret) is
verified by inspection per task guidance, not by a unit test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
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>
|
|
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>
|