/overlay/generic/lib/svc/method/manifest-import
Korn Shell | 517 lines | 312 code | 67 blank | 138 comment | 67 complexity | 4490812f9aadfa9b7cf678d7110a6608 MD5 | raw file
Possible License(s): BSD-3-Clause, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0, 0BSD, MIT, Apache-2.0
- #!/bin/ksh
- #
- # 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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- #
- # 0a Initialization.
- [ -f /lib/svc/share/smf_include.sh ] || exit 1
- . /lib/svc/share/smf_include.sh
- activity=false
- EMI_SERVICE="svc:/system/early-manifest-import:default"
- PROFILE_DIR_SITE="/etc/svc/profile/site"
- X=
- ALT_REPOSITORY=
- ALT_MFST_DIR=
- early=false
- [ "$SMF_FMRI" == "$EMI_SERVICE" ] && early=true
- usage()
- {
- echo "Usage: /lib/svc/method/manifest-import [-n]" \
- "[-f repository-file -d manifest-directory]"
- echo "\nOptions:"
- echo "-n dryrun"
- echo "-f and -d specify alternate repository and" \
- "manifest directory for import\n"
- exit 2
- }
- while getopts "nd:f:" opt; do
- case $opt in
- n) X=echo;;
- d) ALT_MFST_DIR=$OPTARG;;
- f) ALT_REPOSITORY=$OPTARG;;
- ?) usage;;
- esac
- done
- #
- # Both -f and -d options must be specified together or not specified at all
- #
- [ -n "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ] && usage
- [ -n "$ALT_MFST_DIR" -a -z "$ALT_REPOSITORY" ] && usage
- function svccfg_apply {
- $X /usr/sbin/svccfg apply $1
- if [ $? -ne 0 ]; then
- echo "WARNING: svccfg apply $1 failed" | tee /dev/msglog
- fi
- }
- #
- # If the smf/manifest table has file entries that are missing
- # then there is work to be done by the cleanup process.
- #
- function cleanup_needwork {
- if [ "$early" == true ]; then
- smfmfiles=`/usr/bin/svcprop smf/manifest | \
- awk '(/^lib_/ && /\/manifestfile /) {print $3}'`
- else
- smfmfiles=`/usr/bin/svcprop smf/manifest | \
- awk '/\/manifestfile / {print $3}'`
- fi
- nw=`/lib/svc/bin/mfstscan $smfmfiles 2>&1 1>/dev/null`
- [ "$nw" ] && return 1
- return 0
- }
- #
- # Upon upgrading to early manifest import code, preserve hashes of system
- # profiles which lived under /var/svc/profile so that svccfg apply would
- # not re-apply the profiles and overwrite user customizations. Simply
- # migrate manifestfile and hash values to new property groups named after
- # profiles under /etc/svc/profile. If the profiles don't really exist,
- # svccfg cleanup will remove the property groups in a later step.
- #
- # Existing generic.xml, inetd_services.xml, and name_service.xml symlinks
- # need to be preserved.
- #
- # Don't process site.xml profile since it is still supported under
- # /var/svc/profile directory.
- #
- function preserve_system_profiles {
- #
- # If /var is a separate fs, return and let Late Import
- # preserves the hashes.
- #
- [ -d "/var/svc/profile" ] || return 1
- #
- # Preserve hashes for the following profiles: generic (two
- # cases) and platform (uname -i, uname -m outputs).
- #
- gn="var_svc_profile_generic_open_xml"
- gh=`/usr/bin/svcprop -p ${gn}/md5sum smf/manifest 2>/dev/null`
- [ $? = 0 ] || gh=""
- gn="etc_svc_profile_generic_open_xml"
- gln="var_svc_profile_generic_limited_net_xml"
- glh=`/usr/bin/svcprop -p ${gln}/md5sum smf/manifest 2>/dev/null`
- [ $? = 0 ] || glh=""
- gln="etc_svc_profile_generic_limited_net_xml"
- 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=""
- pln="etc_svc_profile_platform_${pl}_xml"
- 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=""
- plmn="etc_svc_profile_platform_${plm}_xml"
- else
- plmh=""
- fi
- [ -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
- /usr/sbin/svccfg -s smf/manifest setprop ${gn}/manifestfile = \
- astring: "/etc/svc/profile/generic.xml"
- }
- [ -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
- /usr/sbin/svccfg -s smf/manifest setprop ${gln}/manifestfile = \
- astring: "/etc/svc/profile/generic.xml"
- }
- [ -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
- /usr/sbin/svccfg -s smf/manifest setprop ${pln}/manifestfile = \
- astring: "/etc/svc/profile/platform_${pl}_xml"
- }
- [ -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
- /usr/sbin/svccfg -s smf/manifest setprop \
- ${plmn}/manifestfile = \
- astring: "/etc/svc/profile/platform_${plm}_xml"
- }
- #
- # Move symlinks from /var/svc/profile to /etc/svc/profile
- #
- generic_prof="/var/svc/profile/generic.xml"
- ns_prof="/var/svc/profile/name_service.xml"
- inetd_prof="/var/svc/profile/inetd_services.xml"
- platform_prof="/var/svc/profile/platform.xml"
- [ -L "$generic_prof" ] && mv $generic_prof /etc/svc/profile/
- [ -L "$ns_prof" ] && mv $ns_prof /etc/svc/profile/
- [ -L "$inetd_prof" ] && mv $inetd_prof /etc/svc/profile/
- [ -L "$platform_prof" ] && mv $platform_prof /etc/svc/profile/
- return 0
- }
- #
- # 2. Manifest import. Application directories first, then
- # site-specific manifests.
- #
- function import_manifests {
- typeset basedir=$1
- typeset console_print=$2
- typeset logf="/etc/svc/volatile/manifest_import.$$"
- rm -f $logf
- if [ "${basedir}" == "/opt/custom/smf" ]; then
- # Special case where we will just import from the root, not subdirs
- nonsite_dirs=${basedir}
- else
- nonsite_dirs=`/usr/bin/find $basedir/* -name site \
- -prune -o -type d -print -prune`
- fi
- if [ -n "$_MFST_DEBUG" ]; then
- nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs`
- site_manifests=`/lib/svc/bin/mfstscan $basedir/site`
- manifests="$nonsite_manifests $site_manifests"
- echo "Changed manifests to import:"
- for m in $manifests; do echo " $m"; done
- fi
- #
- # Upon boot, attempt to move the repository to tmpfs.
- #
- if [ -z "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ]; then
- /usr/sbin/svcadm _smf_repository_switch fast
- fi
- #
- # Import the manifests while giving a running display of imports on
- # console, and a final count in the logfile.
- #
- dirs="$nonsite_dirs"
- [ -d "$basedir/site" ] && dirs="$dirs $basedir/site"
- if [ "$console_print" = "true" ]; then
- $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1
- else
- $X /usr/sbin/svccfg import $dirs > $logf 2>&1
- fi
- grep "Loaded .*. smf(5) service descriptions" $logf > /dev/null 2>&1
- if [ $? -eq 0 ]; then
- activity=true
- fi
- if [ -s $logf ]; then
- grep "smf(5) service descriptions failed to load" $logf > /dev/null 2>&1
- failures=$?
- if [ $failures -eq 0 ]; then
- echo "svccfg warnings:"
- fi
- cat $logf
- if [ $failures -eq 0 -a "$console_print" = "true" ]; then
- msg="svccfg import warnings. See"
- msg="$msg /var/svc/log/system-manifest-import:default.log ."
- echo $msg > /dev/msglog
- fi
- fi
- rm -f $logf
- }
- #
- # 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.
- #
- # Generic and platform profiles are only supported in /etc.
- #
- function apply_profile {
- #
- # If smf/manifest doesn't have any profile under /etc/var/profile,
- # this is very likely an import after upgrade so call
- # preserve_system_profiles in that case.
- #
- LC_ALL=C pl=`/usr/bin/uname -i | /usr/bin/tr , _`
- pln="etc_svc_profile_platform_${pl}_xml"
- LC_ALL=C plm=`/usr/bin/uname -m | /usr/bin/tr , _`
- [ $plm != $pl ] && plmn="etc_svc_profile_platform_${plm}_xml"
- preserve_profiles=1
- for prof in $pln $plmn etc_svc_profile_platform_none_xml \
- etc_svc_profile_generic_limited_net_xml \
- etc_svc_profile_generic_open_xml; do
- if /usr/bin/svcprop -p $prof smf/manifest >/dev/null 2>&1
- then
- preserve_profiles=0
- break
- fi
- done
- if [ $preserve_profiles -eq 1 ]; then
- echo "/etc/svc system profiles not found: upgrade system profiles"
- preserve_system_profiles || return
- fi
- typeset prefix="/etc/svc/profile"
- svccfg_apply $prefix/generic.xml
- if [ ! -f $prefix/platform.xml ]; then
- this_karch=`uname -m`
- this_plat=`uname -i`
- if [ -f $prefix/platform_$this_plat.xml ]; then
- platform_profile=platform_$this_plat.xml
- elif [ -f $prefix/platform_$this_karch.xml ]; then
- platform_profile=platform_$this_karch.xml
- else
- platform_profile=platform_none.xml
- fi
- ln -s $platform_profile $prefix/platform.xml
- fi
- svccfg_apply $prefix/platform.xml
- }
- #
- # 4. Upgrade handling. The upgrade file generally consists of a series
- # of svcadm(1M) and svccfg(1M) commands.
- #
- function handle_upgrade {
- [ -f /var/svc/profile/upgrade ] && activity=true
- (
- 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`
- 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. Giving administrator the final say, apply site.xml profile and profiles
- # under /etc/svc/profile/site directory.
- #
- function apply_site_profile {
- typeset prefix="$1"
- [ -f $prefix/site.xml ] && svccfg_apply $prefix/site.xml
- if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc/svc/profile" ]; then
- svccfg_apply $PROFILE_DIR_SITE
- fi
- }
- #
- # 0b Cleanup deathrow
- #
- if [ "$early" = "false" ];then
- 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
- fi
- SVCCFG_CHECKHASH=1 export SVCCFG_CHECKHASH
- #
- # 0c Clean up repository
- #
- if [ "$early" = "false" ]; then
- 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
- fi
- #
- # If the alternate repository and directory are specified, simply set
- # SVCCFG_REPOSITORY env, run svccfg import on the given directory, and
- # exit.
- #
- if [ -n "$ALT_REPOSITORY" -a -n "$ALT_MFST_DIR" ]; then
- SVCCFG_REPOSITORY=$ALT_REPOSITORY export SVCCFG_REPOSITORY
- import_manifests "$ALT_MFST_DIR" false
- unset SVCCFG_REPOSITORY
- exit 0
- fi
- #
- # Call import and apply profiles here
- #
- if [ "$early" = "true" ]; then
- import_manifests "/lib/svc/manifest" true
- apply_profile
- apply_site_profile "/etc/svc/profile"
- else
- #
- # Process both /lib/svc/manifest and /var/svc/manifest
- # during late manifest-import
- #
- # First import the manifests
- #
- import_manifests "/lib/svc/manifest" true
- import_manifests "/var/svc/manifest" true
- if [ -d "/opt/custom/smf" ]; then
- import_manifests "/opt/custom/smf" true
- fi
- #
- # Apply profiles
- #
- apply_profile
- apply_site_profile "/etc/svc/profile"
- #
- # Run the upgrade script
- #
- handle_upgrade
- apply_site_profile "/var/svc/profile"
- fi
- #
- # 6. Final actions.
- #
- #if $activity; then
- # /usr/sbin/svcadm _smf_backup "manifest_import" || true
- #fi
- #
- # If the filesystem is NOT read only then move the repo back to perm
- # There is no care wether the switch was made or not, but just want
- # to move it. If it is already perm this does not affect anything
- # at least on the surface. REALLY want to improve on this...
- #
- touch /etc/svc/smf_rwtest.$$ > /dev/null 2>&1
- if [ $? -eq 0 ]; then
- rm -f /etc/svc/smf_rwtest.$$
- /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
- if $activity; then
- /usr/sbin/svccfg cleanup | /usr/bin/tee /dev/msglog
- else
- cleanup_needwork
- if [ $? -ne 0 ]; then
- /usr/sbin/svccfg cleanup -a | /usr/bin/tee /dev/msglog
- fi
- fi
- exit 0