FR: Option to delegate function setup to external programs
systemd, together with gt, offers a way to provision the function before passing control to a user program that handles the rest. Collabora has a writeup that covers some details on how this works.
This would be nice for situations where one absolutely doesn't want any part of the function to be ran as root at any time (except maybe during installation where one could generate and install the gadget scheme file from within python-functionfs), and there will be no lingering management process waiting to clean up the provisioned function which saves a bit of RAM.
Thanks for the heads-up.
I reply a bit out-of-order as I think my response makes a bit more sense this way.
This would be nice for situations where one absolutely doesn't want any part of the function to be ran as root at any time
This point, taken in isolation, should already be possible with the code as-is: only functionfs.gadget, which sets up the mountpoint and the device-wide options (everything in the gt template), ever needs to run as root. It changes user (...unless not told what user to pick) before executing the function's code. At least, this is the intention, and I would be quite surprised if it does not work as my own gadgets make use of this (as opposed to USB3, for example, as I do not have any USB3-enabled gadget).
Collabora has a writeup that covers some details on how this works.
Here is what I understand so far of the work needed to add support for this:
- there should be nothing to do to integrate with gt, besides not using
functionfs.gadget - it must not write the descriptors to ep0, as systemd already did that
- ...but it must still know which endpoints are to be managed and in which direction, and possibly instanciating custom classes, which so far is implemented by looking at the descriptors provided by the caller. Here, these descriptors would be redundant with
USBFunctionDescriptors=given to systemd. I guess the least-ugly workaround would be for this project to somehow get access to that file, parse it and get the needed values from there. Then the duplications are the path to that file and the code parsing that file. - as you mentioned,
functionfscould generate this file, as it is already capable of serialising it. This could be as easy as adding'getDescsV2'tofunctionfs.__all__.
Am I missing anything ?
I gave a stab at it, and while I have yet to implement the descriptor parser, the only bad surprise so far is that the current endpoint class API did not expect to receive a file descriptor as first argument (bad first argument name, docstrings explicitly mentioning string as the only expected type), and did not expect to have to pass a closefd argument to io.FileIO. Changing this will break compatibility. So far, I assume sd_listen_fds_with_names will be usable and the descriptors can be closed. Of course, I do not do the systemd calls in functionfs.Function and instead expect the plain values.
Then of course some testing will be needed to check if this is actually usable and doing what is expected.