目录表
Hotplug原理
Hotplug即热插拔,在新版本OpenWRT上,hotplug,coldplug与watchdog等被集成到全新的Procd系统中。
Procd是OpenWRT下新的预初始化,初始化,热插拔和事件系统。在openwrt 中, procd 作为 init 进程会处理许多事情, 其中就包括 hotplug。procd本身并不知道如何处理hotplug事件,也没有必要知道,因为它只实现机制,而不实现策略。事件的处理是由配置文件决定的,这些配置文件即所谓的rules.。老版本下独立的hotplug2在r36987被移除了。所以下面我们要介绍的就是新版本下Hotplug的机制。
要了解Hotplug运行的整个过程,首先得了解procd系统的工作流程。才能从全局了解hotplug是如何工作的。在这里我们重点介绍与hotplug相关的procd启动过程。
Procd启动过程分析
preinit()函数
void
preinit(void)
{
char *init[] = { "/bin/sh", "/etc/preinit", NULL };
char *plug[] = { "/sbin/procd", "-h", "/etc/hotplug-preinit.json", NULL };
LOG("- preinit -\n");
plugd_proc.cb = plugd_proc_cb;
plugd_proc.pid = fork();
if (!plugd_proc.pid) {
execvp(plug[0], plug);
ERROR("Failed to start plugd\n");
exit(-1);
}
if (plugd_proc.pid <= 0) {
ERROR("Failed to start new plugd instance\n");
return;
}
uloop_process_add(&plugd_proc);
setenv("PREINIT", "1", 1);
preinit_proc.cb = spawn_procd;
preinit_proc.pid = fork();
if (!preinit_proc.pid) {
execvp(init[0], init);
ERROR("Failed to start preinit\n");
exit(-1);
}
if (preinit_proc.pid <= 0) {
ERROR("Failed to start new preinit instance\n");
return;
}
uloop_process_add(&preinit_proc);
DEBUG(4, "Launched preinit instance, pid=%d\n", (int) preinit_proc.pid);
}
-
创建子进程执行
/etc/preinit脚本,此时PREINIT环境变量被设置为1,主进程同时使用uloop_process_add()把/etc/preinit子进程加入uloop进行监控,当/etc/preinit执行结束时回调plugd_proc_cb()函数把监控/etc/preinit进程对应对象中pid属性设置为0,表示/etc/preinit已执行完成。 -
创建子进程执行
/sbin/procd -h /etc/hotplug-preinit.json,主进程同时使用uloop_process_add()把/sbin/procd子进程加入uloop进行监控,当/sbin/procd进程结束时回调spawn_procd()函数。 -
spawn_procd()函数繁衍后继真正使用的/sbin/procd进程,从/tmp/debuglevel读出debug级别并设置到环境变量DBGLVL中,把watchdog fd设置到环境变量WDTFD中,最后调用execvp()繁衍/sbin/procd进程。
procd进程
在这里我们主要分析procd的五个状态,分别为 STATE_EARLY、STATE_INIT、STATE_RUNNING、STATE_SHUTDOWN、STATE_HALT,这5个状态将按顺序变化,当前状态保存在全局变量state中,可通过procd_state_next()函数使用状态发生变化。
static void state_enter(void)
{
char ubus_cmd[] = "/sbin/ubusd";
switch (state) {
case STATE_EARLY:
LOG("- early -\n");
watchdog_init(0);
hotplug("/etc/hotplug.json");
procd_coldplug();
break;
case STATE_INIT:
// try to reopen incase the wdt was not available before coldplug
watchdog_init(0);
LOG("- ubus -\n");
procd_connect_ubus();
LOG("- init -\n");
service_init();
service_start_early("ubus", ubus_cmd);
procd_inittab();
procd_inittab_run("respawn");
procd_inittab_run("askconsole");
procd_inittab_run("askfirst");
procd_inittab_run("sysinit");
break;
case STATE_RUNNING:
LOG("- init complete -\n");
break;
case STATE_SHUTDOWN:
LOG("- shutdown -\n");
pro

本文详细介绍了OpenWRT系统中Hotplug的原理,包括Procd的启动过程、Hotplug在内核与用户空间的交互。此外,文章还探讨了如何利用Hotplug实现U盘的自动挂载卸载,以及Button按键检测和接口状态检测的应用。通过Hotplug,OpenWRT可以智能处理外设插入和状态变化,提供更便捷的系统管理。

910

被折叠的 条评论
为什么被折叠?



