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

Commit 0e5ad5a0 authored by David Anderson's avatar David Anderson
Browse files

snapuserd: Allow connecting to the first-stage daemon.

Currently there is no socket for daemon instances launched during the
selinux phase of init. We don't create any sockets due to the complexity
of the required sepolicy.

This workaround will allow us to create the socket with very minimal
sepolicy changes. init will launch a one-off instance of snapuserd in
"proxy" mode, and then the following steps will occur:

1. The proxy daemon will be given two sockets, the "normal" socket that
snapuserd clients would connect to, and a "proxy" socket.
2. The proxy daemon will listen on the proxy socket.
3. The first-stage daemon will wake up and connect to the proxy daemon
as a client.
4. The proxy will send the normal socket via SCM_RIGHTS, then exit.
5. The first-stage daemon can now listen and accept on the normal
socket.

Ordering of these events is achieved through a snapuserd.proxy_ready
property.

Some special-casing was needed in init to make this work. The snapuserd
socket owned by snapuserd_proxy is placed into a "persist" mode so it
doesn't get deleted when snapuserd_proxy exits. There's also a special
case method to create a Service object around a previously existing pid.

Finally, first-stage init is technically on a different updateable
partition than snapuserd. Thus, we add a way to query snapuserd to see
if it supports socket handoff. If it does, we communicate this
information through an environment variable to second-stage init.

Bug: 193833730
Test: manual test
Change-Id: I1950b31028980f0138bc03578cd455eb60ea4a58
parent 0b23b2a3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -206,6 +206,9 @@ bool OneShotInotify::ConsumeEvents() {
}

int64_t OneShotInotify::RemainingMs() const {
    if (relative_timeout_ == std::chrono::milliseconds::max()) {
        return std::chrono::milliseconds::max().count();
    }
    auto remaining = (std::chrono::steady_clock::now() - start_time_);
    auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(remaining);
    return (relative_timeout_ - elapsed).count();
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ namespace fs_mgr {
// Wait at most |relative_timeout| milliseconds for |path| to exist. dirname(path)
// must already exist. For example, to wait on /dev/block/dm-6, /dev/block must
// be a valid directory.
//
// If relative_timeout is std::chrono::milliseconds::max(), then the wait will
// block indefinitely.
bool WaitForFile(const std::string& path, const std::chrono::milliseconds relative_timeout);

// Wait at most |relative_timeout| milliseconds for |path| to stop existing.
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ cc_defaults {
        "libbrotli",
        "libcutils_sockets",
        "libdm",
        "libfs_mgr",
        "libgflags",
        "liblog",
        "libsnapshot_cow",
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ namespace snapshot {
static constexpr uint32_t PACKET_SIZE = 512;

static constexpr char kSnapuserdSocket[] = "snapuserd";
static constexpr char kSnapuserdSocketProxy[] = "snapuserd_proxy";

// Ensure that the second-stage daemon for snapuserd is running.
bool EnsureSnapuserdStarted();
@@ -75,6 +76,9 @@ class SnapuserdClient {
    // snapuserd to gracefully exit once all handler threads have terminated.
    // This should only be used on first-stage instances of snapuserd.
    bool DetachSnapuserd();

    // Returns true if the snapuserd instance supports bridging a socket to second-stage init.
    bool SupportsSecondStageSocketHandoff();
};

}  // namespace snapshot
+9 −0
Original line number Diff line number Diff line
@@ -5,3 +5,12 @@ service snapuserd /system/bin/snapuserd
    user root
    group root system
    seclabel u:r:snapuserd:s0

service snapuserd_proxy /system/bin/snapuserd -socket-handoff
    socket snapuserd stream 0660 system system
    socket snapuserd_proxy seqpacket 0660 system root
    oneshot
    disabled
    user root
    group root system
    seclabel u:r:snapuserd:s0
Loading