1#!/sbin/sh 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License, Version 1.0 only 7# (the "License"). You may not use this file except in compliance 8# with the License. 9# 10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11# or http://www.opensolaris.org/os/licensing. 12# See the License for the specific language governing permissions 13# and limitations under the License. 14# 15# When distributing Covered Code, include this CDDL HEADER in each 16# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17# If applicable, add the following below this CDDL HEADER, with the 18# fields enclosed by brackets "[]" replaced with your own identifying 19# information: Portions Copyright [yyyy] [name of copyright owner] 20# 21# CDDL HEADER END 22# 23# 24# Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27#ident "%Z%%M% %I% %E% SMI" 28 29# 0. Initialization. 30 31[ -f /lib/svc/share/smf_include.sh ] || exit 1 32 33activity=false 34 35X= 36while getopts n opt; do 37 case $opt in 38 n) X=echo;; 39 ?) echo "Usage: /lib/svc/method/manifest-import [-n]\n" 40 exit 2;; 41 esac 42done 43 44svccfg_apply () { 45 $X /usr/sbin/svccfg apply $1 46 if [ $? -ne 0 ]; then 47 echo "WARNING: svccfg apply $1 failed" | tee /dev/msglog 48 fi 49} 50 51svccfg_import () { 52 $X /usr/sbin/svccfg import $1 2>>/tmp/manifest_import.$$ 53 if [ $? -ne 0 ]; then 54 echo > /dev/msglog 55 echo "WARNING: svccfg import $1 failed" | tee /dev/msglog 56 fi 57} 58 59prophist_upgrade () { 60 # 61 # A property has changed in the manifest that we wish to propagate into 62 # the repository during manifest import. We don't want to pollute 63 # manifests with overrides, so handle explicitly here. 64 # 65 fmri=$1 66 pgrp=$2 67 prop=$3 68 nval=$4 69 shift 4 70 71 /lib/svc/bin/prophist upgrade -e $fmri -g $pgrp -p $prop -n "$nval" \ 72 "$@" 73 [ $? = 0 ] && instance_refresh $fmri 74} 75 76prophist_override () { 77 # 78 # A property has changed in the manifest that we wish to propagate 79 # into the repository during manifest import. 80 # 81 fmri=$1 82 pgrp=$2 83 prop=$3 84 nval=$4 85 86 /lib/svc/bin/prophist overwrite -e $fmri -g $pgrp -p $prop -n "$nval" 87 [ $? = 0 ] && instance_refresh $fmri 88} 89 90prophist_delete_svc_pg () { 91 # 92 # Certain property groups have migrated from the service level to the 93 # instance level. We don't care if they are at both, as the instance 94 # level will trump. But having neither could be bad. So check and if 95 # the given pg exists at both levels, delete the service-level one only. 96 # 97 service=$1 98 instance=$2 99 property_group=$3 100 101 /usr/bin/svcprop -q -p $property_group $service 102 res1=$? 103 /usr/bin/svcprop -q -c -p $property_group $service:$instance 104 res2=$? 105 if [ $res1 -eq 0 -a $res2 -eq 0 ]; then 106 /lib/svc/bin/prophist delete -e $service -g $property_group 107 instance_refresh $service:$instance 108 fi 109} 110 111prophist_delete_dependency () { 112 # 113 # Some services have stale dependencies that need to be removed. 114 # This is done by removing the dependency property group. 115 # 116 fmri=$1 117 property_group=$2 118 119 /usr/bin/svcprop -q -c -p $property_group $fmri 120 if [ $? -eq 0 ]; then 121 /lib/svc/bin/prophist delete -e $fmri -g $property_group 122 else 123 [ -n "$_MFST_DEBUG" ] && \ 124 echo "Dependency $property_group not defined on $fmri" 125 fi 126} 127 128prophist_delete_pg () { 129 # Delete obsolete property groups from old manifests. Instances 130 # should be refreshed for changes to take effect. 131 fmri=$1 132 pg=$2 133 134 /usr/bin/svcprop -Cqp $pg $fmri && 135 /lib/svc/bin/prophist delete -e $fmri -g $pg 136} 137 138prophist_addprop () { 139 # 140 # If a property doesn't exist, create it. Instances should be 141 # refreshed for changes to take effect. 142 # 143 if [ $# -lt 6 ]; then 144 echo "prophist_addprop(): Insufficient arguments ($*)." 145 exit 1 146 fi 147 148 fmri=$1 149 /usr/bin/svcprop -q $fmri || return 150 151 pg=$2 152 pgtype=$3 153 prop=$4 154 155 /usr/bin/svcprop -Cqp $pg/$prop $fmri && return 156 157 shift 4 158 159 /usr/bin/svcprop -Cqp $pg $fmri || \ 160 /usr/sbin/svccfg -s $fmri addpg $pg $pgtype 161 /usr/sbin/svccfg -s $fmri setprop $pg/$prop = $* 162} 163 164prophist_addmeth () { 165 # 166 # If a method doesn't exist, create it. Instances should be refreshed 167 # for changes to take effect. 168 # 169 if [ $# -ne 4 ]; then 170 echo "prophist_addmeth(): Insufficient arguments ($*)" 171 exit 1 172 fi 173 174 fmri=$1 175 /usr/bin/svcprop -q $fmri || return 176 177 name=$2 178 /usr/bin/svcprop -Cqp $name $fmri && return 179 180 exec=$3 181 to=$4 182 183 /usr/sbin/svccfg -s $fmri <<END 184 addpg $name method 185 setprop $name/type = astring: method 186 setprop $name/exec = astring: "$exec" 187 setprop $name/timeout_seconds = count: $to 188END 189} 190 191prophist_adddep () { 192 # 193 # If a dependency doesn't exist, create it. Instances should be 194 # refreshed for changes to take effect. 195 # 196 if [ $# -lt 6 ]; then 197 echo "prophist_adddep(): Insufficient arguments ($*)" 198 exit 1 199 fi 200 201 fmri=$1 202 /usr/bin/svcprop -q $fmri || return 203 204 name=$2 205 /usr/bin/svcprop -Cqp $name $fmri && return 206 207 type=$3 208 group=$4 209 ro=$5 210 shift 5 211 212 /usr/sbin/svccfg -s $fmri <<END 213 addpg $name dependency 214 setprop $name/type = astring: $type 215 setprop $name/grouping = astring: $group 216 setprop $name/restart_on = astring: $ro 217 setprop $name/entities = fmri: $* 218END 219} 220 221prophist_adddpt () { 222 # 223 # If a dependent doesn't exist, create it. Instances should be 224 # refresh for changes to take effect. 225 # 226 if [ $# -ne 5 ]; then 227 echo "prophist_adddpt(): Incorrect arguments ($*).\n" 228 exit 1 229 fi 230 231 fmri=$1 232 /usr/bin/svcprop -q $fmri || return 233 234 name=$2 235 /usr/bin/svcprop -Cqp dependents/$name $fmri && return 236 237 group=$3 238 ro=$4 239 target=$5 240 241 prophist_addprop $fmri dependents framework $name fmri: $target 242 prophist_adddep $target $name service $group $ro $fmri 243} 244 245instance_refresh () { 246 echo $1 >> /etc/svc/volatile/refreshes 247} 248 249refresh_instances () { 250 [ -r /etc/svc/volatile/refreshes ] && { 251 sort -u /etc/svc/volatile/refreshes | xargs -l svcadm refresh 252 } 253} 254 255instance_clear () { 256 echo $1 >> /etc/svc/volatile/clears 257} 258 259clear_conditionally () { 260 [ "`/usr/bin/svcprop -p restarter/state $1`" = "maintenance" ] && \ 261 /usr/sbin/svcadm clear $1 262} 263 264clear_instances () { 265 [ -r /etc/svc/volatile/clears ] && { 266 for inst in `/usr/bin/sort -u /etc/svc/volatile/clears`; do 267 clear_conditionally $inst 268 done 269 } 270} 271 272prepare_last_import () { 273 # Preserve the five hashes for the profiles: generic (two 274 # cases), platform (uname -i, uname -m outputs), and site. 275 276 gn="var_svc_profile_generic_open_xml" 277 gh=`/usr/bin/svcprop -p ${gn}/md5sum smf/manifest 2>/dev/null` 278 [ $? = 0 ] || gh="" 279 280 gln="var_svc_profile_generic_limited_net_xml" 281 glh=`/usr/bin/svcprop -p ${gln}/md5sum smf/manifest 2>/dev/null` 282 [ $? = 0 ] || glh="" 283 284 LC_ALL=C pl=`/usr/bin/uname -i | /usr/bin/tr , _` 285 pln="var_svc_profile_platform_${pl}_xml" 286 plh=`/usr/bin/svcprop -p ${pln}/md5sum smf/manifest 2>/dev/null` 287 [ $? = 0 ] || plh="" 288 289 LC_ALL=C plm=`/usr/bin/uname -m | /usr/bin/tr , _` 290 if [ $plm != $pl ]; then 291 plmn="var_svc_profile_platform_${plm}_xml" 292 plmh=`/usr/bin/svcprop -p ${plmn}/md5sum smf/manifest \ 293 2>/dev/null` 294 [ $? = 0 ] || plmh="" 295 else 296 plmh="" 297 fi 298 299 sn="var_svc_profile_site_xml" 300 sh=`/usr/bin/svcprop -p $sn/md5sum smf/manifest 2>/dev/null` 301 [ $? = 0 ] || sh="" 302 303 # Remove all manifest hashes. 304 /usr/sbin/svccfg delete smf/manifest 305 306 # Restore smf/manifest and hash values. 307 /usr/sbin/svccfg add smf/manifest 308 [ -n "$gh" ] && { 309 echo "Preserving generic hash ($gh)." 310 /usr/sbin/svccfg -s smf/manifest addpg ${gn} framework 311 /usr/sbin/svccfg -s smf/manifest setprop ${gn}/md5sum = \ 312 opaque: $gh 313 } 314 [ -n "$glh" ] && { 315 echo "Preserving generic_limited hash ($glh)." 316 /usr/sbin/svccfg -s smf/manifest addpg ${gln} framework 317 /usr/sbin/svccfg -s smf/manifest setprop ${gln}/md5sum = \ 318 opaque: $glh 319 } 320 [ -n "$plh" ] && { 321 echo "Preserving platform hash ($plh)." 322 /usr/sbin/svccfg -s smf/manifest addpg $pln framework 323 /usr/sbin/svccfg -s smf/manifest setprop $pln/md5sum = \ 324 opaque: $plh 325 } 326 [ -n "$plmh" ] && { 327 echo "Preserving platform hash ($plmh)." 328 /usr/sbin/svccfg -s smf/manifest addpg $plmn framework 329 /usr/sbin/svccfg -s smf/manifest setprop $plmn/md5sum = \ 330 opaque: $plmh 331 } 332 [ -n "$sh" ] && { 333 echo "Preserving site hash ($sh)." 334 /usr/sbin/svccfg -s smf/manifest addpg $sn framework 335 /usr/sbin/svccfg -s smf/manifest setprop $sn/md5sum = \ 336 opaque: $sh 337 } 338} 339 340SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH 341 342# 343# 0. Clean up repository 344# 345if [ -z "$X" ] && /usr/bin/svcprop smf/manifest 2>/dev/null | 346 /usr/bin/grep '^ar_svc_[^/]*/md5sum opaque ' >/dev/null 347then 348 set -- ` 349 /usr/bin/svcprop smf/manifest 2>/dev/null | 350 /usr/bin/grep '^ar_svc[^/]*/md5sum opaque ' | 351 /usr/bin/tr '/' ' ' | 352 while read pg prop type value; do 353 echo "$pg/$value" 354 done 355 ` 356 backup=`echo "$#/$#" | sed 's/.//g'` 357 fwidth=`echo "$#\c" | wc -c` 358 359 echo "Converting obsolete repository entries: \c" > /dev/msglog 360 i=1; n=$# 361 while [ $# -gt 0 ]; do 362 printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog 363 echo $1 | sed 's:/: :' | ( 364 read pg value 365 366 (echo "select /smf/manifest"; echo "delpg v$pg") | 367 /usr/sbin/svccfg 2>/dev/null >/dev/null 368 (echo "select /smf/manifest"; echo "delpg $pg") | 369 /usr/sbin/svccfg 2>/dev/null >/dev/null 370 (echo "select /smf/manifest"; 371 echo "addpg v$pg framework") | 372 /usr/sbin/svccfg 2>/dev/null >/dev/null 373 (echo "select /smf/manifest"; 374 echo "setprop v$pg/md5sum = opaque: $value") | 375 /usr/sbin/svccfg 2>/dev/null >/dev/null 376 ) 377 i=`expr $i + 1` 378 shift 379 echo "$backup\c" > /dev/msglog 380 done 381 echo > /dev/msglog 382 echo "Converted $n obsolete repository entries" 383 activity=true 384fi 385 386# 387# If no last-import snapshots are present on critical services, then we are 388# creating the last-import snapshots for the first time post upgrade. 389# 390create_last_import=1 391for svc in single-user multi-user multi-user-server; do 392 if /usr/bin/svcprop -s last-import svc:/milestone/$svc:default \ 393 >/dev/null 2>&1 394 then 395 create_last_import= 396 break 397 fi 398done 399 400if [ $create_last_import ]; then 401 echo "Last import snapshots absent; preparing for re-import" 402 prepare_last_import 403 404 # 405 # Apply property history files. 406 # 407 echo "Upgrade detected; applying property history" 408 for phist in /var/svc/profile/prophist.*; do 409 /lib/svc/bin/prophist hash $phist 410 if [ $? = 3 ]; then 411 echo "Sourcing $phist" 412 . $phist 413 fi 414 done 415 416 /usr/bin/rm -f /var/svc/profile/.upgrade_prophist 417fi 418 419# 420# 2. Manifest import. Application directories first, then 421# site-specific manifests. 422# 423nonsite_dirs=`/usr/bin/find /var/svc/manifest/* -name site -prune -o -type d \ 424 -print -prune` 425 426nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs` 427site_manifests=`/lib/svc/bin/mfstscan /var/svc/manifest/site` 428 429manifests="$nonsite_manifests $site_manifests" 430 431[ -n "$_MFST_DEBUG" ] && { 432 echo "Changed manifests to import:" 433 for m in $manifests; do echo " $m"; done 434} 435 436# 437# 2b. Import the manifests while giving a running display of imports on 438# console, and a final count in the logfile. 439# 440if [ -n "$nonsite_manifests" -o -n "$site_manifests" ]; then 441 rm -f /tmp/manifest_import.$$ 442 443 set -- $manifests 444 backup=`echo "$#/$#" | sed 's/.//g'` 445 fwidth=`echo "$#\c" | wc -c` 446 447 echo "Loading smf(5) service descriptions: \c" > /dev/msglog 448 449 i=1; n=$# 450 while [ $# -gt 0 ]; do 451 printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog 452 svccfg_import $1 453 i=`expr $i + 1` 454 shift 455 echo "$backup\c" > /dev/msglog 456 done 457 458 echo > /dev/msglog 459 echo "Loaded $n smf(5) service descriptions" 460 activity=true 461 462 if [ -s /tmp/manifest_import.$$ ]; then 463 echo "svccfg warnings:" 464 cat /tmp/manifest_import.$$ 465 466 msg="svccfg import warnings. See" 467 msg="$msg /var/svc/log/system-manifest-import:default.log ." 468 echo $msg > /dev/msglog 469 fi 470 rm -f /tmp/manifest_import.$$ 471fi 472 473# 474# 3. Profile application. We must create the platform profile upon 475# first boot, as we may be a diskless client of a platform or 476# architecture distinct from our NFS server. 477# 478svccfg_apply /var/svc/profile/generic.xml 479 480if [ ! -f /var/svc/profile/platform.xml ]; then 481 this_karch=`uname -m` 482 this_plat=`uname -i` 483 484 if [ -f /var/svc/profile/platform_$this_plat.xml ]; then 485 platform_profile=platform_$this_plat.xml 486 elif [ -f /var/svc/profile/platform_$this_karch.xml ]; then 487 platform_profile=platform_$this_karch.xml 488 else 489 platform_profile=platform_none.xml 490 fi 491 492 ln -s $platform_profile /var/svc/profile/platform.xml 493fi 494 495svccfg_apply /var/svc/profile/platform.xml 496 497# 498# 4. Upgrade handling. The upgrade file generally consists of a series 499# of svcadm(1M) and svccfg(1M) commands. 500# 501( 502 unset SVCCFG_CHECKHASH 503 504 if [ -f /var/svc/profile/upgrade ]; then 505 . /var/svc/profile/upgrade 506 507 /usr/bin/mv /var/svc/profile/upgrade \ 508 /var/svc/profile/upgrade.app.`date +\%Y\%m\%d\%H\%M\%S` 509 activity=true 510 fi 511) 512 513# 514# 5. Site profile is applied last to give administrator the final say. 515# 516if [ -f /var/svc/profile/site.xml ]; then 517 svccfg_apply /var/svc/profile/site.xml 518fi 519 520# 521# 6. Final actions. 522# 523refresh_instances 524clear_instances 525 526if $activity; then 527 svcadm _smf_backup "manifest_import" || true 528fi 529 530exit 0 531