File manager - Edit - /usr/local/cpanel/install/enable_service_keepalives.pm
Back
package Install::enable_service_keepalives; # Copyright 2026 WebPros International, LLC # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited. use cPstrict; use parent qw( Cpanel::Task ); use Errno (); use Fcntl (); use Cpanel::Config::CpConfGuard (); use Cpanel::ConfigFiles (); our $VERSION = '1.0'; use constant DO_ONCE_FLAG => q[cpanel-55185-enable-service-keepalives]; our $SETTING = 'cpsrvd_keepalives_disabled'; # The autofixer dispatcher treats "a file of this name is present in # /usr/local/cpanel/src" as the run-once record for the autofixer of the same # name, and creates it when it downloads the script. Creating it ourselves stops # the dispatcher from ever fetching or running disable_service_keepalives here. our $autofixer_record = '/usr/local/cpanel/src/disable_service_keepalives'; # Written into the record so that whoever finds this file later knows why an # autofixer that never ran left something behind. The dispatcher runs a fetched # script by passing it to perl, so this is valid Perl and a no-op in the event # something reaches it rather than just testing that it is there. use constant RECORD_CONTENT => <<'END_OF_RECORD'; # Placed by install/enable_service_keepalives.pm, not by the autofixer # dispatcher. # # The dispatcher treats the presence of a file in /usr/local/cpanel/src as the # record that the autofixer of the same name has already run. This server runs a # version that does not need the cpsrvd_keepalives_disabled mitigation, so this # file exists to keep the dispatcher from applying it. # # Deleting this file allows the mitigation to be applied again, which disables # cpsrvd keep-alive connections and costs a TCP and TLS handshake per request. 1; END_OF_RECORD =encoding utf8 =head1 NAME Install::enable_service_keepalives - Restore cpsrvd keep-alive connections. =head1 DESCRIPTION The C<disable_service_keepalives> autofixer sets C<cpsrvd_keepalives_disabled> in F<cpanel.config> and hard-restarts cpsrvd, which retires every cpsrvd connection after a single request. That was shipped as a blanket mitigation for servers that could not receive the fix, and it costs a TCP and TLS handshake per request across cPanel, WHM and Webmail. A server running this code no longer needs the mitigation, so this task removes the setting and records the autofixer as already run, which stops the dispatcher from re-applying it later. The record is written first, and is deliberately unconditional and permanent. It states that this server is patched and must never receive the mitigation, which is true whether or not the setting turned out to be present. It matters most on a fresh install. A new server starts with nothing in F</usr/local/cpanel/src>, so it has no record of its own, and the dispatcher runs from a cron entry that the install itself sets up. Without the record written here, the autofixer would arm against a server that already carries the fix and never needed the mitigation at all. That is why this task writes the record even though a fresh install has no setting to remove. The one case the record does not cover is a downgrade back below the fix, which leaves the server un-mitigated until the record is removed by hand. The task does not restart cpsrvd. F<scripts/post_sync_cleanup> runs C<taskrun> before its own C<restart_services>, and that restart replaces the cpsrvd parent process outright, so the change is picked up without cutting off a browser-based update session part way through. =over 1 =item Type: Bugfix =item Frequency: once =item EOL: 11.142 =back =cut exit __PACKAGE__->runtask() unless caller; sub new ($proto) { my $self = $proto->SUPER::new; $self->set_internal_name('enable_service_keepalives'); return $self; } =head2 perform() Records the autofixer as run and removes its setting, once. Returns true. =cut sub perform ($self) { $self->run_sub_once( version => DO_ONCE_FLAG, eol => '11.142', code => sub { # Record first. Once the dispatcher's run-once record is in place the # autofixer can no longer arm, which closes the window where it could # re-apply the setting we are about to remove. my $recorded = $self->_record_autofixer_as_run(); # A fresh install cannot be carrying the setting, and its # cpanel.config is not necessarily written yet, so the record above is # the whole job here. my $removed = $ENV{'CPANEL_BASE_INSTALL'} ? 1 : $self->_remove_setting(); # Neither step is retried on its own, so report failure and let the # whole task run again on the next update. return $recorded && $removed ? 1 : 0; }, ); return 1; } =head2 _record_autofixer_as_run() Creates the dispatcher's run-once record for C<disable_service_keepalives> if it is not already there. Returns true on success. =cut sub _record_autofixer_as_run ($self) { return 1 if -e $autofixer_record; my $fh; if ( !sysopen( $fh, $autofixer_record, Fcntl::O_WRONLY() | Fcntl::O_CREAT() | Fcntl::O_EXCL(), 0644 ) ) { # The dispatcher downloaded the real script while we were working. Its # presence is the only thing we wanted, so this is not a failure. # Errno is loaded at compile time on purpose: a require() here would do # enough file I/O to reset $! before we could read it. return 1 if $! == Errno::EEXIST(); warn "Unable to create $autofixer_record: $!\n"; return 0; } print {$fh} RECORD_CONTENT or warn "Unable to write to $autofixer_record: $!\n"; close $fh or do { warn "Unable to close $autofixer_record: $!\n"; return 0; }; return 1; } =head2 _remove_setting() Removes C<cpsrvd_keepalives_disabled> from F<cpanel.config>. Returns true when the setting is gone, including when it was never there. =cut sub _remove_setting ($self) { my $ok = eval { my $path = $Cpanel::ConfigFiles::cpanel_config_file; # An absent or empty cpanel.config is not a config we can rewrite. Saving # over it would strand every other setting at its default value. die "$path is missing or empty\n" unless -s $path; # CpConfGuard takes the same lock every other writer of cpanel.config # reaches for, so this does not race a concurrent Tweak Settings save. # no_validate skips the whole-file validation, and the notifications that # go with it, that a plain new() would run. We touch one key. my $guard = Cpanel::Config::CpConfGuard->new( 'no_validate' => 1 ); # Same reasoning as the -s check above, for a file that exists but did # not parse: never write back a hash we did not really load. die "no configuration data was loaded from $path\n" unless ref $guard->{'data'} eq 'HASH' && keys %{ $guard->{'data'} }; if ( !exists $guard->{'data'}{$SETTING} ) { $guard->abort(); # Release the lock without writing. } else { # CpConfGuard has no delete method, and save() flushes the data hash # as it stands, so removing the key here removes it from the file. delete $guard->{'data'}{$SETTING}; $guard->save() or die "save() did not report success\n"; } 1; }; return 1 if $ok; my $error = $@ || 'unknown error'; chomp $error; warn "Unable to remove $SETTING from cpanel.config: $error\n"; return 0; } 1;
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.05 |
proxy
|
phpinfo
|
Settings