-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathpp.back.solaris.svc
520 lines (464 loc) · 16.6 KB
/
pp.back.solaris.svc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
# http://www.sun.com/bigadmin/content/selfheal/sdev_intro.html
# http://opensolaris.org/os/community/smf/faq
#@ pp_backend_solaris_init_svc_vars(): initialise service var defaults
pp_backend_solaris_init_svc_vars () {
_smf_category=${pp_solaris_smf_category:-application}
_smf_method_envvar_name=${smf_method_envvar_name:-"PP_SMF_SERVICE"}
pp_solaris_service_shell=/sbin/sh
}
#@ pp_solaris_init_svc(): initialise solaris backend vars for services
pp_solaris_init_svc () {
smf_version=1
smf_type=service
solaris_user=
solaris_stop_signal=
solaris_sysv_init_start=S70 # invocation order for start scripts
solaris_sysv_init_kill=K30 # invocation order for kill scripts
solaris_sysv_init_start_states="2" # states to install start link
solaris_sysv_init_kill_states="S 0 1" # states to install kill link
#
# To have the service be installed to start automatically,
# %service foo
# solaris_sysv_init_start_states="S 0 1 2"
#
}
#@ pp_solaris_smf(svc): create an service file
pp_solaris_smf () {
typeset f _pp_solaris_service_script svc _pp_solaris_manpage
pp_solaris_name=${pp_solaris_name:-$name}
pp_solaris_manpath=${pp_solaris_manpath:-"/usr/share/man"}
pp_solaris_mansect=${pp_solaris_mansect:-1}
smf_start_timeout=${smf_start_timeout:-60}
smf_stop_timeout=${smf_stop_timeout:-60}
smf_restart_timeout=${smf_restart_timeout:-60}
svc=${pp_solaris_smf_service_name:-$1}
_pp_solaris_service_script=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
_pp_solaris_manpage=${pp_solaris_manpage:-$svc}
if [ -z $pp_svc_xml_file ]; then
pp_svc_xml_file="/var/svc/manifest/$_smf_category/$svc.xml"
echo "## Generating the smf service manifest file for $pp_svc_xml_file"
else
echo "## SMF service manifest file already defined at $pp_svc_xml_file"
if [ -z $pp_solaris_smf_service_name ] || [ -z $pp_solaris_smf_category ] || [ -z $pp_solaris_service_script ] || [ -z $smf_method_envvar_name ]; then
pp_error "All required variables are not set.\n"\
"When using a custom manifest file all of the following variables must be set:\n"\
"pp_solaris_smf_service_name, pp_solaris_smf_category, pp_solaris_service_script and smf_method_envvar_name.\n\n"\
"Example:\n"\
" \$pp_solaris_smf_category=application\n"\
" \$pp_solaris_smf_service_name=pp\n\n"\
" <service name='application/pp' type='service' version='1'>\n\n"\
"Example:\n"\
" \$pp_solaris_service_script=/etc/init.d/pp\n\n"\
" <exec_method type='method' name='start' exec='/etc/init.d/pp' />\n\n"\
"Example:\n"\
" \$smf_method_envvar_name=PP_SMF_SERVICE\n\n"\
" <method_environment>\n"\
" <envvar name='PP_SMF_SERVICE' value='1'/>\n"\
" </method_environment>\n"
return 1
fi
return 0
fi
f=$pp_svc_xml_file
pp_add_file_if_missing $f ||
return 0
pp_solaris_add_parent_dirs "$f"
_pp_solaris_smf_dependencies="
<dependency name='pp_local_filesystems'
grouping='require_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>
<dependency name='pp_single-user'
grouping='require_all'
restart_on='none'
type='service'>
<service_fmri value='svc:/milestone/single-user' />
</dependency>
"
_pp_solaris_smf_dependencies=${pp_solaris_smf_dependencies:-$_pp_solaris_smf_dependencies}
cat <<-. >$pp_destdir$f
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<!--
$copyright
Generated by PolyPackage $pp_version
-->
<service_bundle type='manifest' name='${pp_solaris_name}:${svc}' >
<service name='$_smf_category/$svc'
type='$smf_type'
version='$smf_version'>
<create_default_instance enabled='false'/>
<single_instance />
$_pp_solaris_smf_dependencies
$pp_solaris_smf_additional_dependencies
<method_context>
<method_credential user='${solaris_user:-$user}' />
<method_environment>
<envvar name='$_smf_method_envvar_name' value='1'/>
</method_environment>
</method_context>
<exec_method type='method' name='start'
exec='$_pp_solaris_service_script start'
timeout_seconds='$smf_start_timeout' />
<exec_method type='method' name='stop'
exec='$_pp_solaris_service_script stop'
timeout_seconds='$smf_stop_timeout' />
<exec_method type='method' name='restart'
exec='$_pp_solaris_service_script restart'
timeout_seconds='$smf_restart_timeout' />
$pp_solaris_smf_property_groups
<template>
<common_name>
<loctext xml:lang='C'>$description</loctext>
</common_name>
<documentation>
<manpage title='$pp_solaris_manpage' section='$pp_solaris_mansect' manpath='$pp_solaris_manpath'/>
</documentation>
</template>
</service>
</service_bundle>
.
}
#@ pp_solaris_make_service_group (group svcs): create a SysV service group
# script and adds it to %files.run if not there already
pp_solaris_make_service_group () {
typeset group out file svcs svc
group="$1"
svcs="$2"
file="/etc/init.d/$group"
out="$pp_destdir$file"
#-- return if the script is supplied already
pp_add_file_if_missing "$file" run 755 || return 0
pp_solaris_add_parent_dirs "$file"
echo "#! /sbin/sh" > $out
echo "# polypkg service group script for these services:" >> $out
echo "svcs=\"$svcs\"" >> $out
cat <<'.' >>$out
#-- starts services in order.. stops them all if any break
pp_start () {
undo=
for svc in $svcs; do
if /etc/init.d/$svc start; then
undo="$svc $undo"
else
if test -n "$undo"; then
for svc in $undo; do
/etc/init.d/$svc stop
done
return 1
fi
fi
done
return 0
}
#-- stops services in reverse
pp_stop () {
reverse=
for svc in $svcs; do
reverse="$svc $reverse"
done
rc=0
for svc in $reverse; do
/etc/init.d/$svc stop || rc=$?
done
return $rc
}
#-- returns true only if all services return true status
pp_status () {
rc=0
for svc in $svcs; do
/etc/init.d/$svc status || rc=$?
done
return $rc
}
case "$1" in
start) pp_start;;
stop) pp_stop;;
status) pp_status;;
restart) pp_stop && pp_start;;
*) echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
esac
.
}
#@ pp_solaris_make_service (svc): create a SysV service script
# creates and adds the file /etc/init.d/$svc to %files.run if
# it isn't there already.
pp_solaris_make_service () {
typeset file out svc
svc="${pp_solaris_smf_service_name:-$1}"
file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
out="$pp_destdir$file"
#-- return if we don't need to create the init script
pp_add_file_if_missing "$file" run 755 ||
return 0
pp_solaris_add_parent_dirs "$file"
echo "#! /sbin/sh" >$out
echo "#-- This service init file generated by polypkg" >>$out
#-- Start SMF integration.
if [ -n "$pp_svc_xml_file" ] ; then
cat <<_EOF >>$out
if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envvar_name" = "t" ] ; then
case "\$1" in
start)
echo "starting $svc"
/usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
/usr/sbin/svcadm enable -s $_smf_category/$svc
RESULT=\$?
if [ "\$RESULT" -ne 0 ] ; then
echo "Error \$RESULT starting $svc" >&2
fi
;;
stop)
echo "stopping $svc"
/usr/sbin/svcadm disable -ts $_smf_category/$svc
RESULT=0
;;
restart)
echo "restarting $svc"
/usr/sbin/svcadm disable -ts $_smf_category/$svc
/usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
/usr/sbin/svcadm enable -s $_smf_category/$svc
RESULT=\$?
if [ "\$RESULT" -ne 0 ] ; then
echo "Error \$RESULT starting $svc" >&2
fi
;;
*)
echo "Usage: $file {start|stop|restart|status}" >&2
RESULT=1
esac
exit $RESULT
fi
_EOF
fi
#-- Construct a start command that builds a pid file as needed
# and forks the daemon. Services started by smf may not fork.
if test -z "$pidfile"; then
# The service does not define a pidfile, so we have to make
# our own up. On Solaris systems where there is no /var/run
# we must use /tmp to guarantee the pid files are removed after
# a system crash.
if test -z "$pp_piddir"; then
pp_piddir="/var/run"
fi
cat <<. >>$out
pp_isdaemon=0
pp_piddirs="${pp_piddir}${pp_piddir+ }/var/run /tmp"
for pp_piddir in \$pp_piddirs; do
test -d "\$pp_piddir/." && break
done
pidfile="\$pp_piddir/$svc.pid"
.
else
# The service is able to write its own PID file
cat <<. >>$out
pp_isdaemon=1
pidfile="$pidfile"
.
fi
pp_su=
if test "${user:-root}" != "root"; then
pp_su="su $user -c exec "
fi
cat <<. >>$out
stop_signal="${stop_signal:-TERM}"
svc="${svc}"
# generated command to run $svc as a service
pp_exec () {
if [ \$pp_isdaemon -ne 1 ]; then
if [ "t\$PP_SMF_SERVICE" = "t" ]; then
${pp_su}$cmd &
echo \$! > \$pidfile
else
echo "via exec."
echo \$$ > \$pidfile
exec ${pp_su}$cmd
return 1
fi
else
${pp_su}$cmd
fi
}
.
#-- write the invariant section of the init script
cat <<'.' >>$out
# returns true if $svc is running
pp_running () {
if test -s "$pidfile"; then
read pid < "$pidfile" 2>/dev/null
if test ${pid:-0} -gt 1 && kill -0 "$pid" 2>/dev/null; then
# make sure command name matches up to the first 8 chars
c="`echo $cmd | sed -e 's: .*::' -e 's:^.*/::' -e 's/^\(........\).*$/\1/'`"
pid="`ps -p $pid 2>/dev/null | sed -n \"s/^ *\($pid\) .*$c *$/\1/p\"`"
if test -n "$pid"; then
return 0
fi
fi
fi
return 1
}
# prints a message describing $svc's running state
pp_status () {
if pp_running; then
echo "service $svc is running (pid $pid)"
return 0
elif test -f "$pidfile"; then
echo "service $svc is not running, but pid file exists"
return 2
else
echo "service $svc is not running"
return 1
fi
}
# starts $svc
pp_start () {
if pp_running; then
echo "service $svc already running" >&2
return 0
fi
echo "starting $svc... \c"
if pp_exec; then
echo "done."
else
echo "ERROR."
exit 1
fi
}
# stops $svc
pp_stop () {
if pp_running; then
echo "stopping $svc... \c"
if kill -$stop_signal $pid; then
rm -f "$pidfile"
echo "done."
else
echo "ERROR."
return 1
fi
else
echo "service $svc already stopped" >&2
return 0
fi
}
umask 022
case "$1" in
start) pp_start;;
stop) pp_stop;;
status) pp_status;;
restart) pp_stop && pp_start;;
*) echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
esac
.
}
#@ pp_solaris_remove_service($svc): generate commands to remove svc
# output is intended to go to preremove
pp_solaris_remove_service () {
typeset file svc
svc="${pp_solaris_smf_service_name:-$1}"
file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
echo '
# Stop the service and remove it from SMF if present
if [ "x${PKG_INSTALL_ROOT}" = 'x' ]; then
if [ -x /usr/sbin/svcadm ] ; then
/usr/sbin/svcadm disable -s '$svc' 2>/dev/null
if [ `uname -r` = 5.10 ] || [ "'${pp_svc_xml_file%/*/*}'" != "/var/svc/manifest" ]; then
/usr/sbin/svccfg delete '$svc' 2>/dev/null
else
/usr/sbin/svcadm restart manifest-import 2>/dev/null
fi
else
'$file' stop >/dev/null 2>/dev/null
fi
fi
'
}
#@ pp_solaris_install_service($svc): generate commands to install svc
# output is intended to go to postinstall
pp_solaris_install_service () {
typeset s k l file svc
svc="${pp_solaris_smf_service_name:-$1}"
file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
s="${solaris_sysv_init_start}$svc"
k="${solaris_sysv_init_kill}$svc"
echo '
if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
if [ -x ${PKG_INSTALL_ROOT}/usr/sbin/svcadm ]; then
if [ `uname -r` = 5.10 ] || [ "'${pp_svc_xml_file%/*/*}'" != "/var/svc/manifest" ]; then
echo "/usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null" >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
else
echo "/usr/sbin/svcadm restart manifest-import 2>/dev/null" >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
fi
else'
test -n "${solaris_sysv_init_start_states}" &&
for state in ${solaris_sysv_init_start_states}; do
l="/etc/rc$state.d/$s"
echo "echo '$l'"
echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
pp_solaris_space /etc/rc$state.d 0 1
done
test -n "${solaris_sysv_init_kill_states}" &&
for state in ${solaris_sysv_init_kill_states}; do
l="/etc/rc$state.d/$k"
echo "echo '$l'"
echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
pp_solaris_space /etc/rc$state.d 0 1
done
echo '
fi
else
if [ -x /usr/sbin/svcadm ]; then
echo "Registering '$svc' with SMF"
/usr/sbin/svcadm disable -s '$svc' 2>/dev/null
if [ `uname -r` = 5.10 ] || [ "'${pp_svc_xml_file%/*/*}'" != "/var/svc/manifest" ]; then
/usr/sbin/svccfg delete '$svc' 2>/dev/null
/usr/sbin/svccfg import '$pp_svc_xml_file'
else
/usr/sbin/svcadm restart manifest-import
# Wait for import to complete, otherwise it will not know
# about our service until after we try to start it
echo Waiting for manifest-import...
typeset waited
waited=0
while [ $waited -lt 15 ] && ! /usr/bin/svcs -l '$svc' >/dev/null 2>&1; do
sleep 1
waited=`expr $waited + 1`
done
if /usr/bin/svcs -l '$svc' >/dev/null 2>&1; then
echo OK
else
echo manifest-import took to long, you might have to control '$svc' manually.
fi
fi
else'
test -n "${solaris_sysv_init_start_states}" &&
for state in ${solaris_sysv_init_start_states}; do
l="/etc/rc$state.d/$s"
echo "echo '$l'"
echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
pp_solaris_space /etc/rc$state.d 0 1
done
test -n "${solaris_sysv_init_kill_states}" &&
for state in ${solaris_sysv_init_kill_states}; do
l="/etc/rc$state.d/$k"
echo "echo '$l'"
echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
pp_solaris_space /etc/rc$state.d 0 1
done
echo '
fi
fi'
}
#@ pp_solaris_add_parent_dirs($file): add parent dirs for file to %files.run
# Suppresses warnings from pkgmk
pp_solaris_add_parent_dirs () {
typeset dir
dir=${1%/*}
while test -n "$dir"; do
if awk "\$6 == \"$dir/\" {exit 1}" < $pp_wrkdir/%files.run; then
echo "d - - - - $dir/" >> $pp_wrkdir/%files.run
fi
dir=${dir%/*}
done
}