cryptfs: [HACK] reboot if the crypto block dev failed to open
There are cases where the /dev/block/dm-0 fails to open.
This leads to the device not completing the boot up sequence.
Currently, the only way out is to reboot.
Bug: 17898962
Change-Id: If4583ebb1ef1ebdbaf680d69b876459aaec2f4ce
(cherry picked from commit 7fc1de8a44
)
This commit is contained in:
parent
7776871d82
commit
512f0d52ac
2 changed files with 46 additions and 20 deletions
61
cryptfs.c
61
cryptfs.c
|
@ -2431,20 +2431,20 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
|
if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
|
||||||
SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
|
SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n",
|
||||||
crypto_blkdev, errno, strerror(errno));
|
crypto_blkdev, errno, strerror(errno));
|
||||||
rc = -1;
|
rc = ENABLE_INPLACE_ERR_DEV;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setjmp(setjmp_env)) {
|
if (setjmp(setjmp_env)) {
|
||||||
SLOGE("Reading extent caused an exception");
|
SLOGE("Reading ext4 extent caused an exception\n");
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_ext(data.realfd, 0) != 0) {
|
if (read_ext(data.realfd, 0) != 0) {
|
||||||
SLOGE("Failed to read extent");
|
SLOGE("Failed to read ext4 extent\n");
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
@ -2453,7 +2453,7 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev,
|
||||||
data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
|
data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
|
||||||
data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
|
data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
|
||||||
|
|
||||||
SLOGI("Encrypting filesystem in place...");
|
SLOGI("Encrypting ext4 filesystem in place...");
|
||||||
|
|
||||||
data.tot_used_blocks = data.numblocks;
|
data.tot_used_blocks = data.numblocks;
|
||||||
for (i = 0; i < aux_info.groups; ++i) {
|
for (i = 0; i < aux_info.groups; ++i) {
|
||||||
|
@ -2521,12 +2521,12 @@ static int encrypt_one_block_f2fs(u64 pos, void *data)
|
||||||
off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;
|
off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;
|
||||||
|
|
||||||
if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
|
if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
|
||||||
SLOGE("Error reading real_blkdev %s for inplace encrypt", priv_dat->crypto_blkdev);
|
SLOGE("Error reading real_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
|
if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
|
||||||
SLOGE("Error writing crypto_blkdev %s for inplace encrypt", priv_dat->crypto_blkdev);
|
SLOGE("Error writing crypto_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
log_progress_f2fs(pos, false);
|
log_progress_f2fs(pos, false);
|
||||||
|
@ -2545,10 +2545,10 @@ static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
|
||||||
u32 i;
|
u32 i;
|
||||||
struct encryptGroupsData data;
|
struct encryptGroupsData data;
|
||||||
struct f2fs_info *f2fs_info = NULL;
|
struct f2fs_info *f2fs_info = NULL;
|
||||||
int rc = -1;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
if (previously_encrypted_upto > *size_already_done) {
|
if (previously_encrypted_upto > *size_already_done) {
|
||||||
SLOGD("Not fast encrypting since resuming part way through");
|
SLOGD("Not fast encrypting since resuming part way through");
|
||||||
return -1;
|
return ENABLE_INPLACE_ERR_OTHER;
|
||||||
}
|
}
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.real_blkdev = real_blkdev;
|
data.real_blkdev = real_blkdev;
|
||||||
|
@ -2556,13 +2556,14 @@ static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
|
||||||
data.realfd = -1;
|
data.realfd = -1;
|
||||||
data.cryptofd = -1;
|
data.cryptofd = -1;
|
||||||
if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
|
if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
|
||||||
SLOGE("Error opening real_blkdev %s for inplace encrypt\n",
|
SLOGE("Error opening real_blkdev %s for f2fs inplace encrypt\n",
|
||||||
real_blkdev);
|
real_blkdev);
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
|
if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
|
||||||
SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
|
SLOGE("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n",
|
||||||
crypto_blkdev, errno, strerror(errno));
|
crypto_blkdev, errno, strerror(errno));
|
||||||
|
rc = ENABLE_INPLACE_ERR_DEV;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2593,7 +2594,8 @@ static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
|
||||||
rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);
|
rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SLOGE("Error in running over blocks");
|
SLOGE("Error in running over f2fs blocks");
|
||||||
|
rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2620,21 +2622,21 @@ static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev,
|
||||||
{
|
{
|
||||||
int realfd, cryptofd;
|
int realfd, cryptofd;
|
||||||
char *buf[CRYPT_INPLACE_BUFSIZE];
|
char *buf[CRYPT_INPLACE_BUFSIZE];
|
||||||
int rc = -1;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
off64_t numblocks, i, remainder;
|
off64_t numblocks, i, remainder;
|
||||||
off64_t one_pct, cur_pct, new_pct;
|
off64_t one_pct, cur_pct, new_pct;
|
||||||
off64_t blocks_already_done, tot_numblocks;
|
off64_t blocks_already_done, tot_numblocks;
|
||||||
|
|
||||||
if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) {
|
if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) {
|
||||||
SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
|
SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
|
||||||
return -1;
|
return ENABLE_INPLACE_ERR_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
|
if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
|
||||||
SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
|
SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
|
||||||
crypto_blkdev, errno, strerror(errno));
|
crypto_blkdev, errno, strerror(errno));
|
||||||
close(realfd);
|
close(realfd);
|
||||||
return -1;
|
return ENABLE_INPLACE_ERR_DEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is pretty much a simple loop of reading 4K, and writing 4K.
|
/* This is pretty much a simple loop of reading 4K, and writing 4K.
|
||||||
|
@ -2733,11 +2735,13 @@ errout:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns on of the ENABLE_INPLACE_* return codes */
|
||||||
static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
|
static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
|
||||||
off64_t size, off64_t *size_already_done,
|
off64_t size, off64_t *size_already_done,
|
||||||
off64_t tot_size,
|
off64_t tot_size,
|
||||||
off64_t previously_encrypted_upto)
|
off64_t previously_encrypted_upto)
|
||||||
{
|
{
|
||||||
|
int rc_ext4, rc_f2fs, rc_full;
|
||||||
if (previously_encrypted_upto) {
|
if (previously_encrypted_upto) {
|
||||||
SLOGD("Continuing encryption from %" PRId64, previously_encrypted_upto);
|
SLOGD("Continuing encryption from %" PRId64, previously_encrypted_upto);
|
||||||
}
|
}
|
||||||
|
@ -2751,21 +2755,32 @@ static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
|
||||||
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
||||||
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
||||||
* */
|
* */
|
||||||
if (cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
|
if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
|
||||||
size, size_already_done,
|
size, size_already_done,
|
||||||
tot_size, previously_encrypted_upto) == 0) {
|
tot_size, previously_encrypted_upto)) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
SLOGD("cryptfs_enable_inplace_ext4()=%d\n", rc_ext4);
|
||||||
|
|
||||||
if (cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
|
if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
|
||||||
size, size_already_done,
|
size, size_already_done,
|
||||||
tot_size, previously_encrypted_upto) == 0) {
|
tot_size, previously_encrypted_upto)) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
SLOGD("cryptfs_enable_inplace_f2fs()=%d\n", rc_f2fs);
|
||||||
|
|
||||||
return cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
|
rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
|
||||||
size, size_already_done, tot_size,
|
size, size_already_done, tot_size,
|
||||||
previously_encrypted_upto);
|
previously_encrypted_upto);
|
||||||
|
SLOGD("cryptfs_enable_inplace_full()=%d\n", rc_full);
|
||||||
|
|
||||||
|
/* Hack for b/17898962, the following is the symptom... */
|
||||||
|
if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
|
||||||
|
&& rc_f2fs == ENABLE_INPLACE_ERR_DEV
|
||||||
|
&& rc_full == ENABLE_INPLACE_ERR_DEV) {
|
||||||
|
return ENABLE_INPLACE_ERR_DEV;
|
||||||
|
}
|
||||||
|
return rc_full;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CRYPTO_ENABLE_WIPE 1
|
#define CRYPTO_ENABLE_WIPE 1
|
||||||
|
@ -2845,6 +2860,12 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
|
||||||
tot_encryption_size,
|
tot_encryption_size,
|
||||||
previously_encrypted_upto);
|
previously_encrypted_upto);
|
||||||
|
|
||||||
|
if (rc == ENABLE_INPLACE_ERR_DEV) {
|
||||||
|
/* Hack for b/17898962 */
|
||||||
|
SLOGE("cryptfs_enable: crypto block dev failure. Must reboot...\n");
|
||||||
|
cryptfs_reboot(reboot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
crypt_ftr->encrypted_upto = cur_encryption_done;
|
crypt_ftr->encrypted_upto = cur_encryption_done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,11 @@ struct volume_info {
|
||||||
#define CRYPTO_COMPLETE_INCONSISTENT -3
|
#define CRYPTO_COMPLETE_INCONSISTENT -3
|
||||||
#define CRYPTO_COMPLETE_CORRUPT -4
|
#define CRYPTO_COMPLETE_CORRUPT -4
|
||||||
|
|
||||||
|
/* Return values for cryptfs_enable_inplace*() */
|
||||||
|
#define ENABLE_INPLACE_OK 0
|
||||||
|
#define ENABLE_INPLACE_ERR_OTHER -1
|
||||||
|
#define ENABLE_INPLACE_ERR_DEV -2 /* crypto_blkdev issue */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue