Print this page
7818 SMF does not always cleanup services that have been removed
Reviewed by: Joshua M. Clulow <josh@sysmgr.org>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/svc/milestone/manifest-import
+++ new/usr/src/cmd/svc/milestone/manifest-import
1 1 #!/bin/ksh
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 +# Copyright 2017 RackTop Systems.
23 24 #
24 25
25 26 # 0a Initialization.
26 27
27 28 [ -f /lib/svc/share/smf_include.sh ] || exit 1
28 29
29 30 . /lib/svc/share/smf_include.sh
30 31
31 32 activity=false
32 33
33 34 EMI_SERVICE="svc:/system/early-manifest-import:default"
34 35 PROFILE_DIR_SITE="/etc/svc/profile/site"
35 36
36 37 X=
37 38 ALT_REPOSITORY=
38 39 ALT_MFST_DIR=
39 40 early=false
40 41 [ "$SMF_FMRI" == "$EMI_SERVICE" ] && early=true
41 42
42 43 usage()
43 44 {
44 45 echo "Usage: /lib/svc/method/manifest-import [-n]" \
45 46 "[-f repository-file -d manifest-directory]"
46 47 echo "\nOptions:"
47 48 echo "-n dryrun"
48 49 echo "-f and -d specify alternate repository and" \
49 50 "manifest directory for import\n"
50 51 exit 2
51 52 }
52 53
53 54 while getopts "nd:f:" opt; do
54 55 case $opt in
55 56 n) X=echo;;
56 57 d) ALT_MFST_DIR=$OPTARG;;
57 58 f) ALT_REPOSITORY=$OPTARG;;
58 59 ?) usage;;
59 60 esac
60 61 done
61 62
62 63 #
63 64 # Both -f and -d options must be specified together or not specified at all
64 65 #
65 66 [ -n "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ] && usage
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
66 67 [ -n "$ALT_MFST_DIR" -a -z "$ALT_REPOSITORY" ] && usage
67 68
68 69 function svccfg_apply {
69 70 $X /usr/sbin/svccfg apply $1
70 71 if [ $? -ne 0 ]; then
71 72 echo "WARNING: svccfg apply $1 failed" | tee /dev/msglog
72 73 fi
73 74 }
74 75
75 76 #
76 -# If the smf/manifest table has file entries that are missing
77 +# If the smf repository has file entries that are missing
77 78 # then there is work to be done by the cleanup process.
78 79 #
79 80 function cleanup_needwork {
80 - if [ "$early" == true ]; then
81 - smfmfiles=`/usr/bin/svcprop smf/manifest | \
82 - awk '(/^lib_/ && /\/manifestfile /) {print $3}'`
83 - else
84 - smfmfiles=`/usr/bin/svcprop smf/manifest | \
85 - awk '/\/manifestfile / {print $3}'`
86 - fi
81 + smfmfiles=`svcprop -p manifestfiles '*' 2>/dev/null |
82 + nawk -v early="$early" '$2 == "astring" &&
83 + (early != "true" || $3 ~ "^/lib/") { print $3 }'`
87 84
88 85 nw=`/lib/svc/bin/mfstscan $smfmfiles 2>&1 1>/dev/null`
89 86 [ "$nw" ] && return 1
90 87
91 88 return 0
92 89 }
93 90
94 91 #
95 92 # Upon upgrading to early manifest import code, preserve hashes of system
96 93 # profiles which lived under /var/svc/profile so that svccfg apply would
97 94 # not re-apply the profiles and overwrite user customizations. Simply
98 95 # migrate manifestfile and hash values to new property groups named after
99 96 # profiles under /etc/svc/profile. If the profiles don't really exist,
100 97 # svccfg cleanup will remove the property groups in a later step.
101 98 #
102 99 # Existing generic.xml, inetd_services.xml, and name_service.xml symlinks
103 100 # need to be preserved.
104 101 #
105 102 # Don't process site.xml profile since it is still supported under
106 103 # /var/svc/profile directory.
107 104 #
108 105 function preserve_system_profiles {
109 106
110 107 #
111 108 # If /var is a separate fs, return and let Late Import
112 109 # preserves the hashes.
113 110 #
114 111 [ -d "/var/svc/profile" ] || return 1
115 112
116 113 #
117 114 # Preserve hashes for the following profiles: generic (two
118 115 # cases) and platform (uname -i, uname -m outputs).
119 116 #
120 117 gn="var_svc_profile_generic_open_xml"
121 118 gh=`/usr/bin/svcprop -p ${gn}/md5sum smf/manifest 2>/dev/null`
122 119 [ $? = 0 ] || gh=""
123 120 gn="etc_svc_profile_generic_open_xml"
124 121
125 122 gln="var_svc_profile_generic_limited_net_xml"
126 123 glh=`/usr/bin/svcprop -p ${gln}/md5sum smf/manifest 2>/dev/null`
127 124 [ $? = 0 ] || glh=""
128 125 gln="etc_svc_profile_generic_limited_net_xml"
129 126
130 127 LC_ALL=C pl=`/usr/bin/uname -i | /usr/bin/tr , _`
131 128 pln="var_svc_profile_platform_${pl}_xml"
132 129 plh=`/usr/bin/svcprop -p ${pln}/md5sum smf/manifest 2>/dev/null`
133 130 [ $? = 0 ] || plh=""
134 131 pln="etc_svc_profile_platform_${pl}_xml"
135 132
136 133 LC_ALL=C plm=`/usr/bin/uname -m | /usr/bin/tr , _`
137 134 if [ $plm != $pl ]; then
138 135 plmn="var_svc_profile_platform_${plm}_xml"
139 136 plmh=`/usr/bin/svcprop -p ${plmn}/md5sum smf/manifest \
140 137 2>/dev/null`
141 138 [ $? = 0 ] || plmh=""
142 139 plmn="etc_svc_profile_platform_${plm}_xml"
143 140 else
144 141 plmh=""
145 142 fi
146 143
147 144 [ -n "$gh" ] && {
148 145 echo "Preserving generic hash ($gh)."
149 146 /usr/sbin/svccfg -s smf/manifest addpg ${gn} framework
150 147 /usr/sbin/svccfg -s smf/manifest setprop ${gn}/md5sum = \
151 148 opaque: $gh
152 149 /usr/sbin/svccfg -s smf/manifest setprop ${gn}/manifestfile = \
153 150 astring: "/etc/svc/profile/generic.xml"
154 151 }
155 152 [ -n "$glh" ] && {
156 153 echo "Preserving generic_limited hash ($glh)."
157 154 /usr/sbin/svccfg -s smf/manifest addpg ${gln} framework
158 155 /usr/sbin/svccfg -s smf/manifest setprop ${gln}/md5sum = \
159 156 opaque: $glh
160 157 /usr/sbin/svccfg -s smf/manifest setprop ${gln}/manifestfile = \
161 158 astring: "/etc/svc/profile/generic.xml"
162 159 }
163 160 [ -n "$plh" ] && {
164 161 echo "Preserving platform hash ($plh)."
165 162 /usr/sbin/svccfg -s smf/manifest addpg $pln framework
166 163 /usr/sbin/svccfg -s smf/manifest setprop $pln/md5sum = \
167 164 opaque: $plh
168 165 /usr/sbin/svccfg -s smf/manifest setprop ${pln}/manifestfile = \
169 166 astring: "/etc/svc/profile/platform_${pl}_xml"
170 167 }
171 168 [ -n "$plmh" ] && {
172 169 echo "Preserving platform hash ($plmh)."
173 170 /usr/sbin/svccfg -s smf/manifest addpg $plmn framework
174 171 /usr/sbin/svccfg -s smf/manifest setprop $plmn/md5sum = \
175 172 opaque: $plmh
176 173 /usr/sbin/svccfg -s smf/manifest setprop \
177 174 ${plmn}/manifestfile = \
178 175 astring: "/etc/svc/profile/platform_${plm}_xml"
179 176 }
180 177
181 178 #
182 179 # Move symlinks from /var/svc/profile to /etc/svc/profile
183 180 #
184 181 generic_prof="/var/svc/profile/generic.xml"
185 182 ns_prof="/var/svc/profile/name_service.xml"
186 183 inetd_prof="/var/svc/profile/inetd_services.xml"
187 184 platform_prof="/var/svc/profile/platform.xml"
188 185 [ -L "$generic_prof" ] && mv $generic_prof /etc/svc/profile/
189 186 [ -L "$ns_prof" ] && mv $ns_prof /etc/svc/profile/
190 187 [ -L "$inetd_prof" ] && mv $inetd_prof /etc/svc/profile/
191 188 [ -L "$platform_prof" ] && mv $platform_prof /etc/svc/profile/
192 189
193 190 return 0
194 191 }
195 192
196 193 #
197 194 # 2. Manifest import. Application directories first, then
198 195 # site-specific manifests.
199 196 #
200 197 function import_manifests {
201 198 typeset basedir=$1
202 199 typeset console_print=$2
203 200 typeset logf="/etc/svc/volatile/manifest_import.$$"
204 201
205 202 rm -f $logf
206 203
207 204 nonsite_dirs=`/usr/bin/find $basedir/* -name site \
208 205 -prune -o -type d -print -prune`
209 206
210 207 if [ -n "$_MFST_DEBUG" ]; then
211 208 nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs`
212 209 site_manifests=`/lib/svc/bin/mfstscan $basedir/site`
213 210
214 211 manifests="$nonsite_manifests $site_manifests"
215 212
216 213 echo "Changed manifests to import:"
217 214 for m in $manifests; do echo " $m"; done
218 215 fi
219 216
220 217 #
221 218 # Upon boot, attempt to move the repository to tmpfs.
222 219 #
223 220 if [ -z "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ]; then
224 221 /usr/sbin/svcadm _smf_repository_switch fast
225 222 fi
226 223
227 224 #
228 225 # Import the manifests while giving a running display of imports on
229 226 # console, and a final count in the logfile.
230 227 #
231 228 dirs="$nonsite_dirs"
232 229 [ -d "$basedir/site" ] && dirs="$dirs $basedir/site"
233 230
234 231 if [ "$console_print" = "true" ]; then
235 232 $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1
236 233 else
237 234 $X /usr/sbin/svccfg import $dirs > $logf 2>&1
238 235 fi
239 236
240 237 grep "Loaded .*. smf(5) service descriptions" $logf > /dev/null 2>&1
241 238 if [ $? -eq 0 ]; then
242 239 activity=true
243 240 fi
244 241
245 242 if [ -s $logf ]; then
246 243 grep "smf(5) service descriptions failed to load" $logf > /dev/null 2>&1
247 244 failures=$?
248 245 if [ $failures -eq 0 ]; then
249 246 echo "svccfg warnings:"
250 247 fi
251 248 cat $logf
252 249
253 250 if [ $failures -eq 0 -a "$console_print" = "true" ]; then
254 251 msg="svccfg import warnings. See"
255 252 msg="$msg /var/svc/log/system-manifest-import:default.log ."
256 253 echo $msg > /dev/msglog
257 254 fi
258 255 fi
259 256 rm -f $logf
260 257 }
261 258
262 259 #
263 260 # 3. Profile application. We must create the platform profile upon
264 261 # first boot, as we may be a diskless client of a platform or
265 262 # architecture distinct from our NFS server.
266 263 #
267 264 # Generic and platform profiles are only supported in /etc.
268 265 #
269 266 function apply_profile {
270 267 #
271 268 # If smf/manifest doesn't have any profile under /etc/var/profile,
272 269 # this is very likely an import after upgrade so call
273 270 # preserve_system_profiles in that case.
274 271 #
275 272 LC_ALL=C pl=`/usr/bin/uname -i | /usr/bin/tr , _`
276 273 pln="etc_svc_profile_platform_${pl}_xml"
277 274
278 275 LC_ALL=C plm=`/usr/bin/uname -m | /usr/bin/tr , _`
279 276 [ $plm != $pl ] && plmn="etc_svc_profile_platform_${plm}_xml"
280 277
281 278 preserve_profiles=1
282 279 for prof in $pln $plmn etc_svc_profile_platform_none_xml \
283 280 etc_svc_profile_generic_limited_net_xml \
284 281 etc_svc_profile_generic_open_xml; do
285 282 if /usr/bin/svcprop -p $prof smf/manifest >/dev/null 2>&1
286 283 then
287 284 preserve_profiles=0
288 285 break
289 286 fi
290 287 done
291 288
292 289 if [ $preserve_profiles -eq 1 ]; then
293 290 echo "/etc/svc system profiles not found: upgrade system profiles"
294 291 preserve_system_profiles || return
295 292 fi
296 293
297 294 typeset prefix="/etc/svc/profile"
298 295 svccfg_apply $prefix/generic.xml
299 296 if [ ! -f $prefix/platform.xml ]; then
300 297 this_karch=`uname -m`
301 298 this_plat=`uname -i`
302 299
303 300 if [ -f $prefix/platform_$this_plat.xml ]; then
304 301 platform_profile=platform_$this_plat.xml
305 302 elif [ -f $prefix/platform_$this_karch.xml ]; then
306 303 platform_profile=platform_$this_karch.xml
307 304 else
308 305 platform_profile=platform_none.xml
309 306 fi
310 307
311 308 ln -s $platform_profile $prefix/platform.xml
312 309 fi
313 310
314 311 svccfg_apply $prefix/platform.xml
315 312 }
316 313
317 314 #
318 315 # 4. Upgrade handling. The upgrade file generally consists of a series
319 316 # of svcadm(1M) and svccfg(1M) commands.
320 317 #
321 318 function handle_upgrade {
322 319
323 320 [ -f /var/svc/profile/upgrade ] && activity=true
324 321
325 322 (
326 323 unset SVCCFG_CHECKHASH
327 324
328 325 if [ -f /var/svc/profile/upgrade ]; then
329 326 . /var/svc/profile/upgrade
330 327
331 328 /usr/bin/mv /var/svc/profile/upgrade \
332 329 /var/svc/profile/upgrade.app.`date +\%Y\%m\%d\%H\%M\%S`
333 330 fi
334 331
335 332 #
336 333 # Rename the datalink upgrade script file. This script is used in the
337 334 # network/physical service to upgrade datalink configuration, but
338 335 # the file cannot be renamed until now (when the file system becomes
339 336 # read-write).
340 337 #
341 338 datalink_script=/var/svc/profile/upgrade_datalink
342 339 if [ -f "${datalink_script}" ]; then
343 340 /usr/bin/mv "${datalink_script}" \
344 341 "${datalink_script}".app.`date +\%Y\%m\%d\%H\%M\%S`
345 342 fi
346 343 )
347 344 }
348 345
349 346 #
350 347 # 5. Giving administrator the final say, apply site.xml profile and profiles
351 348 # under /etc/svc/profile/site directory.
352 349 #
353 350 function apply_site_profile {
354 351 typeset prefix="$1"
355 352 [ -f $prefix/site.xml ] && svccfg_apply $prefix/site.xml
356 353
357 354 if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc/svc/profile" ]; then
358 355 svccfg_apply $PROFILE_DIR_SITE
359 356 fi
360 357 }
361 358
362 359 #
363 360 # 0b Cleanup deathrow
364 361 #
365 362 if [ "$early" = "false" ];then
366 363 deathrow=/etc/svc/deathrow
367 364 if [ -s $deathrow ];then
368 365 #
369 366 # svc.startd has unconfigured the services found in deathrow,
370 367 # clean them now.
371 368 #
372 369 while read fmri mfst pkgname; do
373 370 # Delete services and instances from the deathrow file.
374 371 /usr/sbin/svccfg delete -f $fmri >/dev/null 2>&1
375 372 # Remove deathrow manifest hash.
376 373 /usr/sbin/svccfg delhash -d $mfst >/dev/null 2>&1
377 374 done < $deathrow
378 375 /usr/bin/mv $deathrow $deathrow.old
379 376 fi
380 377 fi
381 378
382 379 SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH
383 380
384 381 #
385 382 # 0c Clean up repository
386 383 #
387 384 if [ "$early" = "false" ]; then
388 385 if [ -z "$X" ] && /usr/bin/svcprop smf/manifest 2>/dev/null |
389 386 /usr/bin/grep '^ar_svc_[^/]*/md5sum opaque ' >/dev/null
390 387 then
391 388 set -- `
392 389 /usr/bin/svcprop smf/manifest 2>/dev/null |
393 390 /usr/bin/grep '^ar_svc[^/]*/md5sum opaque ' |
394 391 /usr/bin/tr '/' ' ' |
395 392 while read pg prop type value; do
396 393 echo "$pg/$value"
397 394 done
398 395 `
399 396 backup=`echo "$#/$#" | sed 's/.//g'`
400 397 fwidth=`echo "$#\c" | wc -c`
401 398
402 399 echo "Converting obsolete repository entries: \c" > /dev/msglog
403 400 i=1; n=$#
404 401 while [ $# -gt 0 ]; do
405 402 printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog
406 403 echo $1 | sed 's:/: :' | (
407 404 read pg value
408 405
409 406 (echo "select /smf/manifest"; echo "delpg v$pg") |
410 407 /usr/sbin/svccfg 2>/dev/null >/dev/null
411 408 (echo "select /smf/manifest"; echo "delpg $pg") |
412 409 /usr/sbin/svccfg 2>/dev/null >/dev/null
413 410 (echo "select /smf/manifest";
414 411 echo "addpg v$pg framework") |
415 412 /usr/sbin/svccfg 2>/dev/null >/dev/null
416 413 (echo "select /smf/manifest";
417 414 echo "setprop v$pg/md5sum = opaque: $value") |
418 415 /usr/sbin/svccfg 2>/dev/null >/dev/null
419 416 )
420 417 i=`expr $i + 1`
421 418 shift
422 419 echo "$backup\c" > /dev/msglog
423 420 done
424 421 echo > /dev/msglog
425 422 echo "Converted $n obsolete repository entries"
426 423 activity=true
427 424 fi
428 425
429 426 fi
430 427
431 428 #
432 429 # If the alternate repository and directory are specified, simply set
433 430 # SVCCFG_REPOSITORY env, run svccfg import on the given directory, and
434 431 # exit.
435 432 #
436 433 if [ -n "$ALT_REPOSITORY" -a -n "$ALT_MFST_DIR" ]; then
437 434 SVCCFG_REPOSITORY=$ALT_REPOSITORY export SVCCFG_REPOSITORY
438 435 import_manifests "$ALT_MFST_DIR" false
439 436 unset SVCCFG_REPOSITORY
440 437 exit 0
441 438 fi
442 439
443 440 #
444 441 # Call import and apply profiles here
445 442 #
446 443 if [ "$early" = "true" ]; then
447 444 import_manifests "/lib/svc/manifest" true
448 445 apply_profile
449 446 apply_site_profile "/etc/svc/profile"
450 447 else
451 448 #
452 449 # Process both /lib/svc/manifest and /var/svc/manifest
453 450 # during late manifest-import
454 451 #
455 452 # First import the manifests
456 453 #
457 454 import_manifests "/lib/svc/manifest" true
458 455 import_manifests "/var/svc/manifest" true
459 456
460 457 #
461 458 # Apply profiles
462 459 #
463 460 apply_profile
464 461 apply_site_profile "/etc/svc/profile"
465 462
466 463 #
467 464 # Run the upgrade script
468 465 #
469 466 handle_upgrade
470 467 apply_site_profile "/var/svc/profile"
471 468 fi
472 469
473 470
474 471 #
475 472 # 6. Final actions.
476 473 #
477 474
478 475 if $activity; then
479 476 /usr/sbin/svcadm _smf_backup "manifest_import" || true
480 477 fi
481 478
482 479 #
483 480 # If the filesystem is NOT read only then move the repo back to perm
484 481 # There is no care wether the switch was made or not, but just want
485 482 # to move it. If it is already perm this does not affect anything
486 483 # at least on the surface. REALLY want to improve on this...
487 484 #
488 485 touch /etc/svc/smf_rwtest.$$ > /dev/null 2>&1
489 486 if [ $? -eq 0 ]; then
490 487 rm -f /etc/svc/smf_rwtest.$$
491 488 /usr/sbin/svcadm _smf_repository_switch perm || { \
492 489 echo "Repository switch back operation failed, \c"
493 490 echo "please check the system log for the"
494 491 echo "possible fatal error messages."
495 492 exit $SMF_EXIT_ERR_FATAL
496 493 }
497 494 fi
498 495
499 496 if $activity; then
500 497 /usr/sbin/svccfg cleanup | /usr/bin/tee /dev/msglog
501 498 else
502 499 cleanup_needwork
503 500 if [ $? -ne 0 ]; then
504 501 /usr/sbin/svccfg cleanup -a | /usr/bin/tee /dev/msglog
505 502 fi
506 503 fi
507 504
508 505 exit 0
↓ open down ↓ |
412 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX