vold start
目录
概述
vold进程启动流程:
-
注册vold服务
-
创建emulated volume
-
创建netlinkmanager,用来监听uevent事件,add disksource属于mmc1(sd卡)和usb的
源码解析
1. main模块
1.1 main函数
int main(int argc, char** argv) {
// 关闭atrace
atrace_set_tracing_enabled(false);
setenv("ANDROID_LOG_TAGS", "*:d", 1); // Do not submit with verbose logs enabled
// 设置logcat为system的
// 将这句改为android::base::InitLogging(argv, &android::base::KernelLogger);
// 就可以把log打印到串口中了
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
LOG(INFO) << "Vold 3.0 (the awakening) firing up";
ATRACE_BEGIN("main");
LOG(DEBUG) << "Detected support for:"
<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
<< (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
<< (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");
VolumeManager* vm;
NetlinkManager* nm;
// 解析参数,vold --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
parse_args(argc, argv);
sehandle = selinux_android_file_context_handle();
if (sehandle) {
selinux_android_set_sehandle(sehandle);
}
mkdir("/dev/block/vold", 0755);
/* For when cryptfs checks and mounts an encrypted filesystem */
// 设置内核打印等级
klog_set_level(6);
/* Create our singleton managers */
if (!(vm = VolumeManager::Instance())) {
LOG(ERROR) << "Unable to create VolumeManager";
exit(1);
}
if (!(nm = NetlinkManager::Instance())) {
LOG(ERROR) << "Unable to create NetlinkManager";
exit(1);
}
// 设置vold.debug为true,然后重启vold,就可以打印debug信息了,主要是显示handleBlockEvent信息
if (android::base::GetBoolProperty("vold.debug", false)) {
vm->setDebug(true);
}
// 启动VolumeManager
if (vm->start()) {
PLOG(ERROR) << "Unable to start VolumeManager";
exit(1);
}
bool has_adoptable;
bool has_quota;
bool has_reserved;
// 解析fstab文件
if (process_config(vm, &has_adoptable, &has_quota, &has_reserved)) {
PLOG(ERROR) << "Error reading configuration... continuing anyways";
}
// binder相关的
android::hardware::configureRpcThreadpool(1, false /* callerWillJoin */);
ATRACE_BEGIN("VoldNativeService::start");
// 启动vold服务
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");
if (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 launched
coldboot("/sys/block");
ATRACE_END();
// binder相关
android::IPCThreadState::self()->joinThreadPool();
LOG(INFO) << "vold shutting down";
exit(0);
}
1.2 process_config-解析fstab文件
static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota,
bool* has_reserved) {
ATRACE_NAME("process_config");
// 读fstab文件
if (!ReadDefaultFstab(&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 (auto& entry : fstab_default) {
// fstab中配置了quota
if (entry.fs_mgr_flags.quota) {
*has_quota = true;
}// fstab中配置了reservedsize=
if (entry.reserved_size > 0) {
*has_reserved = true;
}
/* Make sure logical partitions have an updated blk_device. */
// system_a变为/dev/block/dm-0设备
if (entry.fs_mgr_flags.logical && !fs_mgr_update_logical_partition(&entry)) {
PLOG(FATAL) << "could not find logical partition " << entry.blk_device;
}
// 配置了voldmanaged
/devices/platform/*/4020000.sdmmc/mmc_host/mmc* auto auto defaults voldmanaged=extsd:auto,encryptable=footer
/devices/platform/**/usb* auto auto defaults voldmanaged=usb:auto,encryptable=footer
if (entry.fs_mgr_flags.vold_managed) {
if (entry.fs_mgr_flags.nonremovable) {
LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
continue;
}
// /devices/platform/*/4020000.sdmmc/mmc_host/mmc* sd卡的
// /devices/platform/**/usb* u盘的
std::string sysPattern(entry.blk_device);
// label为extsd和usb,partnum为-1
std::string nickname(entry.label);
int flags = 0;
// 是有encryptable=的
if (entry.is_encryptable()) {
flags |= android::vold::Disk::Flags::kAdoptable;
*has_adoptable = true;
}// noemulatedsd配置
if (entry.fs_mgr_flags.no_emulated_sd ||
android::base::GetBoolProperty("vold.debug.default_primary", false)) {
flags |= android::vold::Disk::Flags::kDefaultPrimary;
}
// 添加disksource到mDiskSources中
vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(
new VolumeManager::DiskSource(sysPattern, nickname, flags)));
}
}
return 0;
}
1.3 coldboot-往/sys/block发送add uevent事件
static void coldboot(const char* path) {
ATRACE_NAME("coldboot");
DIR* d = opendir(path);
if (d) {
do_coldboot(d, 0);
closedir(d);
}
}
1.4 do_coldboot-往/sys/block发送add uevent事件
static void do_coldboot(DIR* d, int lvl) {
struct dirent* de;
int dfd, fd;
dfd = dirfd(d);
fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);
if (fd >= 0) {
write(fd, "add\n", 4);
close(fd);
}
while ((de = readdir(d))) {
DIR* d2;
if (de->d_name[0] == '.') continue;
if (de->d_type != DT_DIR && lvl > 0) continue;
fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (fd < 0) continue;
d2 = fdopendir(fd);
if (d2 == 0)
close(fd);
else {
do_coldboot(d2, lvl + 1);
closedir(d2);
}
}
}
2. VolumeManager模块
2.1 Instance-构造VolumeManager对象
VolumeManager* VolumeManager::Instance() {
if (!sInstance) sInstance = new VolumeManager();
return sInstance;
}
VolumeManager::VolumeManager() {
mDebug = false;
mNextObbId = 0;
mNextStubId = 0;
// For security reasons, assume that a secure keyguard is
// showing until we hear otherwise
mSecureKeyguardShowing = true;
}
2.2 start-启动VolumeManager
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();
// 删除dm设备
Devmapper::destroyAll();
// 这里会打印一堆的,这样的信息:是正常的
// Failed to LOOP_GET_STATUS64 /dev/block/loop23: No such device or address
Loop::destroyAll();
// Assume that we always have an emulated volume on internal
// storage; the framework will decide if it should be mounted.
// 开机的时候,一般是空的
CHECK(mInternalEmulatedVolumes.empty());
// 新建EmulatedVolume卷
auto vol = std::shared_ptr<android::vold::VolumeBase>(
new android::vold::EmulatedVolume("/data/media", 0));
vol->setMountUserId(0);
vol->create();
mInternalEmulatedVolumes.push_back(vol);
// Consider creating a virtual disk
// 啥都没做,sm set-virtual-disk true之后会做东西
updateVirtualDisk();
return 0;
}
2.3 unmountAll-先卸载文件系统
int VolumeManager::unmountAll() {
std::lock_guard<std::mutex> lock(mLock);
ATRACE_NAME("VolumeManager::unmountAll()");
// First, try gracefully unmounting all known devices
// 第一次启动,这个为空的
for (const auto& vol : mInternalEmulatedVolumes) {
vol->unmount();
}// 第一次启动,这也为空
for (const auto& disk : mDisks) {
disk->unmountAll();
}
// Worst case we might have some stale mounts lurking around, so
// force unmount those just to be safe.
// 打开/proc/mounts文件
FILE* fp = setmntent("/proc/mounts", "re");
if (fp == NULL) {
PLOG(ERROR) << "Failed to open /proc/mounts";
return -errno;
}
// Some volumes can be stacked on each other, so force unmount in
// reverse order to give us the best chance of success.
std::list<std::string> toUnmount;
mntent* mentry; // 将/proc/mounts文件中的挂载点,解析为mentry数据结构
while ((mentry = getmntent(fp)) != NULL) {
// mnt_dir表示挂载点/storage/目录的
auto test = std::string(mentry->mnt_dir);
// 挂载在/mnt目录或者
if ((StartsWith(test, "/mnt/") &&
#ifdef __ANDROID_DEBUGGABLE__
!StartsWith(test, "/mnt/scratch") &&
#endif
!StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product") &&
!StartsWith(test, "/mnt/installer") && !StartsWith(test, "/mnt/androidwritable")) ||
StartsWith(test, "/storage/")) {
//都要umount它
toUnmount.push_front(test);
}
}
endmntent(fp);
for (const auto& path : toUnmount) {
LOG(DEBUG) << "Tearing down stale mount " << path;
// 这里进行umount
android::vold::ForceUnmount(path);
}
return 0;
}
2.4 updateVirtualDisk-和virtual disk有关
int VolumeManager::updateVirtualDisk() {
ATRACE_NAME("VolumeManager::updateVirtualDisk");
// persist.sys.virtual_disk,为空,默认为false
if (GetBoolProperty(kPropVirtualDisk, false)) {
if (access(kPathVirtualDisk, F_OK) != 0) {
Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
}
if (mVirtualDisk == nullptr) {
if (Loop::create(kPathVirtualDisk, mVirtualDiskPath) != 0) {
LOG(ERROR) << "Failed to create virtual disk";
return -1;
}
struct stat buf;
if (stat(mVirtualDiskPath.c_str(), &buf) < 0) {
PLOG(ERROR) << "Failed to stat " << mVirtualDiskPath;
return -1;
}
auto disk = new android::vold::Disk(
"virtual", buf.st_rdev, "virtual",
android::vold::Disk::Flags::kAdoptable | android::vold::Disk::Flags::kSd);
mVirtualDisk = std::shared_ptr<android::vold::Disk>(disk);
handleDiskAdded(mVirtualDisk);
}
} else {// 启动阶段默认为nullptr
if (mVirtualDisk != nullptr) {
dev_t device = mVirtualDisk->getDevice();
handleDiskRemoved(device);
Loop::destroyByDevice(mVirtualDiskPath.c_str());
mVirtualDisk = nullptr;
}
// /data/misc/vold/virtual_disk不可访问
if (access(kPathVirtualDisk, F_OK) == 0) {
unlink(kPathVirtualDisk);
}
}
return 0;
}
2.5 DiskSource模块
2.5.1 DiskSource构造函数
// /devices/platform/*/4020000.sdmmc/mmc_host/mmc* extsd kAdoptable
// /devices/platform/**/usb* usb kAdoptable
DiskSource(const std::string& sysPattern, const std::string& nickname, int flags)
: mSysPattern(sysPattern), mNickname(nickname), mFlags(flags) {}
2.5.2 matches-正则表达式匹配
bool matches(const std::string& sysPath) {
// unix下的正则表达式匹配库函数
return !fnmatch(mSysPattern.c_str(), sysPath.c_str(), 0);
}
2.6 handleBlockEvent-处理uevent事件,插入sd卡,插入u盘这些
void VolumeManager::handleBlockEvent(NetlinkEvent* evt) {
std::lock_guard<std::mutex> lock(mLock);
if (mDebug) {
LOG(DEBUG) << "----------------";
LOG(DEBUG) << "handleBlockEvent with action " << (int)evt->getAction();
evt->dump();
}
std::string eventPath(evt->findParam("DEVPATH") ? evt->findParam("DEVPATH") : "");
std::string devType(evt->findParam("DEVTYPE") ? evt->findParam("DEVTYPE") : "");
if (devType != "disk") return;
int major = std::stoi(evt->findParam("MAJOR"));
int minor = std::stoi(evt->findParam("MINOR"));
dev_t device = makedev(major, minor);
switch (evt->getAction()) {
case NetlinkEvent::Action::kAdd: {
for (const auto& source : mDiskSources) {
// 对于add事件,首先要和disksources进行匹配路径,路径一直才进行add的动作
// /devices/platform/*/4020000.sdmmc/mmc_host/mmc*
// /devices/platform/**/usb*
if (source->matches(eventPath)) {
// For now, assume that MMC and virtio-blk (the latter is
// specific to virtual platforms; see Utils.cpp for details)
// devices are SD, and that everything else is USB
int flags = source->getFlags();
if (major == kMajorBlockMmc || IsVirtioBlkDevice(major)) {
flags |= android::vold::Disk::Flags::kSd;
} else {
flags |= android::vold::Disk::Flags::kUsb;
}
auto disk =
new android::vold::Disk(eventPath, device, source->getNickname(), flags);
handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk));
break;
}
}
break;
}
case NetlinkEvent::Action::kChange: {
LOG(DEBUG) << "Disk at " << major << ":" << minor << " changed";
handleDiskChanged(device);
break;
}
case NetlinkEvent::Action::kRemove: {
handleDiskRemoved(device);
break;
}
default: {
LOG(WARNING) << "Unexpected block event action " << (int)evt->getAction();
break;
}
}
}
3. NetlinkManager模块
3.1 Instance-构造NetlinkManager模块
NetlinkManager* NetlinkManager::Instance() {
if (!sInstance) sInstance = new NetlinkManager();
return sInstance;
}
NetlinkManager::NetlinkManager() {
mBroadcaster = NULL;
}
3.2 start-启动netlink,监控uevent事件
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;
// 连接NETLINK_KOBJECT_UEVENT的socket,监听uevent事件
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;
}
mHandler = new NetlinkHandler(mSock);
// ps -T -p 196看到的vold进程中do_sys_po+的线程,就是netlinkhandler的
if (mHandler->start()) {
PLOG(ERROR) << "Unable to start NetlinkHandler";
goto out;
}
return 0;
out:
close(mSock);
return -1;
}
3.3 NetlinkHandler构造函数
NetlinkHandler::NetlinkHandler(int listenerSocket) : NetlinkListener(listenerSocket) {}
3.4 start-启动socketlistener线程
int NetlinkHandler::start() {
return this->startListener();
}
3.5 onEvent-处理uevent事件,挂载sd卡
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;
}
// 这里进行过滤了,必须是block的才处理
if (std::string(subsys) == "block") {
vm->handleBlockEvent(evt);
}
}
4. VoldNativeService模块
4.1 start-注册vold服务
status_t VoldNativeService::start() {
// binder相关
IPCThreadState::self()->disableBackgroundScheduling(true);
// 注册vold服务
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;
}
5. Utils模块
5.1 ForceUnmount-强制卸载文件系统
status_t ForceUnmount(const std::string& path) {
const char* cpath = path.c_str();
// 卸载成功,直接返回
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
// Apps might still be handling eject request, so wait before
// we start sending signals
if (sSleepOnUnmount) sleep(5);
// 先把使用文件的进程全部干掉
KillProcessesWithOpenFiles(path, SIGINT);
if (sSleepOnUnmount) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
KillProcessesWithOpenFiles(path, SIGTERM);
if (sSleepOnUnmount) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
KillProcessesWithOpenFiles(path, SIGKILL);
if (sSleepOnUnmount) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(INFO) << "ForceUnmount failed";
return -errno;
}
5.2 IsFilesystemSupported-文件系统是否支持
bool IsFilesystemSupported(const std::string& fsType) {
std::string supported;
// /proc/filesystems文件系统
if (!ReadFileToString(kProcFilesystems, &supported)) {
PLOG(ERROR) << "Failed to read supported filesystems";
return false;
}
return supported.find(fsType + "\n") != std::string::npos;
}
bool IsSdcardfsUsed() {
return IsFilesystemSupported("sdcardfs") &&
base::GetBoolProperty(kExternalStorageSdcardfs, true);
}
6. Process模块
6.1 KillProcessesWithOpenFiles-杀掉那些使用了挂载点prefix中的文件的进程
int KillProcessesWithOpenFiles(const std::string& prefix, int signal) {
std::unordered_set<pid_t> pids;
auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
if (!proc_d) {
PLOG(ERROR) << "Failed to open proc";
return -1;
}
struct dirent* proc_de;
while ((proc_de = readdir(proc_d.get())) != nullptr) {
// We only care about valid PIDs
pid_t pid;
if (proc_de->d_type != DT_DIR) continue;
if (!android::base::ParseInt(proc_de->d_name, &pid)) continue;
// Look for references to prefix
bool found = false;
auto path = StringPrintf("/proc/%d", pid);
// /proc/pid/maps文件
found |= checkMaps(path + "/maps", prefix);
found |= checkSymlink(path + "/cwd", prefix);
found |= checkSymlink(path + "/root", prefix);
found |= checkSymlink(path + "/exe", prefix);
// 打开/proc/pid/fd文件夹
auto fd_path = path + "/fd";
auto fd_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fd_path.c_str()), closedir);
if (!fd_d) {
PLOG(WARNING) << "Failed to open " << fd_path;
} else {
struct dirent* fd_de;
while ((fd_de = readdir(fd_d.get())) != nullptr) {
if (fd_de->d_type != DT_LNK) continue;
found |= checkSymlink(fd_path + "/" + fd_de->d_name, prefix);
}
}
if (found) {
// 有一个匹配了,都可以干掉了这个进程
pids.insert(pid);
}
}
if (signal != 0) {
for (const auto& pid : pids) {
LOG(WARNING) << "Sending " << strsignal(signal) << " to " << pid;
// 干掉进程
kill(pid, signal);
}
}
return pids.size();
}
6.2 checkMaps-检查/proc/pid/maps文件,是否有挂载点prefix的文件
static bool checkMaps(const std::string& path, const std::string& prefix) {
bool found = false;
auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
if (!file) {
return false;
}
char* buf = nullptr;
size_t len = 0;
while (getline(&buf, &len, file.get()) != -1) {
std::string line(buf);
// 找/,因为有些是[anon:.bss]开头的
std::string::size_type pos = line.find('/');
if (pos != std::string::npos) {
line = line.substr(pos);
// 看是否匹配
if (android::base::StartsWith(line, prefix)) {
LOG(WARNING) << "Found map " << path << " referencing " << line;
found = true;
break;
}
}
}
free(buf);
return found;
}
6.3 checkSymlink-读文件链接,匹配挂载点prefix
static bool checkSymlink(const std::string& path, const std::string& prefix) {
std::string res;
if (android::base::Readlink(path, &res)) {
if (android::base::StartsWith(res, prefix)) {
LOG(WARNING) << "Found symlink " << path << " referencing " << res;
return true;
}
}
return false;
}
7. Devmapper模块
7.1 destroyAll-一般没有vold:开头的文件的
int Devmapper::destroyAll() {
ATRACE_NAME("Devmapper::destroyAll");
// 打开/dev/device-mapper设备
auto& dm = DeviceMapper::Instance();
std::vector<DeviceMapper::DmBlockDevice> devices;
if (!dm.GetAvailableDevices(&devices)) {
LOG(ERROR) << "Failed to get dm devices";
return -1;
}
for (const auto& device : devices) {
// vold:开头的
if (android::base::StartsWith(device.name(), kVoldPrefix)) {
LOG(DEBUG) << "Tearing down stale dm device named " << device.name();
if (!dm.DeleteDevice(device.name())) {
if (errno != ENXIO) {
PLOG(WARNING) << "Failed to destroy dm device named " << device.name();
}
}
} else {
LOG(DEBUG) << "Found unmanaged dm device named " << device.name();
}
}
return 0;
}
8. Loop设备
8.1 destroyAll-删掉vold管理的loop设备,一般没有vold:管理的loop设备的
int Loop::destroyAll() {
ATRACE_NAME("Loop::destroyAll");
std::string root = "/dev/block/";
auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(root.c_str()), closedir);
if (!dirp) {
PLOG(ERROR) << "Failed to opendir";
return -1;
}
// Poke through all devices looking for loops
struct dirent* de;
while ((de = readdir(dirp.get()))) {
auto test = std::string(de->d_name);
// /dev/block/loop开头的设备
if (!android::base::StartsWith(test, "loop")) continue;
auto path = root + de->d_name;
unique_fd fd(open(path.c_str(), O_RDWR | O_CLOEXEC));
if (fd.get() == -1) {
if (errno != ENOENT) {
PLOG(WARNING) << "Failed to open " << path;
}
continue;
}
struct loop_info64 li;
// 获取状态,开机的时候,会打印一大堆的信息:
// Failed to LOOP_GET_STATUS64 /dev/block/loop23: No such device or address
if (ioctl(fd.get(), LOOP_GET_STATUS64, &li) < 0) {
PLOG(WARNING) << "Failed to LOOP_GET_STATUS64 " << path;
continue;
}
auto id = std::string((char*)li.lo_crypt_name);
if (android::base::StartsWith(id, kVoldPrefix)) {
LOG(DEBUG) << "Tearing down stale loop device at " << path << " named " << id;
// 删掉loop设备
if (ioctl(fd.get(), LOOP_CLR_FD, 0) < 0) {
PLOG(WARNING) << "Failed to LOOP_CLR_FD " << path;
}
} else {
LOG(DEBUG) << "Found unmanaged loop device at " << path << " named " << id;
}
}
return 0;
}
9. EmulatedVolume类
继承自VolumeBase类
9.1 EmulatedVolume构造函数
EmulatedVolume::EmulatedVolume(const std::string& rawPath, int userId)
: VolumeBase(Type::kEmulated) { // kEmulated内部存储
// emulated;0
setId(StringPrintf("emulated;%u", userId));
// /data/media
mRawPath = rawPath;
mLabel = "emulated";
mFuseMounted = false;
// Android 11 之后,就不支持sdcardfs了,改用fuse了
mUseSdcardFs = IsSdcardfsUsed();
// sys.vold_app_data_isolation_enabled,为空,默认为false
mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
}
10. VolumeBase类
10.1 VolumeBase构造函数
VolumeBase::VolumeBase(Type type)
: mType(type), // kEmulated
mMountFlags(0),
mMountUserId(USER_UNKNOWN), // 为0
mCreated(false),
mState(State::kUnmounted),
mSilent(false) {}
10.2 create-创建内部存储卷
status_t VolumeBase::create() {
CHECK(!mCreated);
// 创建状态
mCreated = true;
status_t res = doCreate();
// 这个listener为storagemanagerservice那里的,vold启动阶段,没有listener,因为system_server还没起来
auto listener = getListener();
if (listener) {
// 上报给storagemanagerservice
listener->onVolumeCreated(getId(), static_cast<int32_t>(mType), mDiskId, mPartGuid,
mMountUserId);
}
// 设为kUnmounted状态
setState(State::kUnmounted);
return res;
}
10.3 setState
void VolumeBase::setState(State state) {
mState = state;
auto listener = getListener();
if (listener) {
listener->onVolumeStateChanged(getId(), static_cast<int32_t>(mState));
}
}
10.4 doCreate-EmulatedVolume类使用默认的,就是什么都不做
status_t VolumeBase::doCreate() {
return OK;
}
问题
卸载U盘之后,杀掉进程,导致应用闪退
卸载data分区
1. stop
2. lsof | grep data
3. 杀掉lsof中列出的使用了data文件的进程
stop tombstoned
stop credstore
stop keystore
stop gatekeeperd
stop update_engine
kill -9 920
最后卸载data分区文件系统
4. umount /data/user/0
5. umount /data