tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

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



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, Swiss-based encrypted email.


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
Em domingo, 13 de setembro de 2020 às 23:57, Maciej <maciej.grochowski%pm.me@localhost> 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 <bmelo%protonmail.com@localhost> 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 args 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 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.







Home | Main Index | Thread Index | Old Index