0

We have launchd daemon which should be running forever and be started as soon as system is booted, therefore in its plist we say:

<key>KeepAlive</key> <true/>

Everything is OK until the system is shutdown. Agent needs to inform the remote server about the system being shutdown, via HTTP. System sends SIGTERM to the agent just fine and agent is able to process it. However, by the time it receives SIGTERM, DNS (or maybe entire networking subsystem) is already down, and it cannot send status to the server as it cannot resolve its name. All network functions fail, so I suspect networking is down. On Linux this is resolved by SNN/KMM symlinks with NN=99 and MM=00. However on OSX it is explicitly said that launchd daemons don't have any priorities. How then can we have OSX to send SIGTERM to our daemon before it shuts down DNS/networking?

I have quickly looked at ability to register a listener for system shutdown event as program can register itself to listen for power mode changes (namely, sleep), however a few sources told that this is not possible either - Receiving power notifications (especially shutdown) on Mac OSX.

Community
  • 1
  • 1
DimaA6_ABC
  • 578
  • 4
  • 15

1 Answers1

0

I had a suspicion there would be a distributed notification notifying apps of this, so I wrote a little Obj-C app...

#import <Foundation/Foundation.h>

int main(int argc, char *argv[])
{
    @autoreleasepool
    {
        [[NSDistributedNotificationCenter defaultCenter]
         addObserverForName: nil
         object: nil
         queue: [NSOperationQueue mainQueue]
         usingBlock: ^(NSNotification *notification) {
            NSLog(@"Got a notification %@", notification);
        }];

        [[NSRunLoop mainRunLoop] run];
    }
}

I picked up these notifications

05/12/2012 19:17:12.044 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98e04900 {name = com.apple.logoutInitiated; object = 501}
05/12/2012 19:17:22.376 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98c0c580 {name = com.apple.shutdownInitiated; object = 501}
05/12/2012 19:17:22.388 Untitled 2[62058]: Got a notification __CFNotification 0x7ffd98c0b8f0 {name = com.apple.logoutContinued; object = 501}
  • com.apple.logoutInitiated corresponded with the opening of the Shut Down dialog, and
  • com.apple.shutdownInitiated was received when the button was pressed.

Now, of course you won't know whether the shut down will actually happen, an app can cancel the shut down. You'd probably get a notification for that too, though.

joerick
  • 16,078
  • 4
  • 53
  • 57
  • Sorry, I have not mentioned - this is C++ application, so we can call only Mac APIs available in C, no Obj-C. As I have read in the URL provided in my question, daemons are not notified of system shutdown. Anyway we are notified that daemon is shut down by SIGTERM, question is more about affecting the order of system components going down. But yesterday's night I seem to get around the problem - it looks like only DNS is down when agent gets SIGTERM, networking is still up. We cache IP address of the server on last successful session, and use it on notifying about being shutdown. – DimaA6_ABC Dec 06 '12 at 05:56
  • Well my point was that you'd get this notification when the shutdown process begins, which would be before your daemon was sent SIGTERM. You could also do the above with Core Foundation, which is a C API. https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html . Glad you've found a solution anyway! – joerick Dec 06 '12 at 10:47