[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

@ -3,12 +3,22 @@
#include "mammoth/debug.h"
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
ScopedDenaliClient&& denali) {
const DenaliInfo& denali_info) {
// Read 1024 bytes from 1024 offset.
// FIXME: Don't assume 512 byte sectors somehow.
ASSIGN_OR_RETURN(MappedMemoryRegion superblock, denali.ReadSectors(2, 2));
DenaliClient client(denali_info.denali_endpoint());
ReadRequest req;
req.set_device_id(denali_info.device_id());
req.set_lba(denali_info.lba_offset() + 2);
req.set_size(2);
ReadResponse resp;
RET_ERR(client.Read(req, resp));
MappedMemoryRegion superblock =
MappedMemoryRegion::FromCapability(resp.memory());
return glcr::SharedPtr<Ext2BlockReader>(
new Ext2BlockReader(glcr::Move(denali), superblock));
new Ext2BlockReader(glcr::Move(client), denali_info.device_id(),
denali_info.lba_offset(), superblock));
}
Superblock* Ext2BlockReader::GetSuperblock() {
@ -51,15 +61,40 @@ uint64_t Ext2BlockReader::InodeTableBlockSize() {
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlock(
uint64_t block_number) {
return denali_.ReadSectors(block_number * SectorsPerBlock(),
SectorsPerBlock());
return ReadBlocks(block_number, 1);
}
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlocks(
uint64_t block_number, uint64_t num_blocks) {
return denali_.ReadSectors(block_number * SectorsPerBlock(),
num_blocks * SectorsPerBlock());
ReadRequest req;
req.set_device_id(device_id_);
req.set_lba(lba_offset_ + block_number * SectorsPerBlock());
req.set_size(num_blocks * SectorsPerBlock());
ReadResponse resp;
RET_ERR(denali_.Read(req, resp));
return MappedMemoryRegion::FromCapability(resp.memory());
}
Ext2BlockReader::Ext2BlockReader(ScopedDenaliClient&& denali,
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlocks(
const glcr::Vector<uint64_t>& block_list) {
ReadManyRequest req;
req.set_device_id(device_id_);
// FIXME: We should have better ergonomics for setting a repeated field in
// Yunq.
for (uint64_t i = 0; i < block_list.size(); i++) {
uint64_t sector = lba_offset_ + block_list.at(i) * SectorsPerBlock();
for (uint64_t j = 0; j < SectorsPerBlock(); j++) {
req.add_lba(sector + j);
}
}
ReadResponse resp;
RET_ERR(denali_.ReadMany(req, resp));
return MappedMemoryRegion::FromCapability(resp.memory());
}
Ext2BlockReader::Ext2BlockReader(DenaliClient&& denali, uint64_t device_id,
uint64_t lba_offset,
MappedMemoryRegion super_block)
: denali_(glcr::Move(denali)), super_block_region_(super_block) {}
: denali_(glcr::Move(denali)),
device_id_(device_id),
lba_offset_(lba_offset),
super_block_region_(super_block) {}

View file

@ -1,9 +1,10 @@
#pragma once
#include <denali/scoped_denali_client.h>
#include <denali/denali.yunq.client.h>
#include <glacier/memory/shared_ptr.h>
#include <glacier/status/error_or.h>
#include <mammoth/memory_region.h>
#include <yellowstone/yellowstone.yunq.h>
#include "fs/ext2/ext2.h"
@ -15,7 +16,7 @@
class Ext2BlockReader {
public:
static glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Init(
ScopedDenaliClient&& denali);
const DenaliInfo& denali_info);
// TODO: Consider creating a new class wrapper with these computations.
Superblock* GetSuperblock();
@ -32,11 +33,17 @@ class Ext2BlockReader {
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_number,
uint64_t num_blocks);
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(
const glcr::Vector<uint64_t>& block_list);
private:
ScopedDenaliClient denali_;
DenaliClient denali_;
uint64_t device_id_;
uint64_t lba_offset_;
MappedMemoryRegion super_block_region_;
Ext2BlockReader(ScopedDenaliClient&& denali, MappedMemoryRegion super_block);
Ext2BlockReader(DenaliClient&& denali, uint64_t device_id,
uint64_t lba_offset, MappedMemoryRegion super_block);
uint64_t SectorsPerBlock();
};

View file

@ -3,9 +3,9 @@
#include <glacier/string/string.h>
#include <mammoth/debug.h>
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(ScopedDenaliClient&& denali) {
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(const DenaliInfo& denali_info) {
ASSIGN_OR_RETURN(glcr::SharedPtr<Ext2BlockReader> reader,
Ext2BlockReader::Init(glcr::Move(denali)));
Ext2BlockReader::Init(glcr::Move(denali_info)));
ASSIGN_OR_RETURN(
MappedMemoryRegion bgdt,
@ -99,10 +99,31 @@ glcr::ErrorOr<MappedMemoryRegion> Ext2Driver::ReadFile(uint64_t inode_number) {
uint64_t real_block_cnt =
(inode->blocks - 1) / (ext2_reader_->BlockSize() / 512) + 1;
if (real_block_cnt > 1) {
dbgln("Can't handle scatter-gather yet.");
if (inode->block[14]) {
dbgln("Can't handle triply-indirect blocks yet.");
return glcr::UNIMPLEMENTED;
}
return ext2_reader_->ReadBlock(inode->block[0]);
if (inode->block[13]) {
dbgln("Can't handle doubly-indirect blocks yet.");
return glcr::UNIMPLEMENTED;
}
MappedMemoryRegion indirect_block;
if (inode->block[12]) {
ASSIGN_OR_RETURN(indirect_block, ext2_reader_->ReadBlock(inode->block[12]));
}
glcr::Vector<uint64_t> blocks_to_read;
for (uint64_t i = 0; i < 12 && i < real_block_cnt; i++) {
blocks_to_read.PushBack(inode->block[i]);
}
for (uint64_t i = 12; i < 268 && i < real_block_cnt; i++) {
uint32_t* block_array = reinterpret_cast<uint32_t*>(indirect_block.vaddr());
uint64_t offset = i - 12;
blocks_to_read.PushBack(block_array[offset]);
}
return ext2_reader_->ReadBlocks(blocks_to_read);
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <denali/scoped_denali_client.h>
#include <glacier/memory/move.h>
#include <glacier/memory/unique_ptr.h>
#include <yellowstone/yellowstone.yunq.h>
#include "fs/ext2/ext2.h"
#include "fs/ext2/ext2_block_reader.h"
@ -10,7 +10,7 @@
class Ext2Driver {
public:
static glcr::ErrorOr<Ext2Driver> Init(ScopedDenaliClient&& denali);
static glcr::ErrorOr<Ext2Driver> Init(const DenaliInfo& denali_info);
glcr::ErrorCode ProbePartition();

View file

@ -28,19 +28,20 @@ void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, u
} // namespace
void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse path.
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
ParseFromBytesInternal(bytes, offset);
}
void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
}
void OpenFileRequest::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse path.
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
}
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
@ -86,19 +87,21 @@ uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t off
return next_extension;
}
void OpenFileResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse path.
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
ParseFromBytesInternal(bytes, offset);
// Parse memory.
// FIXME: Implement in-buffer capabilities for inprocess serialization.
set_memory(0);
}
void OpenFileResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
// Parse memory.
uint64_t memory_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 2));
set_memory(caps.At(memory_ptr));
}
void OpenFileResponse::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
// Parse path.
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
@ -107,9 +110,8 @@ void OpenFileResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t of
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse memory.
uint64_t memory_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 2));
// Skip Cap.
set_memory(caps.At(memory_ptr));
}
uint64_t OpenFileResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {

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 OpenFileRequest {
@ -15,13 +16,15 @@ class OpenFileRequest {
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;
glcr::String path() const { return path_; }
void set_path(const glcr::String& value) { path_ = value; }
private:
glcr::String path_;
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};
class OpenFileResponse {
public:
@ -33,11 +36,11 @@ class OpenFileResponse {
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;
glcr::String path() const { return path_; }
void set_path(const glcr::String& value) { path_ = value; }
void set_path(const glcr::String& value) { path_ = 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; }
@ -46,4 +49,6 @@ class OpenFileResponse {
uint64_t size_;
z_cap_t memory_;
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};

View file

@ -1,4 +1,3 @@
#include <denali/scoped_denali_client.h>
#include <mammoth/debug.h>
#include <mammoth/init.h>
#include <yellowstone/yellowstone.yunq.client.h>
@ -15,10 +14,7 @@ uint64_t main(uint64_t init_cap) {
Empty empty;
DenaliInfo denali_info;
RET_ERR(yellowstone.GetDenali(empty, denali_info));
dbgln("LBA (recv): {x}", denali_info.lba_offset());
ScopedDenaliClient denali(denali_info.denali_endpoint(),
denali_info.device_id(), denali_info.lba_offset());
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(denali_info));
ASSIGN_OR_RETURN(auto server, VFSServer::Create(ext2));