[Sys] Successfully spin up a new process from disk.

This commit is contained in:
Drew Galbraith 2023-11-15 09:47:32 -08:00
parent e5568450c2
commit 7c105c8a31
22 changed files with 415 additions and 191 deletions

View file

@ -1,5 +1,6 @@
interface Denali {
method Read(ReadRequest) -> (ReadResponse);
method ReadMany(ReadManyRequest) -> (ReadResponse);
}
message ReadRequest {
@ -8,9 +9,14 @@ message ReadRequest {
u64 size;
}
message ReadManyRequest {
u64 device_id;
repeated u64 lba;
}
message ReadResponse {
u64 device_id;
u64 lba;
u64 size;
capability memory;
}

View file

@ -39,3 +39,35 @@ glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& res
}
glcr::ErrorCode DenaliClient::ReadMany(const ReadManyRequest& request, ReadResponse& response) {
uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize;
const uint32_t kSentinel = 0xBEEFDEAD;
buffer_.WriteAt<uint32_t>(0, kSentinel);
buffer_.WriteAt<uint64_t>(8, 1);
cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap;
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap));
// FIXME: Add a way to zero out the first buffer.
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
if (buffer_.At<uint32_t>(0) != kSentinel) {
return glcr::INVALID_RESPONSE;
}
// Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK;
}

View file

@ -19,6 +19,8 @@ class DenaliClient {
[[nodiscard]] glcr::ErrorCode Read(const ReadRequest& request, ReadResponse& response);
[[nodiscard]] glcr::ErrorCode ReadMany(const ReadManyRequest& request, ReadResponse& response);
private:
z_cap_t endpoint_;
uint64_t kBufferSize = 0x1000;

View file

@ -28,16 +28,14 @@ void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, u
} // namespace
void ReadRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse device_id.
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
ParseFromBytesInternal(bytes, offset);
}
void ReadRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
}
void ReadRequest::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse device_id.
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 0)));
@ -45,6 +43,7 @@ void ReadRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset,
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
}
uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
@ -79,45 +78,117 @@ uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset,
return next_extension;
}
void ReadResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
void ReadManyRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
ParseFromBytesInternal(bytes, offset);
}
void ReadManyRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
}
void ReadManyRequest::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse device_id.
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
auto lba_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 1));
lba_.Resize(lba_pointer.length / sizeof(uint64_t));
for (uint64_t i = offset + lba_pointer.offset;
i < offset + lba_pointer.offset + lba_pointer.length;
i += sizeof(uint64_t)) {
lba_.PushBack(bytes.At<uint64_t>(i));
}
}
uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
uint32_t next_extension = header_size + 8 * 2;
const uint32_t core_size = next_extension;
// Write device_id.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
ExtPointer lba_ptr{
.offset = next_extension,
.length = (uint32_t)(lba().size() * sizeof(uint64_t)),
};
next_extension += lba_ptr.length;
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 1), lba_ptr);
for (uint64_t i = 0; i < lba().size(); i++) {
uint32_t ext_offset = offset + lba_ptr.offset + (i * sizeof(uint64_t));
bytes.WriteAt<uint64_t>(ext_offset, lba().at(i));
}
// The next extension pointer is the length of the message.
WriteHeader(bytes, offset, core_size, next_extension);
return next_extension;
}
uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
uint32_t next_extension = header_size + 8 * 2;
const uint32_t core_size = next_extension;
uint64_t next_cap = 0;
// Write device_id.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
ExtPointer lba_ptr{
.offset = next_extension,
.length = (uint32_t)(lba().size() * sizeof(uint64_t)),
};
next_extension += lba_ptr.length;
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 1), lba_ptr);
for (uint64_t i = 0; i < lba().size(); i++) {
uint32_t ext_offset = offset + lba_ptr.offset + (i * sizeof(uint64_t));
bytes.WriteAt<uint64_t>(ext_offset, lba().at(i));
}
// The next extension pointer is the length of the message.
WriteHeader(bytes, offset, core_size, next_extension);
return next_extension;
}
void ReadResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
ParseFromBytesInternal(bytes, offset);
// Parse memory.
// FIXME: Implement in-buffer capabilities for inprocess serialization.
set_memory(0);
}
void ReadResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
CheckHeader(bytes);
// Parse device_id.
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
ParseFromBytesInternal(bytes, offset);
// Parse memory.
uint64_t memory_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 3));
uint64_t memory_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 2));
set_memory(caps.At(memory_ptr));
}
void ReadResponse::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse device_id.
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 0)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse memory.
// Skip Cap.
}
uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
uint32_t next_extension = header_size + 8 * 4;
uint32_t next_extension = header_size + 8 * 3;
const uint32_t core_size = next_extension;
// Write device_id.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), size());
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), size());
// Write memory.
// FIXME: Implement inbuffer capabilities.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 3), 0);
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), 0);
// The next extension pointer is the length of the message.
WriteHeader(bytes, offset, core_size, next_extension);
@ -126,18 +197,16 @@ uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset
}
uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
uint32_t next_extension = header_size + 8 * 4;
uint32_t next_extension = header_size + 8 * 3;
const uint32_t core_size = next_extension;
uint64_t next_cap = 0;
// Write device_id.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), size());
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), size());
// Write memory.
caps.WriteAt(next_cap, memory());
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 3), next_cap++);
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), next_cap++);
// The next extension pointer is the length of the message.
WriteHeader(bytes, offset, core_size, next_extension);

View file

@ -3,6 +3,7 @@
#include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h>
#include <glacier/container/vector.h>
#include <glacier/string/string.h>
#include <ztypes.h>
class ReadRequest {
@ -15,11 +16,11 @@ class ReadRequest {
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
uint64_t device_id() const { return device_id_; }
void set_device_id(const uint64_t& value) { device_id_ = value; }
void set_device_id(const uint64_t& value) { device_id_ = value; }
uint64_t lba() const { return lba_; }
void set_lba(const uint64_t& value) { lba_ = value; }
void set_lba(const uint64_t& value) { lba_ = value; }
uint64_t size() const { return size_; }
void set_size(const uint64_t& value) { size_ = value; }
@ -28,6 +29,31 @@ class ReadRequest {
uint64_t lba_;
uint64_t size_;
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};
class ReadManyRequest {
public:
ReadManyRequest() {}
// Delete copy and move until implemented.
ReadManyRequest(const ReadManyRequest&) = delete;
ReadManyRequest(ReadManyRequest&&) = delete;
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
uint64_t device_id() const { return device_id_; }
void set_device_id(const uint64_t& value) { device_id_ = value; }
const glcr::Vector<uint64_t>& lba() const { return lba_; }
void add_lba(const uint64_t& value) { lba_.PushBack(value); }
private:
uint64_t device_id_;
glcr::Vector<uint64_t> lba_;
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};
class ReadResponse {
public:
@ -39,20 +65,19 @@ class ReadResponse {
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
uint64_t device_id() const { return device_id_; }
void set_device_id(const uint64_t& value) { device_id_ = value; }
uint64_t lba() const { return lba_; }
void set_lba(const uint64_t& value) { lba_ = value; }
void set_device_id(const uint64_t& value) { device_id_ = value; }
uint64_t size() const { return size_; }
void set_size(const uint64_t& value) { size_ = value; }
void set_size(const uint64_t& value) { size_ = value; }
z_cap_t memory() const { return memory_; }
void set_memory(const z_cap_t& value) { memory_ = value; }
private:
uint64_t device_id_;
uint64_t lba_;
uint64_t size_;
z_cap_t memory_;
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};

View file

@ -97,6 +97,17 @@ glcr::ErrorCode DenaliServerBase::HandleRequest(const glcr::ByteBuffer& request,
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break;
}
case 1: {
ReadManyRequest yunq_request;
ReadResponse yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleReadMany(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break;
}
default: {
return glcr::UNIMPLEMENTED;
}

View file

@ -23,6 +23,8 @@ class DenaliServerBase {
[[nodiscard]] virtual glcr::ErrorCode HandleRead(const ReadRequest&, ReadResponse&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleReadMany(const ReadManyRequest&, ReadResponse&) = 0;
private:
z_cap_t endpoint_;

View file

@ -1,32 +0,0 @@
#pragma once
#include <glacier/status/error_or.h>
#include <mammoth/memory_region.h>
#include "denali.yunq.client.h"
class ScopedDenaliClient : protected DenaliClient {
public:
ScopedDenaliClient(z_cap_t endpoint_cap, uint64_t device_id,
uint64_t lba_offset)
: DenaliClient(endpoint_cap),
device_id_(device_id),
lba_offset_(lba_offset) {}
glcr::ErrorOr<MappedMemoryRegion> ReadSectors(uint64_t lba,
uint64_t num_sectors) {
ReadRequest req;
req.set_device_id(device_id_);
req.set_lba(lba_offset_ + lba);
req.set_size(num_sectors);
ReadResponse resp;
RET_ERR(DenaliClient::Read(req, resp));
return MappedMemoryRegion::FromCapability(resp.memory());
}
private:
uint64_t device_id_;
uint64_t lba_offset_;
};