适用于 Solaris 2.6 (SPARC 平台版) 的 Solaris Resource Manager 1.0 系统管理指南

第 5 章 管理 Lnode

Solaris Resource Manager 系统是围绕着对核心的一个根本性补充而建立的:一个称作 lnode 的针对每一用户的结构。针对口令映射中所定义的每一个唯一的UID,均应当存在一个对应的 lnode。(这是连续调用 getpwent(3C)所返回的每个唯一的 UID。)也可能存在没有口令映射条目与之对应的 lnode,但不建议这种情形。lnode 存储在磁盘上,并由核心自动移进或者移出内存。lnode 的内存内副本如果自从从磁盘读出之后发生过改变,则会写回磁盘,作为定期系统同步操作的一部分,运行 sync(1M)命令发出请求时,或者为了读取其它的 lnode 而需要释放 lnode 高速缓存中的空间。一个 lnode 必须是一个大小固定的地方,其中可以存储有针对每一用户的多种数据,并进行更新。

Lnode是作为一个树状的分层结构而加以维护的,中央管理员是树的头目,而其他用户是树内较小的用户组的组头目。中央管理员是超级用户,或者系统的根用户。

与 lnode 有关的错误,诸如孤立或者组循环,在 第 9 章,故障排除 中有论述。

代理管理

对 lnode进行管理的主要责任落在中央管理员的肩上。 Solaris Resource Manager 在引进多个可以进行指派和管理的资源控制的同时,还允许有选择地将某些管理特权赋予非根用户,从而分散用户管理的负担。管理特权可以赋予适合的用户,方法是设置用户的 uselimadm 或者 admin 标志。uselimadm 标志经过设置的用户,在 limadm(1MSRM)程序中拥有与超级用户一样的管理特权。而 admin 标志经过设置的组头目用户称作分管理员,拥有高于其调度组内用户的特权(下面有描述)。

中央管理员为将根为作其父节点的调度组创建和指派限制,从而对系统资源的整体分割进行控制。分管理员通常是进行同类的资源控制,但只限于其调度组内的用户。而由分管理员分割的资源,只限于业已分配组的资源(例如,分配给组头目 lnode 的资源)。注意,一个分管理员可以将 admin 标志指派给其调度组内的任意用户,从而进一步将其自己的管理责任分摊出去)。

分管理员可以进行如下操作:

  1. 创建和删除其调度组内用户的 lnode。

  2. 更改其调度组内任意用户的资源限制。

    注意,尽管某个分管理员可以将某个资源的限制设置为大于组的限制,但组成员所消耗的资源,也同样认为是组头目消耗的,而对单个用户的限制也同样适用于超过组头目限制的企图。

  3. 更改其调度组内的任意 lnode 的标志,只要该标志没有 noadmin 条件。无法向某一用户赋予分管理员尚未拥有的特权,在这一点上分管理员所进行的标志指派进一步受到限制。应用该限制,是为了避免分管理员绕过 Solaris Resource Manager 内的安全机制。

  4. 对拥有 selfadmin 条件的其自己的属性进行调整。

分管理员的主要工具是 limadm(1MSRM)limreport(1SRM) 命令。limadm 程序用于对一个或者多个现有用户的限制、标志以及其它 Solaris Resource Manager 属性进行操作。这些工具与报告生成器 limreport 一起使用,就可以让调度组进行自治性自我管理,而无需触动其它的不相交的调度组的资源分配或资源管理。

超级用户豁免于所有的资源限制,无论其标志设置如何,均总是拥有完全的管理特权,借助 limadm 程序,可以添加、删除和更改用户帐户,且能够更改任何 lnode 的利用率、限制或者标志值。

安全

Solaris Resource Manager 对 Solaris系统管理有着广泛的影响,因而安装和维护时要确保系统的安全,这一点十分重要。

有若干方法可供系统管理员用来确保 Solaris Resource Manager 系统的安全得到维护。对于任何 Solaris系统来讲,最为重要的是确保根口令的隐秘。任何人只要知道根用户的口令,就可以不受限制地访问系统的资源,就如同中央管理员一样。

有将若干特别的管理特权可以赋予 Solaris Resource Manager 内的用户,方法是设置这些用户所在的 lnode 内的某些系统标志。这样做可能有助于提高某一系统的安全性,因为这允许代理用户执行需要他们执行的任务,而无需赋予他们完全的超级用户特权。

不要轻易赋予某些特权,因为这会给予收到特权的用户广泛的权力。应当积极地对拥有特殊特权的用户的口令加以保护,就象保护根用户的口令一样。

有些时候,如果中央管理员对调度树的结构操作不慎,则有可能使系统的安全遭到破坏。让中央管理员了解如何正确地修改调度树,以及如何在当前的结构中监测到潜在的故障,均十分重要。

uselimadm admin 标志

中央管理员可以借助一个用户的 lnode 中的 uselimadm admin 标志,在 Solaris Resource Manager 内部指派管理特权。 limadm(1MSRM)命令使用 uselimadm 标志,使得用户拥有与中央管理员相同的管理特权。而如果为某一组头目设置 admin 标志,则使得该组头目拥有高于其所带领的组成员的管理特权,但不允许其对其组外的任何 lnode 的内容进行更改。

admin标志得到设置的组头目称作分管理员。在 Solaris Resource Manager 内可以采取多个安全防范措施,以避免分管理员滥用赋予其的管理特权:参考 "典型的应用程序服务器""Lnode 维护程序" ,了解详尽的解释。

分管理员删除 lnode 时,应当确保将子树从最低部的 lnode 往上全部删除。如果您从正要删除的子树的顶部开始,您就会丧失对所删除的 lnode 的子节点的控制,因为它们因其父节点被删除而遭到孤立。lnode 一旦遭到孤立,分管理员就无法对其进行更改,因为它们位于调度组之外。

建议的分管理员 lnode 结构

分管理员可能遇到的一个问题是,他们与其组成员共享组限制。例如,如果组头目 lnode 设置有进程限制,则该限制也控制着整个组所能使用的进程的数目,其中包括组头目。除非进一步加以限制,否则调度树的任意用户只要超过其自身的进程限制,就可以阻止分管理员创建新的进程。对此加以防范的一个方法就是让组管理员为每个组成员设置单个的限制。但是,这些限制如要发生作用,就不得不是过渡限制性的。另外,强迫分管理员管理单个的限制,有悖于 Solaris Resource Manager 的分层结构资源控制的目标。解决该问题的一个替代性方法就是让管理员改变其组的lnode 的结构。他们不是将用户直接置于其自身的 lnode 的下面,而是在其自身下面创建一个"控制"lnode,作为其唯一的子 lnode,然后使用户成为该控制 lnode 的子节点。这样就促成了所显示的结构。

图形 5-1 分管理员lnode结构

Graphic

参考上图,分管理员帐户的 UID 与标记为 "实际的" 的 lnode,即树的父节点的 UID 相对应。这就是 admin 标记得到设置的 lnode。要为该"控制"lnode创建一个哑帐户。无需允许该帐户拥有登录权利。标记为 "A"、"B" 和 "C"的 lnode与分管理员控制下的用户相对应。

在这种情况下,"实际的" lnode 的进程限制可以是100,"控制"lnode 可以是90,而单个用户的限制设置为0。这样设置是为了确保,即使用户A、B 和 C 总共使用了90个进程(且全部得到允许),但分管理员仍旧可以创建10个进程。在这种情况下,用户仍旧有可能彼此阻止创建进程。对此加以防止的唯一方法是为这些用户设置单个限制。但在此例中,可以将限制设置为40,从而在防止单一的用户完全饿死其它用户的同时,仍旧留有灵活性。在此例中,请另外注意,分管理员可以为新的用户创建更多的 lnode,作为"控制"lnode 的子节点,而不必担心重新平衡的限制。

限制数据库

限制数据库是用户信息的数据库, Solaris Resource Manager 用于进行所有的资源控制。其中为每个 UID 包括有一个 lnode,将该 UID 作为进入文件的一个直接索引,对 lnode 进行访问。如果某个数值较大的 UID 有一个 lnode,则限制数据库会看起来很大。但是,在系统中用户的 UID 并非连续的情况下,在一个对此予以支持的文件系统类型上,限制数据库会有很大的缝隙或者空洞。这意味着,并未实际为存储该文件的"空白"部分分配任何磁盘块。ufs 文件系统支持稀疏文件,但 tmpfs 文件系统不支持。请参阅下面 "保存和恢复限制数据库" 中的讨论,了解稀疏文件对于保存和恢复限制数据库的含义。

您每创建一个新的用户,就必须创建一个新的 lnode。

创建限制数据库

Solaris Resource Manager 启动文件(/etc/init.d/init.srm)在第一次被调用时,会创建一个初始的限制数据库。而如果发现该文件丢失,则会在任何启动时加以创建。

典型情况是,限制数据库位于 /var/srm 目录中。

限制数据库应当为根、根所拥有的组所拥有,且只能由其拥有者进行读取。无需写入许可,因为只有拥有超级用户凭证的核心代码写入该文件。


小心:小心:

如果某个用户可以写入 Solaris Resource Manager 限制数据库,则系统安全性就有可能遭受威胁。


保存和恢复限制数据库

因为限制数据库可能是一个稀疏文件,所以在复制该文件时应当谨慎。如果进行写入的是一个并不支持稀疏文件的实用程序,则该文件很有可能消耗大量的磁盘空间,原因在于文件的空白区域会读作连续的零,且写回时是作为真正的块,而不是空白区域。如果文件是通过诸如 tar(1)cpio(1)或者 cp(1)这样的实用程序进行复制、备份或者恢复的,则有可能发生此类情形。但诸如 ufsdump(1M)ufsrestore(1M)的程序可以保持空洞。

进行限制数据库备份和恢复,也可以借助 limreport(1SRM),生成文件的一个 ASCII 版本,然后借助 limadm(1MSRM),从所保存的 ASCII 版本,重新创建原来的文件。例如,命令:

limreport 'flag.real' - lname preserve > /var/tmp/savelnodes 

将创建 /var/tmp/savelnodes,用作口令映射中每个用户的 lnode 的 ASCII 代表。注意,这并不保存没有相对应的口令映射条目的 lnode。建议至多只为口令映射中的全部 UID 创建 lnode。

命令

# limadm set -f - < /var/tmp/savelnodes

将重新创其建数据以前得到过保存的 lnode。该命令不会删除未经保存的 lnode,所以这些技巧也可以用于保存和恢复所选的 lnode,而不是整个限制数据库。

"limreportlimadm 命令" 更加详细地描述 limreport(1SRM)limadm(1MSRM)的使用方法。用于让管理员熟悉用这些命令来保存和恢复 lnode 的方法,因为在对 lnode 结构的解释进行改变时有可能用到这些命令(其定义见于配置文件)。

注意,随着限制数据库在正常的系统启动过程中经常发生变化,建议在系统静止或者正处于单用户模式时进行备份操作。同理,对整个限制数据库进行恢复,只应在 Solaris Resource Manager 未在使用时进行,诸如系统正处于单用户模式时。

创建和删除 lnode

每创建一个新的用户,就应当创建一个相应的 lnode,并设置其限制和特权。只有创建了 lnode,用户才能登录。在使用 Solaris Resource Manager 时,管理员应当在维护常规的 Solaris 口令数据库的同时,也对限制数据库进行维护。命令:

# limreport \ !flag.real - uid lname 

可以用来打印出没有对应 lnode 的用户的 UID 和登录名称列表。

在本版本中,用于创建和删除帐户的系统命令并不自动创建和删除 lnode。要由管理员来进行这些操作。但是,用户登录时,可以根据要求自动创建 lnode,请参阅 "PAM 子系统",了解更多的细节。

同理,就在从口令映射中删除某一用户帐户之前,应当从限制数据库删除其对应的 lnode,方法是使用 limadm(1MSRM)命令。

如果某个用户的 UID 被更改,则应当将其 lnode 的内容复制到一个与新的数字相对应的新的 lnode,并将原来的 lnode 删除。请参考 "复制和删除 lnode"

任何子 lnode 均应当附加到新建的 lnode,或者附加到其它合适的父 lnode。命令:

# limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f - 

可以用来查找其调度组父的 UID 为 X 的所有 lnode,并使其成为 UID 为 Y 的 lnode 的子节点。

下面的步骤演示的是将某一 lnode 的 UID 从 X 更改为 Y。

  1. 保存所要更改 UID 的 lnode 的状态:

    # limreport 'uid==X' - lname preserve > /var/tmp/savelnode.X

  2. 将该用户的口令映射条目的 UID 从旧的值(X)更改为新的值(Y)。

  3. 为新的 UID 创建一个 lnode,恢复先前所保存的状态:

    # limadm set -f /var/tmp/savelnode.X

  4. 针对将要更改的 lnode(UID X)的所有子 lnode,将其调度组更改到新的 lnode(UID Y):

    # limreport 'sgroup==X' '%u\tsgroup=Y\n' uid | limadm set -u -f -  

  5. 确保当前没有任何进程附加到旧的 lnode。请参阅 "创建和删除 lnode "

  6. 使用 chown(2)命令,将所有由原来的 UID 拥有的文件的拥有者,更改为新的 UID的拥有者。例如:

    # find / -user X -print | xargs chown Y

  7. 删除旧的 lnode:

    # limadm delete X

Lnode 维护程序

limadm 命令是管理员用来维护用户的 lnode 的主要工具。该命令对某一列表的用户帐户的 Solaris Resource Manager 属性值进行更改。如果有任何用户的 lnode并不存在,则先创建一个用默认值填充的空白 lnode。新的 lnode 创建时带有如下属性:

新的 lnode 的调度组设置为 limadm 的调用者,条件是该用户是一个分管理员;否则(如果调用者是或者其 uselimadm 标志得到设置),则设置为用户其它,条件是该用户帐户否则设置为根 lnode。

limadm 调用者需要足够的管理特权才能进行所指定的更改。其必须是超级用户,有一个得到设置的 uselimadm 标志,或者是分管理员,且只是要更改其调度组成员的属性。分管理员使用 limadm 时受到限制:

limadm 命令使得管理员可以删除某一 lnode,而不删除口令映射中相对应的用户帐户。如要使用 limadm,调用者必须是超级用户,有一个设置过的 uselimadm 标志,或者有一个设置过的 admin 标志。如果调用者有一个设置过的 admin 标志,则其只能删除其为组头目的用户的 lnode。

单位

Solaris Resource Manager 内的值是用三种单位来表示的。

已缩放

已缩放单位是默认的易于认读的格式,用于显示和输入值。已缩放单位减少了需要录入的数位的数目,有助于用户避免输入错误。

原始(或者未缩放)

原始单位是表示数值的基本单位。例如,虚拟内存的原始单位是字节,而应计虚拟内存的的原始单位是字节-秒钟。这主要是在为利用率计费而需要精确的数量的时候使用。

内部

内部单位用于 Solaris Resource Manager 以针对具体机器的单位存储内存属性,而不是以字节为单位。

转换

Solaris Resource Manager 程序在用于存储属性值的内部单位之间进行转换,从而呈现给用户的总是已缩放单位或原始单位。这意味着,除个别情况外,用户几乎无需关心 Solaris Resource Manager 所使用的内部单位。

exa、peta、tera、giga、mega和 kilo 这些名词用于 Solaris Resource Manager 内部表示二的乘方,而不是10的乘方。例如,一个 megabyte (兆字节)是1,048,576字节,而不是1,000,000 字节。上述每个名词的二的乘方分别为60 (exa)、50 (peta)、40 (tera)、30 (giga)、20 (mega)和 10 (kilo)。

用户和 Solaris Resource Manager 系统之间的主要接口程序为:limadm(1MSRM)liminfo(1SRM)limreport(1SRM)。其所进行的转换和缩放,在下面几个分节中有详细表述。

limadm命令

在更改属性值时,limadm 允许将数字后面缀有缩放字符:[EPTGMK][B][.][wdhms]。大写和小写之间可以互换。如果属性拥有存储(内存属性)或者应计存储的尺寸,则允许有一个来自第一组(EPTGMK)的字符,再根据适当情况,乘以一个 exabyte (E)、petabyte (P)、terabyte (T)、gigabyte (G)、megabyte (M) 或者 kilobyte (K) 所包含的字节数目。为了便于人阅读,还可以附加可选的B字符,但其不起任何作用。如果属性拥有时间(日期或者时间类型)或者应计存储的尺寸,则允许有来自第二组的字符。在根据适当情况,乘以星期 (w)、天 (d)、小时 (h) 分钟 (m) 或者秒钟 (s) 所包含的秒数。可以用一个可选的半角句号分隔存储和时间单位(例如,mh、M.h 和 MB.h 均代表"兆字节小时"。当使用 M 后缀产生歧义时, limadm 试图从上下文推导出其含义。如果不可能,则假设为 mega(兆),而不是 minutes(分钟)。

在输入大数目时,这些转换字符有助于避免在录入量极顺序上发生错误,但无论其录入方法如何,数量均是以内部单位存储的。

还可以单独使用一个特殊的缩放字符 u,只能用于内存属性值。其所指示的数字是针对具体机器(内部)的单位,而不是字节。

liminfo 命令

liminfo(1SRM)命令报告时所使用的后缀与 limadm(1MSRM)输入时所使用的的后缀相同(见上述)。通常,liminfo 将值转换成适当的已缩放格式,以供打印输出,但可以用 -r 选项来促使 liminfo 以原始(未缩放)形式打印值。例如,通常会将内存缩放到一个合适的单位,诸如兆字节(例如,"102 MB"),但指定 -r 选项,将促使其以字节为单位进行打印(例如,106954752 字节)。

limreport 命令

limreport(1SRM)命令总是以其原始(未缩放)格式报告值。如果需要已缩放值,则在用于打印值的表达式中,必须明确地声明进行转换。例如,如要用兆字节显示所有用户的虚拟内存利用率,四舍五入到最靠近的兆字节:

# limreport 'flag.real' '%-8.8s %d KB\n' lname '(memory.usage+1k-1)/1k' 

正如此例所示,表达式中的数字是允许使用缩放后缀的,从而简化原始单位到已缩放数值的转换。

注意,某些属性的内部单位与其"原始"形式并不相同。通常,这无需用户注意,因为是 Solaris Resource Manager 程序进行从已缩放单位到原始单位的转换,但是这意味着,举例而言,limreport 中的选择表达式指定对字节数目进行精确的匹配,如果所指定的数目并非相关内部单位的一个整数乘积,则匹配总是失败。

操作 lnode

limreportlimadm 命令

limreport(1SRM)limadm(1MSRM)命令向管理员提供了一个极其简单的方法,用于为任意数目的用户保存和恢复 lnode 的内容。limreport命令用于选择和提取所要保存的 lnode,而 limadm 用于对其进行恢复。这一组命令的最为常见的用途是复制 lnode,以及改变 lnode 结构。

limreport命令为选择和显示用户的属性提供了一个灵活的方法。提供有两级的选择:选择 lnode,以及选择每个已选 lnode 所要显示的属性。lnode 选择是通过指定一个选择表达式,这可以是单个条件,也可以是以 C 风格句法用逻辑运算符连接起来的一组条件。属性选择由列出属性的符号名称而获得。显示属性的方式,可以通过一个类似于 C 函数limreport 的格式控制字符串加以指定,外加处理特殊 Solaris Resource Manager 类型的扩展。如果指定了一个"-"格式控制字符串,则 limreport 使用默认的格式显示每个属性。请参考 limreport(1SRM),了解进一步的细节。

limadm 命令为对 lnode 内部属性进行微量改变值提供了一个手段,条件是调用者拥有足够的特权。可以直接通过命令行指定改变命令,也可以指定包含改变命令的一个文件的名称(借助-f选项)。

limreport能够借助 lim 句法(参考 lim 句法中的保留识别符),生成对属性的赋值;lim 句法的输出可以作为 limreport 的输入,方法是使用-f选项。这使得管理员可以使用两个程序来有选择地保存和恢复限制数据库的内容。

复制和删除 lnode

命令:

# limreport 'uid==X' - Y preserve | limadm set -u -f -

将把某一 lnode 从 UID X 复制到 UID Y。表达式"uid==X" 提供了选择源 lnode 的方法。保留识别符促使 limreport 将以一个适于传给 limadm 的句法,输出所有非只读的属性值。在保留识别符之前放置 UID Y,使其成为传给 lim 的数据的第一个项目,从而提供对目标 lnode 的选择。

如果不再需要源 lnode。则可以借助 limadm 将其删除。


注意:

在将 UID 匹配用作 limreport 选择表达式时,要十分谨慎。如果多个登录名称共享一个 UID,则全部得到匹配。这在上面的实例中没有问题,同一 lnode 数据将得到保留且加载多次。在 Solaris 系统中,UID 0拥有 root smtp 两个登录名称。