On Thu, Jul 24, 2008 at 01:28:58PM -0700, Jordan Brown wrote:
> David Powell wrote:
> > Jordan Brown wrote:
> >> What would you expect to happen if you were to svccfg delete -f a 
> >> service while its start method was running?
> > 
> >   "Not Defined"
> 
> Thanks.  That sounds like a reasonable answer.  (Not a convenient one 
> for me, but reasonable.)

Below is a script (tested) that solves the runonce problem.

Call it 'runonce' and then use it in either of these ways:

a) execute it last in your service's start method, with a single
   argument '-d'

or

b) use it as the start method like so: runonce -1 <command> [<args>]

If you run it with no arguments you get a usage message.

NOTE: This is a KSH script, so it will have to be converted to /sbin/sh
      before it can be used by services that run early.

Nico


#!/bin/ksh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

PATH=/usr/bin:/usr/sbin:/sbin
PROG=${0##*/}

. /lib/svc/share/smf_include.sh || exit 95

function usage {
        cat <<EOF
Usage: $PROG -1 command arguments
       $PROG -d

       The first form runs the given command and arguments and then
       deletes the service.

       The second form deletes the service.

       This is done by starting a background job in a separate process
       group which will synchronously disable the service and then
       delete.
EOF
        exit 1
}

[[ "$#" -eq 0 ]] && usage

[[ "$1" != -[d1] ]] && usage
[[ "$1" = "-d" && $# -ne 1 ]] && usage
[[ "$1" = "-1" && $# -lt 2 ]] && usage

runonce=false
[[ "$1" = "-1" ]] && runonce=:
shift

if [[ -z "${SMF_FMRI}" ]]
then
        print -u2 "Error: $PROG not called in the context of a service 
(SMF_FMRI not set)"
        exit 22
fi

ps -o ctid= -p $$|read my_ctid
ps -o ctid= -p $PPID|read parent_ctid
svcs -o ctid -H "$SMF_FMRI" 2>/dev/null|read svc_ctid

print "DEBUG: my_ctid=$my_ctid, parent_ctid=$parent_ctid, svc_ctid=$svc_ctid"

if [[ -z $svc_ctid ]]
then
        print -u2 "Error: $SMF_FMRI doesn't match any instances"
        exit 23
fi

if [[ $svc_ctid = "-" ]]
then
        print -u2 "Error: $SMF_FMRI is not running"
        exit 24
fi

if [[ $my_ctid -ne $svc_ctid && $parent_ctid -ne $svc_ctid ]]
then
        print -u2 "Error: $PROG not called in the context of a service"
        exit 1
fi

if [[ $my_ctid -eq $svc_ctid ]]
then
        $runonce && "$@"
        status=$?

        if [[ $status -ne $SMF_EXIT_OK ]]
        then
                exit $status
        fi

        # Start bg job
        ctrun -l child -o pgrponly $0 -d &

        # Exit, allowing the service start method to run to completion
        exit $SMF_EXIT_OK
fi

if ! svcadm disable -s "$SMF_FMRI"
then
        print -u2 "Error: $PROG could not disable $SMF_FMRI"
        exit $SMF_EXIT_ERR_FATAL
fi

svccfg delete "$SMF_FMRI" && exit $SMF_EXIT_OK

print -u2 "Error: Could not delete $SMF_FMRI"

exit $SMF_EXIT_ERR_FATAL

Reply via email to