经过一番努力之后,我得到了一个无盘服务器 2012,它通过 MS 软件 iSCSI 启动器运行,并通过从 NIC 的 PXE 链接的 gPXE 启动。
但是,现在它已正常启动,但我又遇到了另一个问题(iSCSI HBA 变得越来越有吸引力)。服务器有双 NIC,而 Windows 只接受连接到 SAN 的 NIC,导致我没有 LAN 连接!
设备管理器显示两个 NIC,但 LAN 的 NIC 上有一个感叹号,并且属性显示“此设备无法正常工作,因为 Windows 无法加载此设备所需的驱动程序。 (代码 31)”
显然是 Windows做有正确的驱动程序,因为两个端口是相同的,另一个端口正在工作;此外,如果我将相同的操作系统安装到相同的硬件上,但安装到本地硬盘上,网卡就不会出现问题。如果我告诉它搜索更好的驱动程序,它就会转过身来,说驱动程序没问题,这并不奇怪。
我很确定我知道这里发生了什么,这要感谢这次冒险的前几章。
预启动程序(本例中为 gPXE)必须将 iBFT(iSCSI 启动固件表)写入内存,然后操作系统(本例中为 Windows)会获取该表。该表提供了网卡列表等信息。对于每个网卡,它指定了 PCI 总线和设备号、MAC 地址和 IP 信息。
通过检查其源代码(以及我开发的用于转储 iBFT 的小工具),我得知 gPXE 出于设计/懒惰,只会将一个 NIC 写入 iBFT,尽管标准允许大约 240 个 NIC。即使它确实写入了多个 NIC,我仍然会遇到同样的情况,因为其他 gPXE/iPXE 问题迫使我使用仅 UNDI 版本,这意味着它甚至不知道其他 NIC。
我假设这里发生的事情是 Windows 正在查看 iBFT,尽管它从自己的设备管理系统中知道另一个 NIC 存在,但它决定不能使用它,因为它不在 iBFT 中。我不知道为什么它会这样做。
是否有某种方法可以诱导 Windows 使用其他 NIC,即使它不在 iBFT 中?或者,是否有一些 iSCSI 预启动程序可以正常工作?或者有完全不同的解释吗?
答案1
我终于搞清楚了这个问题,并设法让它正常工作。不过,在此过程中,我得出的结论是,Windows、gPXE 和 iPXE 中的 iSCSI 启动功能都是半生不熟的。我将分享对我有用的方法,以防它对其他人有所帮助,但请注意一些注意事项:
这是一个糟糕的解决方案。 基于硬件的解决方案(例如 iSCSI HBA)将提供更好的性能和稳健性,并且设置起来也更加容易。
这种解决方案不适用于大规模部署,主要是因为每个无盘服务器的设置需要太多的人工。
这个解决方案并不那么简单。可能有一个更简单的解决方案(除了显而易见的,使用 iSCSI HBA)。如果您知道一个,请添加它,如果我可以复制它,我会将你的答案标记为答案。
这个解决方案实在是太丑陋了。 使用风险自负!!
在继续之前,我想澄清一下,任何时候我说“NIC”,我指的是 Windows 认为的单个“设备”,但实际上可能只是实际 NIC 上的几个端口之一。这个术语与 iBFT 标准本身和 iPXE/gPXE 一致。
当 Windows 在其 iSCSI 启动器上启动时,它对 iBFT(“iSCSI 启动解决方案”在调用 Windows 启动加载程序之前写入内存的表,该表告诉它如何访问 iSCSI LU)有一些非常严格的要求。我已经能够拼凑出一些“陷阱”规则(这些规则可能适用于您的特定情况,也可能不适用):
如果 NIC 不在 iBFT 中,Windows 将无法使用它。它将表现出问题中给出的症状。
iBFT 中的 NIC 列表必须按特定顺序排序。我没有完整的详细信息,因为我在测试服务器上只有两个 NIC 端口,位于同一个 NIC 上。一个是 PCI
08:04.0
,另一个是 PCI08:04.1
。如果 iBFT 将 的 NIC 列08:04.1
在 的 NIC 之前08:04.0
,Windows 就会发疯。(请注意,标准中没有任何内容要求给定顺序。)iSCSI 目标必须能够从第一的iBFT 中列出的 NIC。根据上述规则,这可能需要您切换 SAN 和 LAN 端口。
如果 iBFT 中的第一个 NIC 与 Windows 首次安装时的不同,它将崩溃并重新启动。如果您最初的设置不正确,这可能需要您重新安装 Windows。(我不确定什么构成“相同”,但同一 NIC 上的不同端口肯定不是“相同”。)
NIC 部分在内存中的出现顺序必须与控制部分中列出的顺序相同,否则 Windows 会发疯。(请注意,标准确实不是规定顺序必须匹配 —— 再次强调,这只是 Windows 的懒惰。)
第一条规则是关键。无论是 gPXE 1.0.0 还是其继任者 iPXE 在 2013 年 1 月 31 日的提交,曾经将多个 NIC 写入 iBFT,即使他们知道有多个 NIC。我已通过检查其源代码验证了这一点。
我的解决方案是获取 iPXE 源代码树,然后修改程序,使其将第二个 NIC 部分写入 iBFT,与我服务器中的另一个 NIC(我使用的 NIC)相对应不是启动时。)我只是硬连线了 MAC 地址和 PCI 地址。我发现没有必要将 IP 地址放入 NIC 部分 - 只需将其全部留零,Windows 将在启动时稍后分配它。(请注意,IP 地址做需要为 SAN NIC 编写,但 iPXE 已经编码来执行此操作。)
通过使用#define
,可以将实际地址输入到一些方便的地方,而不必每次想要更改它们时都挖掘源代码。
如果您进行了此更改,请注意 NIC 部分在其标头中有一个索引字节。iPXE 代码不会触及这些(尽管在中给出了struct
),因为它永远不会写入多个 NIC,但如果您写入第二个 NIC,则需要将其索引字节设置为 1,否则 Windows 将不高兴。
该解决方案的明显缺点是您必须为每个服务器重新编译 iPXE,在 TFTP 服务器上保留这些单独的 iPXE 版本,并配置 PXE 服务器以向每个服务器发布不同的启动程序。
进行初始更改需要一些 C 编程知识,以及 Linux 发行版和 GNU 开发工具。iBFT 格式指定这里。
我希望我可以在这里发布我的更改,但实际上我最终更改了一个非常旧的版本,ipxe.org 网站诱骗我下载了该版本。(显然,他们从不标记稳定版本;从那时起我了解到主分支上的所有版本都是稳定的。)我宁愿不鼓励任何人使用这样的旧版本。
最新版本仍然有同样的限制。我会将此转发给他们的开发列表,希望它能得到修复。