0

我遇到的问题是,当我在远程 PC 上启动设备管理器并且我连接了具有 10GigE 端口的外部硬件设备时,来自设备管理器的 registerDevice 消息注册了连接的外部设备使用的 10GigE 接口的 IP 地址到设备管理器 PC 而不是设备管理器机器的实际 IP 地址。

网络设置:

PC1
  域管理器:192.168.5.10
  设备管理器 A(GPP):192.168.5.10(与域管理器在同一台机器上)
PC2
  设备管理器 B(GPP):192.168.5.11
  设备接口:192.168.100.10(外接硬件)

如果我在没有连接到 PC2 的外部设备的情况下运行我的方案,则该机器上的设备管理器会使用 IP 地址注册:192.168.5.11。如果我将外部硬件连接到 PC2 并且 10GigE 接口上线,设备管理器使用 IP 地址注册:192.168.100.10 并且整个 REDHAWK 域挂起。

我通过查看 PC1 和 PC2 上的 wireshark 日志验证了这个问题。在连接具有 10GigE 端口的 UHD 设备以外的 UHD 设备时,我们没有遇到此问题。需要注意的是,此时实际上并未使用任何设备或设备管理器。设备刚上电,一个只有 GPP 的节点启动。在 UHD 和外部硬件案例中,两个 10GigE 端口都是定制的,并实现了有限的 10GigE 接口。当连接到具有 10GigE 的另一台 PC 而不是具有有限 10GigE 实现的设备时,设备管理器可以工作。

如果我在节点处于活动状态后连接 10GigE 设备,则 FE 2.0 设备可以正常工作。但是,这种情况对我们不起作用,因为实际走过去并打开设备电源对我们的用例无效。此外,使用在同一台计算机上启动的域上的设备运行不会出现这些问题。仅当域位于远程 PC 上时才会出现此问题。

我们目前正在使用以下 REDHAWK 版本,并且两者都有相同的问题。

CentOS 6.6 与 REDHAWK 2.0.3 和 OmniORB 4.1
Fedora 24 与 REDHAWK 2.0.3 和 OmniORB 4.2

有没有其他人遇到过这个问题,我能做些什么吗?

4

1 回答 1

2

让我们使用 docker 来运行一个完整的示例。您需要启动 3 个终端并安装 docker,但我们可以在一台主机上完成这一切。我将 3 个终端称为“域”、“沙盒”和“主机系统”。

在域终端中,启动一个新的 redhawk 2.0.2 实例:

docker run -it --name=domain axios/redhawk:2.0.2 bash -l

在沙盒终端中,启动另一个 redhawk 2.0.2 实例:

docker run -it --name=sandbox axios/redhawk:2.0.2 bash -l

如果您不熟悉 docker,这两个 docker 实例具有独特的文件系统、内存和网络。检查每个ifconfigIP 地址并记下它们。请注意,它们位于同一子网中,并且可以相互 ping 通。

我们现在可以通过创建两个无法相互连接的新网络来模拟您的 10GigE 端口。在主机终端上,使用 docker 创建两个单独的假网络并将它们分配给您的容器实例。

docker network create -o "com.docker.network.bridge.host_binding_ipv4"="1.1.1.1" bad_net_1
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="2.2.2.2" bad_net_2
docker network connect bad_net_1 domain
docker network connect bad_net_2 sandbox

回到 Domain 和 Sandbox 终端重新运行ifconfig,请注意您现在有一个 eth0 和 eth1 接口,其中 Domain 和 Sandbox 实例上的 eth1 位于唯一的子网上并且无法通信。

您的 IP 地址可能不同,但对我来说,我有:

领域:
  eth0:172.17.0.2
  eth1:172.19.0.2

沙盒:
  eth0:172.17.0.3
  eth1:172.20.0.2

我现在将域配置为omniNames 主机,设置omniORB 连接超时,这样我们就不会挂起corba 调用,并且错误地配置endPoint 以便通告错误的IP 地址。

在域机器上:

sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.19.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF

在沙盒机器上:

sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.20.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF

在域机器上启动 omniNames 和事件,通过cleanomni它们也将清除任何陈旧状态:

cleanomni

在沙盒机器上运行nameclt list以查看 omniORB 对象。请注意,它不起作用,因为为域通告的端点地址是错误的。如果我们通过 /etc/omniORB.cfg 登录,traceLevel=40我们甚至可以在消息中看到不正确的 IP 地址。

omniORB: inputMessage: from giop:tcp:172.17.0.2:2809 236 bytes
omniORB:
4749 4f50 0100 0101 e000 0000 0000 0000 GIOP............
0400 0000 0000 0000 0000 0000 2a00 0000 ............*...
4944 4c3a 6f6d 672e 6f72 672f 436f 734e IDL:omg.org/CosN
616d 696e 672f 4269 6e64 696e 6749 7465 aming/BindingIte
7261 746f 723a 312e 3000 0000 0100 0000 rator:1.0.......
0000 0000 9400 0000 0101 0200 0b00 0000 ................
3137 322e 3139 2e30 2e32 0000 23ae 0000 172.19.0.2..#...
0e00 0000 ff00 bb05 0a58 0100 003c 0000 .........X...<..
0002 0000 0400 0000 0000 0000 0800 0000 ................
0100 0000 0054 5441 0100 0000 1c00 0000 .....TTA........
0100 0000 0100 0100 0100 0000 0100 0105 ................
0901 0100 0100 0000 0901 0100 0300 0000 ................
1600 0000 0100 0000 0b00 0000 3137 322e ............172.
3137 2e30 2e32 0000 f90a 0000 0354 5441 17.0.2.......TTA
0800 0000 bb05 0a58 0100 003c           .......X...<

在域终端上,使用 vim 或 emacs 修复 /etc/omniORB.cfg 中的端点并运行cleanomni以清除所有旧引用并重新启动全方位服务。您现在可以从沙盒终端正确运行nameclt list.

在域终端上使用沙盒终端启动域,nodeBooter -D并通过 python 从沙盒终端连接到域,并确认您可以按预期与其交互。

>>> from ossie.utils import redhawk
>>> dom = redhawk.attach('REDHAWK_DEV')
>>> dom.name
'REDHAWK_DEV'
>>> fs = dom.fileManager
>>> fs.list('.')

请注意,到目前为止,我们只从沙盒向域进行调用,因此只有域机器的广告端点很重要。像“start”和“stop”这样的调用是从你到一个组件的,但像 pushPacket 这样的调用是从组件发出给你的。我们可以通过将域机器上的 SigGen 连接到沙盒机器上的 HardLimit 来确认这一点。请记住,现在域机器已正确配置,而沙盒机器未正确配置。

在域机器上,停止域并运行以下命令来安装波形并使用 GPP 启动域:

sudo yum install -y rh.basic_components_demo
nodeBooter -D -d /var/redhawk/sdr/dev/nodes/DevMgr_12ef887a9000/DeviceManager.dcd.xml

现在回到 python 中的沙箱机器:

from ossie.utils import redhawk, sb
import time
dom = redhawk.attach('REDHAWK_DEV')
app = dom.createApplication('/waveforms/rh/basic_components_demo/basic_components_demo.sad.xml')
siggen = app.comps[0]
siggen.start()
hardlimit = sb.launch('rh.HardLimit')
sink = sb.DataSink()
hardlimit.connect(sink)
siggen.connect(hardlimit)
sb.start()
time.sleep(1)
sink.getData()

您应该在接收器中没有数据,因为沙盒机器通告了错误的端点。现在退出 python 修复 Sandbox 实例上的 endPoint 并重新运行此实验。这次您获得了数据,因为两个端点都已正确配置。

最后,如果您根本不设置端点会发生什么?(正如我想象的那样)来自omniORB示例配置文件

默认情况下,未定义端点配置。在这种情况下,ORB 将只创建 1 个 tcp 端点,就好像在配置文件中指定了行:endPoint = giop:tcp::

主机和端口参数是可选的。如果缺少一个或两个,ORB 将填补空白。例如,“giop:tcp::”将导致 ORB 选择一个任意的 tcp 端口作为端点,它会选择一个主机的 IP 地址作为主机地址。

所以你可能会得到非常奇怪的行为。希望这个例子对每个人都有帮助并且足够容易地运行/重现。

现在我们已经完成了,我们可以清理我们的 docker 实例和 docker 网络:

docker rm -f domain sandbox
docker network rm bad_net_1 bad_net_2
于 2016-10-19T21:15:42.373 回答