lg icon indicating copy to clipboard operation
lg copied to clipboard

Consider different/configurable name and location for .lgd-nfyx pipes

Open matthijskooijman opened this issue 2 years ago • 4 comments

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:

  1. 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).
  2. 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?

matthijskooijman avatar Mar 15 '22 18:03 matthijskooijman

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.

joan2937 avatar Mar 15 '22 18:03 joan2937

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...

matthijskooijman avatar Mar 15 '22 20:03 matthijskooijman

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 avatar Apr 18 '22 09:04 joan2937

@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>
``

txoof avatar Aug 03 '24 17:08 txoof