keepalived源码浅析——Global_data全局定义块

本文详细解析了Keepalived的全局配置文件,包括默认值设置、数据结构定义及核心函数实现等内容。介绍了如何通过配置文件指定邮件通知、SMTP服务器等关键参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

全局定义模块作用:设置全局模块数据的默认值 以及申请和释放全局模块数据指针

#全局定义块

global_defs {
   notification_email {  #指定keepalived在发生切换时需要发送email到的对象,一行一个
    sysadmin@fire.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc #指定发件人
   smtp_server localhost #指定smtp服务器地址
   smtp_connect_timeout 30 #指定smtp连接超时时间
   router_id LVS_DEVEL #运行keepalived机器的一个标识
}

 

Global_data.h 源码:

#ifndef _GLOBAL_DATA_H
#define _GLOBAL_DATA_H

/* system includes */
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

/* local includes */
#include "list.h"
#include "timer.h"

/* constants */                         //默认的数据
#define DEFAULT_SMTP_SERVER 0x7f000001                 
#define DEFAULT_SMTP_CONNECTION_TIMEOUT (30 * TIMER_HZ)  // #define TIMER_HZ  1000000
#define DEFAULT_PLUGIN_DIR "/etc/keepalived/plugins"         //组件目录

/* email link list */
typedef struct _email {  //收件人列表
	char *addr;
} email;

/* Configuration data root */
typedef struct _conf_data {
	int linkbeat_use_polling;
	char *router_id;
	char *plugin_dir;
	char *email_from;
	struct sockaddr_storage smtp_server;
	long smtp_connection_to;
	list email;
#ifdef _WITH_SNMP_
	int enable_traps;
#endif
} conf_data_t;

/* Global vars exported */
extern conf_data_t *global_data; /* Global configuration data */

/* Prototypes */
extern void alloc_email(char *);
extern conf_data_t *alloc_global_data(void);
extern void free_global_data(conf_data_t *);
extern void dump_global_data(conf_data_t *);

#endif


 

Global_data.c 源码:

#include <syslog.h>
#include <unistd.h>
#include <pwd.h>
#include <netdb.h>
#include "global_data.h"
#include "memory.h"
#include "list.h"
#include "logger.h"
#include "utils.h"

/* global vars */
conf_data_t *global_data = NULL;

/* Default settings */
static void
set_default_router_id(conf_data_t * data)     // router_id 默认值设置为主机名 
{
	char *new_id = NULL;
	int len = 0;

	new_id = get_local_name();
	if (!new_id || !new_id[0])
		return;

	len = strlen(new_id);
	data->router_id = MALLOC(len + 1);
	if (!data->router_id)
		return;

	memcpy(data->router_id, new_id, len);
}

static void
set_default_email_from(conf_data_t * data)   //默认的发件人 由 用户识别码中的用户名@主机名组成
{
	struct passwd *pwd = NULL;
	char *hostname = NULL;
	int len = 0;

	hostname = get_local_name();
	if (!hostname || !hostname[0])
		return;

	pwd = getpwuid(getuid());
	if (!pwd)
		return;

	len = strlen(hostname) + strlen(pwd->pw_name) + 2;
	data->email_from = MALLOC(len);
	if (!data->email_from)
		return;

	snprintf(data->email_from, len, "%s@%s", pwd->pw_name, hostname);
}

static void
set_default_smtp_connection_timeout(conf_data_t * data)        //设置默认超时时间
{
	data->smtp_connection_to = DEFAULT_SMTP_CONNECTION_TIMEOUT;
}

static void
set_default_values(conf_data_t * data)          //设置默认变量 调用上面三个函数
{
	/* No global data so don't default */
	if (!data)
		return;
	set_default_router_id(data);
	set_default_smtp_connection_timeout(data);
	set_default_email_from(data);
}

/* email facility functions */
static void
free_email(void *data_obj)         //释放收件人信息
{
	FREE(data_obj);
}
static void
dump_email(void *data_obj)         //打印邮件信息
{
	char *addr = data_obj;
	log_message(LOG_INFO, " Email notification = %s", addr);
}

void
alloc_email(char *addr)                //申请收件人邮件信息数据
{
	int size = strlen(addr);
	char *new;

	new = (char *) MALLOC(size + 1);
	memcpy(new, addr, size + 1);

	list_add(global_data->email, new); 
}

/* data facility functions */
conf_data_t *
alloc_global_data(void)                //申请全局数据内存 返回指向全局数据的指针
{
	conf_data_t *new;

	new = (conf_data_t *) MALLOC(sizeof (conf_data_t));
	new->email = alloc_list(free_email, dump_email);            //alloc_list函数传入 free和dump函数 

	set_default_values(new);
	return new;
}

void
free_global_data(conf_data_t * data)    //释放全局数据
{
	free_list(data->email);
	FREE_PTR(data->router_id);
	FREE_PTR(data->plugin_dir);
	FREE_PTR(data->email_from);
	FREE(data);
}

void
dump_global_data(conf_data_t * data)  //打印全局数据信息
{
	if (!data)
		return;

	if (data->router_id ||
	    data->smtp_server.ss_family || data->smtp_connection_to || data->email_from) {
		log_message(LOG_INFO, "------< Global definitions >------");
	}
	if (data->router_id)
		log_message(LOG_INFO, " Router ID = %s", data->router_id);
	if (data->plugin_dir)
		log_message(LOG_INFO, " Plugin dir = %s", data->plugin_dir);
	if (data->smtp_server.ss_family)
		log_message(LOG_INFO, " Smtp server = %s", inet_sockaddrtos(&data->smtp_server)); //转换
	if (data->smtp_connection_to)
		log_message(LOG_INFO, " Smtp server connection timeout = %lu",
		       data->smtp_connection_to / TIMER_HZ);
	if (data->email_from) {
		log_message(LOG_INFO, " Email notification from = %s",
		       data->email_from);
		dump_list(data->email);
	}
#ifdef _WITH_SNMP_
	if (data->enable_traps)
		log_message(LOG_INFO, " SNMP Trap enabled"); // SNMP trap(SNMP 陷阱):某种入口,到达该入口会使SNMP被管设备主动通知                                                                        //SNMP管理器,而不是等待SNMP管理器的再次轮询。
	else
		log_message(LOG_INFO, " SNMP Trap disabled");
#endif
}


 

其中 alloc_global_data函数调用的位置:

Vrrp_daemon.c 中的start_vrrp函数 和 Check_daemon.c中的start_check函数

global_data = alloc_global_data();



 


 

##################################################################################################################################

相关函数解释:

定义函数: struct passwd * getpwuid(uid_t uid);
函数说明: getpwuid()用来逐一搜索参数uid 指定的用户识别码,找到时便将该用户的数  据以结构返回,结构请参考将该用户的数据以passwd 结构
返回。passwd 结构请参考getpwent()。
返回值 返回passwd 结构数据,如果返回NULL 则表示已无数据,或者有错
误发生。

 

系统数据相关的结构passwd定义如下

struct passwd

{

      char *pw_name;       /* 用户名*/

      char *pw_passwd;     /* 密码.*/

      __uid_t pw_uid;      /* 用户ID.*/

      __gid_t pw_gid;      /*组ID.*/

      char *pw_gecos;      /*真实名*/

      char *pw_dir;        /* 主目录.*/

      char *pw_shell;      /*使用的shell*/

};


 

实例:

#include<pwd.h>
#include<sys/types.h>
main()
{
struct passwd *user;
user= getpwuid(6);
printf(“name:%s\n”,user->pw_name);
printf(“uid:%d\n”,user->pw_uid);
printf(“home:%s\n”,user->pw_dir);
}







 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值