SBD原理及代码分析

SBD原理及代码分析

2023年7月26日发(作者:)

作者:谷锎(gushenbusi@)

时间:2010-11-15

原理简析

Sbd设备需要在开始阶段初在SAN(包括iscsi)始化一个target或lun。写入下面信息

Header存放公共数据。

Slot 对应自己一个mbox。

可以认为slot是集群主机在sbd device的地址,mbox是邮箱。

每个地址对应一个单独的邮箱。

共有255个地址和邮箱。

Header slot mbox都占一个sector。所以sbd至少需要512个sector的大小。

当主机启用SBD deamon(调用watch命令)。主机就会启用watchdog,直到自身重启或收到message exit。

启动SBD deamon时会给当前主机重新分配一个slot。并清空信箱。

Deamon轮训查看自己信箱中的命令然后响应这些操作。

响应的操作包括:

Reset: 向/proc/sysrq-trigger写入b让主机重新启动。即使操作不成功会等待两倍喂狗时间,

让watchdog重新启动。

Off: 向/proc/sysrq-trigger写入o让主机关机。即使操作不成功会等待两倍喂狗时间, 让watchdog重新启动。

Exit: 关闭watchdog

Test: 收到消息后迅速制空信箱。(对ping命令的响应,其他节点看到迅速制空,知道该

节点能够ping通)

信箱中的信息由message命令填入。当填入命令时,会在邮箱中写入寄信人。(寄信人没有实际作用)

fence分析

对于一个节点来说被fence存在两种可能。

1.收到message后响应-(收到消息)-------------- -------调用do_reset(void)

2.无法读取自己mbox(和共享存储断开)----------- 调用do_reset(void)

do_reset(void) 调用sysrq_trigger(char t) 向里面写b重启。如果失败的话sleep双倍喂狗时间。靠watchdog来重新启动。

结论:sbd最终都是靠watchdog保证重新启动。最好还是有 硬件watchdong。并用 -w来指定。

fence谁?

1.以上只要和共享存储断开连接那么就会do_reset(void)重新启动

2.由于双机情况只能有一台主机发送message。(即拥有SBD resource),否则一旦出项下面场景,可能出现deathmatch(相互不停的fence)

下面情况一段出现,都会由拥有发送message权力的一方fence对方。所以对于场景4而言就会出现 问题机 fence 非问题机的现象。(本质上发message只是向共享存储写信息,并不会走业务线路)。

问题出在:集群业务线路(非共享存储)出现问题的情况。拥有发送message权限的一方,不能确定message该发送给谁(可以给自己发送message) 能否采用ping网关的方式。

代码流程

数据结构:

struct sector_header_s {

char magic[8]; //标识sbd的header

unsigned char version; //版本信息

unsigned char slots; //slots的数量

/* Caveat: stored in network byte-order */

uint32_t sector_size; //sector的大小

uint32_t timeout_watchdog; //watchdog等待响应的时间

uint32_t timeout_allocate; //

uint32_t timeout_loop; //循环检测信箱内容的时间

uint32_t timeout_msgwait; //等待信息的时间

};

下面是每个slot的数据结构,只有当前该slot的用户名,和该slot是否被占用的标示.

struct sector_node_s {

/* slots will be created with in_use == 0 */ char in_use; //1标示该slot已经被占用,0表示没有被占用

char name[64]; //占用该slot的主机的networkname和集群id,uname -n一致的。

};

下面是每个邮箱的额数据结构:

struct sector_mbox_s {

signed char cmd; //要响应的操作

char from[64]; //向邮箱发送消息的人。

};

主要接口函数

sector_alloc() 在内存建立一个sector的内存映射,并全部置0

header_get() 获取heaer信息到heaer在内存的映射

header_write() 将heaer在内存中的映射写入到磁盘中

slot_read() 获取slot信息到slot在内存的映射

slot_write() 将slot在内存中的映射写入到磁盘中

mbox_read() 获取mbox信息到mbox在内存的映射

mbox_write() 将mbox在内存中的映射写入到磁盘中

slot_lookup(header,name) 查看name指定的主机是否已经非配了slot,如果非配了返 回分配的slot号,没有分配返回-1.

slot_unused(s_header); 找到没有第一个应用的slot,返回号码

sysrq_trigger(char t) 向/proc/sysrq-trigger写信息

do_reset(void) 调用sysrq_trigger(char t) 向里面写b重启。如果失败的话

sleep双倍喂狗时间。

主代码流程分析

1.程序开始根据命令或exec获取到程序执行的参数并设置响应的全局变量。

2.用uname获取当前主机网络名。同 命令行 uname -n

3.判断程序是否可以执行。有两点 :

1)必须存在命令 create dump allocate list message ping watch

2)必须有-d选项,且指定的sbd物理设备必须存在,且可读写。

4.响应各个命令create dump allocate list message ping watch

5.只要执行出现问题就输出help信息

create

调用init_device执行create操作

sector_alloc()函数为 header(sector_header_s) slot(sector_node_s) 信箱 (sector_mbox_s)

映射内存,并全部置0.

将命令行的响应参数赋值给heaer在内存中的映射。

header_write() 把header在内存写入到磁盘中

用slot_write()和 mbox_write()分别写入255个信息,都为0. dump

header_get()读取header信息后打印

allocate

slot_lookup(s_header, name)查看指定的name是否已经分配slot

slot_unused(s_header) 找到没有第一个应用的slot,返回号码

给slot的内存映射写入信息

用 slot_write()将信息写入磁盘

等待 timeout_allocate 秒,确保信息完成。

message

header_get();读取header信息。(然后匹配LOCAL字符和当前主机名)

slot_lookup(header,name) 找到指定的主机名并返回slot号。

建立新型mbox在内存中的映射,struct sector_mbox_s 中forom填为当前主机,cmds写入要执行的操作。

可以发送的操作包括

test|reset|off|clear|exit(message并不关心对方是否watch,只要分配了slot就可以了)

mbox_write()将内存映射写到对应slot的mbox中去。

只要发的不是exit,无论对方是否响应,会等待timeout_msgwait时间,这段时间不能操作。

list

通过s_node->in_use找到应用中的slot

mbox_read () slot_read()读取信息

打印出slot和mbox信息

ping

slot_lookup(s_header, name) 找到对应的name的slot号

mbox_write()写入test操作

没秒查看对方mbox中的test操作是否被清除。直到看到被清除或尝试timeout_msgwait次,发现依然没有被清除。

ps:ping命令在命令行也可以用,ping之后没有输出则表示通,输出help则表示不通。

watch

slot_allocate()和allocate一样,为watch的主机自动分配slot

mbox_write()命令将当前的的slot的mbox置空

如果参数里设置了-D的话讲该程序设置成守护进程

判断是否有-W参数,有的话开启看门狗,默认/dev/watchdog可以由-w指定看门狗。

然后进入一个死循环,死循环用于不停查看当前主机slot对应的mbox中的信息,并给予响应。

(循环红色字体) t0 = time(NULL); 获取系统时间

sleep(timeout_loop) 每次循环监视 间隔的时间

mbox_read() 读取当前slot的mbox。如果无法读取,那么

s_mbox->cmd 获取mbox中的信息。

switch case语句对不同的cmd给予响应

test操作: mbox_write()将mbox清空(用于响应ping,对方通过读取信

箱为空,当前主机可以被ping)

reset操作:调用reboot()函数sysrq_trigger()向/proc/sysrq-trigger写‘b’

实现重启。如果操作失败,等待两倍喂狗时间,用watchdog重启

off操作:sysrq_trigger()向/proc/sysrq-trigger写‘c’实现重启。如果操作失

败,会等待两倍喂狗时间,用watchdog重启。

exit操作:关闭watchdog,退出循环。

watchdog_tickle() 喂狗

t1 = time(NULL); 再次获取系统时间

latency = t1 - t0计算本次循环所花费时间

如果timeout_watchdog_warn不为0,且话费时间超过timeout_watchdog_warn的话,系统将给与警告,距离喂狗时间太接近,可能某些情况造成喂狗失败。

设置分析

时间的设置

-1 Set watchdog timeout to N seconds (optional) (create only)

-2 Set slot allocation timeout to N seconds (optional) (create only)

-3 Set daemon loop timeout to N seconds (optional) (create only)

-4 Set msgwait timeout to N seconds (optional) (create only)

-5 Warn if loop latency exceeds threshold (optional) (watch only)

(default is 3, set to 0 to disable)

-1 timeout_watchdog 默认5 设置的是看门狗需要喂狗的间隔时间,超过时间主机重

新启动

-2 timeout_allocate 默认2 设置:当用allocate和在watch为主机分配时,默认等

待的时间,以保证其他操作之前,该操作完成。

-3 timeout_loop 默认1 设置:watch过程中,每次检查本机mbox并相应后 休 息的时间,无限循环中。

-4 timeout_msgwait 默认10 调用地方有两个:

1)message发送的消息只要不是exit,无论对方是 否响应,会等待timeout_msgwait时间,这段时 间不能操作。

2) ping的时候等待timeout_msgwait秒,这段

时间内有响应,就算能ping通。 是设置等待消息的时间,在这段时间内确保对方能够

收到消息。发送消息期间。

-5 timeout_watchdog_warn 默认3 设置成0,关闭此功能。用警告操作时间过长,可能 造成喂狗时间不够的情况。系统在监视自己slot对应

的mbox信息,首先每次先sleep一段时间,该时间为 timeout_loop,然后在进行获取mbox信息,处理

mbox信息,如果处理的信息不是重启或关机。那

么就会喂狗。然后再获取一次系统时间。计算两次

设置限制:

timeout_watchdog > timeout_watchdog_warn(非0) > timeout_loop

timeout_loop 决定系统watch自己信箱并相应的间隔时间,降低这个值会让响应更

加迅速。但设置过低会执行过频繁i/o操作,加重系统负担。

timeout_watchdog 决定喂狗间隔时间。

系统每隔一段时间会查看自己信箱、处理响应(主要针对test),并

喂狗。如果设置过低timeout_loop必须设置的更低。

建议 timeout_loop-timeout_loop >=2 过于接近可能在处理繁忙时 处理test的i/0操作时不能及时喂狗。

timeout_watchdog_warn 警告每次检测时间距离watchdog过于接近,会在日志写入警告信 息。

timeout_msgwait 每次都需要等待n秒钟,保证对方收到消息前当前主机不执行其他操 作。可以适当降低。

其他参数分析

Syntax:

sbd

Options:

-d Block device to use (mandatory)

-h Display this help.

-n Set local node name; defaults to uname -n (optional)

-W Use watchdog (recommended) (watch only)

-w Specify watchdog device (optional) (watch only)

-D Run as background daemon (optional) (watch only)

-v Enable some verbose debug logging (optional)

-d是必选项。以保证程序正确执行。

-W是必选项。集群所有fence都依赖于watchdog

-D是必选项。让主机的watch成为一个守护进程

-w最好还是有硬件watchdog。在这里设置。

时间只差。如果超过timeout_watchdog_warn,就会在

日志中输出警告。

发布者:admin,转转请注明出处:http://www.yc00.com/news/1690377551a340413.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信