VFS: Populate the initial filesystem based on the initial ramdisk
This commit is contained in:
parent
ac304073b4
commit
c6aa2fe4ad
@ -1,6 +1,7 @@
|
|||||||
#include "InitRD.h"
|
#include "InitRD.h"
|
||||||
#include "arch/MMU.h"
|
#include "arch/MMU.h"
|
||||||
#include "boot/bootboot.h"
|
#include "boot/bootboot.h"
|
||||||
|
#include "fs/VFS.h"
|
||||||
|
|
||||||
TarStream g_initrd;
|
TarStream g_initrd;
|
||||||
extern const BOOTBOOT bootboot;
|
extern const BOOTBOOT bootboot;
|
||||||
@ -11,3 +12,29 @@ void InitRD::initialize()
|
|||||||
|
|
||||||
g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size);
|
g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result<void> vfs_create_dir_if_not_exists(const char* path)
|
||||||
|
{
|
||||||
|
auto rc = VFS::create_directory(path);
|
||||||
|
if (rc.has_error())
|
||||||
|
{
|
||||||
|
if (rc.error() == EEXIST) return {};
|
||||||
|
return rc.release_error();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void> InitRD::populate_vfs()
|
||||||
|
{
|
||||||
|
TarStream::Entry entry;
|
||||||
|
while (TRY(g_initrd.read_next_entry(entry)))
|
||||||
|
{
|
||||||
|
if (entry.type == TarStream::EntryType::RegularFile)
|
||||||
|
{
|
||||||
|
auto file = TRY(VFS::create_file(entry.name));
|
||||||
|
file->write(entry.data(), 0, entry.size);
|
||||||
|
}
|
||||||
|
else if (entry.type == TarStream::EntryType::Directory) { TRY(vfs_create_dir_if_not_exists(entry.name)); }
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
@ -6,4 +6,5 @@ extern TarStream g_initrd;
|
|||||||
namespace InitRD
|
namespace InitRD
|
||||||
{
|
{
|
||||||
void initialize();
|
void initialize();
|
||||||
|
Result<void> populate_vfs();
|
||||||
}
|
}
|
||||||
|
@ -15,18 +15,12 @@ namespace VFS
|
|||||||
{
|
{
|
||||||
auto parser = TRY(PathParser::create(path));
|
auto parser = TRY(PathParser::create(path));
|
||||||
|
|
||||||
kdbgln("vfs: trying to resolve path %s", path);
|
|
||||||
|
|
||||||
SharedPtr<Inode> current_inode = root_fs->root_inode();
|
SharedPtr<Inode> current_inode = root_fs->root_inode();
|
||||||
|
|
||||||
// FIXME: Properly handle relative paths.
|
// FIXME: Properly handle relative paths.
|
||||||
|
|
||||||
const char* section;
|
const char* section;
|
||||||
while (parser.next().try_set_value(section))
|
while (parser.next().try_set_value(section)) { current_inode = TRY(current_inode->find(section)); }
|
||||||
{
|
|
||||||
kdbgln("vfs: searching for entry '%s' in inode %zu", section, current_inode->inode_number());
|
|
||||||
current_inode = TRY(current_inode->find(section));
|
|
||||||
}
|
|
||||||
|
|
||||||
return current_inode;
|
return current_inode;
|
||||||
}
|
}
|
||||||
@ -40,8 +34,22 @@ namespace VFS
|
|||||||
|
|
||||||
auto child_name = TRY(parser.basename());
|
auto child_name = TRY(parser.basename());
|
||||||
|
|
||||||
kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
// kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
||||||
|
|
||||||
return parent_inode->create_subdirectory(child_name.chars());
|
return parent_inode->create_subdirectory(child_name.chars());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<SharedPtr<Inode>> create_file(const char* path)
|
||||||
|
{
|
||||||
|
auto parser = TRY(PathParser::create(path));
|
||||||
|
auto parent_path = TRY(parser.dirname());
|
||||||
|
|
||||||
|
auto parent_inode = TRY(resolve_path(parent_path.chars()));
|
||||||
|
|
||||||
|
auto child_name = TRY(parser.basename());
|
||||||
|
|
||||||
|
// kdbgln("vfs: creating file '%s' in parent '%s'", child_name.chars(), parent_path.chars());
|
||||||
|
|
||||||
|
return parent_inode->create_file(child_name.chars());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ namespace VFS
|
|||||||
Result<SharedPtr<Inode>> resolve_path(const char* path);
|
Result<SharedPtr<Inode>> resolve_path(const char* path);
|
||||||
|
|
||||||
Result<SharedPtr<Inode>> create_directory(const char* path);
|
Result<SharedPtr<Inode>> create_directory(const char* path);
|
||||||
|
Result<SharedPtr<Inode>> create_file(const char* path);
|
||||||
|
|
||||||
Inode& root_inode();
|
Inode& root_inode();
|
||||||
}
|
}
|
||||||
|
@ -51,37 +51,7 @@ static Result<void> try_init_vfs()
|
|||||||
{
|
{
|
||||||
VFS::root_fs = TRY(TmpFS::FileSystem::create());
|
VFS::root_fs = TRY(TmpFS::FileSystem::create());
|
||||||
|
|
||||||
VFS::Inode& root_inode = VFS::root_inode();
|
InitRD::populate_vfs();
|
||||||
|
|
||||||
kinfoln("root inode number: %zu", root_inode.inode_number());
|
|
||||||
|
|
||||||
kinfoln("root inode's '.' entry inode number: %zu", TRY(root_inode.find("."))->inode_number());
|
|
||||||
kinfoln("root inode's '..' entry inode number: %zu", TRY(root_inode.find(".."))->inode_number());
|
|
||||||
|
|
||||||
TRY(VFS::create_directory("/etc/"));
|
|
||||||
|
|
||||||
kinfoln("root inode's 'etc' entry inode number: %zu", TRY(root_inode.find("etc"))->inode_number());
|
|
||||||
|
|
||||||
auto& etc = *TRY(root_inode.find("etc"));
|
|
||||||
|
|
||||||
kinfoln("etc inode's '.' entry inode number: %zu", TRY(etc.find("."))->inode_number());
|
|
||||||
kinfoln("etc inode's '..' entry inode number: %zu", TRY(etc.find(".."))->inode_number());
|
|
||||||
|
|
||||||
TRY(etc.create_file("passwd"));
|
|
||||||
|
|
||||||
kinfoln("etc inode's 'passwd' entry inode number: %zu", TRY(etc.find("passwd"))->inode_number());
|
|
||||||
|
|
||||||
auto& passwd = *TRY(VFS::resolve_path("/etc/passwd"));
|
|
||||||
|
|
||||||
kinfoln("/etc/passwd's inode number: %zu", passwd.inode_number());
|
|
||||||
|
|
||||||
const char* data = "hello, world!";
|
|
||||||
TRY(passwd.write((const u8*)data, 0, 14));
|
|
||||||
|
|
||||||
char output[14];
|
|
||||||
TRY(passwd.read((u8*)output, 0, 14));
|
|
||||||
|
|
||||||
kinfoln("/etc/passwd contents: '%s'", output);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -94,6 +64,7 @@ static void init_vfs()
|
|||||||
static Result<void> try_init_userspace()
|
static Result<void> try_init_userspace()
|
||||||
{
|
{
|
||||||
TarStream::Entry entry;
|
TarStream::Entry entry;
|
||||||
|
g_initrd.rewind();
|
||||||
while (TRY(g_initrd.read_next_entry(entry)))
|
while (TRY(g_initrd.read_next_entry(entry)))
|
||||||
{
|
{
|
||||||
if (entry.type == TarStream::EntryType::RegularFile)
|
if (entry.type == TarStream::EntryType::RegularFile)
|
||||||
|
Loading…
Reference in New Issue
Block a user