Re: Fwd: StartupItems
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com In message <F85B2026-5AB1-4E96-9834-C38BC20A0C51@freebsd.org>, Michael Smith wr ites:
In the common case, it already does; I just don't think you understand how.
Okay.
Part of that comes from looking at it the wrong way. It's not a question of "when it can be safely launched", but "when it is needed".
What about an always-on job? Here's an example that recently kicked me around some: A security cam. while true do sleep 6 lynx --source ... > `date +%H%M%S`.jpg done (It's obviously more complicated, but think of the above as an example.) This can't be done with CalendarInterval, and anyway, I don't want all my startup code running every 6 seconds. So. I want to launch this job, and then just keep it running forever. I have an existing script, which used to be launched from /etc/rc: for i in ... do /path/to/camera_prog $i & done That works. Done. Put it after network startup and you're fine. Put it in /etc/init.d/rcN.d with something like S30camera (where 30 is higher than the number for network) and it Just Works. So. How do I do this with launchd? The obvious idea would be to use RunAtLoad. This doesn't work; launchd hangs forever at a blue screen without starting Finder, because the child processes are still there and have open file descriptors. The best I could do was directly violate the manual's instructions and intentionally emulate daemon(3) in shell so that my script could be loaded without halting launchd. However, I've lost the ability to say "don't run this if there's no network", so I get occasional empty files, which in turn make the code that uses the security camera code annoying. It is perhaps possible that launchd could maintain these programs, so my script which launches them isn't necessary. However, to do this, I would have to have multiple file.plist files, one per camera. They need to have unique ids, and they need to encode in themselves the arguments. The existing launcher uses the configuration files to figure out what to do. So, making them into jobs would require me to make multiple nearly-identical plist files which duplicate the configuration data I've already recorded. That's no good.
I understand that, in the abstract, it might be neat if every program everywhere graciously handled all sorts of service availability. However, that involves a huge amount of duplication of effort, and leaves me with dozens of developers whose code could potentially screw things up in some way.
... and here you make it really clear that you don't get it at all.
Maybe I don't. But I've spent a lot of time talking to people who claim to get it, and I've understood what they said well enough to write about the topic... And I've come to the conclusion that this is more a matter of disagreeing than of not getting.
Let's say that you're launching something that requires a service on port 1234.
In the launchd world, you connect to port 1234. That's your service availability check - either you get a connection refusal in which case your depended service is not installed and you can abort right now with an error, or you will block until the service is brought up by launchd, which will have noticed you looking for it.
And here's the problem. In some cases, what happens is I get a refusal, because launchd launched my program BEFORE SOMETHING ELSE WAS READY. So, I get told "sorry, no such service", and there's no way for me to find out "... but there will be in 18 seconds" without writing new code. (Actually, the Mac doesn't load launchd.plist files until it's done doing the actual startup work, which is done in rc and StartupItems. But if we were in the launchd world, this is what WOULD happen.)
There is no code for you to add. In fact, you can #ifdef out the block of code that looks for the PID file the depended service would otherwise have written, because you don't need it and until you start the service it ain't going to be there anyway.
But I never had any code to check for PID files. I just relied on the startup code to not even TRY to start my program until the program I depended on was up.
So, it'd be REALLY NICE if launchd provided at least a few basic hooks so that the easy cases would Just Work.
It already does. Note that your system boots just fine.
$ ls /System/Library/Startupitems | wc -l 29 Launchd does not provide fundamentally needed functionality. Apple, given a large pool of programmers, months of warning, and complete control over the contents of the shipped system, cannot make core system services work entirely in the launchd model.
What I want, here, is to NOT have a situation where every separate daemon has to actually contain the Mac-specific code to handle its startup dependancies. This is Software Engineering 101: If you're writing the same code several times, you have probably done something wrong.
Sorry, but that's the argument from the launchd side of things.
No, it isn't. Every time I say "just launch me after the network is up", someone says "you need to modify your program to verify service availability".
And here you fall back into your retrograde view of things.
Yeah. Next thing you know I'll be insisting that I need oxygen, even though that's totally outmoded.
Launch the program *whenever*. The system will follow the dependency chain expressed by the program's normal actions as it runs, and bring up the required services. There's nothing you have to add to your program, only the ad-hoc synchronisation that you can *remove*.
Really? If I run gethostname(3), my program will seamlessly block until the system has gotten its hostname from the DHCP server? If I call fopen(), the system will magically ensure that the disk containing the file I want is mounted, rather than giving me an error? Because if so, that's the exact opposite of everything I've been told. I was once told that the launchd answer to "is my disk mounted" is "query DiskArbitration".
You can; from everything you've said so far, you are inventing problems that just don't exist.
Hmm. So why do 18 of 29 StartupItems in OS X, AS SHIPPED BY APPLE, use "Requires", if it's so outmoded and useless? It seems to me that, at least at the moment, that's a real need. Meeting that need is good. Offering a model that allows people to migrate away from that is great. Demanding that people do it right now because every alternative is gone or "deprecated" is not great. When the new system actually works well enough that you can ship a robust server using only the new system, THEN is the time to start talking about deprecating the old system. Right now, it doesn't work. Maybe it should. It doesn't. Maybe it will tomorrow. It doesn't today. The problem here is there's serious overclaiming going on. Launchd does not solve startup ordering and dependency problems. Launchd provides a hook for launching services on demand, but those hooks still depend on someone having configured the network so that launchd CAN listen on a port. Until the loopback interface is up, even local network services can't be launched on-demand by socket access. If you pitch launchd as a solid replacement for everything *inetd and *cron ever did, I'm totally with you on that. I like launchd better than anything along those lines I've ever seen. I would happily replace both of them with launchd. But it's not a replacement for rc.d, or init.d, or StartupItems. It is not solving those problems. It's no more true that launchd "solves" dependency on other daemons than it's true that inetd "solves" dependency on other daemons. While inetd sucked badly, it still did the same thing launchd does now; launch demons on demand based on access to sockets. It hasn't solved the problems. Declaring that everyone should do things so there's no problem doesn't solve the problem. "People should drive better" is not a good response to "Your car has no seatbelts". -s _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com
participants (1)
-
seebs@plethora.net