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