中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

杭州蕭山網站建設公司seo顧問咨詢

杭州蕭山網站建設公司,seo顧問咨詢,網站建站平臺,國外市場網站推廣公司前言 我們分2篇文章來介紹Android 9.0中存儲卡的掛載流程,本篇文章先介紹總體的掛載模塊、Vold進程的入口main函數的詳細分析,有了這些基礎知識,下一篇中我們再詳細介紹收到驅動層消息是怎么掛載和卸載存儲卡的,還有framework層如…

前言

我們分2篇文章來介紹Android 9.0中存儲卡的掛載流程,本篇文章先介紹總體的掛載模塊、Vold進程的入口main函數的詳細分析,有了這些基礎知識,下一篇中我們再詳細介紹收到驅動層消息是怎么掛載和卸載存儲卡的,還有framework層如何與vold進程通訊交流。Android 9.0 Vold掛載流程解析(下)

Android掛載模塊整體框架

存儲卡掛載模塊由驅動層、vold進程、framework層、App層這幾個模塊注冊,vold進程通過Socket方式監(jiān)聽驅動層存儲卡熱插拔事件(Add、Change 、Remove),創(chuàng)建相應的磁盤管理類,管理磁盤的生命周期狀態(tài),提供掛載、卸載等功能,并把相應磁盤信息狀態(tài)通過Binder的方式回調給Framework層,方便App層獲取磁盤信息和狀態(tài)。以下是其整體的模塊框架圖:
掛載流程框架圖

從圖中我們知道vold有三個核心的類,NetlinkManager、VolumeManager、VoldNativeService,這三個類在啟動vold進程時就會調用其start方法啟動,NetlinkManager里創(chuàng)建了Socket連接并交給NetlinkHandler處理通訊,由NetlinkHandler監(jiān)聽驅動層發(fā)送的uevent事件,并轉發(fā)給VolumeManager處理,VolumeManager接受到相應的事件,會創(chuàng)建存儲管理的類獲取存儲卡的信息和狀態(tài)的并通過VoldNativeService回調給Framework層StorageManagerService處理,StroageManagerService也可以通過binder機制調用VoldNativeSerivice的方法,設置userId,shutdown等,好讓vold進程進行相應的處理。StorageManagerService也提供了存儲卡操作相關的方法給APP調用,App通過獲取StorageManager類間接調用StorageManagerService中的方法。

Vold進程main函數詳細分析

我們從Vold進程的main.cpp中入手開始分析
vold進程main.cpp路徑:system/vold/main.cpp

int main(int argc, char** argv) {atrace_set_tracing_enabled(false);//設置日志等級setenv("ANDROID_LOG_TAGS", "*:v", 1);android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));LOG(INFO) << "Vold 3.0 (the awakening) firing up";ATRACE_BEGIN("main");//打印支持的底層文件系統(tǒng)LOG(VERBOSE) << "Detected support for:"<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")<< (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")<< (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "")// Mediatek Android Patch Begin<< (android::vold::IsFilesystemSupported("ntfs") ? " ntfs" : "")<< (android::vold::IsFilesystemSupported("cifs") ? " cifs" : "");// Mediatek Android Patch EndVolumeManager *vm;NetlinkManager *nm;//解析參數parse_args(argc, argv);sehandle = selinux_android_file_context_handle();if (sehandle) {selinux_android_set_sehandle(sehandle);}
//創(chuàng)建/dev/block/vold目錄,掛載存儲卡了其下有對應的節(jié)點信息mkdir("/dev/block/vold", 0755);/* For when cryptfs checks and mounts an encrypted filesystem */klog_set_level(6);/* Create our singleton managers *///單例模式獲取VolumeManager對象if (!(vm = VolumeManager::Instance())) {LOG(ERROR) << "Unable to create VolumeManager";exit(1);}
//單例模式獲取NetlinkManager對象if (!(nm = NetlinkManager::Instance())) {LOG(ERROR) << "Unable to create NetlinkManager";exit(1);}
//設置是否打開VolumeManager中的日志,默認falseif (android::base::GetBoolProperty("vold.debug", false)) {vm->setDebug(true);}
//調用其start方法,稍后分析 1if (vm->start()) {PLOG(ERROR) << "Unable to start VolumeManager";exit(1);}bool has_adoptable;bool has_quota;bool has_reserved;
//解析fstab文件,該文件描述系統(tǒng)中各種文件系統(tǒng)的信息;我以MTK9669為例分析其fsab文件路徑在vendor/etc/fstab.m7642
//稍后詳細分析該方法 2if (process_config(vm, &has_adoptable, &has_quota, &has_reserved)) {PLOG(ERROR) << "Error reading configuration... continuing anyways";}ATRACE_BEGIN("VoldNativeService::start");//啟動與framework通訊的服務if (android::vold::VoldNativeService::start() != android::OK) {LOG(ERROR) << "Unable to start VoldNativeService";exit(1);}ATRACE_END();LOG(DEBUG) << "VoldNativeService::start() completed OK";ATRACE_BEGIN("NetlinkManager::start");//調用NetlinkManager start 方法    //稍后詳細分析 3if (nm->start()) {PLOG(ERROR) << "Unable to start NetlinkManager";exit(1);}ATRACE_END();// This call should go after listeners are started to avoid// a deadlock between vold and init (see b/34278978 for details)//解析的參數設置到屬性中android::base::SetProperty("vold.has_adoptable", has_adoptable ? "1" : "0");android::base::SetProperty("vold.has_quota", has_quota ? "1" : "0");android::base::SetProperty("vold.has_reserved", has_reserved ? "1" : "0");// Do coldboot here so it won't block booting,// also the cold boot is needed in case we have flash drive// connected before Vold launchedcoldboot("/sys/block");ATRACE_END();//將vold進程中主線程加入到線程池中android::IPCThreadState::self()->joinThreadPool();LOG(INFO) << "vold shutting down";exit(0);
}

通過以上代碼分析我們總結其做了以下幾件事:
1.創(chuàng)建/dev/block/vold目錄
2.單例模式獲取NetlinkManager對象并調用其start方法
3.解析fstab文件
4.調用VoldNativeService::start()方法,與framework通訊
5.單例模式獲取VolumeManager對象并調用其start方法

接下來分析NetlinkManager中start方法,路徑:system/vold/NetlinkManager.cpp

int NetlinkManager::start() {struct sockaddr_nl nladdr;int sz = 64 * 1024;int on = 1;memset(&nladdr, 0, sizeof(nladdr));nladdr.nl_family = AF_NETLINK;nladdr.nl_pid = getpid();nladdr.nl_groups = 0xffffffff;
//創(chuàng)建socket客戶端if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC,NETLINK_KOBJECT_UEVENT)) < 0) {PLOG(ERROR) << "Unable to create uevent socket";return -1;}// When running in a net/user namespace, SO_RCVBUFFORCE will fail because// it will check for the CAP_NET_ADMIN capability in the root namespace.// Try using SO_RCVBUF if that fails.if ((setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) &&(setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) < 0)) {PLOG(ERROR) << "Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option";goto out;}if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {PLOG(ERROR) << "Unable to set uevent socket SO_PASSCRED option";goto out;}
//綁定服務端if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {PLOG(ERROR) << "Unable to bind uevent socket";goto out;}
//交給NetlinkHander處理通訊mHandler = new NetlinkHandler(mSock);if (mHandler->start()) {PLOG(ERROR) << "Unable to start NetlinkHandler";goto out;}return 0;
//關閉socket
out:close(mSock);return -1;
}

該方法處理很簡單就是建立了Socket并交給其NetlinkHandler處理,調用其start方法,接下來看NetlinkHandler中做了什么
路徑:system/vold/NetlinkHandler.cpp

int NetlinkHandler::start() {//調用其父類SocketListener中的方法,開始監(jiān)聽服務端中的消息//消息會解析成NetlinkEvent對象作為參數并回調onEvent(NetlinkEvent *evt)方法return this->startListener();
}void NetlinkHandler::onEvent(NetlinkEvent *evt) {VolumeManager *vm = VolumeManager::Instance();const char *subsys = evt->getSubsystem();if (!subsys) {LOG(WARNING) << "No subsystem found in netlink event";return;}// 如果subsys是block類型的就調用VolumeManager的handleBlockEvent方法處理if (std::string(subsys) == "block") {vm->handleBlockEvent(evt);}
}

通過以上代碼分析NetlinkManager主要與驅動層建立Socket連接,接收存儲卡的插拔事件傳遞給VolumeManager處理。

回到main.cpp中分析下怎么解析fstab文件的,先看下MTK9669中vendor/etc/fstab.m7642中的內容
fstab文件內容
第一列Src,下面方法解析中的rec->blk_device屬性,用于匹配解析驅動穿過來的掛載的文件系統(tǒng)路徑
第二列mnt_point,掛載點,外部存儲卡掛載為auto
第三列類型,文件系統(tǒng)類型,外部存儲卡為auto
第四列第五列為mnt_flags、fs_mgr_flags文件系統(tǒng)掛載標志位

static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota,bool* has_reserved) {ATRACE_NAME("process_config");//解析fstab文件獲取fstab結構體對象fstab_default = fs_mgr_read_fstab_default();if (!fstab_default) {PLOG(ERROR) << "Failed to open default fstab";return -1;}/* Loop through entries looking for ones that vold manages */*has_adoptable = false;*has_quota = false;*has_reserved = false;//遍歷每一行數據for (int i = 0; i < fstab_default->num_entries; i++) {auto rec = &fstab_default->recs[i];//fs_mgr_flags列是否包含了quotaif (fs_mgr_is_quota(rec)) {*has_quota = true;}//reserved_size是否大于0if (rec->reserved_size > 0) {*has_reserved = true;}//fs_mgr_flags列是否有voldmanaged標志if (fs_mgr_is_voldmanaged(rec)) {//是否是不可移動的if (fs_mgr_is_nonremovable(rec)) {LOG(WARNING) << "nonremovable no longer supported; ignoring volume";continue;}std::string sysPattern(rec->blk_device);std::string nickname(rec->label);//add by liuxin debugLOG(DEBUG) << "sysPattern="<<rec->blk_device<<",nickname="<<rec->label<<",mountPoint="<<rec->mount_point;int flags = 0;//fs_mgr_flags是否encryptableif (fs_mgr_is_encryptable(rec)) {flags |= android::vold::Disk::Flags::kAdoptable;*has_adoptable = true;}//沒有主存儲卡if (fs_mgr_is_noemulatedsd(rec)|| android::base::GetBoolProperty("vold.debug.default_primary", false)) {flags |= android::vold::Disk::Flags::kDefaultPrimary;}//把解析的參數創(chuàng)建DiskSource對象添加到VolumeManager中vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(new VolumeManager::DiskSource(sysPattern, nickname, flags)));}}return 0;
}

上面代碼解析了fstabe文件設置了has_adoptable、has_quota 、has_reserved屬性,并且fs_mgr_flags列是voldmanager解析處理創(chuàng)建DiskSource對象添加到VolumeManager中。
看打印如下:
日志打印
接下來分析VoldNativeService的start()方法,VoldNativeService繼承自BinderService,BinderService繼承BBinder,所以它是Binder機制中的服務端程序

status_t VoldNativeService::start() {IPCThreadState::self()->disableBackgroundScheduling(true);//注冊當前客戶端到binder驅動status_t ret = BinderService<VoldNativeService>::publish();if (ret != android::OK) {return ret;}//加入到binder線程池sp<ProcessState> ps(ProcessState::self());ps->startThreadPool();ps->giveThreadPoolName();return android::OK;
}

上述代碼主要把當前的binder服務端加入到binder驅動中,方便提供給客戶端調用

接下來看第五個步驟VolumeManager的start方法:

int VolumeManager::start() {ATRACE_NAME("VolumeManager::start");// Always start from a clean slate by unmounting everything in// directories that we own, in case we crashed.//卸載掉所有的存儲卡unmountAll();Devmapper::destroyAll();Loop::destroyAll();// Assume that we always have an emulated volume on internal// storage; the framework will decide if it should be mounted.CHECK(mInternalEmulated == nullptr);//創(chuàng)建內部存儲卡mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(new android::vold::EmulatedVolume("/data/media"));mInternalEmulated->create();// Consider creating a virtual disk//虛擬存儲卡不考慮updateVirtualDisk();return 0;
}

上面代碼很簡單,先卸載所有的存儲卡,再創(chuàng)建了內部儲存卡,其EmulateVolume關于掛載卸載的操作我們在下一篇文章中再介紹了。

總結

本篇文章介紹總體的掛載模塊、Vold進程的入口main函數的詳細分析,下一篇將介紹收到插拔事件如果管理存儲卡信息和狀態(tài)與Framework層通訊。
Android 9.0 Vold掛載流程解析(下)

http://www.risenshineclean.com/news/64132.html

相關文章:

  • 軟件工程師資格證優(yōu)化網站最好的刷排名軟件
  • 室內設計公司辦公室圖片百度seo工作室
  • 網站制作學什么軟件成都網絡推廣公司
  • 沒有服務器做網站免費下載優(yōu)化大師
  • 教人做飲料的網站做百度推廣的公司電話號碼
  • 網站建設首頁模板下載優(yōu)化大師怎么提交作業(yè)
  • 制作網站服務企業(yè)查詢軟件
  • 運用asp做購物網站的心得google瀏覽器官方下載
  • 淘客網站+wordpress上海百度seo優(yōu)化
  • 網站應該如何進行優(yōu)化網絡營銷分類
  • 做網站建網站安卓手機游戲優(yōu)化器
  • 河南企業(yè)網站制作個人怎么做網站
  • 中國域名注冊中心做博客的seo技巧
  • 上海專業(yè)制作電子商務網站廣西seo公司
  • 做字的網站個人友情鏈接推廣
  • wordpress編輯器 模板seopeixun com cn
  • 動態(tài)網站開發(fā) 實訓總結環(huán)球貿易網
  • 解除網站被攔截的方法快手流量推廣免費網站
  • 合肥建網站公司騰訊與中國聯通
  • 各大網站提交入口怎么聯系地推公司
  • 西安火車站網站建設安卓優(yōu)化大師官方下載
  • 頂級裝修公司百度小程序優(yōu)化
  • 莆田網站建設技術托管南陽網站seo
  • 開發(fā)公司屬于什么行業(yè)網站優(yōu)化 seo和sem
  • 中國專業(yè)的網站建設12月10日新聞
  • 義烏多語言網站建設seo網絡推廣技術
  • 做五金生意什么網站做比較好精準營銷的三要素
  • 網站首頁的模塊布局杭州百度快速排名提升
  • 做競猜網站合法嗎如何快速提升網站關鍵詞排名
  • 哪個平臺查企業(yè)免費谷歌aso優(yōu)化