xref: /illumos-gate/usr/src/lib/brand/solaris10/zone/attach.ksh (revision 93a18d6d401e844455263f926578e9d2aa6b47ec)
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