Subscribe to a file in /sys - linux

Inotify won't trigger on file-changes in /sys - what ways are there to subscribe to changes in there?

Events that change /sys are usually handled by udev. So, you can add udevd rules to handle the events or use libudev to access and monitor the sysfs. I just found some tutorial here: http://www.signal11.us/oss/udev/

Use udev and udev rules to get a notification to changes (hardware hotplug, drivers load, firmware load etc.) that are reflected in /sys.
See http://hackaday.com/2009/09/18/how-to-write-udev-rules/ for details

To be notified on a change on a /sys file or directory, I use the polling objects from python.
import select
poll_objet = select.poll()
fd_object = file("/sys/what_you_want_to_survey", "r")
poll_objet.register(fd_object) # I use the select.POLLPRI | select.POLLERR combination in my code ;)
result = poll_object.poll()
where result is a list of (fd, event) that were touched.

Related

PWM without sysfs

I am pretty new to linux kernel.I am trying to generate PWM through linux. The API man talks about a sysfs interface. I want to implement a userspace program in C. But using PWM forces me to use a command line. Furthermore, using read, write is a problem in C as when I am using cd, it is changing path directory.
Thus the path is variable. Is there any way I can pass values to pwm_config() without using sysfs? Perhaps through ioctl? If yes, then what would be the procedure?
Application C code:
void main(){
int export = open("/sys/class/pwm/pmwchip0/export",O_WRONLY);
int period,duty_cycle,enable;
if(export == -1)
{
perror("Export:");
}
and so on for other files like period and duty cycle.
When I try to run my application I get the following error.
Export:: No such file or directory
Export_write: Bad file descriptor
Period_write:: Bad file descriptor
Duty_cycle_write:: Bad file descriptor
Enable_write:: Bad file descriptor
As far as I know, the sysfs is the only standard userspace interface to PWM. But anything you can do from the command line can be done in C (the shell is written in C, after all).
The problem you are having with cd is not actually a problem. Inside sysfs the directories in /sys/class/pwd/* are actually symbolic links to the proper devices. In your case /sys/class/pwm/pwmchip0 is a symlink to /sys/devices/soc0/amba/f8001000.timer/pwm/pwmchip0.
The funny thing is that some shells, when you cd a symbolic link will resolve to the real directory, but other shells will actually keep the symlink name as the current directory.
But that issue with the directory symlinks should not be an issue for you. A C program willing to manage PWM devices should not change the working directory. Instead open the files with the full path:
open("/sys/class/pwm/pwmchip0/npwm", O_RDONLY);
and so on.

Open file by inode

Is it possible to open a file knowing its inode?
ls -i /tmp/test/test.txt
529965 /tmp/test/test.txt
I can provide path, inode (above 529965) and I am looking to get in return a file descriptor.
This is not possible because it would open a loophole in the access control rules. Whether you can open a file depends not only on its own access permission bits, but on the permission bits of every containing directory. (For instance, in your example, if test.txt were mode 644 but the containing directory test were mode 700, then only root and the owner of test could open test.txt.) Inode numbers only identify the file, not the containing directories (it's possible for a file to be in more than one directory; read up on "hard links") so the kernel cannot perform a complete set of access control checks with only an inode number.
(Some Unix implementations have offered nonstandard root-only APIs to open a file by inode number, bypassing some of the access-control rules, but if current Linux has such an API, I don't know about it.)
Not exactly what you are asking, but (as hinted by zwol) both Linux and NetBSD/FreeBSD provide the ability to open files using previously created “handles”: These are inode-like persistent names that identify a file on a file system.
On *BSD (getfh and fhopen) using this is as simple as:
#include <sys/param.h>
#include <sys/mount.h>
fhandle_t file_handle;
getfh("<file_path>", &file_handle); // Or `getfhat` for the *at-style API
// … possibly save handle as bytes somewhere and recreate it some time later …
int fd = fhopen(&file_handle, O_RDWR);
The last call requiring the caller to be root however.
The Linux name_to_handle_at and open_by_handle_at system calls are similar, but a lot more explicit and require the caller to keep track of the relevant file system mount IDs/UUIDs themselves, so I'll humbly link to the detailed example in the manpage instead. Beware, that the example is not complete if you are looking to persist the handles across reboots; one has to convert the received mount ID to a persistent filesystem identifier, such as a filesystem UUID, and convert that back to a mount ID later on. In essence they do the same however. And just like on *BSD using the later system call requires elevated privileges (CAP_DAC_READ_SEARCH to be exact).

Linux device file is missing

I find the driver specific stuff in /sys/class/graphic/XM_403
But in /dev/ is no XM_403 file.
Here is the pertinent code.
graphic_class = class_create(THIS_MODULE,"graphic");
device_create(graphic_class,NULL,MKDEV(MAJOR_NR,minor),NULL,"XM_403");
device_create creates a file within the sysfs, exactly what you are seeing.
Usually it's udev that creates the device file.

Re-edit netif_Rx function and up the respective module

I edit the function netif_rx in the dev.c at the /net/core just to make a printk when a packet arrives.
I called "make" at the kernel's root directory but i don't know witch module was compiled. I need to update the old-module ir order to turn on the changes that i made.
If i want to see my changes i need to:
1-make at the kernel's root directory;
2- make modules;
3-make bzImage;
4- insert the new bzImage on the grub file;
5-Reboot;
I want to to access directly to the modulean update withou do all that things.
Could you help me.
Best regards,
Ricardo Ribeiro
If I get your goal correctly, the simplest you can do is to implement your own kernel module where you register a protocol handler for ETH_P_ALL with dev_add_pack(). This way you will receive all incoming packets for a particular device (if you also specify pt->dev) or all devices (if pt->dev is NULL).

QFileDialog doesn’t list tty* files in /dev/ on Linux

I’m working on a Linux desktop application that needs to open a USB serial port, typically /dev/ttyUSB0 or /dev/ttyUSB1. I’m using QFileDialog to let the user select the file:
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setFilter(QDir::System | QDir::AllEntries | QDir::Hidden);
dialog.setViewMode(QFileDialog::Detail);
QStringList fileNames;
if (dialog.exec())
fileNames = dialog.selectedFiles();
When I direct the FileDialog to /dev, none of the files that I can see by typing “ls /dev -al” are there. The directories show up, but for example, this file doesn’t:
$ ls -al /dev/ttyS0
crw-rw---- 1 root dialout 4, 64 2011-10-09 10:47 /dev/ttyS0
My user is a member of the dialout group:
$ groups
luke adm dialout cdrom audio video plugdev users fuse netdev bluetooth lpadmin admin sambashare
I’ve tried adding QDir::Readable and QDir::Writable and the above file still doesn’t show up. What am I doing wrong?
It amazes me how often people don't answer the question that was originally asked. I'll try not to do that here, if I can. I've done some homework on this problem since I'm having exactly the same issue. The short answer is that you can't use QFileDialog to reliably list and select nodes in "/dev". When you set the "QDIR::System" bit in the QFileDialog Filter using QFileDialog::setFilter(QDIR::System), you would expect that all the files in /dev would show up, but they do not. Admittedly, there are more entries than when it is not set, but most of the device nodes are still not displayed. It is clear that QFileDialog is doing some additional filtering behind the scenes, and that this filtering cannot be turned off in any obvious way.
On the other hand, if you use the QDir class with the QDir::System filter bit set, then in fact all of the /dev entries do appear in the entryList. For example, assuming that you already have a QComboBox named TTYDevices in your user interface, try something like this:
DevDir=new QDir("/dev","tty*",QDir::Name,QDir::System);
ui->TTyDevices->addItems(DevDir->entryList());
Then use the standard signals from QComboBox to detect and act on selection of the desired device node. By the way, ui is the standard Qt pointer to the instance of your parent window class and should be set up in the Window's constructor. Just make sure that you don't reference it before the constructor calls ui->setupUi(this). If you do, the program will crash.
This trick provides identical functionality to QFileDialog, with the additional features provided by accessing the QDir object directly. It does mean that you cannot easily have the same familiar, uniform interface provided QFileDialog, but it works and is remarkably easy to code.

Resources