1#!/bin/ksh -p 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24# 25 26. /usr/lib/brand/solaris10/common.ksh 27 28m_attach_log=$(gettext "Log File: %s") 29m_zfs=$(gettext "A ZFS file system was created for the zone.") 30m_attaching=$(gettext "Attaching...") 31m_usage=$(gettext "solaris10 brand usage:\n\tattach [-a archive | -d directory | -r recv_type]\n\tThe -a archive option specifies an archive name which can be a flar,\n\ttar, pax or cpio archive.\n\tThe -d directory option specifies an existing directory.\n\tThe -r recv_type option specifies the type of archive to be read from\n\tstdin.") 32m_complete=$(gettext "Attach complete.") 33 34install_fail=$(gettext "*** Attach FAILED ***") 35 36f_n_unimpl=$(gettext "The -n option is not yet implemented.") 37f_zfs=$(gettext "Error creating a ZFS file system (%s) for the zone.") 38f_nodataset=$(gettext "Error: there is no ZFS file system for the zone.") 39f_zfsdestroy=$(gettext "Error destroying ZFS file system %s.") 40 41f_sanity_notzone=$(gettext "Error: this is a system image and not a zone image.") 42 43f_baddir=$(gettext "Invalid '%s' directory within the zone") 44 45# Clean up on interrupt 46trap_cleanup() 47{ 48 msg=$(gettext "Installation cancelled due to interrupt.") 49 log "$msg" 50 51 # umount any mounted file systems 52 umnt_fs 53 54 trap_exit 55} 56 57# If the attach failed then clean up the ZFS datasets we created. 58trap_exit() 59{ 60 if [[ $EXIT_CODE != $ZONE_SUBPROC_OK && $rm_ds == 1 ]]; then 61 /usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F 62 fi 63 64 exit $EXIT_CODE 65} 66 67EXIT_CODE=$ZONE_SUBPROC_USAGE 68install_media="-" 69rm_ds=0 70 71trap trap_cleanup INT 72trap trap_exit EXIT 73 74# If we weren't passed at least two arguments, exit now. 75(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE 76 77ZONENAME="$1" 78ZONEPATH="$2" 79# XXX shared/common script currently uses lower case zonename & zonepath 80zonename="$ZONENAME" 81zonepath="$ZONEPATH" 82 83shift; shift # remove ZONENAME and ZONEPATH from arguments array 84 85ZONEROOT="$ZONEPATH/root" 86logdir="$ZONEROOT/var/log" 87 88noexecute=0 89 90unset inst_type 91 92# Other brand attach options are invalid for this brand. 93while getopts "a:d:nr:" opt; do 94 case $opt in 95 a) 96 if [[ -n "$inst_type" ]]; then 97 fatal "$incompat_options" "$m_usage" 98 fi 99 inst_type="archive" 100 install_media="$OPTARG" 101 ;; 102 d) 103 if [[ -n "$inst_type" ]]; then 104 fatal "$incompat_options" "$m_usage" 105 fi 106 inst_type="directory" 107 install_media="$OPTARG" 108 # '-d -' means use the existing zonepath. 109 if [[ "$install_media" == "$ZONEPATH" ]]; then 110 install_media="-" 111 fi 112 ;; 113 n) noexecute=1 ;; 114 r) 115 if [[ -n "$inst_type" ]]; then 116 fatal "$incompat_options" "$m_usage" 117 fi 118 inst_type="stdin" 119 install_media="$OPTARG" 120 ;; 121 ?) printf "$m_usage\n" 122 exit $ZONE_SUBPROC_USAGE;; 123 *) printf "$m_usage\n" 124 exit $ZONE_SUBPROC_USAGE;; 125 esac 126done 127shift $((OPTIND-1)) 128 129if [[ $noexecute == 1 && -n "$inst_type" ]]; then 130 fatal "$m_usage" 131fi 132 133if [ $noexecute -eq 1 ]; then 134 # 135 # The zone doesn't have to exist when the -n option is used, so do 136 # this work early. 137 # 138 139 # XXX do the sw validation for solaris10 minimal patch level to ensure 140 # everything will be ok. 141 EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE 142 fatal "$f_n_unimpl" 143fi 144 145EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE 146 147if [[ -z "$inst_type" ]]; then 148 inst_type="directory" 149 150elif [[ "$install_media" != "-" ]]; then 151 # 152 # If we're not using a pre-existing zone directory layout then create 153 # the zone datasets and mount them. 154 # 155 unset DATASET 156 pdir=$(/usr/bin/dirname $ZONEPATH) 157 zds=$(/usr/sbin/zfs list -H -t filesystem -o name $pdir 2>/dev/null) 158 if (( $? == 0 )); then 159 pnm=$(/usr/bin/basename $ZONEPATH) 160 /usr/sbin/zfs create "$zds/$pnm" 161 if (( $? == 0 )); then 162 vlog "$m_zfs" 163 DATASET="$zds/$pnm" 164 rm_ds=1 165 else 166 log "$f_zfs" "$zds/$pnm" 167 fi 168 fi 169 170 create_active_ds 171fi 172 173# 174# The zone's datasets are now in place, validate that things 175# are setup correctly. 176# 177 178get_zonepath_ds $zonepath 179 180/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1 181(( $? != 0 )) && fail_fatal "$f_no_active_ds" 182 183zfs set mountpoint=legacy $ZONEPATH_DS/ROOT >/dev/null 2>&1 184zfs set zoned=on $ZONEPATH_DS/ROOT >/dev/null 2>&1 185 186get_active_ds $ZONEPATH_DS 187zfs list -H -o name $ACTIVE_DS >/dev/null 2>&1 188(( $? != 0 )) && fail_fatal "$f_zfs_create" 189 190zfs set canmount=noauto $ACTIVE_DS >/dev/null 2>&1 191zfs inherit mountpoint $ACTIVE_DS >/dev/null 2>&1 192zfs inherit zoned $ACTIVE_DS >/dev/null 2>&1 193 194if [ ! -d $ZONEROOT ]; then 195 mkdir -p $ZONEROOT || fail_fatal "$f_mkdir" "$ZONEROOT" 196 chmod 700 $ZONEPATH || fail_fatal "$f_chmod" "$ZONEPATH" 197fi 198 199mnted=`zfs get -H mounted $ACTIVE_DS | cut -f3` 200if [[ $mnted = "no" ]]; then 201 mount -F zfs $ACTIVE_DS $ZONEROOT || fail_fatal "$f_zfs_mount" 202fi 203 204LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $zonename.attach_log.XXXXXX) 205if [[ -z "$LOGFILE" ]]; then 206 fatal "$e_tmpfile" 207fi 208exec 2>>"$LOGFILE" 209log "$m_attach_log" "$LOGFILE" 210 211log "$m_attaching" 212install_image "$inst_type" "$install_media" 213 214mk_zone_dirs 215 216# 217# Perform a final check that this is really a zone image and not an archive of 218# a system image which would need p2v. Check for a well-known S10 SMF service 219# that shouldn't exist in a zone. 220# 221if [[ -e $ZONEROOT/var/svc/manifest/system/sysevent.xml ]]; then 222 log "$f_sanity_notzone" 223 exit $ZONE_SUBPROC_NOTCOMPLETE 224fi 225 226EXIT_CODE=$ZONE_SUBPROC_OK 227 228log "$m_complete" 229 230zone_logfile="${logdir}/$zonename.attach$$.log" 231 232safe_dir /var 233safe_dir /var/log 234safe_copy $LOGFILE $zone_logfile 235 236log "$m_attach_log" "$zone_logfile" 237rm -f $LOGFILE 238 239exit $ZONE_SUBPROC_OK 240