本文主要是对Gregory Farnum关于cephfs caps介绍的简单总结,主要介绍caps的基本设计,更深入的的如lock相关代码没有涉及。
文章目录
caps基础
基本概念
caps是mds授予client对文件进行操作的许可证,当一个client想要对文件元数据进行变更时,比如读、写、修改权限等等操作,它都必须先获取到相应的caps才可以进行这些操作。
ceph对caps的划分粒度很细,且允许多个client在同一个inode上持有不同的caps。
caps种类
根据元数据内容的不同,ceph将caps也分为了多个类别,每种类别只负责作用于某些特定的元数据:
| 类别 | 功能 |
|---|---|
| PIN | mds是否将inode pin在cache中 |
| AUTH | 权限属性相关的元数据,主要是owner、group、mode;但是如果是完整的鉴权是需要查看ACL的,acl信息保存在xattr中,这就需要XATTR相关的cap |
| LINK | inode的link count |
| XATTR | xattr |
| FILE | 最重要也是最复杂的一个,用于文件数据,以及和文件数据相关的size、atime、ctime、mtime等 |
caps permission种类
#define CEPH_CAP_GSHARED 1 /* client can reads (s) */
#define CEPH_CAP_GEXCL 2 /* client can read and update (x) */
#define CEPH_CAP_GCACHE 4 /* (file) client can cache reads (c) */
#define CEPH_CAP_GRD 8 /* (file) client can read (r) */
#define CEPH_CAP_GWR 16 /* (file) client can write (w) */
#define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes (b) */
#define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF (a) */
#define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io (l) */
caps combination
一个完整cap通过【类别+permission种类】组成,client可以同时申请多个类别的caps。但是并不是每种caps都可以使用每种permission,有些caps只能搭配部分permission。有关caps种类和permission的结合使用,有以下几个规则:
pin
二值型,有pin就代表client知道这个inode存在,这样mds就一定会在其cache中保存这个inode
Auth、Link、Xattr
只能为shared或者exclusive
- shared:client可以将对应元数据保存在本地并缓存和使用
- exclusive:client不仅可以在本地缓存使用,还可以修改
下面是两个例子:
- [A]s:某client对inode 0x11有As的cap,此时收到一个查看0x11状态的系统调用,那么client不需要再向mds请求,直接通过查询自身缓存并进行处理和回复
- [A]x:某client对inode 0x11有Ax的cap,此时收到一个修改mode的系统调用,client可以直接在本地进行修改并回复,并且在之后才将修改变更通知mds
File
如前所述,file是最复杂的一种,下面是File cap的各个类别:
| file cap种类 | client权限 |
|---|---|
| Fs | client可以将mtime和size在本地cache并读取使用 |
| Fx | client可以将mtime和size在本地cache并进行修改和读取 |
| Fr | client可以同步地从osd读取数据,但不能cache |
| Fc | client可以将文件数据cache在本地内存,并直接从cache中读 |
| Fw | client可以同步地写数据到osd中,但是不能buffer write |
| Fb | client可以buffer write,先将写的数据维护在自己内存中,再统一flush到后端落盘 |
caps管理
lock
caps由mds进行管理,其将元数据划分为多个部分,每个部分都有专门的锁(SimpleLock、ScatterLock、FileLock)来保护,mds通过这些锁的状态来确定caps可以怎么样分配。
mds内部维护了每个锁的状态机,其内容非常复杂,也是mds保证caps分配准确性和数据一致性的关键。
caps如何变更
- mds可以针对每个client进行授予和移除caps,通常是由其他client的行为触发
- 例:比如client1已经拥有了inode 0x111的cache read的cap,此时client2要对这个文件进行写,那显然除了授予client2响应的写caps的同时,还要剥夺client1的cache read的cap
- 当client被移除caps时,其必须停止使用该cap,并给mds回应确认消息。mds需要等待收到client的确认消息后才会revoke。(如果client挂掉或者出于某种原因没有回复ack怎么办?)
- client停止使用并不简单,在不同场景下需要完全不同的处理:
- 例1:client被移除cache read cap,直接把该file的cache删掉,并变更状态就行了,这样下次的read请求过来时,还是到osd去读
- 例2:client被移除buffer write cap,已经缓存了大量的数据还没有flush,那就需要先flush到osd,再变更状态和确认,这可能就需要较长时间
下面来看看一个修改权限的例子实际感受下:

caps相关告警
下面是一些caps相关的主要告警信息,可参考对照排查问题:
| 告警信息 | 问题 |
|---|---|
| Client failing to respond to capability release | mds发出了revoke cap消息但是client没有回复 |
| Client failing to cache pressure | mds发送消息请求client去除一些pinned inode以减少内存使用,但client没有drop的足够或者没有回复的足够快 |
总结
- mds需要记住所有client pin的inode,
- mds的cache需要比client的cache更多
- caps是由mds和client端共同协作维护的,所以client需要正常运行,否则可能会block其他client(也就是说前面提出的问题,会被block?)

本文详细介绍了Ceph文件系统中的Caps机制,包括Caps的基础概念、种类、权限类型及组合方式,阐述了Caps在客户端与MDS之间的管理流程,以及Caps变更与告警的相关信息。同时,还提供了Caps代码实现的解析,以及一个FuseWrite实例,帮助读者深入理解CephFS的文件操作许可机制。

2524

被折叠的 条评论
为什么被折叠?



