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>
|