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

Commit 69c7bef1 authored by Siim Sammul's avatar Siim Sammul Committed by Android (Google) Code Review
Browse files

Merge "Add a container proto to include dropped counts with proto tombstones....

Merge "Add a container proto to include dropped counts with proto tombstones. This is needed to keep count of how many events get dropped due to rate limiting."
parents e86d5c0e d2fa0380
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

package android.os;

option java_multiple_files = true;

message TombstoneWithHeadersProto {
  // The original proto tombstone bytes.
  // Proto located at: system/core/debuggerd/proto/tombstone.proto
  optional bytes tombstone = 1;

  // The count of dropped dropbox entries due to rate limiting.
  optional int32 dropped_count = 2;
}
 No newline at end of file
+49 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server;

import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.system.OsConstants.O_RDONLY;

import android.content.BroadcastReceiver;
@@ -26,8 +27,10 @@ import android.os.DropBoxManager;
import android.os.Environment;
import android.os.FileUtils;
import android.os.MessageQueue.OnFileDescriptorEventListener;
import android.os.ParcelFileDescriptor;
import android.os.RecoverySystem;
import android.os.SystemProperties;
import android.os.TombstoneWithHeadersProto;
import android.provider.Downloads;
import android.system.ErrnoException;
import android.system.Os;
@@ -38,6 +41,7 @@ import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
@@ -54,6 +58,8 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
@@ -78,6 +84,11 @@ public class BootReceiver extends BroadcastReceiver {

    private static final String TAG_TOMBSTONE = "SYSTEM_TOMBSTONE";
    private static final String TAG_TOMBSTONE_PROTO = "SYSTEM_TOMBSTONE_PROTO";
    private static final String TAG_TOMBSTONE_PROTO_WITH_HEADERS =
            "SYSTEM_TOMBSTONE_PROTO_WITH_HEADERS";

    // Directory to store temporary tombstones.
    private static final File TOMBSTONE_TMP_DIR = new File("/data/tombstones");

    // The pre-froyo package and class of the system updater, which
    // ran in the system process.  We need to remove its packages here
@@ -329,7 +340,44 @@ public class BootReceiver extends BroadcastReceiver {
        try {
            if (proto) {
                if (recordFileTimestamp(tombstone, timestamps)) {
                    db.addFile(TAG_TOMBSTONE_PROTO, tombstone, 0);
                    // We need to attach the count indicating the number of dropped dropbox entries
                    // 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).

                    // Read the proto tombstone file as bytes.
                    final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath());

                    final File tombstoneProtoWithHeaders = File.createTempFile(
                            tombstone.getName(), ".tmp", TOMBSTONE_TMP_DIR);
                    Files.setPosixFilePermissions(
                            tombstoneProtoWithHeaders.toPath(),
                            PosixFilePermissions.fromString("rw-rw----"));

                    // Write the new proto container proto with headers.
                    ParcelFileDescriptor pfd;
                    try {
                        pfd = ParcelFileDescriptor.open(tombstoneProtoWithHeaders, MODE_READ_WRITE);

                        ProtoOutputStream protoStream = new ProtoOutputStream(
                                pfd.getFileDescriptor());
                        protoStream.write(TombstoneWithHeadersProto.TOMBSTONE, tombstoneBytes);
                        protoStream.write(
                                TombstoneWithHeadersProto.DROPPED_COUNT,
                                rateLimitResult.droppedCountSinceRateLimitActivated());
                        protoStream.flush();

                        // Add the proto to dropbox.
                        db.addFile(TAG_TOMBSTONE_PROTO_WITH_HEADERS, tombstoneProtoWithHeaders, 0);
                    } catch (FileNotFoundException ex) {
                        Slog.e(TAG, "failed to open for write: " + tombstoneProtoWithHeaders, ex);
                        throw ex;
                    } finally {
                        // Remove the temporary file.
                        if (tombstoneProtoWithHeaders != null) {
                            tombstoneProtoWithHeaders.delete();
                        }
                    }
                }
            } else {
                // Add the header indicating how many events have been dropped due to rate limiting.
+11 −0
Original line number Diff line number Diff line
@@ -109,6 +109,13 @@ public final class NativeTombstoneManager {

    private void handleTombstone(File path) {
        final String filename = path.getName();

        // Clean up temporary files if they made it this far (e.g. if system server crashes).
        if (filename.endsWith(".tmp")) {
            path.delete();
            return;
        }

        if (!filename.startsWith("tombstone_")) {
            return;
        }
@@ -561,6 +568,10 @@ public final class NativeTombstoneManager {
        @Override
        public void onEvent(int event, @Nullable String path) {
            mHandler.post(() -> {
                // Ignore .tmp files.
                if (path.endsWith(".tmp")) {
                    return;
                }
                handleTombstone(new File(TOMBSTONE_DIR, path));
            });
        }