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