vold start

目录

概述

vold进程启动流程:

  1. 注册vold服务

  2. 创建emulated volume

  3. 创建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;
}
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

补充

参考

posted @ 2021-06-30 20:16  pyjetson  阅读(1083)  评论(0编辑  收藏  举报