0

i have a daemon that must be finished gracefully. It should have CUSTOM amount of time before system sends SIGKILL and kills it.

Is there a possibility to do such thing on MAC?

  • 1
    SIGKILLs can happen anytime and are outside the control of your process, so your daemon needs a way to recover from that anyway. But to move your question forward: how do you currently launch your daemon? – nohillside Jun 4 at 7:39
  • Thanks for reply. i launch it using 'launchctl start' , and it loads after system starts. I need to prevent only SIGKILL that OS sends during the shutdown\restart of the mac itself. Is it possible? – RomanKosiy Jun 4 at 8:09
  • You can't prevent SIGKILLs. I'm not in front of a Mac right now but AFAIK launchd tries to run launchctl stop for all daemons during shutdown (and only SIGKILLs if the process doesn't stop afterwards). – nohillside Jun 4 at 9:22
  • But can i tell the OS somehow that it should wait CUSTOM_TIME before it runs SiGKILL for my process to stop correctly? i mean i have an application with a lot of connections and stuff, it needs a lot of time to finish properly. is it possible on MACs? or i need to use something different and not daemon for this process? – RomanKosiy Jun 4 at 9:57
  • 2
    Actually I think it's rather essential that processes/daemons can not prevent the OS from shutting down :-) – nohillside Jun 4 at 10:23
0

Yes, this is definitely possible.

If you start your service properly via launchd, you can define the amount of time you need for stopping the service with the "ExitTimeOut" key in the launchd plist for your service. If you set "ExitTimeOut" to for example 300, this means your service have 300 seconds (5 minutes) to do something in between receiving SIGTERM and actually being killed by receiving the SIGKILL signal.

Another possibility is to redefine the shutdown sequence as such. This is a more "hacky" solution, but if this is intended only for your own Mac, it could be the easiest.

A way to do this is simply to replace /sbin/shutdown with a program of your own liking. An idea is to move the original /sbin/shutdown program to for example /sbin/shutdown.apple and then add a simple shell-script in its place.

The shell script should look something like this:

#!/bin/bash
notify_my_program
sleep 300
exec /sbin/shutdown.apple "$@"

The "notify_my_program" should be replaced with something that tells your service to shutdown. It could be as simple as sending it the SIGTERM signal.

Please ensure that you have the proper permissions on the shell script (i.e. the same as the original shutdown program).

After the above mentioned modification, your system should at shutdown first notify your service to shutdown, wait 5 minutes and then do whatever it usually does at shutdown.

The modified shutdown process should be used when you shutdown from the command line as well as when doing it from the GUI (i.e. from the Apple menu).

Finally, a more involved solution would be to actually replace launchd with your own custom init system. The simplest way to do that would be to download the source code for launchd, change the shutdown sequence, recompile and replace launchd on your system. The /sbin/shutdown program works just by sending a signal to launchd (various signals for reboot, halt, poweroff, etc.) - so the actual shutdown sequence for the user-space part of the system is actually handled by launchd, so in this manner, you can customize it to do anything you want.

Note that changing the shutdown sequence in either of the two mentioned ways require you to disable SIP (System Integrity Protection) before proceeding.

  • THANKS A LOT! That works! I talk about the key "ExitTimeOut" Thanks!) The only question i have - is there a limitation on the integer number in the key? – RomanKosiy Jun 6 at 18:20
  • I'm not aware of any limitation, no. The launchd program itself contains no such limitation, but there might be a kernel limitation - but it would be very high. – jksoegaard Jun 6 at 19:37
2

No - this isn't the decision idiom on macOS so your development requirements are conflicting with the system design intention.

Your daemon should be dealing with this and timing and technical ways to do this are built in to MacOS as well as documented fairly well by Apple.

macOS does not shutdown daemons by just sending a SIGKILL it first sends a SIGTERM and then only if the process is still there a SIGKILL. You have some control to delay this by using the disableSuddenTermination method on NSProcessInfo see https://developer.apple.com/documentation/foundation/nsprocessinfo/1412841-disablesuddentermination?language=objc

Thus your daemon should be shutting down on receipt of a SIGTERM and so the SIGKILL will have no effect.

This was documented in Apple's The Life Cycle of a Daemon

It is also the normal BSD and Linux way of shutdown except that launchd is not involved.

  • Thanks for reply! Yes, i know that it first sends SEGTERM and only then SIGKILL. But doc says: "If the system is being shut down or restarted, it sends a SIGTERM signal to all daemons, followed a few seconds later by SIGKILL signal". So i have only few secodns? 2? Can i have 5 minutes? That's the question. On linux and Windows there is a mechanism of services to kill timeout, but i can't find it here. – RomanKosiy Jun 4 at 16:44
  • 1
    @RomanKosiy If your process needs 5 minutes to shutdown you may need to rethink your design. – nohillside Jun 4 at 17:49
  • @nohillside that's not about design, that's a requirement :) the requirements tells me that a lot of work must be done when the shutdown starts. for linux(ubuntu) and windows it works, but for MAC i suppose not.. – RomanKosiy Jun 4 at 17:53
  • 2
    @RomanKosly definitively seems to be a design issue then. Look, I understand that your requirements are as they are, but it might be worthwhile to take a step back, look at the why‘s behind these requirements and rethink the whole thing. But that‘s my advice as a Requirement Engineer, not as a Mac user :-) – nohillside Jun 5 at 8:22
  • 2
    Nice thread. I generally require just a little more money to fund a SRE staff to support applications with requirements like 5 minutes shutdown notice when someone we trust has already decided to restart the OS. It's always easy to satisfy any arbitrary requirement with enough money and time when you think / communicate like a requirements engineer. – bmike Jun 5 at 12:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .