kernel+init: Let userspace control devfs mountpoints
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
dcb8ab569a
commit
ff952cfe16
@ -10,6 +10,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
@ -258,6 +259,13 @@ static Result<void> set_hostname()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mount_devfs()
|
||||||
|
{
|
||||||
|
if (mkdir("/dev", 0755) < 0 && errno != EEXIST) exit(255);
|
||||||
|
|
||||||
|
if (mount("/dev", "devfs") < 0) exit(255);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
@ -266,6 +274,8 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mount_devfs();
|
||||||
|
|
||||||
// Before this point, we don't even have an stdin, stdout and stderr. Set it up now so that child processes (and us)
|
// Before this point, we don't even have an stdin, stdout and stderr. Set it up now so that child processes (and us)
|
||||||
// can print stuff.
|
// can print stuff.
|
||||||
stdin = fopen("/dev/console", "r");
|
stdin = fopen("/dev/console", "r");
|
||||||
|
@ -21,8 +21,6 @@ struct DeviceDescriptor
|
|||||||
|
|
||||||
Vector<DeviceDescriptor> g_available_devices = {};
|
Vector<DeviceDescriptor> g_available_devices = {};
|
||||||
|
|
||||||
SharedPtr<VFS::FileSystem> g_device_fs;
|
|
||||||
|
|
||||||
namespace DeviceRegistry
|
namespace DeviceRegistry
|
||||||
{
|
{
|
||||||
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor)
|
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor)
|
||||||
@ -35,11 +33,11 @@ namespace DeviceRegistry
|
|||||||
return err(ENODEV);
|
return err(ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> create_special_device_inode(DeviceDescriptor& descriptor)
|
Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor)
|
||||||
{
|
{
|
||||||
auto inode = TRY(g_device_fs->create_device_inode(descriptor.major, descriptor.minor));
|
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor));
|
||||||
inode->chmod(descriptor.mode);
|
inode->chmod(descriptor.mode);
|
||||||
TRY(g_device_fs->root_inode()->add_entry(inode, descriptor.name));
|
TRY(fs->root_inode()->add_entry(inode, descriptor.name));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -51,23 +49,17 @@ namespace DeviceRegistry
|
|||||||
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
|
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
kdbgln("DeviceRegistry: registered new device type %u:%u at path /dev/%s", major, minor, name);
|
kdbgln("DeviceRegistry: registered new device type %u:%u at path /%s in devfs", major, minor, name);
|
||||||
|
|
||||||
auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode };
|
auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode };
|
||||||
|
|
||||||
TRY(g_available_devices.try_append(desc));
|
TRY(g_available_devices.try_append(desc));
|
||||||
|
|
||||||
TRY(create_special_device_inode(desc));
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> init()
|
Result<void> init()
|
||||||
{
|
{
|
||||||
auto device_fs = TRY(TmpFS::FileSystem::create());
|
|
||||||
TRY(VFS::mount("/dev", device_fs, Credentials {}));
|
|
||||||
g_device_fs = device_fs;
|
|
||||||
|
|
||||||
NullDevice::create();
|
NullDevice::create();
|
||||||
ZeroDevice::create();
|
ZeroDevice::create();
|
||||||
FullDevice::create();
|
FullDevice::create();
|
||||||
@ -82,4 +74,15 @@ namespace DeviceRegistry
|
|||||||
static u32 next_minor = 0;
|
static u32 next_minor = 0;
|
||||||
return luna_dev_makedev(0, next_minor++);
|
return luna_dev_makedev(0, next_minor++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This devfs will only contain the devices registered before its creation. Otherwise, created devfs
|
||||||
|
// instances would have to be stored using WeakPtr or something (which doesn't exist atm)...
|
||||||
|
Result<SharedPtr<VFS::FileSystem>> create_devfs_instance()
|
||||||
|
{
|
||||||
|
auto fs = TRY(TmpFS::FileSystem::create());
|
||||||
|
|
||||||
|
for (const auto& descriptor : g_available_devices) TRY(create_special_device_inode(fs, descriptor));
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/VFS.h"
|
||||||
#include "fs/devices/Device.h"
|
#include "fs/devices/Device.h"
|
||||||
#include <luna/SharedPtr.h>
|
#include <luna/SharedPtr.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -23,4 +24,6 @@ namespace DeviceRegistry
|
|||||||
|
|
||||||
// Used for file systems (like tmpfs) that do not have a host device.
|
// Used for file systems (like tmpfs) that do not have a host device.
|
||||||
dev_t next_null_device_id();
|
dev_t next_null_device_id();
|
||||||
|
|
||||||
|
Result<SharedPtr<VFS::FileSystem>> create_devfs_instance();
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,14 @@ Result<u64> sys_mount(Registers*, SyscallArgs args)
|
|||||||
auto* current = Scheduler::current();
|
auto* current = Scheduler::current();
|
||||||
if (current->auth.euid != 0) return err(EPERM);
|
if (current->auth.euid != 0) return err(EPERM);
|
||||||
|
|
||||||
// Right now we only support one file system.
|
SharedPtr<VFS::FileSystem> fs;
|
||||||
if (fstype.view() != "tmpfs") return err(ENODEV);
|
|
||||||
|
if (fstype.view() == "tmpfs") fs = TRY(TmpFS::FileSystem::create());
|
||||||
|
else if (fstype.view() == "devfs")
|
||||||
|
fs = TRY(DeviceRegistry::create_devfs_instance());
|
||||||
|
else
|
||||||
|
return err(ENODEV);
|
||||||
|
|
||||||
auto fs = TRY(TmpFS::FileSystem::create());
|
|
||||||
TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory));
|
TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user