corosync 源代码分析1

分析一  corosync服务的load

1 什么是corosync服务

corosync只是一个高可用的网络通讯的框架,所以的功能均是以服务的方式存在于框架之中。

为了可以实现服务的动态装入和可裁剪的架构灵活性,corosync把自身的网络通讯功能部分也做成了服务。

 

2 corosync服务load的层次

corosync的架构:

 1 +----------------------------------------+
2 | IPC Manager |
3 +----------------------------------------+
4 | Service Manager |
5 +----------------------------------------+
6 | Synchronization Engine |
7 +----------------------------------------+
8 | The Totem Stack |
9 +----------------------------------------+
10 | Timers |
11 +----------------------------------------+
12 | Logging System |
13 +----------------------------------------+
14 | Object Database |
15 +----------------------------------------+
16 | Live Component Replacement |
17 +----------------------------------------+
18 | Handle Database Manager |
19 +----------------------------------------+

上面是corosync引擎内部的层次框架,从Object Database开始向上的所有层都被corosync以服务的形式实现。

只有Handle Database Manager 和 Live Component Replacement这两层的代码是以直接调用的方式实现的。

Handle Database Manager只是corosync用来保存服务句柄的一个Map

真正的实现服务的装载的就是Live Component Replacement层


3 corosync服务的装载

如果服务是从Object Database开始,那么最先装载的肯定就是Objdb服务了。从corosync的main代码中可以找到:

 1     /*
2 * Load the object database interface
3 */
4 res = lcr_ifact_reference (
5 &objdb_handle,
6 "objdb",
7 0,
8 &objdb_p,
9 0);
10 if (res == -1) {
11 log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't open configuration object database component.\n");
12 corosync_exit_error (AIS_DONE_OBJDB);
13 }

从上面的代码中可以看出 lcr_ifact_reference 就是装入函数。下面看这个函数

 1 int lcr_ifact_reference (
2 hdb_handle_t *iface_handle,
3 const char *iface_name,
4 int version,
5 void **iface,
6 void *context)
7 {
8
9 /*
10 * Determine if the component is already loaded
11 */
12 instance = lcr_comp_find (iface_name, version, &iface_number);
13 if (instance) {
14 goto found;
15 }
16
17 if (lcr_initialized == 0) {
18 lcr_initialized = 1;
19 defaults_path_build ();
20 ld_library_path_build ();
21 ldso_path_build ("/etc", "ld.so.conf");
22 }
23
24 // TODO error checking in this code is weak
25 /*
26 * Search through all lcrso files for desired interface
27 */
28 for (i = 0; i < path_list_entries; i++) {
29 res = interface_find_and_load (
30 path_list[i],
31 iface_name,
32 version,
33 &instance,
34 &iface_number);
35
36 if (res == 0) {
37 goto found;
38 }
39 }

从上面的代码看,lcr_comp_find将通过iface_name去装入objdb服务。

但是由于corosync刚启动还没有任何服务,所以第12行将找不到任务服务而不能执行goto found,只能继续执行。

第一次调用lcr_ifact_reference,第17行lcr_initialized这个参数将为0,进入这个分支 lcr_initialized变量被置为1,并执行defaults_path_build,ld_library_path_build,ldso_path_build这个三个函数找到服务.so文件的正确位置。

第一个default_path_build中的LCRSODIR宏告诉我们,所有服务的.so文件将在"/usr/libexec/lcrso"这个路径被加载,而这个函数也只是把.so文件的路径放到path_list的数组中。

真正的服务的装载工作是由第29行的interface_find_and_load函数去负责,这个函数将会把每个服务的.so的文件装入其中。 跟进这个函数,我们将看到下面的代码

 1 for (libs_to_scan = 0; libs_to_scan < scandir_entries; libs_to_scan++) {
2 /*
3 * Load objects, scan them, unload them if they are not a match
4 */
5 snprintf (dl_name, sizeof(dl_name), "%s/%s",
6 path, scandir_list[libs_to_scan]->d_name);
7 /*
8 * Don't reload already loaded libraries
9 */
10 if (lcr_lib_loaded (dl_name)) {
11 continue;
12 }
13 dl_handle = dlopen (dl_name, RTLD_NOW);
14 if (dl_handle == NULL) {
15 fprintf(stderr, "%s: open failed: %s\n",
16 dl_name, dlerror());
17 continue;
18 }
19 instance = lcr_comp_find (iface_name, version, iface_number);
20 if (instance) {
21 instance->dl_handle = dl_handle;
22 strcpy (instance->library_name, dl_name);
23 goto found;
24 }

上面的代码的第13行,将会通过dlopen打开服务的.so文件。

注意在第21行的时候,服务组件的实例将会和服务的.so建立联系。

然后我们就可以通过服务组件的实例去使用服务的功能了。

4. 最后总结

我对corosync架构的理解:如果把服务都减去的话,corosync的架构就是一个对象实例管理器,一个大map。

 

 

 



转载于:https://www.cnblogs.com/forfanfan/archive/2012/02/04/2338119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值