API for linux /sys nodes - linux

Do all nodes in /sys (and /proc) have an equivalent API? Like an ioctl or a library function. What resource can I use to find those?
Context:
I want to enable RFS by setting values in /proc/sys/net/core/rps_sock_flow_entries and /sys/class/net/<iface>/queues/rx-X/rps_flow_cnt;.
Using those in the terminal or a shell script is ok but it feels wrong in a C program.

Do all nodes in /sys
Yes.
(and /proc) have an equivalent API?
No, but still 99% of them will use POSIX open/read/write operations.
Some of proc entries can be poll or mmap, some not. Also https://elixir.bootlin.com/linux/latest/source/include/linux/proc_fs.h#L29 .
What resource can I use to find those?
Linux Kernel source code and Linux Kernel documentation. Google and internet resources and man pages.

Related

what is the difference between accessing a pci device using procfs vs sysfs

procfs file: /proc/bus/pci/00/00.0
vs.
sysfs file: /sys/bus/pci/devices/0000:00:00.0/resource
I have seen some drivers use the procfs file and some use sysfs. What is the difference? For what I need, I find that mmap-ing the sysfs/resource<n>? file and read/write works as I need it to, but similar operation on the procfs file does not work. But obviously the procfs file is used successfully elsewhere.
The procfs file you cite (/proc/bus/pci/00/00.0) provides access to the device's configuration header. It is also accessible in sysfs as /sys/bus/pci/devices/0000:00:00.0/config.
The sysfs file you're talking about (/sys/bus/pci/devices/0000:00:00.0/resource<N>) provides access to the device's BAR regions. See https://en.wikipedia.org/wiki/PCI_configuration_space for an explanation of the relationships. Also, you may want to read the linux kernel documentation at
https://www.kernel.org/doc/Documentation/filesystems/sysfs-pci.txt

Can bash be used to communicate directly with hardware?

I am interested in writing my own tool in bash to act in place of my current network controller (wpa_supplicant) if possible. For example if I want to issue commands in order to begin a wps authentication session with a router's external registrar, is it possible, without using any pre-built tools, to communicate with the kernel to directly access the hardware? I have been told that I can achieve what I desire with a bash plugin called ctypes.sh but I am not too certain.
Generally speaking, the Linux kernel can interact with user-space through the following mechanisms:
Syscalls
Devices in /dev
Entries in /sys
Entries in /proc
Syscalls cannot be directly used from Bash but you need at least a binding through a C program.
You can create a Linux kernel driver or module which reads/writes data in an entry under /proc or /sys and then use a bash program to interact with it. Even if technically feasible, my personal opinion is that it is an overkill, and the usual C/C++ user-level programming with proper entries in /dev is much better.
No, this is generally not possible. Shell scripts can mess around in /proc, but they don't have the ability to perform arbitrary IOCTLs or even multi-step interactive IO. It's the wrong tool for the job.

How to trap system calls in a userspace library in Linux?

I have a requirement to write a linux device driver in userspace.
How can I write a library which, when linked to an application, can handle system calls to a particular device.
The application should be able to use open(), read(), write(), ioctl() on a device such as /dev/mydev0, but these calls should terminate in a userspace library instead of a kernel module.
Please advise on if this is possible and how can I achieve this.
Linux is a monolithic kernel which means in general, what you're asking is not possible; you can't write arbitrary drivers in user-mode.
You could (as your title alludes to), use ptrace(2) to trap on system calls, and basically redirect them to functions in your library. That is not a simple, straightforward solution however.
See also:
How to use ptrace(2) to change behaviour of syscalls?
FUSE (Filesystem in USErspace) may be what you're looking for. It's a mechanism that allows filesystem drivers specifically to be implemented via a user-space process. This is how sshfs, for example, is implemented.
Resources:
http://fuse.sourceforge.net/

How do I create a RAM disk using Node.js?

I would like to create a RAM disk programmatically using Node.js, no matter what the underlying OS is (OS X, Linux and Windows should be supported).
What is the best way to achieve this?
Of course I can run a command as a child process, but I would need to write this code individually for each OS. For obvious reasons I'd like to avoid this.
Is there a better approach (even a module that does it would be fine)?
In a low level and uncommon operation like this, there is no standartized way to generate a RAM disk, it is platform dependent and hence there is no functionality of this in NodeJS and there won't be likely, you have to write an extension. In Windows, it will call ramdisk.exe (not so familiar with it) and on Linux it is availalbe under /dev/shm , which you can resize by mount options later. So, the best way is to find the best external program for Windows versions, and in Linux just mount and use the /dev/shm like a normal folder.
More Info on /dev/shm

How to communicate with a Linux kernel module from user space without littering /dev with new nodes?

What are the ways to communicate with a kernel module from user space? By communication i mean sending information and commands between the kernel module and a user space process.
I currently know of two way:
open/close/read/write/ioctl on published device node.
read/write on exported and hooked /proc file.
More specifically, can someone advice the best way to communicate with a kernel module that does not actually drives any hardware and therefore should not be littering /dev with stub nodes that exists solely for ioctl calls? I mostly need to check its various status variables and send it a block of data with a request type tag and see if the request succeeded.
Netlink sockets are designed for that kind of requirements, too...
Also see
man 7 netlink
libnl - Netlink library
The libnl Archives
There's also the /sys filesystem (sysfs):
Sysfs exports information about
devices and drivers from the kernel
device model to userspace, and is also
used for configuration.
(from Wikipedia)
You could also read/write from /dev device nodes.
IMHO, /dev is already littered with stuff and adding your own nodes there isn't a big issue. Don't forget that you can have lots of ioctl codes for a single device node, and the ioctl paramters are passed by reference so can be as big as you like.
Third one is add a new syscall, but the two you have written are the preferred ones, I think. I've found this document that might help, but I still think this option is unadvised: http://www.csee.umbc.edu/courses/undergraduate/CMSC421/fall02/burt/projects/howto_add_systemcall.html
Another acceptable option might be sharing memory.
You could also use Shared Memory and IOCTL
debugfs is another good possibility for APIs that are less stable than sysfs, but the API is basically the same. Here is a minimal runnable example.
configfs is another one. It allows easy dynamic creation of kernel objects from userspace through the filesystem: https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
In any case, you will have to dirty some namespace... a filesystem entry in case of sysfs and debugfs. Just choose your poison.
Also, udev rules make /dev very similar to sysfs and debugfs: How to create a device in /dev automatically upon loading of the kernel module for a device driver?

Resources