博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dhcpcd守护进程分析【转】
阅读量:6955 次
发布时间:2019-06-27

本文共 4586 字,大约阅读时间需要 15 分钟。

本文转载自;

最近在调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看到能调到

  1. E/EthernetStateTracker( 185): DhcpHandler: DHCP request failed: Timed out waiting for dhcpcd to start
  2. D/EthernetStateTracker( 185): DhcpHandler: DHCP request started

说明patch是好的能正常工作,能正常掉用dhcp,只是DHCP运行不成功。
然后我查了 getprop: 显示 init.svc.dhcpcd_eth0 = stop
正常应该是running的,这样DHCP 才能运行成功。
最后调试了两天,才搞明白,原来是 init.rc 中 dhcpcd_eth0 守护进程的问题:
改成:

  1. on property:init.svc.dhcpcd_eth0=stopped
  2.     start dhcpcd_eth0
  3. service dhcpcd_eth0 /system/bin/dhcpcd -ABKL -f /system/etc/dhcpcd/dhcpcd.conf -d eth0
  4.     class main
  5.     disabled
  6.     oneshot

这样就可以了。
这时init.svc.dhcpcd_eth0 就会是 running 了。这时再点击Setting -> ethernet configuration, DHCP就能正常分配IP了。
libnetutils 和dhcpcd 调用过程如下:
1. libnetutils 调用过程:

  1. jni
  2. =>runDhcp
  3. =>android_net_utils_runDhcp
  4. libs/netutils/dhcp_utils.c
  5. =>dhcp_do_request
  6. =>
  7. static const char DAEMON_NAME[] = "dhcpcd";
  8. static const char DAEMON_PROP_NAME[] = "init.svc.dhcpcd";
  9. static const char DHCP_PROP_NAME_PREFIX[] = "dhcp";
  10. const char *ctrl_prop = "ctl.start";
  11. const char *desired_status = "running";
  12. snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
  13. DHCP_PROP_NAME_PREFIX,
  14. interface);
  15. property_set(result_prop_name, "");//设置dhcp.eth0.result="";等到成功完成dhcp之后,
  16. property_set(ctrl_prop, DAEMON_NAME);//向名字为dhcpcd的service,发送"ctrl.start"启动命令字,该service在init.rc中
  17. //init.rc中dhcpcd服务进程命令字
  18. //service dhcpcd /system/bin/dhcpcd eth0
  19. // disabled
  20. // oneshot
  21. wait_for_property(DAEMON_PROP_NAME, desired_status, 10);
  22. //init.c=>init进程
  23. //=>handle_property_set_fd因为是"ctrl.start"命令字,所以调用handle_control_message处理控制信息
  24. //=>handle_control_message
  25. //=>msg_start
  26. //=>
  27. // struct service *svc = service_find_by_name(name);
  28. // service_start(svc);//启动svc,即执行:/system/bin/dhcpcd eth0
  29. //=>service_start
  30. //=>pid = fork();
  31. // if(pid == 0)execve(svc->args[0], (char**) svc->args, (char**) ENV);子进程执行execve运行/system/bin/dhcpcd,参数为eth0
  32. //=>否则父进程,即init进程将
  33. //=>notify_service_state(svc->name, "running");设置该svc的状态prop
  34. // snprintf(pname, sizeof(pname), "init.svc.%s", name);
  35. // property_set(pname, state);//所以这样上面wait_for_property(DAEMON_PROP_NAME, desired_status, 10);也才能够正常pass[luther.gliethttp].
  36. wait_for_property(result_prop_name, NULL, 15);//等待dhcp.eth0.result=非空

2. dhcpcd 调用过程:

    1. system/extra/dhcpcd-4.0.0-beta9/dhcpcd.c
    2. dhcpcd
    3. =>main
    4. # define SYSCONFDIR "/system/etc/dhcpcd"
    5. #define PACKAGE "dhcpcd"
    6. # define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
    7. # define LIBEXECDIR "/system/etc/dhcpcd"
    8. # define SCRIPT LIBEXECDIR "/" PACKAGE "-run-hooks"
    9. =>strlcpy(options->script, SCRIPT, sizeof(options->script));//默认的options->script="/system/etc/dhcpcd /dhcpcd-run-hooks"
    10. =>f = fopen(cf ? cf : CONFIG, "r");//如果没有指定.conf文件,那么使用默认.conf文件
    11. =>parse_config_line//解析"/system/etc/dhcpcd/dhcpcd.conf"默认配置文件
    12. =>parse_option
    13. =>如果在"/system/etc/dhcpcd/dhcpcd.conf"有"script"这个节
    14. =>那么执行strlcpy(options->script, oarg, sizeof(options->script));直接拷贝
    15. /*
    16. {"script", required_argument, NULL, 'c'},
    17. {"option", required_argument, NULL, 'o'},
    18. "/system/etc/dhcpcd/dhcpcd.conf"中的部分内容如下:
    19. ...
    20. option domain_name_servers, domain_name, domain_search, host_name
    21. ...
    22. */
    23. =>dhcp_run
    24. =>handle_dhcp_packet
    25. =>handle_dhcp
    26. =>bind_dhcp
    27.   reason = "TIMEOUT";reason = "BOUND";reason = "REBIND";reason = "RENEW";
    28. system/extra/dhcpcd-4.0.0-beta9/configure.c
    29. => configure(iface, reason, state->new, state->old, &state->lease, options, 1);
    30. //如果dhcp超时或者dhcp成功,都会调用exec_script来执行脚本,
    31. //执行setprop dhcp.${interface}.result "failed"或者
    32. //执行setprop dhcp.${interface}.result "ok"
    33. =>exec_script(options, iface->name, reason, NULL, old);
    34. =>然后configure_env通过环境变量将reason传递到脚本中
    35. int exec_script(const struct options *options, const char *iface, const char *reason,
    36.      const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)
    37. =>pid = fork();
    38. =>if(pid == 0)execve(options->script, argv, env);//子进程执行脚本,默认"/system/etc/dhcpcd/dhcpcd-run-hooks"
    39. //dhcpcd-run-hooks脚本会根据level值,决定是否执行system/etc/dhcpcd/dhcpcd-hook/*目录下的相应文件
    40. //我们的系统在该system/etc/dhcpcd/dhcpcd-hook/*目录下有如下3个文件
    41. //95-configured
    42. //20-dns.conf
    43. //01-test
    44. =>父进程返回while (waitpid(pid, &status, 0) == -1)等待子进程脚本执行完成
    45. system/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/20-dns.conf
    46. system/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/95-configured
    47.     ...
    48.     setprop dhcp.${interface}.ipaddress "${new_ip_address}"
    49.     setprop dhcp.${interface}.result "ok"//设置属性为ok
    50.     setprop dhcp.${interface}.result "failed"
    51.     ...
你可能感兴趣的文章
搭建AngualarJS开发环境
查看>>
我的前端开发准则
查看>>
如何助力企业 APP 在竞争中占据先机?
查看>>
[译]在 React.js 中使用 ES6+
查看>>
协同过滤算法
查看>>
移动端原生JS实现手指跟随的触控滑动
查看>>
js初级应用之svg实现环形进度条
查看>>
ASP.NET CORE下运行CMD命令
查看>>
requests库核心API源码分析
查看>>
C语言程序员不会告诉你的14个工具和插件 | 收藏 ...
查看>>
2019年人工智能硬件与应用大趋势
查看>>
2018 FDA获批医疗器械盘点,政策红利能否继续?
查看>>
Git协同工作流介绍
查看>>
语音识别实时对比(百度收费 VS SpeechTexter免费)
查看>>
2018智能汽车盘点,新旧造车势力的智能化PK
查看>>
阿里云服务器的配置及搭建教程
查看>>
书籍:python游戏编码 Coding Games in Python - 2018
查看>>
Docker镜像细节
查看>>
如何通过脚本实现数据动态更新
查看>>
远禾科技出席阿里ASRC生态大会 并参与安恒西湖论剑
查看>>