summaryrefslogtreecommitdiffstats
path: root/fs_mgr/fs_mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr/fs_mgr.c')
-rw-r--r--fs_mgr/fs_mgr.c233
1 files changed, 157 insertions, 76 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 15d44ef..e78b581 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -39,6 +39,7 @@
#include <cutils/partition_utils.h>
#include <cutils/properties.h>
#include <logwrap/logwrap.h>
+#include <blkid/blkid.h>
#include "mincrypt/rsa.h"
#include "mincrypt/sha.h"
@@ -60,6 +61,7 @@
#define FSCK_LOG_FILE "/dev/fscklogs/log"
#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
+#define ZRAM_STREAMS "/sys/block/zram0/max_comp_streams"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -161,10 +163,10 @@ static void check_fs(char *blk_device, char *fs_type, char *target)
} else if (!strcmp(fs_type, "f2fs")) {
char *f2fs_fsck_argv[] = {
F2FS_FSCK_BIN,
- "-f",
+ "-a",
blk_device
};
- INFO("Running %s -f %s\n", F2FS_FSCK_BIN, blk_device);
+ INFO("Running %s -a %s\n", F2FS_FSCK_BIN, blk_device);
ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
&status, true, LOG_KLOG | LOG_FILE,
@@ -304,6 +306,8 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
int i;
int mount_errno = 0;
int mounted = 0;
+ int cmp_len;
+ char *detected_fs_type;
if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
errno = EINVAL;
@@ -329,8 +333,16 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
}
if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
- check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
- fstab->recs[i].mount_point);
+ /* Skip file system check unless we are sure we are the right type */
+ detected_fs_type = blkid_get_tag_value(NULL, "TYPE", fstab->recs[i].blk_device);
+ if (detected_fs_type) {
+ cmp_len = (!strncmp(detected_fs_type, "ext", 3) &&
+ strlen(detected_fs_type) == 4) ? 3 : strlen(detected_fs_type);
+ if (!strncmp(fstab->recs[i].fs_type, detected_fs_type, cmp_len)) {
+ check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
+ fstab->recs[i].mount_point);
+ }
+ }
}
if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
*attempted_idx = i;
@@ -492,6 +504,52 @@ static int handle_encryptable(struct fstab *fstab, const struct fstab_rec* rec)
return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
}
+/*
+ * Reads the kernel cmdline to check if MDTP is activated.
+ * When MDTP is activated, kernel cmdline will have the word 'mdtp'.
+ */
+int fs_mgr_is_mdtp_activated()
+{
+ char cmdline[2048];
+ char *ptr;
+ int fd;
+ static int mdtp_activated = 0;
+ static int mdtp_activated_set = 0;
+
+ if (mdtp_activated_set) {
+ return mdtp_activated;
+ }
+
+ fd = open("/proc/cmdline", O_RDONLY);
+ if (fd >= 0) {
+ int n = read(fd, cmdline, sizeof(cmdline) - 1);
+ if (n < 0) n = 0;
+
+ /* get rid of trailing newline, it happens */
+ if (n > 0 && cmdline[n-1] == '\n') n--;
+
+ cmdline[n] = 0;
+ close(fd);
+ } else {
+ cmdline[0] = 0;
+ }
+
+ ptr = cmdline;
+ while (ptr && *ptr) {
+ char *x = strchr(ptr, ' ');
+ if (x != 0) *x++ = 0;
+ if (!strcmp(ptr,"mdtp")) {
+ mdtp_activated = 1;
+ break;
+ }
+ ptr = x;
+ }
+
+ mdtp_activated_set = 1;
+
+ return mdtp_activated;
+}
+
/* When multiple fstab records share the same mount_point, it will
* try to mount each one in turn, and ignore any duplicates after a
* first successful mount.
@@ -547,91 +605,106 @@ int fs_mgr_mount_all(struct fstab *fstab)
continue;
}
}
- int last_idx_inspected;
- int top_idx = i;
- mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
- i = last_idx_inspected;
- mount_errno = errno;
+ if (fs_mgr_is_mdtp_activated() && ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) ||
+ device_is_force_encrypted())) {
+ INFO("%s(): mdtp activated, blkdev %s for mount %s type %s expected to be encrypted)\n",
+ __func__, fstab->recs[i].blk_device, fstab->recs[i].mount_point,
+ fstab->recs[i].fs_type);
+ if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
+ ++error_count;
+ continue;
+ }
- /* Deal with encryptability. */
- if (!mret) {
- int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]);
+ encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
- if (status == FS_MGR_MNTALL_FAIL) {
- /* Fatal error - no point continuing */
- return status;
- }
+ } else {
+ int last_idx_inspected;
+ int top_idx = i;
- if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
- if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
- // Log and continue
- ERROR("Only one encryptable/encrypted partition supported\n");
- }
- encryptable = status;
- }
+ mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
+ i = last_idx_inspected;
+ mount_errno = errno;
- /* Success! Go get the next one */
- continue;
- }
+ /* Deal with encryptability. */
+ if (!mret) {
+ int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]);
- /* mount(2) returned an error, handle the encryptable/formattable case */
- bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
- if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
- fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
- /* top_idx and attempted_idx point at the same partition, but sometimes
- * at two different lines in the fstab. Use the top one for formatting
- * as that is the preferred one.
- */
- ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
- fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
- fstab->recs[top_idx].fs_type);
- if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
- strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
- int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
- if (fd >= 0) {
- INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
- wipe_block_device(fd, get_file_size(fd));
- close(fd);
- } else {
- ERROR("%s(): %s wouldn't open (%s)\n", __func__,
- fstab->recs[top_idx].key_loc, strerror(errno));
+ if (status == FS_MGR_MNTALL_FAIL) {
+ /* Fatal error - no point continuing */
+ return status;
}
- }
- if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
- /* Let's replay the mount actions. */
- i = top_idx - 1;
+
+ if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
+ if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
+ // Log and continue
+ ERROR("Only one encryptable/encrypted partition supported\n");
+ }
+ encryptable = status;
+ }
+
+ /* Success! Go get the next one */
continue;
}
- }
- if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
- fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
- if (wiped) {
- ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_type);
- encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
- continue;
- } else {
- /* Need to mount a tmpfs at this mountpoint for now, and set
- * properties that vold will query later for decrypting
+
+ /* mount(2) returned an error, handle the encryptable/formattable case */
+ bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
+ if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
+ fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
+ /* top_idx and attempted_idx point at the same partition, but sometimes
+ * at two different lines in the fstab. Use the top one for formatting
+ * as that is the preferred one.
*/
- ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_type);
- if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
- ++error_count;
+ ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
+ fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
+ fstab->recs[top_idx].fs_type);
+ if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
+ strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
+ int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
+ if (fd >= 0) {
+ INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
+ wipe_block_device(fd, get_file_size(fd));
+ close(fd);
+ } else {
+ ERROR("%s(): %s wouldn't open (%s)\n", __func__,
+ fstab->recs[top_idx].key_loc, strerror(errno));
+ }
+ }
+ if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
+ /* Let's replay the mount actions. */
+ i = top_idx - 1;
continue;
}
}
- encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
- } else {
- ERROR("Failed to mount an un-encryptable or wiped partition on"
- "%s at %s options: %s error: %s\n",
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
- ++error_count;
- continue;
+ if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
+ fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
+ if (wiped) {
+ ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_type);
+ encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
+ continue;
+ } else {
+ /* Need to mount a tmpfs at this mountpoint for now, and set
+ * properties that vold will query later for decrypting
+ */
+ ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_type);
+ if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
+ ++error_count;
+ continue;
+ }
+ }
+ encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
+ } else {
+ ERROR("Failed to mount an un-encryptable or wiped partition on"
+ "%s at %s options: %s error: %s\n",
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
+ ++error_count;
+ continue;
+ }
}
}
@@ -799,6 +872,14 @@ int fs_mgr_swapon_all(struct fstab *fstab)
*/
FILE *zram_fp;
+ /* The stream count parameter is only available on new kernels.
+ * It must be set before the disk size. */
+ zram_fp = fopen(ZRAM_STREAMS, "r+");
+ if (zram_fp) {
+ fprintf(zram_fp, "%d\n", fstab->recs[i].zram_streams);
+ fclose(zram_fp);
+ }
+
zram_fp = fopen(ZRAM_CONF_DEV, "r+");
if (zram_fp == NULL) {
ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);