mirror of
https://github.com/topjohnwu/Magisk
synced 2024-11-10 15:59:04 +01:00
Make tmpfs mount of magic mount atomic
This avoid system libraries disappear temporarily during magic mount, which causes some dynamic executables fails to run during post-fs-data.
This commit is contained in:
parent
d49b02b274
commit
1fd49e4987
@ -122,8 +122,8 @@ void dir_node::collect_module_files(const char *module, int dfd) {
|
|||||||
* Mount Implementations
|
* Mount Implementations
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
void node_entry::create_and_mount(const char *reason, const string &src) {
|
void node_entry::create_and_mount(const char *reason, const string &src, bool ro) {
|
||||||
const string &dest = node_path();
|
const string dest = isa<tmpfs_node>(parent()) ? worker_path() : node_path();
|
||||||
if (is_lnk()) {
|
if (is_lnk()) {
|
||||||
VLOGD("cp_link", src.data(), dest.data());
|
VLOGD("cp_link", src.data(), dest.data());
|
||||||
cp_afc(src.data(), dest.data());
|
cp_afc(src.data(), dest.data());
|
||||||
@ -135,6 +135,9 @@ void node_entry::create_and_mount(const char *reason, const string &src) {
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
bind_mount(reason, src.data(), dest.data());
|
bind_mount(reason, src.data(), dest.data());
|
||||||
|
if (ro) {
|
||||||
|
xmount(nullptr, dest.data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,22 +163,23 @@ void module_node::mount() {
|
|||||||
|
|
||||||
void tmpfs_node::mount() {
|
void tmpfs_node::mount() {
|
||||||
string src = mirror_path();
|
string src = mirror_path();
|
||||||
const string &dest = node_path();
|
const char *src_path = access(src.data(), F_OK) == 0 ? src.data() : parent()->node_path().data();
|
||||||
const char *src_path;
|
|
||||||
if (access(src.data(), F_OK) == 0)
|
|
||||||
src_path = src.data();
|
|
||||||
else
|
|
||||||
src_path = parent()->node_path().data();
|
|
||||||
if (!isa<tmpfs_node>(parent())) {
|
if (!isa<tmpfs_node>(parent())) {
|
||||||
auto worker_dir = get_magisk_tmp() + "/"s WORKERDIR + dest;
|
const string &dest = node_path();
|
||||||
|
auto worker_dir = worker_path();
|
||||||
mkdirs(worker_dir.data(), 0);
|
mkdirs(worker_dir.data(), 0);
|
||||||
create_and_mount(skip_mirror() ? "replace" : "tmpfs", worker_dir);
|
bind_mount("tmpfs", worker_dir.data(), worker_dir.data());
|
||||||
|
dir_node::mount();
|
||||||
|
VLOGD(skip_mirror() ? "replace" : "move", worker_dir.data(), dest.data());
|
||||||
|
xmount(worker_dir.data(), dest.data(), nullptr, MS_MOVE, nullptr);
|
||||||
|
clone_attr(src_path, dest.data());
|
||||||
} else {
|
} else {
|
||||||
|
const string dest = worker_path();
|
||||||
// We don't need another layer of tmpfs if parent is tmpfs
|
// We don't need another layer of tmpfs if parent is tmpfs
|
||||||
mkdir(dest.data(), 0);
|
mkdir(dest.data(), 0);
|
||||||
|
clone_attr(src_path, dest.data());
|
||||||
|
dir_node::mount();
|
||||||
}
|
}
|
||||||
clone_attr(src_path, dest.data());
|
|
||||||
dir_node::mount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
@ -191,7 +195,7 @@ public:
|
|||||||
if (access(src.data(), F_OK))
|
if (access(src.data(), F_OK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const string &dir_name = parent()->node_path();
|
const string dir_name = isa<tmpfs_node>(parent()) ? parent()->worker_path() : parent()->node_path();
|
||||||
if (name() == "magisk") {
|
if (name() == "magisk") {
|
||||||
for (int i = 0; applet_names[i]; ++i) {
|
for (int i = 0; applet_names[i]; ++i) {
|
||||||
string dest = dir_name + "/" + applet_names[i];
|
string dest = dir_name + "/" + applet_names[i];
|
||||||
@ -203,8 +207,7 @@ public:
|
|||||||
VLOGD("create", "./magiskpolicy", dest.data());
|
VLOGD("create", "./magiskpolicy", dest.data());
|
||||||
xsymlink("./magiskpolicy", dest.data());
|
xsymlink("./magiskpolicy", dest.data());
|
||||||
}
|
}
|
||||||
create_and_mount("magisk", src);
|
create_and_mount("magisk", src, true);
|
||||||
xmount(nullptr, node_path().data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,8 +218,7 @@ public:
|
|||||||
|
|
||||||
void mount() override {
|
void mount() override {
|
||||||
const string src = get_magisk_tmp() + "/magisk"s + (is64bit ? "64" : "32");
|
const string src = get_magisk_tmp() + "/magisk"s + (is64bit ? "64" : "32");
|
||||||
create_and_mount("zygisk", src);
|
create_and_mount("zygisk", src, true);
|
||||||
xmount(nullptr, node_path().data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -45,6 +45,8 @@ public:
|
|||||||
|
|
||||||
// Don't call the following two functions before prepare
|
// Don't call the following two functions before prepare
|
||||||
const string &node_path();
|
const string &node_path();
|
||||||
|
const string worker_path();
|
||||||
|
|
||||||
string mirror_path() { return mirror_dir + node_path(); }
|
string mirror_path() { return mirror_dir + node_path(); }
|
||||||
|
|
||||||
virtual void mount() = 0;
|
virtual void mount() = 0;
|
||||||
@ -67,7 +69,7 @@ protected:
|
|||||||
delete other;
|
delete other;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_and_mount(const char *reason, const string &src);
|
void create_and_mount(const char *reason, const string &src, bool ro=false);
|
||||||
|
|
||||||
// Use bit 7 of _file_type for exist status
|
// Use bit 7 of _file_type for exist status
|
||||||
bool exist() const { return static_cast<bool>(_file_type & (1 << 7)); }
|
bool exist() const { return static_cast<bool>(_file_type & (1 << 7)); }
|
||||||
@ -314,3 +316,7 @@ const string &node_entry::node_path() {
|
|||||||
_node_path = _parent->node_path() + '/' + _name;
|
_node_path = _parent->node_path() + '/' + _name;
|
||||||
return _node_path;
|
return _node_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string node_entry::worker_path() {
|
||||||
|
return get_magisk_tmp() + "/"s WORKERDIR + node_path();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user