Re: Fwd: StartupItems
Re: Fwd: StartupItems
- Subject: Re: Fwd: StartupItems
- From: email@hidden (Peter Seebach)
- Date: Sat, 03 Jun 2006 21:25:12 -0500
In message <email@hidden>, 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 (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden