Analyzing Android 6.0 Storage Architecture and Communication Design
This article examines Android 6.0’s storage architecture, detailing the roles and interactions of MountService, Vold, and the kernel, illustrating module and process structures, communication flows via sockets, and highlighting performance considerations such as thread blocking and ANR issues.
Introduction: The author encountered storage‑related bugs causing ANR on Android devices, traced to the main thread being blocked in the vold process. To understand and fix the issue, the article dives into the design of Android’s storage system based on Android 6.0 source code.
Overview : The storage system centers on two core modules, MountService (a Binder service running in system_server ) and Vold (the Volume Daemon, a native process). The article focuses on these modules and their interaction, showing only essential code snippets.
Module Architecture : The communication chain is Linux Kernel → uevent → NetlinkManager → VolumeManager → CommandListener → MountService. Each step forwards events or commands to the next component.
Process Architecture :
Java layer: 1 main thread ( system_server ) plus three MountService‑related threads (VoldConnector, MountService, CryptdConnector).
Native layer: 1 main thread ( /system/bin/vold ), three child threads (named vold ), and one child process ( /system/bin/sdcard ).
The article also notes two additional system threads used by handlers: android.fg and android.io .
Communication Architecture :
MountService communicates with Vold via a socket rather than the usual Android Binder IPC. The instantiation of MountService creates several threads and handlers:
Create ICallbacks on the android.fg thread.
Start a handler thread named "MountService".
Create OBB handler on the android.io thread.
Instantiate NativeDaemonConnector .
Start threads "VoldConnector" and "CryptdConnector".
Register broadcast listeners for user add/remove events.
Thus three dedicated threads (MountService, VoldConnector, CryptdConnector) plus the two system threads are used for storage operations.
MountService Sending Messages :
When a mount request is issued, MountService calls:
public void mount(String volId) {
// ...
mConnector.execute("volume", "mount", vol.id, vol.mountFlags, vol.mountUserId);
}The execute call eventually reaches NDC.execute , which increments a sequence number, writes the command (e.g., 3 volume reset ) to the socket, and blocks waiting for a response with a poll loop. It exits the loop either after a timeout (1 minute) or when a response code outside the [100,200) range is received. Commands taking longer than 500 ms generate a log prefixed with "NDC Command" for performance analysis.
Vold’s native side creates a listener thread via pthread_create . When data arrives on the socket, FL.onDataAvailable is invoked, which forwards the command to FL.dispatchCommand . The dispatcher maps the command to a handler class; unknown commands or overly long arguments result in a 500‑code error response.
For a volume mount command, CommandListener.VolumeCmd.runCommand processes the mount branch.
MountService Receiving Messages :
After Vold processes a command, it sends a response via sendGenericOkFail . Response codes are categorized as follows:
Code Range
Event Category
Method
[100,200)
Partial response, more events follow
isClassContinue
[200,300)
Success
isClassOk
[400,500)
Remote server error
isClassServerError
[500,600)
Local client error
isClassClientError
[600,700)
Unsolicited event from Vold
isClassUnsolicited
If the response code is not in [600,700) , the event is added to mResponseQueue , unblocking the original NDC.execute call. Unsolicited events are dispatched to the android.fg handler, which invokes NativeDaemonConnector.handleMessage .
Summary :
The article provides a module‑level and process‑level view of Android’s storage system, explains the socket‑based communication between MountService and Vold, and points out that heavy I/O operations (e.g., fsck, fstrim) can block the main thread, leading to ANR. Future work will cover Vold‑kernel communication.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.