Android 14 vold 分析(2)VolumeManager 和 NetlinkManger

3. VolumeManager::Instance() 和 VolumeManager::start()

system/vold/VolumeManager.cpp
3.1 Instance()没啥好说的 非常简单

cpp 复制代码
    112  VolumeManager* VolumeManager::Instance() {
    113      if (!sInstance) sInstance = new VolumeManager();
    114      return sInstance;
    115  }
    116  
    117  VolumeManager::VolumeManager() {
    118      mDebug = false;
    119      mNextObbId = 0;
    120      mNextStubId = 0;
    121      // For security reasons, assume that a secure keyguard is
    122      // showing until we hear otherwise
    123      mSecureKeyguardShowing = true;
    124  }
3.2 VolumeManager::start()
cpp 复制代码
    174  int VolumeManager::start() {
    175      ATRACE_NAME("VolumeManager::start");
    176  
    177      // Always start from a clean slate by unmounting everything in
    178      // directories that we own, in case we crashed.
    179      unmountAll();           -----> 全部 unmount , 这里的unmount似乎并不是全部所有分区, 全部的话那还了得
    180  
    181      Loop::destroyAll();
    182  
    183      // Assume that we always have an emulated volume on internal
    184      // storage; the framework will decide if it should be mounted.
    185      CHECK(mInternalEmulatedVolumes.empty());
    186  
    187      auto vol = std::shared_ptr<android::vold::VolumeBase>(
    188              new android::vold::EmulatedVolume("/data/media", 0));  ---> 创建 EmulatedVolume
    189      vol->setMountUserId(0);
    190      vol->create();
    191      mInternalEmulatedVolumes.push_back(vol);
    192  
    193      // Consider creating a virtual disk
    194      updateVirtualDisk();
    195  
    196      return 0;
    197  }
4. NetlinkManger::Instance() 和 NetlinkManger::start()

system/vold/NetlinkManager.cpp
4.1 NetlinkManger::Instance() 很简单 不需要赘述

cpp 复制代码
    36  NetlinkManager* NetlinkManager::Instance() {
    37      if (!sInstance) sInstance = new NetlinkManager();
    38      return sInstance;
    39  }
    40  
    41  NetlinkManager::NetlinkManager() {
    42      mBroadcaster = NULL;
    43  }
4.2 NetlinkManger::start()
cpp 复制代码
47  int NetlinkManager::start() {
    48      struct sockaddr_nl nladdr;
    49      int sz = 64 * 1024;
    50      int on = 1;
    51  
    52      memset(&nladdr, 0, sizeof(nladdr));
    53      nladdr.nl_family = AF_NETLINK;
    54      nladdr.nl_pid = getpid();
    55      nladdr.nl_groups = 0xffffffff;
    56  
    57      if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)) < 0) {   ---> 创建socket client
    58          PLOG(ERROR) << "Unable to create uevent socket";
    59          return -1;
    60      }
    61  
    62      // When running in a net/user namespace, SO_RCVBUFFORCE will fail because
    63      // it will check for the CAP_NET_ADMIN capability in the root namespace.
    64      // Try using SO_RCVBUF if that fails.
    65      if ((setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) &&
    66          (setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) < 0)) {
    67          PLOG(ERROR) << "Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option";
    68          goto out;
    69      }
    70  
    71      if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
    72          PLOG(ERROR) << "Unable to set uevent socket SO_PASSCRED option";
    73          goto out;
    74      }
    75  
    76      if (bind(mSock, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {  --> socket bind
    77          PLOG(ERROR) << "Unable to bind uevent socket";
    78          goto out;
    79      }
    80  
    81      mHandler = new NetlinkHandler(mSock);    --> 创建 new NetlinkHandler
    82      if (mHandler->start()) {     --> 创建 new NetlinkHandler.start() 见4.3
    83          PLOG(ERROR) << "Unable to start NetlinkHandler";
    84          goto out;
    85      }
    86  
    87      return 0;
    88  
    89  out:
    90      close(mSock);
    91      return -1;
    92  }
4.3 new NetlinkHandler and start()

这有个继承关系NetlinkHandler : NetlinkListener : SocketListener

cpp 复制代码
    2  int NetlinkHandler::start() {
    33      return this->startListener();       ------> 实际就是SocketListener poll监听,是否有POLLIN 产生, onDataAvailable -> onEvent
    34  }
    35  
    36  void NetlinkHandler::onEvent(NetlinkEvent* evt) {  ---> 收到了uevent
    37      VolumeManager* vm = VolumeManager::Instance();
    38      const char* subsys = evt->getSubsystem();
    39  
    40      if (!subsys) {
    41          LOG(WARNING) << "No subsystem found in netlink event";
    42          return;
    43      }
    44  
    45      if (std::string(subsys) == "block") {   ------> 只有uevent的subsys是block才会处理的
    46          vm->handleBlockEvent(evt);       ------> VolumeManager处理 block device uevent  见 4.4
    47      }
    48  }
4.4 VolumeManager::handleBlockEvent()
cpp 复制代码
199  void VolumeManager::handleBlockEvent(NetlinkEvent* evt) {
    200      std::lock_guard<std::mutex> lock(mLock);
    201  
    202      if (mDebug) {
    203          LOG(DEBUG) << "----------------";
    204          LOG(DEBUG) << "handleBlockEvent with action " << (int)evt->getAction();  ---> 这里是vold.debug控制的,打印具体的action
    205          evt->dump();
    206      }
    207  
    208      std::string eventPath(evt->findParam("DEVPATH") ? evt->findParam("DEVPATH") : "");
    209      std::string devType(evt->findParam("DEVTYPE") ? evt->findParam("DEVTYPE") : "");
    210  
    211      if (devType != "disk") return;    --->  devType不是disk还不处理, 真是牛逼哄哄
    212   
    213      int major = std::stoi(evt->findParam("MAJOR"));
    214      int minor = std::stoi(evt->findParam("MINOR"));
    215      dev_t device = makedev(major, minor);   ---> 创建block device组合
    216  
    217      switch (evt->getAction()) {
    218          case NetlinkEvent::Action::kAdd: {     ---> uevent action为add 具体见4.5
    219              for (const auto& source : mDiskSources) {  ---> 之前添加的两个disksource,还记得吗,只支持sd卡和U盘
    220                  if (source->matches(eventPath)) {
    221                      // For now, assume that MMC and virtio-blk (the latter is
    222                      // specific to virtual platforms; see Utils.cpp for details)
    223                      // devices are SD, and that everything else is USB
    224                      int flags = source->getFlags();
    225                      if (major == kMajorBlockMmc || IsVirtioBlkDevice(major)) {
    226                          flags |= android::vold::Disk::Flags::kSd;  ---> SD卡
    227                      } else {
    228                          flags |= android::vold::Disk::Flags::kUsb; ---> usb storage, 通过otg插入的
    229                      }
    230  
    231                      auto disk =
    232                          new android::vold::Disk(eventPath, device, source->getNickname(), flags);  ---> 创建一个disk设备节点mknod
    233                      handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk)); --> 真正的处理
    234                      break;
    235                  }
    236              }
    237              break;
    238          }
    239          case NetlinkEvent::Action::kChange: {  --> uevent action为add 具体见4.6
    240              LOG(VERBOSE) << "Disk at " << major << ":" << minor << " changed";
    241              handleDiskChanged(device);
    242              break;
    243          }
    244          case NetlinkEvent::Action::kRemove: { --> uevent action为add 具体见4.7
    245              handleDiskRemoved(device);
    246              break;
    247          }
    248          default: {
    249              LOG(WARNING) << "Unexpected block event action " << (int)evt->getAction();
    250              break;
    251          }
    252      }
    253  }
4.5 new android::vold::Disk()和handleDiskAdded()

system/vold/model/Disk.cpp

4.5.1 new android::vold::Disk()
cpp 复制代码
        Disk::Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags)
        95      : mDevice(device),
        96        mSize(-1),
        97        mNickname(nickname),
        98        mFlags(flags),
        99        mCreated(false),
        100        mJustPartitioned(false) {
        101      mId = StringPrintf("disk:%u,%u", major(device), minor(device));
        102      mEventPath = eventPath;
        103      mSysPath = StringPrintf("/sys/%s", eventPath.c_str());
        104      mDevPath = StringPrintf("/dev/block/vold/%s", mId.c_str());
        105      CreateDeviceNode(mDevPath, mDevice);  ---------> 创建block device 的设备节点mknod
        106  }
4.5.2 handleDiskAdded()
cpp 复制代码
255  void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {
        256      // For security reasons, if secure keyguard is showing, wait
        257      // until the user unlocks the device to actually touch it
        258      // Additionally, wait until user 0 is actually started, since we need
        259      // the user to be up before we can mount a FUSE daemon to handle the disk.
        260      bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();
        261      if (mSecureKeyguardShowing) {
        262          LOG(INFO) << "Found disk at " << disk->getEventPath()
        263                    << " but delaying scan due to secure keyguard";
        264          mPendingDisks.push_back(disk);
        265      } else if (!userZeroStarted) {
        266          LOG(INFO) << "Found disk at " << disk->getEventPath()
        267                    << " but delaying scan due to user zero not having started";
        268          mPendingDisks.push_back(disk);
        269      } else {
        270          disk->create();        ---------> disk->create()
        271          mDisks.push_back(disk);
        272      }
        273  }


        146  status_t Disk::create() {
        147      CHECK(!mCreated);
        148      mCreated = true;
        149  
        150      auto listener = VolumeManager::Instance()->getListener();   ---------> StorageManaerService通信
        151      if (listener) listener->onDiskCreated(getId(), mFlags);  ------> StorageManaerService->onDiskCreated()
        152  
        153      if (isStub()) {
        154          createStubVolume();
        155          return OK;
        156      }
        157      readMetadata();  -------->  listener->onDiskMetadataChanged(getId(), mSize, mLabel, mSysPath);
        158      readPartitions();  --------> Disk::createPublicVolume()  listener->onVolumeCreated()and listener->onDiskScanned()
        159      return OK;
        160  }

思考, vold比mount service启动的早,那开机时vold获取到的listener为空,也就是说虽然disk创建了但是不会mount,那什么时候才会mount呢? 我们下一篇文章解答

相关推荐
烬奇小云3 小时前
认识一下Unicorn
android·python·安全·系统安全
顾北川_野15 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO15 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他15 小时前
Android ANR分析总结
android
PenguinLetsGo17 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博19 小时前
音频格式转换
android·音视频
音视频牛哥21 小时前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.1 天前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda
二流小码农1 天前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos
夏非夏1 天前
Android 生成并加载PDF文件
android