Android的儲存系統—Vold與MountService分析(一)

來源:互聯網
上載者:User

標籤:

Android的儲存系統(一)

看了很長時間Vold儲存模組的相關知識,也死扣了一段時間的Android源碼,發現Android儲存系統所涉及的函數調用,以及Kernel與上層之間的Socket傳輸真的是讓人頭疼,除了需要整理整個架構的原理以外,還要反覆看源碼,真真的鬱悶。

鬱悶之餘,還是打算把自己看過的經驗之貼和參考資料進行整理,以文章的形式發出來,供碼神們參考,有不對的地方請指正,我們互相交流,下面就進入主題。

Android的儲存系統主要由:SystemServer進程中的MountService和Vold進程中的VolumeManager組成。

它們管理著系統的存放裝置,執行各種操作,如:mount、unmount、format等。

圖1 Android儲存系統架構圖

圖2 Android儲存系統原理圖

【重要組成分析】

1、NetlinkManager

     全稱是NetlinkManager.cpp位於Android 4.x 源碼位置/system/vold/NetlinkManager.cpp。

     該類的主要通過引用NetlinkHandler類中的onEvent()方法來接收來自核心的事件訊息,NetlinkHandler位於/system/vold/NetlinkHandler.cpp。

2、VolumeManager

     全稱是VolumeManager.cpp位於Android 4.x源碼位置/system/vold/VolumeManager.cpp。該類的主要作用是接收經過NetlinkManager處理過後的事件訊息。

     因為我們這裡是SD的掛載,因此經過NetlinkManager處理過後的訊息會分為五種,分別是:block、switch、usb_composite、battery、power_supply。

     這裡SD卡掛載的事件是block。

3、DirectVolume

     位於/system/vold/DirectVolume.cpp。該類的是一個工具類,主要負責對傳入的事件進行進一步的處理。

     block事件又可以分為:Add、Removed、Change、Noaction這四種。

4、Volume

     位於/system/vold/Volume.cpp,該類是負責SD卡掛載的主要類。Volume.cpp主要負責檢查SD卡格式,以及對複合要求的SD卡進行掛載,並通過Socket將訊息SD卡掛載的訊息傳遞給NativeDaemonConnector。

5、CommandListener

     該類位於位於/system/vold/CommandListener.cpp,通過vold socket與NativeDaemonConnector通訊。

6、NativeDaemonConnector

     該類位於frameworks/base/services/java/com.android.server/NativeDaemonConnector.java。該類用於接收來自Volume.cpp 發來的SD卡掛載訊息並向上傳遞。

7、MountService

     位於frameworks/base/services/java/com.android.server/MountService.java。

     MountService是一個服務類,該服務是系統服務,提供對外部存放裝置的管理、查詢等。在外部存放裝置狀態發生變化的時候,該類會發出相應的通知給上層應用。在Android系統中這是一個非常重要的類。

8、StorageManaer

     位於frameworks/base/core/java/andriod/os/storage/StorageManager.java。

     在該類的說明中有提到,該類是系統儲存服務的介面。在系統設定中,有Storage相關項目,同時Setting也註冊了該類的監聽器。

     而StorageManager又將自己的監聽器註冊到了MountService中,因此該類主要用於上層應用擷取SD卡狀態。

 

【SD卡掛載流程】

1、Kernel發出SD卡插入uevent訊息。

2、NetlinkHandler::onEvent()接收核心發出的uevent並進行解析。

3、VolumeManager::handleBlockEvent()處理經過第二步處理後的事件。

4、接下來調用DirectVolume::handleBlockEvent()。

在該方法中需要注意亮點:

(1)程式首先會遍曆mPath容器,尋找與event對應的sysfs_path是否存在於mPath容器中;

(2)針對event中的action有4種處理方式:Add、Removed、Change、Noaction。

 

 

 

5、經過上一步之後會調用DirectVolume::handleDiskAdded()方法,該方法中會廣播disk insert訊息。

6、SocketListener::runListener()會接收DirectVolume::handleDiskAdded()廣播的訊息。該方法主要完成對event中資料的擷取,通過Socket。

7、調用FrameworkListener::onDataAvailable()方法處理接收到的訊息內容。

8、FrameworkListener::dispatchCommand()該方法用於分髮指令。

9、在FrameworkListener::dispatchCommand()方法中,通過runCommand()方法去調用相應的指令。

10、在/system/vold/CommandListener.cpp中有runCommand()的具體實現。在該類中可以找到這個方法:CommandListener::VolumeCmd::runCommand(),從字面意思上來看這個方法就是對Volume分髮指令的解析。該方法中會執行“mount”函數:vm>mountVolume(arg[2])。

11、mountVolume(arg[2])在VolumeManager::mountVolume()中實現,在該方法中調用v>mountVol()。

12、mountVol()方法在Volume::mountVol()中實現,該函數是真正的掛載函數。(在該方法中,後續的處理都在該方法中,在Mount過程中會廣播相應的訊息給上層,通過setState()函數)。

13、setState(Volume::Checking)?廣播給上層,正在檢查SD卡,為掛載做準備。

14、Fat::check()?SD卡檢查方法,檢查SD卡是否是FAT格式。

15、Fat::doMount()掛載SD卡。

至此,SD的掛載已算初步完成,接下來應該將SD卡掛載後的訊息發送給上層,在13中也提到過,在掛載以及檢查的過程中其實也有發送訊息給上層的。

 

16、MountService的建構函式中會開啟監聽線程,用於監聽來自vold的socket資訊。

     Thread thread = new Thread(mConnector,VOLD_TAG)? thread.start()?

17、mConnector是NativeDaemonConnector的對象,NativeDaemonConnector繼承了Runnable並Override了run方法。在run方法中通過一個while(true)調用ListenToSocket()方法來實現即時監聽。

18、在ListenToSocket()中,首先建立與Vold通訊的Socket Server端,然後調用MountService中的onDaemonConnected()方法。

19、onDaemonConnected()方法是在介面INativeDaemonConnectorCallbacks中定義的,MountService實現了該介面並Override了onDaemonConnected()方法。該方法開啟一個線程用於更新外置存放裝置的狀態,主要更新狀態的方法也在其中實現。

20、然後回到ListenToSocket中,通過inputStream來擷取Vold傳遞來的event,並存放在隊列中。

21、然後這些event會在onDaemonConnected()通過隊列的”隊列.take()”方法取出。並根據不同的event調用updatePublicVolumeState()方法,在該方法中調用packageManagerService中的updateExteralState()方法來更新存放裝置的狀態。

22、更新是通過packageHelper.getMountService().finishMediaUpdate()方法來實現的。

23、在updatePublicVolumeState()方法中,更新後會執行如下代碼:

       bl.mListener.onStorageStateChanged()?

在Android源碼/packages/apps/Settings/src/com.android.settings.deviceinfo/Memory.java代碼中,實現了StorageEventListener 的匿名內部類,並Override了onStorageStateChanged()方法。因此在updatePublicVolumeState()中調用onStorageStateChanged()方法後,Memory.java中也會收到。在Memory.java中收到以後會在Setting介面進行更新,系統設定—儲存中會更新SD卡的狀態。從而SD卡的掛載從底層到達了上層。

 

在下一個文章中我會對Vold模組的源碼以及MountService服務進行分析,包括main函數、NetlinkManager、NetlinkHandler、處理block類型的uevent、處理MountService命令、VolumeManager、NativeDaemonConnector等源碼,很快就會與大家見面,感謝支援,歡迎交流與指正!

 

 

 

 

Android的儲存系統—Vold與MountService分析(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.