zoukankan      html  css  js  c++  java
  • 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看到能调到

    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.     ...
  • 相关阅读:
    JDK1.5新特性
    mysql的基本使用
    IO简单示例
    序列化
    策略模式
    div+css布局之流体浮动布局
    xp优化
    Junit所使用的设计模式
    SSH使用总结(annotation配置方式)
    hibernate3.6.0使用总结
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/8243982.html
Copyright © 2011-2022 走看看