eudev-project / eudev

Repository for eudev development
GNU General Public License v2.0
522 stars 147 forks source link

RetroArch fails to detect input devices with EUDEV #227

Open vanfanel opened 2 years ago

vanfanel commented 2 years ago

Hi there,

After the great news that EUDEV is back to active development, I am trying to use it for some of my embedded systems. One of the main tests I do is RetroArch compatibility.

Strangely enough, EUDEV doesn't work with RetroArch after rebuilding RetroArch against EUDEV.

RetroArch says:

[WARN] [udev]: Couldn't open any keyboard, mouse or touchpad. Are permissions set correctly for /dev/input/event* and /run/udev/?
[INFO] [Joypad]: Found joypad driver: "udev".

Which comes from this piece of code:

https://github.com/libretro/RetroArch/blob/dcc67278754452071c0c6c073d239f7e90b7b2a2/input/drivers/udev_input.c#L1452

Seems to me that it's simply trying to open devices using libudev function calls, so it should work with libeudev too.

Note that this system does NOT have eudev's udevd daemon running, because harware is connected before booting so I don't need any hotplug events being processed.

All intended nodes (created by the kernel's DEVTMPFS) are in /dev/input (where /dev/input/event2 is the keyboard).

This other udev implementation (which is awesome, btw) works well with RA: https://github.com/illiliti/libudev-zero ...So I don't know WHY libudev-zero works with RA and EUDEV doesn't. Any ideas, please?

ArsenArsen commented 2 years ago

Permissions are also set by udevd (besides just reacting to events); as a hunch, can you replicate this with udevd running?
I'm also of the opinion that if (e)udevd can't run on an embedded system, the reasons why should be looked into.

I could be off, since I'm just doing a quick drive-by look, but I can give it a more in-depth look later.

Thanks!

vanfanel commented 2 years ago

@ArsenArsen Permissions should not be a problem on this system, as it's a system without any users, only root is created on the system. Unless I am misunderstanding or ignoring something with regards to permissions...

I can reproduce the issue with udevd running, yes. On an ssh TTY I do: XDG_RUNTIME_DIR=/tmp udevd -d And in another ssh TTY I do: XDG_RUNTIME_DIR=/tmp retroarch -v

...and the results are the same as before.

bbonev commented 2 years ago

@vanfanel Thanks for the report. Unfortunately I am not using RetroArch and can not test/debug this problem. Please provide more information on what is causing it and/or where the problem is, and I will help to review and merge a proposed patch. Even if you are not able to propose a patch, in case it gets located we can work together on a fix.

vanfanel commented 2 years ago

@bbonev Sorry it took me a bit long to go down the RetroArch machine room and start debugging this. So let's take a look together!

The problem seems to be in this function, open_devices():

https://github.com/libretro/RetroArch/blob/a577d7d22418836c9adecc06c3459ae731456db0/input/drivers/udev_input.c#L1343

It adds match parameters on what it's looking for, so both udev_enumerate_add_match_property and udev_enumerate_add_match_subsystem succeed.

The call to udev_enumerate_scan_devices here: https://github.com/libretro/RetroArch/blob/a577d7d22418836c9adecc06c3459ae731456db0/input/drivers/udev_input.c#L1356 also succeeds: it returns 0. No problem.

The problem is exactly here:

https://github.com/libretro/RetroArch/blob/a577d7d22418836c9adecc06c3459ae731456db0/input/drivers/udev_input.c#L1357

This call to udev_enumerate_get_list_entry returns null.

With libudev-zero (https://github.com/illiliti/libudev-zero), udev_enumerate_get_list_entry returns a proper udev_list_entry struct.

Now, remember I don't have udevd running. This system has no services. Is udevd somehow needed so udev_enumerate_get_list_entry returns a proper udev_list_entry struct? If so, why? Is there an alternative?

libudev-zero (https://github.com/illiliti/libudev-zero) works without any service running, so maybe that's why I am confused.

nekopsykose commented 1 year ago

Now, remember I don't have udevd running.

well, you also ran a test above where you started it in one tty, and it still didn't work. so the issue existed with it running, too.

but for some more testing, could you instead do a more 'normal' udevd init, something like:

udevd # make this background itself with -d, or put it somewhere else like you did before
udevadm trigger --attr-match=dev --action=add
udevadm trigger --subsystem-match=net --action=add
udevadm trigger --type=subsystems --action=add
udevadm trigger --type=devices --action=add
udevadm settle

and then trying again? i'm not sure if that's entirely correct (there might be a few other requirements i'm forgetting, and i didn't test if it literally works, but you need to run some triggers), but it should be a little more full than just 'udevd' to set it up, in case eudev needs to do a coldplug to work correctly. systemd more or less requires the same: https://github.com/systemd/systemd/issues/17373#issuecomment-711992464 , as the mode of operation here is a little different than what libudev-zero is doing (no udev rules, just stuff with readied devices).