/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Utils.h"

#include "Process.h"
#include "sehandle.h"

#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/fs.h>
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
#include <private/android_projectid_config.h>

#include <dirent.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/xattr.h>
#include <unistd.h>

#include <filesystem>
#include <list>
#include <mutex>
#include <regex>
#include <thread>

#ifndef UMOUNT_NOFOLLOW
#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
#endif

using namespace std::chrono_literals;
using android::base::EndsWith;
using android::base::ReadFileToString;
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::unique_fd;

namespace android {
namespace vold {

char* sBlkidContext = nullptr;
char* sBlkidUntrustedContext = nullptr;
char* sFsckContext = nullptr;
char* sFsckUntrustedContext = nullptr;

bool sSleepOnUnmount = true;

static const char* kBlkidPath = "/system/bin/blkid";
static const char* kKeyPath = "/data/misc/vold";

static const char* kProcDevices = "/proc/devices";
static const char* kProcFilesystems = "/proc/filesystems";

static const char* kAndroidDir = "/Android/";
static const char* kAppDataDir = "/Android/data/";
static const char* kAppMediaDir = "/Android/media/";
static const char* kAppObbDir = "/Android/obb/";

static const char* kMediaProviderCtx = "u:r:mediaprovider:";
static const char* kMediaProviderAppCtx = "u:r:mediaprovider_app:";

// Lock used to protect process-level SELinux changes from racing with each
// other between multiple threads.
static std::mutex kSecurityLock;

std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path) {
    return StringPrintf("/mnt/user/%d/%s", user_id, relative_upper_path.c_str());
}

status_t CreateDeviceNode(const std::string& path, dev_t dev) {
    std::lock_guard<std::mutex> lock(kSecurityLock);
    const char* cpath = path.c_str();
    status_t res = 0;

    char* secontext = nullptr;
    if (sehandle) {
        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) {
            setfscreatecon(secontext);
        }
    }

    mode_t mode = 0660 | S_IFBLK;
    if (mknod(cpath, mode, dev) < 0) {
        if (errno != EEXIST) {
            PLOG(ERROR) << "Failed to create device node for " << major(dev) << ":" << minor(dev)
                        << " at " << path;
            res = -errno;
        }
    }

    if (secontext) {
        setfscreatecon(nullptr);
        freecon(secontext);
    }

    return res;
}

status_t DestroyDeviceNode(const std::string& path) {
    const char* cpath = path.c_str();
    if (TEMP_FAILURE_RETRY(unlink(cpath))) {
        return -errno;
    } else {
        return OK;
    }
}

// Sets a default ACL on the directory.
status_t SetDefaultAcl(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
                       std::vector<gid_t> additionalGids) {
    if (IsSdcardfsUsed()) {
        // sdcardfs magically takes care of this
        return OK;
    }

    size_t num_entries = 3 + (additionalGids.size() > 0 ? additionalGids.size() + 1 : 0);
    size_t size = sizeof(posix_acl_xattr_header) + num_entries * sizeof(posix_acl_xattr_entry);
    auto buf = std::make_unique<uint8_t[]>(size);

    posix_acl_xattr_header* acl_header = reinterpret_cast<posix_acl_xattr_header*>(buf.get());
    acl_header->a_version = POSIX_ACL_XATTR_VERSION;

    posix_acl_xattr_entry* entry =
            reinterpret_cast<posix_acl_xattr_entry*>(buf.get() + sizeof(posix_acl_xattr_header));

    int tag_index = 0;

    entry[tag_index].e_tag = ACL_USER_OBJ;
    // The existing mode_t mask has the ACL in the lower 9 bits:
    // the lowest 3 for "other", the next 3 the group, the next 3 for the owner
    // Use the mode_t masks to get these bits out, and shift them to get the
    // correct value per entity.
    //
    // Eg if mode_t = 0700, rwx for the owner, then & S_IRWXU >> 6 results in 7
    entry[tag_index].e_perm = (mode & S_IRWXU) >> 6;
    entry[tag_index].e_id = uid;
    tag_index++;

    entry[tag_index].e_tag = ACL_GROUP_OBJ;
    entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
    entry[tag_index].e_id = gid;
    tag_index++;

    if (additionalGids.size() > 0) {
        for (gid_t additional_gid : additionalGids) {
            entry[tag_index].e_tag = ACL_GROUP;
            entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
            entry[tag_index].e_id = additional_gid;
            tag_index++;
        }

        entry[tag_index].e_tag = ACL_MASK;
        entry[tag_index].e_perm = (mode & S_IRWXG) >> 3;
        entry[tag_index].e_id = 0;
        tag_index++;
    }

    entry[tag_index].e_tag = ACL_OTHER;
    entry[tag_index].e_perm = mode & S_IRWXO;
    entry[tag_index].e_id = 0;

    int ret = setxattr(path.c_str(), XATTR_NAME_POSIX_ACL_DEFAULT, acl_header, size, 0);

    if (ret != 0) {
        PLOG(ERROR) << "Failed to set default ACL on " << path;
    }

    return ret;
}

int SetQuotaInherit(const std::string& path) {
    unsigned int flags;

    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << path << " to set project id inheritance.";
        return -1;
    }

    int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
    if (ret == -1) {
        PLOG(ERROR) << "Failed to get flags for " << path << " to set project id inheritance.";
        return ret;
    }

    flags |= FS_PROJINHERIT_FL;

    ret = ioctl(fd, FS_IOC_SETFLAGS, &flags);
    if (ret == -1) {
        PLOG(ERROR) << "Failed to set flags for " << path << " to set project id inheritance.";
        return ret;
    }

    return 0;
}

int SetQuotaProjectId(const std::string& path, long projectId) {
    struct fsxattr fsx;

    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << path << " to set project id.";
        return -1;
    }

    int ret = ioctl(fd, FS_IOC_FSGETXATTR, &fsx);
    if (ret == -1) {
        PLOG(ERROR) << "Failed to get extended attributes for " << path << " to get project id.";
        return ret;
    }

    fsx.fsx_projid = projectId;
    ret = ioctl(fd, FS_IOC_FSSETXATTR, &fsx);
    if (ret == -1) {
        PLOG(ERROR) << "Failed to set project id on " << path;
        return ret;
    }
    return 0;
}

int PrepareDirWithProjectId(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
                            long projectId) {
    int ret = fs_prepare_dir(path.c_str(), mode, uid, gid);

    if (ret != 0) {
        return ret;
    }

    if (!IsSdcardfsUsed()) {
        ret = SetQuotaProjectId(path, projectId);
    }

    return ret;
}

static int FixupAppDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid, long projectId) {
    namespace fs = std::filesystem;

    // Setup the directory itself correctly
    int ret = PrepareDirWithProjectId(path, mode, uid, gid, projectId);
    if (ret != OK) {
        return ret;
    }

    // Fixup all of its file entries
    for (const auto& itEntry : fs::directory_iterator(path)) {
        ret = lchown(itEntry.path().c_str(), uid, gid);
        if (ret != 0) {
            return ret;
        }

        ret = chmod(itEntry.path().c_str(), mode);
        if (ret != 0) {
            return ret;
        }

        if (!IsSdcardfsUsed()) {
            ret = SetQuotaProjectId(itEntry.path(), projectId);
            if (ret != 0) {
                return ret;
            }
        }
    }

    return OK;
}

int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
                          bool fixupExisting) {
    long projectId;
    size_t pos;
    int ret = 0;
    bool sdcardfsSupport = IsSdcardfsUsed();

    // Make sure the Android/ directories exist and are setup correctly
    ret = PrepareAndroidDirs(root);
    if (ret != 0) {
        LOG(ERROR) << "Failed to prepare Android/ directories.";
        return ret;
    }

    // Now create the application-specific subdir(s)
    // path is something like /data/media/0/Android/data/com.foo/files
    // First, chop off the volume root, eg /data/media/0
    std::string pathFromRoot = path.substr(root.length());

    uid_t uid = appUid;
    gid_t gid = AID_MEDIA_RW;
    std::vector<gid_t> additionalGids;
    std::string appDir;

    // Check that the next part matches one of the allowed Android/ dirs
    if (StartsWith(pathFromRoot, kAppDataDir)) {
        appDir = kAppDataDir;
        if (!sdcardfsSupport) {
            gid = AID_EXT_DATA_RW;
            // Also add the app's own UID as a group; since apps belong to a group
            // that matches their UID, this ensures that they will always have access to
            // the files created in these dirs, even if they are created by other processes
            additionalGids.push_back(uid);
        }
    } else if (StartsWith(pathFromRoot, kAppMediaDir)) {
        appDir = kAppMediaDir;
        if (!sdcardfsSupport) {
            gid = AID_MEDIA_RW;
        }
    } else if (StartsWith(pathFromRoot, kAppObbDir)) {
        appDir = kAppObbDir;
        if (!sdcardfsSupport) {
            gid = AID_EXT_OBB_RW;
            // See comments for kAppDataDir above
            additionalGids.push_back(uid);
        }
    } else {
        LOG(ERROR) << "Invalid application directory: " << path;
        return -EINVAL;
    }

    // mode = 770, plus sticky bit on directory to inherit GID when apps
    // create subdirs
    mode_t mode = S_IRWXU | S_IRWXG | S_ISGID;
    // the project ID for application-specific directories is directly
    // derived from their uid

    // Chop off the generic application-specific part, eg /Android/data/
    // this leaves us with something like com.foo/files/
    std::string leftToCreate = pathFromRoot.substr(appDir.length());
    if (!EndsWith(leftToCreate, "/")) {
        leftToCreate += "/";
    }
    std::string pathToCreate = root + appDir;
    int depth = 0;
    // Derive initial project ID
    if (appDir == kAppDataDir || appDir == kAppMediaDir) {
        projectId = uid - AID_APP_START + PROJECT_ID_EXT_DATA_START;
    } else if (appDir == kAppObbDir) {
        projectId = uid - AID_APP_START + PROJECT_ID_EXT_OBB_START;
    }

    while ((pos = leftToCreate.find('/')) != std::string::npos) {
        std::string component = leftToCreate.substr(0, pos + 1);
        leftToCreate = leftToCreate.erase(0, pos + 1);
        pathToCreate = pathToCreate + component;

        if (appDir == kAppDataDir && depth == 1 && component == "cache/") {
            // All dirs use the "app" project ID, except for the cache dirs in
            // Android/data, eg Android/data/com.foo/cache
            // Note that this "sticks" - eg subdirs of this dir need the same
            // project ID.
            projectId = uid - AID_APP_START + PROJECT_ID_EXT_CACHE_START;
        }

        if (fixupExisting && access(pathToCreate.c_str(), F_OK) == 0) {
            // Fixup all files in this existing directory with the correct UID/GID
            // and project ID.
            ret = FixupAppDir(pathToCreate, mode, uid, gid, projectId);
        } else {
            ret = PrepareDirWithProjectId(pathToCreate, mode, uid, gid, projectId);
        }

        if (ret != 0) {
            return ret;
        }

        if (depth == 0) {
            // Set the default ACL on the top-level application-specific directories,
            // to ensure that even if applications run with a umask of 0077,
            // new directories within these directories will allow the GID
            // specified here to write; this is necessary for apps like
            // installers and MTP, that require access here.
            //
            // See man (5) acl for more details.
            ret = SetDefaultAcl(pathToCreate, mode, uid, gid, additionalGids);
            if (ret != 0) {
                return ret;
            }

            if (!sdcardfsSupport) {
                // Set project ID inheritance, so that future subdirectories inherit the
                // same project ID
                ret = SetQuotaInherit(pathToCreate);
                if (ret != 0) {
                    return ret;
                }
            }
        }

        depth++;
    }

    return OK;
}

int SetAttrs(const std::string& path, unsigned int attrs) {
    unsigned int flags;
    android::base::unique_fd fd(
            TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));

    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << path;
        return -1;
    }

    if (ioctl(fd, FS_IOC_GETFLAGS, &flags)) {
        PLOG(ERROR) << "Failed to get flags for " << path;
        return -1;
    }

    if ((flags & attrs) == attrs) return 0;
    flags |= attrs;
    if (ioctl(fd, FS_IOC_SETFLAGS, &flags)) {
        PLOG(ERROR) << "Failed to set flags for " << path << "(0x" << std::hex << attrs << ")";
        return -1;
    }
    return 0;
}

status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
                    unsigned int attrs) {
    std::lock_guard<std::mutex> lock(kSecurityLock);
    const char* cpath = path.c_str();

    char* secontext = nullptr;
    if (sehandle) {
        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) {
            setfscreatecon(secontext);
        }
    }

    int res = fs_prepare_dir(cpath, mode, uid, gid);

    if (secontext) {
        setfscreatecon(nullptr);
        freecon(secontext);
    }

    if (res) return -errno;
    if (attrs) res = SetAttrs(path, attrs);

    if (res == 0) {
        return OK;
    } else {
        return -errno;
    }
}

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;
}

status_t KillProcessesWithTmpfsMountPrefix(const std::string& path) {
    if (KillProcessesWithTmpfsMounts(path, SIGINT) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    if (KillProcessesWithTmpfsMounts(path, SIGTERM) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    if (KillProcessesWithTmpfsMounts(path, SIGKILL) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    // Send SIGKILL a second time to determine if we've
    // actually killed everyone mount
    if (KillProcessesWithTmpfsMounts(path, SIGKILL) == 0) {
        return OK;
    }
    PLOG(ERROR) << "Failed to kill processes using " << path;
    return -EBUSY;
}

status_t KillProcessesUsingPath(const std::string& path) {
    if (KillProcessesWithOpenFiles(path, SIGINT, false /* killFuseDaemon */) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    if (KillProcessesWithOpenFiles(path, SIGTERM, false /* killFuseDaemon */) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    if (KillProcessesWithOpenFiles(path, SIGKILL, false /* killFuseDaemon */) == 0) {
        return OK;
    }
    if (sSleepOnUnmount) sleep(5);

    // Send SIGKILL a second time to determine if we've
    // actually killed everyone with open files
    // This time, we also kill the FUSE daemon if found
    if (KillProcessesWithOpenFiles(path, SIGKILL, true /* killFuseDaemon */) == 0) {
        return OK;
    }
    PLOG(ERROR) << "Failed to kill processes using " << path;
    return -EBUSY;
}

status_t BindMount(const std::string& source, const std::string& target) {
    if (UnmountTree(target) < 0) {
        return -errno;
    }
    if (TEMP_FAILURE_RETRY(mount(source.c_str(), target.c_str(), nullptr, MS_BIND, nullptr)) < 0) {
        PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;
        return -errno;
    }
    return OK;
}

status_t Symlink(const std::string& target, const std::string& linkpath) {
    if (Unlink(linkpath) < 0) {
        return -errno;
    }
    if (TEMP_FAILURE_RETRY(symlink(target.c_str(), linkpath.c_str())) < 0) {
        PLOG(ERROR) << "Failed to create symlink " << linkpath << " to " << target;
        return -errno;
    }
    return OK;
}

status_t Unlink(const std::string& linkpath) {
    if (TEMP_FAILURE_RETRY(unlink(linkpath.c_str())) < 0 && errno != EINVAL && errno != ENOENT) {
        PLOG(ERROR) << "Failed to unlink " << linkpath;
        return -errno;
    }
    return OK;
}

status_t CreateDir(const std::string& dir, mode_t mode) {
    struct stat sb;
    if (TEMP_FAILURE_RETRY(stat(dir.c_str(), &sb)) == 0) {
        if (S_ISDIR(sb.st_mode)) {
            return OK;
        } else if (TEMP_FAILURE_RETRY(unlink(dir.c_str())) == -1) {
            PLOG(ERROR) << "Failed to unlink " << dir;
            return -errno;
        }
    } else if (errno != ENOENT) {
        PLOG(ERROR) << "Failed to stat " << dir;
        return -errno;
    }
    if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), mode)) == -1 && errno != EEXIST) {
        PLOG(ERROR) << "Failed to mkdir " << dir;
        return -errno;
    }
    return OK;
}

bool FindValue(const std::string& raw, const std::string& key, std::string* value) {
    auto qual = key + "=\"";
    size_t start = 0;
    while (true) {
        start = raw.find(qual, start);
        if (start == std::string::npos) return false;
        if (start == 0 || raw[start - 1] == ' ') {
            break;
        }
        start += 1;
    }
    start += qual.length();

    auto end = raw.find("\"", start);
    if (end == std::string::npos) return false;

    *value = raw.substr(start, end - start);
    return true;
}

static status_t readMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
                             std::string* fsLabel, bool untrusted) {
    fsType->clear();
    fsUuid->clear();
    fsLabel->clear();

    std::vector<std::string> cmd;
    cmd.push_back(kBlkidPath);
    cmd.push_back("-c");
    cmd.push_back("/dev/null");
    cmd.push_back("-s");
    cmd.push_back("TYPE");
    cmd.push_back("-s");
    cmd.push_back("UUID");
    cmd.push_back("-s");
    cmd.push_back("LABEL");
    cmd.push_back(path);

    std::vector<std::string> output;
    status_t res = ForkExecvp(cmd, &output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
    if (res != OK) {
        LOG(WARNING) << "blkid failed to identify " << path;
        return res;
    }

    for (const auto& line : output) {
        // Extract values from blkid output, if defined
        FindValue(line, "TYPE", fsType);
        FindValue(line, "UUID", fsUuid);
        FindValue(line, "LABEL", fsLabel);
    }

    return OK;
}

status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
                      std::string* fsLabel) {
    return readMetadata(path, fsType, fsUuid, fsLabel, false);
}

status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
                               std::string* fsLabel) {
    return readMetadata(path, fsType, fsUuid, fsLabel, true);
}

static std::vector<const char*> ConvertToArgv(const std::vector<std::string>& args) {
    std::vector<const char*> argv;
    argv.reserve(args.size() + 1);
    for (const auto& arg : args) {
        if (argv.empty()) {
            LOG(DEBUG) << arg;
        } else {
            LOG(DEBUG) << "    " << arg;
        }
        argv.emplace_back(arg.data());
    }
    argv.emplace_back(nullptr);
    return argv;
}

static status_t ReadLinesFromFdAndLog(std::vector<std::string>* output,
                                      android::base::unique_fd ufd) {
    std::unique_ptr<FILE, int (*)(FILE*)> fp(android::base::Fdopen(std::move(ufd), "r"), fclose);
    if (!fp) {
        PLOG(ERROR) << "fdopen in ReadLinesFromFdAndLog";
        return -errno;
    }
    if (output) output->clear();
    char line[1024];
    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
        LOG(DEBUG) << line;
        if (output) output->emplace_back(line);
    }
    return OK;
}

status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>* output,
                    char* context) {
    auto argv = ConvertToArgv(args);

    android::base::unique_fd pipe_read, pipe_write;
    if (!android::base::Pipe(&pipe_read, &pipe_write)) {
        PLOG(ERROR) << "Pipe in ForkExecvp";
        return -errno;
    }

    pid_t pid = fork();
    if (pid == 0) {
        if (context) {
            if (setexeccon(context)) {
                LOG(ERROR) << "Failed to setexeccon in ForkExecvp";
                abort();
            }
        }
        pipe_read.reset();
        if (dup2(pipe_write.get(), STDOUT_FILENO) == -1) {
            PLOG(ERROR) << "dup2 in ForkExecvp";
            _exit(EXIT_FAILURE);
        }
        pipe_write.reset();
        execvp(argv[0], const_cast<char**>(argv.data()));
        PLOG(ERROR) << "exec in ForkExecvp";
        _exit(EXIT_FAILURE);
    }
    if (pid == -1) {
        PLOG(ERROR) << "fork in ForkExecvp";
        return -errno;
    }

    pipe_write.reset();
    auto st = ReadLinesFromFdAndLog(output, std::move(pipe_read));
    if (st != 0) return st;

    int status;
    if (waitpid(pid, &status, 0) == -1) {
        PLOG(ERROR) << "waitpid in ForkExecvp";
        return -errno;
    }
    if (!WIFEXITED(status)) {
        LOG(ERROR) << "Process did not exit normally, status: " << status;
        return -ECHILD;
    }
    if (WEXITSTATUS(status)) {
        LOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
        return WEXITSTATUS(status);
    }
    return OK;
}

status_t ForkExecvpTimeout(const std::vector<std::string>& args, std::chrono::seconds timeout,
                           char* context) {
    int status;

    pid_t wait_timeout_pid = fork();
    if (wait_timeout_pid == 0) {
        pid_t pid = ForkExecvpAsync(args, context);
        if (pid == -1) {
            _exit(EXIT_FAILURE);
        }
        pid_t timer_pid = fork();
        if (timer_pid == 0) {
            std::this_thread::sleep_for(timeout);
            _exit(ETIMEDOUT);
        }
        if (timer_pid == -1) {
            PLOG(ERROR) << "fork in ForkExecvpAsync_timeout";
            kill(pid, SIGTERM);
            _exit(EXIT_FAILURE);
        }
        pid_t finished = wait(&status);
        if (finished == pid) {
            kill(timer_pid, SIGTERM);
        } else {
            kill(pid, SIGTERM);
        }
        if (!WIFEXITED(status)) {
            _exit(ECHILD);
        }
        _exit(WEXITSTATUS(status));
    }
    if (waitpid(wait_timeout_pid, &status, 0) == -1) {
        PLOG(ERROR) << "waitpid in ForkExecvpAsync_timeout";
        return -errno;
    }
    if (!WIFEXITED(status)) {
        LOG(ERROR) << "Process did not exit normally, status: " << status;
        return -ECHILD;
    }
    if (WEXITSTATUS(status)) {
        LOG(ERROR) << "Process exited with code: " << WEXITSTATUS(status);
        return WEXITSTATUS(status);
    }
    return OK;
}

pid_t ForkExecvpAsync(const std::vector<std::string>& args, char* context) {
    auto argv = ConvertToArgv(args);

    pid_t pid = fork();
    if (pid == 0) {
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        if (context) {
            if (setexeccon(context)) {
                LOG(ERROR) << "Failed to setexeccon in ForkExecvpAsync";
                abort();
            }
        }

        execvp(argv[0], const_cast<char**>(argv.data()));
        PLOG(ERROR) << "exec in ForkExecvpAsync";
        _exit(EXIT_FAILURE);
    }
    if (pid == -1) {
        PLOG(ERROR) << "fork in ForkExecvpAsync";
        return -1;
    }
    return pid;
}

status_t ReadRandomBytes(size_t bytes, std::string& out) {
    out.resize(bytes);
    return ReadRandomBytes(bytes, &out[0]);
}

status_t ReadRandomBytes(size_t bytes, char* buf) {
    int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
    if (fd == -1) {
        return -errno;
    }

    ssize_t n;
    while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], bytes))) > 0) {
        bytes -= n;
        buf += n;
    }
    close(fd);

    if (bytes == 0) {
        return OK;
    } else {
        return -EIO;
    }
}

status_t GenerateRandomUuid(std::string& out) {
    status_t res = ReadRandomBytes(16, out);
    if (res == OK) {
        out[6] &= 0x0f; /* clear version        */
        out[6] |= 0x40; /* set to version 4     */
        out[8] &= 0x3f; /* clear variant        */
        out[8] |= 0x80; /* set to IETF variant  */
    }
    return res;
}

status_t HexToStr(const std::string& hex, std::string& str) {
    str.clear();
    bool even = true;
    char cur = 0;
    for (size_t i = 0; i < hex.size(); i++) {
        int val = 0;
        switch (hex[i]) {
            // clang-format off
            case ' ': case '-': case ':': continue;
            case 'f': case 'F': val = 15; break;
            case 'e': case 'E': val = 14; break;
            case 'd': case 'D': val = 13; break;
            case 'c': case 'C': val = 12; break;
            case 'b': case 'B': val = 11; break;
            case 'a': case 'A': val = 10; break;
            case '9': val = 9; break;
            case '8': val = 8; break;
            case '7': val = 7; break;
            case '6': val = 6; break;
            case '5': val = 5; break;
            case '4': val = 4; break;
            case '3': val = 3; break;
            case '2': val = 2; break;
            case '1': val = 1; break;
            case '0': val = 0; break;
            default: return -EINVAL;
                // clang-format on
        }

        if (even) {
            cur = val << 4;
        } else {
            cur += val;
            str.push_back(cur);
            cur = 0;
        }
        even = !even;
    }
    return even ? OK : -EINVAL;
}

static const char* kLookup = "0123456789abcdef";

status_t StrToHex(const std::string& str, std::string& hex) {
    hex.clear();
    for (size_t i = 0; i < str.size(); i++) {
        hex.push_back(kLookup[(str[i] & 0xF0) >> 4]);
        hex.push_back(kLookup[str[i] & 0x0F]);
    }
    return OK;
}

status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex) {
    hex.clear();
    for (size_t i = 0; i < str.size(); i++) {
        hex.push_back(kLookup[(str.data()[i] & 0xF0) >> 4]);
        hex.push_back(kLookup[str.data()[i] & 0x0F]);
    }
    return OK;
}

status_t NormalizeHex(const std::string& in, std::string& out) {
    std::string tmp;
    if (HexToStr(in, tmp)) {
        return -EINVAL;
    }
    return StrToHex(tmp, out);
}

status_t GetBlockDevSize(int fd, uint64_t* size) {
    if (ioctl(fd, BLKGETSIZE64, size)) {
        return -errno;
    }

    return OK;
}

status_t GetBlockDevSize(const std::string& path, uint64_t* size) {
    int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
    status_t res = OK;

    if (fd < 0) {
        return -errno;
    }

    res = GetBlockDevSize(fd, size);

    close(fd);

    return res;
}

status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec) {
    uint64_t size;
    status_t res = GetBlockDevSize(path, &size);

    if (res != OK) {
        return res;
    }

    *nr_sec = size / 512;

    return OK;
}

uint64_t GetFreeBytes(const std::string& path) {
    struct statvfs sb;
    if (statvfs(path.c_str(), &sb) == 0) {
        return (uint64_t)sb.f_bavail * sb.f_frsize;
    } else {
        return -1;
    }
}

// TODO: borrowed from frameworks/native/libs/diskusage/ which should
// eventually be migrated into system/
static int64_t stat_size(struct stat* s) {
    int64_t blksize = s->st_blksize;
    // count actual blocks used instead of nominal file size
    int64_t size = s->st_blocks * 512;

    if (blksize) {
        /* round up to filesystem block size */
        size = (size + blksize - 1) & (~(blksize - 1));
    }

    return size;
}

// TODO: borrowed from frameworks/native/libs/diskusage/ which should
// eventually be migrated into system/
int64_t calculate_dir_size(int dfd) {
    int64_t size = 0;
    struct stat s;
    DIR* d;
    struct dirent* de;

    d = fdopendir(dfd);
    if (d == NULL) {
        close(dfd);
        return 0;
    }

    while ((de = readdir(d))) {
        const char* name = de->d_name;
        if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
            size += stat_size(&s);
        }
        if (de->d_type == DT_DIR) {
            int subfd;

            /* always skip "." and ".." */
            if (IsDotOrDotDot(*de)) continue;

            subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
            if (subfd >= 0) {
                size += calculate_dir_size(subfd);
            }
        }
    }
    closedir(d);
    return size;
}

uint64_t GetTreeBytes(const std::string& path) {
    int dirfd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC);
    if (dirfd < 0) {
        PLOG(WARNING) << "Failed to open " << path;
        return -1;
    } else {
        return calculate_dir_size(dirfd);
    }
}

// TODO: Use a better way to determine if it's media provider app.
bool IsFuseDaemon(const pid_t pid) {
    auto path = StringPrintf("/proc/%d/mounts", pid);
    char* tmp;
    if (lgetfilecon(path.c_str(), &tmp) < 0) {
        return false;
    }
    bool result = android::base::StartsWith(tmp, kMediaProviderAppCtx)
            || android::base::StartsWith(tmp, kMediaProviderCtx);
    freecon(tmp);
    return result;
}

bool IsFilesystemSupported(const std::string& fsType) {
    std::string supported;
    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);
}

status_t WipeBlockDevice(const std::string& path) {
    status_t res = -1;
    const char* c_path = path.c_str();
    uint64_t range[2] = {0, 0};

    int fd = TEMP_FAILURE_RETRY(open(c_path, O_RDWR | O_CLOEXEC));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << path;
        goto done;
    }

    if (GetBlockDevSize(fd, &range[1]) != OK) {
        PLOG(ERROR) << "Failed to determine size of " << path;
        goto done;
    }

    LOG(INFO) << "About to discard " << range[1] << " on " << path;
    if (ioctl(fd, BLKDISCARD, &range) == 0) {
        LOG(INFO) << "Discard success on " << path;
        res = 0;
    } else {
        PLOG(ERROR) << "Discard failure on " << path;
    }

done:
    close(fd);
    return res;
}

static bool isValidFilename(const std::string& name) {
    if (name.empty() || (name == ".") || (name == "..") || (name.find('/') != std::string::npos)) {
        return false;
    } else {
        return true;
    }
}

std::string BuildKeyPath(const std::string& partGuid) {
    return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
}

std::string BuildDataSystemLegacyPath(userid_t userId) {
    return StringPrintf("%s/system/users/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataSystemCePath(userid_t userId) {
    return StringPrintf("%s/system_ce/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataSystemDePath(userid_t userId) {
    return StringPrintf("%s/system_de/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataMiscLegacyPath(userid_t userId) {
    return StringPrintf("%s/misc/user/%u", BuildDataPath("").c_str(), userId);
}

// Keep in sync with installd (frameworks/native/cmds/installd/utils.h)
std::string BuildDataProfilesDePath(userid_t userId) {
    return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataVendorCePath(userid_t userId) {
    return StringPrintf("%s/vendor_ce/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataVendorDePath(userid_t userId) {
    return StringPrintf("%s/vendor_de/%u", BuildDataPath("").c_str(), userId);
}

std::string BuildDataPath(const std::string& volumeUuid) {
    // TODO: unify with installd path generation logic
    if (volumeUuid.empty()) {
        return "/data";
    } else {
        CHECK(isValidFilename(volumeUuid));
        return StringPrintf("/mnt/expand/%s", volumeUuid.c_str());
    }
}

std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userId) {
    // TODO: unify with installd path generation logic
    std::string data(BuildDataPath(volumeUuid));
    return StringPrintf("%s/media/%u", data.c_str(), userId);
}

std::string BuildDataMiscCePath(const std::string& volumeUuid, userid_t userId) {
    return StringPrintf("%s/misc_ce/%u", BuildDataPath(volumeUuid).c_str(), userId);
}

std::string BuildDataMiscDePath(const std::string& volumeUuid, userid_t userId) {
    return StringPrintf("%s/misc_de/%u", BuildDataPath(volumeUuid).c_str(), userId);
}

std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userId) {
    // TODO: unify with installd path generation logic
    std::string data(BuildDataPath(volumeUuid));
    if (volumeUuid.empty() && userId == 0) {
        std::string legacy = StringPrintf("%s/data", data.c_str());
        struct stat sb;
        if (lstat(legacy.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
            /* /data/data is dir, return /data/data for legacy system */
            return legacy;
        }
    }
    return StringPrintf("%s/user/%u", data.c_str(), userId);
}

std::string BuildDataUserDePath(const std::string& volumeUuid, userid_t userId) {
    // TODO: unify with installd path generation logic
    std::string data(BuildDataPath(volumeUuid));
    return StringPrintf("%s/user_de/%u", data.c_str(), userId);
}

dev_t GetDevice(const std::string& path) {
    struct stat sb;
    if (stat(path.c_str(), &sb)) {
        PLOG(WARNING) << "Failed to stat " << path;
        return 0;
    } else {
        return sb.st_dev;
    }
}

// Returns true if |path1| names the same existing file or directory as |path2|.
bool IsSameFile(const std::string& path1, const std::string& path2) {
    struct stat stbuf1, stbuf2;
    if (stat(path1.c_str(), &stbuf1) != 0 || stat(path2.c_str(), &stbuf2) != 0) return false;
    return stbuf1.st_ino == stbuf2.st_ino && stbuf1.st_dev == stbuf2.st_dev;
}

status_t RestoreconRecursive(const std::string& path) {
    LOG(DEBUG) << "Starting restorecon of " << path;

    static constexpr const char* kRestoreconString = "selinux.restorecon_recursive";

    android::base::SetProperty(kRestoreconString, "");
    android::base::SetProperty(kRestoreconString, path);

    android::base::WaitForProperty(kRestoreconString, path);

    LOG(DEBUG) << "Finished restorecon of " << path;
    return OK;
}

bool Readlinkat(int dirfd, const std::string& path, std::string* result) {
    // Shamelessly borrowed from android::base::Readlink()
    result->clear();

    // Most Linux file systems (ext2 and ext4, say) limit symbolic links to
    // 4095 bytes. Since we'll copy out into the string anyway, it doesn't
    // waste memory to just start there. We add 1 so that we can recognize
    // whether it actually fit (rather than being truncated to 4095).
    std::vector<char> buf(4095 + 1);
    while (true) {
        ssize_t size = readlinkat(dirfd, path.c_str(), &buf[0], buf.size());
        // Unrecoverable error?
        if (size == -1) return false;
        // It fit! (If size == buf.size(), it may have been truncated.)
        if (static_cast<size_t>(size) < buf.size()) {
            result->assign(&buf[0], size);
            return true;
        }
        // Double our buffer and try again.
        buf.resize(buf.size() * 2);
    }
}

static unsigned int GetMajorBlockVirtioBlk() {
    std::string devices;
    if (!ReadFileToString(kProcDevices, &devices)) {
        PLOG(ERROR) << "Unable to open /proc/devices";
        return 0;
    }

    bool blockSection = false;
    for (auto line : android::base::Split(devices, "\n")) {
        if (line == "Block devices:") {
            blockSection = true;
        } else if (line == "Character devices:") {
            blockSection = false;
        } else if (blockSection) {
            auto tokens = android::base::Split(line, " ");
            if (tokens.size() == 2 && tokens[1] == "virtblk") {
                return std::stoul(tokens[0]);
            }
        }
    }

    return 0;
}

bool IsVirtioBlkDevice(unsigned int major) {
    // Most virtualized platforms expose block devices with the virtio-blk
    // block device driver. Unfortunately, this driver does not use a fixed
    // major number, but relies on the kernel to assign one from a specific
    // range of block majors, which are allocated for "LOCAL/EXPERIMENAL USE"
    // per Documentation/devices.txt. This is true even for the latest Linux
    // kernel (4.4; see init() in drivers/block/virtio_blk.c).
    static unsigned int kMajorBlockVirtioBlk = GetMajorBlockVirtioBlk();
    return kMajorBlockVirtioBlk && major == kMajorBlockVirtioBlk;
}

status_t UnmountTree(const std::string& mountPoint) {
    if (TEMP_FAILURE_RETRY(umount2(mountPoint.c_str(), MNT_DETACH)) < 0 && errno != EINVAL &&
        errno != ENOENT) {
        PLOG(ERROR) << "Failed to unmount " << mountPoint;
        return -errno;
    }
    return OK;
}

bool IsDotOrDotDot(const struct dirent& ent) {
    return strcmp(ent.d_name, ".") == 0 || strcmp(ent.d_name, "..") == 0;
}

static status_t delete_dir_contents(DIR* dir) {
    // Shamelessly borrowed from android::installd
    int dfd = dirfd(dir);
    if (dfd < 0) {
        return -errno;
    }

    status_t result = OK;
    struct dirent* de;
    while ((de = readdir(dir))) {
        const char* name = de->d_name;
        if (de->d_type == DT_DIR) {
            /* always skip "." and ".." */
            if (IsDotOrDotDot(*de)) continue;

            android::base::unique_fd subfd(
                openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
            if (subfd.get() == -1) {
                PLOG(ERROR) << "Couldn't openat " << name;
                result = -errno;
                continue;
            }
            std::unique_ptr<DIR, decltype(&closedir)> subdirp(
                android::base::Fdopendir(std::move(subfd)), closedir);
            if (!subdirp) {
                PLOG(ERROR) << "Couldn't fdopendir " << name;
                result = -errno;
                continue;
            }
            result = delete_dir_contents(subdirp.get());
            if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
                PLOG(ERROR) << "Couldn't unlinkat " << name;
                result = -errno;
            }
        } else {
            if (unlinkat(dfd, name, 0) < 0) {
                PLOG(ERROR) << "Couldn't unlinkat " << name;
                result = -errno;
            }
        }
    }
    return result;
}

status_t DeleteDirContentsAndDir(const std::string& pathname) {
    status_t res = DeleteDirContents(pathname);
    if (res < 0) {
        return res;
    }
    if (TEMP_FAILURE_RETRY(rmdir(pathname.c_str())) < 0 && errno != ENOENT) {
        PLOG(ERROR) << "rmdir failed on " << pathname;
        return -errno;
    }
    LOG(VERBOSE) << "Success: rmdir on " << pathname;
    return OK;
}

status_t DeleteDirContents(const std::string& pathname) {
    // Shamelessly borrowed from android::installd
    std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir(pathname.c_str()), closedir);
    if (!dirp) {
        if (errno == ENOENT) {
            return OK;
        }
        PLOG(ERROR) << "Failed to opendir " << pathname;
        return -errno;
    }
    return delete_dir_contents(dirp.get());
}

// TODO(118708649): fix duplication with init/util.h
status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout) {
    android::base::Timer t;
    while (t.duration() < timeout) {
        struct stat sb;
        if (stat(filename, &sb) != -1) {
            LOG(INFO) << "wait for '" << filename << "' took " << t;
            return 0;
        }
        std::this_thread::sleep_for(10ms);
    }
    LOG(WARNING) << "wait for '" << filename << "' timed out and took " << t;
    return -1;
}

bool pathExists(const std::string& path) {
    return access(path.c_str(), F_OK) == 0;
}

bool FsyncDirectory(const std::string& dirname) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dirname.c_str(), O_RDONLY | O_CLOEXEC)));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << dirname;
        return false;
    }
    if (fsync(fd) == -1) {
        if (errno == EROFS || errno == EINVAL) {
            PLOG(WARNING) << "Skip fsync " << dirname
                          << " on a file system does not support synchronization";
        } else {
            PLOG(ERROR) << "Failed to fsync " << dirname;
            return false;
        }
    }
    return true;
}

bool FsyncParentDirectory(const std::string& path) {
    return FsyncDirectory(android::base::Dirname(path));
}

// Creates all parent directories of |path| that don't already exist.  Assigns
// the specified |mode| to any new directories, and also fsync()s their parent
// directories so that the new directories get written to disk right away.
bool MkdirsSync(const std::string& path, mode_t mode) {
    if (path[0] != '/') {
        LOG(ERROR) << "MkdirsSync() needs an absolute path, but got " << path;
        return false;
    }
    std::vector<std::string> components = android::base::Split(android::base::Dirname(path), "/");

    std::string current_dir = "/";
    for (const std::string& component : components) {
        if (component.empty()) continue;

        std::string parent_dir = current_dir;
        if (current_dir != "/") current_dir += "/";
        current_dir += component;

        if (!pathExists(current_dir)) {
            if (mkdir(current_dir.c_str(), mode) != 0) {
                PLOG(ERROR) << "Failed to create " << current_dir;
                return false;
            }
            if (!FsyncDirectory(parent_dir)) return false;
            LOG(DEBUG) << "Created directory " << current_dir;
        }
    }
    return true;
}

bool writeStringToFile(const std::string& payload, const std::string& filename) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
        open(filename.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0666)));
    if (fd == -1) {
        PLOG(ERROR) << "Failed to open " << filename;
        return false;
    }
    if (!android::base::WriteStringToFd(payload, fd)) {
        PLOG(ERROR) << "Failed to write to " << filename;
        unlink(filename.c_str());
        return false;
    }
    // fsync as close won't guarantee flush data
    // see close(2), fsync(2) and b/68901441
    if (fsync(fd) == -1) {
        if (errno == EROFS || errno == EINVAL) {
            PLOG(WARNING) << "Skip fsync " << filename
                          << " on a file system does not support synchronization";
        } else {
            PLOG(ERROR) << "Failed to fsync " << filename;
            unlink(filename.c_str());
            return false;
        }
    }
    return true;
}

status_t AbortFuseConnections() {
    namespace fs = std::filesystem;

    for (const auto& itEntry : fs::directory_iterator("/sys/fs/fuse/connections")) {
        std::string fsPath = itEntry.path().string() + "/filesystem";
        std::string fs;

        // Virtiofs is on top of fuse and there isn't any user space daemon.
        // Android user space doesn't manage it.
        if (android::base::ReadFileToString(fsPath, &fs, false) &&
            android::base::Trim(fs) == "virtiofs") {
            LOG(INFO) << "Ignore virtiofs connection entry " << itEntry.path().string();
            continue;
        }

        std::string abortPath = itEntry.path().string() + "/abort";
        LOG(DEBUG) << "Aborting fuse connection entry " << abortPath;
        bool ret = writeStringToFile("1", abortPath);
        if (!ret) {
            LOG(WARNING) << "Failed to write to " << abortPath;
        }
    }

    return OK;
}

status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
    if (access(path.c_str(), F_OK) != 0) {
        PLOG(WARNING) << "Dir does not exist: " << path;
        if (fs_prepare_dir(path.c_str(), mode, uid, gid) != 0) {
            return -errno;
        }
    }
    return OK;
}

// Gets the sysfs path for parameters of the backing device info (bdi)
static std::string getBdiPathForMount(const std::string& mount) {
    // First figure out MAJOR:MINOR of mount. Simplest way is to stat the path.
    struct stat info;
    if (stat(mount.c_str(), &info) != 0) {
        PLOG(ERROR) << "Failed to stat " << mount;
        return "";
    }
    unsigned int maj = major(info.st_dev);
    unsigned int min = minor(info.st_dev);

    return StringPrintf("/sys/class/bdi/%u:%u", maj, min);
}

// Configures max_ratio for the FUSE filesystem.
void ConfigureMaxDirtyRatioForFuse(const std::string& fuse_mount, unsigned int max_ratio) {
    LOG(INFO) << "Configuring max_ratio of " << fuse_mount << " fuse filesystem to " << max_ratio;
    if (max_ratio > 100) {
        LOG(ERROR) << "Invalid max_ratio: " << max_ratio;
        return;
    }
    std::string fuseBdiPath = getBdiPathForMount(fuse_mount);
    if (fuseBdiPath == "") {
        return;
    }
    std::string max_ratio_file = StringPrintf("%s/max_ratio", fuseBdiPath.c_str());
    unique_fd fd(TEMP_FAILURE_RETRY(open(max_ratio_file.c_str(), O_WRONLY | O_CLOEXEC)));
    if (fd.get() == -1) {
        PLOG(ERROR) << "Failed to open " << max_ratio_file;
        return;
    }
    LOG(INFO) << "Writing " << max_ratio << " to " << max_ratio_file;
    if (!WriteStringToFd(std::to_string(max_ratio), fd)) {
        PLOG(ERROR) << "Failed to write to " << max_ratio_file;
    }
}

// Configures read ahead property of the fuse filesystem with the mount point |fuse_mount| by
// writing |read_ahead_kb| to the /sys/class/bdi/MAJOR:MINOR/read_ahead_kb.
void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb) {
    LOG(INFO) << "Configuring read_ahead of " << fuse_mount << " fuse filesystem to "
              << read_ahead_kb << "kb";
    std::string fuseBdiPath = getBdiPathForMount(fuse_mount);
    if (fuseBdiPath == "") {
        return;
    }
    // We found the bdi path for our filesystem, time to configure read ahead!
    std::string read_ahead_file = StringPrintf("%s/read_ahead_kb", fuseBdiPath.c_str());
    unique_fd fd(TEMP_FAILURE_RETRY(open(read_ahead_file.c_str(), O_WRONLY | O_CLOEXEC)));
    if (fd.get() == -1) {
        PLOG(ERROR) << "Failed to open " << read_ahead_file;
        return;
    }
    LOG(INFO) << "Writing " << read_ahead_kb << " to " << read_ahead_file;
    if (!WriteStringToFd(std::to_string(read_ahead_kb), fd)) {
        PLOG(ERROR) << "Failed to write to " << read_ahead_file;
    }
}

status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
                       const std::string& relative_upper_path, android::base::unique_fd* fuse_fd) {
    std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));
    std::string fuse_path(
            StringPrintf("%s/%s", pre_fuse_path.c_str(), relative_upper_path.c_str()));

    std::string pre_pass_through_path(StringPrintf("/mnt/pass_through/%d", user_id));
    std::string pass_through_path(
            StringPrintf("%s/%s", pre_pass_through_path.c_str(), relative_upper_path.c_str()));

    // Ensure that /mnt/user is 0700. With FUSE, apps don't need access to /mnt/user paths directly.
    // Without FUSE however, apps need /mnt/user access so /mnt/user in init.rc is 0755 until here
    auto result = PrepareDir("/mnt/user", 0750, AID_ROOT, AID_MEDIA_RW);
    if (result != android::OK) {
        PLOG(ERROR) << "Failed to prepare directory /mnt/user";
        return -1;
    }

    // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
    // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
    // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
    // These bits should be consistent with what is set in zygote in
    // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
    result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
                             multiuser_get_uid(user_id, AID_EVERYBODY));
    if (result != android::OK) {
        PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
        return -1;
    }

    result = PrepareDir(fuse_path, 0700, AID_ROOT, AID_ROOT);
    if (result != android::OK) {
        PLOG(ERROR) << "Failed to prepare directory " << fuse_path;
        return -1;
    }

    result = PrepareDir(pre_pass_through_path, 0710, AID_ROOT, AID_MEDIA_RW);
    if (result != android::OK) {
        PLOG(ERROR) << "Failed to prepare directory " << pre_pass_through_path;
        return -1;
    }

    result = PrepareDir(pass_through_path, 0710, AID_ROOT, AID_MEDIA_RW);
    if (result != android::OK) {
        PLOG(ERROR) << "Failed to prepare directory " << pass_through_path;
        return -1;
    }

    if (relative_upper_path == "emulated") {
        std::string linkpath(StringPrintf("/mnt/user/%d/self", user_id));
        result = PrepareDir(linkpath, 0755, AID_ROOT, AID_ROOT);
        if (result != android::OK) {
            PLOG(ERROR) << "Failed to prepare directory " << linkpath;
            return -1;
        }
        linkpath += "/primary";
        Symlink("/storage/emulated/" + std::to_string(user_id), linkpath);

        std::string pass_through_linkpath(StringPrintf("/mnt/pass_through/%d/self", user_id));
        result = PrepareDir(pass_through_linkpath, 0710, AID_ROOT, AID_MEDIA_RW);
        if (result != android::OK) {
            PLOG(ERROR) << "Failed to prepare directory " << pass_through_linkpath;
            return -1;
        }
        pass_through_linkpath += "/primary";
        Symlink("/storage/emulated/" + std::to_string(user_id), pass_through_linkpath);
    }

    // Open fuse fd.
    fuse_fd->reset(open("/dev/fuse", O_RDWR | O_CLOEXEC));
    if (fuse_fd->get() == -1) {
        PLOG(ERROR) << "Failed to open /dev/fuse";
        return -1;
    }

    // Note: leaving out default_permissions since we don't want kernel to do lower filesystem
    // permission checks before routing to FUSE daemon.
    const auto opts = StringPrintf(
        "fd=%i,"
        "rootmode=40000,"
        "allow_other,"
        "user_id=0,group_id=0,",
        fuse_fd->get());

    result = TEMP_FAILURE_RETRY(mount("/dev/fuse", fuse_path.c_str(), "fuse",
                                      MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME | MS_LAZYTIME,
                                      opts.c_str()));
    if (result != 0) {
        PLOG(ERROR) << "Failed to mount " << fuse_path;
        return -errno;
    }

    if (IsSdcardfsUsed()) {
        std::string sdcardfs_path(
                StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));

        LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
        return BindMount(sdcardfs_path, pass_through_path);
    } else {
        LOG(INFO) << "Bind mounting " << absolute_lower_path << " to " << pass_through_path;
        return BindMount(absolute_lower_path, pass_through_path);
    }
}

status_t UnmountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
                         const std::string& relative_upper_path) {
    std::string fuse_path(StringPrintf("/mnt/user/%d/%s", user_id, relative_upper_path.c_str()));
    std::string pass_through_path(
            StringPrintf("/mnt/pass_through/%d/%s", user_id, relative_upper_path.c_str()));

    LOG(INFO) << "Unmounting fuse path " << fuse_path;
    android::status_t result = ForceUnmount(fuse_path);
    if (result != android::OK) {
        // TODO(b/135341433): MNT_DETACH is needed for fuse because umount2 can fail with EBUSY.
        // Figure out why we get EBUSY and remove this special casing if possible.
        PLOG(ERROR) << "Failed to unmount. Trying MNT_DETACH " << fuse_path << " ...";
        if (umount2(fuse_path.c_str(), UMOUNT_NOFOLLOW | MNT_DETACH) && errno != EINVAL &&
            errno != ENOENT) {
            PLOG(ERROR) << "Failed to unmount with MNT_DETACH " << fuse_path;
            return -errno;
        }
        result = android::OK;
    }
    rmdir(fuse_path.c_str());

    LOG(INFO) << "Unmounting pass_through_path " << pass_through_path;
    auto status = ForceUnmount(pass_through_path);
    if (status != android::OK) {
        LOG(ERROR) << "Failed to unmount " << pass_through_path;
    }
    rmdir(pass_through_path.c_str());

    return result;
}

status_t PrepareAndroidDirs(const std::string& volumeRoot) {
    std::string androidDir = volumeRoot + kAndroidDir;
    std::string androidDataDir = volumeRoot + kAppDataDir;
    std::string androidObbDir = volumeRoot + kAppObbDir;
    std::string androidMediaDir = volumeRoot + kAppMediaDir;

    bool useSdcardFs = IsSdcardfsUsed();

    // mode 0771 + sticky bit for inheriting GIDs
    mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH | S_ISGID;
    if (fs_prepare_dir(androidDir.c_str(), mode, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
        PLOG(ERROR) << "Failed to create " << androidDir;
        return -errno;
    }

    gid_t dataGid = useSdcardFs ? AID_MEDIA_RW : AID_EXT_DATA_RW;
    if (fs_prepare_dir(androidDataDir.c_str(), mode, AID_MEDIA_RW, dataGid) != 0) {
        PLOG(ERROR) << "Failed to create " << androidDataDir;
        return -errno;
    }

    gid_t obbGid = useSdcardFs ? AID_MEDIA_RW : AID_EXT_OBB_RW;
    if (fs_prepare_dir(androidObbDir.c_str(), mode, AID_MEDIA_RW, obbGid) != 0) {
        PLOG(ERROR) << "Failed to create " << androidObbDir;
        return -errno;
    }
    // Some other apps, like installers, have write access to the OBB directory
    // to pre-download them. To make sure newly created folders in this directory
    // have the right permissions, set a default ACL.
    SetDefaultAcl(androidObbDir, mode, AID_MEDIA_RW, obbGid, {});

    if (fs_prepare_dir(androidMediaDir.c_str(), mode, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
        PLOG(ERROR) << "Failed to create " << androidMediaDir;
        return -errno;
    }

    return OK;
}

namespace ab = android::base;

static ab::unique_fd openDirFd(int parentFd, const char* name) {
    return ab::unique_fd{::openat(parentFd, name, O_CLOEXEC | O_DIRECTORY | O_PATH | O_NOFOLLOW)};
}

static ab::unique_fd openAbsolutePathFd(std::string_view path) {
    if (path.empty() || path[0] != '/') {
        errno = EINVAL;
        return {};
    }
    if (path == "/") {
        return openDirFd(-1, "/");
    }

    // first component is special - it includes the leading slash
    auto next = path.find('/', 1);
    auto component = std::string(path.substr(0, next));
    if (component == "..") {
        errno = EINVAL;
        return {};
    }
    auto fd = openDirFd(-1, component.c_str());
    if (!fd.ok()) {
        return fd;
    }
    path.remove_prefix(std::min(next + 1, path.size()));
    while (next != path.npos && !path.empty()) {
        next = path.find('/');
        component.assign(path.substr(0, next));
        fd = openDirFd(fd, component.c_str());
        if (!fd.ok()) {
            return fd;
        }
        path.remove_prefix(std::min(next + 1, path.size()));
    }
    return fd;
}

std::pair<android::base::unique_fd, std::string> OpenDirInProcfs(std::string_view path) {
    auto fd = openAbsolutePathFd(path);
    if (!fd.ok()) {
        return {};
    }

    auto linkPath = std::string("/proc/self/fd/") += std::to_string(fd.get());
    return {std::move(fd), std::move(linkPath)};
}

bool IsFuseBpfEnabled() {
    std::string bpf_override = android::base::GetProperty("persist.sys.fuse.bpf.override", "");
    if (bpf_override == "true") {
        return true;
    } else if (bpf_override == "false") {
        return false;
    }
    return base::GetBoolProperty("ro.fuse.bpf.enabled", false);
}

}  // namespace vold
}  // namespace android
