1*7836SJohn.Forte@Sun.COM#!/bin/ksh 2*7836SJohn.Forte@Sun.COM# CDDL HEADER START 3*7836SJohn.Forte@Sun.COM# 4*7836SJohn.Forte@Sun.COM# The contents of this file are subject to the terms of the 5*7836SJohn.Forte@Sun.COM# Common Development and Distribution License (the "License"). 6*7836SJohn.Forte@Sun.COM# You may not use this file except in compliance with the License. 7*7836SJohn.Forte@Sun.COM# 8*7836SJohn.Forte@Sun.COM# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7836SJohn.Forte@Sun.COM# or http://www.opensolaris.org/os/licensing. 10*7836SJohn.Forte@Sun.COM# See the License for the specific language governing permissions 11*7836SJohn.Forte@Sun.COM# and limitations under the License. 12*7836SJohn.Forte@Sun.COM# 13*7836SJohn.Forte@Sun.COM# When distributing Covered Code, include this CDDL HEADER in each 14*7836SJohn.Forte@Sun.COM# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7836SJohn.Forte@Sun.COM# If applicable, add the following below this CDDL HEADER, with the 16*7836SJohn.Forte@Sun.COM# fields enclosed by brackets "[]" replaced with your own identifying 17*7836SJohn.Forte@Sun.COM# information: Portions Copyright [yyyy] [name of copyright owner] 18*7836SJohn.Forte@Sun.COM# 19*7836SJohn.Forte@Sun.COM# CDDL HEADER END 20*7836SJohn.Forte@Sun.COM# 21*7836SJohn.Forte@Sun.COM# 22*7836SJohn.Forte@Sun.COM# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7836SJohn.Forte@Sun.COM# Use is subject to license terms. 24*7836SJohn.Forte@Sun.COM# 25*7836SJohn.Forte@Sun.COM####################################################################### 26*7836SJohn.Forte@Sun.COM# 27*7836SJohn.Forte@Sun.COM# This file contains system setup requirements for scm. 28*7836SJohn.Forte@Sun.COM# 29*7836SJohn.Forte@Sun.COM# For systems before Solaris 10 it should be located in /etc/init.d 30*7836SJohn.Forte@Sun.COM# directory with the following links: 31*7836SJohn.Forte@Sun.COM# 32*7836SJohn.Forte@Sun.COM# ln /etc/init.d/scm /etc/rc0.d/K84scm 33*7836SJohn.Forte@Sun.COM# ln /etc/init.d/scm /etc/rc2.d/S002scm 34*7836SJohn.Forte@Sun.COM# 35*7836SJohn.Forte@Sun.COM# For Solaris 10 or later systems this script is run as part of SVC by 36*7836SJohn.Forte@Sun.COM# svc.startd and should be located in /lib/svc/method 37*7836SJohn.Forte@Sun.COM# 38*7836SJohn.Forte@Sun.COM#USAGE="Usage: $0 { start | stop } 39*7836SJohn.Forte@Sun.COM# 40*7836SJohn.Forte@Sun.COM####################################################################### 41*7836SJohn.Forte@Sun.COM 42*7836SJohn.Forte@Sun.COMSVCS=/usr/bin/svcs 43*7836SJohn.Forte@Sun.COMDSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" 44*7836SJohn.Forte@Sun.COMOS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2` 45*7836SJohn.Forte@Sun.COM 46*7836SJohn.Forte@Sun.COM. /lib/svc/share/smf_include.sh 47*7836SJohn.Forte@Sun.COM 48*7836SJohn.Forte@Sun.COM# Make sure prior SMF dependents are not 'online' 49*7836SJohn.Forte@Sun.COM# $1 = name of SMF service to validate dependents 50*7836SJohn.Forte@Sun.COM# 51*7836SJohn.Forte@Sun.COMdo_smf_depends () 52*7836SJohn.Forte@Sun.COM{ 53*7836SJohn.Forte@Sun.COM times=0 54*7836SJohn.Forte@Sun.COM count=1 55*7836SJohn.Forte@Sun.COM 56*7836SJohn.Forte@Sun.COM if [ $OS_MINOR -ge 11 ] 57*7836SJohn.Forte@Sun.COM then 58*7836SJohn.Forte@Sun.COM return 0 59*7836SJohn.Forte@Sun.COM elif [ -f $DSCFG_DEPEND_NOCHK ] 60*7836SJohn.Forte@Sun.COM then 61*7836SJohn.Forte@Sun.COM for pid in `pgrep dscfgadm` 62*7836SJohn.Forte@Sun.COM do 63*7836SJohn.Forte@Sun.COM if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ] 64*7836SJohn.Forte@Sun.COM then 65*7836SJohn.Forte@Sun.COM return 0 66*7836SJohn.Forte@Sun.COM fi 67*7836SJohn.Forte@Sun.COM done 68*7836SJohn.Forte@Sun.COM elif [ `ps -ef | grep preremove | grep -c SUNWscmu` -gt 0 ] 69*7836SJohn.Forte@Sun.COM then 70*7836SJohn.Forte@Sun.COM return 0 71*7836SJohn.Forte@Sun.COM 72*7836SJohn.Forte@Sun.COM fi 73*7836SJohn.Forte@Sun.COM 74*7836SJohn.Forte@Sun.COM while [ $count -ne 0 ] 75*7836SJohn.Forte@Sun.COM do 76*7836SJohn.Forte@Sun.COM count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l` 77*7836SJohn.Forte@Sun.COM if [ $count -ne 0 ] 78*7836SJohn.Forte@Sun.COM then 79*7836SJohn.Forte@Sun.COM # Output banner after waiting first 5 seconds 80*7836SJohn.Forte@Sun.COM # 81*7836SJohn.Forte@Sun.COM if [ $times -eq 1 ] 82*7836SJohn.Forte@Sun.COM then 83*7836SJohn.Forte@Sun.COM echo "Waiting for $1 dependents to be 'offline'" 84*7836SJohn.Forte@Sun.COM $SVCS -D $1 2>>/dev/null | grep "^online" 85*7836SJohn.Forte@Sun.COM fi 86*7836SJohn.Forte@Sun.COM 87*7836SJohn.Forte@Sun.COM # Has it been longer then 5 minutes? (60 * 5 secs.) 88*7836SJohn.Forte@Sun.COM # 89*7836SJohn.Forte@Sun.COM if [ $times -eq 60 ] 90*7836SJohn.Forte@Sun.COM then 91*7836SJohn.Forte@Sun.COM echo "Error: Failed waiting for $1 dependents to be 'offline'" 92*7836SJohn.Forte@Sun.COM $SVCS -D $1 2>>/dev/null | grep "^online" 93*7836SJohn.Forte@Sun.COM exit $SMF_EXIT_ERR_FATAL 94*7836SJohn.Forte@Sun.COM fi 95*7836SJohn.Forte@Sun.COM 96*7836SJohn.Forte@Sun.COM # Now sleep, giving other services time to stop 97*7836SJohn.Forte@Sun.COM # 98*7836SJohn.Forte@Sun.COM sleep 5 99*7836SJohn.Forte@Sun.COM times=`expr $times + 1` 100*7836SJohn.Forte@Sun.COM fi 101*7836SJohn.Forte@Sun.COM done 102*7836SJohn.Forte@Sun.COM return 0 103*7836SJohn.Forte@Sun.COM} 104*7836SJohn.Forte@Sun.COM 105*7836SJohn.Forte@Sun.COMset_system_type() 106*7836SJohn.Forte@Sun.COM{ 107*7836SJohn.Forte@Sun.COM CLINFO=/usr/sbin/clinfo 108*7836SJohn.Forte@Sun.COM ESMSBIN=/usr/sbin 109*7836SJohn.Forte@Sun.COM SCMBIN=/usr/sbin 110*7836SJohn.Forte@Sun.COM ESMSCMLIB=/usr/lib 111*7836SJohn.Forte@Sun.COM SCMLIB=/usr/lib 112*7836SJohn.Forte@Sun.COM DSCFG_LOCKDB=/etc/dscfg_lockdb 113*7836SJohn.Forte@Sun.COM} 114*7836SJohn.Forte@Sun.COM 115*7836SJohn.Forte@Sun.COMdo_stopsdbc () 116*7836SJohn.Forte@Sun.COM{ 117*7836SJohn.Forte@Sun.COM if [ ! -r /dev/sdbc ] 118*7836SJohn.Forte@Sun.COM then 119*7836SJohn.Forte@Sun.COM return 120*7836SJohn.Forte@Sun.COM fi 121*7836SJohn.Forte@Sun.COM 122*7836SJohn.Forte@Sun.COM ${SCMBIN}/scmadm -d 123*7836SJohn.Forte@Sun.COM if [ $? -ne 0 ] ; then 124*7836SJohn.Forte@Sun.COM # If the disable failed that means we have pinned data. 125*7836SJohn.Forte@Sun.COM echo "Cache Not Deconfigured" 126*7836SJohn.Forte@Sun.COM fi 127*7836SJohn.Forte@Sun.COM} 128*7836SJohn.Forte@Sun.COM 129*7836SJohn.Forte@Sun.COMdo_stopnskernd () 130*7836SJohn.Forte@Sun.COM{ 131*7836SJohn.Forte@Sun.COM ps -e | grep -w nskernd > /dev/null 2>&1 132*7836SJohn.Forte@Sun.COM if [ $? -eq 0 ] ; then 133*7836SJohn.Forte@Sun.COM # make sure that all data services are unloaded before stopping 134*7836SJohn.Forte@Sun.COM # nskernd - cannot stop nskernd when its threads could be in use 135*7836SJohn.Forte@Sun.COM # Note: sv is unloadable, but its threadset is shutdown in the 136*7836SJohn.Forte@Sun.COM # final close(9e) call. 137*7836SJohn.Forte@Sun.COM stop=1 138*7836SJohn.Forte@Sun.COM for m in ste rdc rdcsrv ii sdbc ; do 139*7836SJohn.Forte@Sun.COM mid=`/usr/sbin/modinfo | grep -w $m | awk '{print $1}' -` 140*7836SJohn.Forte@Sun.COM if [ -z "$mid" ] ; then 141*7836SJohn.Forte@Sun.COM continue # not loaded 142*7836SJohn.Forte@Sun.COM fi 143*7836SJohn.Forte@Sun.COM /usr/sbin/modunload -i $mid > /dev/null 2>&1 144*7836SJohn.Forte@Sun.COM if [ $? -ne 0 ] ; then 145*7836SJohn.Forte@Sun.COM stop=0 146*7836SJohn.Forte@Sun.COM break 147*7836SJohn.Forte@Sun.COM fi 148*7836SJohn.Forte@Sun.COM done 149*7836SJohn.Forte@Sun.COM 150*7836SJohn.Forte@Sun.COM # kill nskernd if we can 151*7836SJohn.Forte@Sun.COM pid=`ps -e | grep -w nskernd | sed -e 's/^ *//' -e 's/ .*//'` 152*7836SJohn.Forte@Sun.COM if [ $stop -eq 1 ] ; then 153*7836SJohn.Forte@Sun.COM if [ -n "$pid" ] ; then 154*7836SJohn.Forte@Sun.COM kill -15 $pid 155*7836SJohn.Forte@Sun.COM fi 156*7836SJohn.Forte@Sun.COM fi 157*7836SJohn.Forte@Sun.COM fi 158*7836SJohn.Forte@Sun.COM 159*7836SJohn.Forte@Sun.COM if [ -r /dev/ncall -a -x $ESMSCMLIB/ncalladm ] 160*7836SJohn.Forte@Sun.COM then 161*7836SJohn.Forte@Sun.COM $ESMSCMLIB/ncalladm -d 162*7836SJohn.Forte@Sun.COM fi 163*7836SJohn.Forte@Sun.COM} 164*7836SJohn.Forte@Sun.COM 165*7836SJohn.Forte@Sun.COMdo_stopdscfglockd () 166*7836SJohn.Forte@Sun.COM{ 167*7836SJohn.Forte@Sun.COM pid=`ps -e | grep -w dscfgloc | sed -e 's/^ *//' -e 's/ .*//'` 168*7836SJohn.Forte@Sun.COM if [ -n "$pid" ] ; then 169*7836SJohn.Forte@Sun.COM kill -15 $pid 170*7836SJohn.Forte@Sun.COM fi 171*7836SJohn.Forte@Sun.COM} 172*7836SJohn.Forte@Sun.COM 173*7836SJohn.Forte@Sun.COMdo_stop () 174*7836SJohn.Forte@Sun.COM{ 175*7836SJohn.Forte@Sun.COM do_smf_depends "system/nws_scm" 176*7836SJohn.Forte@Sun.COM do_stopsdbc 177*7836SJohn.Forte@Sun.COM do_stopnskernd 178*7836SJohn.Forte@Sun.COM do_stopdscfglockd 179*7836SJohn.Forte@Sun.COM} 180*7836SJohn.Forte@Sun.COM 181*7836SJohn.Forte@Sun.COMdo_nskernd () 182*7836SJohn.Forte@Sun.COM{ 183*7836SJohn.Forte@Sun.COM if [ -x $ESMSCMLIB/ncalladm ] 184*7836SJohn.Forte@Sun.COM then 185*7836SJohn.Forte@Sun.COM $ESMSCMLIB/ncalladm -e 186*7836SJohn.Forte@Sun.COM fi 187*7836SJohn.Forte@Sun.COM 188*7836SJohn.Forte@Sun.COM ps -e | grep -w nskernd > /dev/null 2>&1 189*7836SJohn.Forte@Sun.COM if [ $? -ne 0 ] ; then 190*7836SJohn.Forte@Sun.COM ${SCMLIB}/nskernd 191*7836SJohn.Forte@Sun.COM if [ $? -ne 0 ] ; then 192*7836SJohn.Forte@Sun.COM echo "Error: Unable to start nskernd" 193*7836SJohn.Forte@Sun.COM exit $SMF_EXIT_ERR_FATAL 194*7836SJohn.Forte@Sun.COM fi 195*7836SJohn.Forte@Sun.COM fi 196*7836SJohn.Forte@Sun.COM} 197*7836SJohn.Forte@Sun.COM 198*7836SJohn.Forte@Sun.COMdo_dscfglockd () 199*7836SJohn.Forte@Sun.COM{ 200*7836SJohn.Forte@Sun.COM ps -e | grep -w dscfgloc > /dev/null 2>&1 201*7836SJohn.Forte@Sun.COM if [ $? -ne 0 ] 202*7836SJohn.Forte@Sun.COM then 203*7836SJohn.Forte@Sun.COM rm -f /var/tmp/.cfglockd.pid 204*7836SJohn.Forte@Sun.COM else 205*7836SJohn.Forte@Sun.COM # dscfglockd already running 206*7836SJohn.Forte@Sun.COM return 207*7836SJohn.Forte@Sun.COM fi 208*7836SJohn.Forte@Sun.COM 209*7836SJohn.Forte@Sun.COM if ${CLINFO} 210*7836SJohn.Forte@Sun.COM then 211*7836SJohn.Forte@Sun.COM # 212*7836SJohn.Forte@Sun.COM # create or update the dscfg_lockdb file 213*7836SJohn.Forte@Sun.COM # 214*7836SJohn.Forte@Sun.COM 215*7836SJohn.Forte@Sun.COM # create clean tmpnodelist 216*7836SJohn.Forte@Sun.COM NODELIST=/tmp/$$.dscfg_nodelist 217*7836SJohn.Forte@Sun.COM rm -f $NODELIST >/dev/null 2>&1 218*7836SJohn.Forte@Sun.COM touch $NODELIST 219*7836SJohn.Forte@Sun.COM 220*7836SJohn.Forte@Sun.COM if [ -x /usr/cluster/bin/scstat ] 221*7836SJohn.Forte@Sun.COM then 222*7836SJohn.Forte@Sun.COM # get valid names in cluster 223*7836SJohn.Forte@Sun.COM /usr/cluster/bin/scstat -n | grep node: | \ 224*7836SJohn.Forte@Sun.COM awk '{print $3}' >> $NODELIST 225*7836SJohn.Forte@Sun.COM if [ ! -f $DSCFG_LOCKDB ] 226*7836SJohn.Forte@Sun.COM then 227*7836SJohn.Forte@Sun.COM printf "In clustered environment.\n" 228*7836SJohn.Forte@Sun.COM printf "creating per node dscfg_lockdb database" 229*7836SJohn.Forte@Sun.COM printf " with following nodenames:\n" 230*7836SJohn.Forte@Sun.COM cat $NODELIST 231*7836SJohn.Forte@Sun.COM cp $NODELIST $DSCFG_LOCKDB 232*7836SJohn.Forte@Sun.COM else 233*7836SJohn.Forte@Sun.COM # check if there are any changes 234*7836SJohn.Forte@Sun.COM diff $NODELIST $DSCFG_LOCKDB > /dev/null 235*7836SJohn.Forte@Sun.COM if [ $? != 0 ] 236*7836SJohn.Forte@Sun.COM then 237*7836SJohn.Forte@Sun.COM printf "The cluster node names have " 238*7836SJohn.Forte@Sun.COM printf "changed. Updating dscfg_lockdb " 239*7836SJohn.Forte@Sun.COM printf "database.\n" 240*7836SJohn.Forte@Sun.COM printf "Previous node names:\n" 241*7836SJohn.Forte@Sun.COM cat $DSCFG_LOCKDB 242*7836SJohn.Forte@Sun.COM printf "New node names:\n" 243*7836SJohn.Forte@Sun.COM cat $NODELIST 244*7836SJohn.Forte@Sun.COM rm -f $DSCFG_LOCKDB 245*7836SJohn.Forte@Sun.COM cp $NODELIST $DSCFG_LOCKDB 246*7836SJohn.Forte@Sun.COM fi 247*7836SJohn.Forte@Sun.COM fi 248*7836SJohn.Forte@Sun.COM else 249*7836SJohn.Forte@Sun.COM # we're in a cluster, but scstat is not available 250*7836SJohn.Forte@Sun.COM printf "In clustered environment.\n" 251*7836SJohn.Forte@Sun.COM printf "Required configuration file, $DSCFG_LOCKDB\n" 252*7836SJohn.Forte@Sun.COM printf "was not properly populated with the cluster " 253*7836SJohn.Forte@Sun.COM printf "nodenames.\nThis file needs to be manually" 254*7836SJohn.Forte@Sun.COM printf "updated with the cluster\nnodenames before " 255*7836SJohn.Forte@Sun.COM printf "reboot. Refer to Sun Storage Availability\n" 256*7836SJohn.Forte@Sun.COM printf "Suite Installation Guide for details.\n" 257*7836SJohn.Forte@Sun.COM fi 258*7836SJohn.Forte@Sun.COM 259*7836SJohn.Forte@Sun.COM # clustered start of dscfglockd 260*7836SJohn.Forte@Sun.COM if [ -f $DSCFG_LOCKDB ] 261*7836SJohn.Forte@Sun.COM then 262*7836SJohn.Forte@Sun.COM printf "Starting dscfglockd\n" 263*7836SJohn.Forte@Sun.COM ${SCMLIB}/dscfglockd -f $DSCFG_LOCKDB 264*7836SJohn.Forte@Sun.COM else 265*7836SJohn.Forte@Sun.COM printf "WARNING: Mis-Configuration of Availability " 266*7836SJohn.Forte@Sun.COM printf "Suite for Sun Cluster\n" 267*7836SJohn.Forte@Sun.COM printf "WARNING: Can't find configuration file for " 268*7836SJohn.Forte@Sun.COM printf "dscfglockd\n" 269*7836SJohn.Forte@Sun.COM fi 270*7836SJohn.Forte@Sun.COM 271*7836SJohn.Forte@Sun.COM rm -f $NODELIST 272*7836SJohn.Forte@Sun.COM fi 273*7836SJohn.Forte@Sun.COM 274*7836SJohn.Forte@Sun.COM} 275*7836SJohn.Forte@Sun.COM 276*7836SJohn.Forte@Sun.COMdo_sdbc () 277*7836SJohn.Forte@Sun.COM{ 278*7836SJohn.Forte@Sun.COM ${SCMBIN}/scmadm -e 279*7836SJohn.Forte@Sun.COM} 280*7836SJohn.Forte@Sun.COM 281*7836SJohn.Forte@Sun.COM 282*7836SJohn.Forte@Sun.COMdo_start () 283*7836SJohn.Forte@Sun.COM{ 284*7836SJohn.Forte@Sun.COM # do nothing if we do not have a dscfg 285*7836SJohn.Forte@Sun.COM if [ ! -f /etc/dscfg_local ] 286*7836SJohn.Forte@Sun.COM then 287*7836SJohn.Forte@Sun.COM echo "Cannot find Availability Suite configuration location" 288*7836SJohn.Forte@Sun.COM exit $SMF_EXIT_ERR_NOSMF 289*7836SJohn.Forte@Sun.COM fi 290*7836SJohn.Forte@Sun.COM 291*7836SJohn.Forte@Sun.COM # 292*7836SJohn.Forte@Sun.COM # Ordering: 293*7836SJohn.Forte@Sun.COM # dscfglockd -- locking must be present before any dscfg access 294*7836SJohn.Forte@Sun.COM # nskernd -- starts infrastructure (nskernd, ncall). 295*7836SJohn.Forte@Sun.COM # sdbc -- start the cache itself 296*7836SJohn.Forte@Sun.COM # 297*7836SJohn.Forte@Sun.COM do_dscfglockd 298*7836SJohn.Forte@Sun.COM do_nskernd 299*7836SJohn.Forte@Sun.COM do_sdbc 300*7836SJohn.Forte@Sun.COM} 301*7836SJohn.Forte@Sun.COM 302*7836SJohn.Forte@Sun.COM 303*7836SJohn.Forte@Sun.COMdo_usage () 304*7836SJohn.Forte@Sun.COM{ 305*7836SJohn.Forte@Sun.COM echo "Usage: $0" 306*7836SJohn.Forte@Sun.COM echo " start" 307*7836SJohn.Forte@Sun.COM echo " stop" 308*7836SJohn.Forte@Sun.COM exit 1 309*7836SJohn.Forte@Sun.COM} 310*7836SJohn.Forte@Sun.COM 311*7836SJohn.Forte@Sun.COMset_system_type 312*7836SJohn.Forte@Sun.COM 313*7836SJohn.Forte@Sun.COMUSED=0 314*7836SJohn.Forte@Sun.COMACTION= 315*7836SJohn.Forte@Sun.COMCLUSTERTAG= 316*7836SJohn.Forte@Sun.COM 317*7836SJohn.Forte@Sun.COMcase $# in 318*7836SJohn.Forte@Sun.COM'0') 319*7836SJohn.Forte@Sun.COM do_usage 320*7836SJohn.Forte@Sun.COM ;; 321*7836SJohn.Forte@Sun.COM'1') 322*7836SJohn.Forte@Sun.COM ACTION=$1 323*7836SJohn.Forte@Sun.COM USED=1 324*7836SJohn.Forte@Sun.COM ;; 325*7836SJohn.Forte@Sun.COM'2') 326*7836SJohn.Forte@Sun.COM ACTION=$1 327*7836SJohn.Forte@Sun.COM CLUSTERTAG="$2" 328*7836SJohn.Forte@Sun.COM USED=1 329*7836SJohn.Forte@Sun.COM exit 0 330*7836SJohn.Forte@Sun.COM ;; 331*7836SJohn.Forte@Sun.COM'*') 332*7836SJohn.Forte@Sun.COM do_usage 333*7836SJohn.Forte@Sun.COM ;; 334*7836SJohn.Forte@Sun.COMesac 335*7836SJohn.Forte@Sun.COM 336*7836SJohn.Forte@Sun.COMif [ $USED = 0 ] ; then 337*7836SJohn.Forte@Sun.COM do_usage 338*7836SJohn.Forte@Sun.COMfi 339*7836SJohn.Forte@Sun.COM 340*7836SJohn.Forte@Sun.COMif [ $ACTION = "start" ] ; then 341*7836SJohn.Forte@Sun.COM do_start 342*7836SJohn.Forte@Sun.COMelif [ $ACTION = "stop" ] ; then 343*7836SJohn.Forte@Sun.COM do_stop 344*7836SJohn.Forte@Sun.COMelse 345*7836SJohn.Forte@Sun.COM do_usage 346*7836SJohn.Forte@Sun.COMfi 347*7836SJohn.Forte@Sun.COM 348*7836SJohn.Forte@Sun.COMexit $SMF_EXIT_OK 349