Clean rootfs in switch_root
This commit is contained in:
parent
b28668e18d
commit
dbfde74c1e
@ -478,7 +478,7 @@ static void collect_modules() {
|
||||
fd_pathat(modfd, "uninstall.sh", buf, sizeof(buf));
|
||||
if (access(buf, F_OK) == 0)
|
||||
exec_script(buf);
|
||||
frm_rf(modfd);
|
||||
frm_rf(xdup(modfd));
|
||||
unlinkat(dfd, entry->d_name, AT_REMOVEDIR);
|
||||
continue;
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ if (!is_lnk("/" #name) && read_dt_fstab(cmd, #name)) { \
|
||||
|
||||
static void switch_root(const string &path) {
|
||||
LOGD("Switch root to %s\n", path.data());
|
||||
int root = xopen("/", O_RDONLY);
|
||||
vector<string> mounts;
|
||||
parse_mnt("/proc/mounts", [&](mntent *me) {
|
||||
// Skip root and self
|
||||
@ -142,6 +143,9 @@ static void switch_root(const string &path) {
|
||||
chdir(path.data());
|
||||
xmount(path.data(), "/", nullptr, MS_MOVE, nullptr);
|
||||
chroot(".");
|
||||
|
||||
LOGD("Cleaning rootfs\n");
|
||||
frm_rf(root);
|
||||
}
|
||||
|
||||
static void mount_persist(const char *dev_base, const char *mnt_base) {
|
||||
@ -219,11 +223,6 @@ void SARInit::early_mount() {
|
||||
|
||||
backup_files();
|
||||
|
||||
LOGD("Cleaning rootfs\n");
|
||||
int root = xopen("/", O_RDONLY | O_CLOEXEC);
|
||||
frm_rf(root, { "proc", "sys", "dev" });
|
||||
close(root);
|
||||
|
||||
mount_system_root();
|
||||
switch_root("/system_root");
|
||||
|
||||
|
@ -47,27 +47,15 @@ int mkdirs(const char *pathname, mode_t mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_excl(initializer_list<const char *> excl, const char *name) {
|
||||
for (auto item : excl)
|
||||
if (strcmp(item, name) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void post_order_walk(int dirfd, initializer_list<const char *> excl,
|
||||
function<int(int, dirent *)> &&fn) {
|
||||
static void post_order_walk(int dirfd, function<int(int, dirent *)> &&fn) {
|
||||
auto dir = xopen_dir(dirfd);
|
||||
if (!dir) return;
|
||||
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
if (entry->d_name == "."sv || entry->d_name == ".."sv)
|
||||
continue;
|
||||
if (is_excl(excl, entry->d_name))
|
||||
continue;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
int newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
post_order_walk(newfd, excl, std::move(fn));
|
||||
}
|
||||
if (entry->d_type == DT_DIR)
|
||||
post_order_walk(xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC), std::move(fn));
|
||||
fn(dirfd, entry);
|
||||
}
|
||||
}
|
||||
@ -80,15 +68,13 @@ void rm_rf(const char *path) {
|
||||
struct stat st;
|
||||
if (lstat(path, &st) < 0)
|
||||
return;
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
int fd = xopen(path, O_RDONLY | O_CLOEXEC);
|
||||
frm_rf(fd);
|
||||
}
|
||||
if (S_ISDIR(st.st_mode))
|
||||
frm_rf(xopen(path, O_RDONLY | O_CLOEXEC));
|
||||
remove(path);
|
||||
}
|
||||
|
||||
void frm_rf(int dirfd, initializer_list<const char *> excl) {
|
||||
post_order_walk(dup(dirfd), excl, remove_at);
|
||||
void frm_rf(int dirfd) {
|
||||
post_order_walk(dirfd, remove_at);
|
||||
}
|
||||
|
||||
/* This will only on the same file system */
|
||||
@ -389,7 +375,7 @@ void parse_prop_file(const char *file, const function<bool (string_view, string_
|
||||
}
|
||||
|
||||
void parse_mnt(const char *file, const function<bool (mntent*)> &fn) {
|
||||
unique_ptr<FILE, decltype(&endmntent)> fp(setmntent(file, "re"), &endmntent);
|
||||
auto fp = sFILE(setmntent(file, "re"), endmntent);
|
||||
if (fp) {
|
||||
mntent mentry{};
|
||||
char buf[4096];
|
||||
@ -404,11 +390,11 @@ void backup_folder(const char *dir, vector<raw_file> &files) {
|
||||
char path[4096];
|
||||
realpath(dir, path);
|
||||
int len = strlen(path);
|
||||
int dirfd = xopen(dir, O_RDONLY);
|
||||
post_order_walk(dirfd, {}, [&](int dfd, dirent *entry) -> int {
|
||||
post_order_walk(xopen(dir, O_RDONLY), [&](int dfd, dirent *entry) -> int {
|
||||
int fd = xopenat(dfd, entry->d_name, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
run_finally f([&]{ close(fd); });
|
||||
if (fd_path(fd, path, sizeof(path)) < 0)
|
||||
return -1;
|
||||
raw_file file;
|
||||
@ -423,11 +409,9 @@ void backup_folder(const char *dir, vector<raw_file> &files) {
|
||||
file.buf = (uint8_t *) xmalloc(file.sz);
|
||||
memcpy(file.buf, path, file.sz);
|
||||
}
|
||||
close(fd);
|
||||
files.emplace_back(std::move(file));
|
||||
return 0;
|
||||
});
|
||||
close(dirfd);
|
||||
}
|
||||
|
||||
void restore_folder(const char *dir, vector<raw_file> &files) {
|
||||
@ -438,7 +422,7 @@ void restore_folder(const char *dir, vector<raw_file> &files) {
|
||||
if (S_ISDIR(file.attr.st.st_mode)) {
|
||||
mkdirs(path.data(), 0);
|
||||
} else if (S_ISREG(file.attr.st.st_mode)) {
|
||||
auto fp = xopen_file(path.data(), "w");
|
||||
auto fp = xopen_file(path.data(), "we");
|
||||
fwrite(file.buf, 1, file.sz, fp.get());
|
||||
} else if (S_ISLNK(file.attr.st.st_mode)) {
|
||||
symlink((char *)file.buf, path.data());
|
||||
|
@ -66,7 +66,7 @@ static inline void file_readline(const char *file,
|
||||
void parse_prop_file(const char *file,
|
||||
const std::function<bool(std::string_view, std::string_view)> &fn);
|
||||
void *__mmap(const char *filename, size_t *size, bool rw);
|
||||
void frm_rf(int dirfd, std::initializer_list<const char *> excl = {});
|
||||
void frm_rf(int dirfd);
|
||||
void clone_dir(int src, int dest, bool overwrite = true);
|
||||
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
||||
void backup_folder(const char *dir, std::vector<raw_file> &files);
|
||||
|
@ -258,6 +258,14 @@ int xfstat(int fd, struct stat *buf) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xdup(int fd) {
|
||||
int ret = dup(fd);
|
||||
if (ret == -1) {
|
||||
PLOGE("dup");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xdup2(int oldfd, int newfd) {
|
||||
int ret = dup2(oldfd, newfd);
|
||||
if (ret == -1) {
|
||||
|
@ -35,6 +35,7 @@ int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
int xstat(const char *pathname, struct stat *buf);
|
||||
int xlstat(const char *pathname, struct stat *buf);
|
||||
int xfstat(int fd, struct stat *buf);
|
||||
int xdup(int fd);
|
||||
int xdup2(int oldfd, int newfd);
|
||||
int xdup3(int oldfd, int newfd, int flags);
|
||||
ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz);
|
||||
|
Loading…
Reference in New Issue
Block a user