私はマスターホストからスレーブホストへのZFSリモートレプリケーションを行います。ここでは、マスターホスト上で動作するPerlスクリプトがあります。<defunct>の処理を回避する方法はありますか?
ファイルシステムごとに、リモートホストにsshし、リスニングモードでmbufferを開始してから、スクリプトを継続してからデータを送信します。成功すると、mbufferは単独で終了する必要があります。
問題
SSH経由でリモートホスト上mbuffer開始し、スクリプトを継続できるようにするには非常に困難でした。私はあなたが下で見ることができることをやりました。
問題は、スクリプトが終了するまで、<defunct>
が各ファイルシステムに1つずつ処理されることです。
<defunct>
プロセスを避けることが可能である
質問?
sub mbuffer {
my ($id, $zfsPath) = @_;
my $m = join(' ', $mbuffer, '-I', $::c{port});
my $z = join(' ', $zfs, 'receive', , $zfsPath);
my $c = shellQuote($ssh, $::c{slaves}{$id}, join('|', $m, $z));
my $pm = Parallel::ForkManager->new(1);
my $pid = $pm->start;
if (!$pid) {
no warnings; # fixes "exec" not working
exec($c);
$pm->finish;
}
sleep 3; # wait for mbuffer to listen
return $pid;
}
親プロセスは、終了した子プロセスをクリーンアップできることをカーネルに知らせるために、子プロセスに対して常に 'wait'(またはそのバリエーションの1つ)を呼び出さなければなりません。 [この質問](https://stackoverflow.com/questions/9164316/c-fork-without-wait-defuncts-execl)には、正しい方向に向けるかもしれない答えがあります。 – Thomas
最も簡単な修正は '$ SIG {CHLD} = 'IGNORE'を設定することです。 ['perldoc -f fork'](http://metacpan.org/pod/perlfunc#fork)を参照してください。 – mob
無効なプロセスまたはゾンビプロセスは、親プロセスが' wait'を呼び出すことなく終了したプロセスです。このように、カーネルは終了した子プロセスのエントリを保持するので、親プロセスが 'wait'を呼び出すと、必要な情報が返されます。ゾンビを避けるために、親プロセスは子プロセスを待つ必要があります。 – direprobs