#!/usr/sbin/sh
#
# Copyright (c) 1992, 2014, Oracle and/or its affiliates. All rights reserved.
#
# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
# All rights reserved.
#
#
. /lib/svc/share/smf_include.sh
. /lib/svc/share/fs_include.sh
# Mount other file systems to be available in single user mode.
# Currently, these are /var, /var/adm, /var/share and /tmp. A change
# here will require a modification to the following programs (and
# documentation): /usr/sbin/mountall, /usr/sbin/umountall, and
# /lib/svc/bin/svc.startd.
#
# Once root is read/write we can enable the dedicated dumpdevice if it exists
# locally. This is an optimization as svc-dumpadm will attempt do this later.
# As the crash directory is generally under /var/share, we need to postpone
# the dump setup until /var/share is mounted.
#
dump_setup()
{
[ -r /etc/dumpadm.conf ] && . /etc/dumpadm.conf
readswapdev $DUMPADM_DEVICE < $vfstab
#
# If we have a dedicated dump device, then go ahead and configure it.
#
if [[ $special != $DUMPADM_DEVICE && -x /usr/sbin/dumpadm &&
-b $DUMPADM_DEVICE ]]; then
/usr/sbin/dumpadm -u || exit $SMF_EXIT_ERR_CONFIG
fi
}
#
# Write a unique id into this kernel image; this will be included
# in the dump header and panicbuf of any crashdump of this image.
#
if [[ -c /dev/dump && -x /usr/sbin/dumpadm ]]; then
/usr/sbin/dumpadm -i
fi
#
# Add physical swap. Needs to be done after dumpadm -i.
#
/usr/sbin/swapadd -1
rootiszfs=0
# In a zone, the zone root is mounted with a temporary mountpoint option
# (zfs mount -o mountpoint=
). If the mountpoint of a child
# dataset is inherited, neither "zfs mount " nor "zfs mount -a"
# will cause that child dataset to be mounted. That is, the only way to
# mount such a child is with a temporary mountpoint option. Thus, if the
# root (zone root, that is) file system is mounted with a temporary
# mountpoint option, we also need to mount other datasets in the BE
# using a temporary mountpoint.
rootistmpmnt=0
readmnttab / < /etc/mnttab
if [ "$fstype" = zfs ] ; then
rootiszfs=1
be=$special
case "$mntopts" in
*mountpoint=*)
rootistmpmnt=1
;;
esac
fi
for fs in /var /var/adm /var/share /tmp; do
readvfstab $fs < $vfstab
if [ -n "$mountp" ]; then
mounted $mountp $mntopts $fstype < /etc/mnttab && continue
checkfs $fsckdev $fstype $mountp || exit $SMF_EXIT_ERR_FATAL
mountfs -O $mountp $fstype $mntopts - ||
exit $SMF_EXIT_ERR_FATAL
continue
fi
if [ "$rootiszfs" = 1 ]; then
mounted $fs - zfs < /etc/mnttab && continue
mountpt=`zfs get -H -o value mountpoint $be$fs 2>/dev/null`
if [ $? = 0 ] ; then
if [ "x$mountpt" = "x$fs" ] ; then
opts=-O
if [ $rootistmpmnt = 1 ]; then
opts="$opts -o mountpoint=$mountpt"
fi
/usr/sbin/zfs mount $opts $be$fs
fi
fi
fi
done
function ds_create_err {
# We have not been able to create or mount the shared dataset
# /VARSHARE/zones.
# This is severe enough to cause us to exit with an error.
print ""
print "Unable to create dataset $fsname or mount it on /system/zones."
print "/usr/sbin/zfs create -o mountpoint=/system/zones/ $1"
print ""
exit $SMF_EXIT_ERR_FATAL
}
function varshare_create_err {
# We have not been able to create or mount the shared dataset, passed as
# the first argument, and have not migrated contents from /var/.migrate.
# This is severe enough to cause us to exit with an error.
print ""
print "Unable to create dataset $fsname or mount it on /var/share."
print "Please move any existing content from /var/share to "
print "/var/.migrate, ensure that /var/share is an empty directory,"
print "then run the following commands:"
print "/usr/sbin/zfs create -o canmount=noauto -o mountpoint=/var/share $1"
print "/usr/sbin/zfs mount $1"
print "/lib/svc/share/migrate_shared_files.py /var/.migrate /var/share $SMF_FMRI"
print ""
exit $SMF_EXIT_ERR_FATAL
}
if [ "$rootiszfs" = 1 ] ; then
/usr/sbin/zfs list -rH -o mountpoint -s mountpoint -t filesystem \
"$be" 2> /dev/null | \
while read mountp ; do
if [ "x$mountp" != "x" -a "$mountp" != "legacy" ] ; then
mounted $mountp - zfs < /etc/mnttab && continue
opts=
if [ $rootistmpmnt = 1 ]; then
opts="$opts -o mountpoint=$mountp"
fi
/usr/sbin/zfs mount $opts $be$mountp
fi
done
rpool=${be%%/*}
/usr/sbin/zfs list -Ho mountpoint "$rpool/VARSHARE" > /dev/null 2>&1 &&
/usr/sbin/zfs mount "$rpool/VARSHARE" 2> /dev/null
# For directories under /var that we wish to share across boot
# environments, we must ensure that our shared dataset exists, then
# must migrate any salvaged files and directories over to that dataset.
if ! mounted /var/share - zfs < /etc/mnttab ; then
fsname="$rpool/VARSHARE"
compression=""
if mounted /var - zfs < /etc/mnttab ; then
compression=`zfs get -H -o value compression $be/var`
if [ $? = 0 ]; then
compression="-o compression=$compression"
fi
fi
/usr/sbin/zfs create -o canmount=noauto \
-o mountpoint=/var/share $compression $fsname
if [ $? != 0 ] ; then
varshare_create_err $fsname
fi
/usr/sbin/zfs mount $fsname
if [ $? != 0 ] ; then
varshare_create_err $fsname
fi
fi
if is_self_assembly_boot; then
/lib/svc/share/migrate_shared_files.py /var/.migrate \
/var/share $SMF_FMRI > /dev/console
if [ $? != 0 ] ; then
exit $SMF_EXIT_ERR_FATAL
fi
fi
dump_setup
#
# Create rpool/VARSHARE/zones and mount it at /system/zones in the
# global zone.
#
if smf_is_globalzone &&
! mounted /system/zones - zfs < /etc/mnttab; then
fsname="$rpool/VARSHARE/zones"
if ! /usr/sbin/zfs list $fsname > /dev/null 2>&1 &&
! /usr/sbin/zfs create -o mountpoint=/system/zones \
$fsname; then
ds_create_err $fsname
fi
fi
fi
mount_shared
# Updating the last boot time property if booted r/w
if [[ -w / ]]; then
rootfs=$(/usr/sbin/zfs list -Ho name / 2>/dev/null)
if [[ -n $rootfs ]]; then
# Set Boot Timestamp
now=$(TZ=UTC date +%Y%m%dT%H%M%SZ)
/usr/sbin/zfs set com.oracle.libbe:last-boot-time="$now" \
"$rootfs"
fi
fi
exit $SMF_EXIT_OK