dhcpcd守护进程分析【转】
本文转载自;http://blog.csdn.net/lishanmin11/article/details/37930073
最近在调android ethernet功能,android本身不带 ethernet 功能,需要打patch。这个patch可以在setting里出来 ethernet configuration 选项。即添加了用户配置IP的功能。
我打上patch之后,点击选上DHCP功能,结果路由器一直不能自动分配IP。
经检测,命令行里运行 netcfg eth0 up dhcp 时,ethernet能被正常启动,DHCP能分配到IP。
但是Setting里选上时,dhcp却不能正常分配IP。 这很费解,我先后查看了,
/system/core/libnetutils/*
/externel/dhcpcd/*
发现都没什么问题。
在Setting中点击turn on ethernet选项时,从log看到能调到
- E/EthernetStateTracker( 185): DhcpHandler: DHCP request failed: Timed out waiting for dhcpcd to start
- D/EthernetStateTracker( 185): DhcpHandler: DHCP request started
说明patch是好的能正常工作,能正常掉用dhcp,只是DHCP运行不成功。
然后我查了 getprop: 显示 init.svc.dhcpcd_eth0 = stop
正常应该是running的,这样DHCP 才能运行成功。
最后调试了两天,才搞明白,原来是 init.rc 中 dhcpcd_eth0 守护进程的问题:
改成:
- on property:init.svc.dhcpcd_eth0=stopped
- start dhcpcd_eth0
- service dhcpcd_eth0 /system/bin/dhcpcd -ABKL -f /system/etc/dhcpcd/dhcpcd.conf -d eth0
- class main
- disabled
- oneshot
这样就可以了。
这时init.svc.dhcpcd_eth0 就会是 running 了。这时再点击Setting -> ethernet configuration, DHCP就能正常分配IP了。
libnetutils 和dhcpcd 调用过程如下:
1. libnetutils 调用过程:
- jni
- =>runDhcp
- =>android_net_utils_runDhcp
- libs/netutils/dhcp_utils.c
- =>dhcp_do_request
- =>
- static const char DAEMON_NAME[] = "dhcpcd";
- static const char DAEMON_PROP_NAME[] = "init.svc.dhcpcd";
- static const char DHCP_PROP_NAME_PREFIX[] = "dhcp";
- const char *ctrl_prop = "ctl.start";
- const char *desired_status = "running";
- snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
- DHCP_PROP_NAME_PREFIX,
- interface);
- property_set(result_prop_name, "");//设置dhcp.eth0.result="";等到成功完成dhcp之后,
- property_set(ctrl_prop, DAEMON_NAME);//向名字为dhcpcd的service,发送"ctrl.start"启动命令字,该service在init.rc中
- //init.rc中dhcpcd服务进程命令字
- //service dhcpcd /system/bin/dhcpcd eth0
- // disabled
- // oneshot
- wait_for_property(DAEMON_PROP_NAME, desired_status, 10);
- //init.c=>init进程
- //=>handle_property_set_fd因为是"ctrl.start"命令字,所以调用handle_control_message处理控制信息
- //=>handle_control_message
- //=>msg_start
- //=>
- // struct service *svc = service_find_by_name(name);
- // service_start(svc);//启动svc,即执行:/system/bin/dhcpcd eth0
- //=>service_start
- //=>pid = fork();
- // if(pid == 0)execve(svc->args[0], (char**) svc->args, (char**) ENV);子进程执行execve运行/system/bin/dhcpcd,参数为eth0
- //=>否则父进程,即init进程将
- //=>notify_service_state(svc->name, "running");设置该svc的状态prop
- // snprintf(pname, sizeof(pname), "init.svc.%s", name);
- // property_set(pname, state);//所以这样上面wait_for_property(DAEMON_PROP_NAME, desired_status, 10);也才能够正常pass[luther.gliethttp].
- wait_for_property(result_prop_name, NULL, 15);//等待dhcp.eth0.result=非空
2. dhcpcd 调用过程:
- system/extra/dhcpcd-4.0.0-beta9/dhcpcd.c
- dhcpcd
- =>main
- # define SYSCONFDIR "/system/etc/dhcpcd"
- #define PACKAGE "dhcpcd"
- # define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
- # define LIBEXECDIR "/system/etc/dhcpcd"
- # define SCRIPT LIBEXECDIR "/" PACKAGE "-run-hooks"
- =>strlcpy(options->script, SCRIPT, sizeof(options->script));//默认的options->script="/system/etc/dhcpcd /dhcpcd-run-hooks"
- =>f = fopen(cf ? cf : CONFIG, "r");//如果没有指定.conf文件,那么使用默认.conf文件
- =>parse_config_line//解析"/system/etc/dhcpcd/dhcpcd.conf"默认配置文件
- =>parse_option
- =>如果在"/system/etc/dhcpcd/dhcpcd.conf"有"script"这个节
- =>那么执行strlcpy(options->script, oarg, sizeof(options->script));直接拷贝
- /*
- {"script", required_argument, NULL, 'c'},
- {"option", required_argument, NULL, 'o'},
- "/system/etc/dhcpcd/dhcpcd.conf"中的部分内容如下:
- ...
- option domain_name_servers, domain_name, domain_search, host_name
- ...
- */
- =>dhcp_run
- =>handle_dhcp_packet
- =>handle_dhcp
- =>bind_dhcp
- reason = "TIMEOUT";reason = "BOUND";reason = "REBIND";reason = "RENEW";
- system/extra/dhcpcd-4.0.0-beta9/configure.c
- => configure(iface, reason, state->new, state->old, &state->lease, options, 1);
- //如果dhcp超时或者dhcp成功,都会调用exec_script来执行脚本,
- //执行setprop dhcp.${interface}.result "failed"或者
- //执行setprop dhcp.${interface}.result "ok"
- =>exec_script(options, iface->name, reason, NULL, old);
- =>然后configure_env通过环境变量将reason传递到脚本中
- int exec_script(const struct options *options, const char *iface, const char *reason,
- const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)
- =>pid = fork();
- =>if(pid == 0)execve(options->script, argv, env);//子进程执行脚本,默认"/system/etc/dhcpcd/dhcpcd-run-hooks"
- //dhcpcd-run-hooks脚本会根据level值,决定是否执行system/etc/dhcpcd/dhcpcd-hook/*目录下的相应文件
- //我们的系统在该system/etc/dhcpcd/dhcpcd-hook/*目录下有如下3个文件
- //95-configured
- //20-dns.conf
- //01-test
- =>父进程返回while (waitpid(pid, &status, 0) == -1)等待子进程脚本执行完成
- system/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/20-dns.conf
- system/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/95-configured
- ...
- setprop dhcp.${interface}.ipaddress "${new_ip_address}"
- setprop dhcp.${interface}.result "ok"//设置属性为ok
- setprop dhcp.${interface}.result "failed"
- ...
dhcpcd守护进程分析【转】的更多相关文章
- 1.2 Linux中的进程 --- fork、vfork、exec函数族、进程退出方式、守护进程等分析
fork和vfork分析: 在fork还没有实现copy on write之前,Unix设计者很关心fork之后立即执行exec所造成的地址空间浪费,也就是拷贝进程地址空间时的效率问题,所以引入vfo ...
- twemproxy源码分析2——守护进程的创建
twemproxy源码中关于守护进程的创建实现得比较标准,先贴出代码来,然后结合一些资料来分析和列举一些实现守护进程的常用方法,不过不得不说twemproxy的实现确实是不错的,注释都写在了代码中,直 ...
- php守护进程创建和简要分析
守护进程可 由系统启动脚本 /etc/rc.local crontab任务, 用户shell 方式运行 具体概念可参考c的 进程守护化基本步骤 1.创建子进程,终止父进程 (pcntl_fork,ex ...
- secureCRT 中各种传输协议分析 启动daemon运行守护进程(转)
转载链接:http://blog.sina.com.cn/s/blog_61798d5d01018yk4.html [Telnet]著名的终端访问协议,传统的网络服务程序,如FTP.POP和Telne ...
- exec函数族,守护进程,线程同步和互斥
2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...
- Linux中的两种守护进程stand alone和xinetd
Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...
- linux第1天 fork exec 守护进程
概念方面 文件是对I/O设备的抽象表示.虚拟存储器是对主存和磁盘I/O设备的抽象表示.进程则是对处理器.主存和I/O设备的抽象表示 中断 早期是没有进程这个概念,当出现中断技术以后才出现进程这个概念 ...
- windows下捕获dump之守护进程
一两个月前为产品写了一个独立的exe,由于产品使用的捕获dump是一个现成的进程外exe,如果以资源的方式集成它容易出现安全警告,由于时间关系没有寻求新的解决方法,还是遵循旧方案,不捕获dump. 最 ...
- supervisor运行golang守护进程
最近在鼓捣golang守护进程的实现,无意发现了supervisor这个有意思的东西.supervisor是一个unix的系统进程管理软件,可以用它来管理apache.nginx等服务,若服务挂了可以 ...
随机推荐
- python 中各种数据类型的排序问题
list #按照list的第二键值排序 disP2P = [[1,2,3],[2,3,4],[4,5,6]] disP2P = sorted(disP2P,key = lambda x:x[2]) s ...
- Mybatis逆向生成使用扩展类
1.背景介绍 用的mybatis自动生成的插件,然而每次更改数据库的时候重新生成需要替换原有的mapper.xml文件,都要把之前业务相关的sql重新写一遍,感觉十分麻烦,就想着把自动生成的作为一个基 ...
- BZOJ1005明明的烦恼 Prufer + 分解質因數 + 高精度
@[高精度, Prufer, 質因數分解] Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线,可产生多 ...
- SQLServer 跟踪 扩展事件(Extended Events) 专家
http://blog.csdn.net/kk185800961/article/details/49725903
- 调用tensorflow中的concat方法时Expected int32, got list containing Tensors of type '_Message' instead.
grid = tf.concat(0, [x_t_flat, y_t_flat, ones])#报错语句 grid = tf.concat( [x_t_flat, y_t_flat, ones],0) ...
- Hibernate调试——定位查询源头
本文是我在importNew翻译的文章,首发在importNew,这里会定期更新链接. 为什么有时Hibernate会在程序某一部分生成一条指定sql查询?这个问题让人非常难立马理解.当处理不是我们本 ...
- 百科知识 tar文件如何打开
tar 是什么文件格式,是干什么用的,用什么打开 tarball压缩格式,源于Linux的一个指令,Windows上可以用WinRAR打开 Linux的实用程序tar最初是为了制作磁带存档而设计的(把 ...
- php性能监控扩展xhprof
XHProf是facebook开源出来的一个php轻量级的性能分析工具,跟Xdebug类似,但性能开销更低,还可以用在生产环境中,也可以由程序开 关来控制是否进行profile.总体来说是个不错的工具 ...
- select中分割多组option
<optgroup style="color:gray; font-style:normal" label="——雪佛兰(五菱)——"></o ...
- kubernetes容器编排之定义环境变量以及通过downwardapi把pod信息作为环境变量传入容器内
系列目录 在学习docker的时候,大家可能经常看到不少示例在docker run的时候指定环境变量(比如wordpress的docker示例就是通过环境变量传入账户和密码到容器内).这里之所以经常用 ...