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.
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.
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]
23 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 # Use is subject to license terms.
26 # Copyright (C) 2013 by Jim Klimov - implemented the previously absent
27 # cloning of zones from specified snapshot, and avoidance of sys-unconfig
29 .
/usr
/lib
/brand
/ipkg
/common.ksh
31 m_usage
=$
(gettext "clone {sourcezone}")
32 f_nosource
=$
(gettext "Error: unable to determine source zone dataset.")
33 f_badsource
=$
(gettext "Error: specified snapshot is invalid for this source zone.")
38 if (( $ZONE_IS_MOUNTED != 0 )); then
40 zoneadm
-z $ZONENAME unmount
43 exit $ZONE_SUBPROC_INCOMPLETE
46 # Set up ZFS dataset hierarchy for the zone.
50 # Other brand clone options are invalid for this brand.
51 while getopts "R:s:Xz:" opt
; do
53 R
) ZONEPATH
="$OPTARG" ;;
55 *@
*) # Full snapshot name was provided, or just "@snap"
56 # Split this into dataset name (even if empty) and
57 # snapshot name (also may be empty)
58 SNAPNAME
="`echo "$OPTARG" | sed 's/^[^@]*@//'`"
59 REQUESTED_DS
="`echo "$OPTARG" | sed 's/\([^@]*\)@.*$/\1/'`"
61 */*) # Only dataset name was passed, so we will make a
62 # snapshot there automatically and clone off it
64 REQUESTED_DS
="$OPTARG"
66 *) # Only snapshot name was passed, so we will clone
67 # the source zone's active ZBE and this snapshot
73 X
) NO_SYSUNCONFIG
=yes ;;
74 z
) ZONENAME
="$OPTARG" ;;
87 if [ -z "$REQUESTED_DS" ]; then
88 # Find the active source zone dataset to clone.
89 sourcezonepath
=`/usr/sbin/zoneadm -z $sourcezone list -p | awk -F: '{print $4}'`
90 if [ -z "$sourcezonepath" ]; then
91 fail_fatal
"$f_nosource"
94 get_zonepath_ds
$sourcezonepath
95 get_active_ds
$CURRENT_GZBE $ZONEPATH_DS
97 # Sanity-check the provided dataset (should exist and be an IPS ZBE)
98 REQUESTED_DS
="`echo "$REQUESTED_DS" | egrep '^.*/'"$sourcezone"'/ROOT/[^/]+$'`"
99 if [ $?
!= 0 -o x
"$REQUESTED_DS" = x
]; then
100 fail_fatal
"$f_badsource"
103 org.opensolaris.libbe
:parentbe
,org.opensolaris.libbe
:active \
104 "$REQUESTED_DS" > /dev
/null || \
105 fail_fatal
"$f_badsource"
106 ACTIVE_DS
="$REQUESTED_DS"
109 # Another sanity-check: requested snapshot exists for default or requested ZBE
110 if [ x
"$SNAPNAME" != x
]; then
111 zfs list
-H "$ACTIVE_DS@$SNAPNAME" > /dev
/null || \
112 fail_fatal
"$f_badsource"
116 # Now set up the zone's datasets
120 # First make the top-level dataset.
123 pdir
=`/usr/bin/dirname $ZONEPATH`
124 zpname
=`/usr/bin/basename $ZONEPATH`
126 get_zonepath_ds
$pdir
129 fail_zonepath_in_rootds
$zpds
132 # We need to tolerate errors while creating the datasets and making the
133 # mountpoint, since these could already exist from some other BE.
136 /usr
/sbin
/zfs create
$zpds/$zpname
138 /usr
/sbin
/zfs create
-o mountpoint
=legacy
-o zoned
=on
$zpds/$zpname/ROOT
140 if [ x
"$SNAPNAME" = x
]; then
142 SNAPNAME
=${ZONENAME}_snap
144 while [ $SNAPNUM -lt 100 ]; do
145 /usr
/sbin
/zfs snapshot
$ACTIVE_DS@
$SNAPNAME
149 SNAPNUM
=`expr $SNAPNUM + 1`
150 SNAPNAME
="${ZONENAME}_snap$SNAPNUM"
153 # NOTE: This artificially limits us to 100 clones of a "golden" zone
154 # into a same-named (test?) zone, unless clones are based on some
155 # same snapshot via command-line
156 if [ $SNAPNUM -ge 100 ]; then
157 fail_fatal
"$f_zfs_create"
164 while [ $BENUM -lt 100 ]; do
165 /usr
/sbin
/zfs clone
$ACTIVE_DS@
$SNAPNAME $zpds/$zpname/ROOT
/$BENAME
169 BENUM
=`expr $BENUM + 1`
173 if [ $BENUM -ge 100 ]; then
174 fail_fatal
"$f_zfs_create"
177 /usr
/sbin
/zfs
set $PROP_ACTIVE=on
$zpds/$zpname/ROOT
/$BENAME || \
178 fail_incomplete
"$f_zfs_create"
180 /usr
/sbin
/zfs
set $PROP_PARENT=$CURRENT_GZBE $zpds/$zpname/ROOT
/$BENAME || \
181 fail_incomplete
"$f_zfs_create"
183 /usr
/sbin
/zfs
set canmount
=noauto
$zpds/$zpname/ROOT
/$BENAME || \
184 fail_incomplete
"$f_zfs_create"
186 if [ ! -d $ZONEPATH/root
]; then
187 /usr
/bin
/mkdir
-p $ZONEPATH/root
188 /usr
/bin
/chmod 700 $ZONEPATH
194 if [ x
"$NO_SYSUNCONFIG" = xyes
]; then
197 zoneadm
-z $ZONENAME mount
-f || fatal
"$e_badmount"
203 exit $ZONE_SUBPROC_OK