Repository navigation
feat: read title files from a read-only app0.zar (ZArchive) layer - #5835
Conversation
e56b48f to
20122a7
Compare
20122a7 to
129d9e2
Compare
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for this, the layering and the tests are careful. One blocking issue before merge:
- An archived file is a real null-device descriptor (
core/libs/prx/libkernel/File/src/ArchivedFile.cpp:23), and only read/seek/stat/FIONREAD/AIO/dup check for it. Every other descriptor call still runs on the null device:mmap_nid_postfix(DirectMemory/PosixMemory.cpp:92, takes the fd straight to the hostmmap),fchmod,fchown,futimes,flock,ftruncate,fsync/fdatasync(File/src/Stdio.cpp~288-311, 693, 736, 903, 913). They either succeed silently or fail with an unrelated errno, andfchmod/futimesact on the host's/dev/null. That contradicts "any call that does not read the archive throwsNotImplemented" in the description and the exact-or-throw rule (titles commonlymmaptheir assets). - Fix: for an archived descriptor these calls throw
NotImplemented(asfdopenalready does), and the debt line indocs/dev/debt/libkernel.mdlists them. Add a test inGuestKernelAppArchive.cppthat calls each one on an archived fd.
Also note: the Windows paths (NUL placeholder, linking zarchive into libc) are not exercised by the PR CI, so the full Build dispatch will be the evidence for them.
Thanks for the review now it should be fixed |
0de73b9 to
a9bb46d
Compare
a272b01 to
7456669
Compare
Build zstd v1.5.7 and ZArchive from source as static, position-independent libraries that are not part of the default target set. Their symbols stay out of the dynamic export table of the library that links them.
…lsewhere A ZArchive named app0.zar beside app0/ is a read-only layer under it. libc opens it at the first path resolution, looks paths missing from app0/ up case-insensitively, reads files across compressed blocks and keeps the archived descriptor table with shared positions. Resolving an archive-only path through a call that does not read the archive throws instead of failing with ENOENT, as do opendir of a directory present in both places, fdopen of an archived descriptor and chdir into the archive. A path through .. in an archive-only directory resolves.
sceKernelOpen and open give an archived file a read-only null-device descriptor. Reads, positioned, vectored and AIO reads, seeks, fstat and FIONREAD are served from the archive; dup, dup2 and F_DUPFD share the position. sceKernelStat and sceKernelCheckReachability see archived paths. Writing opens fail with EROFS, O_CREAT|O_EXCL with EEXIST and O_DIRECTORY on a file with ENOTDIR. Opening an archived directory or one merged with the disk throws until getdents can list it.
flock, fstatfs, ftruncate, fsync, fdatasync, getdirentries, fchmod, futimes and mmap on an archived descriptor acted on its null device and succeeded or failed with an unrelated errno. They now throw NotImplemented, each covered by the kernel archive test; mmap is noexcept, so its refusal is checked through the terminate handler.
7456669 to
d97d6ef
Compare
adriadam10
left a comment
There was a problem hiding this comment.
Rebased onto current main: the only real conflict was File/src/Stdio.cpp in TransferIovecs, where main added File::LockPositionedTransfer(d). Kept both, the archived read first and the lock after it. No other change to the PR. guest_app_archive* and guest_kernel_app_archive* pass on the rebased tree. Merging once the full Build (Windows) is green.
What
Closes #4848. Adds an opt-in, read-only
app0.zar(ZArchive) besideapp0/. A path missing fromapp0/is looked up in the archive case-insensitively; files on disk take precedence. Without an archive nothing changes.build: zstd v1.5.7 and ZArchive as submodules, built from source as static PIC libraries; their symbols are excluded from the.prxexport table on Linux.libc: archive reader, archived-descriptor table with shared positions, and a guard inResolvePath_nid_no_patch. Any call that does not read the archive throwsNotImplementedfor an archive-only path instead of returningENOENT.opendirof a directory present on disk and in the archive,fdopenof an archived descriptor andchdirinto the archive also throw...through an archive-only directory resolves.libkernel:sceKernelOpen/opengive an archived file a read-only null-device descriptor.read,pread,readv,preadvand AIO reads are served from the archive.lseek,fstatandFIONREADare served from the archive.dup,dup2andF_DUPFDshare the position.sceKernelStatandsceKernelCheckReachabilitysee archived paths.EROFS,O_CREAT|O_EXCLwithEEXIST, andO_DIRECTORYon a file withENOTDIR. Opening an archived or merged directory throws untilgetdentscan list it.fopen,access,mmap, record locks, directory listing) are recorded indocs/dev/debt/libc.mdandlibkernel.md; usage is indocs/user/USAGE.md.Tested
Linux x86-64, GCC, full build with
BUILD_TESTING=ON.guest_app_archive_{present,absent,damaged,invalid}andguest_kernel_app_archive_{archive,plain}. They cover:dup,F_DUPFDandclose, anddup2over an archived descriptor;stat/fstat, the error codes, the refusals, a damaged block and an invalid archive;sceKernelReadhook makes the kernel test fail.ctest: only environment failures (UDP/TCP sockets unavailable in the sandbox; shm EACCES check while running as root).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)