3 ms·
I wish Linux (and other Unix-like systems) had an API to let you create named temporary files which are automatically deleted - by the operating system - when a
by skissane 2y ago
I wish Linux (and other Unix-like systems) had an API to let you create named temporary files which are automatically deleted - by the operating system - when a process exits.
If you create an anonymous temporary file, then it will be deleted when the last file descriptor to it is closed-but anonymous temporary files are difficult to use (even given access via /dev/fd aka /proc/self/fd). You can delete it using atexit() but that doesn’t get run if the process terminates abnormally (core dump, kernel panic, kill -9, power outage, etc)
Maybe something like a pidtmpfs where the top-level directories are pid numbers, you can create any files or directories you want under them, but it all disappears as soon as the process with that pid exits. Actually, pids are a bad idea due to pid reuse, you want something like a process serial number or a process UUID which doesn’t get reused.
Another somewhat more flexible idea would be that you can create arbitrary top-level directories, but they - and all their content - are automatically deleted as soon as the last open fd to them is closed. That way you could have multiple processes sharing a temporary workspace, and the workspace could survive the failure of any one of them, but if they all fail it gets deleted
- pram 2y agoPrivateTmp in systemd does this.
- skissane 2y agoUnfortunately it only works for systemd units, as far as I am aware. Consider this use case: I have a test program which executes some unit tests, it creates some temporary files. I want the temporary files it creates to all be removed when it exits, even if it core dumps. But while it runs, I want those files to easily be accessible to subprocesses it spawns. I don't think systemd addresses this, because my unit test runner isn't going to be a systemd unit. So really I was talking about a generic facility an arbitrary program could use, not just something limited to systemd units only.
- Wowfunhappy 2y ago> Consider this use case: I have a test program which executes some unit tests, it creates some temporary files. I want the temporary files it creates to all be removed when it exits, even if it core dumps. But while it runs, I want those files to easily be accessible to subprocesses it spawns. For this precise use case, what if you deleted the last run's temporary files at the start of the test program?
- LegionMammal978 2y agoWith mount namespaces, you can create an anonymous tmpfs mount that gets detached and deleted once nothing refers to it any more, and add whatever files you want to that. It can be accessed using the *at() syscalls, or alternatively using an initial fchdir() to make it the current directory. Too bad that unprivileged namespaces have been buried by the big-name distros, though.
- bduffany 2y agoWhat do you mean by unprivileged namespaces being buried by the big-name distros?
- happymellon 2y agoPresumably this, Unprivileged Name Spaces getting blocked by Ubuntu. Not sure if anyone else is doing it. https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged...
- LegionMammal978 2y agoIt seems that until 2020, Debian used to block them as well [0]. So perhaps some of my perceptions are out of date. In any case, it means namespaces are unreliable to use for the typical Linux program. [0] https://salsa.debian.org/kernel-team/linux/-/commit/a381917851e762684ebe28e04c5ae0d8be7f42c7 https://salsa.debian.org/kernel-team/linux/-/commit/a3819178...
- LegionMammal978 2y agoWell, perhaps I'm being unfair talking about distros plural: I'm mainly thinking of how the latest Ubuntu has disabled unprivileged user namespaces by default [0], seeing them as too big an attack surface to let everything use them. It looks like Debian used to have them disabled, but then re-enabled them for the sake of web browsers [1]; I'm sure they'd re-disable them if they found some solution similar to Ubuntu's AppArmor one. For other distros, it's difficult to find up-to-date information on whether they enable or disable unprivileged user namespaces, since many have flipped back and forth over the last decade. All that is to say that unless your program is given privileges itself (e.g., Docker), or can wheedle user-namespace permissions out of the packagers, there's no chance you'll be able to distribute namespace-using code and have it work consistently for most users. [0] https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat-release-notes/39890#unprivileged-user-namespace-restrictions-15 https://discourse.ubuntu.com/t/ubuntu-24-04-lts-noble-numbat... [1] https://salsa.debian.org/kernel-team/linux/-/commit/a381917851e762684ebe28e04c5ae0d8be7f42c7 https://salsa.debian.org/kernel-team/linux/-/commit/a3819178...
- ithkuil 2y agoWhat's the main problem you see with /dev/fd? It even works when you write a temp script and execute it in /dev/fd/... However since you can't control the file name in that case you cannot control argv[0] for such temp executables which may be a problem for BusyBox-style tools. Have you encountered other issues with using that approach for named but auto-cleaned files?
- skissane 2y agoExample: suppose I am testing a program which reads in a directory tree. I have my test driver program create a temporary directory, with multiple files and subdirectories in it. I can’t use /dev/fd for that, since it doesn’t support directories Related example: testing a program which expects a file name to match a certain pattern; can’t do that because /dev/fd file names are just numbers
- gray_-_wolf 2y agoLooking at `man 3 exec', argv0 is controlled by the caller and has no connection to the actual name on the disk.
- ithkuil 2y agoWell if you can call a syscall you don't need a named file. You can call execfd. One case where I need an executable named temp file is when I need to pass that named file to another process which in turn will call that file (so I don't have control on how that other process will call exec)
- skissane 2y ago> Well if you can call a syscall you don't need a named file. You can call execfd. Sadly you can’t exec an fd on macOS. I don’t think Apple is going to change that, because I think it causes difficulties for their security/codesigning/sandboxing infrastructure, and I think they don’t see the difficulty and risk of making it work with that as being worth the rather limited benefit
- deleted 2y ago[deleted]
- Brian_K_White 2y agoI have a magic tmp dir I set up using a one-line find command that runs every minute from cron, that deletes anything in that dir with an atime older than some small value like 30 seconds or 2 minutes. That sounds expensive but since it's always running, the find work is always small, and this is all in ram tmpfs usually too, because ideally you want atime enabled in this dir, and ideally you do not want atime enabled most anywhere else. It is used by all the application software for "fire & forget", so the app code can just generate the file and not have to hang around (and also, hang) while waiting to delete the file some unpredicatble time later. The file may or may not ever be used in some cases, and if used, it's used in some other process that the writing process doesn't know how long it will take unless you rig up some way to signal. Every user of the special directory knows this special property of it, as this is it's entire purpose in the first place. It's not /tmp so no surprises. It eventually got used for all kinds of other things too because it's just so handy. It works best with atime, which means mounting the filesystem with atime enabled, which I don't like to do in most cases, so ideally you make this it's own tmpfs in ram, and then the atime doesn't hurt much. But it also works well enough with just ctime & mtime and a slightly longer TTL. Even if a file is large and the user is on a slow link and the file is still downloading when the TTL expires, and the filesystem does not have atime, and so the reaper does actually delete the file while still in use, it's still ok most of the time even then, because the actual process that has the open handle still has it and can continue downloading the file until they close it, even while it has disappeared from view for the rest of the system. But with atime, it's like magic, the file just naturally lives exactly as long as anyone is interested in it, and gets reaped 2 minutes after that, with no application process needing to keep track of it. The reaping happens regardless of crashed processes or reboots, graceful or ungraceful, etc. It's something I did almost the first week over 20 years ago at a company I worked at from '99 to about '22, and got used for practically all temp files, and the normal tmp became the special case you only used in special cases. (actually the application software really never used the global /tmp, there were various other customer-specific and app-specific dirs) Basically it was like an OS feature (for us) in that every system (of ours) always had this magic tmp dir. This worked fine on old sco systems without even gnu find with it's handy -delete, let alone cgroups or even a ram fs. In fact it started there.