RRO: Synchronize access to overlays.list
idmap --scan is executed as a part of the pre-loading in ZygoteInit. The pre loading is executed in parallel for each supported architecture (32/64 bit). This will cause a race condition in the creation of the overlays.list file and the idmap files for the system overlays. Apply flock on overlays.list to prevent the file from being thrown away and recreated when it is in use by another Zygote. Cherry-picked from AOSP. Bug: 28032298 Test: manual Change-Id: I51d39f121d207b11181340b68b164b60020f0c61
This commit is contained in:
committed by
Adam Lesinski
parent
52cd2948a6
commit
0fbb608110
@@ -1,5 +1,6 @@
|
||||
#include <dirent.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "idmap.h"
|
||||
@@ -35,16 +36,31 @@ namespace {
|
||||
|
||||
bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
|
||||
{
|
||||
FILE* fout = fopen(filename, "w");
|
||||
// the file is opened for appending so that it doesn't get truncated
|
||||
// before we can guarantee mutual exclusion via the flock
|
||||
FILE* fout = fopen(filename, "a");
|
||||
if (fout == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
|
||||
fclose(fout);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
|
||||
TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
|
||||
fclose(fout);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < overlayVector.size(); ++i) {
|
||||
const Overlay& overlay = overlayVector[i];
|
||||
fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
|
||||
}
|
||||
|
||||
TEMP_FAILURE_RETRY(fflush(fout));
|
||||
TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
|
||||
fclose(fout);
|
||||
|
||||
// Make file world readable since Zygote (running as root) will read
|
||||
@@ -171,9 +187,6 @@ int idmap_scan(const char *target_package_name, const char *target_apk_path,
|
||||
{
|
||||
String8 filename = String8(idmap_dir);
|
||||
filename.appendPath("overlays.list");
|
||||
if (unlink(filename.string()) != 0 && errno != ENOENT) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SortedVector<Overlay> overlayVector;
|
||||
const size_t N = overlay_dirs->size();
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/Trace.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
@@ -767,6 +770,12 @@ void AssetManager::addSystemOverlays(const char* pathOverlaysList,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) {
|
||||
fclose(fin);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
char buf[1024];
|
||||
while (fgets(buf, sizeof(buf), fin)) {
|
||||
// format of each line:
|
||||
@@ -797,6 +806,10 @@ void AssetManager::addSystemOverlays(const char* pathOverlaysList,
|
||||
const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN));
|
||||
#endif
|
||||
fclose(fin);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user