Merge changes I49495684,I0db2e0f4,I07bb811b
* changes: init: Initiate other misc devices from BlockDevInitializer. Allow snapuserd to be included in the initial ramdisk. Add experimental daemon for handling dm-user requests.
This commit is contained in:
commit
67665a4571
6 changed files with 176 additions and 4 deletions
|
@ -42,6 +42,7 @@ cc_library_static {
|
|||
enabled: false,
|
||||
},
|
||||
},
|
||||
ramdisk_available: true,
|
||||
}
|
||||
|
||||
filegroup {
|
||||
|
|
|
@ -310,3 +310,36 @@ cc_test {
|
|||
auto_gen_config: 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
fs_mgr/libsnapshot/snapuserd.cpp
Normal file
126
fs_mgr/libsnapshot/snapuserd.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -37,7 +37,15 @@ BlockDevInitializer::BlockDevInitializer() : uevent_listener_(16 * 1024 * 1024)
|
|||
}
|
||||
|
||||
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;
|
||||
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
|
||||
if (uevent.path == dm_path) {
|
||||
|
@ -49,13 +57,13 @@ bool BlockDevInitializer::InitDeviceMapper() {
|
|||
};
|
||||
uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
|
||||
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;
|
||||
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) {
|
||||
LOG(ERROR) << "device-mapper device not found after polling timeout";
|
||||
LOG(ERROR) << name << " device not found after polling timeout";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -27,12 +27,15 @@ class BlockDevInitializer final {
|
|||
BlockDevInitializer();
|
||||
|
||||
bool InitDeviceMapper();
|
||||
bool InitDmUser();
|
||||
bool InitDevices(std::set<std::string> devices);
|
||||
bool InitDmDevice(const std::string& device);
|
||||
|
||||
private:
|
||||
ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);
|
||||
|
||||
bool InitMiscDevice(const std::string& name);
|
||||
|
||||
std::unique_ptr<DeviceHandler> device_handler_;
|
||||
UeventListener uevent_listener_;
|
||||
};
|
||||
|
|
|
@ -203,6 +203,7 @@ static const struct fs_path_config android_files[] = {
|
|||
{ 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/e2fsck" },
|
||||
{ 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/tune2fs" },
|
||||
{ 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/resize2fs" },
|
||||
{ 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/snapuserd" },
|
||||
// generic defaults
|
||||
{ 00755, AID_ROOT, AID_ROOT, 0, "bin/*" },
|
||||
{ 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
|
||||
|
|
Loading…
Reference in a new issue