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