mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-29 03:17:48 +00:00
Merge remote-tracking branch 'john/master' into development
This commit is contained in:
commit
065051a360
@ -23,7 +23,6 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
@ -95,7 +94,7 @@ public class DownloadModuleService extends Service {
|
||||
.setDownloadProgressListener(progress)
|
||||
.execForInputStream().getResult();
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(output));
|
||||
processZip(in, out, repo.isNewInstaller());
|
||||
processZip(in, out);
|
||||
Intent intent = new Intent(this, ClassMap.get(FlashActivity.class));
|
||||
intent.setData(Uri.fromFile(output))
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
@ -120,25 +119,23 @@ public class DownloadModuleService extends Service {
|
||||
removeNotification(progress);
|
||||
}
|
||||
|
||||
private void processZip(InputStream in, OutputStream out, boolean inject)
|
||||
private void processZip(InputStream in, OutputStream out)
|
||||
throws IOException {
|
||||
try (ZipInputStream zin = new ZipInputStream(in);
|
||||
ZipOutputStream zout = new ZipOutputStream(out)) {
|
||||
|
||||
if (inject) {
|
||||
// Inject latest module-installer.sh as update-binary
|
||||
zout.putNextEntry(new ZipEntry("META-INF/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/update-binary"));
|
||||
try (InputStream update_bin = Networking.get(Const.Url.MODULE_INSTALLER)
|
||||
.execForInputStream().getResult()) {
|
||||
ShellUtils.pump(update_bin, zout);
|
||||
}
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/updater-script"));
|
||||
zout.write("#MAGISK\n".getBytes(StandardCharsets.UTF_8));
|
||||
// Inject latest module-installer.sh as update-binary
|
||||
zout.putNextEntry(new ZipEntry("META-INF/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/"));
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/update-binary"));
|
||||
try (InputStream update_bin = Networking.get(Const.Url.MODULE_INSTALLER)
|
||||
.execForInputStream().getResult()) {
|
||||
ShellUtils.pump(update_bin, zout);
|
||||
}
|
||||
zout.putNextEntry(new ZipEntry("META-INF/com/google/android/updater-script"));
|
||||
zout.write("#MAGISK\n".getBytes("UTF-8"));
|
||||
|
||||
int off = -1;
|
||||
ZipEntry entry;
|
||||
@ -148,7 +145,7 @@ public class DownloadModuleService extends Service {
|
||||
String path = entry.getName().substring(off);
|
||||
if (path.isEmpty())
|
||||
continue;
|
||||
if (inject && path.startsWith("META-INF"))
|
||||
if (path.startsWith("META-INF"))
|
||||
continue;
|
||||
zout.putNextEntry(new ZipEntry(path));
|
||||
if (!entry.isDirectory())
|
||||
|
@ -7,8 +7,6 @@ import android.os.Parcelable;
|
||||
|
||||
import com.topjohnwu.magisk.Const;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.net.Networking;
|
||||
import com.topjohnwu.net.Request;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
@ -91,18 +89,6 @@ public class Repo extends BaseModule {
|
||||
return String.format(Const.Url.FILE_URL, getId(), file);
|
||||
}
|
||||
|
||||
public boolean isNewInstaller() {
|
||||
try (Request install = Networking.get(getFileUrl("install.sh"))) {
|
||||
if (install.connect().isSuccess()) {
|
||||
// Double check whether config.sh exists
|
||||
try (Request config = Networking.get(getFileUrl("config.sh"))) {
|
||||
return !config.connect().isSuccess();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String getLastUpdateString() {
|
||||
return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(mLastUpdate);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
APP_ABI := armeabi-v7a x86
|
||||
APP_CFLAGS := -Oz -fomit-frame-pointer -flto \
|
||||
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto \
|
||||
-D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE}
|
||||
APP_LDFLAGS := -flto
|
||||
APP_CPPFLAGS := -std=c++17
|
||||
|
@ -207,7 +207,7 @@ void node_entry::create_module_tree(const char *module) {
|
||||
void node_entry::clone_skeleton() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
struct node_entry *dummy;
|
||||
node_entry *dummy;
|
||||
|
||||
// Clone the structure
|
||||
auto full_path = get_path();
|
||||
@ -498,20 +498,20 @@ void unlock_blocks() {
|
||||
struct dirent *entry;
|
||||
int fd, dev, OFF = 0;
|
||||
|
||||
if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0)
|
||||
if (!(dir = xopendir("/dev/block")))
|
||||
return;
|
||||
dir = xfdopendir(dev);
|
||||
dev = dirfd(dir);
|
||||
|
||||
while((entry = readdir(dir))) {
|
||||
if (entry->d_type == DT_BLK) {
|
||||
if ((fd = openat(dev, entry->d_name, O_RDONLY)) < 0)
|
||||
if ((fd = openat(dev, entry->d_name, O_RDONLY | O_CLOEXEC)) < 0)
|
||||
continue;
|
||||
if (ioctl(fd, BLKROSET, &OFF) == -1)
|
||||
if (ioctl(fd, BLKROSET, &OFF) < 0)
|
||||
PLOGE("unlock %s", entry->d_name);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
close(dev);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
static bool log_dump = false;
|
||||
|
@ -38,10 +38,9 @@ using namespace std;
|
||||
|
||||
#ifdef MAGISK_DEBUG
|
||||
static FILE *kmsg;
|
||||
static char kbuf[4096];
|
||||
static int vprintk(const char *fmt, va_list ap) {
|
||||
vsprintf(kbuf, fmt, ap);
|
||||
return fprintf(kmsg, "magiskinit: %s", kbuf);
|
||||
fprintf(kmsg, "magiskinit: ");
|
||||
return vfprintf(kmsg, fmt, ap);
|
||||
}
|
||||
|
||||
static void setup_klog() {
|
||||
|
2
native/jni/external/busybox
vendored
2
native/jni/external/busybox
vendored
@ -1 +1 @@
|
||||
Subproject commit 1dcc6befca9c7a5a89d8dfd95943220bd534d6cb
|
||||
Subproject commit a57ccd7378e6858f9b2a564c75517ed4b41fcd39
|
2
native/jni/external/dtc
vendored
2
native/jni/external/dtc
vendored
@ -1 +1 @@
|
||||
Subproject commit 88f18909db731a627456f26d779445f84e449536
|
||||
Subproject commit d37f6b20107e952064e3f77e9d6915a9c09d10a6
|
2
native/jni/external/lz4
vendored
2
native/jni/external/lz4
vendored
@ -1 +1 @@
|
||||
Subproject commit 641b453d9db536ee020851bfcb1dc39f61006f0a
|
||||
Subproject commit 398e36c756a3067de8e2b35dd380baef040dfe0d
|
2
native/jni/external/nanopb
vendored
2
native/jni/external/nanopb
vendored
@ -1 +1 @@
|
||||
Subproject commit 3626b5c40e2457629ac60a563dde523be7c10bb4
|
||||
Subproject commit 3c69a905b16df149e1bda12f25e0522073a24678
|
2
native/jni/external/selinux
vendored
2
native/jni/external/selinux
vendored
@ -1 +1 @@
|
||||
Subproject commit 4d7d59c49675eef4a18c2b1f73e630bf675811f9
|
||||
Subproject commit c61cf3916dc8f19ef2236078ff87f7a33fce6a52
|
2
native/jni/external/xz
vendored
2
native/jni/external/xz
vendored
@ -1 +1 @@
|
||||
Subproject commit 3d566cd519017eee1a400e7961ff14058dfaf33c
|
||||
Subproject commit b5be61cc06088bb07f488f9baf7d447ff47b37c1
|
@ -422,8 +422,8 @@ void LZ4FEncoder::write_header() {
|
||||
FilterOutStream::write(outbuf, write);
|
||||
}
|
||||
|
||||
LZ4Decoder::LZ4Decoder() : init(false), buf_off(0), total(0), block_sz(0),
|
||||
outbuf(new char[LZ4_UNCOMPRESSED]), buf(new char[LZ4_COMPRESSED]) {}
|
||||
LZ4Decoder::LZ4Decoder() : outbuf(new char[LZ4_UNCOMPRESSED]), buf(new char[LZ4_COMPRESSED]),
|
||||
init(false), block_sz(0), buf_off(0), total(0) {}
|
||||
|
||||
LZ4Decoder::~LZ4Decoder() {
|
||||
delete[] outbuf;
|
||||
@ -476,8 +476,8 @@ uint64_t LZ4Decoder::finalize() {
|
||||
return total;
|
||||
}
|
||||
|
||||
LZ4Encoder::LZ4Encoder() : init(false), buf_off(0), out_total(0), in_total(0),
|
||||
outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]) {}
|
||||
LZ4Encoder::LZ4Encoder() : outbuf(new char[LZ4_COMPRESSED]), buf(new char[LZ4_UNCOMPRESSED]),
|
||||
init(false), buf_off(0), out_total(0), in_total(0) {}
|
||||
|
||||
LZ4Encoder::~LZ4Encoder() {
|
||||
delete[] outbuf;
|
||||
|
@ -165,7 +165,7 @@ void magisk_cpio::backup(const char *orig) {
|
||||
res = lhs->first.compare(rhs->first);
|
||||
} else if (lhs == o.entries.end()) {
|
||||
res = 1;
|
||||
} else if (rhs == entries.end()) {
|
||||
} else {
|
||||
res = -1;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "magiskpolicy.h"
|
||||
#include "sepolicy.h"
|
||||
#include "flags.h"
|
||||
|
||||
static void allowSuClient(const char *target) {
|
||||
if (!sepol_exists(target))
|
||||
@ -47,7 +48,7 @@ void sepol_magisk_rules() {
|
||||
sepol_attradd(SEPOL_PROC_DOMAIN, "bluetoothdomain");
|
||||
sepol_attradd(SEPOL_FILE_DOMAIN, "mlstrustedobject");
|
||||
|
||||
// Let init daemon transit context
|
||||
// Let init transit to SEPOL_PROC_DOMAIN
|
||||
sepol_allow("kernel", "kernel", "process", "setcurrent");
|
||||
sepol_allow("kernel", SEPOL_PROC_DOMAIN, "process", "dyntransition");
|
||||
|
||||
@ -148,7 +149,7 @@ void sepol_magisk_rules() {
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, "tmpfs", "filesystem", "unmount");
|
||||
sepol_allow("kernel", ALL, "file", "read");
|
||||
|
||||
// Allow su to do anything to any files/dir/links
|
||||
// Allow us to do anything to any files/dir/links
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, ALL, "file", ALL);
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, ALL, "dir", ALL);
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, ALL, "lnk_file", ALL);
|
||||
@ -157,6 +158,10 @@ void sepol_magisk_rules() {
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, ALL, "chr_file", ALL);
|
||||
sepol_allow(SEPOL_PROC_DOMAIN, ALL, "fifo_file", ALL);
|
||||
|
||||
// Allow us to do any ioctl on all block devices
|
||||
if (policydb->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL)
|
||||
sepol_allowxperm(SEPOL_PROC_DOMAIN, ALL, "blk_file", "0x0000-0xFFFF");
|
||||
|
||||
// Allow all binder transactions
|
||||
sepol_allow(ALL, SEPOL_PROC_DOMAIN, "binder", ALL);
|
||||
|
||||
@ -184,12 +189,14 @@ void sepol_magisk_rules() {
|
||||
// Allow update engine to source addon.d.sh
|
||||
sepol_allow("update_engine", "adb_data_file", "dir", ALL);
|
||||
|
||||
// Remove all dontaudit
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Remove all dontaudit in debug mode
|
||||
avtab_ptr_t av;
|
||||
avtab_for_each(&policydb->te_avtab, av, {
|
||||
if (av->key.specified == AVTAB_AUDITDENY || av->key.specified == AVTAB_XPERMS_DONTAUDIT)
|
||||
avtab_remove_node(&policydb->te_avtab, av);
|
||||
})
|
||||
#endif
|
||||
|
||||
log_cb.w = bak;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
// 0x18000020 = FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_INCLUDE_STOPPED_PACKAGES
|
||||
|
||||
static inline const char *get_command(const struct su_request *to) {
|
||||
static inline const char *get_command(const su_request *to) {
|
||||
if (to->command[0])
|
||||
return to->command;
|
||||
if (to->shell[0])
|
||||
@ -25,21 +25,21 @@ static inline const char *get_command(const struct su_request *to) {
|
||||
return DEFAULT_SHELL;
|
||||
}
|
||||
|
||||
static inline void get_user(char *user, struct su_info *info) {
|
||||
static inline void get_user(char *user, su_info *info) {
|
||||
sprintf(user, "%d",
|
||||
info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_USER
|
||||
? info->uid / 100000
|
||||
: 0);
|
||||
}
|
||||
|
||||
static inline void get_uid(char *uid, struct su_info *info) {
|
||||
static inline void get_uid(char *uid, su_info *info) {
|
||||
sprintf(uid, "%d",
|
||||
info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_OWNER_MANAGED
|
||||
? info->uid % 100000
|
||||
: info->uid);
|
||||
}
|
||||
|
||||
static void silent_run(const char **args, struct su_info *info) {
|
||||
static void silent_run(const char **args, su_info *info) {
|
||||
char component[128];
|
||||
sprintf(component, "%s/a.m", info->str[SU_MANAGER].data());
|
||||
char user[8];
|
||||
@ -62,7 +62,7 @@ static void silent_run(const char **args, struct su_info *info) {
|
||||
exec_command(exec);
|
||||
}
|
||||
|
||||
void app_log(struct su_context *ctx) {
|
||||
void app_log(su_context *ctx) {
|
||||
char fromUid[8];
|
||||
get_uid(fromUid, ctx->info);
|
||||
|
||||
@ -88,7 +88,7 @@ void app_log(struct su_context *ctx) {
|
||||
silent_run(cmd, ctx->info);
|
||||
}
|
||||
|
||||
void app_notify(struct su_context *ctx) {
|
||||
void app_notify(su_context *ctx) {
|
||||
char fromUid[8];
|
||||
get_uid(fromUid, ctx->info);
|
||||
|
||||
@ -104,7 +104,7 @@ void app_notify(struct su_context *ctx) {
|
||||
silent_run(cmd, ctx->info);
|
||||
}
|
||||
|
||||
void app_connect(const char *socket, struct su_info *info) {
|
||||
void app_connect(const char *socket, su_info *info) {
|
||||
const char *cmd[] = {
|
||||
START_ACTIVITY, "request",
|
||||
"--es", "socket", socket,
|
||||
@ -113,7 +113,7 @@ void app_connect(const char *socket, struct su_info *info) {
|
||||
silent_run(cmd, info);
|
||||
}
|
||||
|
||||
void socket_send_request(int fd, struct su_info *info) {
|
||||
void socket_send_request(int fd, su_info *info) {
|
||||
write_key_token(fd, "uid", info->uid);
|
||||
write_string_be(fd, "eof");
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ static void pump_async(int input, int output) {
|
||||
*/
|
||||
int pts_open(char *slave_name, size_t slave_name_size) {
|
||||
int fdm;
|
||||
char sn_tmp[256];
|
||||
|
||||
// Open master ptmx device
|
||||
fdm = open("/dev/ptmx", O_RDWR);
|
||||
|
@ -60,16 +60,16 @@ struct su_request : public su_req_base {
|
||||
} __attribute__((packed));
|
||||
|
||||
struct su_context {
|
||||
struct su_info *info;
|
||||
struct su_request req;
|
||||
su_info *info;
|
||||
su_request req;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
// connect.c
|
||||
|
||||
void app_log(struct su_context *ctx);
|
||||
void app_notify(struct su_context *ctx);
|
||||
void app_connect(const char *socket, struct su_info *info);
|
||||
void socket_send_request(int fd, struct su_info *info);
|
||||
void app_log(su_context *ctx);
|
||||
void app_notify(su_context *ctx);
|
||||
void app_connect(const char *socket, su_info *info);
|
||||
void socket_send_request(int fd, su_info *info);
|
||||
|
||||
#endif
|
||||
|
@ -26,8 +26,8 @@ static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static su_info *cache;
|
||||
|
||||
su_info::su_info(unsigned uid) :
|
||||
uid(uid), access(DEFAULT_SU_ACCESS), _lock(PTHREAD_MUTEX_INITIALIZER),
|
||||
count(0), ref(0), timestamp(0), mgr_st({}) {}
|
||||
uid(uid), count(0), access(DEFAULT_SU_ACCESS), mgr_st({}), ref(0),
|
||||
timestamp(0), _lock(PTHREAD_MUTEX_INITIALIZER) {}
|
||||
|
||||
su_info::~su_info() {
|
||||
pthread_mutex_destroy(&_lock);
|
||||
@ -90,7 +90,7 @@ static void database_check(su_info *info) {
|
||||
validate_manager(info->str[SU_MANAGER], uid / 100000, &info->mgr_st);
|
||||
}
|
||||
|
||||
static struct su_info *get_su_info(unsigned uid) {
|
||||
static su_info *get_su_info(unsigned uid) {
|
||||
su_info *info = nullptr;
|
||||
|
||||
// Get from cache or new instance
|
||||
@ -235,7 +235,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
|
||||
// Abort upon any error occurred
|
||||
log_cb.ex = exit;
|
||||
|
||||
struct su_context ctx = {
|
||||
su_context ctx = {
|
||||
.info = info,
|
||||
.pid = credential->pid
|
||||
};
|
||||
|
@ -80,9 +80,23 @@ if [ -d /system/addon.d ]; then
|
||||
ui_print "- Adding addon.d survival script"
|
||||
mount -o rw,remount /system
|
||||
ADDOND=/system/addon.d/99-magisk.sh
|
||||
echo '#!/sbin/sh' > $ADDOND
|
||||
echo '# ADDOND_VERSION=2' >> $ADDOND
|
||||
echo 'exec sh /data/adb/magisk/addon.d.sh "$@"' >> $ADDOND
|
||||
cat <<EOF > $ADDOND
|
||||
#!/sbin/sh
|
||||
# ADDOND_VERSION=2
|
||||
|
||||
if [ -f /data/adb/magisk/addon.d.sh ]; then
|
||||
exec sh /data/adb/magisk/addon.d.sh "\$@"
|
||||
else
|
||||
OUTFD=\$(ps | grep -v 'grep' | grep -oE 'update(.*)' | cut -d" " -f3)
|
||||
ui_print() { echo -e "ui_print \$1\nui_print" >> /proc/self/fd/\$OUTFD; }
|
||||
|
||||
ui_print "************************"
|
||||
ui_print "* Magisk addon.d failed"
|
||||
ui_print "************************"
|
||||
ui_print "! Cannot find Magisk binaries - was data wiped or not decrypted?"
|
||||
ui_print "! Reflash OTA from decrypted recovery or reflash Magisk"
|
||||
fi
|
||||
EOF
|
||||
chmod 755 $ADDOND
|
||||
fi
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
##########################################################################################
|
||||
#########################################
|
||||
#
|
||||
# Magisk General Utility Functions
|
||||
# by topjohnwu
|
||||
#
|
||||
# Used everywhere in Magisk
|
||||
#
|
||||
##########################################################################################
|
||||
#########################################
|
||||
|
||||
##########
|
||||
# Presets
|
||||
@ -167,40 +165,42 @@ find_block() {
|
||||
return 1
|
||||
}
|
||||
|
||||
mount_part() {
|
||||
local PART=$1
|
||||
local POINT=/${PART}
|
||||
[ -L $POINT ] && rm -f $POINT
|
||||
mkdir $POINT 2>/dev/null
|
||||
is_mounted $POINT && return
|
||||
ui_print "- Mounting $PART"
|
||||
mount -o ro $POINT 2>/dev/null
|
||||
if ! is_mounted $POINT; then
|
||||
local BLOCK=`find_block $PART$SLOT`
|
||||
mount -o ro $BLOCK $POINT
|
||||
fi
|
||||
is_mounted $POINT || abort "! Cannot mount $POINT"
|
||||
}
|
||||
|
||||
mount_partitions() {
|
||||
# Check A/B slot
|
||||
SLOT=`grep_cmdline androidboot.slot_suffix`
|
||||
if [ -z $SLOT ]; then
|
||||
SLOT=_`grep_cmdline androidboot.slot`
|
||||
[ $SLOT = "_" ] && SLOT=
|
||||
SLOT=`grep_cmdline androidboot.slot`
|
||||
[ -z $SLOT ] || SLOT=_${SLOT}
|
||||
fi
|
||||
[ -z $SLOT ] || ui_print "- Current boot slot: $SLOT"
|
||||
|
||||
ui_print "- Mounting /system, /vendor"
|
||||
mkdir /system 2>/dev/null
|
||||
[ -f /system/build.prop ] || is_mounted /system || mount -o ro /system 2>/dev/null
|
||||
if ! is_mounted /system && ! [ -f /system/build.prop ]; then
|
||||
SYSTEMBLOCK=`find_block system$SLOT`
|
||||
mount -o ro $SYSTEMBLOCK /system
|
||||
fi
|
||||
[ -f /system/build.prop ] || is_mounted /system || abort "! Cannot mount /system"
|
||||
grep -qE '/dev/root|/system_root' /proc/mounts && SYSTEM_ROOT=true || SYSTEM_ROOT=false
|
||||
mount_part system
|
||||
if [ -f /system/init.rc ]; then
|
||||
SYSTEM_ROOT=true
|
||||
[ -L /system_root ] && rm -f /system_root
|
||||
mkdir /system_root 2>/dev/null
|
||||
mount --move /system /system_root
|
||||
mount -o bind /system_root/system /system
|
||||
else
|
||||
grep -qE '/dev/root|/system_root' /proc/mounts && SYSTEM_ROOT=true || SYSTEM_ROOT=false
|
||||
fi
|
||||
[ -L /system/vendor ] && mount_part vendor
|
||||
$SYSTEM_ROOT && ui_print "- Device is system-as-root"
|
||||
if [ -L /system/vendor ]; then
|
||||
mkdir /vendor 2>/dev/null
|
||||
is_mounted /vendor || mount -o ro /vendor 2>/dev/null
|
||||
if ! is_mounted /vendor; then
|
||||
VENDORBLOCK=`find_block vendor$SLOT`
|
||||
mount -o ro $VENDORBLOCK /vendor
|
||||
fi
|
||||
is_mounted /vendor || abort "! Cannot mount /vendor"
|
||||
fi
|
||||
}
|
||||
|
||||
get_flags() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user