- 注册时间
- 2011-10-23
- 最后登录
- 2011-10-31
- 阅读权限
- 70
- 积分
- 1028
- 精华
- 0
- 帖子
- 346
 
升级   1.4%
|
相关的主题文章:
主要的事老是简略的
他也断乎不会指出任何人的任何问题
你才是那特殊的一个
布布要做铁娘子...比外公...妈咪都要强的人....
女人不要认为有些幻想本人一个人就能够实现的
return false;
int len;
bool quote = false;
for (k = 0; k < argc; k++) {
CommandListener *cl;
SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));
} else if (!strcmp(subsys, "power_supply")) {
下面的内容摘自vold(NetlinkManager.cpp)
type label mount_point part sysfs_path sysfs_path
exit(1);
SLOGE("Unable to create VolumeManager");
SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
}
if (*p == '"') {
char *q = tmp;
q = tmp;
argv[argc++] = strdup(tmp);
vm->setBroadcaster((SocketListener *) cl);
};
*q++ = '\\';
if (!quote && *q == ' ') {
return -1;
if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
char state[255];
free(argv[j]);
return;
dev_mount sdcard /data/disk auto /block/sda
这就是监听sysfs的uevent的socket的症结设置,有网络编程背影的人很轻易理解上面这段代码。
return;
在netLinkListener中,VOLD的重点是OnEvent这个虚接口的实现,而CommandSistener中,VOLD处理的重点则是分发VoldCommand类。VoldCommand是由FrameworkCommand派生出的,而VolumeCmd,ShareCmd等子类则是各种操作的封装。
向sysfs目录(或子目录)下面的uevent文件写入”add\n”字符也会触发内核上发这些uevent,相称于从新履行了一次热插拔。
etc/ vold.fstab的配置文件
}
mkdir("/dev/block/vold", 0755);
if (esc) {
vm->handleBlockEvent(evt);
SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno));
PHYSDEVPATH=/class/mmc_host/mmc0/mmc0:1234
if (process_config(vm)) { //解析配置
goto out;
if (nm->start()) {//创建监听sysfs的socket
int k;
linux对热插拔的支撑并不是生来就有的,而是阅历了一个庞杂而有戏剧性的进程,寰球linux喜好者用脚投出了他们保贵的一票,udev终极成为事实上的尺度。
kernel层能检测到有新的装备接入,并能为之加载相应的驱动,但如何告诉用户层呢?这就是sysfs的工作,内核中的sysfs机制请求当有新的驱动加载时给用户层发送相应的event.但这些event只尽告诉的任务,详细怎么处理,这就是vold(或者udev)的事了。
PHYSDEVDRIVER=mmcblk
SLOGE("Unable to bind uevent socket: %s", strerror(errno));
我们进入/sys/block/mmcblk0(也可以是/sys/block下的其它目录),执行:
else
nm->setBroadcaster((SocketListener *) cl);
}
continue;
}
SLOGE("Unable to start VolumeManager (%s)", strerror(errno));
SLOGI("Vold 2.1 (the revenge) firing up");
char tmp[255];
#if 0
*q++ = '\\';
}
if ((mSock = socket(PF_NETLINK,
}
}
}
}
while(*p) {
VolumeManager *vm;
Netlink socket大家应当不会生疏吧,socket这套货色不仅能用于网络间的通讯,也用能用于进程间的通信,像这种内核态与用户沟通的活,天然也少不了它。
* For now we manually bootstrap
NPARTS=1
if (!(nm = NetlinkManager::Instance())) {//实例化
int argc = 0;
FILE *fp;
DEVTYPE=disk
}
}
/*
} else
if (*p == '\\') {
continue;
int j;
else if (*p == '\\')
*q++ = '"';
*/
exit(1);
goto out;
NetlinkManager *nm;
分析vold的源码,要有必定的C++的基本跟设计模式的常识,习惯过程式设计的程序员在读vold时会有很大的艰苦,不外幸好vold代码未几。另外,与vold相干的大批秘密都在libsysutils中,千万不要遗漏这个库。
系统启动时vold错过了的消息可以用这个特征重新触发。
char *argv[FrameworkListener::CMD_ARGS_MAX];
* Switch uevents are broken.
esc = true;
if (buffer == '\0') {
cli->sendMsg(500, "Unclosed quotes error", false);
* the ums switch
MINOR=0
if (vm->start()) {
};
SLOGI("Vold exiting");
for (i = 0; i < len; i++) {
}
{
这一行),vold要对这个多行文档进行解析,而后决议怎么做。vold会把解协出来的消息再通可别一个vold的socket传到其它的进程,同时接收其它进程的反馈。
exit(1);
cli->sendMsg(500, "Command not recognized", false);
MAJOR=179
if (quote)
sysfs传上来的是一个多行的文本(这点要特殊留神,并不仅是add@/block/PHYSDEVDRIVER=mmcblk
quote = false;
先看看对 NetlinkHandler: nEvent的处置
先看看下图SocketListener这套架构,监听sysfs与其它进程的消息,全凭仗这套框架。
else {
PHYSDEVBUS=mmc
MAJOR=179
DEVNAME=mmcblk0
continue;
part指定分区个数,如果是auto则只有一个分区
SLOGE("Unable to set uevent socket options: %s", strerror(errno));
首先,我们要晓得如何吸收来自内核的event.
* Now that we're up, we can respond to commands
}
PHYSDEVDRIVER=mmcblk
cli->sendMsg(500, "Unsupported escape sequence", false);
const char *subsys = evt->getSubsystem();
} else if (esc) {
}
FrameworkCommand *c = *i;
quote = true;
q++;
int i;
} else if (!strcmp(subsys, "battery")) {
}
memset(tmp, 0, sizeof(tmp));
coldboot("/sys/block"); //冷启动,vold错过了一些uevent,重新触发。向sysfs的uevent文件写入”add\n” 字符也可以触发sysfs事件,相称执行了一次热插拔。
// Eventually we'll become the monitoring thread
格式是:
return true;
}
} else if (!strcmp(subsys, "switch")) {
sysfs_path能够有多个,但最后不要有空格,否则会解析过错
SLOGD("arg[%d] = '%s'", k, argv[k]);
DEVNAME=mmcblk0
if (!subsys) {
}
dispatchCommand(c, buffer + offset);
memset(argv, 0, sizeof(argv));
}
cl = new CommandListener(); //创立vold socket,用于向其它过程转发解析的sysfs event,并接受其进程的命令。
Volume定义了各种磁盘的操作,属于工具类。
VolumeManager *vm = VolumeManager::Instance();
void NetlinkHandler: nEvent(NetlinkEvent *evt) {
p++;
bool esc = false;
无论是udev还是vold,都是基于sysfs的,sysfs为内核与用户层的通讯提供了一种全新的方式,并将这种方法加以标准。
exit(1);
out:
SLOGW("No subsystem found in netlink event");
/*
exit(0);
}
if (!strcmp(argv[0], c->getCommand())) {
}
}
return errno;
SLOGE("Unable to create NetlinkManager");
SLOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
FrameworkCommandCollection::iterator i;
return -1;
下面紧接着的问题就是这个socket通路会给我们什么新闻:
char *p = data;
*q = *p++;
sleep(1000);
p++;
例:echo "add" > /sys/block/mmcblk0/uevent
while(1) {
cat *
esc = false;
/* Create our singleton managers */
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
vm->handleSwitchEvent(evt);
p++;
if (cl->startListener()) { //监听上层的反馈
......
SLOGE("read() failed (%s)", strerror(errno));
offset = i + 1;
例:(每一行的停止不能有空格等任何字符,vold对这个处所的处理有bug.)
要将这些类是如何组织在一起的呢,要害是下面两个工厂类。
add@/block/PHYSDEVDRIVER=mmcblk
在android中,代替udev的是vold,我们这里不去过多的探讨为什么android不持续使用udev,但要知道vold的机制和udev是一样的,理解了udev,也就懂得了vold。android一诞生就不尊守传统linux的很多标准,当然也不能指望udev能很好的服务于android。android社区的抉择是别起炉灶,为android定做一套udev,这就是vold了。
MINOR=0
if (*p == '"')
if (!(vm = VolumeManager::Instance())) {//实例化
memset(tmp, 0, sizeof(tmp));
对于用户层而言,我们无需关怀sysfs的细节,只有知道sysfs能向用户层供给什么就行了。
int offset = 0;
我们通过socket从内核处到的envent中所包含的信息也与此类似,是一个包括这些信息的文本,可能是如下格局的
}
PHYSDEVPATH=/class/mmc_host/mmc0/mmc0:1234
} else if (!len)
if (c->runCommand(cli, argc, argv)) {//调用派生类的接口。
goto out;
exit(1);
continue;
char buffer[255];
esc = false;
return -1;
SLOGE("Unable to create uevent socket: %s", strerror(errno));
}
*q = '\0';
if (quote) {
if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
}
当初可能很少有人会用mknod这个命令了,也很少有应用它的机遇,但就在多少年前,这仍是一项linux工程师的必备技巧,在制造文件体系前或加载新的驱动前,我们必需胆大妄为的创建设备节点。
这里重要是通过基类解析的uevent消息分辨调用不同的处理。假如看了上面的图还有人问NetlinkHandler: nEvent是在什么时候调用的,那就要补一下C++了,这不是一两句话能说得明白的。
SLOGE("Unable to start CommandListener (%s)", strerror(errno));
}
VoldCommand主要是实现对runcommand动作的封装,在 FrameworkListener会依据收到的消息取舍相应的派生类。
不须要使用mknod并不是他消散了,而是我们有了更好更智能的方式。
bool Framew |
|