From b37a953cfd66dcafb8891edc27598938198aef03 Mon Sep 17 00:00:00 2001 From: Dillard Blom Date: Wed, 7 Oct 2026 00:48:11 +0200 Subject: [PATCH] Detect a busy run by identity, and clean up a failed kit write step() hands back the same Run object when another process holds the lease; comparing update times per second could stop the scheduled job early after a quick step. A failed write of the recovery kit file now closes the handle and removes the partial file. --- lib/BackgroundJob/BackupJob.php | 8 ++++---- lib/Command/KeyKit.php | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/BackgroundJob/BackupJob.php b/lib/BackgroundJob/BackupJob.php index e8c7536..cce6c89 100644 --- a/lib/BackgroundJob/BackupJob.php +++ b/lib/BackgroundJob/BackupJob.php @@ -46,11 +46,11 @@ final class BackupJob extends TimedJob { $this->startScheduled(); foreach ($this->runs->findRunning(null, BackupService::KIND_FULL) as $run) { while (microtime(true) < $deadline && $run->getStatus() === 'running') { - $before = $run->getUpdatedAt(); - $run = $this->backups->step($run, min($deadline, microtime(true) + $budget)); - if ($run->getUpdatedAt() === $before && $run->getStatus() === 'running') { - break; // another process holds this run's lease: leave it to that process + $next = $this->backups->step($run, min($deadline, microtime(true) + $budget)); + if ($next === $run) { + break; // step() hands back the same object when another process holds the run's lease } + $run = $next; } } $this->failStaleRestores(); diff --git a/lib/Command/KeyKit.php b/lib/Command/KeyKit.php index 5a7638c..2284aeb 100644 --- a/lib/Command/KeyKit.php +++ b/lib/Command/KeyKit.php @@ -47,8 +47,14 @@ final class KeyKit extends Command { } finally { umask($old); } - if ($fh === false || fwrite($fh, $json) !== strlen($json) || !fclose($fh)) { - $output->writeln("Cannot write $file (it must not exist yet)"); + if ($fh === false) { + $output->writeln("Cannot create $file (it must not exist yet)"); + return 1; + } + $ok = fwrite($fh, $json) === strlen($json); + if (!fclose($fh) || !$ok) { + @unlink($file); + $output->writeln("Cannot write $file"); return 1; } $output->writeln("Recovery kit written to $file. Copy it off this server, then run occ backup:key:confirm.");