summaryrefslogtreecommitdiff
path: root/cryptfs.cpp
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-03-04 05:09:52 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-03-04 05:09:52 +0000
commit332d1ec143d02821bdd41bd974d913965131153b (patch)
tree6e473a37fc7fae282be077b43e992a9721b6126b /cryptfs.cpp
parentf06148d31c7208df4ad82d4f1cc6d3812d58b409 (diff)
parent20f9f29d53f12077125ae9a85024b1d1dead8d94 (diff)
downloadvold-332d1ec143d02821bdd41bd974d913965131153b.tar.gz
Merge "umount /data/user/0 before umount /data" am: 3a0fd35b62 am: 20f9f29d53
Change-Id: I0cef7deb44c9b55d7f9adbc7022bb484086449c9
Diffstat (limited to 'cryptfs.cpp')
-rw-r--r--cryptfs.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 14314597..1ddb34b2 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -32,6 +32,7 @@
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <bootloader_message/bootloader_message.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
@@ -54,6 +55,7 @@
#include <libgen.h>
#include <linux/kdev_t.h>
#include <math.h>
+#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -1396,8 +1398,46 @@ static int create_encrypted_random_key(const char* passwd, unsigned char* master
return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
}
+static void ensure_subdirectory_unmounted(const char *prefix) {
+ std::vector<std::string> umount_points;
+ std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "r"), endmntent);
+ if (!mnts) {
+ SLOGW("could not read mount files");
+ return;
+ }
+
+ //Find sudirectory mount point
+ mntent* mentry;
+ std::string top_directory(prefix);
+ if (!android::base::EndsWith(prefix, "/")) {
+ top_directory = top_directory + "/";
+ }
+ while ((mentry = getmntent(mnts.get())) != nullptr) {
+ if (strcmp(mentry->mnt_dir, top_directory.c_str()) == 0) {
+ continue;
+ }
+
+ if (android::base::StartsWith(mentry->mnt_dir, top_directory)) {
+ SLOGW("found sub-directory mount %s - %s\n", prefix, mentry->mnt_dir);
+ umount_points.push_back(mentry->mnt_dir);
+ }
+ }
+
+ //Sort by path length to umount longest path first
+ std::sort(std::begin(umount_points), std::end(umount_points),
+ [](const std::string& s1, const std::string& s2) {return s1.length() > s2.length(); });
+
+ for (std::string& mount_point : umount_points) {
+ umount(mount_point.c_str());
+ SLOGW("umount sub-directory mount %s\n", mount_point.c_str());
+ }
+}
+
static int wait_and_unmount(const char* mountpoint, bool kill) {
int i, err, rc;
+
+ // Subdirectory mount will cause a failure of umount.
+ ensure_subdirectory_unmounted(mountpoint);
#define WAIT_UNMOUNT_COUNT 20
/* Now umount the tmpfs filesystem */