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

Commit cff35f67 authored by David Anderson's avatar David Anderson
Browse files

snapuserd: Refactor daemon/server.

This is in preparation for moving to a traditional client/server model
where clients stay connected and the server multiplexes multiple
connections.

Client has been renamed to DmUserClient to differentiate it from local
socket clients.

poll() responsibilities have been moved into SnapuserdServer. In
addition, the server now tracks all open clients and polls them
together with the listen socket.

SnapuserDaemon is now only responsible for signal masking. These two
classes can probably be merged together - I didn't do that here because
the patch was already large.

Bug: 168554689
Test: manual test
Change-Id: Ibc06f6287d49e832a8e25dd936ec07747a1b0555
parent ba8a3097
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ namespace snapshot {
static constexpr uint32_t PACKET_SIZE = 512;
static constexpr uint32_t MAX_CONNECT_RETRY_COUNT = 10;

static constexpr char kSnapuserdSocketFirstStage[] = "snapuserd_first_stage";
static constexpr char kSnapuserdSocket[] = "snapuserd";

class SnapuserdClient {
  private:
    int sockfd_ = 0;
+4 −5
Original line number Diff line number Diff line
@@ -25,22 +25,21 @@ class Daemon {
    // The Daemon class is a singleton to avoid
    // instantiating more than once
  public:
    Daemon() {}

    static Daemon& Instance() {
        static Daemon instance;
        return instance;
    }

    int StartServer(std::string socketname);
    bool IsRunning();
    bool StartServer(const std::string& socketname);
    void Run();
    void Interrupt();

  private:
    bool is_running_;
    std::unique_ptr<struct pollfd> poll_fd_;
    // Signal mask used with ppoll()
    sigset_t signal_mask_;

    Daemon();
    Daemon(Daemon const&) = delete;
    void operator=(Daemon const&) = delete;

+16 −9
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

#pragma once

#include <poll.h>

#include <cstdio>
#include <cstring>
#include <functional>
@@ -34,12 +36,11 @@ static constexpr uint32_t MAX_PACKET_SIZE = 512;
enum class DaemonOperations {
    START,
    QUERY,
    TERMINATING,
    STOP,
    INVALID,
};

class Client {
class DmUserHandler {
  private:
    std::unique_ptr<std::thread> threadHandler_;

@@ -77,7 +78,15 @@ class SnapuserdServer : public Stoppable {
  private:
    android::base::unique_fd sockfd_;
    bool terminating_;
    std::vector<std::unique_ptr<Client>> clients_vec_;
    std::vector<std::unique_ptr<DmUserHandler>> dm_users_;
    std::vector<struct pollfd> watched_fds_;

    void AddWatchedFd(android::base::borrowed_fd fd);
    void AcceptClient();
    bool HandleClient(android::base::borrowed_fd fd, int revents);
    bool Recv(android::base::borrowed_fd fd, std::string* data);
    bool Sendmsg(android::base::borrowed_fd fd, const std::string& msg);
    bool Receivemsg(android::base::borrowed_fd fd, const std::string& msg);

    void ThreadStart(std::string cow_device, std::string backing_device,
                     std::string control_device) override;
@@ -92,13 +101,11 @@ class SnapuserdServer : public Stoppable {

  public:
    SnapuserdServer() { terminating_ = false; }
    ~SnapuserdServer();

    int Start(std::string socketname);
    int AcceptClient();
    int Receivemsg(int fd);
    int Sendmsg(int fd, char* msg, size_t len);
    std::string Recvmsg(int fd, int* ret);
    android::base::borrowed_fd GetSocketFd() { return sockfd_; }
    bool Start(const std::string& socketname);
    bool Run();
    void Interrupt();
};

}  // namespace snapshot
+9 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <csignal>

#include <libsnapshot/snapuserd.h>
#include <libsnapshot/snapuserd_client.h>
#include <libsnapshot/snapuserd_daemon.h>
#include <libsnapshot/snapuserd_server.h>

@@ -476,13 +477,13 @@ int Snapuserd::WriteDmUserPayload(size_t size) {
bool Snapuserd::Init() {
    backing_store_fd_.reset(open(backing_store_device_.c_str(), O_RDONLY));
    if (backing_store_fd_ < 0) {
        LOG(ERROR) << "Open Failed: " << backing_store_device_;
        PLOG(ERROR) << "Open Failed: " << backing_store_device_;
        return false;
    }

    cow_fd_.reset(open(cow_device_.c_str(), O_RDWR));
    if (cow_fd_ < 0) {
        LOG(ERROR) << "Open Failed: " << cow_device_;
        PLOG(ERROR) << "Open Failed: " << cow_device_;
        return false;
    }

@@ -492,7 +493,7 @@ bool Snapuserd::Init() {

    ctrl_fd_.reset(open(control_path.c_str(), O_RDWR));
    if (ctrl_fd_ < 0) {
        LOG(ERROR) << "Unable to open " << control_path;
        PLOG(ERROR) << "Unable to open " << control_path;
        return false;
    }

@@ -623,7 +624,11 @@ int main([[maybe_unused]] int argc, char** argv) {

    android::snapshot::Daemon& daemon = android::snapshot::Daemon::Instance();

    daemon.StartServer(argv[1]);
    std::string socket = android::snapshot::kSnapuserdSocket;
    if (argc >= 2) {
        socket = argv[1];
    }
    daemon.StartServer(socket);
    daemon.Run();

    return 0;
+9 −38
Original line number Diff line number Diff line
@@ -20,16 +20,12 @@
namespace android {
namespace snapshot {

int Daemon::StartServer(std::string socketname) {
    int ret;

    ret = server_.Start(socketname);
    if (ret < 0) {
bool Daemon::StartServer(const std::string& socketname) {
    if (!server_.Start(socketname)) {
        LOG(ERROR) << "Snapuserd daemon failed to start...";
        exit(EXIT_FAILURE);
    }

    return ret;
    return true;
}

void Daemon::MaskAllSignalsExceptIntAndTerm() {
@@ -51,51 +47,26 @@ void Daemon::MaskAllSignals() {
    }
}

Daemon::Daemon() {
    is_running_ = true;
}

bool Daemon::IsRunning() {
    return is_running_;
}

void Daemon::Run() {
    poll_fd_ = std::make_unique<struct pollfd>();
    poll_fd_->fd = server_.GetSocketFd().get();
    poll_fd_->events = POLLIN;

    sigfillset(&signal_mask_);
    sigdelset(&signal_mask_, SIGINT);
    sigdelset(&signal_mask_, SIGTERM);

    // Masking signals here ensure that after this point, we won't handle INT/TERM
    // until after we call into ppoll()
    MaskAllSignals();
    signal(SIGINT, Daemon::SignalHandler);
    signal(SIGTERM, Daemon::SignalHandler);
    signal(SIGPIPE, Daemon::SignalHandler);

    LOG(DEBUG) << "Snapuserd-server: ready to accept connections";

    while (IsRunning()) {
        int ret = ppoll(poll_fd_.get(), 1, nullptr, &signal_mask_);
    MaskAllSignalsExceptIntAndTerm();

        if (ret == -1) {
            PLOG(ERROR) << "Snapuserd:ppoll error";
            break;
        }

        if (poll_fd_->revents == POLLIN) {
            if (server_.AcceptClient() == static_cast<int>(DaemonOperations::STOP)) {
                Daemon::Instance().is_running_ = false;
            }
    server_.Run();
}

        // Mask all signals to ensure that is_running_ can't become false between
        // checking it in the while condition and calling into ppoll()
        MaskAllSignals();
    }
void Daemon::Interrupt() {
    server_.Interrupt();
}

void Daemon::SignalHandler(int signal) {
@@ -103,7 +74,7 @@ void Daemon::SignalHandler(int signal) {
    switch (signal) {
        case SIGINT:
        case SIGTERM: {
            Daemon::Instance().is_running_ = false;
            Daemon::Instance().Interrupt();
            break;
        }
        case SIGPIPE: {
Loading