snapuserd: Remove dm-user specific code from ReadWorker.
This uses the new IBlockServer abstraction layer instead.
Bug: 288273605
Test: snapuserd_test
Change-Id: Ie9a781e44da7447426706d4874644aabf1be1946
diff --git a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/block_server.h b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/block_server.h
index 3be6d1c..72b73fc 100644
--- a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/block_server.h
+++ b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/block_server.h
@@ -38,7 +38,7 @@
//
// If false is returned, an error will be automatically reported unless
// SendError was called.
- virtual bool RequestSectors(uint64_t sector, size_t size) = 0;
+ virtual bool RequestSectors(uint64_t sector, uint64_t size) = 0;
};
virtual ~IBlockServer() {}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
index 7d2e3a6..ce4be43 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.cpp
@@ -26,18 +26,18 @@
using android::base::unique_fd;
void ReadWorker::CloseFds() {
- ctrl_fd_ = {};
+ block_server_ = {};
backing_store_fd_ = {};
Worker::CloseFds();
}
ReadWorker::ReadWorker(const std::string& cow_device, const std::string& backing_device,
- const std::string& control_device, const std::string& misc_name,
- const std::string& base_path_merge,
- std::shared_ptr<SnapshotHandler> snapuserd)
+ const std::string& misc_name, const std::string& base_path_merge,
+ std::shared_ptr<SnapshotHandler> snapuserd,
+ std::shared_ptr<IBlockServerOpener> opener)
: Worker(cow_device, misc_name, base_path_merge, snapuserd),
backing_store_device_(backing_device),
- control_device_(control_device) {}
+ block_server_opener_(opener) {}
// Start the replace operation. This will read the
// internal COW format and if the block is compressed,
@@ -197,9 +197,9 @@
return false;
}
- ctrl_fd_.reset(open(control_device_.c_str(), O_RDWR));
- if (ctrl_fd_ < 0) {
- SNAP_PLOG(ERROR) << "Unable to open " << control_device_;
+ block_server_ = block_server_opener_->Open(this, PAYLOAD_BUFFER_SZ);
+ if (!block_server_) {
+ SNAP_PLOG(ERROR) << "Unable to open block server";
return false;
}
return true;
@@ -214,7 +214,7 @@
// Start serving IO
while (true) {
- if (!ProcessIORequest()) {
+ if (!block_server_->ProcessRequests()) {
break;
}
}
@@ -225,29 +225,6 @@
return true;
}
-// Send the payload/data back to dm-user misc device.
-bool ReadWorker::WriteDmUserPayload(size_t size) {
- size_t payload_size = size;
- void* buf = bufsink_.GetPayloadBufPtr();
- if (header_response_) {
- payload_size += sizeof(struct dm_user_header);
- buf = bufsink_.GetBufPtr();
- }
-
- if (!android::base::WriteFully(ctrl_fd_, buf, payload_size)) {
- SNAP_PLOG(ERROR) << "Write to dm-user failed size: " << payload_size;
- return false;
- }
-
- // After the first header is sent in response to a request, we cannot
- // send any additional headers.
- header_response_ = false;
-
- // Reset the buffer for use by the next request.
- bufsink_.ResetBufferOffset();
- return true;
-}
-
bool ReadWorker::ReadDataFromBaseDevice(sector_t sector, void* buffer, size_t read_size) {
CHECK(read_size <= BLOCK_SZ);
@@ -281,7 +258,7 @@
std::make_pair(sector, nullptr), SnapshotHandler::compare);
bool not_found = (it == chunk_vec.end() || it->first != sector);
- void* buffer = bufsink_.AcquireBuffer(BLOCK_SZ, size);
+ void* buffer = block_server_->GetResponseBuffer(BLOCK_SZ, size);
if (!buffer) {
SNAP_LOG(ERROR) << "AcquireBuffer failed in ReadAlignedSector";
return false;
@@ -334,7 +311,8 @@
int num_sectors_skip = sector - it->first;
size_t skip_size = num_sectors_skip << SECTOR_SHIFT;
size_t write_size = std::min(size, BLOCK_SZ - skip_size);
- auto buffer = reinterpret_cast<uint8_t*>(bufsink_.AcquireBuffer(BLOCK_SZ, write_size));
+ auto buffer =
+ reinterpret_cast<uint8_t*>(block_server_->GetResponseBuffer(BLOCK_SZ, write_size));
if (!buffer) {
SNAP_LOG(ERROR) << "ProcessCowOp failed to allocate buffer";
return -1;
@@ -462,7 +440,7 @@
CHECK(diff_size <= BLOCK_SZ);
size_t read_size = std::min(remaining_size, diff_size);
- void* buffer = bufsink_.AcquireBuffer(BLOCK_SZ, read_size);
+ void* buffer = block_server_->GetResponseBuffer(BLOCK_SZ, read_size);
if (!buffer) {
SNAP_LOG(ERROR) << "AcquireBuffer failed in ReadUnalignedSector";
return false;
@@ -488,88 +466,17 @@
return true;
}
-void ReadWorker::RespondIOError() {
- struct dm_user_header* header = bufsink_.GetHeaderPtr();
- header->type = DM_USER_RESP_ERROR;
- // This is an issue with the dm-user interface. There
- // is no way to propagate the I/O error back to dm-user
- // if we have already communicated the header back. Header
- // is responded once at the beginning; however I/O can
- // be processed in chunks. If we encounter an I/O error
- // somewhere in the middle of the processing, we can't communicate
- // this back to dm-user.
- //
- // TODO: Fix the interface
- CHECK(header_response_);
-
- WriteDmUserPayload(0);
-}
-
-bool ReadWorker::DmuserReadRequest() {
- struct dm_user_header* header = bufsink_.GetHeaderPtr();
-
+bool ReadWorker::RequestSectors(uint64_t sector, uint64_t len) {
// Unaligned I/O request
- if (!IsBlockAligned(header->sector << SECTOR_SHIFT)) {
- return ReadUnalignedSector(header->sector, header->len);
+ if (!IsBlockAligned(sector << SECTOR_SHIFT)) {
+ return ReadUnalignedSector(sector, len);
}
- return ReadAlignedSector(header->sector, header->len);
+ return ReadAlignedSector(sector, len);
}
bool ReadWorker::SendBufferedIo() {
- return WriteDmUserPayload(bufsink_.GetPayloadBytesWritten());
-}
-
-bool ReadWorker::ProcessIORequest() {
- // Read Header from dm-user misc device. This gives
- // us the sector number for which IO is issued by dm-snapshot device
- struct dm_user_header* header = bufsink_.GetHeaderPtr();
- if (!android::base::ReadFully(ctrl_fd_, header, sizeof(*header))) {
- if (errno != ENOTBLK) {
- SNAP_PLOG(ERROR) << "Control-read failed";
- }
-
- SNAP_PLOG(DEBUG) << "ReadDmUserHeader failed....";
- return false;
- }
-
- SNAP_LOG(DEBUG) << "Daemon: msg->seq: " << std::dec << header->seq;
- SNAP_LOG(DEBUG) << "Daemon: msg->len: " << std::dec << header->len;
- SNAP_LOG(DEBUG) << "Daemon: msg->sector: " << std::dec << header->sector;
- SNAP_LOG(DEBUG) << "Daemon: msg->type: " << std::dec << header->type;
- SNAP_LOG(DEBUG) << "Daemon: msg->flags: " << std::dec << header->flags;
-
- // Use the same header buffer as the response header.
- int request_type = header->type;
- header->type = DM_USER_RESP_SUCCESS;
- header_response_ = true;
-
- // Reset the output buffer.
- bufsink_.ResetBufferOffset();
-
- bool ok;
- switch (request_type) {
- case DM_USER_REQ_MAP_READ:
- ok = DmuserReadRequest();
- break;
-
- case DM_USER_REQ_MAP_WRITE:
- // TODO: We should not get any write request
- // to dm-user as we mount all partitions
- // as read-only. Need to verify how are TRIM commands
- // handled during mount.
- ok = false;
- break;
-
- default:
- ok = false;
- break;
- }
-
- if (!ok && header->type != DM_USER_RESP_ERROR) {
- RespondIOError();
- }
- return ok;
+ return block_server_->SendBufferedIo();
}
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.h
index 8d6f663..a6a3eb8 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.h
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/read_worker.h
@@ -17,28 +17,26 @@
#include <utility>
#include <vector>
+#include <snapuserd/block_server.h>
#include "worker.h"
namespace android {
namespace snapshot {
-class ReadWorker : public Worker {
+class ReadWorker : public Worker, public IBlockServer::Delegate {
public:
ReadWorker(const std::string& cow_device, const std::string& backing_device,
- const std::string& control_device, const std::string& misc_name,
- const std::string& base_path_merge, std::shared_ptr<SnapshotHandler> snapuserd);
+ const std::string& misc_name, const std::string& base_path_merge,
+ std::shared_ptr<SnapshotHandler> snapuserd,
+ std::shared_ptr<IBlockServerOpener> opener);
bool Run();
bool Init() override;
void CloseFds() override;
private:
- // Functions interacting with dm-user
- bool ProcessIORequest();
- bool WriteDmUserPayload(size_t size);
- bool DmuserReadRequest();
+ bool RequestSectors(uint64_t sector, uint64_t size) override;
bool SendBufferedIo();
- void RespondIOError();
bool ProcessCowOp(const CowOperation* cow_op, void* buffer);
bool ProcessXorOp(const CowOperation* cow_op, void* buffer);
@@ -60,10 +58,9 @@
std::string backing_store_device_;
unique_fd backing_store_fd_;
- std::string control_device_;
- unique_fd ctrl_fd_;
+ std::shared_ptr<IBlockServerOpener> block_server_opener_;
+ std::unique_ptr<IBlockServer> block_server_;
- bool header_response_ = false;
std::basic_string<uint8_t> xor_buffer_;
};
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
index 6d09bc9..6d3d5c7 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -22,6 +22,7 @@
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/strings.h>
+#include <snapuserd/dm_user_block_server.h>
#include "merge_worker.h"
#include "read_worker.h"
@@ -48,9 +49,10 @@
}
bool SnapshotHandler::InitializeWorkers() {
+ auto opener = std::make_shared<DmUserBlockServerOpener>(misc_name_, control_device_);
for (int i = 0; i < num_worker_threads_; i++) {
- auto wt = std::make_unique<ReadWorker>(cow_device_, backing_store_device_, control_device_,
- misc_name_, base_path_merge_, GetSharedPtr());
+ auto wt = std::make_unique<ReadWorker>(cow_device_, backing_store_device_, misc_name_,
+ base_path_merge_, GetSharedPtr(), opener);
if (!wt->Init()) {
SNAP_LOG(ERROR) << "Thread initialization failed";
return false;