注意

本文档适用于 Ceph 开发版本。

MDS静默协议

MDS暂停协议是一种用于“暂停”(静音)文件系统中树的方法,停止所有写入(有时也会附带读取)I/O。

此API的目的是防止多个客户端在最终一致性的快照屏障中交错读取和写入,其中客户端之间存在带外通信。这种通信可能导致客户端错误地认为他们已达到可以通过快照相互恢复的检查点。

Note

这是MDS中用于暂停文件树的低级机制的文档。更高层次的QuiesceDb是客户端执行暂停的预期API。

机制

启动的子请求是内部请求。这些请求将获取“与权限相关的”锁,这些锁控制权限状态,包括...quiesce_path internal request that obtains appropriate locks on the root of a tree and then launches a series of sub-requests for locking other inodes in the tree. The locks obtained will force clients to release caps and in-progress client/MDS requests to complete.

启动的子请求是内部请求。这些请求将获取“与权限相关的”锁,这些锁控制权限状态,包括...quiesce_inode internal requests. These will obtain “cap-related” locks which control capability state, including the filelock, authlock, linklock, and xattrlock此外,还会获取新的本地锁...quiescelock更多关于该锁的信息在下一节中。

与权限不相关的锁会被跳过,因为它们不控制典型的和持久的元数据状态。此外,只有权限可以给客户端对文件的元数据或数据提供本地控制。

一旦所有锁都已获取,权限相关的锁将被释放,并依赖...quiescelock来防止为客户端发出与权限相关的锁的权限。这主要由...CInode:get_caps_*方法控制。释放这些锁是允许具有复制inode的其他等级暂停而不导致死锁状态转换的必要条件。例如,一个想要...Xx在一个inode上的客户端将触发...xattrlock in LOCK_SYNC状态转换到...LOCK_SYNC_EXCL。该状态将不允许另一个等级获取...xattrlock用于读取,从而创建死锁,取决于暂停超时/过期。(暂停不能完成,直到所有等级都暂停了树。)

最后,如果inode是一个目录,...quiesce_inode操作将遍历所有目录片段,并为任何子inode发出新的...quiesce_inode请求。

节点静默锁

The quiescelock是用于inode的新本地锁,支持暂停I/O。它是一种超级锁,客户端或MDS的任何需要“与权限相关的”inode锁上的wrlock或xlock的操作也会隐式地获取...quiescelock.

Note

本地锁支持多个写入者,并且只有一个排他性锁。没有读锁。

在MDS的正常操作期间,...quiescelock除了写入外,永远不会持有。但是,当子树被暂停时,...quiesce_inode内部操作将...quiescelock排他性地持有...quiesce_inode操作的整个生命周期。这将阻止...new获取任何其他与权限相关的inode锁。...quiescelock必须在所有其他锁之前排序(见...src/include/ceph_fs.h对于排序),以便充当这个超级锁。

这样做的一个主要原因是防止客户端请求在获取由...quiescelock is to prevent a client request from blocking on acquiring locks held by quiesce_inode(例如...filelockquiescelock)持有的锁时阻塞,同时仍然持有在正常路径遍历期间获取的锁。值得注意的是,重要的锁是通过...snaplockpolicylock obtained via Locker::try_rdlock_snap_layout在请求的根inode的所有父节点上获取的(即...ino。Cephadm 还支持使用filepath结构)。如果该操作在持有这些锁的情况下等待,那么未来的...mksnap在根inode上将是不可行的。

Note

The mksnapRPC只为要快照的inode在...snaplock上获取wrlock(写锁)。

...quiescelock防止这种情况的方法是,在获取与权限相关的锁的wrlock或xlock时,它是第一个强制获取的锁。此外,当它无法获取时,也会有特殊处理:操作持有的所有锁都会被丢弃,并且操作会等待...mandatory lock acquired when acquiring a wrlock or xlock on a cap-related lock. Additionally, there is also special handling when it cannot be acquired: all locks held by the operation are dropped and the operation waits for the quiescelock可用。该锁是强制性的,因为对...Locker::acquire_locks的调用,在具有与权限相关的锁的wrlock/xlock时,将自动包含(添加)...quiescelock.

所以,预期的正常流程是,像...mkdir这样的操作将执行其路径遍历,获取父节点和dentry锁,然后尝试获取创建dentry所需的父inode上的锁。操作将无法获取...quiescelock的wrlock,将自己添加到...quiescelock等待列表中,然后丢弃所有持有的锁。

查找和导出

暂停树会导致每个树下的inode执行多个...quiesce_inode操作。这些操作具有与父...quiesce_path操作相关的共享生命周期。因此,一旦操作完成暂停(但未完成并释放锁),操作将持有锁而不会监控树的状态。这意味着我们需要处理导入新元数据的情况。

如果通过目录...lookupreaddir获取inode,MDS将检查其父节点是否已暂停(即是否是父目录...quiescelockx锁定的?)。如果是,MDS将立即发出...quiesce_inode操作。由于这是一个新的inode,操作将立即成功,并防止向客户端发出不适当的权限。

第二种情况是处理从另一个等级导入的子树。这是有问题的,因为子树导入可能具有不适当的状态,这将使据报道“已暂停”的树的保证无效。为了避免这种情况,导入的MDS如果遇到已暂停的目录inode,将跳过导入的根inode的发现。如果跳过,等级将向导出者发送NAK消息,导出者将中止导出。

由 Ceph 基金会带给您

Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.