Solaris

Configuring services on Solaris 10

Posted
General description of SMF infrastructure:
man smf
To list enabled services:
# svcs
To list all enabled and disabled services:
# svcs -a
Detailed information on a service:
# svcs -v svc:/system/webconsole:console

Look at and change options values

# svccfg
svc:> select volfs
svc:/system/filesystem/volfs> listprop vold/*
vold/config_file            astring
vold/log_debuglevel         count    0
vold/log_file               astring
vold/log_nfs_trace          boolean  false
vold/log_verbose            boolean  false
vold/never_writeback_label  boolean  false
vold/root_dir               astring
svc:/system/filesystem/volfs> setprop vold/never_writeback_label=true
svc:/system/filesystem/volfs> exit

Restart service:
# svcadm disable volfs
# svcadm enable volfs

How to create our own service.
General steps:* Create a service manifest file.
* Create a methods script file to define the start, stop, and restart methods for the service.
* Validate and import the service manifest using svccfg(1M).
* Enable or start the service using svcadm(1M).
* Verify the service is running using svcs(1).

1. Create manifest. All manifests are located in /var/svc/manifest directory. Subdirectories classify service types.
We should choose an appropriate subdirectory and create a manifest file in it. An easy way is to copy some existing file
as a template.
/var/svc/manifest/network/rsync.xml
манифест можно не писать руками, а сгенерить на основе /etc/inetd.conf
для этого надо добавить строку в /etc/services:
rsync  873/tcp
добавить строку в /etc/inetd.conf:
rsync stream tcp nowait root /usr/local/bin/rsync rsyncd –daemon
и запустить
inetconv -i /etc/inet/inetd.conf
При данном способе получения сервиса последующие шаги не нужны. После окончания работы команды сервис становится полностью сконфигурированным и запускается автоматически.
In the manifest file should be at least one instance tag. Parameter tags are optional. An example of manifest is below.
2. Create startup/shutdown script for the service daemon
/lib/svc/method/rsync
The first argument of the script is a command name. The script may execute the following commands:
– start
– stop
– reload
– force-reload
– restart

 

———————————————————————————————————————-
Startrup script file example

#!/bin/bash

SRV_HOME=”/opt/oracle10/product/filerep”
# !!IMPORTANT!! one space should be at the end of command

REMOTE_DEBUG_JAVA_OPTIONS=”-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=4020,server=y,suspend=n”
JAVA_OPTIONS=”-Djava.util.logging.config.file=/opt/oracle10/product/filerep/logging.properties”
JAVA_COMMAND=”/usr/jdk/instances/jdk1.6.0/bin/java $JAVA_OPTIONS -jar $SRV_HOME/FileRep.jar ”
JAVA_COMMAND_KEYWORD=”FileRep.jar”
SERVICE_NAME=”filerep”                                    # service name
SERVICE_USER=”oracle”                                      # OS user name for the service
SERVICE_GROUP=”dba”                                    # OS group name for the service
PID_FILE=”/var/run/$SERVICE_NAME.pid”                      # name of PID file (PID = process ID number)
LOG_FILE=”/var/log/$SERVICE_NAME.log”               # log file for StdOut/StdErr
MAX_SHUTDOWN_TIME=15                                         # maximum number of seconds to wait for the daemon to terminate normally

# Makes the file $1 writable by the group $serviceGroup.
function makeFileWritable {
local filename=”$1″
touch $filename || return 1
chgrp $SERVICE_GROUP $filename || return 1
chmod g+w $filename || return 1
return 0;
}

# Returns 0 if the process with PID $1 is running.
function checkProcessIsRunning {
local pid=”$1″
if [ -z “$pid” -o “$pid” == ” ” ]; then return 1; fi
if [ ! -e /proc/$pid ]; then return 1; fi
return 0;
}

# Returns 0 if the process with PID $1 is our Java service process.
function checkProcessIsOurService {
local pid=”$1″
echo “check ours $pid”
local real=”-$(pargs -l $pid)-”
real=${real//”‘”/}
local ours=”-$JAVA_COMMAND-”
echo “real=$real”
echo “ours=$ours”
if [ “$real” != “$ours” ]
then
echo “commands not equal”
return 1
fi
return 0;
}

# Returns 0 when the service is running and sets the variable $pid to the PID.
function getServicePID {
if [ ! -f $PID_FILE ]; then return 1; fi
pid=”$(<$PID_FILE)”
checkProcessIsRunning $pid || return 1
checkProcessIsOurService $pid || return 1
return 0;
}

function startServiceProcess {
cd $SRV_HOME || return 1
rm -f $pidFile
makeFileWritable $PID_FILE || return 1
makeFileWritable $LOG_FILE || return 1
cmd=”nohup $JAVA_COMMAND >>$LOG_FILE 2>&1 & echo \$! >$PID_FILE”
echo “su – $SERVICE_USER -c $cmd”
su – $SERVICE_USER -c “$cmd” || return 1
sleep 1
pid=”$(<$PID_FILE)”
if checkProcessIsRunning $pid; then :; else
echo -ne “\n$SERVICE_NAME start failed, see logfile.”
return 1
fi
return 0;
}

function stopServiceProcess {
kill $pid || return 1
for ((i=0; i< MAX_SHUTDOWN_TIME*10; i++)); do
checkProcessIsRunning $pid
if [ $? -ne 0 ]; then
rm -f $PID_FILE
return 0
fi
sleep 1
done
echo -e “\n$SERVICE_NAME did not terminate within $MAX_SHUTDOWN_TIME seconds, sending SIGKILL…”
kill -s KILL $pid || return 1
local killWaitTime=15
for ((i=0; i<killWaitTime*10; i++)); do
checkProcessIsRunning $pid
if [ $? -ne 0 ]; then
rm -f $PID_FILE
return 0
fi
sleep 1
done
echo “Error: $SERVICE_NAME could not be stopped within $MAX_SHUTDOWN_TIME+$killWaitTime seconds!”
return 1;
}

function startService {
getServicePID
if [ $? -eq 0 ]; then echo -n “$SERVICE_NAME is already running”; RETVAL=0; return 0; fi
echo -n “Starting $SERVICE_NAME   ”
startServiceProcess
if [ $? -ne 0 ]; then RETVAL=1; echo “failed”; return 1; fi
echo “started PID=$pid”
RETVAL=0
return 0;
}

function stopService {
getServicePID
if [ $? -ne 0 ]; then echo -n “$SERVICE_NAME is not running”; RETVAL=0; echo “”; return 0; fi
echo -n “Stopping $SERVICE_NAME   ”
stopServiceProcess
if [ $? -ne 0 ]; then RETVAL=1; echo “failed”; return 1; fi
echo “stopped PID=$pid”
RETVAL=0
return 0; }

function checkServiceStatus {
echo -n “Checking for $SERVICE_NAME:   ”
if getServicePID; then
echo “running PID=$pid”
RETVAL=0
else
echo “stopped”
RETVAL=3
fi
return 0;
}

function main {
RETVAL=0
case “$1” in
start)                                               # starts the Java program as a Linux service
startService
;;
stop)                                                # stops the Java program service
stopService
;;
restart)                                             # stops and restarts the service
stopService && startService
;;
status)                                              # displays the service status
checkServiceStatus
;;
*)
echo “Usage: $0 {start|stop|restart|status}”
exit 1
;;
esac
exit $RETVAL
}

main $1

———————————————————————————————————————-
Manifest file example

<!DOCTYPE service_bundle SYSTEM “/usr/share/lib/xml/dtd/service_bundle.dtd.1″>
<!–
File replication service
–>

<service_bundle type=’manifest’ name=’filerep’>

<service
name=’application/filerep’
type=’service’
version=’1′>

<!–
Wait for network interfaces to be initialized.
–>
<dependency
name=’network’
grouping=’require_all’
restart_on=’none’
type=’service’>
<service_fmri value=’svc:/milestone/network:default’ />
</dependency>

<!–
Wait for all local filesystems to be mounted.
–>
<dependency
name=’filesystem-local’
grouping=’require_all’
restart_on=’none’
type=’service’>
<service_fmri value=’svc:/system/filesystem/local:default’ />
</dependency>

<exec_method
type=’method’
name=’start’
exec=’/lib/svc/method/filerep start’
timeout_seconds=’60’ />

<exec_method
type=’method’
name=’stop’
exec=’/lib/svc/method/filerep stop’
timeout_seconds=’60’ />

<exec_method
type=’method’
name=’refresh’
exec=’/lib/svc/method/filerep refresh’
timeout_seconds=’60’ />

<!–
We define two instances of PostgreSQL as examples (8.1 & 8.2).
–>

<instance name=’instance’ enabled=’true’>
<method_context>
<method_credential user=’root’ group=’root’ />
</method_context>
</instance>

<stability value=’Evolving’ />

<template>
<common_name>
<loctext xml:lang=’C’>
Filerep
</loctext>
</common_name>
<documentation>
<manpage title=’filerep’ section=’5′ />
<doc_link name=”
uri=” />
</documentation>
</template>

</service>

</service_bundle>