lg
lg copied to clipboard
Consider different/configurable name and location for .lgd-nfyx pipes
Currently, lg seems to create pipes named .gld-nfy<handle>
in the current directory (where I believe handle is just an index of opened handles inside the current process). This approach has two problems:
- It assumes that the current directory is writable, which might not always be the case (I'm running into this issue with a read-only rootfs, where only places like /run, /var/tmp and /tmp are writable).
- If multiple processes using lgpio are started in the same directory, they will overwrite each others pipes (this is hypothetical based on looking at the code, I have not actually tried this).
Maybe it would be good to revisit the naming to fix either or both of these?
For 1., I would suggest using /run/user/<uid>
to create these pipes. This seems to be the standard location on modern Linux distros, as defined by the FHS (See for example https://renenyffenegger.ch/notes/Linux/fhs/run/user/uid/index). Rather than hardcoding just this location, I guess it would be good to make it configurable, and also provide fallbacks. I can imagine to use the first of the following that is writable: $LG_RUNTIME_DIR
, $XDG_RUNTIME_DIR
, /run/user/<pid>
, '/tmp/,
.(I'm not sure about
/tmp`, using that might be a security risk).
For 2., I would suggest maybe using something like .gld-nfy-<pid>-<handle>
, which should make the filenames unique.
However, while writing this, I wonder if it would not be possible to simply use a anonymous socketpair (see https://man7.org/linux/man-pages/man2/socketpair.2.html) rather than an on-disk fifo. IIRC this supports pretty much the same thing (bidirectional data transfer using read()/write(), but does not need to be stored on disk (you would just need a way to return the FD to the calling program, rather than just the handle). I do not have a full picture of the architecture involved, so it's likely that I'm missing some part that prevents this, but maybe you just haven't considered this option?
All good points. I wasn't happy having the pipes in the local directory. Unfortunately I do not remember my thinking at the time. I think point 2) is handled by Linux as I certainly had multiple non-conflicting processes during testing.
I like your suggestions. I will look into this again but can not give a time-scale. If you have a working solution I will happily accept a pull request.
All good points. I wasn't happy having the pipes in the local directory. Unfortunately I do not remember my thinking at the time. I think point 2) is handled by Linux as I certainly had multiple non-conflicting processes during testing.
Thanks. I recently needed something like this for another project and found that the default anonymous pipes were cumbersome, since they are unidirectional (so you'd need two, and thus juggle 4 fd's...). Then I found that a socketpair (of the unix stream type) can do pretty much the same, but bidrectional.
I like your suggestions. I will look into this again but can not give a time-scale. If you have a working solution I will happily accept a pull request.
Cool! I would love to make a pull request, but the meadow for this project already has a big herd of yaks, so I cannot really spare the time...
I suggest unless I can think of a better solution you will need to set the working directory when your programs start.
The daemon rgpiod has the -w option.
The other programs will pick up their working directory from the LG_WD environment variable. E.g.
export LG_WD=/tmp
@joan2937 I'm working to wrap my head around this. I understand that a working directory needs to be set (-w option) where users can have the ability to create service handles.
What I'm not sure about is where that needs to be set on a raspbian system. Can you offer any links to documentation or clues as to how this can be sorted out?
EDIT and RESOLTUTION:
For my purposes, this impacted a daemon service that was failing to start due to not having write permissions. If anyone else stumbles on this, the solution is to add the following lines to the [Service]
section of the unit file:
[Service]
...
RuntimeDirectory=<your name of choice>
WorkingDirectory=/run/<your name of choice>
``