How to handle getting killed (kill -9) while using Shared Memory?
Asked Answered
R

2

6

I am using Shared Memory in a Client-Server Model. When my Server gets killed off by the user by using sigkill instead of sigterm / sigint I can't do anything about it (as intended), but my Shared Memory Object and Semaphores still exist in /dev/shm/.

The next time I start my Server I want to create a new object with exactly the same name, and - as intented - this fails and I exit my program.

The user would need to remove the objects on his own - which is certainly not the best thing.

How can I handle this?

I could just call shm_open() without the O_EXCL flag, ultimately destroying the purpose of this flag. Because maybe there is already an instance of my server running and uses this object.

Pulseaudio seems to use a combination of digits to keep it's objects distinct and doesn't get affected by killing it with -9, so there seems to be a way.

Reynaud answered 10/1, 2016 at 17:47 Comment(2)
Don't you have other means to identify a server process already running? A pid file, maybe?Canescent
@Canescent That's why I ask how to deal with it - seems like a good start, but where should I locate such a file?Reynaud
L
1

An outline of a possible server initialization:

Open pid file w/O_EXCL | O_WRONLY if success write pid close Open shm w/O_CREAT done

open pid file w/O_RDONLY read pid Use kill(0) to see if server alive If yes, exit If no, remove pid file Close pid, start at top again

Pid files are usually located in the /var/run dir and are named foobar.pid where foobar is the program name

Liquidator answered 10/1, 2016 at 18:6 Comment(1)
So combined with this unix.stackexchange.com/questions/12815/… I see where this is heading. Seems like the proper thing to do. Thanks! Will accept this answer if nothing easier comes up in a few hours.Reynaud
C
5

One option is to use IPC_RMID (see this).

This options marks the shm segment for cleanup after the last process attached to it disappears.

For semaphores, you can look at robust mutexes. It does require you to code for an extra error case (when a process holding the mutex dies).

You also have the option of using file locks, which are released if the process terminates (see lockf()).

Carline answered 10/1, 2016 at 18:57 Comment(6)
Is it possible to obtain the shmid when using functions from SHM_OVERVIEW(7), e.g. the POSIX shared memory way? I can't see a way to get it, as System V shared memory operations and POSIX shared memory operations seem to work a little bit different. Still great input, it's not easy to get a grab of all the options I have.Reynaud
Not sure if it would work for your use case, but if you can call shm_unlink() after all the processes have opened the shm by name, it has a similar effect of cleaning up the shm after the processes disappear.Carline
Sadly, I can't call shm_unlink() when I receive sigkill. Calling it any time before that would be a disaster as no new clients could open the SHM after calling it. Otherwise it would be a good trick.Reynaud
The pid file route may be the best option for you. See this for a decent example.Carline
Seems so, altough it's quite sad that I can't solve it your way. Excellent example, thanks!Reynaud
Is the IPC_RMID option only for System V shared memory?Lodestar
L
1

An outline of a possible server initialization:

Open pid file w/O_EXCL | O_WRONLY if success write pid close Open shm w/O_CREAT done

open pid file w/O_RDONLY read pid Use kill(0) to see if server alive If yes, exit If no, remove pid file Close pid, start at top again

Pid files are usually located in the /var/run dir and are named foobar.pid where foobar is the program name

Liquidator answered 10/1, 2016 at 18:6 Comment(1)
So combined with this unix.stackexchange.com/questions/12815/… I see where this is heading. Seems like the proper thing to do. Thanks! Will accept this answer if nothing easier comes up in a few hours.Reynaud

© 2022 - 2024 — McMap. All rights reserved.