#!/sbin/sh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # 0a Initialization. [ -f /lib/svc/share/smf_include.sh ] || exit 1 . /lib/svc/share/smf_include.sh activity=false X= while getopts n opt; do case $opt in n) X=echo;; ?) echo "Usage: /lib/svc/method/manifest-import [-n]\n" exit 2;; esac done svccfg_apply () { $X /usr/sbin/svccfg apply $1 if [ $? -ne 0 ]; then echo "WARNING: svccfg apply $1 failed" | tee /dev/msglog fi } svccfg_import () { $X /usr/sbin/svccfg import $1 2>>/tmp/manifest_import.$$ if [ $? -ne 0 ]; then echo > /dev/msglog echo "WARNING: svccfg import $1 failed" | tee /dev/msglog fi } prophist_upgrade () { # # A property has changed in the manifest that we wish to propagate into # the repository during manifest import. We don't want to pollute # manifests with overrides, so handle explicitly here. # fmri=$1 pgrp=$2 prop=$3 nval=$4 shift 4 /lib/svc/bin/prophist upgrade -e $fmri -g $pgrp -p $prop -n "$nval" \ "$@" [ $? = 0 ] && instance_refresh $fmri } prophist_override () { # # A property has changed in the manifest that we wish to propagate # into the repository during manifest import. # fmri=$1 pgrp=$2 prop=$3 nval=$4 /lib/svc/bin/prophist overwrite -e $fmri -g $pgrp -p $prop -n "$nval" [ $? = 0 ] && instance_refresh $fmri } prophist_delete_svc_pg () { # # Certain property groups have migrated from the service level to the # instance level. We don't care if they are at both, as the instance # level will trump. But having neither could be bad. So check and if # the given pg exists at both levels, delete the service-level one only. # service=$1 instance=$2 property_group=$3 /usr/bin/svcprop -q -p $property_group $service res1=$? /usr/bin/svcprop -q -c -p $property_group $service:$instance res2=$? if [ $res1 -eq 0 -a $res2 -eq 0 ]; then /lib/svc/bin/prophist delete -e $service -g $property_group instance_refresh $service:$instance fi } prophist_delete_dependency () { # # Some services have stale dependencies that need to be removed. # This is done by removing the dependency property group. # fmri=$1 property_group=$2 /usr/bin/svcprop -q -c -p $property_group $fmri if [ $? -eq 0 ]; then /lib/svc/bin/prophist delete -e $fmri -g $property_group else [ -n "$_MFST_DEBUG" ] && \ echo "Dependency $property_group not defined on $fmri" fi } prophist_delete_pg () { # Delete obsolete property groups from old manifests. Instances # should be refreshed for changes to take effect. fmri=$1 pg=$2 /usr/bin/svcprop -Cqp $pg $fmri && /lib/svc/bin/prophist delete -e $fmri -g $pg } prophist_addprop () { # # If a property doesn't exist, create it. Instances should be # refreshed for changes to take effect. # if [ $# -lt 6 ]; then echo "prophist_addprop(): Insufficient arguments ($*)." exit 1 fi fmri=$1 /usr/bin/svcprop -q $fmri || return pg=$2 pgtype=$3 prop=$4 /usr/bin/svcprop -Cqp $pg/$prop $fmri && return shift 4 /usr/bin/svcprop -Cqp $pg $fmri || \ /usr/sbin/svccfg -s $fmri addpg $pg $pgtype /usr/sbin/svccfg -s $fmri setprop $pg/$prop = $* } prophist_addmeth () { # # If a method doesn't exist, create it. Instances should be refreshed # for changes to take effect. # if [ $# -ne 4 ]; then echo "prophist_addmeth(): Insufficient arguments ($*)" exit 1 fi fmri=$1 /usr/bin/svcprop -q $fmri || return name=$2 /usr/bin/svcprop -Cqp $name $fmri && return exec=$3 to=$4 /usr/sbin/svccfg -s $fmri <> /etc/svc/volatile/refreshes } refresh_instances () { [ -r /etc/svc/volatile/refreshes ] && { sort -u /etc/svc/volatile/refreshes | xargs -l svcadm refresh } } instance_clear () { echo $1 >> /etc/svc/volatile/clears } clear_conditionally () { [ "`/usr/bin/svcprop -p restarter/state $1`" = "maintenance" ] && \ /usr/sbin/svcadm clear $1 } clear_instances () { [ -r /etc/svc/volatile/clears ] && { for inst in `/usr/bin/sort -u /etc/svc/volatile/clears`; do clear_conditionally $inst done } } prepare_last_import () { # Preserve the five hashes for the profiles: generic (two # cases), platform (uname -i, uname -m outputs), and site. gn="var_svc_profile_generic_open_xml" gh=`/usr/bin/svcprop -p ${gn}/md5sum smf/manifest 2>/dev/null` [ $? = 0 ] || gh="" gln="var_svc_profile_generic_limited_net_xml" glh=`/usr/bin/svcprop -p ${gln}/md5sum smf/manifest 2>/dev/null` [ $? = 0 ] || glh="" LC_ALL=C pl=`/usr/bin/uname -i | /usr/bin/tr , _` pln="var_svc_profile_platform_${pl}_xml" plh=`/usr/bin/svcprop -p ${pln}/md5sum smf/manifest 2>/dev/null` [ $? = 0 ] || plh="" LC_ALL=C plm=`/usr/bin/uname -m | /usr/bin/tr , _` if [ $plm != $pl ]; then plmn="var_svc_profile_platform_${plm}_xml" plmh=`/usr/bin/svcprop -p ${plmn}/md5sum smf/manifest \ 2>/dev/null` [ $? = 0 ] || plmh="" else plmh="" fi sn="var_svc_profile_site_xml" sh=`/usr/bin/svcprop -p $sn/md5sum smf/manifest 2>/dev/null` [ $? = 0 ] || sh="" # Remove all manifest hashes. /usr/sbin/svccfg delete smf/manifest # Restore smf/manifest and hash values. /usr/sbin/svccfg add smf/manifest [ -n "$gh" ] && { echo "Preserving generic hash ($gh)." /usr/sbin/svccfg -s smf/manifest addpg ${gn} framework /usr/sbin/svccfg -s smf/manifest setprop ${gn}/md5sum = \ opaque: $gh } [ -n "$glh" ] && { echo "Preserving generic_limited hash ($glh)." /usr/sbin/svccfg -s smf/manifest addpg ${gln} framework /usr/sbin/svccfg -s smf/manifest setprop ${gln}/md5sum = \ opaque: $glh } [ -n "$plh" ] && { echo "Preserving platform hash ($plh)." /usr/sbin/svccfg -s smf/manifest addpg $pln framework /usr/sbin/svccfg -s smf/manifest setprop $pln/md5sum = \ opaque: $plh } [ -n "$plmh" ] && { echo "Preserving platform hash ($plmh)." /usr/sbin/svccfg -s smf/manifest addpg $plmn framework /usr/sbin/svccfg -s smf/manifest setprop $plmn/md5sum = \ opaque: $plmh } [ -n "$sh" ] && { echo "Preserving site hash ($sh)." /usr/sbin/svccfg -s smf/manifest addpg $sn framework /usr/sbin/svccfg -s smf/manifest setprop $sn/md5sum = \ opaque: $sh } } # # 0b Cleanup deathrow # deathrow=/etc/svc/deathrow if [ -s $deathrow ];then # # svc.startd has unconfigured the services found in deathrow, # clean them now. # while read fmri mfst pkgname; do # Delete services and instances from the deathrow file. /usr/sbin/svccfg delete -f $fmri >/dev/null 2>&1 # Remove deathrow manifest hash. /usr/sbin/svccfg delhash -d $mfst >/dev/null 2>&1 done < $deathrow /usr/bin/mv $deathrow $deathrow.old fi SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH # # 0c Clean up repository # if [ -z "$X" ] && /usr/bin/svcprop smf/manifest 2>/dev/null | /usr/bin/grep '^ar_svc_[^/]*/md5sum opaque ' >/dev/null then set -- ` /usr/bin/svcprop smf/manifest 2>/dev/null | /usr/bin/grep '^ar_svc[^/]*/md5sum opaque ' | /usr/bin/tr '/' ' ' | while read pg prop type value; do echo "$pg/$value" done ` backup=`echo "$#/$#" | sed 's/.//g'` fwidth=`echo "$#\c" | wc -c` echo "Converting obsolete repository entries: \c" > /dev/msglog i=1; n=$# while [ $# -gt 0 ]; do printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog echo $1 | sed 's:/: :' | ( read pg value (echo "select /smf/manifest"; echo "delpg v$pg") | /usr/sbin/svccfg 2>/dev/null >/dev/null (echo "select /smf/manifest"; echo "delpg $pg") | /usr/sbin/svccfg 2>/dev/null >/dev/null (echo "select /smf/manifest"; echo "addpg v$pg framework") | /usr/sbin/svccfg 2>/dev/null >/dev/null (echo "select /smf/manifest"; echo "setprop v$pg/md5sum = opaque: $value") | /usr/sbin/svccfg 2>/dev/null >/dev/null ) i=`expr $i + 1` shift echo "$backup\c" > /dev/msglog done echo > /dev/msglog echo "Converted $n obsolete repository entries" activity=true fi # # If no last-import snapshots are present on critical services, then we are # creating the last-import snapshots for the first time post upgrade. # create_last_import=1 for svc in single-user multi-user multi-user-server; do if /usr/bin/svcprop -s last-import svc:/milestone/$svc:default \ >/dev/null 2>&1 then create_last_import= break fi done if [ $create_last_import ]; then echo "Last import snapshots absent; preparing for re-import" prepare_last_import # # Apply property history files. # echo "Upgrade detected; applying property history" for phist in /var/svc/profile/prophist.*; do /lib/svc/bin/prophist hash $phist if [ $? = 3 ]; then echo "Sourcing $phist" . $phist fi done /usr/bin/rm -f /var/svc/profile/.upgrade_prophist fi # # 2. Manifest import. Application directories first, then # site-specific manifests. # nonsite_dirs=`/usr/bin/find /var/svc/manifest/* -name site -prune -o -type d \ -print -prune` nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs` site_manifests=`/lib/svc/bin/mfstscan /var/svc/manifest/site` manifests="$nonsite_manifests $site_manifests" [ -n "$_MFST_DEBUG" ] && { echo "Changed manifests to import:" for m in $manifests; do echo " $m"; done } # # 2b. Import the manifests while giving a running display of imports on # console, and a final count in the logfile. # if [ -n "$nonsite_manifests" -o -n "$site_manifests" ]; then rm -f /tmp/manifest_import.$$ set -- $manifests backup=`echo "$#/$#" | sed 's/.//g'` fwidth=`echo "$#\c" | wc -c` echo "Loading smf(5) service descriptions: \c" > /dev/msglog # # Attempt of moving the repository to tmpfs. If that doesn't # work, reset doswitch so we don't attempt switching back. # /usr/sbin/svcadm _smf_repository_switch fast doswitch=$? i=1; n=$# while [ $# -gt 0 ]; do printf "%${fwidth}s/%${fwidth}s" $i $n > /dev/msglog svccfg_import $1 i=`expr $i + 1` shift echo "$backup\c" > /dev/msglog done # # If switch back fails, exit with the fatal error code. # Normally the failure indicates that there is a serious # problem on the root file system such as file operation # failure or repository access failure. # if [ $doswitch -eq 0 ]; then /usr/sbin/svcadm _smf_repository_switch perm || { \ echo "Repository switch back operation failed, \c" echo "please check the system log for the" echo "possible fatal error messages." exit $SMF_EXIT_ERR_FATAL } fi echo > /dev/msglog echo "Loaded $n smf(5) service descriptions" activity=true if [ -s /tmp/manifest_import.$$ ]; then echo "svccfg warnings:" cat /tmp/manifest_import.$$ msg="svccfg import warnings. See" msg="$msg /var/svc/log/system-manifest-import:default.log ." echo $msg > /dev/msglog fi rm -f /tmp/manifest_import.$$ fi # # 3. Profile application. We must create the platform profile upon # first boot, as we may be a diskless client of a platform or # architecture distinct from our NFS server. # svccfg_apply /var/svc/profile/generic.xml if [ ! -f /var/svc/profile/platform.xml ]; then this_karch=`uname -m` this_plat=`uname -i` if [ -f /var/svc/profile/platform_$this_plat.xml ]; then platform_profile=platform_$this_plat.xml elif [ -f /var/svc/profile/platform_$this_karch.xml ]; then platform_profile=platform_$this_karch.xml else platform_profile=platform_none.xml fi ln -s $platform_profile /var/svc/profile/platform.xml fi svccfg_apply /var/svc/profile/platform.xml # # 4. Upgrade handling. The upgrade file generally consists of a series # of svcadm(1M) and svccfg(1M) commands. # ( unset SVCCFG_CHECKHASH if [ -f /var/svc/profile/upgrade ]; then . /var/svc/profile/upgrade /usr/bin/mv /var/svc/profile/upgrade \ /var/svc/profile/upgrade.app.`date +\%Y\%m\%d\%H\%M\%S` activity=true fi # # Rename the datalink upgrade script file. This script is used in the # network/physical service to upgrade datalink configuration, but # the file cannot be renamed until now (when the file system becomes # read-write). # datalink_script=/var/svc/profile/upgrade_datalink if [ -f "${datalink_script}" ]; then /usr/bin/mv "${datalink_script}" \ "${datalink_script}".app.`date +\%Y\%m\%d\%H\%M\%S` fi ) # # 5. Site profile is applied last to give administrator the final say. # if [ -f /var/svc/profile/site.xml ]; then svccfg_apply /var/svc/profile/site.xml fi # # 6. Final actions. # refresh_instances clear_instances if $activity; then svcadm _smf_backup "manifest_import" || true fi exit 0