Change the StartInterval in a launch daemon?

howie_isaacks
Valued Contributor II

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?

1 ACCEPTED SOLUTION

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.

View solution in original post

5 REPLIES 5

talkingmoose
Moderator
Moderator

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.

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.

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.

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.

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.