martinpitt / umockdev

Mock hardware devices for creating unit tests and bug reporting
https://launchpad.net/umockdev
GNU Lesser General Public License v2.1
308 stars 55 forks source link

Support for spidev SPI_IOC_MESSAGE #121

Closed mincrmatt12 closed 3 years ago

mincrmatt12 commented 3 years ago

I've been working on an SPI driver for libfprint and I'm trying to add tests for it using umockdev.

Although umockdev-record seems to properly output a device node file, trying to record ioctls just gives a blank file with the devnode at the top. I'm fairly sure this isn't #96 because I was testing with my prototype code here which doesn't do any signal hooking.

I'm fairly sure this is just because umockdev isn't setup for the SPI_IOC_MESSAGE ioctl (which is the only syscall the current libfprint implementation will ever use on spi devices), since from my limited viewing of the code here I don't think it's designed to record arbitrary ioctls.

If you could add support for these (or point me to any resources on where to hack it in myself), that'd be great!

martinpitt commented 3 years ago

The known ioctl emulations are defined here. https://www.kernel.org/doc/html/v5.7/spi/spidev.html does not explain how that actually looks like. I found this example where it is relatively complex, you'll need a I_NAMED_SIMPLE_STRUCT_IN I suppose.

However, maybe hold your horses for a bit -- in #118 , @benzea is working on handling ioctls on the test side instead of the preload, which should make this whole thing a bit more flexible.

benzea commented 3 years ago

For the libfprint SPI stuff we currently only need at maximum one write followed by a read (or just a single write/read).

https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/235/diffs#5db95b922b7d4e96dc70034a2eec76d59572610e_0_325

What makes it a bit simpler here is, that libfprint will always use ioctl, rather than mixing read/write/ioctl. At the end, the ioctl is pretty much an IO vector, but with read/write/duplex information for each buffer. If we want to do this properly, then we need to be able to handle both ioctl and read/write from the same place.

@mincrmatt12 you can find related work to #118 in https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/258 and https://github.com/benzea/umockdev/tree/benzea/pcap-usb-replay.

WeierAndreas commented 3 years ago

Hi, I have the same issue as @mincrmatt12. I would also really appreciate to have spi working. Actually to be more detailed, I would be the support of spidev devices. I am using linux spidev interface over the spidev python library, so for now I could do a workaround by creating an simple mock of that libray when testing. But it would be very helful to have the spidev interface supported by umockdev.

Kernel interface doc: https://www.kernel.org/doc/Documentation/spi/spidev

If I should not wait on #118, I would also be happy to contribute in order to add support to this feature.

benzea commented 3 years ago

@WeierAndreas, the trouble is that for correct emulation, you need to both capture read/write and ioctl at the same time. Without #118, you cannot do that properly, but with #118 in, we should be able to take the next step and actually emulate both ioctl's and read/write from the same context.

For libfprint, I don't need that, but in your case it may be needed for proper emulation. But, #118 would just provide the infrastructure, we would still need to integrate the read/write into the ioctl tree handling for example.

So, not entirely sure how to best move forward here. I don't yet fully like the idea of adding special handling for SPI devices (as I have for USB devices with pcap USB monitor replay support).

benzea commented 3 years ago

So, I created a branch, which hopefully makes it just work by using --ioctl for both recording and replay. Note that this consolidates read/write handling into the ioctl emulation (in this case, poll will not be useful at all).

Note that this does not create an ioctl "tree" file, but a special SPI file that just contains read/write transfer chunks.

I don't have an SPI device though, so this is entirely untested right now :-(

If anyone could test it, that would be really appreciated. I am sure there are a lot of horrible bugs in there. Please ping me on IRC (benzea on most networks) if I can help in any way.

See https://github.com/benzea/umockdev/tree/benzea/spi. I'll need to do some cleanups and will need to rebase all the branches. So please be a bit careful.

benzea commented 3 years ago

If anyone needs ioctl's other than SPI_IOC_MESSAGE then you'll need to add a (dummy) implementation for them. It should be really simple to do, I just didn't have any use for it as there is no reason for libfprint to ever call any of them.

So, merge requests are welcome!