Repository navigation
virtio-blk: add sync option to select libkrun's sync mode - #117
Conversation
krun_add_disk2 picks the flush behavior itself, and on macOS that is KRUN_SYNC_RELAXED: guest flushes become fsync(2), which does not ask the drive to flush its buffers. Expose krun_add_disk3's sync_mode as sync=none|relaxed|full; without the option krunkit keeps calling krun_add_disk2, so the default is unchanged. Signed-off-by: Jun Ryoung Ju <junryoungju@gmail.com>
|
Ran into what looks like the failure this is about. A Mac mini (M4, macOS 26.5.1) running krunkit 1.3.2 / libkrun 1.19.6 with no As far as I understand raft, the commit index in a heartbeat is capped at what that follower has acknowledged, and etcd acknowledges entries only after fsyncing its WAL. So it looks like ~89 entries the guest had already flushed didn't make it through the host power loss. etcd had no unsafe-no-fsync and the guest disk reports Not 100% sure nothing else played a part, but it lines up with the fsync(2) note above. I haven't repeated the same pull with |
|
I've unplugged my mac mini while running etcd for 3 or 4 times. looks like the |
krunkit adds every disk with
krun_add_disk2, which leaves the flush behavior to libkrun. In libkrun 1.19.6 that call hardcodes the sync mode per platform:SyncMode::Fullon Linux,SyncMode::Relaxedon macOS (src/libkrun/src/lib.rs,krun_add_disk2). WithRelaxed, a guestVIRTIO_BLK_T_FLUSHends in imago'sFile::sync, which callsfsync(2)rather thanfcntl(F_FULLFSYNC)whenrelaxed_syncis set.On macOS that distinction matters. From
fsync(2):So a flush the guest sees complete (an ext4 journal commit, a database fsync) is not guaranteed to survive a host power loss, and ordering between flushed writes is not guaranteed either. The virtio 1.2 spec (5.2.6.2) asks a device backed by persistent storage to commit stable writes before reporting the flush complete.
libkrun already lets the caller choose:
krun_add_disk3(..., direct_io, sync_mode)withKRUN_SYNC_NONE,KRUN_SYNC_RELAXEDandKRUN_SYNC_FULL. krunkit has no way to reach it.Change
virtio-blkaccepts an optionalsync=none|relaxed|full.sync=, krunkit keeps callingkrun_add_disk2, so the default is unchanged.sync=, krunkit callskrun_add_disk3withread_only=falseanddirect_io=false(whatkrun_add_disk2uses) and the chosen mode.docs/usage.mddocuments the option;cmdline.rstests cover parsing and the unset case.Testing
cargo fmt -- --check,cargo clippy --target aarch64-apple-darwin -- -D warningsandcargo test --releasepass (37 tests).To check what reaches the host, I booted the same Ubuntu 24.04 arm64 disk image three times, each from a fresh APFS clone, with the patched krunkit and no network device, and traced krunkit with
fs_usage -w -f filesysfor 30 seconds, counting calls on the disk image's file descriptor. Mac mini (Mac16,10, M4), macOS 26.5.1, libkrun 1.19.6 (Homebrew bottle from the slp/krun tap).virtio-blkargumentfsyncfcntl(F_FULLFSYNC)sync=)sync=relaxedsync=fullThe counts differ between runs because boot progress within the 30-second window varies; what changes with the option is which call the guest's flushes become. I have not measured the throughput cost of
sync=fullbeyond boot time, and I have not reproduced data loss on power loss; the change rests on the documented semantics above.Whether
fullshould become the default on macOS is left to you; this PR only makes it selectable.