Search code examples
bashmacosdaemonlaunchd

Start daemon on bash check script started by launchd


Quick question for you, related to launchd, actually on MacOS (Mojave). I'm using an LLDP daemon (lldpd, available here --> https://lldpd.github.io/)

I would like to remove the plist created by this package (/Library/LaunchDaemons/im.bernat.lldpd.plist), and replace it with another I did :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
     <key>Label</key>
     <string>XXX_LLDP_check</string>
     <key>UserName</key>
     <string>root</string>
     <key>ProgramArguments</key>
     <array>
          <string>/opt/xxx/lldp_check.sh</string>
     </array>
     <key>WatchPaths</key>
     <array>
           <string>/etc/resolv.conf</string>
           <string>/Library/Preferences/SystemConfiguration/NetworkInterfaces.plist</string>
     </array>
</dict>
</plist>

What I do here is I watch /etc/resolv.conf and /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist to be able to start my /opt/xxx/lldp_check.sh script whenever there's a change on network interfaces status.

Then this script will do some checks (DNS resolution, ping, etc), to be sure I'm connected to my corporate network before starting the lldpd daemon.

#!/bin/bash

sleep 5

ethernet_if=`networksetup -listallhardwareports | awk '/Ethernet/{getline;print}' | awk 'NR==1 {print $2}'`
ethernet_status=`ifconfig $ethernet_if | grep status | awk '{print $2}'`

if [ "$ethernet_status" = "active" ]
then
    echo "ETHERNET WIRED LINK IS UP" >> /tmp/test.log

    # some checks here (removed for sharing)
    if ping -c 1 1.1.1.1 &> /dev/null
    then
        echo "ON CORPORTATE NETWORK. STARTING LLDPD" >> /tmp/test.log
        /usr/local/sbin/lldpd &
        echo "LLDP started" >> /tmp/test.log
        # adding a sleep to see if it is started 
        sleep 10
    else
        echo "NOT ON CORPORATE NETWORK" >> /tmp/test.log
        killall lldpd
        echo "LLDP killed" >> /tmp/test.log
    fi
else
    echo "ETHERNET WIRED LINK DOWN" >> /tmp/test.log
    killall lldpd
    echo "LLDP killed" >> /tmp/test.log
fi

Unfortunately, thanks to the "sleep 10", I'm able to see that lldpd is started for 10 seconds, but is then killed when this check script terminated.

I also tried to use "launchctl load /Library/LaunchDaemons/im.bernat.lldpd.plist" but with no success.

I also tried adding a "nohup" before the "/usr/local/sbin/lldpd &" but it does not makes it better. If I start the /opt/xxx/lldp_check.sh manually (with root rights), lldpd is started properly.

Do you have an idea ?


Solution

  • Finally found the solution :

    • keep "disown" the started lldpd process in the bash script
    • add the "abandonprocessgroup" parameter to "True" on the plist file (AbandonProcessGroup)