gpiocdev-rs icon indicating copy to clipboard operation
gpiocdev-rs copied to clipboard

add a daemon to allow multiple clients to access a request

Open warthog618 opened this issue 11 months ago • 2 comments

Add D-Bus support to the cli to allow sharing of GPIOs between processes and provide an easy to setup option for sysfs users.

The concept is for the gpiocdev cli to run as a daemon managing a fixed set of lines and using a D-Bus session bus to expose methods to clients to control those lines. So a new dbusd subcommand, with options to request lines as inputs and outputs. The existing gpiocdev get/set/edge commands would get a --dbus option allowing them to access the GPIOs via the gpiocdev instance running as a daemon. Clients are not restricted to being gpiocdev.

The D-Bus methods would operate on the request, not individual lines, to maintain the "as atomic as possible" approach of the uAPI.

Potential methods:

  • get lines -> values
  • set (line,value)s
  • get_in (as per get but forces the lines to inputs)
  • set_out (as per set but forces the lines to outputs)
  • edges (signal)
  • level (simplified edges that just reports the line level)
  • reconfigure (to allow complete reconfiguration of requested lines)

There is intentionally some overlap there - the idea being to provide simple methods for common cases (I'm looking at you, sysfs), as well as more comprehensive methods for full functionality.

Going with session bus, rather than a system bus, constrains the scope to one user and so avoids wider authorisation issues. This is in contrast to the daemon Bart is working on for libgpiod, which is a single system daemon using a system bus. Not sure how he will handle access control - last I looked client access is restricted to root.

warthog618 avatar Jul 18 '23 17:07 warthog618

Rather than d-bus, which is a bit heavyweight, my current thinking is a basic text based protocol to the cli via a Unix domain socket when run in daemon mode, either the set or edges subcommand, or perhaps a new subcommand. So similar to the set --interactive, but over a socket. The goal is to have this easily driven even from shell.

The requested lines would be fixed by the initial command line, or possibly a config file if there is a need to support complex configurations not readily passed via command line.

Existing subcommands could be extended to optionally operate via the daemon/socket rather than the ioctls.

warthog618 avatar May 01 '24 02:05 warthog618

After having a bit of a play with this, including using tokio to handle the separate tasks in daemon mode, my current thinking is this is best done in a separate daemon, as this is adding significant bloat to the cli, which isn't good for the cli and is even worse if you want it to fulfill the role of a daemon.

So a separate crate with a simple daemon seems better value. That would do nothing other than expose a single request, setup via config file, to multiple clients via a socket. The user can control access to the requested lines by controlling access to the daemon socket. A config file as that allows for complex configurations, including input and output lines on the one request, without requiring a stupidly complex command line. A YAML config file is my current leaning. The daemon would accept commands from clients similar to the gpiocdev set --interactive command set, plus some new commands to control edge watching per client. Lines would be identified via a name from the config file, which could be different from the name reported by 'gpiocdev line', so the user gains control of the line namespace - at least in the scope of the daemon.

warthog618 avatar May 06 '24 00:05 warthog618