searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

NLM(网络锁管理协议)与NFSv3版本集成方法

2023-01-30 10:43:34
460
0

在存储系统中, NFS(Network File System,即网络文件系统)是一个重要的概念,已成为兼容POSIX语义的分布式文件系统的基础。它允许在多个主机之间共享公共文件系统,并提供数据共享的优势,从而最小化所需的存储空间。

天翼云终端通过NFS实现共享空间服务, 提供基于用户和部门的权限管理与容量管理, 但是在NFSv3对于共享文件系统很重要文件锁功能并不集成在NFS服务中,而是一个分离的NLM服务,这个锁管理服务必须与原生linux版本的NFS服务配合使用,导致当我们需要自行开发NFS服务端时,无法直接利用此服务完成文件锁功能, 这也是导致多数云服务商的NFSv3服务无法提供文件锁功能的原因。

因为Windows原生只支持v3以下版本的NFS, 具备文件锁功能的NFSv4尚无法替代NFSv3。 本文将深入介绍NLM协议的细节, 以及自行实现NLM协议与NFS服务器集成的注意事项。

 

一、协议与框架

NLM基于以下协议与RPC框架实现

ONC-RPC:NLM 协议在 ONC-RPC 之上实现,是一种节省字节的rpc协议。

portmap协议:与NFS一样,客户端通过portmap协议来发现服务端的NLM服务端口, 通常在自行实现的NFS服务端, portmap也可以集成在NFS服务中 。

NSM协议:NLM依赖 NSM 协议来通知彼此服务重启/重启,以便在重启后可以重新同步锁。


二、协议主体内容

NLM协议主要通过以下请求达成锁的效果。

Null :相当于PING,用来查看是否正常运行。

Lock :用来在在服务器上申请锁。在请求独占锁的情况下,可能会发生锁争用。

Unlock :释放已申请的锁。

Cancel :通常与Unlock语义一致,在Linux NFS 客户端实现中:Unlock 通常在应用程序通过 fcntl() 调用显式释放锁定时使用。 Cancel 通常在应用程序终止后由锁管理器发出,而没有自行清理锁。

Granted :当阻塞的锁变得可用时,服务器回调客户端以告诉它需要的锁已经可用。

三、协议报文

对于各类锁请求,服务端的主要响应如下信息:
enum nlm_stats {
    LCK_GRANTED = 0, //加锁成功
    LCK_DENIED = 1, //加锁失败
    LCK_DENIED_NOLOCKS = 2,//加锁失败,服务端没有对应的资源
    LCK_BLOCKED = 3, //加锁失败,当前不可以加锁,服务端会在可加锁时回调客户端
    LCK_DENIED_GRACE_PERIOD = 4 //加锁失败,服务端刚刚重启,无法响应
};

各种锁请求中, 对于锁的描述主要由如下字段构成
struct nlm_lock {
    string caller_name<LM_MAXSTRLEN>;  /*  调用方的唯一标识  */
    netobj fh;         /*  file handle, 文件标识  */
    netobj oh;         /*  调用进程或主机的唯一标识 */
    int uppid;         /*  进程唯一标识  */
    unsigned l_offset; /*  锁开始位置 */
    unsigned l_len;    /*  锁对象长度  */
};

nlm_lock结构 ,是主要的锁请求,如lock,unlock,cancel的主要参数,例如
struct nlm_lockargs {
    netobj cookie;
    bool block;            /*  是否阻塞 */
    bool exclusive;        /* 共享锁还是排它锁*/
    struct nlm_lock alock; /*  锁信息结构 */
    bool reclaim;          /*  与NSM协议配合使用的字段, 只有在感知到服务端重启时才为true */
    int state;             /*  客户端NSM状态 */
};

除此以外,NLM协议还要支持 DOS 3.1 及更高版本兼容的文件共享控制,即share与unshare请求。
通常, windows版本的客户端并不使用nlm lock 请求,而是nlm share请求。
struct nlm_share {
    string caller_name<LM_MAXSTRLEN>;
    netobj fh;
    netobj oh;
    fsh_mode mode;
    fsh_access access;
};

 

struct nlm_shareargs {
    netobj cookie;
    nlm_share share;     /*  actual share data  */
    bool reclaim;        /*  used for recovering shares  */
};

 

四、注意事项

1. NLM协议与NFS使用相同的鉴权方式, NLM服务端与NFS集成的方式实际上有利于复杂鉴权功能的实现。

2. 考虑到网络丢包带来的重复加锁的可能性,服务端在实现加锁请求时要考虑锁的可重入。

3. lock与share两种加锁方式有所不同, lock支持共享/排他锁,并且支持分段加锁, 而share则支持分离的读写锁,服务端需要兼容两种协议的实现。

 

0条评论
0 / 1000
yurch
7文章数
0粉丝数
yurch
7 文章 | 0 粉丝
原创

NLM(网络锁管理协议)与NFSv3版本集成方法

2023-01-30 10:43:34
460
0

在存储系统中, NFS(Network File System,即网络文件系统)是一个重要的概念,已成为兼容POSIX语义的分布式文件系统的基础。它允许在多个主机之间共享公共文件系统,并提供数据共享的优势,从而最小化所需的存储空间。

天翼云终端通过NFS实现共享空间服务, 提供基于用户和部门的权限管理与容量管理, 但是在NFSv3对于共享文件系统很重要文件锁功能并不集成在NFS服务中,而是一个分离的NLM服务,这个锁管理服务必须与原生linux版本的NFS服务配合使用,导致当我们需要自行开发NFS服务端时,无法直接利用此服务完成文件锁功能, 这也是导致多数云服务商的NFSv3服务无法提供文件锁功能的原因。

因为Windows原生只支持v3以下版本的NFS, 具备文件锁功能的NFSv4尚无法替代NFSv3。 本文将深入介绍NLM协议的细节, 以及自行实现NLM协议与NFS服务器集成的注意事项。

 

一、协议与框架

NLM基于以下协议与RPC框架实现

ONC-RPC:NLM 协议在 ONC-RPC 之上实现,是一种节省字节的rpc协议。

portmap协议:与NFS一样,客户端通过portmap协议来发现服务端的NLM服务端口, 通常在自行实现的NFS服务端, portmap也可以集成在NFS服务中 。

NSM协议:NLM依赖 NSM 协议来通知彼此服务重启/重启,以便在重启后可以重新同步锁。


二、协议主体内容

NLM协议主要通过以下请求达成锁的效果。

Null :相当于PING,用来查看是否正常运行。

Lock :用来在在服务器上申请锁。在请求独占锁的情况下,可能会发生锁争用。

Unlock :释放已申请的锁。

Cancel :通常与Unlock语义一致,在Linux NFS 客户端实现中:Unlock 通常在应用程序通过 fcntl() 调用显式释放锁定时使用。 Cancel 通常在应用程序终止后由锁管理器发出,而没有自行清理锁。

Granted :当阻塞的锁变得可用时,服务器回调客户端以告诉它需要的锁已经可用。

三、协议报文

对于各类锁请求,服务端的主要响应如下信息:
enum nlm_stats {
    LCK_GRANTED = 0, //加锁成功
    LCK_DENIED = 1, //加锁失败
    LCK_DENIED_NOLOCKS = 2,//加锁失败,服务端没有对应的资源
    LCK_BLOCKED = 3, //加锁失败,当前不可以加锁,服务端会在可加锁时回调客户端
    LCK_DENIED_GRACE_PERIOD = 4 //加锁失败,服务端刚刚重启,无法响应
};

各种锁请求中, 对于锁的描述主要由如下字段构成
struct nlm_lock {
    string caller_name<LM_MAXSTRLEN>;  /*  调用方的唯一标识  */
    netobj fh;         /*  file handle, 文件标识  */
    netobj oh;         /*  调用进程或主机的唯一标识 */
    int uppid;         /*  进程唯一标识  */
    unsigned l_offset; /*  锁开始位置 */
    unsigned l_len;    /*  锁对象长度  */
};

nlm_lock结构 ,是主要的锁请求,如lock,unlock,cancel的主要参数,例如
struct nlm_lockargs {
    netobj cookie;
    bool block;            /*  是否阻塞 */
    bool exclusive;        /* 共享锁还是排它锁*/
    struct nlm_lock alock; /*  锁信息结构 */
    bool reclaim;          /*  与NSM协议配合使用的字段, 只有在感知到服务端重启时才为true */
    int state;             /*  客户端NSM状态 */
};

除此以外,NLM协议还要支持 DOS 3.1 及更高版本兼容的文件共享控制,即share与unshare请求。
通常, windows版本的客户端并不使用nlm lock 请求,而是nlm share请求。
struct nlm_share {
    string caller_name<LM_MAXSTRLEN>;
    netobj fh;
    netobj oh;
    fsh_mode mode;
    fsh_access access;
};

 

struct nlm_shareargs {
    netobj cookie;
    nlm_share share;     /*  actual share data  */
    bool reclaim;        /*  used for recovering shares  */
};

 

四、注意事项

1. NLM协议与NFS使用相同的鉴权方式, NLM服务端与NFS集成的方式实际上有利于复杂鉴权功能的实现。

2. 考虑到网络丢包带来的重复加锁的可能性,服务端在实现加锁请求时要考虑锁的可重入。

3. lock与share两种加锁方式有所不同, lock支持共享/排他锁,并且支持分段加锁, 而share则支持分离的读写锁,服务端需要兼容两种协议的实现。

 

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0