start_vrrp_child
1,创建子进程
2,父进程执行 thread_add_child,并推出
2.1 定义新的 thread_t 对象,并进行根据给定参数进行初始化,线程id,处理函数等
vrrp_respawn_thread :
判断如果进程类型为 THREAD_CHILD_TIMEOUT,则再次执行 thread_add_child,并返回
如果不是此种类型,则 start_vrrp_child
2.2 调整时间
2.2 按时间从小到大排序插入队列
3,子进程将pid写入 vrrp_pidfile中
4,清理掉从父进程继承的信号处理,以及thread_master_t,并创建新的master:
master = thread_make_master();
5,改变目录到 "/"
6,umask(0)
7,UNSET_RELOAD
8,vrrp_signal_init():
8.1 signal_handler_init():创建pipe,对signal_SIGHUP_handler,signal_SIGINT_handler,signal_SIGTERM_handler,signal_SIGCHLD_handler进行初始化为NULL
8,2 signal_set(SIGHUP, sighup_vrrp, NULL);
8.2.1 sighup_vrrp:thread_add_event(master, reload_vrrp_thread, NULL, 0); thread_new 一个thread,将其加入到 m->event 队列
8.3 signal_set(SIGINT, sigend_vrrp, NULL); signal_set(SIGTERM, sigend_vrrp, NULL);
thread_add_terminate_event(master);
8.4 signal_ignore(SIGPIPE);
signal_set(signo, NULL, NULL): switch 设置
signal_SIGHUP_handler,signal_SIGHUP_v,signal_SIGINT_handler
,signal_SIGINT_v,signal_SIGTERM_handler,signal_SIGTERM_v,
signal_SIGCHLD_handler,signal_SIGCHLD_v
9,start_vrrp():
9.1 init_interface_queue(netlink库的使用具体待学习)
9.1.1 init_if_queue(): if_queue = alloc_list(free_if, dump_if);
9.1.2 netlink_interface_lookup():
9.1.2.1 声明结构体:struct nl_handle nlh, 调用netlink_set_block
9.1.2.2 netlink_request (具体实现待学习) 构造结构体,调用sendto发请求
9.1.2.2.1 声明 struct sockaddr_nl snl;
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
} req;
分别用于 构造要发送的目的套接字和要发送的内容
9.1.2.3 netlink_parse_info(netlink_if_link_filter, &nlh, NULL);
9.1.2.3.1 声明结构体 struct iovec iov = { buf, sizeof buf }; struct sockaddr_nl snl;
struct msghdr msg={ (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
struct nlmsghdr *h;
循环调用 recvmsg(nl->fd, &msg, 0);
9.1.2.3.1.1 内循环
for (h = (struct nlmsghdr *) buf; NLMSG_OK(h, status);h = NLMSG_NEXT(h, status))
处理数据,并用 netlink_if_link_filter函数去处理收到的数据
遍历过程中用到的宏:NLMSG_OK(h, status),NLMSG_NEXT(h, status),NLMSG_DATA(h)
9.1.2.3.1.2
声明 struct ifinfomsg *ifi; struct rtattr *tb[IFLA_MAX + 1]; interface *ifp;
调用 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 填充 ifi
根据iFi,忽略 lookup 地址,if_get_by_ifname忽略if_queue队列中已经存在的interface
调用 if_add_queue(ifp); 将 ifp 加入到 if_add_queue 中
9.2,kernel_netlink_init()
9.2.1 netlink_address_lookup():
9.2.1.1 声明 struct nl_handle nlh
9.2.1.2 netlink_socket(&nlh, 0):
9.2.1.2.1 nl->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
9.2.1.2.2 nl->snl.nl_family = AF_NETLINK; nl->snl.nl_groups = groups;
9.2.1.2.3 bind(nl->fd, (struct sockaddr *) &nl->snl, sizeof (nl->snl));
9.2.1.2.4 ret = getsockname(nl->fd, (struct sockaddr *) &nl->snl, &addr_len);
9.2.1.2.5 if (nl->snl.nl_family != AF_NETLINK)
9.2.1.2.6 nl->seq = time(NULL);
9.2.1.3 ret = netlink_set_block(&nlh, &flags);
9.2.1.4 if (netlink_request(&nlh, AF_INET, RTM_GETADDR) < 0)
9.2.1.5 status = netlink_parse_info(netlink_if_address_filter, &nlh, NULL);
netlink_if_address_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
9.2.1.5.1 声明 struct ifaddrmsg *ifa; struct rtattr *tb[IFA_MAX + 1]; interface *ifp;
9.2.1.5.2 ifa = NLMSG_DATA(h);
9.2.1.5.3 if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
9.2.1.5.4 if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
9.2.1.5.5 len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifaddrmsg));
9.2.1.5.6 parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
9.2.1.5.6.1 while (RTA_OK(rta, len)) {
if (rta->rta_type <= max)
tb[rta->rta_type] = rta;
rta = RTA_NEXT(rta, len);
}
9.2.1.5.7 ifp = if_get_by_ifindex(ifa->ifa_index);
9.2.1.5.8 addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
9.2.1.5.9 update_checker_activity(ifa->ifa_family, addr,(h->nlmsg_type == RTM_NEWADDR) ? 1 : 0);
9.2.1.5.9.1 遍历 checkers_queue
if (inaddr_equal(family, addr, address) && CHECKER_HA_SUSPEND(checker)) 设置 checker->enabled = enable;
9.2.1.6 if (netlink_request(&nlh, AF_INET6, RTM_GETADDR) < 0)
9.2.1.7 status = netlink_parse_info(netlink_if_address_filter, &nlh, NULL);
9.2.1.8 netlink_close(&nlh);
9.2.2 groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
9.2.3 if (nl_kernel.fd > 0) thread_add_read(master, kernel_netlink, NULL, nl_kernel.fd,NETLINK_TIMER);
9.2.3.1 kernel_netlink(thread_t * thread)
9.2.3.1.1 if (thread->type != THREAD_READ_TIMEOUT) netlink_parse_info(netlink_broadcast_filter, &nl_kernel, NULL);
9.2.3.1.1.1 netlink_broadcast_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
9.2.3.1.1.1.1 switch (h->nlmsg_type) case RTM_NEWLINK: case RTM_DELLINK: return netlink_reflect_filter(snl, h); 实现和netlink_if_address_filter 类似
9.2.3.1.1.1.2 case RTM_NEWADDR: case RTM_DELADDR: return netlink_if_address_filter(snl, h);
9.2.3.1.2 thread_add_read(master, kernel_netlink, NULL, nl_kernel.fd,NETLINK_TIMER);
9.2.3.2 thread_add_read(master, kernel_netlink, NULL, nl_kernel.fd,NETLINK_TIMER);
9.2.4 netlink_socket(&nl_cmd, 0);
9.3,gratuitous_arp_init();
9.3.1 garp_buffer = (char *)MALLOC(sizeof(m_arphdr) + ETHER_HDR_LEN);
9.3.2 garp_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_RARP));
9.4,ndisc_init(); // Neighbour Discovery init/close
9.4.1 ndisc_buffer = (char *) MALLOC(ETHER_HDR_LEN + sizeof(struct ip6hdr) + sizeof(struct ndhdr) + sizeof(struct nd_opt_hdr) + ETH_ALEN);
9.4.2 ndisc_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IPV6));
9.5, if (!reload && snmp) vrrp_snmp_agent_init();
9.5.1 vrrp_snmp_agent_init()
9.5.1.1 snmp_agent_init(vrrp_oid, OID_LENGTH(vrrp_oid), "VRRP", (struct variable *)vrrp_vars, sizeof(struct variable8),sizeof(vrrp_vars)/sizeof(struct variable8));
9.6, ipvs_start(); /* Initialize ipvs related */
9.6.1 if (ipvs_init()) { if (modprobe_ipvs() || ipvs_init())... return IPVS_ERROR; }
9.6.2 urule = (struct ip_vs_rule_user *) MALLOC(sizeof (struct ip_vs_rule_user)); /* Allocate global user rules */
9.6.2.1 static struct ip_vs_rule_user *urule;
9.7, global_data = alloc_global_data();
9.8, vrrp_data = alloc_vrrp_data();
9.9, alloc_vrrp_buffer();
9.10,init_data(conf_file, vrrp_init_keywords);
9.11,if (!vrrp_data) { stop_vrrp(); return; }
9.12,if (reload) { clear_diff_saddresses(); clear_diff_sroutes(); clear_diff_vrrp(); clear_diff_script(); }
9.13,if (!vrrp_complete_init()) { stop_vrrp(); return; }
9.14,netlink_iplist(vrrp_data->static_addresses, IPADDRESS_ADD);
9.14.1 if (netlink_ipaddress(ipaddr, cmd) > 0) ......
9.15,netlink_rtlist_ipv4(vrrp_data->static_routes, IPROUTE_ADD);
9.15.1 if (netlink_route_ipv4(iproute, cmd) > 0)......
9.16,init_interface_linkbeat();
9.16.1 init_if_linkbeat();
9.17,thread_add_event(master, vrrp_dispatcher_init, NULL,VRRP_DISPATCHER);
10,free_vrrp_sockpool(old_vrrp_data);
free_vrrp_sockpool(vrrp_conf_data * data):
10.1 free_list(data->vrrp_socket_pool);
11,free_vrrp_data(old_vrrp_data);
12,