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

Commit cfe6ac39 authored by David Anderson's avatar David Anderson Committed by Automerger Merge Worker
Browse files

Merge changes I49495684,I0db2e0f4,I07bb811b am: 67665a45 am: f6016177 am:...

Merge changes I49495684,I0db2e0f4,I07bb811b am: 67665a45 am: f6016177 am: 44cb302f am: 601c99ba am: b28cb9c7

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1358187

Change-Id: I3e70329ab9656efcf286f7b51d8deec2d36328e0
parents 8e41056f b28cb9c7
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ cc_library_static {
            enabled: false,
            enabled: false,
        },
        },
    },
    },
    ramdisk_available: true,
}
}


filegroup {
filegroup {
+33 −0
Original line number Original line Diff line number Diff line
@@ -310,3 +310,36 @@ cc_test {
    auto_gen_config: true,
    auto_gen_config: true,
    require_root: true,
    require_root: true,
}
}

cc_defaults {
    name: "snapuserd_defaults",
    srcs: [
        "snapuserd.cpp",
    ],

    cflags: [
        "-Wall",
        "-Werror"
    ],

    static_libs: [
        "libbase",
        "liblog",
        "libdm",
    ],
}

cc_binary {
    name: "snapuserd",
    defaults: ["snapuserd_defaults"],
}

cc_binary {
    name: "snapuserd_ramdisk",
    stem: "snapuserd",
    defaults: ["snapuserd_defaults"],

    ramdisk: true,
    static_executable: true,
    system_shared_libs: [],
}
+126 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

#include <linux/types.h>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <libdm/dm.h>

using android::base::unique_fd;

#define DM_USER_MAP_READ 0
#define DM_USER_MAP_WRITE 1

struct dm_user_message {
    __u64 seq;
    __u64 type;
    __u64 flags;
    __u64 sector;
    __u64 len;
    __u8 buf[];
};

using namespace android::dm;

static int daemon_main(const std::string& device) {
    unique_fd block_fd(open(device.c_str(), O_RDWR));
    if (block_fd < 0) {
        PLOG(ERROR) << "Unable to open " << device;
        return 1;
    }

    unique_fd ctrl_fd(open("/dev/dm-user", O_RDWR));
    if (ctrl_fd < 0) {
        PLOG(ERROR) << "Unable to open /dev/dm-user";
        return 1;
    }

    size_t buf_size = 1UL << 16;
    auto buf = std::make_unique<char>(buf_size);

    /* Just keeps pumping messages between userspace and the kernel.  We won't
     * actually be doing anything, but the sequence numbers line up so it'll at
     * least make forward progress. */
    while (true) {
        struct dm_user_message* msg = (struct dm_user_message*)buf.get();

        memset(buf.get(), 0, buf_size);

        ssize_t readed = read(ctrl_fd.get(), buf.get(), buf_size);
        if (readed < 0) {
            PLOG(ERROR) << "Control read failed, trying with more space";
            buf_size *= 2;
            buf = std::make_unique<char>(buf_size);
            continue;
        }

        LOG(DEBUG) << android::base::StringPrintf("read() from dm-user returned %d bytes:",
                                                  (int)readed);
        LOG(DEBUG) << android::base::StringPrintf("    msg->seq:    0x%016llx", msg->seq);
        LOG(DEBUG) << android::base::StringPrintf("    msg->type:   0x%016llx", msg->type);
        LOG(DEBUG) << android::base::StringPrintf("    msg->flags:  0x%016llx", msg->flags);
        LOG(DEBUG) << android::base::StringPrintf("    msg->sector: 0x%016llx", msg->sector);
        LOG(DEBUG) << android::base::StringPrintf("    msg->len:    0x%016llx", msg->len);

        switch (msg->type) {
            case DM_USER_MAP_READ: {
                LOG(DEBUG) << android::base::StringPrintf(
                        "Responding to read of sector %lld with %lld bytes data", msg->sector,
                        msg->len);

                if ((sizeof(*msg) + msg->len) > buf_size) {
                    auto old_buf = std::move(buf);
                    buf_size = sizeof(*msg) + msg->len;
                    buf = std::make_unique<char>(buf_size);
                    memcpy(buf.get(), old_buf.get(), sizeof(*msg));
                    msg = (struct dm_user_message*)buf.get();
                }

                if (lseek(block_fd.get(), msg->sector * 512, SEEK_SET) < 0) {
                    PLOG(ERROR) << "lseek failed: " << device;
                    return 7;
                }
                if (!android::base::ReadFully(block_fd.get(), msg->buf, msg->len)) {
                    PLOG(ERROR) << "read failed: " << device;
                    return 7;
                }

                if (!android::base::WriteFully(ctrl_fd.get(), buf.get(), sizeof(*msg) + msg->len)) {
                    PLOG(ERROR) << "write control failed";
                    return 3;
                }
                break;
            }

            case DM_USER_MAP_WRITE:
                abort();
                break;
        }

        LOG(DEBUG) << "read() finished, next message";
    }

    return 0;
}

int main([[maybe_unused]] int argc, char** argv) {
    android::base::InitLogging(argv, &android::base::KernelLogger);
    daemon_main(argv[1]);
    return 0;
}
+12 −4
Original line number Original line Diff line number Diff line
@@ -37,7 +37,15 @@ BlockDevInitializer::BlockDevInitializer() : uevent_listener_(16 * 1024 * 1024)
}
}


bool BlockDevInitializer::InitDeviceMapper() {
bool BlockDevInitializer::InitDeviceMapper() {
    const std::string dm_path = "/devices/virtual/misc/device-mapper";
    return InitMiscDevice("device-mapper");
}

bool BlockDevInitializer::InitDmUser() {
    return InitMiscDevice("dm-user");
}

bool BlockDevInitializer::InitMiscDevice(const std::string& name) {
    const std::string dm_path = "/devices/virtual/misc/" + name;
    bool found = false;
    bool found = false;
    auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
    auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
        if (uevent.path == dm_path) {
        if (uevent.path == dm_path) {
@@ -49,13 +57,13 @@ bool BlockDevInitializer::InitDeviceMapper() {
    };
    };
    uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
    uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
    if (!found) {
    if (!found) {
        LOG(INFO) << "device-mapper device not found in /sys, waiting for its uevent";
        LOG(INFO) << name << " device not found in /sys, waiting for its uevent";
        Timer t;
        Timer t;
        uevent_listener_.Poll(dm_callback, 10s);
        uevent_listener_.Poll(dm_callback, 10s);
        LOG(INFO) << "Wait for device-mapper returned after " << t;
        LOG(INFO) << "Wait for " << name << " returned after " << t;
    }
    }
    if (!found) {
    if (!found) {
        LOG(ERROR) << "device-mapper device not found after polling timeout";
        LOG(ERROR) << name << " device not found after polling timeout";
        return false;
        return false;
    }
    }
    return true;
    return true;
+3 −0
Original line number Original line Diff line number Diff line
@@ -27,12 +27,15 @@ class BlockDevInitializer final {
    BlockDevInitializer();
    BlockDevInitializer();


    bool InitDeviceMapper();
    bool InitDeviceMapper();
    bool InitDmUser();
    bool InitDevices(std::set<std::string> devices);
    bool InitDevices(std::set<std::string> devices);
    bool InitDmDevice(const std::string& device);
    bool InitDmDevice(const std::string& device);


  private:
  private:
    ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);
    ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);


    bool InitMiscDevice(const std::string& name);

    std::unique_ptr<DeviceHandler> device_handler_;
    std::unique_ptr<DeviceHandler> device_handler_;
    UeventListener uevent_listener_;
    UeventListener uevent_listener_;
};
};
Loading