Maintain our own set of loop devices

This commit is contained in:
topjohnwu 2018-07-07 01:32:58 +08:00
parent 23c2e22910
commit 1283167595
3 changed files with 32 additions and 11 deletions

View File

@ -612,6 +612,7 @@ void startup() {
xmkdir(MIRRDIR "/bin", 0755);
xmkdir(BBPATH, 0755);
xmkdir(MOUNTPOINT, 0755);
xmkdir(BLOCKDIR, 0755);
LOGI("* Mounting mirrors");
struct vector mounts;

View File

@ -19,6 +19,7 @@
#define UNBLOCKFILE "/dev/.magisk.unblock"
#define DISABLEFILE "/cache/.disable_magisk"
#define MAGISKTMP "/sbin/.core"
#define BLOCKDIR MAGISKTMP "/block"
#define MIRRDIR MAGISKTMP "/mirror"
#define BBPATH MAGISKTMP "/busybox"
#define MOUNTPOINT MAGISKTMP "/img"

View File

@ -9,6 +9,7 @@
#include <sys/mount.h>
#include <sys/sendfile.h>
#include <sys/statvfs.h>
#include <sys/sysmacros.h>
#include <linux/loop.h>
#include "magisk.h"
@ -26,23 +27,41 @@ struct fs_info {
};
static char *loopsetup(const char *img) {
char device[20];
char device[32];
struct loop_info64 info;
int i, lfd, ffd;
int lfd = -1, ffd;
memset(&info, 0, sizeof(info));
// First get an empty loop device
for (i = 0; i <= 7; ++i) {
if (access(BLOCKDIR, F_OK) == 0) {
for (int i = 8; i < 100; ++i) {
sprintf(device, BLOCKDIR "/loop%02d", i);
if (access(device, F_OK) != 0)
mknod(device, S_IFBLK | 0600, makedev(7, i * 8));
lfd = open(device, O_RDWR);
if (lfd < 0) /* Kernel does not support this */
break;
if (ioctl(lfd, LOOP_GET_STATUS64, &info) == -1)
break;
close(lfd);
lfd = -1;
}
}
// Fallback to existing loop in dev, but in reverse order
if (lfd < 0) {
for (int i = 7; i >= 0; --i) {
sprintf(device, "/dev/block/loop%d", i);
lfd = xopen(device, O_RDWR);
if (ioctl(lfd, LOOP_GET_STATUS64, &info) == -1)
break;
close(lfd);
lfd = -1;
}
if (i == 8) return NULL;
}
if (lfd < 0)
return NULL;
ffd = xopen(img, O_RDWR);
if (ioctl(lfd, LOOP_SET_FD, ffd) == -1)
return NULL;
strcpy((char *) info.lo_file_name, img);
strncpy((char *) info.lo_file_name, img, sizeof(info.lo_file_name));
ioctl(lfd, LOOP_SET_STATUS64, &info);
close(lfd);
close(ffd);