Android2.2 vold analysis-(2)-Netlink event communication mechanism analysis in vold

Source: Internet
Author: User

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.