Linux 如何关闭Net::LDAP::Server

Linux 如何关闭Net::LDAP::Server,linux,perl,service,ldap,application-shutdown,Linux,Perl,Service,Ldap,Application Shutdown,我有一个基于使用的Perl LDAP服务器 模块。 为了让它在Linux中作为服务运行,我使用 图书馆 到目前为止,一切正常,但当我关闭服务时,子进程并没有关闭 关闭所有进程的正确方法是什么 当我发送一个SIGTERM信号时,会调用server\u close方法,但不会发生其他任何事情。从这一点开始,终止的子项不再重新启动,但等待工作的子项不会终止 #!/usr/bin/perl #chkconfig: 345 80 05 #description: LDAP Server for Inno

我有一个基于使用的Perl LDAP服务器 模块。 为了让它在Linux中作为服务运行,我使用 图书馆

到目前为止,一切正常,但当我关闭服务时,子进程并没有关闭

关闭所有进程的正确方法是什么

当我发送一个
SIGTERM
信号时,会调用
server\u close
方法,但不会发生其他任何事情。从这一点开始,终止的子项不再重新启动,但等待工作的子项不会终止

#!/usr/bin/perl

#chkconfig: 345 80 05
#description: LDAP Server for Innovaphone

use strict;
use warnings;

package Listener;

use Net::Server;
use base 'Net::Server::PreForkSimple';

my $continue = 1;

...

sub process_request {
    my $self = shift;

    my $in  = *STDIN{IO};
    my $out = *STDOUT{IO};

    my $sock         = $self->{server}->{client};
    my $peer_address = $sock->peerhost();
    my $peer_port    = $sock->peerport();
    logwarn( "Connection accepted from $peer_address : $peer_port" );

    my $handler = InnoLdapServer->new($sock);

    while ( 1 ) {
        my $finished = $handler->handle;
        return if $finished;
    }
}

...

sub server_close {
    logmsg( "Server close called" );
    $continue = 0;
}

# Start daemon
Proc::Daemon::Init();

my $pidfile = File::Pid->new({ file => "/var/run/inno-ldap.pid" });

if ( $pidfile->running() ) {
    die "Already running";
}

$pidfile->write();

open( STDOUT, '>', "$logpath/inno-ldap.$logName.log" ) or die "Can't open stdout log";
select( ( select( STDOUT ), $| = 1 )[0] );    # make the log file "hot" - turn off buffering

open( STDERR, '>', "$logpath/inno-ldap.$logName.error.log" ) or die "Can't open error log";
select( ( select( STDERR ), $| = 1 )[0] );    # make the log file "hot" - turn off buffering

while ( $continue ) {

    # package main;
    $roothandler = Listener->run(
        port          => [ 636, "389/tcp" ],
        proto         => "ssl",   # use ssl as the default
        ipv           => "*",     # bind both IPv4 and IPv6 interfaces
        user          => "daemon",
        group         => "daemon",
        SSL_key_file  => "/home/root/ssl_cert/server.pem",
        SSL_cert_file => "/home/root/ssl_cert/server.pem",
        max_servers   => 10,
        log_level     => 4
    );
}

$pidfile->remove();

1;
process\u request
中的
while(1)
循环更改为
while($pidfile->running())
。将
$continue
设置为零会阻止任何其他侦听器运行,但据我所知,
process\u request
子例程会忽略该变量


当然,这需要更早地声明
$pidfile
,因为它不在
进程请求的范围内,因为它是在子例程定义之后声明(并分配)的;如果程序被信号终止,服务器本身需要关闭。除了上述信号之外,我们看不到呼叫代码以及您如何“关闭服务”

Net::server
中有一个
server\u close
方法用于此操作。但是问题所指的同名方法似乎是
Listener
类中的方法,因此它覆盖了(grand)父方法。它只会停止子进程中的进一步工作,而不会接触服务器

因此,如果这是在信号处理程序中调用的方法,那么服务器永远不会正确关闭,其现有的子级也不会关闭。您需要在
Net::server
对象上调用
server\u close
,或者在您自己的
server\u close
方法中安排调用父对象的方法

下的
Net::Server
文档

在服务器关闭阶段(
$self->server\u close
),以下内容表示程序流程:

$self->close_children;  # if any  
$self->post_child_cleanup_hook;  
if (Restarting server) {
    $self->restart_close_hook();  
    $self->hup_server;  
}

$self->shutdown_sockets;  

$self->server_exit;
如果对
Net::server
对象或
Listener
对象的父对象上的
server\u close
调用因某种原因无法执行,请尝试使用工作流中列出的各个方法

也有信号列在列表中 “人格”论

每个Fork和PreFork角色都通过退出信号支持优雅的关机。当接收到退出时,家长将向孩子发出信号,然后等待他们退出

然后在

自版本2.000以来,PreForkSimple服务器已接受TTIN和TTOU信号。收到TTIN后,max_服务器增加1。如果收到TTOU信号,则最大服务器数减少1


但我希望关闭它时不需要这个,当然也不是最后一个。

这不会关闭子进程,我认为我们需要向每个分叉的子进程发送信号,以获得所需的结果result@Andr埃希尔德更新了解释(和其他小编辑)删除
子服务器\u close
代码得到了预期的结果,同时删除
while($continue)
循环中的循环。@AndréSchild很棒。这是调用
Net::Server::Server\u close
的最简单方法,不覆盖它。(我也没有看到
while($continue)
循环的目的,但我没有提到它,因为现实中显然有更多的代码。)