Skip to content

Commit 828f33d

Browse files
committed
fix: Fix issues on proxy-server-plugin due to wrong support of long IPC messages
1 parent 182ee22 commit 828f33d

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

Changes

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ core:
66
* Parallel::ForkManager must not use more than 60 workers on MSWin32 due to a
77
perl limitation on this operating system
88
* Refacto events management to permit a task to trigger another one
9+
* IPC long messages only have size limitation on windows
10+
* Add new IPC message type to handle too long IPC_EVENT messages on windows
911

1012
inventory:
1113
* Fix network default route discovery on linux
@@ -51,6 +53,9 @@ deploy:
5153
* Force agent to run a partial software inventory after the deploy task is done
5254
if this has been set as a requirement in any job sent by the server
5355

56+
proxy-server-plugin:
57+
* Fix issues due to wrong support of long IPC messages
58+
5459
toolbox:
5560
* fix #532: Make libssh2 use the right place when looking for known_hosts file
5661
on windows

lib/GLPI/Agent/Daemon.pm

+31-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ use Time::HiRes qw(usleep);
1212
# By convention, we just use 5 chars string as possible internal IPC messages.
1313
# IPC_LEAVE from children is supported and is only really useful while debugging.
1414
# IPC_EVENT can be used to handle events recognized in parent
15+
# IPC_EFILE can be used to handle events recognized in parent and is used on MSWin32
16+
# when transmitted event is too big for IPC
1517
# IPC_ABORT can be used to abort a forked process
1618
use constant IPC_LEAVE => 'LEAVE';
1719
use constant IPC_EVENT => 'EVENT';
1820
use constant IPC_ABORT => 'ABORT';
21+
use constant IPC_EFILE => 'EFILE';
1922

2023
use parent 'GLPI::Agent';
2124

@@ -467,6 +470,27 @@ sub handleChildren {
467470
push @messages, $event
468471
if $child->{in}->sysread($event, $len);
469472
}
473+
} elsif ($msg eq IPC_EFILE) {
474+
my $len;
475+
$len = unpack("S", $len)
476+
if $child->{in}->sysread($len, 2);
477+
if ($len>2) {
478+
my ($event, $size, $file);
479+
$size = unpack("S", $size)
480+
if $child->{in}->sysread($size, 2);
481+
if ($child->{in}->sysread($file, $len-2)) {
482+
$event = GLPI::Agent::Tools::Win32::readEventFile($file, $size);
483+
if (!defined($event) || length($event) != $size) {
484+
# Limit log rate of IPC_EVENT event read failure from IPC_EFILE
485+
if (!$self->{_efile_logger_failure_timeout} || time > $self->{_efile_logger_failure_timeout}) {
486+
$self->{logger}->debug2($child->{name} . "[$pid] failed to read IPC_EVENT from $file file");
487+
$self->{_efile_logger_failure_timeout} = time + 5;
488+
}
489+
} else {
490+
push @messages, $event;
491+
}
492+
}
493+
}
470494
}
471495
}
472496
$count++;
@@ -641,13 +665,18 @@ sub forked_process_event {
641665

642666
return unless length($event);
643667
# On MSWin32, syswrite can block if header+size+event is greater than 512 bytes
644-
if (length($event) > 505) {
668+
if (length($event) > 505 && $OSNAME eq 'MSWin32') {
645669
my ($type) = split(",", $event)
646670
or return;
647671
$type = substr($event, 0, 64) if length($type) > 64;
648672
# Just ignore too big logger event like full inventory content logged at debug2 level
649673
return if $type eq 'LOGGER';
650-
$self->{logger}->error("Skipping $type too long forked process event");
674+
675+
# Convert event to efile: event content in a file
676+
my $file = GLPI::Agent::Tools::Win32::getEventFile($self->{vardir}, $event);
677+
my $efile = pack("S", length($event)).$file;
678+
$self->{_ipc_out}->syswrite(IPC_EFILE.pack("S", length($efile)).$efile);
679+
GLPI::Agent::Tools::Win32::setPoller($self->{_ipc_pollin});
651680
return;
652681
}
653682

lib/GLPI/Agent/Tools/Win32.pm

+30-1
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ sub runPowerShell {
565565
SUFFIX => '.ps1'
566566
);
567567
print $fh $script;
568-
close( $fh);
568+
close $fh;
569569
my $file = $fh->filename;
570570
return unless $file && -f $file;
571571

@@ -1115,6 +1115,35 @@ sub getPoller {
11151115
return $poller->down_nb();
11161116
}
11171117

1118+
sub getEventFile {
1119+
my ($folder, $event) = @_;
1120+
1121+
my $template = "efile-XXXXXXXXXXX";
1122+
my ($fh, $filename) = File::Temp::tempfile($template, DIR => $folder, SUFFIX => '.evt');
1123+
binmode($fh);
1124+
print $fh $event;
1125+
close $fh;
1126+
1127+
return $filename;
1128+
}
1129+
1130+
sub readEventFile {
1131+
my ($file, $size) = @_;
1132+
1133+
return unless -e $file && $size > 0;
1134+
1135+
my $event;
1136+
if (open my $fh, "<", $file) {
1137+
binmode($fh);
1138+
read($fh, $event, $size);
1139+
close $fh;
1140+
}
1141+
1142+
unlink $file;
1143+
1144+
return $event;
1145+
}
1146+
11181147
sub getFormatedWMIDateTime {
11191148
my ($datetime) = @_;
11201149

0 commit comments

Comments
 (0)