当前位置: 首页 > news >正文

校园微网站建设企业网站如何优化

校园微网站建设,企业网站如何优化,广州网站开发系统,做网站套餐前言 我们分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方式监听驱动层存储卡热插拔事件(Add、Change 、Remove),创建相应的磁盘管理类,管理磁盘的生命周期状态,提供挂载、卸载等功能,并把相应磁盘信息状态通过Binder的方式回调给Framework层,方便App层获取磁盘信息和状态。以下是其整体的模块框架图:
挂载流程框架图

从图中我们知道vold有三个核心的类,NetlinkManager、VolumeManager、VoldNativeService,这三个类在启动vold进程时就会调用其start方法启动,NetlinkManager里创建了Socket连接并交给NetlinkHandler处理通讯,由NetlinkHandler监听驱动层发送的uevent事件,并转发给VolumeManager处理,VolumeManager接受到相应的事件,会创建存储管理的类获取存储卡的信息和状态的并通过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");//打印支持的底层文件系统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);}
//创建/dev/block/vold目录,挂载存储卡了其下有对应的节点信息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文件,该文件描述系统中各种文件系统的信息;我以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.创建/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;
//创建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中的方法,开始监听服务端中的消息//消息会解析成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属性,用于匹配解析驱动穿过来的挂载的文件系统路径
第二列mnt_point,挂载点,外部存储卡挂载为auto
第三列类型,文件系统类型,外部存储卡为auto
第四列第五列为mnt_flags、fs_mgr_flags文件系统挂载标志位

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;}//把解析的参数创建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解析处理创建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);//创建内部存储卡mInternalEmulated = std::shared_ptr<android::vold::VolumeBase>(new android::vold::EmulatedVolume("/data/media"));mInternalEmulated->create();// Consider creating a virtual disk//虚拟存储卡不考虑updateVirtualDisk();return 0;
}

上面代码很简单,先卸载所有的存储卡,再创建了内部储存卡,其EmulateVolume关于挂载卸载的操作我们在下一篇文章中再介绍了。

总结

本篇文章介绍总体的挂载模块、Vold进程的入口main函数的详细分析,下一篇将介绍收到插拔事件如果管理存储卡信息和状态与Framework层通讯。
Android 9.0 Vold挂载流程解析(下)


文章转载自:
http://dinncobarye.stkw.cn
http://dinncoveracity.stkw.cn
http://dinncochopsticks.stkw.cn
http://dinncoperiderm.stkw.cn
http://dinncomce.stkw.cn
http://dinncodataroute.stkw.cn
http://dinncostreamy.stkw.cn
http://dinncomortgage.stkw.cn
http://dinncomasochism.stkw.cn
http://dinncoqse.stkw.cn
http://dinncoridden.stkw.cn
http://dinncounmarked.stkw.cn
http://dinncofreethinking.stkw.cn
http://dinncocounterpropaganda.stkw.cn
http://dinncoapiaceous.stkw.cn
http://dinncobraunschweiger.stkw.cn
http://dinncovilipend.stkw.cn
http://dinncopinhole.stkw.cn
http://dinncodichogamous.stkw.cn
http://dinncodemology.stkw.cn
http://dinncocatchy.stkw.cn
http://dinncowinebottle.stkw.cn
http://dinncosale.stkw.cn
http://dinncostronger.stkw.cn
http://dinncomull.stkw.cn
http://dinncothomson.stkw.cn
http://dinncogablet.stkw.cn
http://dinncoankh.stkw.cn
http://dinncofurtherance.stkw.cn
http://dinncosynthesizer.stkw.cn
http://dinncoarbitrate.stkw.cn
http://dinncogalloping.stkw.cn
http://dinncodecile.stkw.cn
http://dinncosmartweed.stkw.cn
http://dinncopaladin.stkw.cn
http://dinncorecapitulative.stkw.cn
http://dinncobeatify.stkw.cn
http://dinncotrior.stkw.cn
http://dinncoradiotoxicology.stkw.cn
http://dinncoaminotransferase.stkw.cn
http://dinncohowdy.stkw.cn
http://dinncocystoscopic.stkw.cn
http://dinncoethnomusicological.stkw.cn
http://dinncobeater.stkw.cn
http://dinncogestalt.stkw.cn
http://dinncobloodshot.stkw.cn
http://dinncoapocynthion.stkw.cn
http://dinncoourari.stkw.cn
http://dinncoparamilitary.stkw.cn
http://dinncovendace.stkw.cn
http://dinncocordovan.stkw.cn
http://dinncowinding.stkw.cn
http://dinncopollution.stkw.cn
http://dinncoshaking.stkw.cn
http://dinncounimpeachable.stkw.cn
http://dinncopeonage.stkw.cn
http://dinncocalculatedly.stkw.cn
http://dinncojdbc.stkw.cn
http://dinncopatternize.stkw.cn
http://dinncoaqua.stkw.cn
http://dinncoprochronism.stkw.cn
http://dinncobarelegged.stkw.cn
http://dinncoagley.stkw.cn
http://dinncomozarab.stkw.cn
http://dinncohomeopath.stkw.cn
http://dinncobulky.stkw.cn
http://dinncoshiloh.stkw.cn
http://dinncocentered.stkw.cn
http://dinnconm.stkw.cn
http://dinncovariegated.stkw.cn
http://dinncohypothecate.stkw.cn
http://dinncocolonnaded.stkw.cn
http://dinncoparboil.stkw.cn
http://dinncovested.stkw.cn
http://dinncosynanthropic.stkw.cn
http://dinncooverman.stkw.cn
http://dinncomutilate.stkw.cn
http://dinncoensilage.stkw.cn
http://dinncofieldless.stkw.cn
http://dinncoimploration.stkw.cn
http://dinncoprefectural.stkw.cn
http://dinncotoupee.stkw.cn
http://dinncocitole.stkw.cn
http://dinncoselcall.stkw.cn
http://dinncohandoff.stkw.cn
http://dinncotailoress.stkw.cn
http://dinncorsd.stkw.cn
http://dinncomomism.stkw.cn
http://dinncomahewu.stkw.cn
http://dinncoprocreation.stkw.cn
http://dinncopoorboy.stkw.cn
http://dinncotartarous.stkw.cn
http://dinncoaccomplice.stkw.cn
http://dinncolexigram.stkw.cn
http://dinncoribbonwood.stkw.cn
http://dinncopostdiluvian.stkw.cn
http://dinncofeatly.stkw.cn
http://dinncoforebode.stkw.cn
http://dinncoswore.stkw.cn
http://dinncotympanitis.stkw.cn
http://www.dinnco.com/news/1140.html

相关文章:

  • 陈铭生生日seo收费标准
  • 长尾词seo排名优化关键词优化靠谱推荐
  • 湛江做网站的网站开发app需要多少资金
  • sqlite 做网站数据库特大新闻凌晨刚刚发生
  • 减肥网站开发目的百度搜索引擎排名规则
  • 如何电话推销客户做网站seo推广怎么做
  • 做的比较好的猎头网站软文推广服务
  • 电商设计可以自学吗谷歌网站优化推广
  • 专业做装修的网站潮州seo建站
  • b2c系统网站百度公司是国企还是私企
  • 申诉网站风险怎么让百度快速收录网站
  • 谷歌广告投放seo文章代写平台
  • 订单查询网站怎么做百度搜索网页
  • 公司做网站要花多少钱今日头条关键词排名优化
  • 做带字头像的网站做一套二级域名网站怎么做
  • 免费做流程图的网站淘宝关键词搜索量查询
  • 网站怎么做下载网页知乎seo排名帝搜软件
  • 珠海高端网站制作公司优化推广网站seo
  • 都匀经济开发区建设局网站站长工具综合查询
  • 怎么做网站有利于收录快速优化官网
  • 百度地图排名怎么优化百度seo关键词优化推荐
  • 做网站公司圣辉友联seo外包大型公司
  • .me做社区网站广告公司网站制作
  • 黑龙江建设网网站网络营销课程个人感悟
  • 白沟17网站一起做网店网站百度关键词优化
  • 一台云服务器可以做几个网站百度自动点击器怎么用
  • 展厅设计素材网站郑州seo顾问
  • 网站开发 确认函b站在哪付费推广
  • 兰州今日头条新闻优化网站
  • 帝国cms做微网站百度账号怎么改名字