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 2009 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26 27. /usr/lib/brand/solaris10/common.ksh 28 29m_attach_log=$(gettext "Log File: %s") 30m_zfs=$(gettext "A ZFS file system was created for the zone.") 31m_attaching=$(gettext "Attaching...") 32m_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.") 33m_complete=$(gettext "Attach complete.") 34 35install_fail=$(gettext "*** Attach FAILED ***") 36 37f_n_unimpl=$(gettext "The -n option is not yet implemented.") 38f_zfs=$(gettext "Error creating a ZFS file system (%s) for the zone.") 39f_nodataset=$(gettext "Error: there is no ZFS file system for the zone.") 40f_zfsdestroy=$(gettext "Error destroying ZFS file system %s.") 41 42f_sanity_notzone=$(gettext "Error: this is a system image and not a zone image.") 43 44f_baddir=$(gettext "Invalid '%s' directory within the zone") 45 46# Clean up on interrupt 47trap_cleanup() 48{ 49 msg=$(gettext "Installation cancelled due to interrupt.") 50 log "$msg" 51 52 # umount any mounted file systems 53 umnt_fs 54 55 trap_exit 56} 57 58# If the attach failed then clean up the ZFS datasets we created. 59trap_exit() 60{ 61 if [[ $EXIT_CODE != $ZONE_SUBPROC_OK && "$install_media" != "-" ]]; then 62 /usr/lib/brand/solaris10/uninstall $ZONENAME $ZONEPATH -F 63 fi 64 65 exit $EXIT_CODE 66} 67 68EXIT_CODE=$ZONE_SUBPROC_USAGE 69install_media="-" 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 ;; 109 n) noexecute=1 ;; 110 r) 111 if [[ -n "$inst_type" ]]; then 112 fatal "$incompat_options" "$m_usage" 113 fi 114 inst_type="stdin" 115 install_media="$OPTARG" 116 ;; 117 ?) printf "$m_usage\n" 118 exit $ZONE_SUBPROC_USAGE;; 119 *) printf "$m_usage\n" 120 exit $ZONE_SUBPROC_USAGE;; 121 esac 122done 123shift $((OPTIND-1)) 124 125if [[ $noexecute == 1 && -n "$inst_type" ]]; then 126 fatal "$m_usage" 127fi 128 129if [ $noexecute -eq 1 ]; then 130 # 131 # The zone doesn't have to exist when the -n option is used, so do 132 # this work early. 133 # 134 135 # XXX do the sw validation for solaris10 minimal patch level to ensure 136 # everything will be ok. 137 EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE 138 fatal "$f_n_unimpl" 139fi 140 141EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE 142 143if [[ -z "$inst_type" ]]; then 144 inst_type="directory" 145 146elif [[ "$install_media" != "-" ]]; then 147 # 148 # If we're not using a pre-existing zone directory layout then create 149 # the zone datasets and mount them. 150 # 151 unset DATASET 152 pdir=$(/usr/bin/dirname $ZONEPATH) 153 zds=$(/usr/sbin/zfs list -H -t filesystem -o name $pdir 2>/dev/null) 154 if (( $? == 0 )); then 155 pnm=$(/usr/bin/basename $ZONEPATH) 156 /usr/sbin/zfs create "$zds/$pnm" 157 if (( $? == 0 )); then 158 vlog "$m_zfs" 159 DATASET="$zds/$pnm" 160 else 161 log "$f_zfs" "$zds/$pnm" 162 fi 163 fi 164 165 create_active_ds 166fi 167 168# 169# The zone's datasets are now in place, validate that things 170# are setup correctly. 171# 172 173get_zonepath_ds $zonepath 174 175/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1 176if (( $? != 0 )); then 177 fail_fatal "$f_no_active_ds" 178else 179 /usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \ 180 >/dev/null 2>&1 181 /usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \ 182 >/dev/null 2>&1 183fi 184 185BENAME=zbe-0 186/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1 187if (( $? != 0 )); then 188 fail_fatal "$f_zfs_create" 189else 190 /usr/sbin/zfs set $PROP_ACTIVE=on $ZONEPATH_DS/ROOT/$BENAME \ 191 >/dev/null 2>&1 192 /usr/sbin/zfs set canmount=noauto $ZONEPATH_DS/ROOT/$BENAME \ 193 >/dev/null 2>&1 194 /usr/sbin/zfs inherit mountpoint $ZONEPATH_DS/ROOT/$BENAME \ 195 >/dev/null 2>&1 196 /usr/sbin/zfs inherit zoned $ZONEPATH_DS/ROOT/$BENAME \ 197 >/dev/null 2>&1 198fi 199 200LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $zonename.attach_log.XXXXXX) 201if [[ -z "$LOGFILE" ]]; then 202 fatal "$e_tmpfile" 203fi 204exec 2>>"$LOGFILE" 205log "$m_attach_log" "$LOGFILE" 206 207log "$m_attaching" 208install_image "$inst_type" "$install_media" 209 210mk_zone_dirs 211 212# 213# Perform a final check that this is really a zone image and not an archive of 214# a system image which would need p2v. Check for a well-known S10 SMF service 215# that shouldn't exist in a zone. 216# 217if [[ -e $ZONEROOT/var/svc/manifest/system/sysevent.xml ]]; then 218 log "$f_sanity_notzone" 219 exit $ZONE_SUBPROC_NOTCOMPLETE 220fi 221 222EXIT_CODE=$ZONE_SUBPROC_OK 223 224log "$m_complete" 225 226zone_logfile="${logdir}/$zonename.attach$$.log" 227 228safe_dir /var 229safe_dir /var/log 230safe_copy $LOGFILE $zone_logfile 231 232log "$m_attach_log" "$zone_logfile" 233rm -f $LOGFILE 234 235exit $ZONE_SUBPROC_OK 236