On Wed, Nov 15, 2006 at 08:12:31PM +0100, Mats Kindahl wrote:
> David Powell wrote:
> > On Mon, Nov 13, 2006 at 08:06:43PM +0100, Mats Kindahl wrote:
...
> >>        $DAEMON &
> >>        sleep 1
...
> >> exit $SMF_EXIT_OK
> >>
> >> When I call the 'inadyn-client' script directly, the daemon starts well
> >> and keeps going without a glitch, but when svc.startd tries to start it,
> >> it decides somehow that "all processes in the service exited". AFAICT,
> >> this is not the case.
> > 
> >   As others have pointed out, pgrep will find the script itself, and
> >   needs to be more selective.  It sounds like you have done so and
> >   achieved some degree of success.
> 
> Yes, it worked fine to solve the immediate problem, but as you are
> pointing out, there are other problems (some of which I managed to
> solve, albeit not in an entirely satisfactory manner).

You shouldn't check whether the service is already in the start method
script since SMF should know.

A deeper problem is what if someone manually started the daemon and the
resources needed for the one started by SMF (e.g., a port number for
listening) are taken by it.  This relates to:

> >   There are deeper problems, though.  The start method interface
> >   requires that when you return SMF_EXIT_OK, your service has been
> >   started and is ready to offer service.  Services which depend on
> >   yours can be started as soon as you return; if you aren't really
> >   ready, they might fail.  Backgrounding the daemon and waiting a
> >   second is, frankly, a hack that won't always work.  That said, you
> >   can get away with this as long as your service doesn't have
> >   dependents, or the dependents are robust enough to tolerate a lack of
> >   availability.
> 
> Yes, backgrounding the daemon and waiting a second is definitely a hack.
> The original solution was to use a switch --background to inadyn, which
> forks and reassigns the PPID of the background process to init (i.e.,
> PID 1).

Correct -- ask the daemon program to fork() itself into the background,
but only when it's ready to start providing its services.

That's how sshd(1M) is started, and this deals with the deeper issue
described above by shifting the burden of checking for resource
allocation conflicts to the daemon program.

Note that in Solaris non-global zones the PPID of orphaned processes is
not 1 but that of the zone's svc.startd.

>         Since I thought this might be the reason for the problem (i.e.,
> the exiting fork of the inadyn process was considered as "part of the
> service", while the re-parented process was not), I rewrote the script
> to background the service instead.

It's not a problem.  SMF tracks process contract events, and process
orphaning does not create a process contract event.

I.e., the daemon program fork()s and the parent exits, but the child
remains in the same process contract as the parent, and this happens
atomically so that the process contract can never become empty because
of the parent of a fork() exiting (unless it arranged specifically for
the child to be in a separate contract).

Process contract emptiness events cause SMF to think that the service
needs restarting; svc.startd will process the exit status of the start
method and the process contract emptiness event in that order.

> >   Every process and subprocess started from the start method of a
> >   service belongs to that service, unless one of those processes
> >   specifically requests otherwise for its children.
> 
> What happens if the process is re-parented? Is that considered as
> "requesting otherwise for its children"? Looking at the output from
> ptree -c, I see the following:

No, see the libcontract(3LIB) and contract(4) man page.  See above.

Nico
-- 

Reply via email to