From 749881dd5d6a32d474b5e600215f6273383e5e1a Mon Sep 17 00:00:00 2001 From: shuki Date: Wed, 4 Mar 2026 04:53:18 +0200 Subject: [PATCH] Fix Run Now backup process getting killed on CGI exit The forked child stayed in the CGI's process group and got killed when Apache cleaned up the CGI process. Now uses double-fork with POSIX::setsid() to fully daemonize the backup process. Co-Authored-By: Claude Opus 4.6 --- whm/gniza-whm/schedules.cgi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/whm/gniza-whm/schedules.cgi b/whm/gniza-whm/schedules.cgi index 592b7eb..0dcfab5 100644 --- a/whm/gniza-whm/schedules.cgi +++ b/whm/gniza-whm/schedules.cgi @@ -8,6 +8,7 @@ use lib '/usr/local/cpanel/whostmgr/docroot/cgi/gniza-whm/lib'; use Whostmgr::HTMLInterface (); use Cpanel::Form (); use File::Copy (); +use POSIX (); use GnizaWHM::Config; use GnizaWHM::Validator; use GnizaWHM::Cron; @@ -376,7 +377,7 @@ sub handle_run_now { my $log_file = "/var/log/gniza/cron-${name}.log"; - # Fork to background + # Double-fork to fully detach from CGI process group my $pid = fork(); if (!defined $pid) { GnizaWHM::UI::set_flash('error', "Failed to fork backup process: $!"); @@ -386,17 +387,24 @@ sub handle_run_now { } if ($pid == 0) { - # Child: detach and exec + # First child: new session, then fork again + POSIX::setsid(); + my $pid2 = fork(); + exit 0 if $pid2; # first child exits immediately + # Grandchild: fully detached daemon close STDIN; + open STDIN, '<', '/dev/null'; close STDOUT; - close STDERR; open STDOUT, '>>', $log_file; + close STDERR; open STDERR, '>&', \*STDOUT; exec @cmd; exit 1; } - # Parent: don't wait, redirect immediately + waitpid($pid, 0); # Reap first child (exits immediately) + + # Parent: redirect GnizaWHM::UI::set_flash('success', "Backup started for schedule '$name'. Check Logs for progress."); print "Status: 302 Found\r\n"; print "Location: schedules.cgi\r\n\r\n";