本文转载自;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. ...

dhcpcd守护进程分析【转】的更多相关文章

  1. 1.2 Linux中的进程 --- fork、vfork、exec函数族、进程退出方式、守护进程等分析

    fork和vfork分析: 在fork还没有实现copy on write之前,Unix设计者很关心fork之后立即执行exec所造成的地址空间浪费,也就是拷贝进程地址空间时的效率问题,所以引入vfo ...

  2. twemproxy源码分析2——守护进程的创建

    twemproxy源码中关于守护进程的创建实现得比较标准,先贴出代码来,然后结合一些资料来分析和列举一些实现守护进程的常用方法,不过不得不说twemproxy的实现确实是不错的,注释都写在了代码中,直 ...

  3. php守护进程创建和简要分析

    守护进程可 由系统启动脚本 /etc/rc.local crontab任务, 用户shell 方式运行 具体概念可参考c的 进程守护化基本步骤 1.创建子进程,终止父进程 (pcntl_fork,ex ...

  4. secureCRT 中各种传输协议分析 启动daemon运行守护进程(转)

    转载链接:http://blog.sina.com.cn/s/blog_61798d5d01018yk4.html [Telnet]著名的终端访问协议,传统的网络服务程序,如FTP.POP和Telne ...

  5. exec函数族,守护进程,线程同步和互斥

    2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...

  6. Linux中的两种守护进程stand alone和xinetd

    Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...

  7. linux第1天 fork exec 守护进程

    概念方面 文件是对I/O设备的抽象表示.虚拟存储器是对主存和磁盘I/O设备的抽象表示.进程则是对处理器.主存和I/O设备的抽象表示 中断 早期是没有进程这个概念,当出现中断技术以后才出现进程这个概念 ...

  8. windows下捕获dump之守护进程

    一两个月前为产品写了一个独立的exe,由于产品使用的捕获dump是一个现成的进程外exe,如果以资源的方式集成它容易出现安全警告,由于时间关系没有寻求新的解决方法,还是遵循旧方案,不捕获dump. 最 ...

  9. supervisor运行golang守护进程

    最近在鼓捣golang守护进程的实现,无意发现了supervisor这个有意思的东西.supervisor是一个unix的系统进程管理软件,可以用它来管理apache.nginx等服务,若服务挂了可以 ...

随机推荐

  1. 遇到的cannot find module 'xxx' 问题

    昨天配置新项目的环境,明明都npm inatsll都安装了,再次运行的时候一直报错,缺少模块.我以为就一个没安装上,就手动npm install -g 'xxx' :结果一个装好了,又继续蹦出cann ...

  2. C++: 多态 虚函数

    一.多态: 1.多态是什么:具有不同功能的函数可以用同一个函数名 2.静态多态:程序编译时决定,通过函数重载实现. 3.动态多态:程序运行时决定,通过虚函数实现. 二.虚函数: 1.引入目的:可以通过 ...

  3. DozerBeanMapper + 对象转Map方法

    1.简介     dozer是一种JavaBean的映射工具,类似于apache的BeanUtils.但是dozer更强大,它可以灵活的处理复杂类型之间的映射.不但可以进行简单的属性映射.复杂的类型映 ...

  4. 【GitHub】给GitHub上的ReadMe.md文件中添加图片怎么做 、 gitHub创建文件夹

    1.首先在github上的仓库上,创建一个空的文件夹,用于上传图片 上图看 要点击的按钮是创建新的文件,并不是创建新的文件夹,具体怎么?往下看 这个时候,下面的提交按钮才能提交 2.进入新创建的文件夹 ...

  5. CSS 发明者 Håkon Wium Lie 访谈--csdn zhangxin09

    原文地址:https://dev.opera.com/articles/css-twenty-years-hakon/ ---------------------------------------- ...

  6. Android 你应该注意的开发规范

    本文由Blankj投稿. Blankjd的博客地址: http://www.jianshu.com/u/46702d5c6978 为了利于项目维护以及规范开发,促进成员之间Code Review的效率 ...

  7. 偏执的iOS逆向研究员:收集全版本的macOS iOS+越狱+内核调试

    Intro 虽然“只有偏执狂才能够生存”这句话已经被假药停给毁了,但是作为一只有逼格的高大上的iOS逆向分析研究员,难道如果有现成的macOS/iOS全版本镜像可以下载并且无限“漫游”,难道你就不想来 ...

  8. Android GC 原理探究

    导语 想写一篇关于 android GC 的想法来源于追查一个魅族手机图片滑动卡顿问题,由于不断的 GC 导致的丢帧卡顿的问题让我们想了很多方案去解决,所以就打算详细的看看内存分配和 GC 的原理,为 ...

  9. c# Dictionary拓展2个key得到1个value

    using System.Collections.Generic; using System.Collections; Dictionary<Tuple<int, int>, int ...

  10. Kick the ball!(dfs)湖南省赛第十届

    Problem K: Kick the ball! Time Limit: 1 Sec  Memory Limit: 128 MB  Special Judge Submit: 109  Solved ...