#!/usr/bin/perl -w

# Invoke /usr/sbin/clustat with 5-second timeout.  clustat output is
# printed on STDOUT.  Exit code is 0 on no error, 1 if timed out.

use strict;
use Sys::Syslog;
use FileHandle;
use IPC::Open2;

my $CLUSTAT   = '/usr/sbin/clustat';

sub logerr($) {
    my $msg = shift;
    openlog('zmclustat', 'pid', 'local0');
    syslog('err', $msg);
    closelog();
    print STDERR $msg . "\n";
}

#
# Invoke clustat with 5-second timeout.
#
sub clustat($) {
    my $args = shift;
    $args = '' if (!defined($args));
    my $output = undef;

    if (! -f $CLUSTAT) {
        logerr("$CLUSTAT is missing");
        return undef;
    }

    my $inh = new FileHandle;
    my $outh = new FileHandle;
    my $pid = open2($outh, $inh, "$CLUSTAT $args");

    my $hung = 1;
    my $bits = '';
    vec($bits, fileno($outh), 1) = 1;
    my $nfound = select($bits, undef, undef, 5);
    if ($nfound > 0 && vec($bits, fileno($outh), 1) == 1) {
	$hung = 0;
	my $offset = 0;
	my $bytesRead = 1;
	while ($bytesRead) {
	    $bytesRead = sysread($outh, $output, 1024, $offset);
	    $offset += $bytesRead;
	}
    }
    close($inh);
    close($outh);
    if ($hung) {
	logerr("clustat [pid=$pid] is hanging.  killing it...");
	kill(9, $pid);
        return (undef, 1);
    }
    waitpid($pid, 0);
    my $rc = $? >> 8;

    return ($output, $rc);
}

my $args = join(' ', @ARGV);
my ($output, $rc) = clustat($args);
if (defined($output)) {
    print $output;
}
exit($rc);
