manifest-import revision 7c478bd95313f5f23a4c958a745db2134aa03244
#!/sbin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (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 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
# 0. Initialization.
[ -f /lib/svc/share/smf_include.sh ] || exit 1
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 <<END
addpg $name method
setprop $name/type = astring: method
setprop $name/exec = astring: "$exec"
setprop $name/timeout_seconds = count: $to
END
}
prophist_adddep () {
#
# If a dependency doesn't exist, create it. Instances should be
# refreshed for changes to take effect.
#
if [ $# -lt 6 ]; then
echo "prophist_adddep(): Insufficient arguments ($*)"
exit 1
fi
fmri=$1
/usr/bin/svcprop -q $fmri || return
name=$2
/usr/bin/svcprop -Cqp $name $fmri && return
type=$3
group=$4
ro=$5
shift 5
/usr/sbin/svccfg -s $fmri <<END
addpg $name dependency
setprop $name/type = astring: $type
setprop $name/grouping = astring: $group
setprop $name/restart_on = astring: $ro
setprop $name/entities = fmri: $*
END
}
prophist_adddpt () {
#
# If a dependent doesn't exist, create it. Instances should be
# refresh for changes to take effect.
#
if [ $# -ne 5 ]; then
echo "prophist_adddpt(): Incorrect arguments ($*).\n"
exit 1
fi
fmri=$1
/usr/bin/svcprop -q $fmri || return
name=$2
/usr/bin/svcprop -Cqp dependents/$name $fmri && return
group=$3
ro=$4
target=$5
prophist_addprop $fmri dependents framework $name fmri: $target
prophist_adddep $target $name service $group $ro $fmri
}
instance_refresh () {
echo $1 >> /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
}
}
SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH
#
# 0. 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
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
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
)
#
# 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