全部博文(51)
分类: C/C++
2016-08-22 11:15:49
1. ulog_open调整日志级别;
2. getopt,参数解析, “h”对应的函数已经在init中执行过;
3. uloop_init
4. procd_signal信号处理函数;
5. trigger_init()???
6. procd_state_next
该函数procd状态转到下一阶段;进程初始状态为STATE_NONE;
a) state_enter
i. STATE_EARLY
-->设置watchdog,超时时间为30s
--> hotplug("/etc/hotplug.json");???
--> procd_coldplug
for进程执行udevtrigger,该进程执行完毕后,其回调函数会将procd状态修改为STATE_UBUS;
ii. STATE_UBUS
--> watchdog_init(0);再次对watchdog初始化,避免coldplug之前不生效的情况;
--> set_stdio(“console”)
--> procd_connect_ubus(void) 启动定时器,1s后与ubus server建立连接;其回调函数为ubus_connect_cb;
-->ubus_connect_cb使用/var/run/ubus.sock(UBUS_UNIX_SOCKET)与ubus通信;连接成功后状态切换为STATE_INIT;
--> service_init 初始化services、validators相关的avl树;
--> service_start_early("ubus", ubus_cmd); 启动/sbin/ubusd服务;
iii. STATE_INIT
-->procd_inittab
读取/etc/inittab文件内容
root@OpenWrt:/# cat /etc/inittab # Copyright (c) 2013 The Linux Foundation. All rights reserved. ::sysinit:/etc/init.d/rcS S boot ::shutdown:/etc/init.d/rcS K shutdown ttyMSM0::askfirst:/bin/ash --login |
函数调用格式化操作函数对文件进行解析,解析出ACTION部分(sysinit、shutdown、askfirst);通过名称比对,查找到handlers中对应的部分,并加入到actions列表;
static struct init_handler handlers[] = { { .name = "sysinit", .cb = runrc, }, { .name = "shutdown", .cb = runrc, }, { .name = "askfirst", .cb = askfirst, .multi = 1, }, { .name = "askconsole", .cb = askconsole, .multi = 1, }, { .name = "respawn", .cb = rcrespawn, .multi = 1, } }; |
-->procd_inittab_run依次执行respawn、askconsole、askfirst、sysinit部分的回调函数;通过/etc/inittab文件内容,回调函数只会执行sysinit、askfirst;
askfirst:调用askfirst ()函数运行,启动/sbin/askfirst,首先出现“Please press Enter to activate this console”打印, 接着执行/bin/ash –login;
sysinit:调用runrc()处理函数,执行rc.d目录下的脚本,running /etc/rc.d/S* boot;其实现是调用add_initd(),对每一个脚本fork出一个进程;进程处理由struct runqueue结构来完成;
所有脚本执行完毕后,调用rcdone()将状态改变为STATE_RUNNING;
iv. STATE_RUNNING
打印提示“init complete”;
v. STATE_SHUTDOWN
reboot命令会触发procd为转变为该状态;处理流程与sysinit一致,唯一却别是入参为shutdown;处理完/etc/rc.d/S* shutdown 脚本后,状态转变为STATE_HALT;
vi. STATE_HALT
发送SIGTERM /SIGKILL信号到所有进程;vfork出一个进程,执行reboot()函数处理
7. uloop_run
8. uloop_done