<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                NetlinkManager(以后簡稱NM)主要負責接收并解析來自Kernel的UEvent消息。其核心代碼在start函數中,如下所示。 ** NetlinkManager.cpp::start** ~~~ int NetlinkManager::start() { //創建接收NETLINK_KOBJECT_UEVENT消息的socket,其值保存在mUeventSock中 //其中,NETLINK_FORMAT_ASCII代表UEvent消息的內容為ASCII字符串 mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT, 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII); //創建接收RTMGPR_LINK消息的socket,其值保存在mRouteSock中 //其中,NETLINK_FORMAT_BINARY代表UEvent消息的類型為結構體,故需要進行二進制解析 mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE, RTMGRP_LINK, NetlinkListener::NETLINK_FORMAT_BINARY); //創建接收NETLINK_NFLOG消息的socket,其值保存在mQuotaSock中 mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG, NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY); return 0; } ~~~ NM的start函數主要是向Kernel注冊了三個用于接收UEvent事件的socket,這三個UEvent[1][2]分別對應于: - NETLINK_KOBJECT_UEVENT:代表kobject事件,由于這些事件包含的信息由ASCII字符串表達,故上述代碼中使用了NETLINK_FOMRAT_ASCII。它表示將采用字符串解析的方法去解析接收到的UEvent消息。kobject一般用來通知內核中某個模塊的加載或卸載。對NM來說,其關注的是/sys/class/net下相應模塊的加載或卸載消息。 - NETLINK_ROUTE:代表kernel中routing或link改變時對應的消息。NETLINK_ROUTE包含很多子項,上述代碼中使用了RTMGRP_LINK項。二者結合起來使用,表示NM希望收到網絡鏈路斷開或接通時對應的UEvent消息(筆者在Ubuntu PC機上測試過,當網卡上拔掉或插入網線時,會觸發這些UEvent消息的發送)。由于對應UEvent消息內部封裝了nlmsghdr等相關結構體,故上述代碼使用了NETLINK_FORMAT_BINARY來指示解析UEvent消息時將使用二進制的解析方法。 - NETLINK_NFLOG:和2.3.6節介紹的帶寬控制有關。Netd中的帶寬控制可以設置一個預警值,當網絡數據超過一定字節數就會觸發kernel發送一個警告。該功能屬于iptables的擴展項,但由于iptables的文檔更新速度較慢(這也是很多開源項目的一大弊端),筆者一直未能找到相關的正式說明。值得指出的是,上述代碼中有關NETLINK_NFLOG相關socket的設置并非所有kernel版本都支持。同時,NFLOG_QUOTA_GROUP的值是直接定義在NetlinkManager.cpp中的,而非和其他類似系統定義一樣定義在系統頭文件中。這也表明NFLOG_QUOTA_GROUP的功能比較新。 * * * * * **提示**:讀者可通過在Linux終端中執行man PF_LINK得到有關NETLINK的詳細說明。 * * * * * 上述start函數將調用setupSocket創建用于接收UEvent消息的socket以及一個解析對象NetlinkHandler。setupSocket代碼本身比較簡單,此處就不擬展開分析。 下面來看NM及其家族成員,它們之間的關系如圖2-2所示。 :-: ![](http://img.blog.csdn.net/20140303220754281?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖2-2 NetlinkManager家族成員的類圖 由圖2-2可知: - NetlinkHandler和CommandListener均間接從SocketListener派生。其中,NetlinkHandler收到的socket消息將通過onEvent回調處理。 - 結合前文所述,NetlinkManager分別注冊了三個用于接收UEvent的socket,其對應的NetlinkHandler分別是mUeventHandler、mRouteHandler和mQuotaHandler。 - NetlinkHandler接收到的UEvent消息會轉換成一個NetlinkEvent對象。NetlinkEvent對象封裝了對UEvent消息的解析方法。對于NETLINK_FOMRAT_ASCII類型,其parseAsciiNetlinkMessage函數會被調用,而對于NETLINK_FORMAT_BINARY類型,其parseBinaryNetlinkMessage函數會被調用。 - NM處理流程的輸入為一個解析后的NetlinkEvent對象。NM完成相應工作后,其處理結果將經由mBroadcaster對象傳遞給Framework層的接收者,也就是NetworkManagementService。 - CommandListener從FrameworkListener派生,而FrameworkListener內部有一個mCommands數組,它用來存儲注冊到FrameworkListener中的命令處理對象。 下面來簡單了解下NetlinkHandler的onEvent函數,由于其內部已針對不同屬性的NetlinkEvent進行了分類處理,故瀏覽這段代碼能加深對前文所述不同UEvent消息的作用的理解。 **NetlinkHandler.cpp::onEvent** ~~~ void NetlinkHandler::onEvent(NetlinkEvent *evt) { const char *subsys = evt->getSubsystem(); ...... //處理對應NETLINK_KOBJECT_UEVENT和NETLINK_ROUTE的信息 if (!strcmp(subsys, "net")) { int action = evt->getAction(); const char *iface = evt->findParam("INTERFACE");//查找消息中攜帶的網絡設備名 if (action == evt->NlActionAdd) { notifyInterfaceAdded(iface);//添加NIC(Network Interface Card)的消息 } else if (action == evt->NlActionRemove) { notifyInterfaceRemoved(iface);//NIC被移除的消息 } else if (action == evt->NlActionChange) { evt->dump(); notifyInterfaceChanged("nana", true);//NIC變化消息 } else if (action == evt->NlActionLinkUp) {//下面兩個消息來自NETLINK_ROUTE notifyInterfaceLinkChanged(iface, true);//鏈路啟用(類似插網線) } else if (action == evt->NlActionLinkDown) { notifyInterfaceLinkChanged(iface, false);//鏈路斷開(類似拔網線) } } else if (!strcmp(subsys, "qlog")) {//對應NETLINK_NFLOG const char *alertName = evt->findParam("ALERT_NAME"); const char *iface = evt->findParam("INTERFACE"); notifyQuotaLimitReached(alertName, iface);//當數據量超過預警值,則會收到該通知 } else if (!strcmp(subsys, "xt_idletimer")) { //這個和后文的idletimer有關,用于跟蹤某個NIC的工作狀態,即是“idle”還是“active” //檢測時間按秒計算 int action = evt->getAction(); const char *label = evt->findParam("LABEL"); const char *state = evt->findParam("STATE"); if (label == NULL) { label = evt->findParam("INTERFACE"); } if (state) notifyInterfaceClassActivity(label, !strcmp("active", state)); } ...... } ~~~ 由上邊代碼可知: NETLINK_KOBJECT_UEVENT和NETLINK_ROUTE主要反映網絡設備的事件和狀態,包括NIC的添加、刪除和修改,以及鏈路的連接狀態等。NETLINK_NFLOG用于反映設置的log是否超過配額。另外,上邊代碼中還處理了“xt_idletimer”的uevent消息,它和后文要介紹的IdleTimerCmd有關,主要用來監視網絡設備的收發工作狀態。當對應設備工作或空閑時間超過設置的監控時間后,Kernel將會發送攜帶其狀態("idle"或"active")的UEvent消息。 圖2-3所示為NetlinkHandler的工作流程。 :-: ![](http://img.blog.csdn.net/20140303220815968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖2-3 NM工作流程圖 由圖2-3可知: NM創建NetlinkHandler后,工作便轉交給NetlinkHandler來完成,而每個NetlinkHandler對象均會單獨創建一個線程用于接收Socket消息。當Kernel發送UEvent消息后,NetlinkHandler便從select調用中返回,然后調用其onDataAvailable函數,該函數內部會創建一個NetlinkEvent對象。NetlinkEvent對象根據socket創建時指定的解析類型去解析來自Kernel的UEvent消息。最終NetlinkHandler的onEvent將被調用,不同的UEvent消息將在此函數中進行分類處理。NetlinkHandler最終將處理結果經由NM內部變量mBroadcaster轉發給NetworkManagementService。 * * * * * **提醒**:請讀者結合上文所述流程自行研讀相關代碼。 * * * * * [1]關于init工作原理以及init.rc的分析方法,讀者可參考《深入理解Android:卷1》第3章關于init進程的分析。 [1]讀者可參考《深入理解Android:卷1》第9章關于Vold的分析。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看