ganesha-DBUS
DBUS接口
在V2.0之前,NFS Ganesha使用SNMP和简单的TCP套接字接口导出统计信息。除了一些UNIX遗留信号外,没有任何控制接口,这些信号会触发诸如重新读取配置文件之类的事件。虽然UNIX信号保留了一些向后兼容性,但这些管理和统计接口都已被DBUS服务器所取代。
DBUS 是一种用于系统管理和点对点应用程序通信的系统本地 IPC 机制。 此页面记录了 NFS Ganesha DBUS 服务。 有关 DBUS 本身的详细信息和文档,请参阅 DBUS 项目 站点。
注
d-feet 工具是一个非常有用的基于 GUI 的 DBUS 消息调试器/工具。 将它与下面的文档结合使用会使这一切变得更容易理解。 它在大多数 Linux 发行版上都以软件包的形式提供。
DBUS 服务是一个总线名称,其中包含一组对象路径。 每个 object path 包含一组 interfaces,每个接口都有一个或多个 methods。 我们在 NFS Ganesha 中实现了以下功能。
安装
NFS Ganesha 服务器无需配置即可连接到使用 DBus。 DBus 的系统库知道 DBus 服务器的位置。 但是,必须让 DBus 服务器知道 NFS Ganesha。 本节介绍如何配置 DBus 服务器以识别和接受来自 NFS Ganesha 的连接。
org.ganesha.nfsd.conf
配置文件位于src/scripts/ganeshactl/org.ganesha.nfsd.conf
。 它是一个 XML 文件,它定义了 org.ganesha.nfsd 总线名称以及访问或连接它的权限。 当前权限仅允许以超级用户身份运行的程序或脚本访问 NFS Ganesha。
配置系统 DBus 服务
下面关于配置DBus以支持NFS Ganesha的说明假设系统是基于Fedora或RHEL的。其他Linux发行版和FreeBSD可能有所不同。有关文件和目录位置的详细信息,请参阅发行版的文件系统和文档。
- 将
src/scripts/ganesha .nfsd.conf
文件拷贝到/etc/dbus-1/system.d/
目录下。DBus服务器(messagebus
)需要重启才能加载这个文件。 - 启动 NFS Ganasha。 请注意,与 DBus 服务器的连接仅在NFS Ganasha服务器初始化时进行一次,因此如果您忘记先复制文件,则必须重新启动 NFS Ganesha。
- 检查服务器日志,通常位于
/var/log/nfs-ganesha.log
。 初始化消息中间应该有一条日志消息,指示 DBUS 线程已启动。 如果消息以其他方式指示线程终止,这可能与 DBus 服务器拒绝其连接尝试有关。 按照错误消息中的建议进行操作。 - 作为超级用户,使用 src/scripts/ganeshactl 中提供的脚本之一或标准 DBus 客户端工具之一来验证所有内容是否已连接。 如果您使用 d-feet,如下所述,您应该会看到至少一个 /org/ganesha/nfsd服务,具体取决于服务器构建中包含的内容。 如果不存在,请重新检查服务器日志和系统的消息日志。 d-feet 是最好的工具,因为它显示所有 DBus 活动并实时更新自身,而提供的脚本仅访问 NFS Ganesha 服务。
- 每个脚本至少有一个命令行选项来显示/报告状态。 作为超级用户,使用其中一个脚本来显示状态。
- 如果您已经走到这一步,DBus 接口就已经启动并正在运行。
ganeshactl 脚本是一个 GUI 应用程序,它集成了与命令行脚本相同的所有功能。 与 d-feet 一样,它全面展示了 NFS Ganesha 服务器。 将它与下面的文档结合使用以访问各种接口及其方法。
接口和方法
DBUS IPC 是客户端和服务中特定对象路径上的接口之间的双向消息交换。
DBUS 规范定义了一组保留的公共接口,客户端可以从服务中获得这些接口。 NFS Ganesha 中使用了其中两个保留接口:
- org.freedesktop.DBus.Introspectable
该接口有一个方法 Introspect(内省),它返回一个 xml 数据字符串,该字符串描述所有其它接口及其针对特定对象路径的方法。 NFS Ganesha服务器中的每个对象路径都提供此接口。
- org.freedesktop.DBus.Properties
此接口用于设置和检索属性的键/值对。 NFS Ganesha 目前还没有提供这个接口。 当它这样做时,它将用于在运行的服务器中设置配置参数,例如日志组件级别。
方法采用一个或多个结构化参数并返回结构化回复。 尽管 DBUS 规范没有为参数或回复内容指定任何内容,但 NFS Ganesha 实现确实构建了回复。 每个回复至少包含两个项目。
名称 | 类型 | 详情 |
---|---|---|
status | 布尔型 | 如果方法/命令成功,则为 true,否则为 false |
error | 字符串 | 如果status == true则OK,否则是一个人们可读的错误消息 |
time | 结构体 | ’ 结构体 timespec '格式的数据的时间戳。(可选) |
… | 结构体或者数组 | 数据负载(可选) |
只有“status”和“error”字段是必填字段。客户端应该使用status来进行错误检查,error用来在GUI中显示用户,比如状态栏。
time 回复为纳秒级精度。 请参阅下文,了解如何将其用于统计计算。 它是可选的,但始终用于统计报告。
注
Introspect(内省)不会显示第一级以下字段的名称。这是DBUS规范中的一个限制。客户端程序可以从 Introspect(内省)和DBUS消息解析中解码行的“shape”,但DBUS不提供进一步的帮助。客户端应用程序开发人员被迫在这里咨询,作为最终的权威,服务器代码本身也是如此。
NFS Ganesha服务
NFS Ganesha 拥有 org.ganesha.nfsd 总线名称。 任何客户端应用程序或系统控制服务都连接到此总线名称以访问服务器。
DBUS服务中的功能被实现为单独的对象路径,专用于服务器的特定子系统。2.0版本支持以下路径:
-
/org/ganesha/nfsd/ClientMgr
这用于管理和报告客户端的统计数据。
-
/org/ganesha/nfsd/ExportMgr
这用于管理和报告文件系统导出的统计信息。
-
/org/ganesha/nfsd/admin
这用于管理服务器本身。
还有一个 /org/ganesha/nfsd/CBSIM 路径,但仅用于调试,不存在于生产环境中。 它的接口也可能会更改(包括删除)并且不受支持。
I/O统计
下面按客户端和导出报告I/O统计信息,并在回复中使用相同的结构。有两种结构,一种用于通过服务器进行I/O,另一种用于NFSv4.1布局。
基本服务器 I/O
以下结构报告 I/O 统计信息。 这适用于所有协议。 在 NFSv4.1 的情况下,这些传输用于由元数据服务器本身执行的读取和写入。 第一个表描述了每个统计报告的回复,分别为 read 和 write 计数。 第二个表描述了每种类型的统计详细信息。
名称 | 类型 | 详情 |
---|---|---|
status | 布尔型 | 如果有统计信息,则为 true,如果没有活动,则为 false |
error | 字符串 | “OK” 或"No activity…" |
time | 结构体 | 采样时的时间戳(以纳秒为单位)(现在) |
read | 结构体 | I/O 结构如下所述 |
write | 结构体 | I/O 结构如下所述 |
这是I/O结构。
名称 | 类型 | 详情 |
---|---|---|
requested | uint64_t | 请求的字节数 |
transferred | uint64_t | 实际传输 |
total | uint64_t | 总操作次数 |
errors | uint64_t | 报告错误的操作数 |
latency | uint64_t | 操作消耗的累积时间(以纳秒为单位) |
queue wait | uint64_t | 在RPC等待队列中花费的累积时间 |
pNFS操作
NFSv4.1 (pNFS)直接将I/O委托给客户端与数据服务器或OSD之间的事务。下面的结构用于报告这些统计数据。
名称 | 类型 | 详情 |
---|---|---|
status | 布尔型 | 如果有统计信息,则为 true,如果没有活动,则为 false |
error | 字符串 | "OK"或 “No activity…” |
time | 结构体 | 采样时的时间戳(以纳秒为单位)(现在) |
getdevinfo | 结构体 | 获取设备信息操作 |
layout_get | 结构体 | layout 获取操作 |
layout_commit | 结构体 | layout提交操作 |
layout_return | 结构体 | layout返回操作 |
layout_recall | 结构体 | 由服务器调用的layout |
此处是上述每个layout操作的layout统计子结构。
名称 | 类型 | 详情 |
---|---|---|
total | uint64_t | 总layout操作 |
errors | uint64_t | layout错误的累积数量 |
delays | uint64_t | 累积延迟时间(以纳秒为单位) |
统计计算
统计信息的累积和报告方式使服务器开销最小,因为这些计数器中的每一个都位于服务器每个操作的主代码路径中。 所有计数器和计时器都是从服务器启动时间开始累积的,并使用原子操作,因此任何单个计数器都是线程安全的。 但是,这并不能保证集合中的所有计数器都保证相对于彼此是原子的。 然而,这并不是一个真正的问题,因为在计算速率时,以一种或另一种方式的单个增量或添加时间是一个小错误。
所有计数器都是从服务器启动时累积的。 所有计数器也是无符号 64 位整数,包括纳秒计数。 内部时间是自服务器启动以来的无符号 64 位纳秒计数,考虑到至少 584 年不需要 65 位纳秒精度,这应该绰绰有余。 每个 DBUS 回复还包含一个纳秒精度的时间戳。 速率的计算方法是从新计数中减去旧计数,然后将结果除以计算为旧时间戳和新时间戳之间的差异的间隔,然后是通常的标准化数学来计算每(秒、分钟、天、 世纪)。
last time 值与统计回复中的 time 值显着不同。 它只是服务器在更新特定计数器集时记录的时间戳。 它的主要用途是简单地记录服务器在特定导出上为特定客户端执行该类型操作的最后时间。
/org/ganesha/nfsd/ClientMgr
客户端管理器负责服务器中的客户端列表。 客户端由 IP 地址引用。 即使在客户端可能通过两种协议访问服务器的情况下,IPv4 和 IPv6 地址也是分开管理的。 NFS Ganesha 确实无法区分这两者,系统管理员可能想知道每个协议版本中流量的性质。 但是,匹配地址将是管理员的一项工作。
客户端管理器有一个为其所有接口和方法生成的 introspectable (内省)接口。
org.ganesha.nfsd.clientmgr
该接口用于管理客户端。 它目前有三种方法。
-
AddClient
此方法将IP地址作为格式化字符串,并将其添加到客户端管理器。地址可以是IPv4格式地址,也可以是IPv6格式地址。每个地址都被单独处理,所以使用两种协议的客户端被单独处理。回复有两个字段,上面描述的status和error字段。
-
RemoveClient
此方法将 IP 地址作为格式化字符串并从客户端管理器中删除该条目。 它的回复也有 status 和 error 字段。 此方法的一个副作用是释放此客户端的所有统计信息存储。 如果重新创建条目,所有计数器将从 0(零)开始。
-
ShowClients
此方法返回一个结构数组,该数组描述了服务器已知的每个客户端的统计状态。 回复格式如下:
名称 | 类型 | 详情 |
---|---|---|
time | 结构体 | ’ 结构体 timespec '格式的数据的时间戳。(可选) |
clients | 数组 | 客户端标志数组。 请参阅下面的客户端表 |
客户端表是一个结构体数组,其中每一行描述了一个客户端的统计状态。
名称 | 类型 | 详情 |
---|---|---|
client | 字符串 | 客户端管理器已知的客户端 IP 地址 |
nfsv3 | 布尔型 | 如果有任何 NFSv3 活动,则为 true |
mnt | 布尔型 | 如果有任何 MNTv3 活动,则为 true |
nlm4 | 布尔型 | 如果有任何 NLMv4 活动,则为 true |
rquota | 布尔型 | 如果有任何 RQUOTA 活动,则为 true |
nfsv40 | 布尔型 | 如果有任何 NFSv4.0 活动,则为 true |
nfsv41 | 布尔型 | 如果有任何 NFSv4.1 活动,则为 true |
nfsv42 | 布尔型 | 如果有任何 NFSv4.2 活动,则为 true |
9P | 布尔型 | 如果有任何 9P 活动,则为 true |
last time | 结构体 | struct timespec 格式的最近一次数据更新的时间戳。 |
此回复有两个时间戳,time 和 last time 的含义见下文。
org.ganesha.nfsd.clientstats
当前定义了四种方法。 9P 协议的统计数据尚未定义。
每个方法都采用一个字符串 ipaddr 参数。 这是上面ShowClients方法返回的数组中返回的ipaddr字段。
每个统计方法都返回自己的相关数据
GetNFSv3IO
此方法报告每个客户端的 NFSv3 协议的 I/O 统计信息。 总操作计数已累计,但此时仅报告 I/O 统计信息。 有关详细信息,请参阅上面的 I/O 操作结构。
GetNFSv40IO
此方法报告每个客户端的 NFSv4.0 协议的 I/O 统计信息。 它的回复格式和语义与 NFSv3 回复相同。
GetNFSv41IO
此方法报告每个客户端的 NFSv4.1 协议的 I/O 统计信息。 尽管其格式与其他协议相同,但其语义却大不相同。 这些计数用于元数据服务器完成的 I/O,而不是数据服务器或 OSD 的统计信息汇总。 这些统计数据必须直接从数据服务器获得,并为完整的服务器吞吐量计算求和。
GetNFSv41Layouts
此方法报告每个客户端的 pNFS 特定操作。 这些计数器代表元数据服务器操作,因此应该等于数据服务器为该客户端报告的操作的总和。
/org/ganesha/nfsd/ExportMgr
导出管理器负责服务器中的导出列表。导出列表由配置文件中定义的导出块生成。
导出管理器有一个为其所有接口和方法生成的 introspectable (内省)接口。
org.ganesha.nfsd.exportmgr
该接口用于管理导出。 该接口中目前定义了四种方法。 它们都使用 DBus 状态处理。
-
AddExport
此方法有两个参数。 第一个参数是要处理的配置文件在服务器本地文件系统中的路径名。 第二个参数是一个字符串,它是一个描述要处理的块的搜索表达式。
-
RemoveExport
此方法接受单个整数参数,该参数通过ID参数标识导出。此方法的未来版本可能采用与AddExport方法类似的表达式。
-
UpdateExport
与 AddExport 类似,此方法接受两个参数。 第一个参数是要处理的配置文件在服务器本地文件系统中的路径名。 第二个参数是一个字符串,它是一个描述要处理的块的搜索表达式。
可以使用 dBus 更新特定导出,并且配置中的所有导出都在 SIGHUP 上刷新。 有了这个,您可以动态更新除 export_id、path 和 pseudo 之外的所有内容,这些基本上意味着删除导出并再次添加它,所以只需使用 dBus 删除和添加命令。 SIGHUP 还将添加已添加到配置文件的任何新导出(它不会删除任何导出 - 它不会检查配置文件中是否不再存在任何导出)。 如果指定的导出尚不存在,则 dBus 更新导出也将添加该导出。
注:
此 UpdateExport 功能在 V2.4 中实现
-
DisplayExport
此方法接受单个整数参数,该参数通过其 ID 参数标识导出。 它返回下表中描述的四个值。
-
ShowExports
此方法不接受输入参数。 它返回一个导出数组,如下所述。
AddExport, UpdateExport搜索表达式
搜索表达式用于标识配置文件中的导出。 这是这些配置文件搜索表达式的第一次使用,但这可以应用于已解析配置中的任何块。 该表达式使用以下形式。 空白被忽略。 只有令牌是重要的。
BlockName ( ParameterName = Value )
BlockName 是配置处理器识别的任何有效块名称,在本例中为 EXPORT。 ParameterName 可以是块中定义的任何参数。 最好选择一个可以唯一标识块的。 在导出的情况下,DisplayExport 方法的任何一个返回值都可以工作。 Value 是通配符的“*”(匹配任何内容)或与块中设置的相应值进行比较的值。
这是最简单的表达方式。 这可以通过两种方式扩展。 第一种是逗号分隔的参数集。
ParameterOne = Value1 , ParameterTwo = Value2 , …
这些表达式中的每一个都是从左到右进行的,, 等效于逻辑 AND。 换句话说,如果 ParameterOne 等于 Value1 并且 ParameterTwo 等于 Value2,则整个列表为真,这意味着该块被选中。 如果任何不相等,从第一个开始,则不选择该块。
第二种情况适用于子块。 在这种情况下,我们在配置中选择一个子块,并且必须选择两者的匹配参数。 这个情况看起来像,
BlockName ( some-set-of-parameters ) . SubBlockName ( subblock-paremeters ) . …
如果 BlockName 的参数匹配,则继续搜索其子块 SubBlockName。 这与参数集一样,可以进行到任意深度的子块。
注:
此选择功能目前,从 V2.1 开始,仅适用于导出块,但此查找功能和表达式处理可以应用于任何配置块。
DisplayExport 结果
下表描述了此方法返回的结果。
名称 | 类型 | 详情 |
---|---|---|
id | 整数 | 导出ID |
fullpath | 字符串 | 要导出的后端文件系统中根点的路径 |
pseudopath | 字符串 | 伪文件系统中要“挂载” fullpath 的路径。 即联结 |
tag | 字符串 | NFSv3 挂载请求使用的备用导出名称。 它类似于 pseudopath,只是它是一个标记符号,而不是路径。 |
ShowExports 结果
以下两个表描述了此方法返回的结果。 系统中每个活动的导出都有一个数组行。
名称 | 类型 | 详情 |
---|---|---|
time | 结构体 | struct timespec 格式的数据的时间戳。 (可选的) |
exports | 数组 | 导出标志数组。 请参阅下面的导出表 |
注
该接口没有status或error字段。 它总是会返回时间,但它可以返回一个空的导出数组,这表明服务器中没有定义导出。
导出表是一个结构体数组,每个结构体都描述了导出的统计状态。 每个导出有一行,格式如下:
名称 | 类型 | 详情 |
---|---|---|
export id | int32 | 配置文件中定义的导出id |
path | 字符串 | 导出的路径根 |
nfsv3 | 布尔型 | 如果有任何 NFSv3 活动,则为 true |
mnt | 布尔型 | 如果有任何 MNTv3 活动,则为 true |
nlm4 | 布尔型 | 如果有任何 NLMv4 活动,则为 true |
rquota | 布尔型 | 如果有任何 RQUOTA 活动,则为 true |
nfsv40 | 布尔型 | 如果有任何 NFSv4.0 活动,则为 true |
nfsv41 | 布尔型 | 如果有任何 NFSv4.1 活动,则为 true |
nfsv42 | 布尔型 | 如果有任何 NFSv4.2 活动,则为 true |
9P | 布尔型 | 如果有任何 9P 活动,则为 true |
last time | 结构体 | struct timespec 格式的最后一次数据更新的时间戳。 |
此处有两个时间戳。 消息的 time 字段是回复的当前“现在”时间。 last time 是最后一次统计更新的时间戳。 例如,如果此特定导出上一次有任何活动是在昨天,那么 time 将比 last time 晚一天。
布尔值用于选择相关统计信息。 每个布尔值都与下面描述的方法相关联。 如果布尔值为 false,则其关联的统计方法将返回“导出没有任何 <protocol></protocol> 活动”错误。 客户端开发人员应首先调用 ShowExports 方法,然后使用结果仅调用实际需要报告的统计方法。
org.ganesha.nfsd.exportstats
当前定义了四种方法。 9P 协议的统计数据尚未定义。
每个方法都接受一个 32 位整数 export id 参数。 这是上面ShowExports 方法返回的数组中返回的export id 字段。
每个统计方法都返回自己的相关数据
GetNFSv3IO
此方法报告每个导出的 NFSv3 协议的 I/O 统计信息。 总操作计数已累计,但此时仅报告 I/O 统计信息。 有关详细信息,请参阅上面的 I/O 操作结构。
GetNFSv40IO
此方法报告每个导出的 NFSv4.0 协议的 I/O 统计信息。 它的回复格式和语义与 NFSv3 回复相同。
GetNFSv41IO
此方法报告每个导出的 NFSv4.1 协议的 I/O 统计信息。 尽管其格式与其他协议相同,但其语义却大不相同。 这些计数用于元数据服务器完成的 I/O,而不是数据服务器或 OSD 的统计信息汇总。 这些统计数据必须直接从数据服务器获得,并为完整的服务器吞吐量计算求和。
GetNFSv41Layouts
此方法报告每个导出的 pNFS 特定操作。 这些计数器代表元数据服务器操作,因此,所有 pNFS 导出的计数器总和应等于数据服务器为这些导出报告的操作总和。
/org/ganesha/nfsd/admin
这是服务器管理的对象路径。 有一个为所有接口和方法生成的自省接口。 一些接口具有自省的属性。
org.ganesha.nfsd.admin
此接口用于管理整体服务器操作。 所有这些方法都返回通常的 status 和 error 回复。
-
grace
此方法将单个 IP 地址作为其参数。 调用此方法(重新)启动服务器中的 GRACE 周期以获取状态并锁定指定的 IP 地址。 这用于管理服务器集群。
-
reload
此方法(当前)不接受任何参数。 这相当于向服务器发送 SIGHUP 信号。
-
shutdown
此方法(当前)不接受任何参数。 这是一个有序的关闭,它释放所有资源,包括后端文件服务器状态。
org.ganesha.nfsd.log
该接口控制服务器的日志记录器。 这是管理员工具用来更改日志记录级别以帮助诊断事件的接口。 大多数组件的默认级别是 NIV_EVENT。 管理员可以使用 COMPONENT_ALL 通过将其设置为 NIV_FATAL 来静默所有日志记录。 这将禁用所有不太严重的消息的报告。 然后,管理员可以将感兴趣的单个组件一直设置到 NIV_FULL_DEBUG 以获取这些组件的每条消息。
当前没有定义方法。 这些属性定义了 Get、Set 和 GetAll 方法。
日志子系统向日志目的地报告事件和错误。 通过为服务器中的大多数子系统定义日志记录组件来管理日志消息的数量。 这允许管理员将日志报告集中在服务器的特定部分。 每个 组件 中的日志消息都有一个分配给它们的日志记录严重性值,以指示消息的重要性。 下表用于控制组件:
名称 | 描述 |
---|---|
COMPONENT_ALL | 这用于设置所有组件的级别 |
COMPONENT_LOG | 日志子系统本身就是这个组件。 |
COMPONENT_LOG_EMERG | 日志系统中的紧急消息 |
COMPONENT_MEMALLOC | 内存分配器错误,(未使用) |
COMPONENT_MEMLEAKS | 检测到内存泄漏 |
COMPONENT_FSAL | FSAL 内部消息 |
COMPONENT_NFSPROTO | NFS(主要是 NFSv3)协议事件和错误 |
COMPONENT_NFS_V4 | NFSv4 特定事件和错误 |
COMPONENT_NFS_V4_PSEUDO | 伪文件系统(用于 NFSv4)事件和错误 |
COMPONENT_FILEHANDLE | 文件句柄编码/解码事件和错误 |
COMPONENT_DISPATCH | NFS RPC 和协议操作解码和调度 |
COMPONENT_CACHE_INODE | 元数据缓存事件和错误 |
COMPONENT_CACHE_INODE_GC | 元数据缓存垃圾回收事件和错误(未使用) |
COMPONENT_CACHE_INODE_LRU | 元数据缓存 LRU 处理事件和错误 |
COMPONENT_HASHTABLE | Hashtable函数事件和调试 |
COMPONENT_HASHTABLE_CACHE | 哈希表缓存事件 |
COMPONENT_LRU | (未使用) |
COMPONENT_DUPREQ | 重复的 NFS 请求处理事件 |
COMPONENT_RPCSEC_GSS | GSS 安全事件 |
COMPONENT_INIT | 服务器初始化和早期启动事件和错误 |
COMPONENT_MAIN | 管理函数和主要服务器事件 |
COMPONENT_IDMAPPER | 客户端 ID 映射函数错误和事件 |
COMPONENT_NFS_READDIR | Readdir 处理错误和事件 |
COMPONENT_NFS_V4_LOCK | NFSv4 文件锁定、状态和委派事件 |
COMPONENT_NFS_V4_XATTR | (未使用) |
COMPONENT_NFS_V4_REFERRAL | (未使用) |
COMPONENT_MEMCORRUPT | (未使用) |
COMPONENT_CONFIG | 配置文件处理错误 |
COMPONENT_CLIENTID | NFSv4 客户端 ID 处理错误和事件 |
COMPONENT_STDOUT | (未使用) |
COMPONENT_SESSIONS | NFSv4.1 会话 ID 处理错误和事件 |
COMPONENT_PNFS | pNFS 错误和事件 |
COMPONENT_RPC_CACHE | (未使用) |
COMPONENT_RW_LOCK | 读/写锁调试 |
COMPONENT_NLM | NLM 锁定协议事件和错误 |
COMPONENT_RPC | RPC 调度和处理错误和事件 |
COMPONENT_NFS_CB | NFSv4 回调事件和错误 |
COMPONENT_THREAD | 一般线程创建和管理错误和事件 |
COMPONENT_NFS_V4_ACL | NFSv4 ACL 处理和访问检查事件 |
COMPONENT_STATE | 一般状态抽象层错误和事件 |
COMPONENT_9P | 9P协议处理事件和错误 |
COMPONENT_9P_DISPATCH | 9P 协议操作调度事件和错误 |
COMPONENT_FSAL_UP | FSAL 对核心服务器事件和错误的调用 |
COMPONENT_DBUS | DBus 服务器和消息处理事件 |
每个组件都有一个用于Set 方法的level 参数,并为Get 和GetAll 方法返回一个level。 名称或短名称都可以用作 Set 的参数。 级别名称始终由 Get 或 GetAll 返回。 下表描述了这些级别及其用途。 这些条目按严重性顺序排列,即,如果级别为 NIV_EVENT,则级别从 NIV_FATAL 到 NIV_EVENT 的任何消息都将被记录,但任何 NIV_INFO 到 *NIV_FULL_DEBUG * 不会被记录。
级别名称 | 短名称 | 描述 |
---|---|---|
NIV_NULL | NULL | Null级别,无操作(内部用于记录器) |
NIV_FATAL | FATAL | 发生了非常糟糕的事情,服务器将退出 |
NIV_MAJ | MAJ | 重大错误。 取决于错误,服务器可能无法继续 |
NIV_CRIT | CRIT | 关键错误。 |
NIV_WARN | WARN | 警告信息,不是致命的 |
NIV_EVENT | EVENT | 报告重要的非错误事件(默认) |
NIV_INFO | INFO | 不如EVENT重要的一般信息 |
NIV_DEBUG | DBG | 用于诊断服务器软件问题的调试消息 |
NIV_MID_DEBUG | M_DBG | 更详细的调试信息 |
NIV_FULL_DEBUG | F_DBG | 非常详细的调试消息 |
致命错误在日志子系统中退出服务器。 重大和严重错误也可能导致服务器在错误发生一段时间后退出,通常是在进一步的错误报告和清理之后。
使用 DBus 管理导出
导出管理对服务器启动和 DBus 发起的更改使用相同的配置文件语法和处理。 本页首先描述了如何编写导出以执行您想要执行的操作,然后解释如何在正在运行的服务器上管理导出。
导出和权限
导出是在 EXPORT 块中定义的。 授予的权限和协议选项在配置文件中有更好的解释,所以我们不会在这里讨论它们。 相反,我们将关注单个导出与其 CLIENT 子块之间的交互。
配置中导出块的全部目的是描述服务器文件命名空间中附加后端文件系统的一部分的位置。 导出还将全局和客户端特定权限附加到这些挂载点。
默认导出参数
如果没有明确指定参数的值,将获得默认值。 服务器已经为大多数配置或多或少敏感的所有参数内置了默认值。 这些可以通过使用类似于 EXPORT 块但只有权限和传输选项的 EXPORTS_DEFAULTS 来更改所有导出。 这些会覆盖内置的默认值。 处理导出块时,首先将其所有参数设置为默认值。 除非在 EXPORT_DEFAULTS 块中设置了值,否则将使用值服务器的内置值。
Sub-mounts
NFS-Ganesha 基础设施能够正确支持多个 FSAL 的导出。 此外,一些 FSAL(VFS、XFS、GPFS 和 LUSTRE)现在可以正确支持多个文件系统的导出,包括子挂载的文件系统。 NFS v4 更适当地支持嵌套导出(其中 /exp1 和 /exp1/some/path/exp2 都是导出)。 当两个导出使用不同的 FSAL 时,大多数情况下支持嵌套导出。 伪文件系统可用于以灵活的方式将各种导出粘贴在一起。
注:
这些示例在表达式参数周围有单引号,因为它们有空格。 但是,鉴于语法使用 ( 和 ),除非有一些引号,否则 Bash 会感到不安。 这些 Python 脚本是参考实现。 对于在内部执行所有 DBus 操作的管理工具来说,这些与 Bash 或任何 shell 的冲突不会成为问题。
这可以通过以下命名空间来说明。 有一个挂载 /fs0 并按原样导出; 我们忽略它实际上可能是本地文件系统中的 /srv/fs0。 我们还在它下面安装了 /fs0/some/path/fs1。 为了让事情更有趣,/fs0 是 ext4,它将使用 VFS FSAL,/fs1 是 GPFS,并使用 GPFS FSAL。 如果我们也有两个导出定义为
EXPORT {export_id = 50;path = /srv/fs0;access_type = RW;pseudo = /fs0;
}
和
EXPORT {export_id = 51;path = /srv/fs1;access_type = MDONLY;pseudo = /fs0/some/path/fs1;
}
/fs0 中的任何文件访问或客户端挂载都将使用 VFS 并被读写。 这将一直延伸到 /fs0/some/path ,此时它将过渡到 /fs1 ,它只允许 MDS 访问。 推测 DS 访问的是 GPFS 集群中的其他节点。 在这个例子中,服务器必须做两件事:
- 服务器在导出处理时检测到这些关系,并在其内部(伪)文件系统中设置 junction。 处理 NFSv3 的挂载请求时,在哪里查找挂载请求的完整路径将确定适用的导出。 换句话说,带有 /fs0/some 的挂载请求将使用 VFS FSAL 并将验证客户端操作的读写。 /fs0/some/path/fs1/foo 的另一个挂载请求将使用 GPFS FSAL 并验证 MDONLY 的客户端操作。 请注意,此示例的访问类型为 NFSv4.1 pNFS,挂载请求为 NFSv3 操作。 在这种情况下,挂载请求将被拒绝。 如果导出是反向定义的,其中子挂载是 /fs0 中的 ext4 文件系统,它将起作用。
- 随着常规操作逐步通过伪文件系统路径,每次查找都必须检测 junction 并移动到适当的 FSAL 以继续查找。 如果示例中只有一个(第二个)导出,这也适用。 查找操作将检测到服务器本地文件系统中的文件系统类型之间存在转换,并执行适当的操作,前三个节点使用 VFS,其余节点使用 GPFS。
客户端参数
CLIENT 子块用于对导出的访问进行细粒度控制。 我们将讨论以下示例。
EXPORT {Path = /srv/fs0;Pseudo = /fs0;Access_type = none;...CLIENT {Access = 192.168.3.4;Access_type = RW;}CLIENT {Access = 192.168.3.0/16;Access_type = RO;}
}
导出作为一个整体拒绝访问任何客户端,因为访问权限是 none。 但是,有两个 CLIENT 块确实允许某些访问。 可以定义任意数量的 CLIENT 块。 以下是在每个请求上处理客户端访问和选项的方式。
- 客户端 192.168.3.4 获得读写访问权限,因为它匹配第一个 CLIENT 块。 权限扫描在第一次匹配时停止。
- 客户端 192.168.4.52 仅获得只读访问权限,因为它不匹配第一个 CLIENT 块,但它匹配第二个的 CIDR 地址定义。
- 客户端 192.168.5.3 根本无法访问,因为它不匹配任何 CLIENT 块,并且导出的权限拒绝所有访问。
此规则不仅适用于访问权限,还适用于其他选项。 例如,可以设置相同的序列以允许 NFSv3 访问某些客户端,而只允许 NFSv4 访问其他客户端。
使用 DBus 工具
2.1 版增加了无需重启服务器即可管理导出的功能。 对于服务器重启可能会造成很大破坏的企业环境,这是一项重要的新功能。 为此目的提供了 manage_exports 命令。
增加导出
要增加导出,管理员需要为命令和子命令提供两个参数。 第一个参数是配置文件的路径,第二个参数是一个表达式,用于标识要在文件中增加哪个导出。
# manage_exports add /etc/ganesha/my_server.conf 'export(export_id = 14)'
第一个参数可以是任何包含相关EXPORT块的配置文件。通常的做法是编辑主配置文件或它可能包含的文件。通过这种方式,如果服务器必须重启,它将提供包含的新导出。然而,这并不是一个硬性要求。可以将一些导出放在单独的文件中,并使用cron作业来控制它们。
add 命令的第二个参数是要添加的导出的描述。 此示例显示添加了 ID 为 14 的导出。 此表达式不限于导出的 ID 号。 可以使用任何可以唯一标识导出的导出参数。 其中最常见的是 export_id、path 或 pseudo。 有关表达式语法的更详细说明,请参阅 DBus 接口。 另一个使用 path 的示例如下所示:
# manage_exports add /etc/ganesha/my_server.conf 'export(path = /fs0/some/path)'
此示例选择 path 定义为 /fs0/some/path 的导出并将其添加到服务器的导出中。
注:
这些示例在表达式参数周围有单引号,因为它们有空格。 但是,鉴于语法使用 ( 和 ),除非有一些引号,否则 Bash 会感到不安。 这些 Python 脚本是参考实现。 对于在内部执行所有 DBus 操作的管理工具来说,这些与 Bash 或任何 shell 的冲突不会成为问题。
移除导出
要删除导出,管理员将导出的 id 提供给子命令。
# manage_exports remove 14
此示例删除了在上一个示例中添加的导出。 从 V2.1 开始,参数是导出 ID。 未来版本可能支持与 add 命令相同的选择语法。
管理导出
在V2.1版本中,唯一可用的选项是add和remove,所以相当于修改的是remove后面跟着add编辑的导出配置。它的工作方式是,它不会干扰服务器,但它确实使导出在remove和add之间的间隔不可用。这通常不是问题,因为NFS协议希望事情消失。如果新的导出定义做了诸如将读写导出转换为只读导出之类的事情,那么9P就会受到影响。
ganesha-DBus实践
列出所有的客户端
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ClientMgr org.ganesha.nfsd.clientmgr.ShowClients
输出
method return time=1700023168.060288 sender=:1.541541 -> destination=:1.585804 serial=6585 reply_serial=2struct {uint64 1700023168uint64 59677086}array [struct {string "::ffff:10.10.10.42"struct {struct {string "NFSv3"boolean true}struct {string "MNT"boolean true}struct {string "NMLv4"boolean false}struct {string "RQUOTA"boolean false}struct {string "NFSv40"boolean false}struct {string "NFSv41"boolean false}struct {string "NFSv42"boolean false}struct {string "9P"boolean false}}struct {uint64 1700023138uint64 734905111}}struct {string "::ffff:127.0.0.1"struct {struct {string "NFSv3"boolean false}struct {string "MNT"boolean true}struct {string "NMLv4"boolean true}struct {string "RQUOTA"boolean false}struct {string "NFSv40"boolean false}struct {string "NFSv41"boolean false}struct {string "NFSv42"boolean false}struct {string "9P"boolean false}}struct {uint64 1700023162uint64 546829022}}]
列出所有导出点
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.ShowExports
输出
method return time=1700026429.339269 sender=:1.541541 -> destination=:1.607663 serial=9842 reply_serial=2struct {uint64 1700016576uint64 197325643}array [struct {uint16 1string "/nfs-share01"struct {struct {string "NFSv3"boolean true}struct {string "MNT"boolean false}struct {string "NMLv4"boolean false}struct {string "RQUOTA"boolean false}struct {string "NFSv40"boolean false}struct {string "NFSv41"boolean false}struct {string "NFSv42"boolean false}struct {string "9P"boolean false}}struct {uint64 1700026372uint64 150023197}}struct {uint16 0string "/"struct {struct {string "NFSv3"boolean false}struct {string "MNT"boolean false}struct {string "NMLv4"boolean false}struct {string "RQUOTA"boolean false}struct {string "NFSv40"boolean false}struct {string "NFSv41"boolean false}struct {string "NFSv42"boolean false}struct {string "9P"boolean false}}struct {uint64 0uint64 0}}]
列出某个导出点的信息
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.DisplayExport uint16:1
输出
method return time=1700026868.059307 sender=:1.541541 -> destination=:1.610578 serial=10281 reply_serial=2uint16 1string "/pcx"string "/nfs-share01"string ""array []
查询某个客户端的NFS3统计
dbus-send --system --print-reply --dest=org.ganesha.nfsd /org/ganesha/nfsd/ClientMgr org.ganesha.nfsd.clientstats.GetNFSv3IO string:"::ffff:20.20.20.43"
其中192.168.80.43为客户端ip地址
输出
method return time=1700027345.675762 sender=:1.541541 -> destination=:1.613817 serial=10765 reply_serial=2boolean truestring "OK"struct {uint64 1700016576uint64 197325643}struct {uint64 0uint64 0uint64 0uint64 0uint64 0uint64 0}struct {uint64 0uint64 0uint64 0uint64 0uint64 0uint64 0}
查询NFS状态统计
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportstats.StatusStats
输出
method return time=1700027657.256637 sender=:1.541541 -> destination=:1.615884 serial=11078 reply_serial=2boolean truestring "OK"struct {boolean truestruct {uint64 1700016576uint64 197325643}}struct {boolean falsestruct {uint64 1700016576uint64 197325643}}struct {boolean falsestruct {uint64 1700016576uint64 197325643}}struct {boolean falsestruct {uint64 1700016576uint64 197325643}}struct {boolean falsestruct {uint64 1700016576uint64 197325643}}struct {boolean falsestruct {uint64 1700016576uint64 197325643}}
查看缓存Inode
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportstats.ShowCacheInode
输出:
method return time=1700018481.642246 sender=:1.537016 -> destination=:1.540390 serial=516 reply_serial=2
boolean true
string "OK"
struct {uint64 1700018481uint64 641894468
}
struct {string " Cache Requests: "uint64 0string " Cache Hits: "uint64 65string " Cache Misses: "uint64 0string " Cache Conflicts: "uint64 0string " Cache Adds: "uint64 7string " Cache Mapping: "uint64 14
}
struct {string " FSAL opened FD count : "uint64 0string " System limit on FDs : "uint32 4096string " FD usage : "string " Below Low Water Mark "string " LRU entries in use : "uint64 7string " Chunks in use : "uint64 0
}
设置ganesha的log输出等级
dbus-send --system --print-reply --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.freedesktop.DBus.Properties.Set \string:org.ganesha.nfsd.log.component string:COMPONENT_FSAL variant:string:NIV_DEBUG
dbus-send --system --print-reply --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.freedesktop.DBus.Properties.Set \string:org.ganesha.nfsd.log.component string:COMPONENT_FSAL variant:string:NIV_FULL_DEBUG
其中NIV_DEBUG、NIV_FULL_DEBUG为日志等级
增加导出点
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport string:/etc/ganesha/test.conf string:"export(path=/opt/testnfs)"
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport string:/etc/ganesha/test.conf string:"export(export_id=3)"
其中path是导出路径
删除导出点
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.RemoveExport uint16:3
其中3是export_id
更新导出点
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport string:/etc/ganesha/test.conf string:"export(path=/opt/testnfs)"
dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport string:/etc/ganesha/test.conf string:"export(export_id=3)"