LVM锁服务lvmlockd分析

  • lvmlockd守护进程使用LVM内部的libdaemon库实现与命令行程序的通信,为LVM命令提供分布式锁功能。
  • lvmlockd的具体实现依赖sanlock(依赖wdmd服务)和dlm(依赖CoroSync、PaceMaker和Fence设备)。
  • lvmlockd必须配合LVM的本地锁(flock)使用,是本地锁在集群环境下的扩充。
  • lvmlockd的作者也是sanlock的原作者,发起此项目的目的是替代clvmd,使得用户在dlm外有更多选择(但从他的源码结构来看,没有使用一个好的抽象接口,很难扩充第三种锁的支持,我认为这不是一个好的设计)。
  • lvmlockd可以和lvmetad共存,但clvmd却不可以(原因未知,我并没有分析出他们为什么不能共存)。
  • lvmlockd的功能没有使用LVM的锁抽象接口来实现,而是直接插入LVM源码中(我认为这不是个好的设计)。

上层接口函数

上层接口函数为LVM命令提供了与lvmlockd守护进程建立连接,并使用其提供的所服务的功能,这些函数的调用分布在LVM命令的所有需要锁的环节。

连接和断开服务

$ cat daemons/lvmlockd/lvmlockd-client.h
...

#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"

/* Wrappers to open/close connection */

static inline daemon_handle lvmlockd_open(const char *sock)
{
	daemon_info lvmlockd_info = {
		.path = "lvmlockd",
		.socket = sock ?: LVMLOCKD_SOCKET,
		.protocol = "lvmlockd",
		.protocol_version = 1,
		.autostart = 0
	};

	return daemon_open(lvmlockd_info);
}

static inline void lvmlockd_close(daemon_handle h)
{
	return daemon_close(h);
}

...

锁操作

$ cat lib/locking/lvmlockd.h
...

/* vgcreate/vgremove use init/free */

int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);

/* vgrename */

int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg);
int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int success);

/* start and stop the lockspace for a vg */

int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init);
int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_wait(struct cmd_context *cmd);

/* locking */

int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *vg_lock_type);
int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags);
int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
	     uint32_t flags, uint32_t *lockd_state);
int lockd_vg_update(struct volume_group *vg);

int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
		  const char *lv_name, struct id *lv_id,
		  const char *lock_args, const char *def_mode, uint32_t flags);
int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
	     const char *def_mode, uint32_t flags);

/* lvcreate/lvremove use init/free */

int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logical_volume *lv,
		  struct lvcreate_params *lp);
int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg,
		       struct logical_volume *lv, const char *lock_type, const char **lock_args);
int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
		  const char *lv_name, struct id *lv_id, const char *lock_args);

const char *lockd_running_lock_type(struct cmd_context *cmd, int *found_multiple);

int handle_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg);

int lockd_lv_uses_lock(struct logical_volume *lv);

...

内部数据结构

锁定范围(对象)

  • 全局
  • 卷组
  • 逻辑卷
$ cat daemons/lvmlockd/lvmlockd-internal.h
...

/* resource types */
enum {
	LD_RT_GL = 1,
	LD_RT_VG,
	LD_RT_LV,
};

...

锁定模式(状态)

  • 无效
  • 解锁
  • 空锁
  • 共享
  • 独占
...

/* lock modes, more restrictive must be larger value */
enum {
	LD_LK_IV = -1,
	LD_LK_UN = 0,
	LD_LK_NL = 1,
	LD_LK_SH = 2,
	LD_LK_EX = 3,
};

...

锁管理器类型

目前只支持DLM和sanlock。

...

/* lock manager types */
enum {
	LD_LM_NONE = 0,
	LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
	LD_LM_DLM = 2,
	LD_LM_SANLOCK = 3,
};

...

客户端管理

每个客户端连接对应一个。

...

struct list_head {
	struct list_head *next, *prev;
};

struct client {
	struct list_head list;
	pthread_mutex_t mutex;
	int pid;
	int fd;
	int pi;
	uint32_t id;
	unsigned int recv : 1;
	unsigned int dead : 1;
	unsigned int poll_ignore : 1;
	unsigned int lock_ops : 1;
	char name[MAX_NAME+1];
};

...

动作(报文)

每个客户端的请求都被填充为一个请求。

类型
...

/* operation types */
enum {
	LD_OP_HELLO = 1,
	LD_OP_QUIT,
	LD_OP_INIT,
	LD_OP_FREE,
	LD_OP_START,
	LD_OP_STOP,
	LD_OP_LOCK,
	LD_OP_UPDATE,
	LD_OP_CLOSE,
	LD_OP_ENABLE,
	LD_OP_DISABLE,
	LD_OP_START_WAIT,
	LD_OP_STOP
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值