HVCS IBM “Hypervisor 虚拟控制台服务器”安装指南

适用于 Linux 内核 2.6.4+

版权所有 (C) 2004 IBM 公司

作者:Ryan S. Arnold <rsa@us.ibm.com>

创建日期:2004年3月2日 最后修改:2004年8月24日

1. 驱动程序简介:

这是 IBM Hypervisor 虚拟控制台服务器“hvcs”的设备驱动程序。IBM hvcs 提供了一个 tty 驱动程序接口,允许 Linux 用户空间应用程序访问运行在同一分区 Power5 ppc64 系统上的逻辑分区操作系统(Linux 和 AIX)的系统控制台。在此硬件上,每个分区配置物理硬件控制台是不切实际的,因此该驱动程序通过指向虚拟终端设备的固件接口来访问系统控制台。

2. 系统要求:

本设备驱动程序使用 2.6.4 Linux 内核 API 编写,只能在此版本或更高版本的内核上构建和运行。

该驱动程序专为在 IBM Power5 ppc64 硬件上运行而编写,不过在编写时也采取了一些措施,将与架构相关的固件调用从驱动程序代码中抽象出来。

系统必须挂载 sysfs,以便用户确定哪些主设备号和次设备号与每个 vty-server 相关联。有关 sysfs 挂载的说明超出了本文档的范围。

3. 构建选项:

hvcs 驱动程序将自己注册为 tty 驱动程序。tty 层会按注册驱动程序请求的数量动态分配一组主设备号和次设备号。默认情况下,hvcs 驱动程序向 tty 层请求 64 个这样的主/次设备号,用于 hvcs 设备节点条目。

如果默认的设备条目数量足够,则可以将此驱动程序直接构建到内核中。如果不够,可以通过将驱动程序作为模块插入并通过 insmod 参数来覆盖默认值。

3.1 内置:

以下 menuconfig 示例演示了如何选择将此驱动程序构建到内核中

Device Drivers  --->
        Character devices  --->
                <*> IBM Hypervisor Virtual Console Server Support

开始内核 make 构建过程。

3.2 模块:

以下 menuconfig 示例演示了如何选择将此驱动程序构建为内核模块

Device Drivers  --->
        Character devices  --->
                <M> IBM Hypervisor Virtual Console Server Support

make 过程将构建以下内核模块

  • hvcs.ko

  • hvcserver.ko

要使用默认分配插入模块,请按以下命令出现的顺序执行它们

insmod hvcserver.ko
insmod hvcs.ko

hvcserver 模块包含特定于体系结构的固件调用,必须首先插入,否则 hvcs 模块将找不到它期望的一些符号。

要覆盖默认值,请使用如下 insmod 参数(以请求 4 个 tty 设备为例)

insmod hvcs.ko hvcs_parm_num_devs=4

在 insmod 上可以指定的设备条目数有一个最大限制。我们认为 1024 目前是允许的服务器适配器的一个合理的上限。这随时可以通过在构建之前修改源文件中的常量来更改。

注意:insmod 驱动程序所需的时间长度似乎与注册驱动程序请求的 tty 接口数量有关。

要移除驱动程序模块,请执行以下命令

rmmod hvcs.ko

将 hvcs 安装为模块的推荐方法是使用 depmod 在 /lib/modules/uname -r 中构建当前的 modules.dep 文件,然后执行

modprobe hvcs hvcs_parm_num_devs=4

modules.dep 文件表明 hvcserver.ko 需要在 hvcs.ko 之前插入,modprobe 会使用此文件以正确的顺序智能地插入模块。

以下 modprobe 命令用于以正确的顺序移除 hvcs 和 hvcserver

modprobe -r hvcs

4. 安装:

tty 层创建了包含为 hvcs 驱动程序分配的主设备号和次设备号的 sysfs 条目。以下 sysfs 目录的 “tree” 输出片段展示了这些数字所在的位置

sys/
|-- *other sysfs base dirs*
|
|-- class
|   |-- *other classes of devices*
|   |
|   `-- tty
|       |-- *other tty devices*
|       |
|       |-- hvcs0
|       |   `-- dev
|       |-- hvcs1
|       |   `-- dev
|       |-- hvcs2
|       |   `-- dev
|       |-- hvcs3
|       |   `-- dev
|       |
|       |-- *other tty devices*
|
|-- *other sysfs base dirs*

对于上述示例,以下输出是 cat hvcs 目录中的 “dev” 条目所得的结果

Pow5:/sys/class/tty/hvcs0/ # cat dev
254:0

Pow5:/sys/class/tty/hvcs1/ # cat dev
254:1

Pow5:/sys/class/tty/hvcs2/ # cat dev
254:2

Pow5:/sys/class/tty/hvcs3/ # cat dev
254:3

读取 “dev” 属性的输出是 tty 层为此驱动程序分配的字符设备主设备号和次设备号。运行 hvcs 的大多数系统已经创建了设备条目,或者 udev 会自动创建它们。

鉴于上面的示例输出,要手动创建 /dev/hvcs* 节点条目,可以按如下方式使用 mknod

mknod /dev/hvcs0 c 254 0
mknod /dev/hvcs1 c 254 1
mknod /dev/hvcs2 c 254 2
mknod /dev/hvcs3 c 254 3

使用 mknod 手动创建设备条目可使这些设备节点具有持久性。一旦创建,它们将在驱动程序 insmod 之前就存在。

在插入 hvcs 模块之前尝试将应用程序连接到 /dev/hvcs* 将导致类似于以下内容的错误消息

"/dev/hvcs*: No such device".

NOTE: 存在设备节点并不意味着为该节点配置了 vty-server 设备。

5. 连接

由于该驱动程序控制提供 tty 接口的设备,用户可以使用任何标准的 tty 交互方法(例如 “cat”、“dd”、“echo”)与设备节点条目进行交互。然而,此驱动程序的目的是提供与 Linux 分区控制台的实时控制台交互,这需要使用能够与 tty 设备进行双向交互式 I/O 的应用程序。

充当终端模拟器或对通过它们传递的数据执行终端类型控制序列转换的应用程序(例如 “minicom” 和 “screen”)不适合提供交互式控制台 I/O。这些程序通常模拟陈旧的终端类型(vt100 和 ANSI),并期望传入数据采用这些受支持的终端类型之一,但它们要么不转换,要么无法_充分_将传出数据转换为调用它们的终端的终端类型(尽管 screen 做过尝试,并且显然可以通过大量的 termcap 调整来进行配置)。

因此,kermit 和 cu 是通过 hvcs 设备与 Linux 控制台进行交互的两个推荐应用程序。这些程序仅充当 tty 设备双向数据传输的管道。它们不要求传入数据采用特定终端类型,也不将传出数据加工成特定终端类型。

为了确保控制台应用程序的正常运行,必须确保一旦连接到 /dev/hvcs 控制台,控制台的 $TERM 环境变量就设置为用于启动交互式 I/O 应用程序的终端模拟器的确切终端类型。如果有人使用 xterm 和 kermit 连接到 /dev/hvcs0,当控制台提示符可用时,应该在控制台上执行 “export TERM=xterm”。这告诉从控制台调用的 ncurses 应用程序,它们应该输出 xterm 可以理解的控制序列。

作为预防措施,hvcs 用户在从设备节点断开 kermit 等应用程序之前,应始终从其会话中 “exit”(退出)。如果不这样做,下一个连接到控制台的用户将继续使用前一个用户的登录会话,其中包括使用前一个用户提供的 $TERM 变量。

vty-server 适配器的热插拔添加和移除会影响使用哪个 /dev/hvcs* 节点连接到各个 vty-server 适配器。为了确定哪个 vty-server 适配器与哪个 /dev/hvcs* 节点关联,每个 vty-server sysfs 条目中都添加了一个特殊的 sysfs 属性。该条目称为 “index”,显示它会揭示一个整数,该整数指代用于连接到该设备的 /dev/hvcs* 条目。例如,cat vty-server 适配器 30000004 的 index 属性会显示以下内容

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat index
2

‘2’ 的这个索引意味着为了连接到 vty-server 适配器 30000004,用户应与 /dev/hvcs2 进行交互。

应该注意的是,由于系统的系统热插拔 I/O 功能,与特定 vty-server 适配器交互的 /dev/hvcs* 条目不能保证在系统重启后保持不变。有关此问题的更多信息,请参阅“问答”部分。

6. 断开连接

作为一项安全特性,为了防止将过时的数据传递到非预期的目标,当 vty-server 与 vty 之间的连接中断时,Power5 系统固件会禁用数据获取并丢弃该数据。例如,当向 vty 输出数据后立即将 vty-server 与 vty 断开连接时,vty 适配器可能没有足够的时间(从其收到数据中断到连接被切断之间的时间)在固件禁用获取之前从固件获取数据。

当 hvcs 用于提供控制台服务时,此行为并不是一个大问题,因为在几乎所有数据写入之后,适配器会长时间保持连接。当 hvcs 用作在两个分区之间传输数据的 tty 管道时[参见下文 Q & A],这是一个大问题,因为向设备 cat 或 dd 数据时的标准 Linux 行为是打开 tty,发送数据,然后关闭 tty。如果此驱动程序在 tty 关闭时手动终止 vty-server 连接,这将在目标 vty 有机会获取数据之前关闭 vty-server 和 vty 连接。

此外,仅在模块移除或适配器移除时断开 vty-server 和 vty 是不切实际的,因为其他分区中的其他 vty-server 可能随时需要使用目标 vty。

由于此行为限制,将 vty-server 与已连接的 vty 断开连接是一个手动过程,需要通过写入下面简述的 sysfs 属性来完成;另一方面,vty-server 对 vty 的初始连接是由该驱动程序自动建立的。从不需要手动建立 vty-server 连接。

为了终止 vty-server 和 vty 之间的连接,需要使用每个 vty-server 的 sysfs 条目中的 “vterm_state” sysfs 属性。读取此属性可显示 vty-server 适配器的当前连接状态。零表示 vty-server 未连接到 vty。一表示连接处于活动状态。

仅当先前读取的 vterm_state 为 ‘1’ 时,向 vterm_state 属性写入 ‘0’(零)才会断开 vty-server 与目标 vty 之间的 VTERM 连接。如果读取的 vterm_state 为 ‘0’,或者向 vterm_state 属性写入了除 ‘0’ 之外的任何值,则写入指令将被忽略。以下示例将展示用于验证 vty-server 连接状态和断开 vty-server 连接的方法

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat vterm_state
1

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # echo 0 > vterm_state

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat vterm_state
0

当设备被热插拔移除以及模块被移除时,所有 vty-server 连接都会自动终止。

7. 配置

每个 vty-server 在 /sys/devices/vio 目录中都有一个 sysfs 条目,它在其他几个 sysfs 树目录中被符号链接,特别是位于 hvcs 驱动程序条目下,它类似于以下示例

Pow5:/sys/bus/vio/drivers/hvcs # ls
.  ..  30000003  30000004  rescan

按设计,固件会向 hvcs 驱动程序通知 vty-server 的生命周期和伙伴 vty 的移除,但不会通知伙伴 vty 的添加。由于 HMC 超级管理员可以动态添加伙伴信息,我们在 hvcs 驱动程序的 sysfs 目录中提供了 “rescan” 更新属性,该属性将查询固件并更新此驱动程序管理的所有 vty-server 的伙伴信息。向该属性写入 ‘1’ 会触发更新。以下是一个明确的示例

Pow5:/sys/bus/vio/drivers/hvcs # echo 1 > rescan

读取该属性将指示状态 ‘1’ 或 ‘0’。一表示更新正在进行中。零表示更新已完成或从未执行过。

此目录中的 vty-server 条目是由固件创建的 32 位分区唯一单元地址。示例 vty-server sysfs 条目如下所示

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
.   current_vty   devspec       name          partner_vtys
..  index         partner_clcs  vterm_state

默认情况下,每个条目都提供了一个 “name” 属性。读取 “name” 属性将显示设备类型,如以下示例所示

Pow5:/sys/bus/vio/drivers/hvcs/30000003 # cat name
vty-server

默认情况下,每个条目还提供了一个 “devspec” 属性,读取时会显示完整的设备规范,如以下示例所示

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat devspec
/vdevice/vty-server@30000004

每个 vty-server sysfs 目录都提供了两个只读属性,它们提供易于解析的伙伴 vty 数据列表:“partner_vtys” 和 “partner_clcs”

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat partner_vtys
30000000
30000001
30000002
30000000
30000000

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # cat partner_clcs
U5112.428.103048A-V3-C0
U5112.428.103048A-V3-C2
U5112.428.103048A-V3-C3
U5112.428.103048A-V4-C0
U5112.428.103048A-V5-C0

读取 partner_vtys 会返回伙伴 vty 的列表。Vty 单元地址编号仅在每个分区内唯一,因此条目会经常重复。

读取 partner_clcs 会返回一个“收敛位置代码 (converged location codes)”列表,它们由系统序列号后跟 “-V*”(其中 ‘*’ 是目标分区号)以及 “-C*”(其中 ‘*’ 是适配器的插槽)组成。第一个 vty 伙伴对应第一个 clc 项,第二个 vty 伙伴对应第二个 clc 项,依此类推。

一个 vty-server 一次只能连接到一个 vty。条目 “current_vty” 在读取时会打印当前选定的伙伴 vty 的 clc。

可以通过向条目写入有效的伙伴 clc 来更改 current_vty,如下例所示

Pow5:/sys/bus/vio/drivers/hvcs/30000004 # echo U5112.428.10304
8A-V4-C0 > current_vty

当 vty-server 已经连接到 vty 时更改 current_vty 不会影响当前的连接。更改将在当前打开的连接被释放时生效。

有关 “vterm_state” 属性的信息已在前面名为“断开连接”的章节中介绍过。

8. 问答:

Q: 涉及 hvcs 的安全问题有哪些?

A: 主要有三个安全问题

1. /dev/hvcs* 节点的创建者有能力将设备条目的访问权限限制给某些用户或组。最好为提供对系统控制台的访问权限创建一个特殊的 hvcs 组权限。

2. 为了在获取控制台时提供网络安全性,建议用户使用安全方法(例如 SSH 或坐在硬件控制台前)连接到托管控制台的分区。

3. 完成控制台操作后,请确保退出用户会话,否则下一个 vty-server 连接(可能来自另一个分区)将体验到先前登录的会话。


Q: 如何多路复用通过 hvcs 获取的控制台,以便其他人也可以看到它?

A: 你可以使用 “screen” 直接连接到 /dev/hvcs* 设备,并在你的机器上使用控制台组权限设置会话。正如前面所指出的,默认情况下,screen 不会为大多数终端模拟器提供 termcap 设置,以提供从终端类型 “screen” 到其他类型的充分字符转换。这意味着基于 curses 的程序可能无法在 screen 会话中正确显示。


Q: 为什么颜色全乱了? Q: 为什么控制字符表现得很奇怪或不起作用? Q: 为什么控制台输出完全奇怪且无法理解?

A: 请参阅前面关于“连接”的章节,了解有关应用程序如何影响字符控制序列显示的讨论。此外,你使用 xterm 登录控制台并不意味着在他之前没有别人用 HMC 控制台 (vt320) 登录过控制台并保持会话登录状态。最好的做法是在获得控制台时,将 TERM 导出(export)为你所用的终端模拟器的终端类型。此外,在断开与控制台的连接之前,请确保从控制台 “exit”。这将确保下一个用户在登录时设置他们自己的 TERM 类型。


Q: 当我尝试将 kermit 连接到 hvcs 设备时,我得到:“对不起,无法打开连接:/dev/hvcs*”发生了什么?

A: 其他某个 Power5 控制台机制与 vty 建立了连接且不肯释放。你可以尝试通过在 HMC 上右键单击该分区并选择“关闭终端(close terminal)”来强制断开控制台连接。否则,你必须找出拥有控制台权限的人。你也有可能已经使用另一个 kermit 会话打开了控制台却忘记了。请查看 Power5 系统的控制台选项,以了解系统控制台可能被占用的多种方式。

或者

A: 另一个用户当前可能没有将连接方法附加到 /dev/hvcs 设备,但 vterm_state 可能显示他们仍然建立了 vty-server 连接。他们需要使用“断开连接”一节中概述的方法释放此连接,以便其他人能够连接到目标 vty。

或者

A: 你用于执行 kermit 的用户配置文件可能没有使用 /dev/hvcs* 设备的权限。

或者

A: 你可能还没有插入 hvcs.ko 模块,但 /dev/hvcs* 条目仍然存在(在没有 udev 的系统上)。

或者

A: 没有与现有 /dev/hvcs* 条目相映射的相应 vty-server 设备。


Q: 当我尝试将 kermit 连接到 hvcs 设备时,我得到:“对不起,拒绝写入 UUCP 锁文件目录的权限。”

A: 你指定的 /dev/hvcs* 条目并不在你所说的地方?也许你还没有插入模块(在有 udev 的系统上)。


Q: 如果我已经安装了一个 Linux 分区,我是否可以在该分区上使用 hvcs 为第二个 Linux 分区的安装提供控制台?

A: 可以,前提是你使用 kermit、cu 或其他不提供终端模拟的程序连接到 /dev/hvcs* 设备。


Q: 使用此驱动程序,我可以同时连接到多个分区的控制台吗?

A: 可以。当然,这意味着必须为此分区配置多个 vty-server,并且每个都必须指向一个未连接的 vty。


Q: hvcs 驱动程序支持设备的动态(热插拔)添加吗?

A: 是的,如果你的系统启用了 dlpar 和热插拔并且它已构建到内核中,则 hvcs 驱动程序被配置为动态处理新设备的添加和未使用设备的移除。


Q: 出于某种原因,/dev/hvcs* 在重启后没有映射到同一个 vty-server 适配器。发生了什么?

A: vty-server 适配器到 /dev/hvcs* 条目的分配始终按照适配器公开的顺序进行。由于此驱动程序的热插拔功能,热插拔添加的 vty-server 的分配顺序可能与它们在模块加载时公开的顺序不同。如果在动态添加后在另外两个 vty-server 适配器之间的插槽中添加了 vty-server 适配器,则重新启动或重新加载模块可能会导致 /dev/hvcs* 与 vty-server 的耦合关系发生变化。请参考上面的章节,了解如何确定哪个 vty-server 对应哪个 /dev/hvcs* 节点。提示:查看 vty-server 的 sysfs “index” 属性。


Q: 我能否将 /dev/hvcs* 用作通往另一个分区的管道,并使用该分区上的 tty 设备作为管道的另一端?

A: 可以,在 Power5 平台上,hvc_console 驱动程序为额外的 /dev/hvc* 设备(其中 /dev/hvc0 很可能是控制台)提供了一个 tty 接口。为了使两个分区之间的 tty 管道正常工作,HMC 超级管理员必须通过 HMC 图形界面为目标分区创建一个额外的“串口服务器(serial server)”,当目标分区重新启动时,它将显示为 /dev/hvc*。

然后,HMC 超级管理员为当前分区创建一个额外的“串口客户端(serial client)”,并将其指向目标分区新创建的“串口服务器”适配器(记住插槽)。这显示为一个额外的 /dev/hvcs* 设备。

现在,可以配置目标系统上的程序以读取或写入 /dev/hvc*,并且可以配置当前分区上的另一个程序以读取或写入 /dev/hvcs*。现在你在两个分区之间拥有了一个 tty 管道。


9. 报告漏洞:

报告漏洞的正确渠道要么是通过提供你所用操作系统的 Linux OS 发行商公司,要么是将问题发布到 PowerPC 开发邮件列表:

linuxppc-dev@lists.ozlabs.org

此请求旨在提供围绕此驱动程序的问题和解决方案的有据可查且可搜索的公开交流,以造福所有用户。