[pgcluster: 795] pgreplicateがSIGTERMで落とせません(PGCluster-1.1.1a)

Masanobu Yasui yasui-m @ klab.org
2005年 8月 7日 (日) 03:01:52 JST


お世話になります。
安井と申します。

PGCluster-1.1.1a で pgreplicate の動作検証をしているのですが、以下のような問題がありましたの
でご相談させて頂けないでしょうか。

【動作環境】
   Debian     : 3.1 Sarge
   LinuxKernel: 2.6.12.3

【現象】
  pgreplicate起動後、一度でもReplication_Port(8001)で接続を受け付けると、その後SIGTERMで終了
  できなくなります。(正確な挙動は若干違いますが、、、要約ということでなんとか)

【詳細】
  replicate_main() では PGR_Create_Socket_Bind() でリスナを生成し、 select で接続待機をして
  いますが、このリスナでAcceptしたsocketがリモートから切断された場合、なぜか リスナのselect
  が rmask をセットして返ってきてしまうようです。

  その結果、待機中の接続がないにもかかわらず replicate_loop() が呼ばれてしまい、BUSY_MODEの
  まま PGR_Create_Acception で接続待ちをしているようです。この状態では SIGTERM が無視されて
  しまうため、SIGQUIT等で終了するしかなくなってしまいます。
  (psqlでクラスタDBに接続したままSIGTERMという手もありますが・・・・)


 「処理の流れ」
  --------------------------------------------------
       replicate_main()
              ↓
           select()
              ↓
   (接続を受け付けてsockを生成)
              ↓
       replicate_loop()
              ↓
     PGR_Create_Acception() 
              ↓
        fork() & return
              ↓
           select()
              ↓
   (sockがリモートから切断される)
              ↓
       replicate_loop()
              ↓
     PGR_Create_Acception() 
              ↓
  (待機中の接続がないのでBUSY_MODEのままだんまり)      
  --------------------------------------------------

  とりあえず、以下のようなパッチで リスナソケットを非ブロッキングモードにし、待機中の接続が
  ない場合は replicate_main() に戻ってくるようにしてみましたが、この対応で問題がないかどうか
  は微妙なのかなあと感じています(全体の挙動に影響するし、移植性の問題とかもありますし・・・)

  既知の問題でしたらすいません。
  次期バージョンでの対応予定等がございましたら、なにかしらの情報を頂けると幸いです。
  よろしくお願い致します。


diff -ur pgcluster-1.1.1a/src/backend/libpq/pgcluster.c pgcluster-1.1.1a-patch/src/backend/libpq/pgcluster.c
--- pgcluster-1.1.1a/src/backend/libpq/pgcluster.c      2005-08-06 20:19:44.000000000 +0900
+++ pgcluster-1.1.1a-patch/src/backend/libpq/pgcluster.c        2005-08-07 01:48:35.000000000 +0900
@@ -206,6 +206,7 @@
        size_t  len = 0;
        struct sockaddr_in addr;
        int one = 1;
+       int fl  = 0;

        if ((*fdP = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
@@ -247,6 +248,18 @@
                PGR_Close_Sock(fdP);
                return STATUS_ERROR;
        }
+       fl = fcntl(*fdP, F_GETFL);
+       if( fl == -1 )
+       {
+               PGR_Close_Sock(fdP);
+               return STATUS_ERROR;
+       }
+       if( fcntl(*fdP, F_SETFL, fl | O_NONBLOCK) == -1 )
+       {
+               PGR_Close_Sock(fdP);
+               return STATUS_ERROR;
+       }
+
        return  STATUS_OK;
 }

@@ -257,10 +270,15 @@
        struct sockaddr  addr;
        size_t  len = 0;
        int one = 1;
+       int fl  = 0;

        len = sizeof(struct sockaddr);
        while ((sock = accept(fd,&addr,&len)) < 0)
        {
+               if( (errno == EAGAIN) || (errno == EWOULDBLOCK) )
+               {
+                       return STATUS_ERROR;
+               }
                PGR_Close_Sock(&fd);
                PGR_Create_Socket_Bind(&fd, hostName , portNumber);
        }
@@ -273,6 +291,15 @@
        {
                return STATUS_ERROR;
        }
+       fl = fcntl(sock, F_GETFL);
+       if( fl == -1 )
+       {
+               return STATUS_ERROR;
+       }
+       if( fcntl(sock, F_SETFL, fl & ~O_NONBLOCK) == -1 )
+       {
+               return STATUS_ERROR;
+       }
        *sockP = sock;

        return  STATUS_OK;
diff -ur pgcluster-1.1.1a/src/pgcluster/pgrp/main.c pgcluster-1.1.1a-patch/src/pgcluster/pgrp/main.c
--- pgcluster-1.1.1a/src/pgcluster/pgrp/main.c  2005-03-02 10:24:28.000000000 +0900
+++ pgcluster-1.1.1a-patch/src/pgcluster/pgrp/main.c    2005-08-07 02:04:53.000000000 +0900
@@ -169,7 +169,11 @@
        int rtn = 0;
        bool exist_sys_log = false;

-       PGR_Create_Acception(fd,&sock,"",Port_Number);
+       if( STATUS_OK != PGR_Create_Acception(fd,&sock,"",Port_Number) )
+       {
+               return(0);
+       }
+
        pgid = getpgid(0);
        pid = fork();
        if (pid <0)


**************************************************************
KLab 株式会社(クラブかぶしきがいしゃ) http://www.klab.org/
  Kラボラトリー: 安井真伸
**************************************************************





pgcluster メーリングリストの案内