带有外部 10GigE 设备的机器上的设备管理器导致问题
Device Managers on Machines with external 10GigE devices causing problems
我遇到的问题是,当我在远程 PC 上启动设备管理器时,我有一个连接了 10GigE 端口的外部硬件设备,来自设备管理器的 registerDevice 消息注册了所用 10GigE 接口的 IP 地址通过连接到设备管理器 PC 的外部设备而不是设备管理器机器的实际 IP 地址。
网络设置:
PC1
Domain Manager:192.168.5.10
Device Manager A(GPP):192.168.5.10 (on same machine as the domain manager)
PC2
Device Manager B(GPP):192.168.5.11
Device Interface: 192.168.100.10 (connected to external hardware)
如果我 运行 我的场景没有连接到 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 版本,这两个版本都存在相同的问题。
带有 REDHAWK 2.0.3 和 OmniORB 4.1 的 CentOS 6.6
Fedora 24 与 REDHAWK 2.0.3 和 OmniORB 4.2
有没有其他人遇到过这个问题,我能做些什么吗?
让我们通过一个完整的例子来使用 docker 到 运行。您需要调出 3 个终端并安装 docker,但我们可以在一台主机上完成所有这些工作。我将这 3 个终端称为 "Domain"、"Sandbox" 和 "Host system"。
在域终端中,启动一个新的 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 实例具有独特的文件系统、内存和网络。执行 ifconfig
检查每个 IP 地址并记下它们。请注意,它们在同一子网中,并且可以相互 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
回到域和沙盒终端 re运行 ifconfig
,请注意,您现在有一个 eth0 和 eth1 接口,其中域和沙盒实例上的 eth1 位于唯一的子网上,无法通信。
您的 IP 地址可能不同,但我有:
Domain:
eth0: 172.17.0.2
eth1: 172.19.0.2
Sandbox:
eth0: 172.17.0.3
eth1: 172.20.0.2
我现在将域配置为 omniNames 主机,设置 omniORB 连接超时,这样我们就不会挂起 corba 调用,错误地配置端点,以便公布错误的 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
在域机器上通过 cleanomni
启动 omniNames 和事件,这也将清除任何陈旧状态:
cleanomni
在沙盒机器上 运行 nameclt list
查看 omniORB 对象。请注意,它不起作用,因为为域公布的端点地址是错误的。如果我们通过 traceLevel=40
在 /etc/omniORB.cfg 中进行登录,我们甚至可以在消息中看到不正确的 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
中的端点以清除所有旧引用并重新启动 omni服务。您现在可以从沙盒终端正确 运行 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 之类的调用是从组件传递给您的。我们可以通过将 Domain Machine 上的 SigGen 连接到 Sandbox 机器上的 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 实例上的端点并重新运行 这个实验。这次您获得了数据,因为两个端点都已正确配置。
最后,如果您根本不设置端点会怎样? (正如我想象的那样)来自 omniORB sample configuration file:
By default, no endPoint configuration is defined. In this case the
ORB will create just 1 tcp endpoint as if the line:
endPoint = giop:tcp::
is specified in the configuration file
和
The host and port parameter are optional. If either or
both are missing, the ORB fills in the blank. For example,
"giop:tcp::" will cause the ORB to pick an arbitrary tcp port
as the endpoint and it will pick one IP address of the host
as the host address.
所以你可能会得到非常奇怪的行为。希望这个例子对每个人都有帮助并且很容易运行通过/重现。
现在我们已经完成了,我们可以清理我们的 docker 实例和 docker 网络:
docker rm -f domain sandbox
docker network rm bad_net_1 bad_net_2
我遇到的问题是,当我在远程 PC 上启动设备管理器时,我有一个连接了 10GigE 端口的外部硬件设备,来自设备管理器的 registerDevice 消息注册了所用 10GigE 接口的 IP 地址通过连接到设备管理器 PC 的外部设备而不是设备管理器机器的实际 IP 地址。
网络设置:
PC1 Domain Manager:192.168.5.10 Device Manager A(GPP):192.168.5.10 (on same machine as the domain manager)
PC2 Device Manager B(GPP):192.168.5.11 Device Interface: 192.168.100.10 (connected to external hardware)
如果我 运行 我的场景没有连接到 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 版本,这两个版本都存在相同的问题。
带有 REDHAWK 2.0.3 和 OmniORB 4.1 的 CentOS 6.6
Fedora 24 与 REDHAWK 2.0.3 和 OmniORB 4.2
有没有其他人遇到过这个问题,我能做些什么吗?
让我们通过一个完整的例子来使用 docker 到 运行。您需要调出 3 个终端并安装 docker,但我们可以在一台主机上完成所有这些工作。我将这 3 个终端称为 "Domain"、"Sandbox" 和 "Host system"。
在域终端中,启动一个新的 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 实例具有独特的文件系统、内存和网络。执行 ifconfig
检查每个 IP 地址并记下它们。请注意,它们在同一子网中,并且可以相互 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
回到域和沙盒终端 re运行 ifconfig
,请注意,您现在有一个 eth0 和 eth1 接口,其中域和沙盒实例上的 eth1 位于唯一的子网上,无法通信。
您的 IP 地址可能不同,但我有:
Domain: eth0: 172.17.0.2 eth1: 172.19.0.2 Sandbox: eth0: 172.17.0.3 eth1: 172.20.0.2
我现在将域配置为 omniNames 主机,设置 omniORB 连接超时,这样我们就不会挂起 corba 调用,错误地配置端点,以便公布错误的 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
在域机器上通过 cleanomni
启动 omniNames 和事件,这也将清除任何陈旧状态:
cleanomni
在沙盒机器上 运行 nameclt list
查看 omniORB 对象。请注意,它不起作用,因为为域公布的端点地址是错误的。如果我们通过 traceLevel=40
在 /etc/omniORB.cfg 中进行登录,我们甚至可以在消息中看到不正确的 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
中的端点以清除所有旧引用并重新启动 omni服务。您现在可以从沙盒终端正确 运行 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 之类的调用是从组件传递给您的。我们可以通过将 Domain Machine 上的 SigGen 连接到 Sandbox 机器上的 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 实例上的端点并重新运行 这个实验。这次您获得了数据,因为两个端点都已正确配置。
最后,如果您根本不设置端点会怎样? (正如我想象的那样)来自 omniORB sample configuration file:
By default, no endPoint configuration is defined. In this case the ORB will create just 1 tcp endpoint as if the line: endPoint = giop:tcp:: is specified in the configuration file
和
The host and port parameter are optional. If either or both are missing, the ORB fills in the blank. For example, "giop:tcp::" will cause the ORB to pick an arbitrary tcp port as the endpoint and it will pick one IP address of the host as the host address.
所以你可能会得到非常奇怪的行为。希望这个例子对每个人都有帮助并且很容易运行通过/重现。
现在我们已经完成了,我们可以清理我们的 docker 实例和 docker 网络:
docker rm -f domain sandbox
docker network rm bad_net_1 bad_net_2