1 #!/bin/bash
   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, Version 1.0 only
   7 # (the "License").  You may not use this file except in compliance
   8 # with the License.
   9 #
  10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11 # or http://www.opensolaris.org/os/licensing.
  12 # See the License for the specific language governing permissions
  13 # and limitations under the License.
  14 #
  15 # When distributing Covered Code, include this CDDL HEADER in each
  16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17 # If applicable, add the following below this CDDL HEADER, with the
  18 # fields enclosed by brackets "[]" replaced with your own identifying
  19 # information: Portions Copyright [yyyy] [name of copyright owner]
  20 #
  21 # CDDL HEADER END
  22 #
  23 #
  24 # Copyright 2012 OmniTI Computer Consulting, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 fail() {
  28         echo "ERROR: $*"
  29         exit 1
  30 }
  31 
  32 # NOTE --> The URL needs to be updated with every release.
  33 # Change "bloody" to whatever release the current branch is.
  34 PUBLISHER=omnios
  35 : ${PKGURL:=http://pkg.omniti.com/omnios/bloody}
  36 : ${GZIP_CMD:=gzip}
  37 SRCDIR=$(dirname $0)
  38 DIDWORK=0
  39 BUILDNUM=${VERSION//r/}
  40 if [[ ${SRCDIR:0:1} != "/" ]]; then
  41   SRCDIR=`pwd`/$SRCDIR
  42 fi
  43 if [[ -z "${1}" ]]; then
  44   echo "$0 <zfs pool> [checkpoint]"
  45   exit 1
  46 else
  47   BASE=${1}
  48   shift
  49   BASEDIR=`zfs get -o value -H mountpoint $BASE`
  50 fi
  51 MKFILEDIR=/tmp
  52 WORKDIR=$BASEDIR
  53 ROOTDIR=$WORKDIR/root
  54 if [[ ! -d $ROOTDIR ]]; then
  55   zfs create -o compression=off $BASE/root || fail "zfs create failed"
  56 fi
  57 SVCCFG_DTD=${ROOTDIR}/usr/share/lib/xml/dtd/service_bundle.dtd.1
  58 SVCCFG_REPOSITORY=${ROOTDIR}/etc/svc/repository.db
  59 SVCCFG=/usr/sbin/svccfg
  60 export WORKDIR ROOTDIR SVCCFG_DTD SVCCFG_REPOSITORY SVCCFG
  61 
  62 # This was uber-helpful
  63 # http://alexeremin.blogspot.com/2008/12/preparing-small-miniroot-with-zfs-and.html
  64 
  65 PKG=/bin/pkg
  66 
  67 UNNEEDED_MANIFESTS="application/management/net-snmp.xml
  68         application/pkg/pkg-server.xml application/pkg/pkg-mdns.xml
  69         system/rmtmpfiles.xml system/mdmonitor.xml
  70         system/fm/notify-params.xml system/device/allocate.xml
  71         system/device/devices-audio.xml system/auditd.xml
  72         system/metasync.xml system/pkgserv.xml system/fcoe_initiator.xml
  73         system/metainit.xml system/zonestat.xml
  74         system/cron.xml system/rbac.xml system/sac.xml
  75         system/auditset.xml system/hotplug.xml
  76         system/wusb.xml system/zones.xml
  77         system/intrd.xml system/coreadm.xml
  78         system/extended-accounting.xml
  79         system/scheduler.xml
  80         system/logadm-upgrade.xml system/resource-mgmt.xml
  81         system/idmap.xml
  82         network/ldap/client.xml network/shares/reparsed.xml
  83         network/shares/group.xml network/inetd-upgrade.xml
  84         network/smb/client.xml network/smb/server.xml
  85         network/network-iptun.xml network/ipsec/policy.xml
  86         network/ipsec/ipsecalgs.xml network/ipsec/ike.xml
  87         network/ipsec/manual-key.xml network/forwarding.xml
  88         network/inetd.xml network/npiv_config.xml
  89         network/ssl/kssl-proxy.xml network/rpc/metamed.xml
  90         network/rpc/mdcomm.xml network/rpc/gss.xml
  91         network/rpc/bind.xml network/rpc/keyserv.xml
  92         network/rpc/meta.xml network/rpc/metamh.xml
  93         network/socket-filter-kssl.xml network/network-netcfg.xml
  94         network/nfs/status.xml network/nfs/cbd.xml
  95         network/nfs/nlockmgr.xml network/nfs/mapid.xml
  96         network/nfs/client.xml network/network-ipqos.xml
  97         network/security/ktkt_warn.xml network/security/krb5kdc.xml
  98         network/security/kadmin.xml network/network-install.xml
  99         network/bridge.xml network/network-initial.xml
 100         network/network-ipmgmt.xml network/routing/legacy-routing.xml
 101         network/network-service.xml network/network-physical.xml
 102         network/network-netmask.xml network/dlmgmt.xml
 103         network/network-location.xml network/ibd-post-upgrade.xml
 104         network/network-routing-setup.xml network/network-loopback.xml
 105         network/dns/client.xml network/dns/install.xml
 106         network/dns/multicast.xml platform/i86pc/acpihpd.xml
 107         system/hostid.xml system/power.xml system/pfexecd.xml
 108         system/consadm.xml system/pools.xml system/console-login.xml
 109         system/stmf.xml system/fmd.xml system/utmp.xml
 110         system/poold.xml system/dumpadm.xml"
 111 
 112 SYSTEM="system/boot/grub system/boot/real-mode system/boot/wanboot/internal
 113         system/boot/wanboot system/data/hardware-registry
 114         system/data/keyboard/keytables system/data/terminfo
 115         system/data/zoneinfo system/extended-system-utilities
 116         system/file-system/autofs system/file-system/nfs
 117         system/file-system/smb system/file-system/udfs
 118         system/file-system/zfs system/flash/fwflash
 119         system/fru-id/platform system/fru-id system/ipc
 120         system/kernel/dynamic-reconfiguration/i86pc
 121         system/kernel/security/gss system/library/math
 122         system/library/platform system/library/policykit
 123         system/library/processor
 124         system/library/storage/fibre-channel/hbaapi
 125         system/library/storage/fibre-channel/libsun_fc
 126         system/library/storage/ima/header-ima
 127         system/library/storage/ima
 128         system/library/storage/libmpapi
 129         system/library/storage/libmpscsi_vhci
 130         system/library/storage/scsi-plugins
 131         system/library system/network
 132         system/prerequisite/gnu system/storage/luxadm
 133         system/storage/fibre-channel/port-utility"
 134 
 135 DEBUG_PKGS="developer/debug/mdb system/dtrace developer/dtrace"
 136 
 137 DRIVERS="driver/audio driver/crypto/dca driver/crypto/tpm driver/firewire
 138         driver/graphics/agpgart driver/graphics/atiatom driver/graphics/drm
 139         driver/i86pc/fipe driver/i86pc/ioat driver/i86pc/platform
 140         driver/network/afe driver/network/amd8111s driver/network/atge
 141         driver/network/bfe driver/network/bge driver/network/bnx
 142         driver/network/bnxe driver/network/bpf driver/network/chxge
 143         driver/network/dmfe driver/network/e1000g driver/network/elxl
 144         driver/network/emlxs driver/network/eoib driver/network/fcip
 145         driver/network/fcp driver/network/fcsm driver/network/fp
 146         driver/network/hermon driver/network/hme driver/network/hxge
 147         driver/network/ib driver/network/ibdma driver/network/ibp
 148         driver/network/igb driver/network/iprb driver/network/ixgb
 149         driver/network/ixgbe driver/network/mxfe driver/network/myri10ge
 150         driver/network/nge driver/network/ntxn driver/network/nxge
 151         driver/network/ofk driver/network/pcn driver/network/platform
 152         driver/network/qlc driver/network/rds driver/network/rdsv3
 153         driver/network/rge driver/network/rpcib driver/network/rtls
 154         driver/network/sdp driver/network/sdpib driver/network/sfe
 155         driver/network/tavor driver/network/usbecm driver/network/vr
 156         driver/network/xge driver/network/yge driver/pcmcia driver/serial/pcser
 157         driver/serial/usbftdi driver/serial/usbsacm driver/serial/usbser
 158         driver/serial/usbser_edge driver/serial/usbsksp
 159         driver/serial/usbsksp/usbs49_fw driver/serial/usbsprl
 160         driver/storage/aac driver/storage/adpu320 driver/storage/ahci
 161         driver/storage/amr driver/storage/arcmsr driver/storage/ata
 162         driver/storage/bcm_sata driver/storage/blkdev driver/storage/cpqary3
 163         driver/storage/glm driver/storage/lsimega driver/storage/marvell88sx
 164         driver/storage/mega_sas driver/storage/mpt_sas driver/storage/mr_sas
 165         driver/storage/nv_sata driver/storage/pcata driver/storage/pmcs
 166         driver/storage/sbp2 driver/storage/scsa1394 driver/storage/sdcard
 167         driver/storage/ses driver/storage/si3124 driver/storage/smp
 168         driver/usb driver/usb/ugen driver/xvm/pv"
 169 
 170 PARTS="release/name release/notices service/picl install/beadm SUNWcs SUNWcsd
 171         library/libidn shell/pipe-viewer text/less /network/ssh editor/vim
 172         developer/linker file/gnu-coreutils"
 173 
 174 PKGS="$PARTS $SYSTEM $DRIVERS"
 175 
 176 if [ -n "$DEBUG" ]; then
 177         PKGS="$PKGS $DEBUG_PKGS"
 178         BIGROOT=1
 179 fi
 180 CULL="perl python package/pkg snmp"
 181 RMRF="/var/pkg /usr/share/man /usr/lib/python2.6 /usr/lib/iconv"
 182 
 183 ID=`id -u`
 184 if [[ "$ID" != "0" ]]; then
 185         echo "must run as root"
 186         exit 1
 187 fi
 188 
 189 chkpt() {
 190         SNAP=`zfs list -H -t snapshot $BASE/root@${1} 2> /dev/null`
 191         if [[ "$DIDWORK" -ne "0" ]]; then
 192                 if [[ -n "$SNAP" ]]; then
 193                         zfs destroy $BASE/root@${1} || \
 194                                 fail "zfs destroy ${1} failed"
 195                 fi
 196                 zfs snapshot $BASE/root@${1} || fail "zfs snapshot failed"
 197         fi
 198         if [[ "${1}" != "begin" ]]; then
 199                 echo " === Proceeding to phase $1 (zfs @${1}) ==="
 200                 zfs rollback -r $BASE/root@${1} || fail "zfs rollback failed"
 201         else
 202                 echo " === Proceeding to phase $1 ==="
 203         fi
 204         CHKPT=$1
 205         DIDWORK=1
 206 }
 207 
 208 if [[ -n "$1" ]]; then
 209         echo "Explicit checkpoint requested: '$1'"
 210         CHKPT=$1
 211         chkpt $CHKPT
 212 fi
 213 if [[ -z "$CHKPT" ]]; then
 214         CHKPT="begin"
 215 fi
 216 
 217 declare -A keep_list
 218 load_keep_list() {
 219         for datafile in $*
 220         do
 221                 FCNT=0
 222                 while read file
 223                 do
 224                         if [[ -n "$file" ]]; then
 225                                 keep_list+=([$file]="x")
 226                                 FCNT=$(($FCNT + 1))
 227                         fi
 228                 done < <(cut -f2- -d/ $datafile)
 229                 echo " --- keeping $FCNT files from $datafile"
 230         done
 231 }
 232 
 233 step() {
 234         CHKPT=""
 235         case "$1" in
 236 
 237         "begin")
 238         zfs destroy -r $BASE/root 2> /dev/null
 239         zfs create -o compression=off $BASE/root || fail "zfs create failed"
 240         chkpt pkg
 241         ;;
 242 
 243         "pkg")
 244 
 245         echo "Creating image of $PUBLISHER from $PKGURL"
 246         $PKG image-create -F -p $PUBLISHER=$PKGURL $ROOTDIR || fail "image-create"
 247         # If a version was requested, respect it
 248         if [[ -n $BUILDNUM ]]; then
 249                 $PKG -R $ROOTDIR install illumos-gate@11-0.$BUILDNUM omnios-userland@11-0.$BUILDNUM || fail "version constraint prep"
 250         fi
 251         $PKG -R $ROOTDIR install $PKGS || fail "install"
 252         if [[ -n $BUILDNUM ]]; then
 253                 $PKG -R $ROOTDIR uninstall illumos-gate omnios-userland || fail "version constraint cleanup"
 254         fi
 255         chkpt fixup
 256         ;;
 257 
 258         "fixup")
 259 
 260         echo "Fixing up install root"
 261         (cp $ROOTDIR/etc/vfstab $WORKDIR/vfstab && \
 262                 awk '{if($3!="/"){print;}}' $WORKDIR/vfstab > $ROOTDIR/etc/vfstab && \
 263                 echo "/devices/ramdisk:a - / ufs - no nologging" >> $ROOTDIR/etc/vfstab) || \
 264                 fail "vfstab / updated"
 265         rm $WORKDIR/vfstab
 266         cp $ROOTDIR/lib/svc/seed/global.db $ROOTDIR/etc/svc/repository.db
 267 
 268         sed -i 's,PASSREQ=YES,PASSREQ=NO,' $ROOTDIR/etc/default/login
 269 
 270         ${SVCCFG} import ${ROOTDIR}/lib/svc/manifest/milestone/sysconfig.xml
 271         for xml in $UNNEEDED_MANIFESTS; do
 272                 rm -f ${ROOTDIR}/lib/svc/manifest/$xml && echo " --- tossing $xml"
 273         done
 274         echo " --- initial manifest import"
 275         ${ROOTDIR}/lib/svc/method/manifest-import -f ${ROOTDIR}/etc/svc/repository.db \
 276                 -d ${ROOTDIR}/lib/svc/manifest
 277 
 278         ${SVCCFG} -s 'system/boot-archive' setprop 'start/exec=:true'
 279         ${SVCCFG} -s 'system/manifest-import' setprop 'start/exec=:true'
 280         ${SVCCFG} -s "system/intrd:default" setprop "general/enabled=false"
 281         ${SVCCFG} -s "system/initial-boot" setprop "start/timeout_seconds=600"
 282         echo " --- nuetering the manifest import"
 283         echo "#!/bin/ksh" > ${ROOTDIR}/lib/svc/method/manifest-import
 284         echo "exit 0" >> ${ROOTDIR}/lib/svc/method/manifest-import
 285         chmod 555 ${ROOTDIR}/lib/svc/method/manifest-import
 286         chkpt cull
 287         ;;
 288 
 289         "cull")
 290         if [[ -z "$BIGROOT" ]]; then
 291                 load_keep_list data/*
 292                 while read file
 293                 do
 294                         if [[ -n "$file" && \
 295                               ${keep_list[$file]} == "" && \
 296                               -e "$ROOTDIR/$file" && \
 297                               ! -d $ROOTDIR/$file ]] ; then
 298                                 rm -f $ROOTDIR/$file
 299                         fi
 300                 done < <(cd $ROOTDIR && find ./ | cut -c3-)
 301                 for path in $RMRF ; do
 302                         rm -rf ${ROOTDIR}$path && echo " -- tossing $path"      
 303                 done
 304         fi
 305 
 306         chkpt mkfs
 307         ;;
 308 
 309         "mkfs")
 310         size=`/usr/bin/du -ks ${ROOTDIR}|/usr/bin/nawk '{print $1+10240}'`
 311         echo " --- making image of size $size"
 312         /usr/sbin/mkfile ${size}k $MKFILEDIR/miniroot || fail "mkfile"
 313         lofidev=`/usr/sbin/lofiadm -a $MKFILEDIR/miniroot`
 314         rlofidev=`echo $lofidev |sed s/lofi/rlofi/`
 315         yes | /usr/sbin/newfs -m 0 $rlofidev 2> /dev/null > /dev/null || fail "newfs"
 316         chkpt mount
 317         ;;
 318 
 319         "mount")
 320         mkdir -p $WORKDIR/mnt
 321         /usr/sbin/mount -o nologging $lofidev $WORKDIR/mnt || fail "mount"
 322         chkpt copy
 323         ;;
 324 
 325         "copy")
 326         pushd $ROOTDIR >/dev/null
 327         /usr/bin/find . | /usr/bin/cpio -pdum $WORKDIR/mnt 2> /dev/null > /dev/null || fail "populate root"
 328         /usr/sbin/devfsadm -r $WORKDIR/mnt > /dev/null
 329         popd >/dev/null
 330         mkdir $WORKDIR/mnt/kayak
 331         cp $SRCDIR/*.sh $WORKDIR/mnt/kayak/
 332         chmod a+x $WORKDIR/mnt/kayak/*.sh
 333         make_initial_boot $WORKDIR/mnt/.initialboot
 334         if [[ -n "$DEBUG" ]]; then
 335                 cp $SRCDIR/anon.system $WORKDIR/mnt/etc/system
 336                 cp $SRCDIR/anon.dtrace.conf $WORKDIR/mnt/kernel/drv/dtrace.conf
 337         fi
 338         chkpt umount
 339         ;;
 340 
 341         "umount")
 342         /usr/sbin/umount $WORKDIR/mnt || fail "umount"
 343         /usr/sbin/lofiadm -d $MKFILEDIR/miniroot || fail "lofiadm delete"
 344         chkpt compress
 345         ;;
 346 
 347         "compress")
 348         $GZIP_CMD -c -f $MKFILEDIR/miniroot > $WORKDIR/miniroot.gz
 349         rm -f $MKFILEDIR/miniroot
 350         chmod 644 $WORKDIR/miniroot.gz
 351         echo " === Finished ==="
 352         ls -l $WORKDIR/miniroot.gz
 353         ;;
 354 
 355         esac
 356 }
 357 
 358 make_initial_boot() {
 359 FILE=$1
 360 cat > $FILE <<EOF
 361         /kayak/install_image.sh
 362         exit \$?
 363 EOF
 364 }
 365 
 366 while [[ -n "$CHKPT" ]]; do
 367         step $CHKPT
 368 done