On Thu, Feb 13, 2025 at 11:13:07PM +0100, Thomas Klausner wrote: > and versioned the statvfs syscall. I'm not sure how the syscall > compatibility works, but rust's libc crate still has the old > definition of the struct
Where is that struct definition? It seems to be wrong somehow. I tried your program on a powerpc machine and get: Breakpoint 3, rust_getmntinfo::get_mount_points () at src/main.rs:20 20 let mut fs_infos: *mut libc::statvfs = std::ptr::null_mut(); (gdb) n 21 let count = unsafe { libc::getmntinfo(&mut fs_infos, libc::MNT_WAIT) }; (gdb) 22 if count < 1 { (gdb) p count $1 = 7 (gdb) p fs_infos[0] $3 = libc::unix::bsd::netbsdlike::netbsd::statvfs {f_flag: 86016, f_bsize: 4096, f_frsize: 32768, f_iosize: 116136549, f_blocks: 481244119186087439, f_bfree: 124951791354018455, f_bavail: 184717953468299, f_bresvd: 20480, f_files: 52110838204711, f_ffree: 1717990144, f_favail: 0, f_fresvd: 788529152, f_syncreads: 0, f_syncwrites: 0, f_asyncreads: 0, f_asyncwrites: 0, f_fsidx: libc::unix::bsd::fsid_t {__fsid_val: [0, 0]}, f_fsid: 0, f_namemax: 0, f_owner: 0, f_spare: [0, 0, 0, 0], f_fstypename: [ 0 <repeats 18 times>, 47, 100, 101, 118, 47, 100, 107, 48, 0, 0, 0, 0, 0, 0], f_mntonname: [ 0 <repeats 77 times>, 7, 16, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0 <repeats 18 times>, 139, 1, 0, 1, 210, 139, 0, 0, 0, 0, 0, 0, 16, 0 <repeats 13 times>, 107, 101, 114, 110, 102, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 107, 101, 114, 110, 0 <repeats 85 times>, 107, 101, 114, 110, 102, 115, 0 <repeats 86 times>, 16, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0 <repeats 18 times>, 123, 2, 0, 0, 107, 123, 0, 0, 0, 0, 0, 0, 16, 0 <repeats 13 times>, 112, 116, 121, 102, 115, 0 <repeats 11 times>, 47, 100, 101, 118, 47, 112, 116, 115, 0 <repeats 82 times>, 112, 116, 121, 102, 115, 0 <repeats 87 times>...], f_mntfromname: [0 <repeats 77 times>, 2, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 127, 255, 255, 255, 127, 255, 255, 255, 96, 61, 106, 120, 21, 103, 253, 254, 21, 86, 181, 164, 0, 0, 11, 5, 0, 0, 7, 11, 0 <repeats 20 times>, 110, 102, 115, 0 <repeats 13 times>, 47, 109, 112, 51, 0 <repeats 86 times>, 101, 109, 109, 97, 115, 58, 47, 110, 111, 114, 97, 105, 100, 47, 109, 112, 51, 0 <repeats 74 times>, 2, 0, 0, 0, 0, 2, 0, 0, 0, 32, 0, 127, 255, 255, 255, 127, 255, 255, 255, 96, 61, 106, 120, 21, 103, 253, 254, 21, 86, 181, 164, 0, 0, 11, 6, 0, 0, 7, 11, 0 <repeats 20 times>, 110, 102, 115, 0 <repeats 13 times>, 47, 109, 110, 116, 0 <repeats 86 times>, 101, 109, 109, 97, 115, 58, 47, 110, 101, 108, 108...]} (gdb) p sizeof(fs_infos[0].f_flag) $5 = 4 Compare with: > df -G / / (/dev/dk0 ): 32768 block size 4096 frag size 116136549 total blocks 112048377 free blocks 106241550 available 29092606 total files 28605079 free files a800 filesys id ffs fstype 0x5000 flag 255 filename length 0 owner 12151 syncwrites 2684 asyncwrites Nearly all fields are wrong or swapped with others (like f_bsize <-> f_frsize) and the f_mntonname field starts 18 bytes early (mountname should be /dev/dk0, aka 47, 100, 101, 118, 47, 100, 107, 48, 0) It would be good to compare with a C version calling __getvfsstat90 explicitly (e.g. via syscall()) or a static binary with debug info compiled on netbsd-9, so we can find out if the error is in the compat code or the C structure mapping in rust. The kernel compat part works by calling do_sys_getvfsstat() with entry_sz = sizeof (struct statvfs) and copyfn = copyout. This just copies mnt_stat from each mountpoint out to userland (in the not-chrooted case). I see no kind of translation happen anywhere here. Martin