Проблема со скриптом внешней авторизации

От: Anton Golubev <anton_at_mx_ru>
Дата: Wed 30 Apr 2003 - 15:21:45 MSD


Привет всем!!

Не могли бы вы глянуть на мой скриптик внешней авторизации? Проблема его в том, что он не работает больше 1-2 дней.

Внешне это выглядит как будь-то скрипт перестает отвечать запросы сервера. Запросы соответственно копятся, файловые дескрипторы расходуются и дело заканчивается ступором сервера, когда он не может открыть ни одного нового соединения чтобы обслужить клиентов. Помогает, естественно, только перезагрузка.

Вот сам скрипт:

#!/usr/bin/perl
########################################################################
#######
# ExternalAuth.PL
# $Id: ExternalAuth.PL,v 1.5 2002/12/18 20:07:30 anton Exp $
# This program designed to handle unknown accounts in @zzz.yyy.ru
namespace
# to allow authomatic mailbox creation upon first student-user login.
########################################################################
########

use DBI;
use CLI;
### Constants
##################################################################
$ServerDomain = 'zzz.yyy.ru';
$CGServerAddress = 'localhost';
$CLILogin = 'postmaster@zzz.yyy.ru';
$CLIPassword = 'xxx';

$CmdTimeOut = 5; # sec
### End of Constants

###########################################################

$| = 1;     #force STDOUT autoflush after each write

my @response;

# Enter in STDIN read loop
while(<STDIN>)
# Handle request
{

    chomp;
    my( $seqNum, $Cmd, @cmdArgs ) = split(/ /);

    uc( $Cmd );
    $handler = "cmd_" . $Cmd . "_handler";     if ( defined(&$handler) ) {

            # print execution result
            print "$seqNum " . join(" ", @response) . "\n";
    }
    else
    {
        print "$seqNum ERROR Unknown command\n";
        warn "Got bad request: $seqNum $Cmd @cmdArgs";
    }
}

exit(0);

sub cmd_INTF_handler
# Version request => respond with "seqNum OK programVersionNumber" {

    return "OK", "2";
}

sub cmd_NEW_handler
# NEW check request
{

    my $accountName = shift(@_);

    my( $userName, $domainName ) = split /@/, $accountName;

    my $dbh;

    my $cli;

    if ( $domainName ne $ServerDomain )
    {

        return "ERROR", "No autoreg service for this domain";     }

    if( not $dbh =
DBI->connect("DBI:mysql:web:mysql.yyy.ru",'cgp','Ghtdhfotybt2002') )

    {

        warn( "Database unavailable: " . $DBI::errstr );
        return "ERROR", "Database unavailable";
    }
    my $sth = $dbh->prepare("SELECT * FROM Users WHERE LOGIN=?");     $sth->execute($userName) || warn "Database error: " . $dbh->errstr;     if( $sth->rows != 1 )
    {

        return "ERROR", "Unknown or non-unique account name";     }

    $row = $sth->fetchrow_hashref;
    my %userData;

    $userData{'RealName'} = `/bin/echo -n '$row->{USER_I} $row->{USER_O}
$row->{USER_F}' | /usr/bin/iconv -f KOI8-R -t UTF-8`;
    $userData{'Password'} = '\002' . $row->{'PASS'};
    $userData{'studyGroup'} = $row->{'GROUP_NUM'};
    $userData{'Surname'} = `/bin/echo -n '$row->{USER_F}' |
/usr/bin/iconv -f KOI8-R -t UTF-8`;

    $userData{'givenName'} = `/bin/echo -n '$row->{USER_I}' | /usr/bin/iconv -f KOI8-R -t UTF-8`;

    $sth->finish;
    $dbh->disconnect;

    if ( not $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,

                                        PeerPort => 106,
                                        login => $CLILogin,
                                        password => $CLIPassword
                                   }  )
       )
    {
        warn "CLI connection error: " . $CGP::ERR_STRING;
        return "ERROR", "CLI connection error: ".$CGP::ERR_STRING;
    }

    #$cli->setDebug(1);

    if ( ! $cli->CreateAccount( accountName=>$accountName, settings=>\%userData ) )

    {

        warn "Account creation error: " . $cli->getErrMessage;
        return "ERROR", "Account creation error: " .
$cli->getErrMessage;

    }

    $cli->Logout();

    return "OK", "Account created";
}

Вот кусок лога, в котором видно момент зависания:

00:06:37.32 4 EXTAUTH out: 14 NEW elf666@zzz.yyy.ru\n
00:06:37.33 4 EXTAUTH inp: 14 ERROR Unknown or non-unique account name
00:06:37.33 1 EXTAUTH elf666@zzz.yyy.ru rejected: ERROR Unknown or
non-unique account name
01:17:27.18 4 EXTAUTH out: 15 NEW skivil@zzz.yyy.ru\n
01:17:27.19 4 EXTAUTH inp: 15 ERROR Unknown or non-unique account name
01:17:27.19 1 EXTAUTH skivil@zzz.yyy.ru rejected: ERROR Unknown or
non-unique account name
02:58:44.25 4 EXTAUTH out: 16 NEW skivil@zzz.yyy.ru\n
02:58:44.25 4 EXTAUTH inp: 16 ERROR Unknown or non-unique account name
02:58:44.25 1 EXTAUTH skivil@zzz.yyy.ru rejected: ERROR Unknown or
non-unique account name
03:14:09.86 4 EXTAUTH out: 17 NEW e-mailmpetushkova@zzz.yyy.ru\n
03:14:09.88 4 EXTAUTH inp: 17 ERROR Unknown or non-unique account name
03:14:09.88 1 EXTAUTH e-mailmpetushkova@zzz.yyy.ru rejected: ERROR
Unknown or non-unique account name
03:45:20.29 4 EXTAUTH out: 18 NEW e-mailoignateva@zzz.yyy.ru\n
03:45:20.29 4 EXTAUTH inp: 18 ERROR Unknown or non-unique account name
03:45:20.29 1 EXTAUTH e-mailoignateva@zzz.yyy.ru rejected: ERROR Unknown
or non-unique account name
09:18:41.87 4 EXTAUTH out: 19 NEW areznik2@zzz.yyy.ru\n
09:18:41.94 4 EXTAUTH inp: 19 OK Account created
09:18:41.94 2 EXTAUTH areznik2@zzz.yyy.ru created
09:33:46.19 4 EXTAUTH out: 20 NEW 1234@zzz.yyy.ru\n
09:33:46.19 4 EXTAUTH inp: 20 ERROR Unknown or non-unique account name
09:33:46.19 1 EXTAUTH 1234@zzz.yyy.ru rejected: ERROR Unknown or
non-unique account name
09:34:15.24 4 EXTAUTH out: 21 NEW ANAGAYK@zzz.yyy.ru\n	
09:34:52.06 4 EXTAUTH out: 22 NEW ANAGAYK@zzz.yyy.ru\n
11:11:07.97 4 EXTAUTH out: 23 NEW Motorehad@zzz.yyy.ru\n
11:49:41.69 4 EXTAUTH out: 24 NEW amyzalev@zzz.yyy.ru\n
11:50:06.61 4 EXTAUTH out: 25 NEW amuzalev@zzz.yyy.ru\n
11:50:10.17 4 EXTAUTH out: 26 NEW amuzalev@zzz.yyy.ru\n
11:50:24.60 4 EXTAUTH out: 27 NEW amuzalev@zzz.yyy.ru\n
13:11:47.30 4 EXTAUTH out: 28 NEW abryakin@zzz.yyy.ru\n
13:11:54.79 4 EXTAUTH out: 29 NEW dbryakin@zzz.yyy.ru\n
13:38:05.24 4 EXTAUTH out: 30 NEW vaLentuna.tsygankova@zzz.yyy.ru\n
13:40:46.21 4 EXTAUTH out: 31 NEW 43535@zzz.yyy.ru\n


Завис на 21-ой записи. Обычно зависает на 20-50 запрос. Если в ручном режиме подавать ту же последовательность запросов, то повторить ошибку не удается. Пробовал на большой скорости засылать по 200 реальных запросов (брал из логов) типа так: # ./ExternalAuth.PL < requests.txt

Все запросы обрабатываются нормально.

Раньше я думал, что дело в отвалившихся коннектах к базе данных и приделал тайм-аут на выполнение команды. Не помогло.

Вот кусок из той версии:

    if ( defined(&$handler) ) {

       eval {
           local $SIG{ALRM} = sub { die "alarm clock restart" };
           alarm $CmdTimeOut;
           @response = &$handler(@cmdArgs);
           alarm 0;
       };
       if ($@ and $@ !~ /alarm clock restart/) { die "Got bad signal
while in eval\n" };
       if ($@) {
           # time out - print error
           print "$seqNum ERROR Time out during executing the
request\n";
       }
       else
       {
           # print execution result
           print "$seqNum " . join(" ", @response) . "\n";
       }

    }

Вопрос: где собака порылась? Что прибавить убавить?

С уважением,
Антон Получено Wed Apr 30 11:21:37 2003

Этот архив был сгенерирован hypermail 2.1.8 : Fri 24 Apr 2015 - 16:12:36 MSK