7

I have a RHEL 8 workstation that hosts an app whose GUI is accessible through https on an unprivileged port.

When the app is started, it creates a few socket files in /tmp with random names and the .sock suffix:

$ ls -l /tmp/*.sock srwx------ 1 app app 0 Dec 21 13:30 /tmp/supervisor-358513b0f6222d2339e4ab66d30b0037.sock srwx------ 1 app app 0 Dec 21 13:31 /tmp/mongodb-358513b0f6222d2339e4ab66d30b0037.sock srwx------ 1 app app 0 Dec 21 13:31 /tmp/livegui-358513b0f6222d2339e4ab66d30b0037.sock $ file /tmp/*.sock /tmp/supervisor-358513b0f6222d2339e4ab66d30b0037.sock: socket /tmp/mongodb-358513b0f6222d2339e4ab66d30b0037.sock: socket /tmp/livegui-358513b0f6222d2339e4ab66d30b0037.sock: socket 

update: The "random" part of the socket filenames is in fact a MD5 of the path where the app is installed.

When people use the app frequently, the app works fine for weeks/months, but when nobody connects to the app for a few days, it stops responding; when that happens I can see that the .sock files got deleted while the app processes are still running...

Is there any way to prevent the deletion of the app socket files in /tmp?

7
  • 4
    You need some variant of unix.stackexchange.com/a/511128/70524 Commented Dec 21, 2024 at 17:15
  • 2
    Are you saying the files are deleted without the machine restarting? Or is there a restart in the middle somewhere? Commented Dec 21, 2024 at 18:01
  • 2
    OK, so that means the machine did NOT restart in the meantime, right? That's what I'm asking. Commented Dec 21, 2024 at 19:04
  • 3
    @JörgWMittag, those are sockets. If their names are deleted, they can't be connected to, even if they might still exist in the process that created them. Commented Dec 21, 2024 at 21:09
  • 2
    @ilkkachu: Indeed, they are! Somehow, my brain read "sockets" but registered "PID files". Commented Dec 22, 2024 at 1:39

4 Answers 4

17

Yes, see man 5 tmpfiles.d: then create a configuration file e.g. /etc/tmpfiles.d/myappsocket.conf with the contents like:

X /tmp/*.sock 

With that, the temporary file manager process should no longer delete your application socket.

7
  • 4
    It is slightly odd that this would be needed, though; I recall systemd-tmpfiles has had code to check sockets against /proc/net so that still-bound ones would be automatically excluded. Commented Dec 21, 2024 at 17:50
  • 2
    That will exclude any .sock file in /tmp; if I want to restrict the rule to the .sock owned by the app user, should I use X /tmp/*.sock - app app - -? Commented Dec 22, 2024 at 0:55
  • @ilkkachu thanks for the correction, it looks like I mistyped the asterisk on my new mobile phone. Commented Dec 22, 2024 at 20:29
  • 1
    @Fravadona according to the version of the man page on my system, the configuration entry type X does not accept username/group parameters, but only the age parameter. If your system's man page says something different, then you should trust that instead. Commented Dec 22, 2024 at 20:36
  • 1
    Yes, and for many types, including x and X, there are - signs in the Mode, UID and GID fields, indicating that those are not applicable for this type of entry. On the man page of my system, the text descriptions on the UID/GID parameters confirms that "These parameters are ignored for x, r, R, L, t and a lines" but does not mention X specifically - I assume this is just a documentation omission but feel free to test it. Commented Dec 22, 2024 at 21:16
16

The preferred resolution is for the app to instead put the socket under /run, because that’s where the standards for this type of thing (note the final line of section 3.15.2) say that such things should be (both because they are not temporary data, and because no sane system cleans out old files in /run except on a reboot).

The least preferred, but still workable, resolution is to add an exception for systemd-tmpfiles in /etc/tmpfiles.d to exclude the files from cleanup as suggested by the answer by telcoM.

Alternatively to both options, and significantly more complicated, would be to have the app itself write out overrides for the specific socket paths in a file in /run/tmpfiles.d once it knows what the paths are.

Irrespective of all of that though, this is a bug that should be reported to the app developers (and possibly the systemd developers, because systemd-tmpfiles shouldn’t be removing listening sockets, though I’m not sure when it started avoiding doing so, so that may just be a result of the version of systemd on RHEL 8).

11
  • 3
    I wrote my answer on a mobile phone, so I decided just to answer the question and omit pondering the root causes; but I agree, depending on further details, either the application's or systemd-tmpfiles's behavior (or maybe even both) would qualify as bugs. Commented Dec 22, 2024 at 23:04
  • 2
    @Fravadona Systemd itself provides handling for this, if you actually set up a proper service unit for the service. The relevant key is RuntimeDir=, which will make sure the directory exists and has the right permissions before the service itself gets started. Alternatively, you could also just add a config entry for systemd-tmpfiles to create the directory at boot. Commented Dec 23, 2024 at 13:26
  • 2
    @Fravadona: If it's a desktop app that only has a regular user's privileges, then it should instead use $XDG_RUNTIME_DIR, i.e. /run/user/<uid>, which is meant to be the per-user equivalent of /run overall. Commented Dec 23, 2024 at 19:11
  • 1
    @Fravadona That would explain why XDG_RUNTIME_DIR isn’t set, you don’t get an actual session when using an explicit command like that with SSH. But if you can’t manage the app as a regular system service, that’s a huge issue. I highly encourage you to look into how to write systemd service files so you can write one for this app, because it’s sounding like that will not only solve your issue, but also make your life much simpler. Commented Dec 23, 2024 at 21:34
  • 3
    @Fravadona Well, if that's what you're doing, I would recommend at least running sudo loginctl enable-linger appuser once, to mark that user account as "keep active even if logged out" in systemd – it'll both create a permanent /run/user/UID and might avoid some other problems. (It'll also let you define a user-level systemd service at ~/.config/systemd/user/ in case that works any better, since the 'linger' flag makes that user's default.target start on boot too.) Commented Dec 24, 2024 at 10:51
1

put them in /var/run/user/UID/ instead

3
  • 2
    /tmp seams hard to change: grep -FRI '/tmp' /.../app | wc -l => 12882 and grep -FRI 'TMPDIR' /.../app | wc -l => 0 Commented Dec 22, 2024 at 9:38
  • 4
    if no source contact vendor for assisitance, requst app comply with FHS Commented Dec 22, 2024 at 20:13
  • 1
    The app should support TMPDIR, and you should contact them to have it do so in the next version(s). And also: using /tmp to store sockets is not correct, they should probably use /run (formerly /var/run, but deprecated) instead, or a subdirectory of /run. Commented Dec 23, 2024 at 8:52
1

An "old school" workaround, which has the advantage of not requiring elevated privileges, would be to regularly update the access times of the .sock files, using for eg. the crontab of the user that runs the app processes:

0 1 * * * touch -ac /tmp/*.sock 

The above entry will update the access times of the /tmp/*.sock files everyday at 1AM

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.