keepalive源码学习

来源:互联网 发布:python 2.7 安装 编辑:程序博客网 时间:2024/06/05 01:17
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,

                              进度:   vrrp_netlink.c   706
                                                          
                                                  
                                        
                                
0 0
原创粉丝点击