diff --git a/native/src/base/files.cpp b/native/src/base/files.cpp index 884ccae4c..4012d2e6f 100644 --- a/native/src/base/files.cpp +++ b/native/src/base/files.cpp @@ -345,45 +345,6 @@ void parse_prop_file(const char *file, const functionmnt_freq, &e->mnt_passno) == 2) { - e->mnt_fsname = &buf[fsname0]; - buf[fsname1] = '\0'; - e->mnt_dir = &buf[dir0]; - buf[dir1] = '\0'; - e->mnt_type = &buf[type0]; - buf[type1] = '\0'; - e->mnt_opts = &buf[opts0]; - buf[opts1] = '\0'; - return e; - } - } - return nullptr; -} - -void parse_mnt(const char *file, const function &fn) { - auto fp = sFILE(setmntent(file, "re"), endmntent); - if (fp) { - mntent mentry{}; - char buf[4096]; - // getmntent_r from system's libc.so is broken on old platform - // use the compat one instead - while (compat_getmntent_r(fp.get(), &mentry, buf, sizeof(buf))) { - if (!fn(&mentry)) - break; - } - } -} - std::vector parse_mount_info(const char *pid) { char buf[PATH_MAX] = {}; ssprintf(buf, sizeof(buf), "/proc/%s/mountinfo", pid); diff --git a/native/src/base/files.hpp b/native/src/base/files.hpp index 0244d5889..ea27cfd75 100644 --- a/native/src/base/files.hpp +++ b/native/src/base/files.hpp @@ -106,7 +106,6 @@ void parse_prop_file(const char *file, void frm_rf(int dirfd); void clone_dir(int src, int dest); std::vector parse_mount_info(const char *pid); -void parse_mnt(const char *file, const std::function &fn); std::string find_apk_path(const char *pkg); using sFILE = std::unique_ptr; diff --git a/native/src/init/mount.cpp b/native/src/init/mount.cpp index 52dc23c1d..42095e29f 100644 --- a/native/src/init/mount.cpp +++ b/native/src/init/mount.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -91,23 +92,17 @@ static int64_t setup_block() { static void switch_root(const string &path) { LOGD("Switch root to %s\n", path.data()); int root = xopen("/", O_RDONLY); - vector mounts; - parse_mnt("/proc/mounts", [&](mntent *me) { - // Skip root and self - if (me->mnt_dir == "/"sv || me->mnt_dir == path) - return true; - // Do not include subtrees - for (const auto &m : mounts) { - if (strncmp(me->mnt_dir, m.data(), m.length()) == 0 && me->mnt_dir[m.length()] == '/') - return true; + for (set> mounts; auto &info : parse_mount_info("self")) { + if (info.target == "/" || info.target == path) + continue; + if (auto last_mount = mounts.upper_bound(info.target); + last_mount != mounts.end() && info.target.starts_with(*last_mount + '/')) { + continue; } - mounts.emplace_back(me->mnt_dir); - return true; - }); - for (auto &dir : mounts) { - auto new_path = path + dir; + mounts.emplace(info.target); + auto new_path = path + info.target; xmkdir(new_path.data(), 0755); - xmount(dir.data(), new_path.data(), nullptr, MS_MOVE, nullptr); + xmount(info.target.data(), new_path.data(), nullptr, MS_MOVE, nullptr); } chdir(path.data()); xmount(path.data(), "/", nullptr, MS_MOVE, nullptr);