Solaris Resource Manager 1.3 系统管理指南

第 5 章 管理 lnode

Solaris Resource Manager 系统是围绕对内核的基础增加而建立的:即被称为 lnode 的针对用户的结构。一个 lnode 就是可以存储和更新多种针对用户的,数据的大小基本上固定的地方。对于口令映射中定义的每个唯一的 UID,都应该有一个对应的 lnode。(这是指由连续的 getpwent(3C) 调用所返回的每个唯一的 UID。)一个 UID 可以在没有对应的口令映射条目的条件下存在,但这不是推荐的。lnode 存储在磁盘上,并可被内核自动地移入或移出内存。自被从磁盘读取后已经被修改的 lnode 的内存副本作为常规系统同步化操作的一部分,并在 sync 命令运行时按照需要或在任何必要的时侯被写回,这样就能腾出 lnode 高速缓存的空间用于读取其它 lnode。

lnode 以树分层结构的方式进行维护,其中 central system administrator 作为树的顶点,而其它用户则作为树中较小用户组的组长。中央管理员就是系统的超级用户或根用户。

孤立和组循环等关于 lnode 的错误在 第 11 章,故障排除 中有介绍。

委任管理

中央管理员对 lnode 的管理负主要责任。Solaris Resource Manager 推出了可以被分配和管理的若干资源控制,并可有选择地向非根用户分配特定的管理特权,从而分摊用户管理的任务。

通过设定用户的 uselimadmadmin 标志可向相应的用户分配管理特权。一个次级管理员是一个具有已设定 uselimadm 标志的用户,与超级用户具有相同的 limadm 程序管理特权。一个具有已设定 admin 标志的组长称做组管理员,并比在同一调度组中的用户具有更高的特权 (如下所述)。

中央管理员为将根作为其父节点的调度组创建和指派限制,从而对系统资源的整体分割进行控制。组管理员一般也要执行同样类型的资源管理控制,但仅限于对他们自己调度组内的用户。组管理员可以分配的资源仅限于分配给该组的资源(例如,那些已分配给组长 lnode 的资源)。注意,组管理员可以将 admin 标志指派给其调度组内的任意用户,以将自己的管理责任进一步往下分派。

组管理员可以执行以下任务:

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

    注意,尽管某个组管理员可以将某个资源的限制设置为大于组的限制,但组成员所消耗的资源,照样被认为是由组长消耗的,而对单个用户的限制在其试图超过组长限制时会强制实行。

  2. 更改其调度组内的任何 lnode 的任何标志或属性(除 flag.uselimadmcpu.usage 以外)。

    组管理员执行标志分配还受一个限制,即不能把组管理员所没有的特权分配给某个用户。采用这一限制的目的是防止组管理员绕过 Solaris Resource Manager 内的安全。

组管理员的主要工具是 limadm(1MSRM)limreport(1SRM) 命令。limadm 程序可对一个或多个现有用户的限制、标志和其它 Solaris Resource Manager 属性进行操作。与报告生成器 limreport 相结合,这些工具就能使调度组实现自发的自我管理,而无需干扰其它离散的调度组的资源分配或管理。

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

安全

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

系统管理员可以采用若干种方法来确保 Solaris Resource Manager 系统的安全能得到维护。对于任何 Solaris 系统来说,最重要的就是要确保 root 口令的机密性。掌握 root 用户口令的任何人均可象中央管理员一样不受限制地访问系统资源。

通过在用户各自的 lnode 中设定特定的系统标志,就能向 Solaris Resource Manager 中的用户赋予若干种特殊管理特权。这些特权有助于提高系统的安全性,因为它们可使代理用户无需获得完全超级用户特权就能执行必要的任务。

这些特权中有一些不能轻率地赋予,因为它们可向被赋予特权的用户提供广泛的功能。拥有特殊特权的用户的口令必须得到严格的保护,就象超级用户的口令应该得到保护一样。

在 Solaris Resource Manager 中可以采取若干种安全预防措施预防授予次级管理员的管理特权的错误使用:请参阅典型的应用程序服务器lnode维护程序

在某些情况下,中央管理员可以在对调度树的结构进行粗心操作时使系统对安全破坏保持开放。中央管理员必须了解如何正确修改调度树和如何在当前结构中检测潜在的问题,这一点非常重要。详细介绍,请参阅 调度树结构

推荐的组管理员 lnode 结构

组管理员可能遇到的一个问题就是他们与组成员共享组限制。例如,如果组长 lnode 对组设定了进程限制,则该限制就能控制包括组长在内的整个组所能使用的进程的数目。除非进一步限制,否则调度组内的任何用户都能不让组管理员只通过简单地超过进程限制就可以创建新的进程。

预防这种情况的一种方法是,由组管理员针对每个组成员分别设定限制。但为了有效起见,这些限制可能必须要有过度的限制作用。此外,强迫某个组管理员管理每个限制也与 Solaris Resource Manager 的分层结构资源控制的目标相冲突。

解决这一问题的一种替代方法是,由中央管理员修改组中的 lnode 的结构。在组管理员的 lnode 的下方创建一个“控制” lnode,作为唯一的子 lnode,而不是把用户直接放置到组管理员自己的 lnode 下方,这样,用户就被设定为控制 lnode 的子节点。这样创建的结构如图所示。

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

图表显示,在组管理员 lnode 的下方创建一个“控制”lnode 作为唯一的子 lnode。这样,用户就被设定为控制 lnode 的子节点。

如上图所示,组管理员帐户的 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,该 lnode 可使用 UID 作为向文件的直接索引而被访问。如果某个数值较大的 UID 有一个 lnode,则限制数据库会看起来很大。但是,在系统中用户的 UID 并非连续的情况下,在一个对此予以支持的文件系统类型上,限制数据库会有很大的缝隙或者空洞。这意味着,并未实际为存储该文件的“空白”部分分配任何磁盘块。 ufs 文件系统支持稀疏文件,但 tmpfs 文件系统不支持。请参阅下面保存和恢复限制数据库中的讨论,了解稀疏文件对于保存和恢复限制数据库的含义。

无论何时,只要您创建一个新用户,您就必须创建一个新 lnode。

创建限制数据库

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

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

限制数据库应该被 root 所拥有,组应该被 root 所拥有且只能被所有者阅读。写许可是不需要的,因为只有具备超级用户证明的内核代码才会写入文件。


小心:小心:

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


保存和恢复限制数据库

因为限制数据库可能是一个稀疏文件,在对其进行复制时应该小心。如果该文件是采用不支持稀疏文件的实用程序编写的,则该文件就非常可能消耗大量磁盘空间,因为文件的空白区域在被读取时可能呈现为一系列的零,并作为真正的块而非空白区域被写回。如果该文件被诸如 tar(1)、cpio(1) 或者 cp(1)等实用程序复制、备份或恢复,则可能发生这种情况,虽然诸如 ufsdump( 1M) 和 ufsrestore(1M) 等程序能保护空洞。

您可使用 limreport 生成文件的一个 ASCII 版本,并使用 limadm 从该保存 ASCII 版本重新生成原始文件,进而对限制数据库进行备份和恢复。例如,命令:

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

将为口令映射中的每个用户创建作为 lnode 的 ASCII 表示的 /var/tmp/savelnodes。请注意,这样的操作将不保存没有相应口令映射条目的 lnode。至多在口令映射中的所有 UID 的集合都应该存在 lnode。

命令:

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

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

limreportlimadm 命令 详细介绍了 limreportlimadm 命令的使用。管理员熟悉用这些命令保存和恢复 lnode 会很有帮助的,因为在改变 lnode 结构的解释(由限制数据库定义)时可能需要使用这些命令。

因为限制数据库的内容在正常系统运行过程中会定期改变,所以应该在系统静止时或者单用户模式下进行备份操作。类似地,只有在不使用 Solaris Resource Manager 时(如系统处于单用户模式时)才能对整个限制数据库进行恢复。

创建和删除 lnode

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

# limreport \!flag.real - uid lname

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

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

类似地,在从口令图中删除一个用户帐户之前,应该使用 limadm(1MSRM) 命令从限制数据库中删除对应的 lnode。


注意:

在删除 lnode时,应确保从最底层的 lnode 向上删除子树。如果您从您正在删除的子树的顶端开始,您就可能丧失对被删除 lnode 的子节点的控制,因为当它们的父节点被删除时,它们就会孤立。


只要某个用户的 UID 被更改,就应该把该用户的 lnode 的内容复制到一个对应新的 UID 的新的 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 上。

  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 的调度组被设置为用户“其它”(srmother)(如果存在一个针对该用户帐户的 lnode 的话)或者设置为 root lnode。

limadm 调用者需要足够的管理特权才能进行指定的更改。调用者必须是超级用户,有一个已设定的 uselimadm 标志,或者是一个只更改该调用者所属调度组成员的属性的组管理员。限制适用于组管理员对 limadm 的使用。

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

单位

Solaris Resource Manager 中的数值可以用如下三种 units 之一表示:

比例

比例单位是缺省单位。它是一种容易读取的格式,可用于显示和输入数值。比例单位可帮助用户较少需要输入的位的数目,从而避免录入错误。

原始(或者非比例)

原始单位是表示一个数值的基本单位。例如,针对虚拟内存利用率的原始单位是字节,而针对虚拟内存应计的原始单位是字节-秒。这种单位一般用于要求准确数量的利用率计费。

内部

内部单位是供 Solaris Resource Manager 用来以与计算机无关的单位而非字节保存内存属性的。

转换

Solaris Resource Manager 程序可在用于保存属性值的内部单位之间进行转换,这样用户所看到的就是比例单位或者原始单位。这就是说,除少数例外情况以外,用户永远都不必关心 Solaris Resource Manager 所使用的内部单位。

exa(艾克)、peta(拍它)、tera(太拉)、giga(吉)、mega(兆)、和 kilo(千)等术语在 Solaris Resource Manager 中用于表示 2 的乘方,而非 10 的乘方。例如,一个兆字节表示 1,048,576 字节,而非 1,000,000 字节。每个术语表示的 2 的乘方分别是 60(exa)、50(peta)、40(tera)、30(giga)、20(mega)和10(kilo)。

作为用户与 Solaris Resource Manager 系统之间的主要界面的程序包括 limadmliminfolimreport。下面章节对它们所进行的转换和比例有详细介绍。

limadm 命令

在更改属性数值时,limadm 可使数字采用比例字符作为后缀:[EPTGMK][B][.][wdhms].大写字母和小写字母可以互换。

如果属性具有存储的尺度(内存属性)或存储应计,则允许使用来自第一个组(EPTGMK)的字符。然后根据需要乘以字节的数目,如 1 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 可尝试从上下文中推理出其中的含义。如果这样做不可能,则应认为它表示兆,而非分钟。

在输入较大的数字时,这些转换字符可用来避免条目的数量级的乘方的错误,但是数量是以内部单位保存的,无论采用何种输入方法。

还可单独使用一个特殊的比例字符 u,但它只能用于内存属性值。它表示数字是以与计算机相关的单位(内部)而非字节存在的。

liminfo 命令

在报告为 limadm( 以便输入时,) liminfo1SRM 命令使用相同的前缀(如上所述)。一般地,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 命令

limreportlimadm 命令为管理员提供了一种针对任何数目的用户保存和恢复 lnode 的内容的简单方法。使用 limreport 命令选择和提取要保存的 lnode,再使用 limadm 命令对其进行恢复。命令的这种混合一般用于复制 lnode 和更改 lnode 结构,如以下章节所述。

limreport 命令还提供了一种选择和显示用户属性的灵活方法。它可提供两级选择:lnode 的选择和针对每个被选 lnode 要显示的属性的选择。lnode 选择是通过规定一个选择表达式而实现的,该表达式可采用一种条件或者多种条件,并采用 C 语言格式的句法用逻辑运算符相连。属性选择是通过列出该属性的符号名而实现的。显示该属性的方式可使用一个格式控制字符串规定,该字符串类似于 C 语言功能 limreport,并采用扩展名来处理特殊的 Solaris Resource Manager 类型。如果规定了一个格式控制串为 '-', 则 limreport 可针对每个被显示的属性使用缺省格式。详细介绍请参见 limreport( 1SRM)。

更改 lnode 结构

limadm 命令提供了一种不加分割地更改 lnode 中的属性内容的工具,但是条件是该调用者有充分的特权。可直接在命令行中规定更改命令,也可(使用 -f 选项)规定含有更改命令的文件的名称。

limreport 命令能使用 limadm 句法生成属性值分配(请参阅 limadm 句法中的 preserve 标识符),其输出可使用-f 选项作为 limreport 的输入。这样就能使管理员同时使用这两个程序有选择地对限制数据库的内容进行保存和恢复。

复制和删除 lnode

命令:

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

将把某个 lnode 从 UID X 复制到 UID Y。表达式 uid==X 提供选择源 lnode 的方法。preserve 标识符可使 limreport 输出在某个句法中不是只读型的所有属性值,该句法可用于传递到 limadm。把 UID Y 放置在 preserve 标识符之前可使其成为传递到 limadm 的数据中的第一个项目,并进而提供对目标 lnode 的选择。

如果不再要求源 lnode,则可用 limadm 将其删除。


注意:

在使用按照 UID 匹配作为 limreport 选择表达式时应加以小心。如果多个登录名共享一个 UID,则它们全都能匹配。在上例中,这没有关系;相同的 lnode 数据将得到保存并多次装载。在 Solaris 环境中, UID 0 具有 rootsmtp 这两个登录名。