From 60788050236ff77f84675e12efe9dba098e49870 Mon Sep 17 00:00:00 2001 From: Michael Lentine Date: Mon, 18 May 2015 13:04:01 -0700 Subject: [PATCH] Adding a build id check to blob cache. Add a build id field to the header structure in blob cache. Add build id support with reading and writing the cache. When the cache gets written it writes the build id at the end of the header. When read it checks to see if there is a match between the current version and the version in the cache. If not, it invalidates the cache which would typically only occur during an ota update. Also remove blob cache from the host build. bug: 18262905 Change-Id: I753b1de1986703a4c1c8691b9d2bb533b2546143 --- include/utils/BlobCache.h | 6 ++++++ libutils/Android.mk | 5 +++-- libutils/BlobCache.cpp | 19 ++++++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/utils/BlobCache.h b/include/utils/BlobCache.h index 7d621e438..65dca9fb4 100644 --- a/include/utils/BlobCache.h +++ b/include/utils/BlobCache.h @@ -185,6 +185,12 @@ private: // mNumEntries is number of cache entries following the header in the // data. size_t mNumEntries; + + // mBuildId is the build id of the device when the cache was created. + // When an update to the build happens (via an OTA or other update) this + // is used to invalidate the cache. + int mBuildIdLength; + char mBuildId[]; }; // An EntryHeader is the header for a serialized cache entry. No need to diff --git a/libutils/Android.mk b/libutils/Android.mk index f675a94e8..40cd31e70 100644 --- a/libutils/Android.mk +++ b/libutils/Android.mk @@ -16,7 +16,6 @@ LOCAL_PATH:= $(call my-dir) commonSources:= \ BasicHashtable.cpp \ - BlobCache.cpp \ CallStack.cpp \ FileMap.cpp \ JenkinsHash.cpp \ @@ -74,6 +73,7 @@ include $(CLEAR_VARS) # we have the common sources, plus some device-specific stuff LOCAL_SRC_FILES:= \ $(commonSources) \ + BlobCache.cpp \ Looper.cpp \ Trace.cpp @@ -83,7 +83,8 @@ endif LOCAL_CFLAGS += -Werror LOCAL_STATIC_LIBRARIES := \ - libcutils + libcutils \ + libc LOCAL_SHARED_LIBRARIES := \ libbacktrace \ diff --git a/libutils/BlobCache.cpp b/libutils/BlobCache.cpp index 0ea09cfa8..126995b8c 100644 --- a/libutils/BlobCache.cpp +++ b/libutils/BlobCache.cpp @@ -25,13 +25,15 @@ #include #include +#include + namespace android { // BlobCache::Header::mMagicNumber value static const uint32_t blobCacheMagic = ('_' << 24) + ('B' << 16) + ('b' << 8) + '$'; // BlobCache::Header::mBlobCacheVersion value -static const uint32_t blobCacheVersion = 2; +static const uint32_t blobCacheVersion = 3; // BlobCache::Header::mDeviceVersion value static const uint32_t blobCacheDeviceVersion = 1; @@ -165,7 +167,7 @@ static inline size_t align4(size_t size) { } size_t BlobCache::getFlattenedSize() const { - size_t size = align4(sizeof(Header)); + size_t size = align4(sizeof(Header) + PROPERTY_VALUE_MAX); for (size_t i = 0; i < mCacheEntries.size(); i++) { const CacheEntry& e(mCacheEntries[i]); sp keyBlob = e.getKey(); @@ -187,10 +189,13 @@ status_t BlobCache::flatten(void* buffer, size_t size) const { header->mBlobCacheVersion = blobCacheVersion; header->mDeviceVersion = blobCacheDeviceVersion; header->mNumEntries = mCacheEntries.size(); + char buildId[PROPERTY_VALUE_MAX]; + header->mBuildIdLength = property_get("ro.build.id", buildId, ""); + memcpy(header->mBuildId, buildId, header->mBuildIdLength); // Write cache entries uint8_t* byteBuffer = reinterpret_cast(buffer); - off_t byteOffset = align4(sizeof(Header)); + off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength); for (size_t i = 0; i < mCacheEntries.size(); i++) { const CacheEntry& e(mCacheEntries[i]); sp keyBlob = e.getKey(); @@ -239,15 +244,19 @@ status_t BlobCache::unflatten(void const* buffer, size_t size) { ALOGE("unflatten: bad magic number: %" PRIu32, header->mMagicNumber); return BAD_VALUE; } + char buildId[PROPERTY_VALUE_MAX]; + int len = property_get("ro.build.id", buildId, ""); if (header->mBlobCacheVersion != blobCacheVersion || - header->mDeviceVersion != blobCacheDeviceVersion) { + header->mDeviceVersion != blobCacheDeviceVersion || + len != header->mBuildIdLength || + strncmp(buildId, header->mBuildId, len)) { // We treat version mismatches as an empty cache. return OK; } // Read cache entries const uint8_t* byteBuffer = reinterpret_cast(buffer); - off_t byteOffset = align4(sizeof(Header)); + off_t byteOffset = align4(sizeof(Header) + header->mBuildIdLength); size_t numEntries = header->mNumEntries; for (size_t i = 0; i < numEntries; i++) { if (byteOffset + sizeof(EntryHeader) > size) {