Linux: how do i know the module that exports a device node? - linux

If a have a /dev device node and its major/minor numbers how do i know the kernel module name that exported this node?

Short answer :
cd /sys/dev/char/major:minor/device/driver/
ls -al | grep module
Each device is generally associated with a driver, and this is all what the "device model" is about. The sysfs filesystem contains a representation of this devices and their associated driver. Unfortuantely, it seems not all sysfs have a representation of the device nodes, so this applyd only if your /sys directory contains a /dev directory.
Let's take an example, with /dev/video0
On my board, ls -al /dev/video0 output is
crw------- 1 root root 81, 0 Jan 1 00:00 video0
So major number is 81 and minor number is 0.
Let's dive into sysfs :
# cd /sys
# ls
block class devices fs module
bus dev firmware kernel
The sys/dev directory contains entry for the char and block devices of the system :
# cd dev
# cd char
# ls
10:61 13:64 1:3 1:8 249:0 252:0 29:0 4:65 81:0 89:1
10:62 1:1 1:5 1:9 250:0 253:0 29:1 5:0 81:2
10:63 1:11 1:7 248:0 251:0 254:0 4:64 5:1 81:3
What the hell are this links with strange names ?
Remember the major and minor number, 81 and 0 ?
Let's follow this link :
#cd major:minor (ie 81:0)
#ls -al
drwxr-xr-x 2 root root 0 Jan 1 01:56 .
drwxr-xr-x 3 root root 0 Jan 1 01:56 ..
-r--r--r-- 1 root root 4096 Jan 1 01:56 dev
lrwxrwxrwx 1 root root 0 Jan 1 01:56 device -> ../../../vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 index
-r--r--r-- 1 root root 4096 Jan 1 01:56 name
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../../../class/video4linux
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
Now we can see that this device nod, which is how the device is presented to userspace, is associated with a kernel device. This association is made through a link. If we follow this link, we end up in a directory, with a driver link. The name of the driver is usually the name of the module :
# ls -al
drwxr-xr-x 3 root root 0 Jan 1 01:56 .
drwxr-xr-x 25 root root 0 Jan 1 00:00 ..
lrwxrwxrwx 1 root root 0 Jan 1 01:56 driver -> ../../../bus/platform/drivers/vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 modalias
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../bus/platform
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
drwxr-xr-x 3 root root 0 Jan 1 01:56 video4linux
So here the name of the module is vpfe_capture

The answer to this question is most likely different based on a number of factors. For example, if you're running udev, devfs, pre-devfs, etc.
If you're using Ubuntu (or another equally modern distro) the udevadm command might be what you want.
% udevadm info -q path -n /dev/cdrom
/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/block/sr0
So, my /dev/cdrom is provided by the sr driver, which resides in the sr_mod kernel module. I don't know of a command that takes /dev/cdrom as an argument and prints sr_mod as output.

Related

Raspberry ISO mount via sshfs fails

I hope someone can help me with my problem.
Background: I want to mount very big ISOs to my raspberry via sftp.
If I try to mount the iso from a local folder, for example Downloads\2005-2010.iso it works perfect. But if I try to mount the ISO from a mounted sshfs folder, it fails. I also tryed to change the permission to 777 (only for testing) to the mounted ftp folder, but no success.
I using "sshfs" to mount my ftp webhosting folder. (Works perfect)
The Output is different to the following statements:
Statement
sudo mount /home/pi/isomount/2005-2010.iso /home/pi/medien/2005-2010/
1.1 Output
mount: /home/pi/medien/2005-2010: cannot mount /home/pi/isomount/2005-2010.iso read-only.
Statement
sudo mount -o loop /home/pi/isomount/2005-2010.iso /home/pi/medien/2005-2010/
2.1 Output
mount: /home/pi/medien/2005-2010/: failed to setup loop device for /home/pi/isomount/2005-2010.iso.
Any idears what I can do to mount this .iso?
For me, this worked :
sudo bash
# Now in root
mkdir /tmp/iso
mount /home/pi/isomount/2005-2010.iso /tmp/iso
More details
~# cd /home/ubuntu/dev
/home/ubuntu/dev# df -k .
Filesystem 1K-blocks Used Available Use% Mounted on
User#remotehost:dev 487213052 380126780 107086272 79% /home/ubuntu/dev <-- sshfs mounted
/home/ubuntu/dev# ls -l ubuntu-20.04.3-desktop-amd64.iso
-rwx------ 1 197609 197121 3071934464 Dec 28 10:44 ubuntu-20.04.3-desktop-amd64.iso
/home/ubuntu/dev# mount ubuntu-20.04.3-desktop-amd64.iso /tmp/iso
mount: /tmp/iso: WARNING: device write-protected, mounted read-only.
/home/ubuntu/dev# ls -ltr /tmp/iso
total 101
lr-xr-xr-x 1 root root 1 Aug 19 11:59 ubuntu -> .
dr-xr-xr-x 1 root root 2048 Aug 19 11:59 preseed
dr-xr-xr-x 1 root root 2048 Aug 19 11:59 pool
dr-xr-xr-x 1 root root 2048 Aug 19 11:59 dists
dr-xr-xr-x 1 root root 2048 Aug 19 12:01 install
dr-xr-xr-x 1 root root 2048 Aug 19 12:01 casper
dr-xr-xr-x 1 root root 2048 Aug 19 12:01 boot
dr-xr-xr-x 1 root root 2048 Aug 19 12:01 EFI
dr-xr-xr-x 1 root root 34816 Aug 19 12:01 isolinux
-r--r--r-- 1 root root 53487 Aug 19 12:03 md5sum.txt
My sshfs mount options in /etc/mtab :
User#remotehost:dev /home/ubuntu/dev fuse.sshfs rw,nosuid,nodev,relatime,user_id=1001,group_id=1001,allow_other 0 0

Can't run dmidecode on docker container

I am trying to run command dmidecode in my docker container,
docker run --device /dev/mem:/dev/mem -it jin/ubu1604
However, it claims that there is no permission
root#bd1062dfd8ab:/# dmidecode
# dmidecode 3.0
Scanning /dev/mem for entry point.
/dev/mem: Operation not permitted
root#bd1062dfd8ab:/# ls -l /dev
total 0
crw--w---- 1 root tty 136, 0 Jan 7 03:21 console
lrwxrwxrwx 1 root root 11 Jan 7 03:20 core -> /proc/kcore
lrwxrwxrwx 1 root root 13 Jan 7 03:20 fd -> /proc/self/fd
crw-rw-rw- 1 root root 1, 7 Jan 7 03:20 full
crw-r----- 1 root kmem 1, 1 Jan 7 03:20 mem
drwxrwxrwt 2 root root 40 Jan 7 03:20 mqueue
crw-rw-rw- 1 root root 1, 3 Jan 7 03:20 null
lrwxrwxrwx 1 root root 8 Jan 7 03:20 ptmx -> pts/ptmx
drwxr-xr-x 2 root root 0 Jan 7 03:20 pts
crw-rw-rw- 1 root root 1, 8 Jan 7 03:20 random
drwxrwxrwt 2 root root 40 Jan 7 03:20 shm
lrwxrwxrwx 1 root root 15 Jan 7 03:20 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jan 7 03:20 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jan 7 03:20 stdout -> /proc/self/fd/1
crw-rw-rw- 1 root root 5, 0 Jan 7 03:20 tty
crw-rw-rw- 1 root root 1, 9 Jan 7 03:20 urandom
crw-rw-rw- 1 root root 1, 5 Jan 7 03:20 zero
This confused me. Since I was able to run dmidecode -t system on the host (ubuntu 14.04) fine.
I even followed some advice and set the permission on dmidecode executable
setcap cap_sys_rawio+ep /usr/sbin/dmidecode
It still doesn't work.
Any ideas?
UPDATE
Based on David Maze's answer, the command should be
run --device /dev/mem:/dev/mem --cap-add SYS_RAWIO -it my/ubu1604a
Do this only when you are going to trust what runs in container. For example, if you are test installation procedure on a pristine OS.
Docker provides an isolation layer, and one of the major goals of Docker is to hide details of the host's hardware from containers. The easiest, most appropriate way to query low-level details of the host's hardware is from a root shell on the host, ignoring Docker entirely.
The actual mechanism of this is by restricting Linux capabilities. capabilities(7) documents that you need CAP_SYS_RAWIO to access /dev/mem, so in principle you can launch your container with --cap-add SYS_RAWIO. You might need other capabilities and/or device access to make this actually work, because Docker is hiding the details of what you're trying to access as a design goal.

Mkdir creates file instead of directory on windows network drive mounted as drvfs using Ubuntu/windows 10 under WSL

The command mkdir creates a file rather than a directory on a mounted network drive on a windows 10 system operating under the Windows sub-system for linux, using the Ubuntu app.
After installing the ubuntu app and putting the windows machine into developer mode I successfully mounted a remote network drive using the command:
sudo mount -t drvfs '\\networkdrive\sharename' /mnt/U
which successfully mounts the network drive at the mount point. I can see the files on the remote drive. However when looking at a directory on the remote machine and issuing the command
mkdir Source
a file called Source is created on the remote drive rather than a directory.
I tried this on two completely different laptops running windows 10, which I set up in exactly the same way and the same problem happens. The windows 10 machines are in developer mode and running the latest version of the ubuntu app. This is a pretty fundamental thing to have go wrong so I'm guessing it's a bug of some sort.
The snippet below is the terminal output which illustrates the problem.
username#~$ pwd
/home/username
username#~$ sudo mount -t drvfs '\\networkdrive.host\sharename\' /mnt/U
[sudo] password for username:
username#~$ cd /mnt/U/People/username/projects/Vesiform
username#Vesiform$ ls -al
total 0
drwxrwxrwx 0 root root 512 Mar 29 2018 .
drwxrwxrwx 0 root root 512 Mar 28 12:04 ..
drwxrwxrwx 0 root root 512 Mar 28 11:12 Builder
drwxrwxrwx 0 root root 512 Mar 28 11:42 Library
drwxrwxrwx 0 root root 512 Mar 28 11:42 NPack
drwxrwxrwx 0 root root 512 Mar 28 11:42 PDBProc
drwxrwxrwx 0 root root 512 Mar 28 11:55 Projects
drwxrwxrwx 0 root root 512 Mar 28 11:55 SpacePack
drwxrwxrwx 0 root root 512 Mar 28 11:55 Utilities
username#Vesiform$ mkdir Source
username#Vesiform$ ls -al
total 0
drwxrwxrwx 0 root root 512 Mar 29 2018 .
drwxrwxrwx 0 root root 512 Mar 28 12:04 ..
drwxrwxrwx 0 root root 512 Mar 28 11:12 Builder
drwxrwxrwx 0 root root 512 Mar 28 11:42 Library
drwxrwxrwx 0 root root 512 Mar 28 11:42 NPack
drwxrwxrwx 0 root root 512 Mar 28 11:42 PDBProc
drwxrwxrwx 0 root root 512 Mar 28 11:55 Projects
-rwxrwxrwx 1 root root 0 Mar 29 2018 Source
drwxrwxrwx 0 root root 512 Mar 28 11:55 SpacePack
drwxrwxrwx 0 root root 512 Mar 28 11:55 Utilities
username#Vesiform$ cd Source
-bash: cd: Source: Not a directory
username#Vesiform$

linux kernel: regulator consumer usage from userspace

I have some kind of driver in user space:
program talk via some interface(rs232) with device.
Also I have pin(gpio) to switch on/off this device.
I do not code in my program concrete gpio, to make it more portable,
so I modify device tree description of my board,
and describe regulator-fixed, after that I thought to use
userspace-consumer driver to control power on/off,
but looks like that not kernel developers expected
(link to discussion of similar problem, not my):
http://patchwork.ozlabs.org/patch/374912/
So how should I control switch on/off
of my device from user space without adding to my program
information about what conrete gpio used to switch on/off device?
More details:
In my board dts I described my pin like this:
regulator-deviceX {
status = "okay";
compatible = "regulator-fixed";
regulator-name = "DEV_X_ON#";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio5 4 GPIO_ACTIVE_LOW>;
};
And of course, after boot "gpio = <&gpio5 4 GPIO_ACTIVE_LOW>" was
locked by the kernel, and it is impossible to use it via /sys/class/gpio interface.
Bad think about such approach, that is impossible (or I don't see how) to
change regulator state from user space, as you can see "state" is read only file.
root#board:/sys/class/regulator/regulator.1# ls -l
lrwxrwxrwx 1 root root 0 May 3 03:32 device -> ../../../regulator-deviceX
-r--r--r-- 1 root root 4096 May 3 03:32 microvolts
-r--r--r-- 1 root root 4096 May 3 03:32 name
-r--r--r-- 1 root root 4096 May 3 03:32 num_users
drwxr-xr-x 2 root root 0 May 3 03:32 power
-r--r--r-- 1 root root 4096 May 3 03:32 state
lrwxrwxrwx 1 root root 0 May 3 03:25 subsystem -> ../../../../class/regulator
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_disk_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_mem_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_standby_state
-r--r--r-- 1 root root 4096 May 3 03:32 type
-rw-r--r-- 1 root root 4096 May 3 03:25 uevent
So, the final solution looks like this:
Step 1
Describe device in device tree, though you no need
kernel for handling it, but looks right to describe it here
gps-reciever {
compatible = "my_company_name,gps_recv_name";
vcc-supply = <&ext_gps_recv_reg>;
comment = "connected via usb<->rs232, port0";
};
where ext_gps_recv_reg of any normal regulator.
Step 2
I wrote a simple platform device driver for linux kernel,
that compatible with device above, and in probe function of this
driver I call platform_device_register_full that setup arguments for
userspace_consumer driver.
After that I can find suitable file via name:
cat /sys/bus/platform/devices/reg-userspace-consumer*/name,
and then disable/enable regulator via:
echo "disabled" > /sys/bus/platform/devices/reg-userspace-consumer*/state
So I separate device description from linux kernel implementation.

Why dev.bus is NULL in my device?

i'm trying to understand how linux device/driver model works and to do this i've written a little module. This module is simple, retrieves a pointer to a struct net_device (let's call it netdev) by the function dev_get_by_name(&init_net, "eth0"). Why the value of netdev->dev.bus is NULL? Should that pointer represent the bus_type structure on which my device is attached? The field netdev->parent->bus is however not NULL but it should represent the bus for eth controller...any explanation?
This is because your eth device, or better said its device "object" in the kernel, is not a bus and thus its bus value is left unitialized. But its parent device usually is on a bus and it is sufficient that the parent device knows the bus it is on, since both device eventually are linked during the driver initialization.
Let's have a look at an example: here is what I have in sysfs for my eth0 device (notice the device field):
$ ll /sys/class/net/eth0/
total 0
-r--r--r-- 1 root root 4096 May 20 11:10 address
-r--r--r-- 1 root root 4096 May 20 11:10 addr_len
-r--r--r-- 1 root root 4096 May 20 11:10 broadcast
-r--r--r-- 1 root root 4096 May 20 11:10 carrier
lrwxrwxrwx 1 root root 0 May 20 11:10 device -> ../../../devices/pci0000:00/0000:00:19.0
-r--r--r-- 1 root root 4096 May 20 11:10 dev_id
-r--r--r-- 1 root root 4096 May 20 11:10 dormant
-r--r--r-- 1 root root 4096 May 20 11:10 features
-rw-r--r-- 1 root root 4096 May 20 11:10 flags
-rw-r--r-- 1 root root 4096 May 20 11:10 ifalias
-r--r--r-- 1 root root 4096 May 20 11:10 ifindex
-r--r--r-- 1 root root 4096 May 20 11:10 iflink
-r--r--r-- 1 root root 4096 May 20 11:10 link_mode
-rw-r--r-- 1 root root 4096 May 20 11:10 mtu
-r--r--r-- 1 root root 4096 May 20 11:10 operstate
drwxr-xr-x 2 root root 0 May 20 11:10 power
drwxr-xr-x 2 root root 0 May 20 11:10 statistics
lrwxrwxrwx 1 root root 0 May 20 11:10 subsystem -> ../../net
-rw-r--r-- 1 root root 4096 May 20 11:10 tx_queue_len
-r--r--r-- 1 root root 4096 May 20 11:10 type
-rw-r--r-- 1 root root 4096 May 20 11:10 uevent
The link for the device is created from this code from the driver probe function, where netdev is the network device, and pdev the associated PCI device:
SET_NETDEV_DEV(netdev, &pdev->dev);
Which according to the documentation is:
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
*/
#define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev))
And here is what I have in the corresponding PCI device, that was set by SET_NETDEV_DEV (where you can notice the bus field):
$ ll /sys/devices/pci0000\:00/0000\:00\:19.0/
total 0
-rw-r--r-- 1 root root 4096 May 20 11:54 broken_parity_status
lrwxrwxrwx 1 root root 0 May 20 11:22 bus -> ../../../bus/pci
-r--r--r-- 1 root root 4096 May 20 11:07 class
-rw-r--r-- 1 root root 256 May 20 11:22 config
-r--r--r-- 1 root root 4096 May 20 11:54 device
lrwxrwxrwx 1 root root 0 May 20 11:22 driver -> ../../../bus/pci/drivers/e1000e
-rw------- 1 root root 4096 May 20 11:22 enable
-r--r--r-- 1 root root 4096 May 20 11:07 irq
-r--r--r-- 1 root root 4096 May 20 11:54 local_cpulist
-r--r--r-- 1 root root 4096 May 20 11:07 local_cpus
-r--r--r-- 1 root root 4096 May 20 11:22 modalias
-rw-r--r-- 1 root root 4096 May 20 11:22 msi_bus
lrwxrwxrwx 1 root root 0 May 20 11:22 net:eth0 -> ../../../class/net/eth0
drwxr-xr-x 2 root root 0 May 20 11:11 power
-r--r--r-- 1 root root 4096 May 20 11:22 resource
-rw------- 1 root root 131072 May 20 11:22 resource0
-rw------- 1 root root 4096 May 20 11:22 resource1
-rw------- 1 root root 32 May 20 11:22 resource2
lrwxrwxrwx 1 root root 0 May 20 11:22 subsystem -> ../../../bus/pci
-r--r--r-- 1 root root 4096 May 20 11:22 subsystem_device
-r--r--r-- 1 root root 4096 May 20 11:22 subsystem_vendor
-rw-r--r-- 1 root root 4096 May 20 11:22 uevent
-r--r--r-- 1 root root 4096 May 20 11:22 vendor
I hope this clarifies the situtation.

Resources