refactored qdb_read_materialize_decrypted_db to handle SQLite opening errors
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
2026-06-12 22:30:36 +02:00
parent ebf27811db
commit 71956c0927

View File

@ -82,21 +82,30 @@ function qdb_read_materialize_decrypted_db(): array {
$memfd = qdb_memfd_write($decrypted); $memfd = qdb_memfd_write($decrypted);
if ($memfd !== null) { if ($memfd !== null) {
[$fd, $path] = $memfd; [$fd, $path] = $memfd;
$pdo = qdb_read_open_sqlite_on_path($path, $sql, false); try {
return [$pdo, $path, $fd]; $pdo = qdb_read_open_sqlite_on_path($path, $sql, false);
return [$pdo, $path, $fd];
} catch (Throwable $e) {
// memfd is filled but SQLite cannot open /proc/self/fd on this host.
qdb_close_fd($fd);
}
} }
$fallbackDir = QDB_UPLOADS_DIR . '/.private_read'; $snapshotPath = qdb_read_ram_snapshot_path();
if (!is_dir($fallbackDir)) { if (file_put_contents($snapshotPath, $decrypted) === false) {
@mkdir($fallbackDir, 0700, true); throw new Exception('Could not write read snapshot');
} }
$fallback = $fallbackDir . '/snap_' . getmypid() . '_' . bin2hex(random_bytes(4)) . '.sqlite'; @chmod($snapshotPath, 0600);
if (file_put_contents($fallback, $decrypted) === false) { $pdo = qdb_read_open_sqlite_on_path($snapshotPath, $sql, false);
throw new Exception('Could not write private read snapshot'); return [$pdo, $snapshotPath, -1];
} }
@chmod($fallback, 0600);
$pdo = qdb_read_open_sqlite_on_path($fallback, $sql, false); /**
return [$pdo, $fallback, -1]; * RAM-backed snapshot path (tmpfs). One file per worker; overwritten on refresh.
*/
function qdb_read_ram_snapshot_path(): string {
$dir = is_writable('/dev/shm') ? '/dev/shm' : sys_get_temp_dir();
return $dir . '/qdb_read_' . getmypid() . '.sqlite';
} }
/** /**
@ -223,6 +232,8 @@ function qdb_read_open_sqlite_on_path(string $sqlitePath, string $schemaSql, boo
if ($bytes === false || file_put_contents($savePath, $bytes) === false) { if ($bytes === false || file_put_contents($savePath, $bytes) === false) {
throw new Exception('Could not copy memfd DB for migration save'); throw new Exception('Could not copy memfd DB for migration save');
} }
} elseif (!is_file($savePath)) {
throw new Exception('Cannot persist migration from missing read snapshot');
} }
$pdo->exec('PRAGMA wal_checkpoint(FULL);'); $pdo->exec('PRAGMA wal_checkpoint(FULL);');
qdb_save($savePath, $migrateLock); qdb_save($savePath, $migrateLock);