Re: Trying to write a kernel module for (un)mounting tmpfs

2020-10-11 Thread Bruno Melo
Hi,

When I call the namei_simple_user function it always return errno 14. It calls 
the nameiat_simple_user who calls the pathbuf_copyin function. I set a bp in 
pathbuf_copyin and i compare what happens when I use mount command vs my 
module. basically it calls the pathbuf_create_raw() who does all the magic, 
when use the mount command it sets pb->pb_path to "/tmp" and when i load my 
module it sets to the "./mount.kmod" (my module's name), that's why namei 
always returns a bad address errno.
The pathbuf_create_raw() calls the PNBUF_GET() who is a macro for
pool_cache_get(pnbuf_cache, PR_WAITOK). My question is how can I pass "/tmp" 
string to pnbuf_cache argument? Will I need to reimplement all these functions 
inside my code?

Thanks for the help.

Sent from [ProtonMail](https://protonmail.com), Swiss-based encrypted email.

‐‐‐ Original Message ‐‐‐
Em domingo, 13 de setembro de 2020 às 23:57, Maciej  
escreveu:

> Hi Bruno,
>
> The reason why it is hard to map VFS operations inside the kernel is due to 
> the way how POSIX filesystems are designed.
> Most of the operations are made to run in the context of some process where 
> we have information about things such mount point,
> some file structures or path. This information is later translated to 
> concrete kernel structures.
>
> From the other side kernel module code when executed would need to get 
> somehow such information like mount point and mount options.
> If you take a look on the man-page of mount(2) you will notice that there are 
> couple arguments like flags
> (Filesystem independent - or at least meant to be independent), and mount 
> data which is filesystem-specific.
>
> The first design question that should ask yourself is how this information 
> would be provided to the kernel module?
> Probably they can be hardcoded in the module; however, if you decide to 
> trigger this operation from userspace
> (by using any US to kernel interface), you can provide some structure that 
> contains more information about current filesystem to make things easier.
>
> A good starting point to understand how things are working would be 
> implementation in VFS layer of mount system call:
>
> `do_sys_mount()` inside: kern/vfs_syscalls.c
>
> You can notice that in order to get vnode (structure needed for mount: the 
> mount point)
> you need to translate file path to find a vnode using `namei` operation
>
> Next thing is mount operation itself, as you realized each filesystem has its 
> own `struct vfsops` that contains filesystem operations.
> Kernel contains the global list `struct vfs_list_head vfs_list ` build inside 
> `kern/vfs_init.c`
> this list contains all filesystems availavble on NetBSD with their operations.
> To get filesystem specific structure you can use `mount_get_vfsops()`.
>
> When finished with the preparation (probably you will need to prepare 
> arguments according to man page mentioned before),
> you can call your favourite FS mount operation by `mount_domount()`.
>
> Hope that quick walkthrough will help you understand how mount operation 
> works inside the kernel.
> Maciej
>
> ‐‐‐ Original Message ‐‐‐
> On Thursday, September 10, 2020 12:51 PM, Bruno Melo  
> wrote:
>
>> Hi,
>>
>> I'm trying to write a kernel module as example for mounting and unmounting 
>> tmpfs. For that, I read the mount_tmpfs code and in line 247 I found the 
>> call for mount() syscall here:
>> https://nxr.netbsd.org/xref/src/sbin/mount_tmpfs/mount_tmpfs.c#247
>>
>> Then I looked for how the kernel mounts file systems and found there are 
>> _mount() function for every file system:
>> https://nxr.netbsd.org/xref/src/sys/sys/mount.h#254
>>
>> Now, I just needed to know how to use tmpfs_mount() and find it here:
>> https://nxr.netbsd.org/xref/src/sys/fs/tmpfs/tmpfs_vfsops.c#86
>> but I still don't know how to use it. I created the struct 
>> [tmpfs_args](https://nxr.netbsd.org/source/s?defs=tmpfs_args=src) 
>> [args](https://nxr.netbsd.org/source/s?refs=args=src) and size_t 
>> args_len = sizeof args variables to pass to data and data_len arguments in 
>> tmpfs_mount(). And the directory I'm mounting is "/tmp". So, I have 3 of 4 
>> arguments needed to tmpfs_mount(), the last one is the struct mount *mp.
>>
>> I know the mount() syscall takes 
>> [MOUNT_TMPFS](https://nxr.netbsd.org/source/s?defs=MOUNT_TMPFS=src) 
>> as first argument, but I'm not understanding the magic behind struct mount 
>> mp and what I need to assign to the struct mount variable to pass it to that 
>> argument. Any hint?
>>
>> Thanks for the help,
>>
>> Bruno Melo.

Re: Trying to write a kernel module for (un)mounting tmpfs

2020-09-13 Thread Maciej
Hi Bruno,

The reason why it is hard to map VFS operations inside the kernel is due to the 
way how POSIX filesystems are designed.
Most of the operations are made to run in the context of some process where we 
have information about things such mount point,
some file structures or path. This information is later translated to concrete 
kernel structures.

From the other side kernel module code when executed would need to get somehow 
such information like mount point and mount options.
If you take a look on the man-page of mount(2) you will notice that there are 
couple arguments like flags
(Filesystem independent - or at least meant to be independent), and mount data 
which is filesystem-specific.

The first design question that should ask yourself is how this information 
would be provided to the kernel module?
Probably they can be hardcoded in the module; however, if you decide to trigger 
this operation from userspace
(by using any US to kernel interface), you can provide some structure that 
contains more information about current filesystem to make things easier.

A good starting point to understand how things are working would be 
implementation in VFS layer of mount system call:

`do_sys_mount()` inside: kern/vfs_syscalls.c

You can notice that in order to get vnode (structure needed for mount: the 
mount point)
you need to translate file path to find a vnode using `namei` operation

Next thing is mount operation itself, as you realized each filesystem has its 
own `struct vfsops` that contains filesystem operations.
Kernel contains the global list `struct vfs_list_head vfs_list ` build inside 
`kern/vfs_init.c`
this list contains all filesystems availavble on NetBSD with their operations.
To get filesystem specific structure you can use `mount_get_vfsops()`.

When finished with the preparation (probably you will need to prepare arguments 
according to man page mentioned before),
you can call your favourite FS mount operation by `mount_domount()`.

Hope that quick walkthrough will help you understand how mount operation works 
inside the kernel.
Maciej

‐‐‐ Original Message ‐‐‐
On Thursday, September 10, 2020 12:51 PM, Bruno Melo  
wrote:

> Hi,
>
> I'm trying to write a kernel module as example for mounting and unmounting 
> tmpfs. For that, I read the mount_tmpfs code and in line 247 I found the call 
> for mount() syscall here:
> https://nxr.netbsd.org/xref/src/sbin/mount_tmpfs/mount_tmpfs.c#247
>
> Then I looked for how the kernel mounts file systems and found there are 
> _mount() function for every file system:
> https://nxr.netbsd.org/xref/src/sys/sys/mount.h#254
>
> Now, I just needed to know how to use tmpfs_mount() and find it here:
> https://nxr.netbsd.org/xref/src/sys/fs/tmpfs/tmpfs_vfsops.c#86
> but I still don't know how to use it. I created the struct 
> [tmpfs_args](https://nxr.netbsd.org/source/s?defs=tmpfs_args=src) 
> [args](https://nxr.netbsd.org/source/s?refs=args=src) and size_t 
> args_len = sizeof args variables to pass to data and data_len arguments in 
> tmpfs_mount(). And the directory I'm mounting is "/tmp". So, I have 3 of 4 
> arguments needed to tmpfs_mount(), the last one is the struct mount *mp.
>
> I know the mount() syscall takes 
> [MOUNT_TMPFS](https://nxr.netbsd.org/source/s?defs=MOUNT_TMPFS=src) 
> as first argument, but I'm not understanding the magic behind struct mount mp 
> and what I need to assign to the struct mount variable to pass it to that 
> argument. Any hint?
>
> Thanks for the help,
>
> Bruno Melo.

Trying to write a kernel module for (un)mounting tmpfs

2020-09-10 Thread Bruno Melo
Hi,

I'm trying to write a kernel module as example for mounting and unmounting 
tmpfs. For that, I read the mount_tmpfs code and in line 247 I found the call 
for mount() syscall here:
https://nxr.netbsd.org/xref/src/sbin/mount_tmpfs/mount_tmpfs.c#247

Then I looked for how the kernel mounts file systems and found there are 
_mount() function for every file system:
https://nxr.netbsd.org/xref/src/sys/sys/mount.h#254

Now, I just needed to know how to use tmpfs_mount() and find it here:
https://nxr.netbsd.org/xref/src/sys/fs/tmpfs/tmpfs_vfsops.c#86
but I still don't know how to use it. I created the struct 
[tmpfs_args](https://nxr.netbsd.org/source/s?defs=tmpfs_args=src) 
[args](https://nxr.netbsd.org/source/s?refs=args=src) and size_t 
args_len = sizeof args variables to pass to data and data_len arguments in 
tmpfs_mount(). And the directory I'm mounting is "/tmp". So, I have 3 of 4 
arguments needed to tmpfs_mount(), the last one is the struct mount *mp.

I know the mount() syscall takes 
[MOUNT_TMPFS](https://nxr.netbsd.org/source/s?defs=MOUNT_TMPFS=src) as 
first argument, but I'm not understanding the magic behind struct mount mp and 
what I need to assign to the struct mount variable to pass it to that argument. 
Any hint?

Thanks for the help,

Bruno Melo.