Android 9.0 Vold 流程分析(-)

Vold 介绍

Vold(volume Daemon),即Volume守护进程,用来管理Android中存储类的热拔插事件,处于Kernel和Framework之间,是两个层级连接的桥梁。vold 代码路径为: system/vold 和 /system/core/libsysutils/src

Vold 分析

分析代码时,首先要看编译脚本即Android.bp,通过Android.bp 可以看出代码的组织关系,如何编译的。可以看出核心是 vold 这个可执行文件,主要入口为main.cpp,那我们就分析 main.cpp

Android.bp 文件
cc_binary {
    name: "vold",
    defaults: [
        "vold_default_flags",
        "vold_default_libs",
    ],

    srcs: ["main.cpp"],
    static_libs: ["libvold"],
	
    init_rc: [
        "vold.rc",
        "wait_for_keymaster.rc",
    ],
}

1. main.cpp

可以看出,主要实例化 VolumeManager NetlinkManager,并调用 VolumeManager NetlinkManager VoldNativeService  onStart() 方法。

main.cpp 
int main(int argc, char** argv) {
  // log初始化
  android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));

  VolumeManager *vm;
  NetlinkManager *nm;

  parse_args(argc, argv);//参数解析
  mkdir("/dev/block/vold", 0755);

  // 获取实例,并调用 start() 方法
  vm = VolumeManager::Instance();
  nm = NetlinkManager::Instance();

  vm->start();
  android::vold::VoldNativeService::start();
  nm->start();

  android::IPCThreadState::self()->joinThreadPool();
}

2. VolumeManager

system/vold/VolumeManager.cpp
int VolumeManager::start() {
  unmountAll();
  Devmapper::destroyAll();
  Loop::destroyAll();

  // 通过 EmulatedVolume 完成对 "/data/media" 初始化
  mInternalEmulated = std::shared_ptr(
    new android::vold::EmulatedVolume("/data/media"));

  mInternalEmulated->create();
  updateVirtualDisk();
}

3. NetlinkManager 

通过 Netlink 与 kernel 进行通信,并new NetlinkHandler对象,并调用 start()方法。

重点在 NetlinkHandler,该类集成关系如下:NetlinkHandler -> NetlinkListener -> SocketListener

system/vold/NetlinkManager.cpp
NetlinkManager *NetlinkManager::sInstance = NULL;
NetlinkManager *NetlinkManager::Instance() {
  if (!sInstance)
    sInstance = new NetlinkManager();

  return sInstance;
}

int NetlinkManager::start() {
  //PF_NETLINK: Netlink 用于在内核模块与在用户地址空间中的进程之间传递消息
  mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC,
    NETLINK_KOBJECT_UEVENT)
  
  setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz);
  setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz);
  setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)
  bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr);

  //重点,new NetlinkHandler对象,并调用 start()方法
  mHandler = new NetlinkHandler(mSock);
  mHandler->start();
}

 4. NetlinkHandler

NetlinkHandler 继承于 NetlinkListener,而NetlinkHandler start() 方法,调用 this->startListener();
该方法必然是父类 NetlinkListener 的方法,继续跟踪代码。

system/vold/NetlinkHandler.h
  class NetlinkHandler: public NetlinkListener {
  public:
    int start(void);
	int stop(void);
  private:
    virtual void onEvent(NetlinkEvent *evt);
  }
system/vold/NetlinkHandler.cpp
    NetlinkHandler::NetlinkHandler(int listenerSocket) :
                NetlinkListener(listenerSocket) {
    }
	int NetlinkHandler::start() {
		return this->startListener();
	}

	int NetlinkHandler::stop() {
		return this->stopListener();
	}

	void NetlinkHandler::onEvent(NetlinkEvent *evt) {
		VolumeManager *vm = VolumeManager::Instance();
		const char *subsys = evt->getSubsystem();

		if (std::string(subsys) == "block") {
			vm->handleBlockEvent(evt);
		}
	}

5.  NetlinkListener

 NetlinkListener 继承于 NetlinkListener,而且NetlinkListener 没有实现 startListener方法,那么该方法应该是其父类实现,继续跟踪。

system/core/libsysutils/include/sysutils/NetlinkListener.h
  class NetlinkListener : public SocketListener {
    virtual bool onDataAvailable(SocketClient *cli);
    virtual void onEvent(NetlinkEvent *evt) = 0;
  }

system/core/libsysutils/src/NetlinkListener.cpp
  NetlinkListener::NetlinkListener(int socket) :
                   SocketListener(socket, false) {
    mFormat = NETLINK_FORMAT_ASCII;
  }

  bool NetlinkListener::onDataAvailable(SocketClient *cli){
    int socket = cli->getSocket();
	
	count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket,
	  mBuffer, sizeof(mBuffer), require_group, &uid));
	
	NetlinkEvent *evt = new NetlinkEvent();
	if (evt->decode(mBuffer, count, mFormat)) {
	  onEvent(evt);
    }
  }
  

6. SocketListener 

终于找到 startListener()方法的实现类。startListener() 方法通过 pthread_create(&mThread, NULL, SocketListener::threadStart, this) 创建单独线程,线程执行方法为 threadStart(),所以会走到 threadStart()方法。

threadStart() 方法有调用 SocketListener类的 runListener() 方法,runListener() 方法主要通过 select() read() 方法 获取事件信息,并放入 pendingList 链表中,最后逐个调用链表元素中的 onDataAvailable() 方法,而该方法在 SocketListener 类中是纯虚函数,必须由子类进行实现,所以到 NetlinkListener 继续分析。

由 NetlinkListener 分析可知,其实现了 onDataAvailable() 方法,该方法 通过uevent_kernel_recv 获取 kernel 的uevent 事件,并最终调用 onEvent() 方法。同样 onEvent() 方法在 NetlinkListener 类中是纯虚函数,所以必须由其子类 NetlinkHandler 实现,所以到 NetlinkHandler 继续分析。

由 NetlinkHandler 分析可知,其实现了 onEvent() 方法,并通过 VolumeManager实例调用其 handleBlockEvent() 方法,我们到 VolumeManager类继续分析。

system/core/libsysutils/include/sysutils/SocketListener.h
  class SocketListener {
  public:
    int startListener();
	int stopListener();
  protected:
     virtual bool onDataAvailable(SocketClient *c) = 0;
  private:
    static void *threadStart(void *obj);
	void runListener();
	void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
  }
system/core/libsysutils/src/SocketListener.cpp
  void SocketListener::runListener() {
    SocketClientCollection pendingList;
	while(1){
	  for (it = mClients->begin(); it != mClients->end(); ++it) {
	    int fd = (*it)->getSocket();
		FD_SET(fd, &read_fds);
      }
	 rc = select(max + 1, &read_fds, NULL, NULL, NULL)
	 TEMP_FAILURE_RETRY(accept4(mSock, nullptr, nullptr, SOCK_CLOEXEC));
	 mClients->push_back(new SocketClient(c, true, mUseCmdNum));
	 
	 for (it = mClients->begin(); it != mClients->end(); ++it) {
	   SocketClient* c = *it;
	   int fd = c->getSocket();
	   if (FD_ISSET(fd, &read_fds)) {
	     pendingList.push_back(c);
	   }
	 }
	 
	 while (!pendingList.empty()) {
	   it = pendingList.begin();
	   SocketClient* c = *it;
	   onDataAvailable(c))
	 }
    }
  }
  
  void *SocketListener::threadStart(void *obj) {
    SocketListener *me = reinterpret_cast(obj);
	me->runListener();
  }
  
  int SocketListener::startListener(int backlog) {
    if (mListen && listen(mSock, backlog) < 0) 
	
	mClients->push_back(new SocketClient(mSock, false, mUseCmdNum));

	pthread_create(&mThread, NULL, SocketListener::threadStart, this)
  }

7. VolumeManager  

 VolumeManager 类 handleBlockEvent 根据 NetlinkEvent 类型不同调用不同的方法。类型有kAdd,kChange,kRemove,分别对应设备新增,设备变更,设备移除操作。以kAdd 为例分析,其调用 handleDiskAdded() 方法,该方法调用  的 create()方法,继续进行跟踪。

system/vold/VolumeManager.cpp
  void VolumeManager::handleDiskAdded(const std::shared_ptr& disk) {
    disk->create();
    mDisks.push_back(disk);
  }
  
  void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
    switch (evt->getAction()) {
      case NetlinkEvent::Action::kAdd: {
	    auto disk = new android::vold::Disk(eventPath, device,source->getNickname(), flags);
		handleDiskAdded(std::shared_ptr(disk));
	  }
	  case NetlinkEvent::Action::kChange: {
	    handleDiskChanged(device);
	  }
      case NetlinkEvent::Action::kRemove: {
	    handleDiskRemoved(device);
	  }
	}
  }

8. Disk.cpp

其中 create() 方法通过 VolumeManager::Instance()->getListener() 获取 listener 并调用 onDiskCreated() 通知到 java StorageManagerService中,这是如何实现的我们继续分析。

system/vold/model/Disk.cpp
  status_t Disk::create() {
    CHECK(!mCreated);
    mCreated = true;

    auto listener = VolumeManager::Instance()->getListener();
    if (listener) listener->onDiskCreated(getId(), mFlags);

    readMetadata();
    readPartitions();
    return OK;
  }

 9.  getListener 实现分析

可以看到 VolumeManager 中实现 getListener() 方法,但是也仅是返回了 mListerner 变量,该变量是在 setListener() 中设置的,通过函数参数可以看出其通过 AIDL 实现了这样的调用。

system/vold/VolumeManager.h
  void setListener(android::sp listener) { mListener = listener; }
  android::sp getListener() { return mListener; }
  
  void handleBlockEvent(NetlinkEvent *evt);
  

10.  IVold.aidl 接口

system/vold/binder/android/os/IVold.aidl
  package android.os;
  import android.os.IVoldListener;
  import android.os.IVoldTaskListener;
  interface IVold {
    void setListener(IVoldListener listener);
	
    void onUserAdded(int userId, int userSerial);
    void onUserRemoved(int userId);
	
	void mount(@utf8InCpp String volId, int mountFlags, int mountUserId);
	void unmount(@utf8InCpp String volId);
	void format(@utf8InCpp String volId, @utf8InCpp String fsType);
	void checkEncryption(@utf8InCpp String volId);
	void mkdirs(@utf8InCpp String path);
	
	void fbeEnable();
	void mountDefaultEncrypted();
	
	void unlockUserKey(int userId, int userSerial, @utf8InCpp String token, @utf8InCpp String secret);
    void lockUserKey(int userId);
  }

11. StorageManagerServie

StorageManagerServie 在connect() 方法中,通过ServiceManager获取 vold 服务,并获取到binder 对象 ,最后通过 setListener(mListener)方法,其中 mListener 为  private final IVoldListener mListener = new IVoldListener.Stub() ,所以在 Disk.cpp 中 listener 为 StorageManagerService 设置的 listener,其 listener->onDiskCreated(getId(), mFlags) 也会调用到 StorageManagerService 中 IVoldListener.Stub 中方法。

frameworks/base/services/core/java/com/android/server/StorageManagerService.java
  import android.os.IVold;
  import android.os.IVoldListener;
  import android.os.IVoldTaskListener;
  
  private void connect() {
    IBinder binder = ServiceManager.getService("storaged");
	mStoraged = IStoraged.Stub.asInterface(binder);
	
	binder = ServiceManager.getService("vold");
	mVold = IVold.Stub.asInterface(binder);
	mVold.setListener(mListener);
  
    onDaemonConnected();
  }

  private final IVoldListener mListener = new IVoldListener.Stub() {

  @Override
	public void onDiskCreated(String diskId, int flags) {
		synchronized (mLock) {
			final String value = SystemProperties.get(StorageManager.PROP_ADOPTABLE);
			switch (value) {
				case "force_on":
					flags |= DiskInfo.FLAG_ADOPTABLE;
					break;
				case "force_off":
					flags &= ~DiskInfo.FLAG_ADOPTABLE;
					break;
			}
			mDisks.put(diskId, new DiskInfo(diskId, flags));
		}
	}
	
	@Override
	public void onDiskScanned(String diskId) {
		synchronized (mLock) {
			final DiskInfo disk = mDisks.get(diskId);
			if (disk != null) {
				onDiskScannedLocked(disk);
			}
		}
	}
	
	@Override
	public void onDiskMetadataChanged(String diskId, long sizeBytes, String label,
			String sysPath) {
		synchronized (mLock) {
			final DiskInfo disk = mDisks.get(diskId);
			if (disk != null) {
				disk.size = sizeBytes;
				disk.label = label;
				disk.sysPath = sysPath;
			}
		}
	}
	
	@Override
	public void onDiskDestroyed(String diskId) {
		synchronized (mLock) {
			final DiskInfo disk = mDisks.remove(diskId);
			if (disk != null) {
				mCallbacks.notifyDiskDestroyed(disk);
			}
		}
	}
	
	@Override
	public void onVolumeCreated(String volId, int type, String diskId, String partGuid) {
		synchronized (mLock) {
			final DiskInfo disk = mDisks.get(diskId);
			final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid);
			mVolumes.put(volId, vol);
			onVolumeCreatedLocked(vol);
		}
	}
	
	@Override
	public void onVolumeStateChanged(String volId, int state) {
		synchronized (mLock) {
			final VolumeInfo vol = mVolumes.get(volId);
			if (vol != null) {
				final int oldState = vol.state;
				final int newState = state;
				vol.state = newState;
				onVolumeStateChangedLocked(vol, oldState, newState);
			}
		}
	}
  }

你可能感兴趣的:(android,android,vold)