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

Commit 8d3b31fe authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

snapuserd: Handle real time signal 36



Add a signal handler for real time signal 36 which
is primarily used by profilers. Default action is to
terminate the daemon if there is no signal handler. We
don't want daemon to get terminated, hence just capture
the signal and ignore it.

Bug: 201497662
Test: cow_snapuserd_test, pkill -36 snapuserd
Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
Change-Id: Ife5a8bdb7344956076bc4223c19a126b90a00706
parent bc631759
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ class CowSnapuserdTest final {
    void MergeInterruptRandomly(int max_duration);
    void ReadDmUserBlockWithoutDaemon();
    void ReadLastBlock();
    void TestRealTimeSignal();

    std::string snapshot_dev() const { return snapshot_dev_->path(); }

@@ -152,6 +153,7 @@ class CowSnapuserdTest final {
    size_t size_ = 50_MiB;
    int cow_num_sectors_;
    int total_base_size_;
    pid_t pid_;
};

class CowSnapuserdMetadataTest final {
@@ -254,6 +256,7 @@ void CowSnapuserdTest::StartSnapuserdDaemon() {
    } else {
        client_ = SnapuserdClient::Connect(kSnapuserdSocketTest, 10s);
        ASSERT_NE(client_, nullptr);
        pid_ = pid;
    }
}

@@ -769,6 +772,16 @@ void CowSnapuserdTest::CreateSnapshotDevice() {
    ASSERT_FALSE(snapshot_dev_->path().empty());
}

void CowSnapuserdTest::TestRealTimeSignal() {
    StartSnapuserdDaemon();
    ASSERT_EQ(kill(pid_, 36), 0);  // Real time signal 36
    ASSERT_EQ(kill(pid_, 0), 0);   // Verify pid exists
    ASSERT_TRUE(client_->DetachSnapuserd());
    std::this_thread::sleep_for(1s);
    client_->CloseConnection();
    client_ = nullptr;
}

void CowSnapuserdTest::SetupImpl() {
    CreateBaseDevice();
    CreateCowDevice();
@@ -1278,6 +1291,11 @@ TEST(Snapuserd_Test, Snapshot_Merge_Crash_Random_Inverted) {
    harness.Shutdown();
}

TEST(Snapuserd_Test, Snapshot_TestRealTimeSignal) {
    CowSnapuserdTest harness;
    harness.TestRealTimeSignal();
}

}  // namespace snapshot
}  // namespace android

+9 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ DEFINE_bool(no_socket, false,
DEFINE_bool(socket_handoff, false,
            "If true, perform a socket hand-off with an existing snapuserd instance, then exit.");

constexpr int kProfilingSignal = __SIGRTMIN + 4;

namespace android {
namespace snapshot {

@@ -39,6 +41,7 @@ bool Daemon::StartServer(int argc, char** argv) {
    sigdelset(&signal_mask_, SIGINT);
    sigdelset(&signal_mask_, SIGTERM);
    sigdelset(&signal_mask_, SIGUSR1);
    sigdelset(&signal_mask_, kProfilingSignal);

    // Masking signals here ensure that after this point, we won't handle INT/TERM
    // until after we call into ppoll()
@@ -46,6 +49,7 @@ bool Daemon::StartServer(int argc, char** argv) {
    signal(SIGTERM, Daemon::SignalHandler);
    signal(SIGPIPE, Daemon::SignalHandler);
    signal(SIGUSR1, Daemon::SignalHandler);
    signal(kProfilingSignal, Daemon::SignalHandler);

    MaskAllSignalsExceptIntAndTerm();

@@ -83,6 +87,7 @@ void Daemon::MaskAllSignalsExceptIntAndTerm() {
    sigdelset(&signal_mask, SIGTERM);
    sigdelset(&signal_mask, SIGPIPE);
    sigdelset(&signal_mask, SIGUSR1);
    sigdelset(&signal_mask, kProfilingSignal);
    if (sigprocmask(SIG_SETMASK, &signal_mask, NULL) != 0) {
        PLOG(ERROR) << "Failed to set sigprocmask";
    }
@@ -116,6 +121,10 @@ void Daemon::SignalHandler(int signal) {
            LOG(ERROR) << "Received SIGPIPE signal";
            break;
        }
        case kProfilingSignal: {
            LOG(INFO) << "Received real-time signal SIGRTMIN+4";
            break;
        }
        case SIGUSR1: {
            LOG(INFO) << "Received SIGUSR1, attaching to proxy socket";
            Daemon::Instance().ReceivedSocketSignal();