Seeing ioctl()s on i2c device failing during a call to i2creg.Open() using periph/golang but not on the same device when using i2cdump. Running as root user in both cases. Completely reproducible.
periph test app is conn/i2c/i2creg/example_test.go (renamed to example.go, built for mips, added func main())
i2cdump strace -f output:
root@Omega-DFEB:~# strace i2cdump -y -r 0-2 0 0x36 w
execve("/usr/sbin/i2cdump", ["i2cdump", "-y", "-r", "0-2", "0", "0x36", "w"], [/* 12 vars */]) = 0
set_thread_area(0x77b39d48) = 0
set_tid_address(0x77b32cac) = 2623
open("/etc/ld-musl-mipsel-sf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=76975, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\20(\0\0004\0\0\0"..., 936) = 936
mmap2(NULL, 143360, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x77a6a000
mmap2(0x77a8c000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x12000) = 0x77a8c000
close(3) = 0
mprotect(0x413000, 4096, PROT_READ) = 0
open("/dev/i2c/0", O_RDWR|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/dev/i2c-0", O_RDWR|O_LARGEFILE) = 3
ioctl(3, _IOC(0, 0x7, 0x5, 0), 0x7fa366d4) = 0 <--------------------- NOTE: This is the call that fails first
ioctl(3, _IOC(0, 0x7, 0x3, 0), 0x36) = 0
ioctl(1, TIOCGWINSZ, 0x7fa36620) = 0
writev(1, [{iov_base=" 0,8 1,9 2,a 3,b 4,c 5,"..., iov_len=43}, {iov_base="\n", iov_len=1}], 2 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f
) = 44
ioctl(3, _IOC(0, 0x7, 0x20, 0), 0x7fa36674) = 0
ioctl(3, _IOC(0, 0x7, 0x20, 0), 0x7fa36674) = 0
ioctl(3, _IOC(0, 0x7, 0x20, 0), 0x7fa36674) = 0
writev(1, [{iov_base="00: 00fc ecfc 13ff "..., iov_len=44}, {iov_base="\n", iov_len=1}], 200: 00fc ecfc 13ff
) = 45
exit_group(0) = ?
+++ exited with 0 +++
root@Omega-DFEB:~#
But when I run the i2c example under strace -f we get:
...
[pid 1744] write(1, "&{/dev/i2c-0 [I2C0] 0 0xe23dc}\n", 31&{/dev/i2c-0 [I2C0] 0 0xe23dc}
) = 31
[pid 1744] write(1, "openerI2C.Open()\n", 17openerI2C.Open()
) = 17
[pid 1744] openat(AT_FDCWD, "/dev/i2c-0", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 5
[pid 1744] epoll_ctl(4, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1860607744, u64=1860607744}}) = -1 EPERM (Operation not permitted)
[pid 1744] epoll_ctl(4, EPOLL_CTL_DEL, 5, 0xc7cdac) = -1 EPERM (Operation not permitted)
[pid 1744] write(1, "before ioctl call\n", 18before ioctl call
) = 18
[pid 1744] ioctl(5, _IOC(_IOC_NONE, 0x7, 0x5, 0), 0xc50104) = -1 ENOTTY (Not a tty)
[pid 1744] write(1, "returning error\n", 16returning error
) = 16
[pid 1744] write(1, "I\302\262C buses available:\n", 22I²C buses available:
) = 22
[pid 1744] write(1, "- /dev/i2c-0\n", 13- /dev/i2c-0
) = 13
[pid 1744] write(1, " 0\n", 4 0
) = 4
[pid 1744] write(1, " I2C0\n", 7 I2C0
) = 7
[pid 1744] openat(AT_FDCWD, "/dev/i2c-0", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 6
[pid 1744] epoll_ctl(4, EPOLL_CTL_ADD, 6, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1860607744, u64=1860607744}}) = -1 EPERM (Operation not permitted)
[pid 1744] epoll_ctl(4, EPOLL_CTL_DEL, 6, 0xc7cd70) = -1 EPERM (Operation not permitted)
****************** This ioctl() fails ********************
[pid 1744] ioctl(6, _IOC(_IOC_NONE, 0x7, 0x5, 0), 0xc50134) = -1 ENOTTY (Not a tty)
[pid 1744] write(1, "returning error\n", 16returning error
) = 16
[pid 1744] write(1, " Failed to open: sysfs-i2c: ina"..., 59 Failed to open: sysfs-i2c: inappropriate ioctl for device) = 59
[pid 1744] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x10} ---
[pid 1744] rt_sigreturn() = 0
[pid 1744] nanosleep({tv_sec=0, tv_nsec=1000}, <unfinished ...>
[pid 1746] <... futex resumed> ) = 1
[pid 1744] <... nanosleep resumed> NULL) = 0
[pid 1744] nanosleep({tv_sec=0, tv_nsec=1000}, <unfinished ...>
[pid 1746] futex(0xc282b4, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
[pid 1744] <... nanosleep resumed> NULL) = 0
[pid 1744] write(2, "panic: ", 7panic: ) = 7
[pid 1744] write(2, "runtime error: invalid memory ad"..., 64runtime error: invalid memory address or nil pointer dereference) = 64
[pid 1744] write(2, "\n", 1
) = 1
[pid 1744] write(2, "[signal ", 8[signal ) = 8
[pid 1744] write(2, "SIGSEGV: segmentation violation", 31SIGSEGV: segmentation violation) = 31
[pid 1744] write(2, " code=", 6 code=) = 6
[pid 1744] write(2, "0x1", 30x1) = 3
[pid 1744] write(2, " addr=", 6 addr=) = 6
[pid 1744] write(2, "0x10", 40x10) = 4
[pid 1744] write(2, " pc=", 4 pc=) = 4
[pid 1744] write(2, "0xe3ae0", 70xe3ae0) = 7
[pid 1744] write(2, "]\n", 2]
) = 2
[pid 1744] write(2, "\n", 1
) = 1
[pid 1744] write(2, "goroutine ", 10goroutine ) = 10
[pid 1744] write(2, "1", 11) = 1
[pid 1744] write(2, " [", 2 [) = 2
[pid 1744] write(2, "running", 7running) = 7
[pid 1744] write(2, "]:\n", 3]:
) = 3
[pid 1744] write(2, "main.ExampleAll", 15main.ExampleAll) = 15
[pid 1744] write(2, "(", 1() = 1
[pid 1744] write(2, ")\n", 2)
) = 2
[pid 1744] write(2, "\t", 1 ) = 1
...
I've tried removing that ioctl() call and the same error occurs later:
[pid 1720] openat(AT_FDCWD, "/dev/i2c-0", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 6
[pid 1720] epoll_ctl(4, EPOLL_CTL_ADD, 6, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1866661632, u64=1866661632}}) = -1 EPERM (Operation not permitted)
[pid 1720] epoll_ctl(4, EPOLL_CTL_DEL, 6, 0x87cd6c) = -1 EPERM (Operation not permitted)
[pid 1720] write(1, "returning i of I2C0\n", 20returning i of I2C0
) = 20
******************** This IOCTL fails ************************
[pid 1720] ioctl(6, _IOC(_IOC_NONE, 0x7, 0x7, 0), 0x87cef4) = -1 ENOTTY (Not a tty)
[pid 1720] clock_gettime(CLOCK_REALTIME, {tv_sec=1545341968, tv_nsec=65321400}) = 0
[pid 1720] clock_gettime(CLOCK_MONOTONIC, {tv_sec=907, tv_nsec=372203156}) = 0
[pid 1720] openat(AT_FDCWD, "/etc//localtime", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
[pid 1720] write(2, "2018/12/20 21:39:28 sysfs-i2c: i"..., 622018/12/20 21:39:28 sysfs-i2c: inappropriate ioctl for device
) = 62
[pid 1720] exit_group(1) = ?
[pid 1722] <... futex resumed>) = ?
[pid 1722] +++ exited with 1 +++
[pid 1721] <... clock_gettime resumed> <unfinished ...>) = ?
[pid 1721] +++ exited with 1 +++
+++ exited with 1 +++
root@Omega-DFEB:~#
I'm stumped. The device is opened differently though, i2cdump calls:
open("/dev/i2c-0", O_RDWR|O_LARGEFILE) = 3
but golang calls:
[pid 1744] openat(AT_FDCWD, "/dev/i2c-0", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 6
Could it be O_CLOEXEC? That looks entirely necessary as golang seems to fork a bunch...
Any ideas?