Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: mdev wrapper for udev rule emulation #89

Open
git-bruh opened this issue Aug 31, 2022 · 14 comments
Open

proposal: mdev wrapper for udev rule emulation #89

git-bruh opened this issue Aug 31, 2022 · 14 comments
Labels

Comments

@git-bruh
Copy link
Member

git-bruh commented Aug 31, 2022

Packages can individually install rules in the mdev.conf syntax to /etc/mdev.conf.d/*, which will be amalgamated and passed to the mdev implementation

@Riteo
Copy link

Riteo commented Aug 31, 2022

I had a similar idea and I support this approach. Just one thing, what do you mean by "amalgamated"? Will the mdev.conf config be rewritten everytime?

@git-bruh
Copy link
Member Author

I had a similar idea and I support this approach. Just one thing, what do you mean by "amalgamated"? Will the mdev.conf config be rewritten everytime?

No, I just mean something like cat /etc/mdev.conf /etc/mdev.conf.d/*.conf | mdev --config=/dev/stdin

@Riteo
Copy link

Riteo commented Aug 31, 2022

Oh, didn't think about this. This is a really cool approach! The only thing I'm concerned about is the fact that this would tie everything to mdev instead of having something like the init-agnostic hook system.

I should have talked about this in the previous ticket IIRC, but basically IMO it'd be better to use something like the Linux hotplug interface which should also be exposed by mdev by making it call a script. It'd also not require to restart the whole mdev service everytime the device rules file would change. I got a POC installed on my system which works pretty well.

I'm aware that my proposed solution is more complex, but IMO the advantage of being able to reuse rules across device managers outweighs the cons.

@git-bruh
Copy link
Member Author

Can you share the POC? Creating a framework is more portable but it would be more messy, and @illiliti has raised some concerns over fork + exec implementation for a framework: https://libera.irclog.whitequark.org/kisslinux/2022-08-30#32825590;

https://libera.irclog.whitequark.org/kisslinux/2022-08-30#32825796

@Riteo
Copy link

Riteo commented Aug 31, 2022

Sadly my POC uses scripts so it definitely has the issues pointed out by illiliti.
Anyways, it's pretty simple, it's just an mdev configuration line and a dispatch script, everything else would be "user-defined".

/etc/mdev.conf:

SUBSYSTEM=usb;.* root:root 660 @/etc/mdev.d/usb-helper

/etc/mdev.d/usb-helper:

#!/bin/sh

for script in /etc/mdev.d/usb/*
do
	source "$script"
done

The programs run by mdev have access to a few environment variables outlined here: https://www.kernel.org/doc/html/v4.18/driver-api/usb/hotplug.html#usb-policy-agent

I use this "framework" for running a little script that scans a list of regexes (with optional comments) and, if the usb product ID matches, it sets its permission to the one defined by the list's filename.

/etc/mdev.d/usb/usbgroup.sh:

#!/bin/sh

for groupdef in /etc/mdev.d/usb/groups/*
do
	group_name="$(basename "$groupdef")";

	if printf "%s\n" "$PRODUCT" | grep -qxe "$(grep -v -e '#' -e '^\n' "$groupdef")"
	then
		chmod g+rw "/dev/$DEVNAME" && chgrp "$group_name" "/dev/$DEVNAME"
	fi
done

this script in turn looks for files into a groups directory which for example are:
/etc/mdev.d/usb/groups/android

18d1/4ee7/.*
4e8/6860/.*

# Xiaomi Mi A2 (recovery)
2a70/4ee7/.*

# Google Android
18d1/d00d/.*
18d1/4ee1/.*
483/374b/.*

While this is very hackish, it works fine for my needs.

@git-bruh
Copy link
Member Author

git-bruh commented Sep 2, 2022

What about coming up with an easy to parse format for udev rules which can be used to generate configs for individual device managers?

@Riteo
Copy link

Riteo commented Sep 3, 2022

@git-bruh that doesn't really convince me at all. You'd have to ship the udev rules and have always in your computer an udev parser, which to me just looks like a good way of supporting that hellish format.

@Riteo
Copy link

Riteo commented Sep 3, 2022

Sorry for the double post, but I and @illiliti have found a good compromise (IMO), which consists of having scripts run per subsystem by using the SUBSYSTEM variable as the directory name to look for. That should keep forks down to a minimum while allowing the most flexibility in the most device-manager-portable way (but still limited to Linux).

@git-bruh
Copy link
Member Author

git-bruh commented Sep 3, 2022

@Riteo
Copy link

Riteo commented Sep 4, 2022

@git-bruh thanks for finding the ref! I didn't think about it. What do you think about this approach?

@git-bruh
Copy link
Member Author

git-bruh commented Sep 4, 2022

@Riteo I still feel it's clunky due to duplication of matching functionality of mdev with printf | grep and chmod / chgrp calls. I'd still prefer the config method though (or atleast config generation from rule file), as we already sort of have a "default" init system as far as packages are concerned - we only install /etc/sv/*/run files.

@Riteo
Copy link

Riteo commented Sep 4, 2022

@git-bruh you're right regarding the fact that this solution would duplicate some of mdev functionality. They're both hotplug managers really.

The thing is though, that having a complete configuration parser and converter brings up its own issues, ranging to theoretical or kinda minor (in the case of using udev rules, wouldn't it reinforce it as a de facto standard?) to practical (wouldn't it be a duplication too? Why not patch the device manager directly to read said format? What if the target device manager doesn't support some features of the "generic" format? How do we choose the "generic" syntax?)

The nice thing about scripts is that they're universal (well, as far as Linux is concerned).
They can be written in any language and can be guaranteed to work anywhere. Also, they've technically got way more power than mdev or any other device manager since they're actual programs (with all the good and bad things they bring).

Another compromise of which I thought of was to make some "domain-specific" """language""" like with the most common case of giving certain permissions to specific USB ids. So you'd have your single script/binary concerning the USB subsystem that'd sieve through a list of ids and assign the group according to something like the filename or some other implementation-specific detail (i'd still expose the directory-per-subsystem approach thought by me and illiliti though). This'd keep forking to a minimum while giving space for esoteric packages to do the weirdest things would they need that.

Wrapping this up, I think that this could be like an alternative generic package-accessible system for some weirder things which should be common to all device managers, while mdev, mdevd and whatever should handle the basic things and the dispatching to this fallback script-based system. Your idea sounds interesting, but it really feels like some slippery slope as something tells me that it'd either create a de facto standard or some intermediate thing which'd do either too much or too little.

@git-bruh
Copy link
Member Author

git-bruh commented Sep 4, 2022

@Riteo I'm fine with your suggestion too, it's probably better for more complex rules as well which can't be expressed in a config file

@git-bruh
Copy link
Member Author

@kiss-community kiss-community locked and limited conversation to collaborators Sep 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants