fix: persistence.dat Method B now uses docker-desktop WSL for ext4 formatting
Previously, when no standard WSL distro was available, Method B only created an empty sparse file without ext4 formatting. This caused Ventoy to fail mounting persistence.dat on boot, dropping to initramfs. Now Method B tries docker-desktop WSL (/sbin/mkfs.ext4) before falling back to raw file. Also added ext4 magic number (0xEF53) verification step. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
19
HANDOFF.md
19
HANDOFF.md
@@ -56,3 +56,22 @@
|
||||
- Live USB 每次重启后,除了持久化分区内的数据,其他都会重置
|
||||
- SSH server 需要每次重启后重新安装(除非持久化生效)
|
||||
- 持久化生效后,apt 安装的包会保留
|
||||
|
||||
## 2026-03-17 修复:persistence.dat 未格式化导致启动失败
|
||||
|
||||
### 问题
|
||||
- U 盘上的 `persistence.dat`(20GB)是空文件,没有 ext4 文件系统
|
||||
- `3-create-persistence.ps1` 因无可用标准 WSL,走了 Method B,只创建了稀疏空文件
|
||||
- Ventoy 启动 Ubuntu → 读 ventoy.json → 尝试挂载空的 persistence.dat → mount 失败 → 卡在 initramfs
|
||||
|
||||
### 修复过程
|
||||
1. 用 docker-desktop WSL 的 `/sbin/mkfs.ext4` 格式化:
|
||||
- 在 WSL 内创建稀疏文件:`dd if=/dev/zero of=/tmp/persistence.dat bs=1M count=0 seek=20480`
|
||||
- 格式化:`/sbin/mkfs.ext4 -F -L casper-rw /tmp/persistence.dat`
|
||||
- 复制到 C: → 移动到 E:(因为 docker-desktop WSL 无法直接访问 E: 盘)
|
||||
2. 验证:offset 1080 处读到 `53 EF`(little-endian `0xEF53`),确认 ext4 有效
|
||||
|
||||
### 代码改进
|
||||
- `3-create-persistence.ps1` Method B 现在会尝试 docker-desktop WSL 格式化
|
||||
- 添加了 ext4 magic number 验证步骤
|
||||
- 只有在完全没有任何 WSL 时才降级为未格式化的空文件
|
||||
|
||||
@@ -93,12 +93,8 @@ if ($wslDistro) {
|
||||
}
|
||||
|
||||
} else {
|
||||
# ── Method B: Create raw file with PowerShell, format in Linux later ──
|
||||
Write-Host "[INFO] No usable WSL distro (only docker-desktop found or none)." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host " Will create a raw persistence image file." -ForegroundColor White
|
||||
Write-Host " It will be formatted automatically on first Linux boot." -ForegroundColor White
|
||||
Write-Host ""
|
||||
# ── Method B: Try docker-desktop WSL, fallback to raw file ──
|
||||
Write-Host "[INFO] No standard WSL distro found." -ForegroundColor Yellow
|
||||
|
||||
$sizeInput = Read-Host "Persistence size in GB (default: $DefaultSizeGB for 32GB USB)"
|
||||
if ([string]::IsNullOrWhiteSpace($sizeInput)) {
|
||||
@@ -113,20 +109,67 @@ if ($wslDistro) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "[INFO] Creating ${sizeGB} GB sparse file (fast, only allocates on write)..." -ForegroundColor Yellow
|
||||
$sizeMB = $sizeGB * 1024
|
||||
$formatted = $false
|
||||
|
||||
# Create sparse file using .NET (instant, doesn't write zeros)
|
||||
# Try docker-desktop WSL (has /sbin/mkfs.ext4)
|
||||
$dockerWSL = $null
|
||||
try {
|
||||
$allDistros = (wsl --list --quiet 2>$null) -replace "`0","" | Where-Object { $_.Trim() -ne "" -and $_ -match "docker" }
|
||||
foreach ($d in $allDistros) {
|
||||
$d = $d.Trim()
|
||||
if ($d) {
|
||||
$testResult = wsl -d $d -- /sbin/mkfs.ext4 -V 2>&1
|
||||
if ($LASTEXITCODE -eq 0 -or "$testResult" -match "mke2fs") {
|
||||
$dockerWSL = $d
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if ($dockerWSL) {
|
||||
Write-Host "[INFO] Found docker-desktop WSL with mkfs.ext4, creating ext4 image..." -ForegroundColor Green
|
||||
$tmpFile = "/tmp/uclaw_persistence.dat"
|
||||
|
||||
# Create sparse file and format in docker-desktop WSL
|
||||
wsl -d $dockerWSL -- dd if=/dev/zero of=$tmpFile bs=1M count=0 seek=$sizeMB 2>$null
|
||||
wsl -d $dockerWSL -- /sbin/mkfs.ext4 -F -L casper-rw $tmpFile 2>$null
|
||||
|
||||
# Copy out via /mnt/host/c/ (docker-desktop mounts C: there)
|
||||
$tmpHostPath = "C:\uclaw_persistence_tmp.dat"
|
||||
wsl -d $dockerWSL -- cp $tmpFile /mnt/host/c/uclaw_persistence_tmp.dat 2>$null
|
||||
|
||||
if (Test-Path $tmpHostPath) {
|
||||
Move-Item -Path $tmpHostPath -Destination $PersistencePath -Force
|
||||
wsl -d $dockerWSL -- rm -f $tmpFile 2>$null
|
||||
$formatted = $true
|
||||
Write-Host "[OK] ext4 image created via docker-desktop WSL." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[WARN] docker-desktop copy failed, falling back to raw file." -ForegroundColor Yellow
|
||||
wsl -d $dockerWSL -- rm -f $tmpFile 2>$null
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $formatted) {
|
||||
# Fallback: create raw sparse file
|
||||
Write-Host "[INFO] Creating ${sizeGB} GB sparse file (needs manual format in Linux)..." -ForegroundColor Yellow
|
||||
$sizeBytes = [int64]$sizeGB * 1024 * 1024 * 1024
|
||||
$fs = [System.IO.File]::Create($PersistencePath)
|
||||
$fs.SetLength($sizeBytes)
|
||||
$fs.Close()
|
||||
}
|
||||
|
||||
if (Test-Path $PersistencePath) {
|
||||
Write-Host "[OK] Created ${sizeGB} GB persistence file." -ForegroundColor Green
|
||||
$actualSize = [math]::Round((Get-Item $PersistencePath).Length / 1GB, 1)
|
||||
Write-Host "[OK] Created ${actualSize} GB persistence file." -ForegroundColor Green
|
||||
if (-not $formatted) {
|
||||
Write-Host ""
|
||||
Write-Host " IMPORTANT: After first boot into Linux, run this to format it:" -ForegroundColor Yellow
|
||||
Write-Host " IMPORTANT: File is NOT yet formatted as ext4!" -ForegroundColor Yellow
|
||||
Write-Host " After first boot into Linux, run:" -ForegroundColor Yellow
|
||||
Write-Host ' sudo mkfs.ext4 -F -L casper-rw /media/*/Ventoy/persistence.dat' -ForegroundColor White
|
||||
Write-Host ' Then reboot for persistence to take effect.' -ForegroundColor White
|
||||
}
|
||||
} else {
|
||||
Write-Host "[ERROR] Failed to create persistence file." -ForegroundColor Red
|
||||
Read-Host "Press Enter to exit"
|
||||
@@ -134,6 +177,26 @@ if ($wslDistro) {
|
||||
}
|
||||
}
|
||||
|
||||
# ── Verify ext4 magic number ──
|
||||
if (Test-Path $PersistencePath) {
|
||||
try {
|
||||
$f = [System.IO.File]::OpenRead($PersistencePath)
|
||||
$f.Seek(1080, 0) | Out-Null
|
||||
$buf = New-Object byte[] 2
|
||||
$f.Read($buf, 0, 2) | Out-Null
|
||||
$f.Close()
|
||||
$magic = "{0:X2}{1:X2}" -f $buf[0], $buf[1]
|
||||
if ($magic -eq "53EF") {
|
||||
Write-Host "[OK] ext4 verified (magic: 0xEF53)." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "[WARN] NOT a valid ext4 filesystem (magic: 0x$magic)." -ForegroundColor Yellow
|
||||
Write-Host " You must format it in Linux before persistence will work." -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "[WARN] Could not verify ext4 magic number." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "[OK] Step 3 complete! Persistence image created." -ForegroundColor Green
|
||||
Write-Host " Path: $PersistencePath" -ForegroundColor White
|
||||
|
||||
Reference in New Issue
Block a user