Android 4.1 Netd详细分析(三)代码分析1

来源:互联网 发布:validate.js 示例 编辑:程序博客网 时间:2024/06/05 14:17
       接下来开始从代码分析,按照从下至上的顺序来分析,从native层向framework层过渡,Android的各个层之间严格按照软件工程原理的低耦合要求.
[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <signal.h>  
  4. #include <errno.h>  
  5. #include <string.h>  
  6. #include <sys/stat.h>  
  7. #include <sys/types.h>  
  8. #include <sys/wait.h>  
  9.   
  10. #include <fcntl.h>  
  11. #include <dirent.h>  
  12.   
  13. #define LOG_TAG "Netd"  
  14.   
  15. #include "cutils/log.h"  
  16.   
  17. #include "CommandListener.h"  
  18. #include "NetlinkManager.h"  
  19. #include "DnsProxyListener.h"  
  20. #include "MDnsSdListener.h"  
  21.   
  22. static void coldboot(const char *path);  
  23. static void sigchld_handler(int sig);  
  24. static void blockSigpipe();  
  25.   
  26. int main() {  
  27.   
  28. /******************************************************** 
  29. *以下两个为函数主要使用的类 
  30. *CommandListener :监听 framework 层的命令,并调用本类中注册的处理函数,并将处理结果返回 
  31. *NetLinkManager  :管理 kernel 层相关的 event,将收到收到的信息提交给 framework 层 
  32. ********************************************************/  
  33.   
  34.     CommandListener *cl;  
  35.     NetlinkManager *nm;  
  36.   
  37. /******************************************************** 
  38. * 这两个可以各自理解为单独的工作模块,相对上面的类更加简单。 
  39. * DnsProxyListener :DNS 解析,通过系统库函数 getaddrinfo,并将解析结果反馈给 framework 层 
  40. * MDnsSdListener   :Muliticast-DNS Server Descript 利用局域网其他对象解析 
  41. ********************************************************/  
  42.       
  43.   DnsProxyListener *dpl;  
  44.     MDnsSdListener *mdnsl;  
  45.   
  46.     ALOGI("Netd 1.0 starting");  
  47.   
  48. //  signal(SIGCHLD, sigchld_handler);  
  49.     blockSigpipe();         //禁用Sigpipe  
  50.   
  51.     if (!(nm = NetlinkManager::Instance())) {   //实例化nm  
  52.         ALOGE("Unable to create NetlinkManager");  
  53.         exit(1);  
  54.     };  
  55.   
  56. /******************************************************* 
  57. * nm->setBroadcaster((SocketListener *) cl) 
  58. * setBroadcaster函数将NetlinkManager的成员变量mBroadcaster设置成cl,这两个变量都是 
  59. * ScoketListener的指针类型,命令执行广播函数,就会调用这个SocketListener的指针来调用 
  60. * SocketListener类的广播函数* 因为:继承关系: 
  61. * CommandListener(子类)-->FrameworkListener()-->SocketListener(父类)*******************************************************/  
  62.    
  63.     cl = new CommandListener();         //实例化cl  
  64.     nm->setBroadcaster((SocketListener *) cl);   //关联nm和cl这样nm就可以通过方法  
  65.                         //广播消息来回复给framework  
  66. /************************************************** 
  67. * 使用了 Netlink socket 是用于实现用户进程与内核进程通信的 IPC, 
  68. * 下面的 start()就是开启监听内核的线程。 
  69. *************************************************/  
  70.    
  71.  if (nm->start()) {  
  72.      ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));   
  73.     exit(1); }  
  74.   
  75. /************************************************** 
  76. * 关于DnsProxyListener/MdnsSdListener会在后面单独详细 
  77. * 各自的原理同CommandListener+NetlinkManager两个组成的系统 
  78. **************************************************/  
  79.    
  80. // Set local DNS mode, to prevent bionic from proxying(自动代理)   
  81. // back to this service, recursively.(递归)   
  82. // DnsProxyListener -> FrameworkListrner -> SocketListener  
  83.      
  84.     setenv("ANDROID_DNS_MODE""local", 1);         //设置为本地模式,是一个全局变量      
  85. //DNS  
  86.     dpl = new DnsProxyListener();  
  87.     if (dpl->startListener()) {  
  88.         ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));  
  89.         exit(1);  
  90.     }  
  91.                             //multicast_DNS_server_descript_listener                                        //多播DNS守护进程  
  92.                         //内网没有DNS服务器时,出现此组播  
  93.     mdnsl = new MDnsSdListener();  
  94.     if (mdnsl->startListener()) {  
  95.         ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));  
  96.         exit(1);  
  97.     }  
  98.   
  99. /************************************************ 
  100. * cl 开启线程,监听 framework 层下发的命令,并调用相关函数处理 
  101. *********************************************** */  
  102.   
  103.     if (cl->startListener()) {  
  104.         ALOGE("Unable to start CommandListener (%s)", strerror(errno));  
  105.         exit(1);  
  106.     }  
  107.       
  108. // 成为守护进程  
  109.     while(1) {  
  110.         sleep(1000);  
  111.     }  
  112.   
  113.     ALOGI("Netd exiting");  
  114.     exit(0);  
  115. }  
  116.    
  117. ///*********打杂函数**************//  
  118. // 实际还真没看到打杂的意义/作用是什么……  
  119. static void do_coldboot(DIR *d, int lvl)  
  120. {  
  121.     struct dirent *de;  
  122.     int dfd, fd;  
  123.   
  124.     dfd = dirfd(d);  
  125.   
  126.     fd = openat(dfd, "uevent", O_WRONLY);  
  127.     if(fd >= 0) {  
  128.         write(fd, "add\n", 4);  
  129.         close(fd);  
  130.     }  
  131.   
  132.     while((de = readdir(d))) {  
  133.         DIR *d2;  
  134.   
  135.         if (de->d_name[0] == '.')  
  136.             continue;  
  137.   
  138.         if (de->d_type != DT_DIR && lvl > 0)  
  139.             continue;  
  140.   
  141.         fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);  
  142.         if(fd < 0)  
  143.             continue;  
  144.   
  145.         d2 = fdopendir(fd);  
  146.         if(d2 == 0)  
  147.             close(fd);  
  148.         else {  
  149.             do_coldboot(d2, lvl + 1);  
  150.             closedir(d2);  
  151.         }  
  152.     }  
  153. }  
  154.   
  155. static void coldboot(const char *path)  
  156. {  
  157.     DIR *d = opendir(path);  
  158.     if(d) {  
  159.         do_coldboot(d, 0);  
  160.         closedir(d);  
  161.     }  
  162. }  
  163.   
  164. static void sigchld_handler(int sig) {  
  165.     pid_t pid = wait(NULL);  
  166.     ALOGD("Child process %d exited", pid);  
  167. }  
  168.   
  169. static void blockSigpipe()  
  170. {  
  171.     sigset_t mask;  
  172.   
  173.     sigemptyset(&mask);  
  174.     sigaddset(&mask, SIGPIPE);  
  175.     if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)  
  176.         ALOGW("WARNING: SIGPIPE not blocked\n");  
  177. }  



       至此,按照 main 函数的流程进行分析

       首先如上图,系统的部分主干关系图,系统可以按照功能和相关性分为三大部分,DnsProxyLis-
tener,MDnsSdListener,和 CommandListener + NetlinkManager 三大部分,每个部分都能够利用内
部 socket 和独立线程,接收到 Framework 层的命令,系统调用操作 Kernel 层,并回复 Framework 反
馈,可是说 Netd 充当了 Framework 与 kernel 的桥梁。

0 0