1. 挂载分区时添加resize功能
system/core/fs_mgr/fs_mgr.cpp
#include "cryptfs.h"
#define RESIZE2FS_BIN "/system/bin/resize2fs"
static void resize_fs(const char *blk_device, char *fs_type, char *key_loc) {
uint64_t device_sz;
uint64_t device_ss;
uint64_t device_sn;
int status = 0;
int ret = 0;
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
if (fd < 0) {
PERROR << "Failed to open '" << blk_device << "'";
return;
}
/* Cannot use BLKGETSIZE to get the number of sectors,
* because need to do device_sz -= CRYPT_FOOTER_OFFSET
*/
if ((ioctl(fd, BLKGETSIZE64, &device_sz)) == -1) {
PERROR << "(BLKGETSIZE64) Can't get '" << blk_device << "' size";
return;
}
if ((ioctl(fd, BLKSSZGET, &device_ss)) == -1) {
PERROR << "(BLKSSZGET) Can't get '" << blk_device << "' size";
return;
}
/* Format the partition using the calculated length */
if (!strcmp(key_loc, KEY_IN_FOOTER))
device_sz -= CRYPT_FOOTER_OFFSET;
if (is_extfs(fs_type)) {
if (access(RESIZE2FS_BIN, X_OK)) {
LINFO << "Not running " << RESIZE2FS_BIN << " on " << blk_device
<< " (executable not in system image)";
} else {
std::string size_kb_str(android::base::StringPrintf("%" PRIu64 "K", device_sz / 1024));
LINFO << "Running " << RESIZE2FS_BIN << " on " << blk_device;
/* extX cmd */
const char *resize2fs_argv[] = {
RESIZE2FS_BIN,
"-f",
blk_device,
size_kb_str.c_str()
};
ret = android_fork_execvp_ext(ARRAY_SIZE(resize2fs_argv),
const_cast<char **>(resize2fs_argv),
&status, true, LOG_KLOG,
false, NULL, NULL, 0);
if (ret < 0) {
/* No need to check for error in fork, we can't really handle it now */
LERROR << "Failed trying to run " << RESIZE2FS_BIN;
return;
}
}
}
}
static int prepare_fs_for_mount(const char* blk_device, const struct fstab_rec* rec) {
...
if ((rec->fs_mgr_flags & MF_RESIZE) && !strcmp(blk_device, rec->blk_device)) {
resize_fs(blk_device, rec->fs_type, rec->key_loc);
check_fs(blk_device, rec->fs_type, rec->mount_point, &fs_stat);
}
...
}
|
2. 添加fstab标签
system/core/fs_mgr/fs_mgr_fstab.cpp
static struct flag_list fs_mgr_flags[] = {
...
{"resize", MF_RESIZE},
...
}
|
system/core/fs_mgr/fs_mgr_priv.h
#define MF_RESIZE 0x10000000
|
3. 添加相关selinux权限
system/sepolicy/private/file_contexts
/system/bin/resize2fs u:object_r:fsck_exec:s0
|
system/sepolicy/vendor/resize.te
type resize, domain;
type resize_exec, exec_type, file_type, vendor_file_type;
init_daemon_domain(resize)
allow resize resize_exec:file execute_no_trans;
allow resize devpts:chr_file { read write open getattr ioctl };
allow resize kmsg_device:chr_file { write open };
allow resize userdata_block_device:blk_file rw_file_perms;
allow resize block_device:dir search;
allow resize resize:capability sys_admin;
allow resize labeledfs:filesystem unmount;
allow resize property_socket:sock_file write;
allow resize init:unix_stream_socket connectto;
allow resize system_file:file execute_no_trans;
|
4. fstab.qcom 更新如下:
/dev/block/bootdevice/by-name/userdata /data ext4 noatime,nosuid,nodev,barrier=1,noauto_da_alloc,discard wait,check,encryptable=footer,quota,resize
// 添加一个 resize 属性。