Solved How to view and clean shared memory created with shm_open?

I have a process that (by design) fails to start if its shared memory created with shm_open(2) already exists. If the process crashes or is kipped with pkill(1), the process will not start until FreeBSD is rebooted. I'm looking to create a "clean" sh script to detect if the shared memory exists and close/remove it if needed.

Previously (on another operating system), I just viewed and cleared the shared memory files directly; however, as per https://forums.freebsd.org/threads/freebsd-8-x-changes-in-shm_open.16850/, shm_open(2) does not actually create files in the given path for FreeBSD 12.3.

Other forum posts have said to use ipcs(1) to see a list and ipcrm(1) to clean; however ipcs(1) shows nothing under shared memory. I'm guessing that is for a mechanism different from shm_open(2).

Using fstat(1), I can see that share memory exists (although the path given is not actually visible in the file system).
Code:
my_user  my_process 2542   25 /tmp/my-shm.a.file1 -rw-r--r--     544 rw
my_user  my_process 2542   26 /tmp/my-shm.a.file2 -rw-r--r--     544 rw
my_user  my_process 2542   27 /tmp/my-shm.a.file3 -rw-r--r--     560 rw
my_user  my_process 2542   28 /tmp/my-shm.b.file4 -rw-r--r--     560 rw
my_user  my_process 2542   29 /tmp/my-shm.b.file5 -rw-r--r--     544 rw
my_user  my_process 2542   30 /tmp/my-shm.b.file6 -rw-r--r--     544 rw

Is there any way in FreeBSD to clean shared memory (without rebooting) with a path matching a given pattern?
 
Maybe that design isn't ideal? I assume the goal is to avoid starting a second instance that just "steals" the shared memory. If that's indeed the case, you could decouple both aspects. Use a classic pidfile with fcntl(2) file locking to ensure a single instance. The locking will enable you to identify a "stale" pidfile, it won't be locked any more if the lock owner died. In that case, you will know it's safe to re-create the shared memory.
 
sig handler to trap kill/termination signals to do the cleanup/close of the shm segment?
Of course, should have mentioned that as well! But no chance with SIGKILL, SIGBUS, SIGSEGV, etc ;), so you still need a strategy for that...
 
Thanks! That gets me at least part of the way there. posixshmcontrol ls shows the shared memory, and posixshmcontrol rm /tmp/my-shm.a.file1 (with exact path) cleans it up. Wildcards don't work: posixshmcontrol rm /tmp/my-shm.a.*, so I may have to do a bit of extra scripting.
 
I was able to do this in a shell script via the following:
Code:
posixshmcontrol ls | cut -f 5 | grep /tmp/my-shm.a.* |  while read -r a; do posixshmcontrol rm $a; done
 
Back
Top