@@ -12,10 +12,13 @@ use Time::HiRes qw(usleep);
12
12
# By convention, we just use 5 chars string as possible internal IPC messages.
13
13
# IPC_LEAVE from children is supported and is only really useful while debugging.
14
14
# 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
15
17
# IPC_ABORT can be used to abort a forked process
16
18
use constant IPC_LEAVE => ' LEAVE' ;
17
19
use constant IPC_EVENT => ' EVENT' ;
18
20
use constant IPC_ABORT => ' ABORT' ;
21
+ use constant IPC_EFILE => ' EFILE' ;
19
22
20
23
use parent ' GLPI::Agent' ;
21
24
@@ -467,6 +470,27 @@ sub handleChildren {
467
470
push @messages , $event
468
471
if $child -> {in }-> sysread ($event , $len );
469
472
}
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
+ }
470
494
}
471
495
}
472
496
$count ++;
@@ -641,13 +665,18 @@ sub forked_process_event {
641
665
642
666
return unless length ($event );
643
667
# 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 ' ) {
645
669
my ($type ) = split (" ," , $event )
646
670
or return ;
647
671
$type = substr ($event , 0, 64) if length ($type ) > 64;
648
672
# Just ignore too big logger event like full inventory content logged at debug2 level
649
673
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 });
651
680
return ;
652
681
}
653
682
0 commit comments