Loading services/core/java/com/android/server/BootReceiver.java +46 −33 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import java.nio.file.Files; import java.nio.file.attribute.PosixFilePermissions; import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -328,9 +329,11 @@ public class BootReceiver extends BroadcastReceiver { * @param tombstone path to the tombstone * @param proto whether the tombstone is stored as proto * @param processName the name of the process corresponding to the tombstone * @param tmpFileLock the lock for reading/writing tmp files */ public static void addTombstoneToDropBox( Context ctx, File tombstone, boolean proto, String processName) { Context ctx, File tombstone, boolean proto, String processName, ReentrantLock tmpFileLock) { final DropBoxManager db = ctx.getSystemService(DropBoxManager.class); if (db == null) { Slog.e(TAG, "Can't log tombstone: DropBoxManager not available"); Loading @@ -351,7 +354,29 @@ public class BootReceiver extends BroadcastReceiver { // due to rate limiting. Do this by enclosing the proto tombsstone in a // container proto that has the dropped entry count and the proto tombstone as // bytes (to avoid the complexity of reading and writing nested protos). tmpFileLock.lock(); try { addAugmentedProtoToDropbox(tombstone, db, rateLimitResult); } finally { tmpFileLock.unlock(); } } } else { // Add the header indicating how many events have been dropped due to rate limiting. final String headers = getBootHeadersToLogAndUpdate() + rateLimitResult.createHeader(); addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE, TAG_TOMBSTONE); } } catch (IOException e) { Slog.e(TAG, "Can't log tombstone", e); } writeTimestamps(timestamps); } private static void addAugmentedProtoToDropbox( File tombstone, DropBoxManager db, DropboxRateLimiter.RateLimitResult rateLimitResult) throws IOException { // Read the proto tombstone file as bytes. final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath()); Loading @@ -364,8 +389,8 @@ public class BootReceiver extends BroadcastReceiver { // Write the new proto container proto with headers. try (ParcelFileDescriptor pfd = ParcelFileDescriptor.open( tombstoneProtoWithHeaders, MODE_READ_WRITE)) { ProtoOutputStream protoStream = new ProtoOutputStream( pfd.getFileDescriptor()); ProtoOutputStream protoStream = new ProtoOutputStream(pfd.getFileDescriptor()); protoStream.write(TombstoneWithHeadersProto.TOMBSTONE, tombstoneBytes); protoStream.write( TombstoneWithHeadersProto.DROPPED_COUNT, Loading @@ -380,24 +405,12 @@ public class BootReceiver extends BroadcastReceiver { } catch (IOException ex) { Slog.e(TAG, "IO exception during write: " + tombstoneProtoWithHeaders, ex); } finally { // Remove the temporary file. // Remove the temporary file and unlock the lock. if (tombstoneProtoWithHeaders != null) { tombstoneProtoWithHeaders.delete(); } } } } else { // Add the header indicating how many events have been dropped due to rate limiting. final String headers = getBootHeadersToLogAndUpdate() + rateLimitResult.createHeader(); addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE, TAG_TOMBSTONE); } } catch (IOException e) { Slog.e(TAG, "Can't log tombstone", e); } writeTimestamps(timestamps); } private static void addLastkToDropBox( DropBoxManager db, HashMap<String, Long> timestamps, Loading services/core/java/com/android/server/os/NativeTombstoneManager.java +10 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import java.util.Collections; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReentrantLock; /** * A class to manage native tombstones. Loading @@ -74,6 +75,8 @@ public final class NativeTombstoneManager { private final Handler mHandler; private final TombstoneWatcher mWatcher; private final ReentrantLock mTmpFileLock = new ReentrantLock(); private final Object mLock = new Object(); @GuardedBy("mLock") Loading Loading @@ -112,7 +115,12 @@ public final class NativeTombstoneManager { // Clean up temporary files if they made it this far (e.g. if system server crashes). if (filename.endsWith(".tmp")) { mTmpFileLock.lock(); try { path.delete(); } finally { mTmpFileLock.unlock(); } return; } Loading @@ -128,7 +136,7 @@ public final class NativeTombstoneManager { if (parsedTombstone.isPresent()) { processName = parsedTombstone.get().getProcessName(); } BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName); BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName, mTmpFileLock); } private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) { Loading Loading
services/core/java/com/android/server/BootReceiver.java +46 −33 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import java.nio.file.Files; import java.nio.file.attribute.PosixFilePermissions; import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -328,9 +329,11 @@ public class BootReceiver extends BroadcastReceiver { * @param tombstone path to the tombstone * @param proto whether the tombstone is stored as proto * @param processName the name of the process corresponding to the tombstone * @param tmpFileLock the lock for reading/writing tmp files */ public static void addTombstoneToDropBox( Context ctx, File tombstone, boolean proto, String processName) { Context ctx, File tombstone, boolean proto, String processName, ReentrantLock tmpFileLock) { final DropBoxManager db = ctx.getSystemService(DropBoxManager.class); if (db == null) { Slog.e(TAG, "Can't log tombstone: DropBoxManager not available"); Loading @@ -351,7 +354,29 @@ public class BootReceiver extends BroadcastReceiver { // due to rate limiting. Do this by enclosing the proto tombsstone in a // container proto that has the dropped entry count and the proto tombstone as // bytes (to avoid the complexity of reading and writing nested protos). tmpFileLock.lock(); try { addAugmentedProtoToDropbox(tombstone, db, rateLimitResult); } finally { tmpFileLock.unlock(); } } } else { // Add the header indicating how many events have been dropped due to rate limiting. final String headers = getBootHeadersToLogAndUpdate() + rateLimitResult.createHeader(); addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE, TAG_TOMBSTONE); } } catch (IOException e) { Slog.e(TAG, "Can't log tombstone", e); } writeTimestamps(timestamps); } private static void addAugmentedProtoToDropbox( File tombstone, DropBoxManager db, DropboxRateLimiter.RateLimitResult rateLimitResult) throws IOException { // Read the proto tombstone file as bytes. final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath()); Loading @@ -364,8 +389,8 @@ public class BootReceiver extends BroadcastReceiver { // Write the new proto container proto with headers. try (ParcelFileDescriptor pfd = ParcelFileDescriptor.open( tombstoneProtoWithHeaders, MODE_READ_WRITE)) { ProtoOutputStream protoStream = new ProtoOutputStream( pfd.getFileDescriptor()); ProtoOutputStream protoStream = new ProtoOutputStream(pfd.getFileDescriptor()); protoStream.write(TombstoneWithHeadersProto.TOMBSTONE, tombstoneBytes); protoStream.write( TombstoneWithHeadersProto.DROPPED_COUNT, Loading @@ -380,24 +405,12 @@ public class BootReceiver extends BroadcastReceiver { } catch (IOException ex) { Slog.e(TAG, "IO exception during write: " + tombstoneProtoWithHeaders, ex); } finally { // Remove the temporary file. // Remove the temporary file and unlock the lock. if (tombstoneProtoWithHeaders != null) { tombstoneProtoWithHeaders.delete(); } } } } else { // Add the header indicating how many events have been dropped due to rate limiting. final String headers = getBootHeadersToLogAndUpdate() + rateLimitResult.createHeader(); addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE, TAG_TOMBSTONE); } } catch (IOException e) { Slog.e(TAG, "Can't log tombstone", e); } writeTimestamps(timestamps); } private static void addLastkToDropBox( DropBoxManager db, HashMap<String, Long> timestamps, Loading
services/core/java/com/android/server/os/NativeTombstoneManager.java +10 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import java.util.Collections; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReentrantLock; /** * A class to manage native tombstones. Loading @@ -74,6 +75,8 @@ public final class NativeTombstoneManager { private final Handler mHandler; private final TombstoneWatcher mWatcher; private final ReentrantLock mTmpFileLock = new ReentrantLock(); private final Object mLock = new Object(); @GuardedBy("mLock") Loading Loading @@ -112,7 +115,12 @@ public final class NativeTombstoneManager { // Clean up temporary files if they made it this far (e.g. if system server crashes). if (filename.endsWith(".tmp")) { mTmpFileLock.lock(); try { path.delete(); } finally { mTmpFileLock.unlock(); } return; } Loading @@ -128,7 +136,7 @@ public final class NativeTombstoneManager { if (parsedTombstone.isPresent()) { processName = parsedTombstone.get().getProcessName(); } BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName); BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName, mTmpFileLock); } private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) { Loading