系统管理指南:高级管理

第 9 章 管理系统记帐(任务)

本章介绍如何设置和维护系统记帐。

以下是本章中概述信息的列表。

有关使用扩展记帐的信息,请参见《系统管理指南:Oracle Solaris Containers-资源管理和 Oracle Solaris Zones》中的第 4  章 “扩展记帐(概述)”

有关与系统记帐相关的逐步过程的信息,请参见系统记帐(任务图)

有关各种系统记帐报告的参考信息,请参见第 10 章

系统记帐方面的新增功能

本节介绍 Oracle Solaris 发行版在系统记帐方面新增或更改的功能。有关新增功能的完整列表以及 Oracle Solaris 发行版的说明,请参见《Oracle Solaris 10 9/10 新增功能》

Oracle Solaris 进程记帐和统计信息改进

Oracle Solaris 10:对平均负荷的内部实现 cpu usr/sys/idle 以及记帐功能进行了更改。微状态记帐取代了原有的记帐机制,并在缺省情况下一直启用。因此,您可能会注意到进程使用情况和计时统计信息与以往稍有不同。

改用微状态记帐,可针对用户进程及其在各个状态上所花费的时间来提供更为准确的信息。此外,这些信息还用于从 /proc 文件系统中生成更精确的负荷平均值和统计信息。有关更多信息,请参见 proc(4) 手册页。

什么是系统记帐?

Oracle Solaris OS 中的系统记帐软件是一组程序,用于收集和记录有关用户连接时间、进程占用的 CPU 时间和磁盘使用情况的数据。收集到此数据后,即可生成报告并针对系统使用情况收取费用。

可以使用每日或每月系统记帐。或者,也可以按用户跟踪磁盘使用情况。

使用记帐程序可以执行以下任务:

在设置系统记帐程序后,这些程序大部分时间会自行运行。

系统记帐的工作原理

设置自动记帐时,先要将记帐启动脚本放入根的 crontab 文件中。然后,cron 命令即可自动启动该记帐启动脚本。

以下概述介绍了系统记帐过程。

  1. 在系统启动和关闭期间,会在记帐文件中收集有关系统使用(如用户登录、运行进程和数据存储)的原始数据。

  2. /usr/lib/acct/runacct 脚本会定期(通常一天一次)处理各种记帐文件并生成累积概要文件和每日记帐报告。然后,/usr/lib/acct/prdaily 脚本将打印每日报告。

    有关 runacct 脚本的更多信息,请参见runacct 脚本

  3. 可以通过执行 monacct 脚本每月处理并打印一次累积 runacct 摘要文件。monacct 脚本生成的摘要报告提供了一种按月或按其他财务周期对用户计费的有效方法。

系统记帐组件

系统记帐软件提供了可将数据组织为摘要文件和报告的 C 语言程序和 Shell 脚本。这些程序驻留在 /usr/lib/acct 目录中。记帐报告驻留在 /var/adm/acct 目录中。

每日记帐有助于执行四种类型的审计:

连接记帐

通过连接记帐可以确定以下信息:

要提供有关连接会话的记帐信息,系统需要存储以下数据:

这些记录是从系统程序(如 dateinitloginttymonacctwtmp)的输出中生成的。这些记录存储在 /var/adm/wtmpx 文件中。

wtmpx 文件中的项可以包含以下信息:

进程记帐

通过进程记帐可以跟踪有关系统中运行的每个进程的以下数据:

每次进程终止时,exit 程序便会收集此信息并将其写入 /var/adm/pacct 文件。

磁盘记帐

通过磁盘记帐可以收集有关每个用户在磁盘中的文件的以下数据并设置数据格式:

/usr/lib/acct/dodisk shell 脚本以一定的时间间隔收集上述数据,该时间间隔是由您向 /var/spool/cron/crontabs/root 文件中添加的项确定的。反过来,dodisk 脚本会调用 acctdiskacctdusg 命令。这些命令按登录名称收集磁盘使用情况的信息。


注意 – 注意 –

通过运行 dodisk 脚本收集的信息存储在 /var/adm/acct/nite/disktacct 文件中。下次运行 dodisk 脚本时将覆写此信息。因此,请避免在同一天中两次运行 dodisk 脚本。


对于随机写入的文件,acctdusg 命令计算的磁盘占用量可能比实际多,这会在文件中形成空洞。出现这种问题是由于 acctdusg 命令在确定文件大小时未读取文件的间接块。更确切地说,acctdusg 文件是通过检查文件 inode 中的当前文件大小值来确定文件大小的。

费用计算

chargefee 实用程序在 /var/adm/fee 文件中存储为用户提供的特殊服务的费用。例如,特殊服务可以是文件恢复。文件中的每项都由用户登录名、用户 ID 和费用组成。runacct 每天都会检查此文件,并将新项合并到记帐记录中。有关运行 chargefee 脚本以对用户计费的说明,请参见如何对用户计费

每日记帐的工作原理

以下是每日记帐的工作原理的分步概要说明:

  1. 将系统切换到多用户模式时,执行 /usr/lib/acct/startup 程序。startup 程序会执行多个调用每日记帐的其他程序。

  2. acctwtmp 程序向 /var/adm/wtmpx 文件中添加一条“引导”记录。在此记录中,系统名显示为 wtmpx 记录中的用户名。下表汇总了原始记帐数据的收集方式及存储位置。

    /var/adm 中的文件

    存储的信息 

    写入程序 

    格式 

    wtmpx

    连接会话  

    logininit

    二进制 

     

    更改

    date

    二进制 

     

    重新引导

    acctwtmp

    二进制 

     

    关闭

    shutacct

    二进制 

    pacctn

    进程 

    Kernel(当进程结束时)  

    二进制 

     

     

    turnacct switch(当原有文件达到 500 块时创建一个新文件)

    二进制 

    fee

    特殊费用 

    chargefee

    ASCII 

    acct/nite/disktacct

    使用的磁盘空间 

    dodisk

    二进制 

  3. 使用 -on 选项调用的 turnacct 脚本开始进程记帐。具体来讲,就是 turnacct 脚本使用 /var/adm/pacct 参数执行 accton 程序。

  4. 删除 Shell 脚本会“清除”由 runacct 脚本留在 sum 目录中的已保存的 pacctwtmpx 文件。

  5. logininit 程序通过向 /var/adm/wtmpx 文件中写入记录来记录连接会话。日期更改(使用带参数的日期)也会写入 /var/adm/wtmpx 文件中。使用 acctwtmp 命令进行重新引导和关闭也会记录到 /var/adm/wtmpx 文件中。

  6. 进程结束时,内核会使用 acct.h 格式在 /var/adm/pacct 文件中为每个进程写入一条记录。

    cron 命令每小时执行一次 ckpacct 脚本,以检查 /var/adm/pacct 文件的大小。如果文件大小超出了 500 块(缺省值),则会执行 turnacct switch 命令。(程序将 pacct 文件移至 pacctn 文件并创建一个新文件。)如果由于处理这些记录时出现故障而尝试重新启动 runacct 脚本,则有多个小型 pacct 文件的优点是显而易见的。

  7. cron 命令每晚都会执行 runacct 脚本。runacct 脚本会对记帐文件进行处理,从而按用户名生成命令概要和使用情况概要。将处理以下记帐文件: /var/adm/pacctn/var/adm/wtmpx/var/adm/fee/var/adm/acct/nite/disktacct

  8. runacct 脚本每天执行一次 /usr/lib/acct/prdaily 脚本,以便将每日记帐信息写入 /var/adm/acct/sum/rprtMMDD 文件中。

  9. monacct 脚本应每月执行一次(或以您确定的时间间隔执行,例如在每个财务周期结束时执行)。monacct 脚本会基于 sum 目录中存储的数据创建一个报告,该目录每天通过 runacct 脚本更新一次。创建报告后,monacct 脚本将“清除”sum 目录,以便为新的 runacct 数据准备目录文件。

系统关闭时执行的操作

如果使用 shutdown 命令关闭系统,则会自动执行 shutacct 脚本。shutacct 脚本会向 /var/adm/wtmpx 文件中写入一条原因记录并关闭进程记帐。

系统记帐(任务图)

任务 

说明 

参考 

设置系统记帐。 

通过执行以下任务来设置系统记帐:

  • 创建 /etc/rc0.d/K22acct/etc/rc2.d/S22acct 文件。

  • 修改 /var/spool/cron/crontabs/adm /var/spool/cron/crontabs/root crontab 文件。

如何设置系统记帐

对用户计费。 

运行 /usr/lib/acct/chargefee username amount 命令。

如何对用户计费

修复损坏的 wtmpx 文件。

wtmpx 文件从二进制转换为 ASCII 格式。

如何修复损坏的 wtmpx 文件

修复 tacct 错误。

运行 prtacct 脚本以检查 /var/adm/acct/sum/tacctprev 文件。然后,修补最新的 /var/adm/acct/sum/tacctMMDD 文件。您将需要重新创建 /var/adm/acct/sum/tacct 文件。

如何修复 tacct 错误

重新启动 runacct 脚本。

删除 lastdate 文件以及任何锁定文件。然后,手动重新启动 runacct 脚本。

如何重新启动 runacct 脚本

临时禁用系统记帐。 

编辑 adm crontab 文件,以阻止 ckpacctrunacctmonacct 程序运行。

如何暂时停止系统记帐

永久禁用系统记帐。 

删除 admcrontab 文件中用于 ckpacctrunacctmonacct 程序的项。

如何永久禁用系统记帐

设置系统记帐

可将系统记帐设置为在系统处于多用户模式时运行(运行级 2)。通常,此任务涉及以下步骤:

  1. 创建 /etc/rc0.d/K22acct/etc/rc2.d/S22acct 启动脚本

  2. 修改 /var/spool/cron/crontabs/adm/var/spool/cron/crontabs/root crontab 文件

下表介绍了缺省记帐脚本。

表 9–1 缺省记帐脚本

目的 

记帐脚本 

手册页 

运行频率 

检查 /usr/adm/pacct 日志文件的大小并确保该文件不会太大。

ckpacct

acctsh(1M)

定期 

处理连接、磁盘和费用记帐的信息。如果不想执行某些记帐功能,则可从此脚本中删除相应命令。 

runacct

runacct(1M)

每日 

每月生成一次财务记帐摘要报告。您可以确定此脚本的运行频率。如果不想使用某些记帐功能,则可从此脚本中删除相应命令。 

monacct

acctsh(1M)

按财务周期 

可以选择缺省情况下运行的记帐脚本。将这些项添加到 crontab 文件后,系统记帐应自动运行。

Procedure如何设置系统记帐

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 如有必要,请使用 pkgadd 命令在系统中安装 SUNWaccrSUNWaccu 软件包。

  3. 安装 /etc/init.d/acct 作为运行级 2 的启动脚本。


    # ln /etc/init.d/acct /etc/rc2.d/S22acct
    
  4. 安装 /etc/init.d/acct 作为运行级 0 的停止脚本。


    # ln /etc/init.d/acct /etc/rc0.d/K22acct
    
  5. adm crontab 文件中添加以下行,以自动启动 ckpacctrunacctmonacct 脚本。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    0 * * * * /usr/lib/acct/ckpacct
    30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
    30 7 1 * * /usr/lib/acct/monacct
  6. root crontab 文件中添加以下行,以自动启动 dodisk 脚本。


    # crontab -e
    30 22 * * 4 /usr/lib/acct/dodisk
  7. 编辑 /etc/acct/holidays 以包括国定假日和当地假日。

    有关更多信息,请参见 holidays(4) 手册页及后面的示例。

  8. 重新引导系统或键入以下内容手动启动系统记帐:


    # /etc/init.d/acct start
    

示例 9–1 设置记帐 (adm crontab)

这一修改的 adm crontab 包含 ckpacctrunacctmonacct 脚本的项。


#ident  "@(#)adm        1.5     92/07/14 SMI"    /* SVr4.0 1.2   */
#
# The adm crontab file should contain startup of performance 
# collection if the profiling and performance feature has been 
# installed.
0 * * * * /usr/lib/acct/ckpacct
30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
30 7 1 * * /usr/lib/acct/monacct


示例 9–2 设置记帐 (root crontab)

这一修改的 root crontab 包含 dodisk 程序的项。


#ident  "@(#)root       1.19    98/07/06 SMI"   /* SVr4.0 1.1.3.1       */
#
# The root crontab should be used to perform accounting data collection.
#
#
10 3 * * * /usr/sbin/logadm
15 3 * * 0 /usr/lib/fs/nfs/nfsfind
30 3 * * * [ -x /usr/lib/gss/gsscred_clean ] && /usr/lib/gss/gsscred_clean
30 22 * * 4 /usr/lib/acct/dodisk


示例 9–3 设置记帐 (/etc/acct/holidays)

以下示例显示一个 /etc/acct/holidays 文件样例。


* @(#)holidays	January 1, 2004
*
* Prime/Nonprime Table for UNIX Accounting System
*
* Curr	Prime	Non-Prime
* Year	Start	Start
*
  2004	0800	1800
*
* only the first column (month/day) is significant.
*
* month/day	Company
* 		Holiday
*
1/1		New Years Day
7/4		Indep. Day
12/25		Christmas

对用户计费

如果您根据需求提供特别用户服务,则需要运行 chargefee 实用程序对用户计费。特殊服务包括恢复文件或远程打印chargefee 实用程序会在 /var/adm/fee 文件中记录费用。每次执行 runacct 实用程序时,都会将新项合并到总记帐记录中。

有关更多信息,请参见 acctsh(1M) 手册页。

Procedure如何对用户计费

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 向用户收取特殊服务的费用。


    # /usr/lib/acct/chargefee username amount
    
    username

    指定要对其计费的用户帐户。

    amount

    指定要对用户计费的单位数量。该值是设置的用于根据打印或恢复文件等任务向用户收费的任意单位。必须编写一个脚本,以调用 chargefee 实用程序并向用户收取特定任务的费用。


示例 9–4 对用户计费

在以下示例中,向用户 print_customer 收取了 10 个单位的费用。


# /usr/lib/acct/chargefee print_customer 10

维护记帐信息

本节介绍如何修复损坏的系统记帐文件以及如何重新启动 runacct 脚本。

修复损坏的文件并更正 wtmpx 错误

遗憾的是,系统记帐并不十分安全。有时候,文件会损坏或丢失。有些文件可以忽略,也可以从备份中恢复。但是,有些文件则必须修复,才能维护系统记帐的完整性。

wtmpx 文件可能会引发每日系统记帐操作中的大多数问题。手动更改日期并且系统处于多用户模式时,会向 /var/adm/wtmpx 文件中写入一组日期更改记录。wtmpfix 实用程序旨在出现日期更改时调整 wtmp 记录中的时间标记。但是,部分日期更改和重新引导的组合会跳过 wtmpfix 实用程序并导致 acctcon 程序失败。

Procedure如何修复损坏的 wtmpx 文件

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 转到 /var/adm 目录。

  3. wtmpx 文件从二进制格式转换为 ASCII 格式。


    # /usr/lib/acct/fwtmp < wtmpx > wtmpx.ascii 
    
  4. 编辑 wtmpx.ascii 文件以删除损坏的记录。

  5. wtmpx.ascii 文件转换回二进制文件。


    # /usr/lib/acct/fwtmp -ic < wtmpx.ascii > wtmpx
    

    有关更多信息,请参见 fwtmp(1M) 手册页。

更正 tacct 错误

如果要向用户收取系统资源费用,则 /var/adm/acct/sum/tacct 文件的完整性极为重要。有时候,会出现异常的 tacct 记录,其中包括负数、重复的用户 ID 或用户 ID 65535。首先,使用 prtacct 脚本列显 /var/adm/acct/sum/tacctprev 文件,以检查该文件。如果内容没有问题,则修补最新的 /var/adm/acct/sum/tacct MMDD 文件。然后,重新创建 /var/adm/acct/sum/tacct 文件。以下步骤概括了一个简单的修补过程。

Procedure如何修复 tacct 错误

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 转到 /var/adm/acct/sum 目录。

  3. tacctMMDD 文件从二进制格式转换为 ASCII 格式。


    # /usr/lib/acct/acctmerg -v < tacctMMDD > xtacct
    

    MMDD 是一对表示月份和日期的两位数。

  4. 编辑 xtacct 文件,删除损坏的记录并将重复记录写入另一个文件。

  5. xtacct 文件从 ASCII 格式转换为二进制格式。


    # /usr/lib/acct/acctmerg -i < xtacct > tacctMMDD
    
  6. 将文件 tacctprevtacct.MMDD 合并到 tacct 文件中。


    # /usr/lib/acct/acctmerg < tacctprev tacctMMDD > tacct
    

重新启动 runacct 脚本

runacct 脚本失败的原因可能有多种。

以下是最常见的原因:

如果存在 active.MMDD 文件,请先检查该文件中是否有错误消息。如果存在 activelock 文件,请检查 fd2log 文件中是否有任何相关消息。

如果不带任何参数运行 runacct 脚本,则该脚本会假定这一次调用是当天的第一次调用。如果 runacct 脚本正在重新启动并指定 runacct 脚本重新运行记帐的月份和日期,则参数 MMDD 是必需的。进行处理的入口点基于 statefile 文件的内容。要覆盖 statefile 文件,请在命令行中包括所需的状态。有关可用状态的说明,请参见 runacct(1M) 手册页。


注意 – 注意 –

手动运行 runacct 程序时,请确保以用户身份 adm 运行该程序。


Procedure如何重新启动 runacct 脚本

  1. 转到 /var/adm/acct/nite 目录。


    $ cd /var/adm/acct/nite
    
  2. 删除 lastdate 文件和所有 lock* 文件(如果有)。


    $ rm lastdate lock*
    

    lastdate 文件包含上次运行 runacct 程序的日期。在下一步中重新启动 runacct 脚本将重新创建此文件。

  3. 重新启动 runacct 脚本。


    $ /usr/lib/acct/runacct MMDD [state] 2> /var/adm/acct/nite/fd2log &
    
    MMDD

    由两位数指定的月份和日期。

    state

    指定 runacct 脚本处理开始的状态或起始点。

停止和禁用系统记帐

可以暂时停止或永久禁用系统记帐。

Procedure如何暂时停止系统记帐

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 编辑 adm crontab 文件,通过注释掉相应行来停止运行 ckpacctrunacctmonacct 程序。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    #0 * * * * /usr/lib/acct/ckpacct
    #30 2 * * * /usr/lib/acct/runacct 2> /var/adm/acct/nite/fd2log
    #30 7 1 * * /usr/lib/acct/monacct
  3. 编辑 root crontab 文件,通过注释掉相应行来停止运行 dodisk 程序。


    # crontab -e
    #30 22 * * 4 /usr/lib/acct/dodisk
  4. 停止系统记帐程序。


    # /etc/init.d/acct stop
    
  5. (可选)从 crontab 文件中删除新增的注释符号。

  6. 重新启动系统记帐程序,以重新启用系统记帐。


    # /etc/init.d/acct start
    

Procedure如何永久禁用系统记帐

  1. 成为超级用户或同等角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:安全性服务》中的“配置 RBAC(任务列表)”

  2. 编辑 adm crontab 文件并删除 ckpacctrunacctmonacct 程序的项。


    # EDITOR=vi; export EDITOR
    # crontab -e adm
    
  3. 编辑 root crontab 文件并删除 dodisk 程序的项。


    # crontab -e
    
  4. 删除运行级 2 的启动脚本。


    # unlink /etc/rc2.d/S22acct
    
  5. 删除运行级 0 的停止脚本。


    # unlink /etc/rc0.d/K22acct
    
  6. 停止系统记帐程序。


    # /etc/init.d/acct stop