Skip to content

CleanupBackgroundJobsJob: crashes on BSD/macOS (ps -o cmd) and ignores background_jobs_expiration_days (hardcoded snowflake) #61635

Description

@mmdevl

The CleanupBackgroundJobsJob.php calls ps -o cmd to detect crashed background jobs, but -o cmd is a Linux-specific keyword rejected by BSD ps (macOS, FreeBSD) with

ps: cmd: keyword not found
ps: no valid keywords; valid keywords:

The fix is to replace the exec('ps ...') call with posix_kill($pid, 0), which is POSIX-standard and works across all platforms.

This bug has been introduced in commit 3956e29

Proposed fix:

diff --git a/core/BackgroundJobs/CleanupBackgroundJobsJob.php b/core/BackgroundJobs/CleanupBackgroundJobsJob.php
index 6242941eed1..b881f855b6d 100644
--- a/core/BackgroundJobs/CleanupBackgroundJobsJob.php
+++ b/core/BackgroundJobs/CleanupBackgroundJobsJob.php
@@ -47,10 +47,8 @@ class CleanupBackgroundJobsJob extends TimedJob {
                        if ($job->serverId !== $currentServerId) {
                                continue;
                        }
-                       $output = [];
-                       $result = 0;
-                       exec('ps -p ' . escapeshellarg((string)$job->pid) . ' -o cmd', $output, $result);
-                       if (count($output) === 1 && current($output) === 'CMD' && $result === 1) {
+                       $processExists = posix_kill($job->pid, 0) || posix_get_last_error() === POSIX_EPERM;
+                       if (!$processExists) {
                                // Process doesn't exists anymore
                                $maxDuration = (new DateTimeImmutable())->diff($job->startedAt);
                                $maxDuration

Moreover in the commit dc5499a, in JobRuns::deleteBefore(), the snowflake ID computed from the configured background_jobs_expiration_days value is immediately overwritten by a hardcoded literal '91480652934574081' on the next line, making the expiration setting have no effect. Removing that hardcoded line restores the intended behavior.

Proposed fix:

diff --git a/lib/private/BackgroundJob/JobRuns.php b/lib/private/BackgroundJob/JobRuns.php
index a2612f6655e..95f47c666a4 100644
--- a/lib/private/BackgroundJob/JobRuns.php
+++ b/lib/private/BackgroundJob/JobRuns.php
@@ -64,7 +64,6 @@ final readonly class JobRuns implements IJobRuns {
 
        public function deleteBefore(int $timestamp): int {
                $beforeSnowflake = $this->snowflakeGenerator->minForTimeId($timestamp);
-               $beforeSnowflake = '91480652934574081';
                $qb = $this->connection->getQueryBuilder();
                $result = $qb
                        ->delete(self::TABLE)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions