Phase 0: fixes from review (torn files, pending blobs, exact sequences, UTF-8, storage checks)
- detect files changing during reading or between resumable steps and re-read them (size/mtime/ctime/inode), spike F overwrites mid-run - drop pending blob ids when a pack or index upload fails - dump and restore PostgreSQL sequence state exactly, bound parameters, validated catalog names; spike C checks all sequences exactly - keep invalid UTF-8 byte-exact (tagged base64) - refuse large tables without a primary key - StorageBackend: check write/flush/close results, validate base path - user_migration import/export: root paths, intermediate folders, partial writes, read errors - spikes: never touch an existing account, own fixtures, 512M note
This commit is contained in:
@@ -58,6 +58,17 @@ switch ($mode) {
|
||||
$repo = Repository::open(new LocalBackend("$work/repo"), $pass);
|
||||
$t = microtime(true);
|
||||
$state = BackupRun::step($repo, $state, $t + $seconds);
|
||||
// Simulate a user overwriting the big file (same size) while the run is in the middle of it.
|
||||
if (getenv('NGB_MUTATE') === '1' && ($state['cur']['path'] ?? '') === 'huge.bin' && !file_exists("$work/mutated")) {
|
||||
$fh = fopen("$src/huge.bin", 'r+b');
|
||||
fseek($fh, 10 * 1048576);
|
||||
fwrite($fh, random_bytes(1048576));
|
||||
fclose($fh);
|
||||
touch("$src/huge.bin", time() + 5);
|
||||
file_put_contents("$work/expected.json", json_encode($hashTree($src)));
|
||||
touch("$work/mutated");
|
||||
echo " -> huge.bin overwritten (same size) between steps\n";
|
||||
}
|
||||
// Save the state atomically: a kill before this point means the step is simply redone.
|
||||
file_put_contents("$stateFile.tmp", json_encode($state));
|
||||
rename("$stateFile.tmp", $stateFile);
|
||||
|
||||
Reference in New Issue
Block a user