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 (the "License"). 7# You may not use this file except in compliance with the License. 8# 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. 13# 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] 19# 20# CDDL HEADER END 21# 22# 23# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26 27# 0a Initialization. 28 29[ -f /lib/svc/share/smf_include.sh ] || exit 1 30 31. /lib/svc/share/smf_include.sh 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 340# 341# 0b Cleanup deathrow 342# 343deathrow=/etc/svc/deathrow 344if [ -s $deathrow ];then 345 # 346 # svc.startd has unconfigured the services found in deathrow, 347 # clean them now. 348 # 349 while read fmri mfst pkgname; do 350 # Delete services and instances from the deathrow file. 351 /usr/sbin/svccfg delete -f $fmri >/dev/null 2>&1 352 # Remove deathrow manifest hash. 353 /usr/sbin/svccfg delhash -d $mfst >/dev/null 2>&1 354 done < $deathrow 355 /usr/bin/mv $deathrow $deathrow.old 356fi 357SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH 358 359# 360# 0c Clean up repository 361# 362if [ -z "$X" ] && /usr/bin/svcprop smf/manifest 2>/dev/null | 363 /usr/bin/grep '^ar_svc_[^/]*/md5sum opaque ' >/dev/null 364then 365 set -- ` 366 /usr/bin/svcprop smf/manifest 2>/dev/null | 367 /usr/bin/grep '^ar_svc[^/]*/md5sum opaque ' | 368 /usr/bin/tr '/' ' ' | 369 while read pg prop type value; do 370 echo "$pg/$value" 371 done 372 ` 373 backup=`echo "$#/$#" | sed 's/.//g'` 374 fwidth=`echo "$#\c" | wc -c` 375 376 echo "Converting obsolete repository entries: \c" > /dev/msglog 377 i=1; n=$# 378 while [ $# -gt 0 ]; do 379 printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog 380 echo $1 | sed 's:/: :' | ( 381 read pg value 382 383 (echo "select /smf/manifest"; echo "delpg v$pg") | 384 /usr/sbin/svccfg 2>/dev/null >/dev/null 385 (echo "select /smf/manifest"; echo "delpg $pg") | 386 /usr/sbin/svccfg 2>/dev/null >/dev/null 387 (echo "select /smf/manifest"; 388 echo "addpg v$pg framework") | 389 /usr/sbin/svccfg 2>/dev/null >/dev/null 390 (echo "select /smf/manifest"; 391 echo "setprop v$pg/md5sum = opaque: $value") | 392 /usr/sbin/svccfg 2>/dev/null >/dev/null 393 ) 394 i=`expr $i + 1` 395 shift 396 echo "$backup\c" > /dev/msglog 397 done 398 echo > /dev/msglog 399 echo "Converted $n obsolete repository entries" 400 activity=true 401fi 402 403# 404# If no last-import snapshots are present on critical services, then we are 405# creating the last-import snapshots for the first time post upgrade. 406# 407create_last_import=1 408for svc in single-user multi-user multi-user-server; do 409 if /usr/bin/svcprop -s last-import svc:/milestone/$svc:default \ 410 >/dev/null 2>&1 411 then 412 create_last_import= 413 break 414 fi 415done 416 417if [ $create_last_import ]; then 418 echo "Last import snapshots absent; preparing for re-import" 419 prepare_last_import 420 421 # 422 # Apply property history files. 423 # 424 echo "Upgrade detected; applying property history" 425 for phist in /var/svc/profile/prophist.*; do 426 /lib/svc/bin/prophist hash $phist 427 if [ $? = 3 ]; then 428 echo "Sourcing $phist" 429 . $phist 430 fi 431 done 432 433 /usr/bin/rm -f /var/svc/profile/.upgrade_prophist 434fi 435 436# 437# 2. Manifest import. Application directories first, then 438# site-specific manifests. 439# 440nonsite_dirs=`/usr/bin/find /var/svc/manifest/* -name site -prune -o -type d \ 441 -print -prune` 442 443nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs` 444site_manifests=`/lib/svc/bin/mfstscan /var/svc/manifest/site` 445 446manifests="$nonsite_manifests $site_manifests" 447 448[ -n "$_MFST_DEBUG" ] && { 449 echo "Changed manifests to import:" 450 for m in $manifests; do echo " $m"; done 451} 452 453# 454# 2b. Import the manifests while giving a running display of imports on 455# console, and a final count in the logfile. 456# 457if [ -n "$nonsite_manifests" -o -n "$site_manifests" ]; then 458 rm -f /tmp/manifest_import.$$ 459 460 set -- $manifests 461 backup=`echo "$#/$#" | sed 's/.//g'` 462 fwidth=`echo "$#\c" | wc -c` 463 464 echo "Loading smf(5) service descriptions: \c" > /dev/msglog 465 466 # 467 # Attempt of moving the repository to tmpfs. If that doesn't 468 # work, reset doswitch so we don't attempt switching back. 469 # 470 /usr/sbin/svcadm _smf_repository_switch fast 471 doswitch=$? 472 473 i=1; n=$# 474 while [ $# -gt 0 ]; do 475 printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog 476 svccfg_import $1 477 i=`expr $i + 1` 478 shift 479 echo "$backup\c" > /dev/msglog 480 done 481 482 # 483 # If switch back fails, exit with the fatal error code. 484 # Normally the failure indicates that there is a serious 485 # problem on the root file system such as file operation 486 # failure or repository access failure. 487 # 488 if [ $doswitch -eq 0 ]; then 489 /usr/sbin/svcadm _smf_repository_switch perm || { \ 490 echo "Repository switch back operation failed, \c" 491 echo "please check the system log for the" 492 echo "possible fatal error messages." 493 exit $SMF_EXIT_ERR_FATAL 494 } 495 fi 496 497 echo > /dev/msglog 498 echo "Loaded $n smf(5) service descriptions" 499 activity=true 500 501 if [ -s /tmp/manifest_import.$$ ]; then 502 echo "svccfg warnings:" 503 cat /tmp/manifest_import.$$ 504 505 msg="svccfg import warnings. See" 506 msg="$msg /var/svc/log/system-manifest-import:default.log ." 507 echo $msg > /dev/msglog 508 fi 509 rm -f /tmp/manifest_import.$$ 510fi 511 512# 513# 3. Profile application. We must create the platform profile upon 514# first boot, as we may be a diskless client of a platform or 515# architecture distinct from our NFS server. 516# 517svccfg_apply /var/svc/profile/generic.xml 518 519if [ ! -f /var/svc/profile/platform.xml ]; then 520 this_karch=`uname -m` 521 this_plat=`uname -i` 522 523 if [ -f /var/svc/profile/platform_$this_plat.xml ]; then 524 platform_profile=platform_$this_plat.xml 525 elif [ -f /var/svc/profile/platform_$this_karch.xml ]; then 526 platform_profile=platform_$this_karch.xml 527 else 528 platform_profile=platform_none.xml 529 fi 530 531 ln -s $platform_profile /var/svc/profile/platform.xml 532fi 533 534svccfg_apply /var/svc/profile/platform.xml 535 536# 537# 4. Upgrade handling. The upgrade file generally consists of a series 538# of svcadm(1M) and svccfg(1M) commands. 539# 540( 541 unset SVCCFG_CHECKHASH 542 543 if [ -f /var/svc/profile/upgrade ]; then 544 . /var/svc/profile/upgrade 545 546 /usr/bin/mv /var/svc/profile/upgrade \ 547 /var/svc/profile/upgrade.app.`date +\%Y\%m\%d\%H\%M\%S` 548 activity=true 549 fi 550 551 # 552 # Rename the datalink upgrade script file. This script is used in the 553 # network/physical service to upgrade datalink configuration, but 554 # the file cannot be renamed until now (when the file system becomes 555 # read-write). 556 # 557 datalink_script=/var/svc/profile/upgrade_datalink 558 if [ -f "${datalink_script}" ]; then 559 /usr/bin/mv "${datalink_script}" \ 560 "${datalink_script}".app.`date +\%Y\%m\%d\%H\%M\%S` 561 fi 562) 563 564# 565# 5. Site profile is applied last to give administrator the final say. 566# 567if [ -f /var/svc/profile/site.xml ]; then 568 svccfg_apply /var/svc/profile/site.xml 569fi 570 571# 572# 6. Final actions. 573# 574refresh_instances 575clear_instances 576 577if $activity; then 578 svcadm _smf_backup "manifest_import" || true 579fi 580 581exit 0 582