how to create /proc file inside kernel module? - c

I want to save some information in a kernel module. I have seen similar question to mine here in stackoverflow, however mine is slightly different. Assuming I am using this code to write in a /proc file. How should I call it inside one of my kernel module? I have a custom kernel module called mymodule which is not the main file (does not have init_module()) inside it the below function is called. In this case what should be the input value to the function like value of file? Basically is it possible to create a /proc file inside a kernel module?
int procfile_write(struct file *file, const char *buffer, unsigned long count,
void *data)

It is definitely possible to add a proc entry in a kernel module but you might be misunderstanding how file handling works in the kernel.
When you create a file in proc, you're not actually 'creating' a file like you would in userspace. You're registering a few callbacks that are called when userspace programs request your file.
That means, when userspace programs request a read, your file read callback has to provide data. When a userspace program requests a write, your file write callback has to handle it.
If you want to use it like a conventional file to store information, you have to allocate the required space and have your read callback copy data from there.

Related

what is the detailed process of bps API map helpers like "bpf_map_update_elem"?

In my understanding, when userspace use bpf_map_update_elem(int fd, void *key, void *value, __u64 flags),
first, userspace find the map through the fd;
second, userspace make a memory in user-space;
and ....
I know a little bit, but the specific process is still unclear.
So I wanna know what the detail is when userspace run API map helpers.
Because you mention “user space”, I am unsure what you are talking about exactly. So let's start with some clarification.
BPF maps (or at least, most of the existing types, including hash maps and arrays) can be accessed in two ways:
From user space, by any application running on the system and having sufficient permission
From kernel space, from BPF programs
From user space, there is no “helper” function. Interaction with maps is entirely (*) done through the bpf() syscall (with the BPF_MAP_LOOKUP_ELEM, BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands passed to the syscall as its first argument). See the bpf(2) manual page for more details. This is what you use in a user space application that would load and manage BPF programs and maps, say bpftool for example.
From kernel space, i.e. from a BPF program, things work differently and access is done with one of the BPF “helpers” such as bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags). See the bpf-helpers(7) man page for details on existing helpers. You can find details on those helper calls in the Cilium guide, or obviously by reading kernel code (e.g. for array maps). They look like low-level C function calls, with BPF registers being used to pass the necessary arguments, and then it calls from the BPF program instructions into the helper that is compiled as part of the kernel binary.
So you mentioned bpf_map_update_elem() and user space. Although this is the name for the helper on the kernel side, I suspect you might be talking about the function with the same name which is offered by the libbpf library, to provide a wrapper around the bpf() system call. So what happens with this function is rather simple.
There is no need to find the map from the file descriptor in user space: Actually the opposite happens, the file descriptor is open from the map in user space (from its map id, or from its pinned path under the /sys/fs/bpf virtual file system for example). So the fd is passed to the bpf() system call and used by the kernel as a reference to the map.
I'm not sure what you mean but “userspace make a memory in user-space”. There is no need to allocate any memory here: The key and value should already have been filled at this point, and they are passed to the kernel through the bpf() syscall to tell what entry to update, and with what value. Same things for the flags.
Once bpf() has been called, what happens on the kernel side is rather straightforwards. Mostly, the kernel check permissions, validates the arguments (to make sure they are safe and consistent with the map), then it updates the actual data. For array maps, array_map_update_elem() (used with the BPF helper on kernel side too, see link above) is called eventually.
(*) Some interactions might actually be done without the bpf() system call, I believe that with “global data” stored in BPF maps, use applications mmap() to the kernel memory. But this goes beyond the scope of basic usage of arrays and maps.

Get Linux kernel module ko file name within running module

Is there a simple way to, within a running Linux kernel module, to determine the full file name for the .ko file (ie: /lib/modules/$(uname -r)/kernel/drivers/mymodule.ko) associated with the module, without traversing procfs, but instead, just relying on internal structures/lists available in kernel space code?
You cannot obtain path to the module file within the kernel: the kernel doesn't store it. Moreover, the kernel even doesn't know that path.
There are two syscalls for load a kernel module: init_module and finit_module (both are defined in kernel/module.c). The first one accepts pointer to user space area, where module image resides (user space should read module file into that area before). The second one accepts descriptor to the module's file, but this descriptor is used only for read content of the file, and isn't stored.
No.
First: your module may have been compiled into the kernel, and thus won't have a file path.
Second: Loading kernel modules from files takes place in userspace. The kernel is passed a module as a data buffer, using the init_module system call -- it's theoretically possible that this data was never loaded from a file at all. (For instance, one can imagine a module loader that loads modules from the network, or from a compressed archive.)

reading seq_file from kernel

Could you post some examples how to read list of meanings from /proc files?
list_head* get_from_proc_file()
{
struct file* file = fopen("example","r");
seq_open(file, &seq_ops);
struct seq_file *p = file->private_data;
READ LIST OF DATA?????
}
You can't use fopen as this is a libc function. The example bellow shows how to read a file from the kernel.
http://www.wasm.ru/forum/viewtopic.php?pid=467952#p467952
Probably you don't need to read a /proc file within kernel, because a /proc interface is used by kernel to export some information to user-space, the information definitely already exists in kernel, either in some list of struct's or other global containers. So the proper way is probably just getting the global list/container by calling some kernel API or using them directly, if they are exported.

How can i call a function that written in kernel module, from the user program?

sample driver created and loaded successfully, in that a user defined function is written, it does some actions. i need to write a user program that calls the user defined function in the driver module.
need help in following cases.
How can i get access to the driver code from a user program ?.
How can i call a function that written in kernel module, from the user program ?.
thanks.
You can make your driver to react on writes (or if necessary, ioctl) to a /dev/xxx file or a /proc/xxx file. Also, you can create a new syscall, but that's more of a toy as the module would only work on custom built kernels.
Edit: try http://www.faqs.org/docs/kernel/x571.html (on character device drivers.)
It depends on what your function does, but in general:
If you want to store and show properties in the form of values (e.g. current brightness of a backlight), the standard way of doing would be using sysfs: http://kernel.org/doc/Documentation/filesystems/sysfs.txt
If you want to write/read values from a device (real or virtual), export memory or IO regions of a device to user space, or more generally control a device (e.g. setting resolution of a camera and capturing frames), you would use a character or block devices with the read/write/mmap and ioctl functions: http://luv.asn.au/overheads/chrdev-talk.html
Finally if your function just controls something from the kernel, then sysfs or procfs should be the way to go. I am not sure why people are still using procfs nowadays, except for misc devices maybe.
So in general, you need to export your kernel functions to user space through files, by defining hooks that will be called when the file is opened, read, written (to copy data from/to user space), mmap'ed (to share memory areas without copying) or when an ioctl is invoked (to perform more general control).
VDSO:
http://en.wikipedia.org/wiki/VDSO
Kernel mode Linux:
http://www.yl.is.s.u-tokyo.ac.jp/~tosh/kml/
for Qn.1:
read/write/ioctl see file_operations
for Qn.2:
1) system calls
2) driver - ioctl

How do I open a directory at kernel level using the file descriptor for that directory?

I'm working on a project where I must open a directory and read the files/directories inside at kernel level. I'm basically trying to find out how ls is implemented at kernel level.
Right now I've figured out how to get a file descriptor for a directory using sys_open() and the O_DIRECTORY flag, but I don't know how to read the fd that I receive. If anyone has any tips or other suggestions I'd appreciate it. (Keep in mind this has to be done at kernel level).
Edit:For a long story short, For a school project I am implementing file/directory attributes. Where I'm storring the attributes is a hidden folder at the same level of the file with a given attribute. (So a file in Desktop/MyFolder has an attributes folder called Desktop/MyFolder/.filename_attr). Trust me I don't care to mess around in kernel for funsies. But the reason I need to read a dir at kernel level is because it's apart of project specs.
To add to caf's answer mentioning vfs_readdir(), reading and writing to files from within the kernel is is considered unsafe (except for /proc, which acts as an interface to internal data structures in the kernel.)
The reasons are well described in this linuxjournal article, although they also provide a hack to access files. I don't think their method could be easily modified to work for directories. A more correct approach is accessing the kernel's filesystem inode entries, which is what vfs_readdir does.
Inodes are filesystem objects such as regular files, directories, FIFOs and other
beasts. They live either on the disc (for block device filesystems)
or in the memory (for pseudo filesystems).
Notice that vfs_readdir() expects a file * parameter. To obtain a file structure pointer from a user space file descriptor, you should utilize the kernel's file descriptor table.
The kernel.org files documentation says the following on doing so safely:
To look up the file structure given an fd, a reader
must use either fcheck() or fcheck_files() APIs. These
take care of barrier requirements due to lock-free lookup.
An example :
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
// Handling of the file structures is special.
// Since the look-up of the fd (fget() / fget_light())
// are lock-free, it is possible that look-up may race with
// the last put() operation on the file structure.
// This is avoided using atomic_long_inc_not_zero() on ->f_count
if (atomic_long_inc_not_zero(&file->f_count))
*fput_needed = 1;
else
/* Didn't get the reference, someone's freed */
file = NULL;
}
rcu_read_unlock();
....
return file;
atomic_long_inc_not_zero() detects if refcounts is already zero or
goes to zero during increment. If it does, we fail fget() / fget_light().
Finally, take a look at filldir_t, the second parameter type.
You probably want vfs_readdir() from fs/readdir.c.
In general though kernel code does not read directories, user code does.

Resources