Android2.2 vold analysis-2---20110105
Analysis of Netlink event communication mechanism in vold
The netlinkhandler member function start () calls socketlistener: startlisten ()
Calling NL-> Start () in the system/vold/Main. cpp main () function is to call the int netlinkmanager: Start () function. The main functions of this function are as follows:
(1). Create netlink socket
(2) construct the netlinkhandler object and call socketlistener: startlisten () through its member function start ();
The analysis is as follows:
Int netlinkmanager: Start (){
Struct sockaddr_nl nladdr;
Int SZ = 64*1024;
Memset (& nladdr, 0, sizeof (nladdr ));
Nladdr. nl_family = af_netlink;
Nladdr. nl_pid = getpid ();
Nladdr. nl_groups = 0 xffffffff;
If (msock = socket (pf_netlink, sock_dgram, netlink_kobject_uevent) <0 ){}
If (setsockopt (msock, sol_socket, so_rcvbufforce, & SZ, sizeof (sz) <0 ){}
If (BIND (msock, (struct sockaddr *) & nladdr, sizeof (nladdr) <0 ){}
Mhandler = new netlinkhandler (msock );
If (mhandler-> Start ()){}
Return 0;
}
Call startlisten, created before msock,
Int socketlistener: startlistener (){
If (! Msocketname & msock =-1 ){}
Else if (msocketname ){
If (msock = android_get_control_socket (msocketname) <0 ){}
}
If (mlisten & listen (msock, 4) <0) {}// listen to the socket to execute this part
Else if (! Mlisten) // if a non-listening socket (TCP has a listening socket and a data exchange socket, UDP only has a data exchange socket), Netlink is UDP, So execute this Part;
Mclients-> push_back (New socketclient (msock); // directly execute this line and add the Netlink socket to the mclient container;
If (pipe (mctrlpipe )){}
If (pthread_create (& mthread, null, socketlistener: threadstart, this) {}// start a new thread. Here This refers to the object of netlinkhandler as follows:
Return 0;
}
Thread functions:
Void * socketlistener: threadstart (void * OBJ ){
Socketlistener * Me = reinterpret_cast <socketlistener *> (OBJ); // forcibly converts a netlinkhandler object to a socketlistener object and calls its runlistener Function
Me-> runlistener ();
}
Function actually executed by the thread: The mlisten member is used to determine whether to listen to sockets.
Netlink socket is a UDP socket. It is a non-listening socket. The main function of this function is reflected in. If the socket has data, it will call the relevant function to read data.
Void socketlistener: runlistener (){
While (1) {// wireless loop, always listen
Socketclientcollection: iterator it;
Fd_set read_fds;
Int rc = 0;
Int max = 0;
Fd_zero (& read_fds); // clear the file descriptor set read_fds
If (mlisten ){
Max = msock;
Fd_set (msock, & read_fds); // Add the file descriptor to the file descriptor set read_fds
}
Fd_set (mctrlpipe [0], & read_fds );
If (mctrlpipe [0]> MAX)
Max = mctrlpipe [0];
Pthread_mutex_lock (& mclientslock );
For (IT = mclients-> begin (); it! = Mclients-> end (); ++ it) {// Add sockets in the nclient of the container to the file descriptor set read_fds
Fd_set (* It)-> getsocket (), & read_fds );
If (* It)-> getsocket ()> MAX)
Max = (* It)-> getsocket ();
}
Pthread_mutex_unlock (& mclientslock );
If (rc = select (MAX + 1, & read_fds, null) <0) {// wait for the arrival of data in a file descriptor or socket
Continue;
} Else if (! RC)
Continue;
If (fd_isset (mctrlpipe [0], & read_fds) // MPs queue
Break;
If (mlisten & fd_isset (msock, & read_fds) {// listener socket
Struct sockaddr ADDR;
Socklen_t Alen = sizeof (ADDR );
Int C;
If (C = accept (msock, & ADDR, & Alen) <0) {// receives a connection request and establishes a connection, if C is successful, it is the data exchange socket after the link is established, add it to the mclient;
Continue;
}
Pthread_mutex_lock (& mclientslock );
Mclients-> push_back (New socketclient (c ));
Pthread_mutex_unlock (& mclientslock );
}
Do {// non-listening socket Processing
Pthread_mutex_lock (& mclientslock );
For (IT = mclients-> begin (); it! = Mclients-> end (); ++ it ){
Int FD = (* It)-> getsocket ();
If (fd_isset (FD, & read_fds )){
Pthread_mutex_unlock (& mclientslock );
If (! Ondataavailable (* It) {// call the corresponding data reading function to read data
Close (FD );
Pthread_mutex_lock (& mclientslock );
Delete * it;
It = mclients-> erase (it );
Pthread_mutex_unlock (& mclientslock );
}
Fd_clr (FD, & read_fds );
Continue;
}
}
Pthread_mutex_unlock (& mclientslock );
} While (0 );
}
}
Analysis Function: ondataavailable (* It)
Ondataavailable is a pure virtual function defined in the socketlistener class. In android2.2, there are five classes that inherit the class and implement the ondataavailable function:
Dhcplistener (System/CORE/nexus ),
Frameworklistener (System/CORE/libsysutils/src ),
Netlinklistener (System/CORE/libsysutils/src ),
Supplicantlistener (System/CORE/nexus ),
Tiwlaneventlistener (System/CORE/nexus );
The socket created for Netlink is the startlisten function called by the netlinkhandler object and starts related threads. netlinkhandler inherits netlinklistener,
Therefore, ondataavailable is a member function of the netlinklistener class;
System/CORE/libsysutils/src/netlinklistener. cpp
Bool netlinklistener: ondataavailable (socketclient * cli)
{
Int socket = cli-> getsocket ();
Int count;
If (COUNT = Recv (socket, mbuffer, sizeof (mbuffer), 0) <0) {}// read data
Netlinkevent * EVT = new netlinkevent ();
If (! EVT-> decode (mbuffer, count )){}
Onevent (EVT); // The netlinklistener class defines the pure virtual function, and its subclass netlinkhandler implements it. Therefore, the onevent function of the subclass netlinkhandler is called here;
Out:
Delete EVT;
Return true;
}
Onevent function analysis:
System/vold/netlinkhandler. cpp
Void netlinkhandler: onevent (netlinkevent * EVT ){
Volumemanager * Vm = volumemanager: instance ();
Const char * subsys = EVT-> getsubsystem ();
If (! Subsys ){
Slogw ("No subsystem found in Netlink event ");
Return;
}
If (! Strcmp (subsys, "Block ")){
VM-> handleblockevent (EVT );
} Else if (! Strcmp (subsys, "Switch ")){
VM-> handleswitchevent (EVT );
} Else if (! Strcmp (subsys, "battery ")){
} Else if (! Strcmp (subsys, "Power_Supply ")){
}
}
Now I have returned to the vold process, and now the Netlink event transfer mechanism of vold-related parts in Android has been analyzed. The next step is to analyze the real vold management part.