Posted on 08-12-2024 02:35 PM
I am working on a script that uses Swift Dialog to prompt users who have been running their Macs for a long time to reboot. The script creates a launch daemon after getting user input from Swift Dialog. The user is offered a drop down menu with 4 options: Reboot Now, 1 hour, 4 hours, 1 day. The StartInterval for the launch daemon gets set based on the option the user chooses from the drop down menu. Users are allowed 3 deferrals which I track using a PLIST. After the time set in the StartInterval elapses, the user is able to choose a different option. This changes the StartInterval to a new value. I included a step in the script to bootout the launch daemon just before it gets deleted and replaced with a new one containing the new StartInterval. When the new launch daemon is installed, there's a step to bootstrap it. I see in the policy log that the bootout step is failing, which then leads to the bootstrap step also failing since the launch daemon is still running.
Boot-out failed: 5: Input/output error
Bootstrap failed: 5: Input/output error
I have written a lot of scripts that bootout and bootstrap launch daemons so I'm confused why this isn't working. What's the best way to unload, delete, and replace a launch daemon or change its StartInterval and have the new one take effect?
Solved! Go to Solution.
Posted on 08-15-2024 07:26 AM
It's there. Just need to look a little harder. 😉 Once you're in the man page, type "/remove" to search and "n" a few time to find the next instance.
Also, remember launch daemons run as root. So in your testing be sure you're prepending sudo to your command. Use something like this to find a specific launch daemon that should be running:
sudo /bin/launchctl list | /usr/bin/grep com.example.process
If it's not running, you won't get a label back.
Posted on 08-12-2024 04:32 PM
I have an example of creating and running a launch daemon and then deleting it in this script. Maybe it will tell you what you're needing.
This script deploys both a local script and a launch daemon. The launch daemon runs the script and the script then deletes the daemon and kills its process.
Posted on 08-14-2024 11:38 AM
Thanks for your help on this! I noticed in your script this command:
/bin/launchctl remove
I'm not familiar with it and it doesn't appear in the man page for launchctl. After running the command with the path to my launch daemon, I can see that it is still running when I run launchctl list.
Posted on 08-15-2024 07:26 AM
It's there. Just need to look a little harder. 😉 Once you're in the man page, type "/remove" to search and "n" a few time to find the next instance.
Also, remember launch daemons run as root. So in your testing be sure you're prepending sudo to your command. Use something like this to find a specific launch daemon that should be running:
sudo /bin/launchctl list | /usr/bin/grep com.example.process
If it's not running, you won't get a label back.
Posted on 08-15-2024 10:38 AM
Thanks! I will work on this later today. I was pulled into some other things earlier. I knew about the list command. That's how I knew that the process was still running. As I test my script in CodeRunner I have it set to use sudo. Of course when I'm running it in Jamf Pro it's already being ran as root. I did just now see the remove option in the man page. I'm not sure how I missed it.
Posted on 08-15-2024 02:26 PM
I appreciate the help. My script is removing the previous process just before installing the new launchdaemon with the new StartCalendarInterval. Each time I run the script and choose a different defer time, I see that the previous launch process is gone and it's replaced with the new one. I built a function that handles the remove command and the deletion of the previous launchdaemon.