Environment
- msb v0.7.2 (
msb update reports latest), libkrunfw bundled
- Windows 11 Pro 10.0.26100, x86_64, physical machine (Lenovo), Windows Hypervisor Platform
msb doctor: clean (only warning: no reflink on MSB_HOME)
- Guest image:
alpine
Repro
mkdir C:\spike\trace2
msb create alpine --name trace2 --mount-dir C:\spike\trace2:/w
msb exec trace2 -- sh -c "cd /w; echo a > f; cat f; mv f h; echo rc=`$?; cat h; ls -la"
Expected: a, rc=0, a, then a listing containing h.
Actual:
a
rc=0
cat: can't open 'h': I/O error
total 0
- Creating and reading a file works. Any rename breaks it: to a new name, over an existing file (
mv -f), and directory renames (mv d1 d2; cat d2/in gives Invalid argument).
- After the rename, the whole directory lists as empty (
total 0), not just the renamed entry.
- The error persists after
echo 3 > /proc/sys/vm/drop_caches in the guest and in a new msb exec session.
msb stop + msb start fixes it: the file is then readable and listed correctly.
- A second sandbox mounting the same folder sees the correct state.
Host side is intact. After the failing rename, on Windows:
h exists with the correct content, and f is gone.
- The
msb.override_stat ADS moved with the file (20 bytes).
- An exclusive
[IO.File]::Open(h, 'Open', 'ReadWrite', 'None') succeeds, so no process holds a handle on it.
- Defender real-time protection is off, so AV interference is ruled out.
So the state that goes wrong appears to be the backend's in-memory inode state, not the host file or the guest's caches.
Tried every mount option: stat-virt=strict, relaxed and off, plus host-perms=mirror,uid=1000,gid=1000. All fail the same way.
Impact: git cannot work on a Windows bind mount, because it writes a lock file and renames it over the original. git init and git clone fail with:
warning: unable to access '/workspace/gitrepo/.git/config': I/O error
fatal: unknown error occurred while reading the configuration files
The same commands work on the guest's own rootfs.
Possibly relevant code (v0.7.2), from reading the source rather than debugging, so these are leads, not a confirmed cause:
passthroughfs/windows/ops.rs:180 (rename) → remove_ops.rs:99 (rename_inode_path). Every later op resolves files through the cached InodeData.path, so a stale entry here would produce exactly this "broken until restart" behaviour.
remove_ops.rs:110: cached descendants of a renamed directory are only re-pathed when owned_checkpoint is set. That fits the mv d1 d2; cat d2/in failure on a plain bind mount.
dir_ops.rs:88-110: dir_entries returns early on the first failing child, which would explain one broken entry making the whole directory appear empty.
mod.rs:726 (host_error): unmapped Windows errors become EIO, which hides the underlying Windows error. Logging the raw error there would probably pinpoint this quickly.
- The existing
heartbeat_style_rename_keeps_source_inode_usable test renames host-created files using the fs_for config. The runtime builds bind mounts differently (runner/vm.rs:2290: external_checkpoint: Some(..), no_symlink_root: true), and the failing case here is a guest-created file.
Possibly related: #1559 (hard links on bind mounts). Hard links also fail on this host (ln g hard → I/O error), and symlinks created in the guest show up as 1-byte regular files on the Windows side.
Environment
msb updatereports latest), libkrunfw bundledmsb doctor: clean (only warning: no reflink on MSB_HOME)alpineRepro
Expected:
a,rc=0,a, then a listing containingh.Actual:
mv -f), and directory renames (mv d1 d2; cat d2/ingivesInvalid argument).total 0), not just the renamed entry.echo 3 > /proc/sys/vm/drop_cachesin the guest and in a newmsb execsession.msb stop+msb startfixes it: the file is then readable and listed correctly.Host side is intact. After the failing rename, on Windows:
hexists with the correct content, andfis gone.msb.override_statADS moved with the file (20 bytes).[IO.File]::Open(h, 'Open', 'ReadWrite', 'None')succeeds, so no process holds a handle on it.So the state that goes wrong appears to be the backend's in-memory inode state, not the host file or the guest's caches.
Tried every mount option:
stat-virt=strict,relaxedandoff, plushost-perms=mirror,uid=1000,gid=1000. All fail the same way.Impact: git cannot work on a Windows bind mount, because it writes a lock file and renames it over the original.
git initandgit clonefail with:The same commands work on the guest's own rootfs.
Possibly relevant code (v0.7.2), from reading the source rather than debugging, so these are leads, not a confirmed cause:
passthroughfs/windows/ops.rs:180(rename) →remove_ops.rs:99(rename_inode_path). Every later op resolves files through the cachedInodeData.path, so a stale entry here would produce exactly this "broken until restart" behaviour.remove_ops.rs:110: cached descendants of a renamed directory are only re-pathed whenowned_checkpointis set. That fits themv d1 d2; cat d2/infailure on a plain bind mount.dir_ops.rs:88-110:dir_entriesreturns early on the first failing child, which would explain one broken entry making the whole directory appear empty.mod.rs:726(host_error): unmapped Windows errors becomeEIO, which hides the underlying Windows error. Logging the raw error there would probably pinpoint this quickly.heartbeat_style_rename_keeps_source_inode_usabletest renames host-created files using thefs_forconfig. The runtime builds bind mounts differently (runner/vm.rs:2290:external_checkpoint: Some(..),no_symlink_root: true), and the failing case here is a guest-created file.Possibly related: #1559 (hard links on bind mounts). Hard links also fail on this host (
ln g hard→I/O error), and symlinks created in the guest show up as 1-byte regular files on the Windows side.