本章介绍对运行 Solaris Resource Manager 的过程中遇到的问题进行诊断的方法。
如果您需要另外的协助,请与您的 Sun 软件支持提供商取得联系。
用户的 nologin 或者 noattach 标志得到设置。
用户的 onelogin 标志得到设置,业已在另一终端或者窗口登录。
用户业已达到连接时间限制。用户必须等到利用率衰变才能再次登录,也可以让管理员更改用户的 terminal.usage 属性或者 terminal.limit 属性,以使用户得到更多终端连接时间。
可能存在用户 lnode,但它可能已被孤立,因为它的父节点 lnode 已被卸除。请参阅孤立 lnode。
上面所列出的 Solaris Resource Manager 限制并不适用于超级用户。
尽管用户能够登录到系统,如果没有对应于用户 UID 的 lnode (没有为此用户的帐户设置 lnode),会出现一条消息标明此问题:No limits information is available.请参考孤立 lnode。
在 Solaris Resource Manager 的正常操作过程中,已登录用户一旦达到某个限制就会收到通知消息。用户可能会没有意识到当前故障的起因,而系统将看似古怪。但是,系统管理员将得到通知。
通知消息的提交是由 Solaris Resource Manager 的守护程序 limdaemon 执行的。如果通知消息未被提交,管理员可以对好几种可能可能性进行调查:
控制台窗口被隐藏。如果用户使用某一具体的窗口登录,然后又打开其它窗口遮盖了登录窗口,则用户也可能会错过提交给其登录窗口的消息。
limdaemon 程序没有运行。
limdaemon 无法为了维持其内部结构而动态分配更多的内存。如果真的如此,则 limdaemon 会在第一次没能获得充足内存时在系统控制台上显示一条诊断消息。它会继续尝试获得内存,但第一次尝试以后再失败,就不再发出消息。
utmp 文件损坏或丢失。limdaemon 需要这个文件才能确定用户所登录的终端,以及向这些终端发送通知消息。如果 utmp 文件损坏或者丢失,则在控制台上报告一个错误消息,并抑制通知消息的提交。
由于某个系统限制,limdaemon 无法提交一条消息。例如,如果 limdaemon 为了提交消息而需要在某个终端上打开一个窗口,但又无法打开,则放弃该消息。
sgroup 属性用于确定 lnode 在调度树中的父节点。该分层结构用于调节资源的利用率和调度 CPU。出于这一原因,为 sgroup 属性的更改设置了多个安全性预防措施,以避免对其进行更改时发生疏忽错误,以及防止绕开 Solaris Resource Manager。
如要修改 sgroup 属性,用户需要有下列特权:
是超级用户
其 uselimadm 标志得到设置
其 admin 标志得到设置,且是正要更改的 lnode 的组长。
孤立 lnode 无法成为其它 lnode 的父节点。请参阅孤立 lnode。
检查是否因以下条件造成了问题:
对于用户的要求而言,用户的管理限制设置得过低。
利用率属性没在衰变。管理员负责确保所有的可更新资源的设备类别均得到衰变(其中包括终端设备类别)。典型情形是通过经常性地执行 limdaemon 命令来实现。如果某一可更新资源没有给予衰变,则该资源的利用率属性会持续增加,一直到达到其限制。
衰减期太长。执行 limdaemon 的频率应设置成适合最短衰减间隔的粒度。
某一可更新资源的衰变属性过小,或者间隔属性过大。如果某一可更新资源在一个给定时间间隔的衰变设置低于该资源的典型消耗率,则利用率属性将逐渐增加,一直到达到其限制。
任何受达到限制影响的用户,均会收到通知消息。因此,如果达到某一组限制,则组长以及分层结构中组长下面的所有用户均将收到一条通知消息。
如果某一用户连接到另一 lnode,则有可能达到限制。该用户不会收到通知消息,但所有其它受影响的用户会收到。受影响的组可能不会晓得该故障的起因。
该故障的最可能的起因是 limdaemon 程序未运行。limdaemon 周期性地为当前所有已登录的用户,对终端设备类别终端利用率和应计属性进行更新。典型情形是,从 Solaris Resource Manager 的 init.d 脚本将其启动。
鉴于系统管理的原因,连接到 root lnode 的进程可被分配其需要的几乎所有 CPU 资源。所以,如果在 root lnode 上连接与 CPU 相关的进程,它就会阻碍 CPU,并造成其它 lnode 上的进程减慢或停止。
可以采取下列预防措施来防止此类情况的发生:
管理员均应登录为管理员正常使用所创建的 lnode,而不能连接到 root lnode 上。如果需要连接到 root lnode,则应小心不得使用任何需要大量耗用 CPU 的应用程序,如编辑程序。要想不连接到 root lnode 就使用某个超级用户的 UID,则管理员可使用 su( 1) 命令。
init.d 脚本不能被更改来使用 srmuser 程序以将所有 daemons 连接到其自身的 lnodes 上,因此它们不能(通过继承)连接到 root lnode 上。不过,不可总推荐此解决方案。这样可能成为一个负担,因为有大量的文件需要编辑,而且这种做法可能会限制以后将修补程序集成到一个系统中的能力。一个不需要手动执行此任务的解决办法正在研究之中。
对于 Solaris Resource Manager 1.0 之后的发行版,在 /usr/srm/unsupport 目录中所提供的脚本 sbin_rc2 和 sbin_rc3 可用来部分解决这个问题。
作为 setuid-root 而运行的程序并不自动连接到 root lnode。通常,该进程保持连接到创建它的父节点的 lnode,而只有有效 UID 被更改。
Solaris Resource Manager 只对 SHR 调度类中的进程的 CPU 使用加以控制。如果其它调度类,特别是 real-time (RT) 和 system (SYS),以较高优先权提出过多要求的话,则 SHR 只能对剩余的 CPU 资源进行调度。
RT 类的使用与 Solaris Resource Manager 软件对系统的控制能力相冲突。实时进程获得对系统的完全访问,特别是为了能够提供实时的响应(通常是几万分之一秒)。依照定义,SHR 类中运行的进程所拥有的优先权比任何实时运行的进程都要低,而 Solaris Resource Manager 并不控制 RT 进程。实时进程很容易就用尽全部的可用内存,使得没有为 Solaris Resource Manager 留下任何资源用于分配给其余的进程。
一个值得注意的完全在 SYS 类中运行的系统服务就是 NFS 服务器。Solaris Resource Manager 无法控制 NFS 守护程序,因为它们是在 SYS 中运行的。在提供广泛的 NFS 服务的系统上,Solaris Resource Manager 产品的分配处理器资源的能力可能会被削弱。
在进程(在系统调用内)执行内核代码时,通常的时间片抢先规则并不适用。大多数系统调用只是进行了适中数量的工作就到达了一个抢先点。但是,如果系统承担的是更加剧烈的系统调用的高负载,则有可能导致整体响应下降,并且是在调度类的控制范围之外。
如果系统缺乏可用的物理内存,则随着页面故障率以及进程交换的增加,所导致的 I/O 瓶颈使得内核的 CPU 消耗增加。等候 I/O 时间太长,可能意味着 CPU 负载能力的损失。而这又是在调度类的控制范围之外。
SHR 调度类是一个分时 (TS) 调度程序。其所使用的全局优先权范围与 TS 和交互式的 (IA) 调度程序相同。除在将所有的进程移入或移出 SHR 类的过渡期间之外,把 SHR 与 TS,LIA 混在一起使用是不合适的。SHR 和 TS 类混合进行系统操作,将使两类的调度性能均遭到削弱。出于这个原因,Solaris Resource Manager 防止非 root 进程将其自身或者其它进程移到 TS 或者 IA 类。RT 类使用一个替代性的优先权范围,可以与 SHR 类一同使用,就象与 TS 和 IA 类一同使用那样。
如果超级用户所运行的进程包含直接使用 priocntl(2) 系统调用的代码,而不是使用 setpriority(3C) 库例行程序来调节进程优先权,则目标进程就可能被移动到另一个调度类(一般是TS)之中。 setpriority 库例行程序代码说明一个事实,即至 SHR 的 priocntl 接口是与 TS 二进制兼容的,并因此避免了出现问题。ps1 的 -c 选项或 priocntl(1) 的 -d 选项可用于显示进程的调度类。
显式地使用 priocntl(2) 来管理进程的调度类成员资格的超级用户特权进程也存在同样的难点。
一个被孤立的 lnode 就是有不存在的父节点 lnode 的 lnode。这是管理员应该关心的问题,因为 Solaris Resource Manager 能防止进程连接到被孤立的或在调度树中有被孤立的前辈的任何 lnode上。
内核对 sgroup 属性的变化进行检查,以避免由于对调度组父节点的变更而创建孤立 lnode。
孤立一个 lnode 的主要后果在于,它可能不再拥有任何连接的进程。鉴于无法连接任何进程,该 lnode 也就无法用于登录。借助相对应的帐户尝试登录将会失败。
管理员可以用来监测孤立 lnode 的最为便利的方法是使用带内置孤立识别符的 limreport 命令。命令:
% limreport orphan - uid sgroup lname |
会列出拥有孤立 lnode 的用户的 UID、调度组父节点和登录名称。sgroup 属性可以用于确定是哪个 lnode 位于树的孤立部分的顶部。
管理员在发现一个孤立 lnode 时所应采取的第一个步骤就是,找出调度树的孤立部分的顶部,因为这正是需要重新附加的 lnode。如果没能正确识别孤立部分的顶部,则会只有孤立部分的一部分被重新附加到树。
一旦确定了孤立部分的顶部,拥有充足特权的管理员就可以使用 limadm 来将最顶端的孤立 lnode 的 sgroup 属性设置为调度树内的一个有效的 lnode。这将促使孤立 lnode 作为有效 lnode 所带领的组的一个成员而重新附加到树。 limadm 用于验证所要应用的新的调度组父节点可以被激活,以便确保所更改的 lnode 不会再次被孤立。
作为替代方案,管理员也可以创建一个新的用户,其 UID 等于孤立 lnode 的 sgroup 属性中的 UID。这将促使树的孤立部分自动重新得到附加。
当一个 lnode 被激活后,在 root lnode 以下的其所有父节点均被激活。作为这个进程的结果,如果看到 lnode 中的某一个有以前曾经遇到过的父节点,则内核就发现了一个 组循环。
如果限制数据库遭到损坏,则有可能出现组循环,即某一 lnode 的某一前辈还是它的一个子节点。当内核发现一个组循环时,内核会毫无声息的自动将其断开,将其作为一个组连接到 root lnode 的底下,从而将循环连接进调度树。内核无法确定哪个是最顶层的 lnode,因为该循环没有起始和终止。这意味着,位于循环连接到调度树处的 lnode 变成了最顶层组的一个组长。该组的成员就有可能继承特权或者获得本来无法得到的更高的限制。
在设置调度组父节点时使用 limadm 就可以避免组循环。造成组循环的唯一原因就是限制数据库遭到损坏。这是一个严重的故障,可能会在 Solaris Resource Manager 导致各种各样其它的困难,因为限制数据库是 Solaris Resource Manager 操作的根基。
就调度树的结构而言,该故障是自行更正的,因为内核将该 lnode 附加到 root lnode 上。鉴于附加是从循环的随意一点进行的,管理员必须确定应当在哪里附加 lnode,并且应当检查循环中其它每个成员的附加点。
列出是 root lnode 的子节点的 lnode 就能看到自动组循环修理的结果。命令:
% limreport 'sgroup==0' - uid lname |
可列出有 root lnode 做为父节点的所有 lnode。如果列出任何不应为 root lnode 的子节点的 lnode,则它们可能是已经附加到 root lnode下方的组循环的顶端。
因为组循环的起因是限制数据库出现了损坏,所以当一个组循环被监测到时,管理员主要关心的就是有可能出现许多更为严重的故障。如果管理员怀疑是限制数据库出现了损坏,则最好对该文件进行某些有效性检查,以确定其是否已遭到损坏,然后采取补救措施。请参考 崩溃恢复,了解有关监测和更正损坏限制数据库的细节。
要验证被系统分配给 srmidle、srmlost 和 srmother 的 UID 并未与任何现有 UID 冲突,请键入:
# /usr/bin/egrep 41\|42\|43 /etc/passwd |
如果存在冲突,则您可通过编辑口令和阴影文件 /etc/passwd 和 /etc/shadow 修改 UID。
当 Solaris 系统出现某一故障时,管理员会有许多当务之急,但所使用的系统是 Solaris Resource Manager 时,则需要进行其它一些考虑。其中有:
可能因为磁盘错误或者其它某个原因,限制数据库业已遭到损坏。
在系统发生故障,特别是与连接时间利用率相关时,运行 limdaemon 就可能造成故障。
下面几节探讨上述问题的细节,并为把握局势提出一些合适的建议。
Solaris Resource Manager 对限制数据库的维护是可靠的,一般不会发生崩溃。但如果真的发生崩溃,则这就是管理员的主要当务之急,因为该数据库对于 Solaris Resource Manager 的运行非常重要。应该对任何潜在的崩溃进行调查,一旦检测出来就应该加以修复。
只根据一项症状是不可能可靠地确定限制数据库是否已经崩溃的,但是有若干种因素可以潜在地表明限制数据库的崩溃:
Solaris Resource Manager 内核对组循环进行的检测可以很好地表明限制数据库已经崩溃。组循环受到 Solaris Resource Manager 的严格预防,只有当 sgroup 属性以某种方式发生崩溃时,它们才可能发生。有关详情,请参阅组循环。
用户在尝试登录时会看到屏幕上显示'没有限制信息可供使用'信息,用户登录被拒绝。如果限制数据库使其 flag.real 属性被清除,并有效地删除了其 lnode,则这样的情况就会发生。它不仅会影响被删除的 lnode,而且还能影响任何被孤立的 lnode(有关详情,请参阅 孤立 lnode)。请注意,只有当没有为帐户创建 lnode,或当 lnode 被故意删除后,才会显示'没有限制信息可供使用'信息,所以它并不能清楚地表明限制数据库已经崩溃。
利用率或限制属性中突然出现不真实的数值。这会导致某些用户突然出现限制。
用户突然抱怨因为特权标志的崩溃而失去了特权或未预期的特权。
如果管理员怀疑限制数据库发生了崩溃,检测崩溃的最好方法就是使用 limreport 请求其属性应具有在已知范围内的数值的 lnode 列表。如果报告了该范围之外的值,则损坏已发生。limreport 还可用来列示拥有清空的 flag.real 的 lnode。这将显示不存在 lnode 的口令映射中的帐户。
当检测出崩溃后,管理员应采用限制数据库的未崩溃版本。如果崩溃仅限于限制数据库的一小部分,则管理员就能保存所有其它 lnode 的内容,并采用 limreport 和 limadm 命令把它们重新装载到刷新的限制数据库中。如果没有限制数据库的最新副本,则这样做就是最好的方法,因为新的限制数据库现在包含最新的利用率和应计属性。保存和恢复限制数据库的步骤如 第 5 章,管理 lnode所示。对于丢失了 lnode 等简单情况,只需使用 limadm 命令重新创建 lnode 就足够了。
如果 limdaemon 因某种原因而中断,则当前登录的所有用户都将停止对任何连接时间利用率的计费。此外,当 limdaemon 重新启动时,已经登录的任何用户将继续免费使用这些终端。这是因为守护程序必须依靠来自 login 的登录通知才能在其用于计算连接时间利用率的内部结构中建立 Solaris Resource Manager 登录对话记录。所以,无论何时,只要它启动,则在接收到第一个通知之前就不会建立 Solaris Resource Manager 登录对话。
一般地,如果 limdaemon 因为系统崩溃而中断,这就不会构成问题,因为崩溃也会使其它进程中断。这样,登录对话在系统重新启动之前就不能重新开始。
如果 limdaemon 因某些其它原因而中断,则管理员有两个选择:
立即重新启动守护程序,并忽略已经登录的用户的终端连接时间的丢失计费。这可能表示除非被标识或退出,否则用户就能无限期免费使用一个终端。
使系统返回单用户模式,然后再返回多用户模式,从而确保所有当前登录对话均被中断,且用户只能在守护程序重新启动后重新登录。