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