Thursday, May 5, 2011

Multiple EPICS IOCs on a Single Host

EPICS の複数 IOC を一つの Linux host で実行する件について、内山さんがいろいろ試験をしてくれて、Channel access (CA) の仕様を含めて情報交換しました。山本さんからも Comment をいただきました。Memo しておきます。

(1) CA-client と IOC の間で Broadcast が使えれば、ひとつの UDP Port を使用して複数 IOC を立ち上げても、それぞれの IOC との間で CA-search, CA-connect できる。しかし、Broadcast が使えない(例えば Router 越えの)Unicast を使用する Client と IOC の間では事情が異なる。

(2) IOC が 2 つの場合は、一方を TCP で、他方を UDP で CA-search するように、EPICS_CA_ADDR_LIST や EPICS_CA_NAME_SERVERS 環境変数を設定すれば、Broadcast が届かない Host 間でも CA 通信が可能になる(内山さんの Idea)。3 つ以上 IOC を実行する場合には他の方法との組み合わせが必要となる。

(3) IOC が 3 つ以上であっても Port 番号が明らかならば、その Port 番号を EPICS_CA_ADDR_LIST で指定することによって、CA 通信が可能になる。IOC 起動時には Port 番号を指定するためには、EPICS_CA_SERVER_PORT を設定する。

(4) 上の (2),(3) がいやならば、Broadcast だけで名前解決できない環境では、ひとつの Host で IOC を 2 つ以上実行しない方がよい。

(5) そもそもひとつの UDP Port を使用して複数 IOC が立上げられるのは UDP stack の実装がどのようになっているかによる。

(6) CA-nameserver を使用すると、Process variable の名前の解決と Channel access 接続の問題を分離できるので有用である。しかし、次の項の Beacon の問題は別に解決しなくてはならない。

(7) 安定な CA client-server の接続のためには client から server に送る CA-search だけでなく、server から client に送る Beacon も正しく届く必要があり、Router を越えた Configuration をいつも保守するのは結構面倒。状況によっては CA-gateway を併用するか、Multi-home (複数 network interface) にした方が現実的。

簡単な UDP socket の試験で UDP 複数 Port の確認してみました。
<http://www-linac.kek.jp/cont/src/s2.ansi.tar.gz>
に入れてある s2_rechod (tcp/udp server) と s2_becho (broadcast/unicast client) を使用すると。

(A) host A で udp server を同じ port 10000 で 2 つ立上げ。
s2_rechod -u -p 10000
s2_rechod -u -p 10000

(B) host B で broadcast を試みる。
s2_becho -p 10000 {broadcast address}
標準入力から入れた message が 2 回ずつ戻ってくる。Port 10000 の Process 双方に message が届いた。

(C) host B で UDP unicast を試みる(普通の UDP message)。
s2_becho -p 10000 {unicast address}
標準入力から入れた message が 1 回ずつしか戻って来ない。Port 10000 の Process のうち一方にだけ message が届いた。

これらの (B), (C) の違いは、

(B) Broadcast packet は 10000 番 port を待っている全ての host の全ての process に等しく届くべき。
(C) Unicast packet は指定されたひとつだけの Host 上の Process のうち 10000 番 port を待っているひとつだけの Process に届けるべき。それが Unicast というもの。

というような考え方に基づいている、と思われます。この Socket の仕様は、Multicast の実装がされる過程で、UDP 用に実装されたようですが、Architecture によって扱いが微妙に異なります。FreeBSD, MacOSX, Tru64unix などではこの仕様を利用するためには SO_REUSEPORT という Option を使用する必要があります。Solaris, Linux, Windows ではこの仕様は SO_REUSEADDR という別の Option と区別されておらず、独立に外す方法はないと思われます。実は、この機能を使うと他人の Server の機能を横取り (Hijack)できる可能性があるので、そういう意味で Solaris, Linux, Windows で UDP server を使用することは少しだけ危険を伴う。

本来はこのような IOC の使い方(Single Host - Over Router - Multiple IOC)は Multicast を用いて実装すべきで、以前から言及されています。

Experimental Physics and Industrial Control System (EPICS)
<http://www.aps.anl.gov/epics/>
Channel access 概要
<http://www-linac.kek.jp/cont/epics/epics-ihep-2010/channelaccess-furukawa6.pdf>
EPICS R3.14 Channel Access Reference Manual
<http://www.aps.anl.gov/epics/base/R3-14/12-docs/CAref.html>
Unix-socket-faq for network programming: 4.11 ... SO_REUSEPORT
<http://www.faqs.org/faqs/unix-faq/socket/>
Simple socket library and test programs
<http://www-linac.kek.jp/cont/src/s2.ansi.tar.gz>
EPICS and WAN (Channel access over Multicast について言及)
<http://www-linac.kek.jp/linac-paper/2003/icalepcs2003-hill-epicswan.pdf>