| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "layer-gpt.hpp" |
| 4 | |
| 5 | #include "blockdev.h" |
| 6 | #include "gptdisk.hpp" |
| 7 | |
| 8 | #include <cstdlib> |
| 9 | #include <memory> |
| 10 | |
| 11 | using namespace std::string_literals; |
| 12 | |
| 13 | std::unique_ptr<BlockdevManagerStub> manager = nullptr; |
| 14 | |
| 15 | GPTLayerServer::GPTLayerServer(std::shared_ptr<GPTDisk> disk, const std::string &servername) : IBlockdevLayerService(servername), disk(disk) |
| 16 | { |
| 17 | const register_layer_server::request req = { |
| 18 | .server_name = strdup(string: servername.c_str()), |
| 19 | .partitions_count = disk->get_partition_count(), |
| 20 | .partitions = new mosrpc_blockdev_partition_info[disk->get_partition_count()], |
| 21 | }; |
| 22 | |
| 23 | for (size_t i = 0; i < disk->get_partition_count(); i++) |
| 24 | { |
| 25 | const auto devname = disk->name() + ".p" + std::to_string(val: i); // "virtblk.00:03:00.p1" |
| 26 | const auto partition = disk->get_partition(index: i); |
| 27 | req.partitions[i].name = strdup(string: devname.c_str()); |
| 28 | req.partitions[i].size = (partition.last_lba - partition.first_lba + 1) * disk->get_block_size(); |
| 29 | req.partitions[i].partid = i; |
| 30 | } |
| 31 | |
| 32 | register_layer_server::response resp; |
| 33 | const auto result = manager->register_layer_server(request: &req, response: &resp); |
| 34 | if (result != RPC_RESULT_OK || !resp.result.success) |
| 35 | throw std::runtime_error("Failed to register GPT layer server"s + (resp.result.error ? ": "s + resp.result.error : ""s )); |
| 36 | |
| 37 | free(pointer: req.server_name); |
| 38 | for (size_t i = 0; i < disk->get_partition_count(); i++) |
| 39 | free(pointer: req.partitions[i].name); |
| 40 | delete[] req.partitions; |
| 41 | } |
| 42 | |
| 43 | rpc_result_code_t GPTLayerServer::read_partition_block(rpc_context_t *context, mosrpc_blockdev_read_partition_block_request *req, read_block::response *resp) |
| 44 | { |
| 45 | MOS_UNUSED(context); |
| 46 | const auto datasize = req->n_blocks * disk->get_block_size(); |
| 47 | resp->data = (pb_bytes_array_t *) malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(datasize)); |
| 48 | resp->data->size = datasize; |
| 49 | disk->read_partition_block(partition_index: req->partition.partid, blockoffset: req->n_boffset, buffer: resp->data->bytes, nblocks: req->n_blocks); |
| 50 | |
| 51 | resp->result.success = true; |
| 52 | resp->result.error = nullptr; |
| 53 | return RPC_RESULT_OK; |
| 54 | } |
| 55 | |
| 56 | rpc_result_code_t GPTLayerServer::write_partition_block(rpc_context_t *context, mosrpc_blockdev_write_partition_block_request *req, write_block::response *resp) |
| 57 | { |
| 58 | MOS_UNUSED(context); |
| 59 | MOS_UNUSED(resp); |
| 60 | disk->write_partition_block(partition_index: req->partition.partid, blockoffset: req->n_boffset, buffer: req->data->bytes, nblocks: req->n_blocks); |
| 61 | return RPC_RESULT_OK; |
| 62 | } |
| 63 | |