cryptfs: kill processes with open files on tmpfs /data

cryptfs will fail to remount /data at boot if any processes (e.g.
dex2oat) have files open on the tmpfs /data partition.  Since these
files are about to be destroyed anyway, just kill the offending
processes: first with SIGHUP and finally with SIGKILL.

Also remove a stray i++ that effectively cut the number of retries in
half.

Bug: 17576594

Change-Id: I76fb90ce2e52846ffb9de706e52b7bde98b4186a
Signed-off-by: Greg Hackmann <ghackmann@google.com>
This commit is contained in:
Greg Hackmann 2014-10-02 17:18:20 -07:00
parent 9c58a871f9
commit 6e8440fd50

View file

@ -1427,28 +1427,40 @@ static int create_encrypted_random_key(char *passwd, unsigned char *master_key,
return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
}
static int wait_and_unmount(char *mountpoint)
static int wait_and_unmount(char *mountpoint, bool kill)
{
int i, err, rc;
#define WAIT_UNMOUNT_COUNT 20
/* Now umount the tmpfs filesystem */
for (i=0; i<WAIT_UNMOUNT_COUNT; i++) {
if (umount(mountpoint)) {
if (umount(mountpoint) == 0) {
break;
}
if (errno == EINVAL) {
/* EINVAL is returned if the directory is not a mountpoint,
* i.e. there is no filesystem mounted there. So just get out.
*/
break;
}
err = errno;
sleep(1);
i++;
} else {
break;
/* If allowed, be increasingly aggressive before the last two retries */
if (kill) {
if (i == (WAIT_UNMOUNT_COUNT - 3)) {
SLOGW("sending SIGHUP to processes with open files\n");
vold_killProcessesWithOpenFiles(mountpoint, 1);
} else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
SLOGW("sending SIGKILL to processes with open files\n");
vold_killProcessesWithOpenFiles(mountpoint, 2);
}
}
sleep(1);
}
if (i < WAIT_UNMOUNT_COUNT) {
SLOGD("unmounting %s succeeded\n", mountpoint);
rc = 0;
@ -1588,7 +1600,7 @@ static int cryptfs_restart_internal(int restart_main)
return -1;
}
if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
if (! (rc = wait_and_unmount(DATA_MNT_POINT, true)) ) {
/* If ro.crypto.readonly is set to 1, mount the decrypted
* filesystem readonly. This is used when /data is mounted by
* recovery mode.
@ -2886,13 +2898,13 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
* above, so just unmount it now. We must do this _AFTER_ killing the framework,
* unlike the case for vold managed devices above.
*/
if (wait_and_unmount(sd_mnt_point)) {
if (wait_and_unmount(sd_mnt_point, false)) {
goto error_shutting_down;
}
}
/* Now unmount the /data partition. */
if (wait_and_unmount(DATA_MNT_POINT)) {
if (wait_and_unmount(DATA_MNT_POINT, false)) {
if (allow_reboot) {
goto error_shutting_down;
} else {