Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70c967ae authored by Siim Sammul's avatar Siim Sammul Committed by Gerrit Code Review
Browse files

Merge "Add a lock when writing temporary files in BootReceiver" into main

parents 693bf0c2 46ea5200
Loading
Loading
Loading
Loading
+46 −33
Original line number Diff line number Diff line
@@ -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;

@@ -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");
@@ -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());

@@ -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,
@@ -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,
+10 −2
Original line number Diff line number Diff line
@@ -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.
@@ -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")
@@ -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;
        }

@@ -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) {