1 #!/usr/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 (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 # Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 # Use is subject to license terms. 24 # 25 # Script to install MilaX 0.4 26 # by Alexander R. Eremin <eremin (at] milax.org> 27 # May 29 2009. 28 # 29 30 31 PATH=/sbin:/usr/sbin:/usr/bin:$PATH 32 export PATH 33 34 PART=/tmp/part.$$ 35 SETACT=/tmp/setact.$$ 36 NUMSECT=/tmp/numsect.$$ 37 MINIMAL_SIZE=500 38 home=/usr/dss/share/hdinstall 39 ROOT_POOL=milax 40 ROOT_FILESYSTEM=rootfs 41 ZFSROOT=/zfsroot 42 declare -a DISKLIST 43 44 # preparing partition 45 preparepart() { 46 47 dev=$1 48 dsk=$2 49 acyls=$(prtvtoc $dsk | awk '/accessible/{print $2 }') 50 cyls=$((acyls - 1)) 51 format $dev >/dev/null <<EOF 52 partition 53 0 54 root 55 wm 56 57 ${cyls}e 58 label 59 60 y 61 EOF 62 63 } 64 65 # get partition info 66 getpart() { 67 68 fdisk -W "$PART" /dev/rdsk/$1 69 cat "$PART"|grep -v '^*'|grep '[0-9]' 70 rm -f "$PART" 71 } 72 73 # check Solaris2 partition 74 checkpart() { 75 76 disk=$1 77 exist=1 78 for item in $(getpart $disk | awk '{print $1}') 79 do 80 if [[ "$item" == 191 ]]; then 81 exist=0 82 fi 83 done 84 return $exist 85 86 } 87 88 # creating ZFS pool, installing packages and configuring system 89 zfsinstall() { 90 91 dev=$1 92 dsk=/dev/dsk/$dev 93 rdsk=/dev/rdsk/$dev 94 preparepart $dev $dsk 95 96 scdev=$(echo $dsk|sed -e 's/p0/s0/') 97 sbdev=$(echo $rdsk|sed -e 's/p0/s0/') 98 99 # Ensure we have things unmounted 100 umount -f $scdev 2>/dev/null >/dev/null 101 102 if [[ -z "${ROOT_FS}" ]] 103 then 104 # make our root pool and file system 105 GOT_ROOT=$( zpool list | grep $ROOT_POOL ) 106 if [[ -z "${GOT_ROOT}" ]] 107 then 108 zpool create -f "${ROOT_POOL}" $scdev 109 if [[ $? != 0 ]] 110 then 111 echo "Sorry, unable to create root pool with zpool options $scdev. Exiting now." 112 exit 1 113 fi 114 else 115 echo "Sorry ZFS pool \"${ROOT_POOL}\" already exists. Recreate it? [Yes|No]" 116 while read answer 117 do 118 case "$answer" in 119 Yes|yes|Y) 120 sleep 2 121 # removing old pool 122 zpool destroy -f "${ROOT_POOL}" 123 # creating new pool 124 zpool create -f "${ROOT_POOL}" $scdev 125 if [[ $? != 0 ]] 126 then 127 echo "Sorry, unable to create root pool with zpool options $scdev. Exiting now." 128 exit 1 129 fi 130 break 131 ;; 132 No|no|N) 133 echo "ZFS pool "${ROOT_POOL}" exists.You must destroy it before installing" 134 exit 1 135 ;; 136 *) 137 echo "Choices are Yes, No" 138 continue 139 ;; 140 esac 141 done 142 143 fi 144 # creating zfs filesystem 145 zfs set compression=on "$ROOT_POOL" 146 zfs create -p "${ROOT_POOL}/${ROOT_FILESYSTEM}" 147 ROOT_FS="${ROOT_POOL}/${ROOT_FILESYSTEM}" 148 fi 149 150 151 zfs set mountpoint=legacy "$ROOT_FS" 152 153 # making install directory 154 rm -rf "$ZFSROOT" 155 if [[ ! -d "$ZFSROOT" ]] 156 then 157 mkdir "$ZFSROOT" 158 else 159 echo "Sorry "$ZFSROOT" already exists : exiting now in case we overwrite data" 160 exit 1 161 fi 162 mount -F zfs "$ROOT_FS" "$ZFSROOT" 163 if [[ $? != 0 ]] 164 then 165 echo "Unable to mount ZFS root filesystem on "$ZFSROOT". Exiting now." 166 exit 1 167 fi 168 169 # start copying main data over to it 170 echo "Starting to copy data from UFS root to $ZFSROOT - this may take some time." 171 cd / 172 find . -xdev -depth | cpio -pdm $ZFSROOT 2>/dev/null >/dev/null 173 # libc! 174 cp -rP /lib/libc.so* $ZFSROOT/lib 2>/dev/null >/dev/null 175 176 mkdir -p $ZFSROOT/alex 177 cd /alex 178 find . -xdev -depth | cpio -pdm /$ZFSROOT/alex 2>/dev/null >/dev/null 179 mkdir -p $ZFSROOT/root 180 cd /root 181 find . -xdev -depth | cpio -pdm $ZFSROOT/root 2>/dev/null >/dev/null 182 183 mkdir -p $ZFSROOT/usr 184 cd /usr 185 find . -xdev -depth | cpio -pdm $ZFSROOT/usr 2>/dev/null >/dev/null 186 187 mkdir -p $ZFSROOT/system/object 188 mkdir -p $ZFSROOT/system/contract 189 mkdir -p $ZFSROOT/mnt 190 mkdir -p $ZFSROOT/tmp 191 mkdir -p $ZFSROOT/proc 192 mkdir -p $ZFSROOT/var/run 193 mkdir -p $ZFSROOT/dev/fd 194 touch $ZFSROOT/etc/mnttab 195 touch $ZFSROOT/etc/dfs/sharetab 196 197 chmod 555 $ZFSROOT/system/object 198 chmod 555 $ZFSROOT/system/contract 199 chmod 555 $ZFSROOT/proc 200 chmod 777 $ZFSROOT/tmp 201 chmod 755 $ZFSROOT/etc/svc/volatile 202 chmod 755 $ZFSROOT/var/run 203 chmod 555 $ZFSROOT/dev/fd 204 chmod 444 $ZFSROOT/etc/mnttab 205 chmod 755 $ZFSROOT/mnt 206 chmod 755 $ZFSROOT/usr 207 chmod 755 $ZFSROOT/alex 208 chmod 755 $ZFSROOT/root 209 chown -R alex:adm $ZFSROOT/alex 210 chown root $ZFSROOT/system/object 211 chown root $ZFSROOT/system/contract 212 chown root $ZFSROOT/proc 213 chown root $ZFSROOT/tmp 214 chown root $ZFSROOT/etc/svc/volatile 215 chown root $ZFSROOT/var/run 216 chown root $ZFSROOT/dev/fd 217 chown root $ZFSROOT/etc/mnttab 218 219 chgrp root $ZFSROOT/system/object 220 chgrp root $ZFSROOT/system/contract 221 chgrp sys $ZFSROOT/tmp 222 chgrp root $ZFSROOT/proc 223 chgrp sys $ZFSROOT/etc/svc/volatile 224 chgrp sys $ZFSROOT/var/run 225 chgrp root $ZFSROOT/dev/fd 226 chgrp root $ZFSROOT/etc/mnttab 227 228 # now populate the devices and /dev directories in $ZFSROOT 229 # do this by lofs mounting / and pulling the files directly 230 mkdir -p /zfs-root-tmp.$$ 231 mount -F lofs -o nosub / /zfs-root-tmp.$$ 232 (cd /zfs-root-tmp.$$; tar cf - devices dev ) | (cd $ZFSROOT; tar xfp -) 2>/dev/null >/dev/null 233 cd / 234 umount /zfs-root-tmp.$$ 235 rm -rf /zfs-root-tmp.$$ 236 237 # copy last etc 238 cd /etc 239 tar cf - . | (cd $ZFSROOT/etc ; tar xfp -) 2>/dev/null >/dev/null 240 241 # rebuild svc at first boot 242 # rm -f $ZFSROOT/var/svc/manifest/system/filesystem/live-root-fs.xml 243 # rm -f $ZFSROOT/var/svc/manifest/system/dss-sysidtool.xml 244 # rm -f $ZFSROOT/var/svc/manifest/system/live-sysidtool.xml 245 # cp $home/misc/root-fs.xml $ZFSROOT/var/svc/manifest/system/filesystem/ 246 # cp /lib/svc/seed/global.db $ZFSROOT/etc/svc/repository.db 247 rm $ZFSROOT/lib/svc/method/live-fs-root 248 cd $ZFSROOT/lib/svc/method/ 249 ln -s fs-root live-fs-root 250 cd / 251 252 # copy vfstab 253 cp $home/misc/vfstab $ZFSROOT/etc/vfstab 254 255 256 ROOT_DSK=$(df -h / | tail -1 | awk '{print $1}') 257 ROOT_RDSK=$(echo $ROOT_DSK | sed -e 's/dsk/rdsk/g') 258 259 echo "Updating vfstab" 260 printf "${ROOT_FS}\t-\t/\tzfs\t-\tno\t-\n" >> $ZFSROOT/etc/vfstab 261 262 # Update bootarchive, and set the bootfs property on the root pool 263 echo "etc/zfs/zpool.cache" >> $ZFSROOT/boot/solaris/filelist.ramdisk 264 zpool set bootfs=$ROOT_FS $ROOT_POOL 265 266 echo "Creating boot_archive" 267 mkdir $ZFSROOT/platform/i86pc/amd64 268 /usr/sbin/bootadm update-archive -R $ZFSROOT 2>/dev/null >/dev/null 269 270 # Put a grub menu.lst into the root pool 271 mkdir -p /$ROOT_POOL/boot/grub 272 cp $home/misc/menu.lst /$ROOT_POOL/boot/grub 273 cp /.cdrom/boot/grub/splash.xpm.gz $ZFSROOT/boot/grub 274 275 # Now, work out from our arguments, which is a disk, installing grub on the 276 # 1st one that we find 277 if [ -e $sbdev ] 278 then 279 echo "Installing grub on $sbdev" 280 installgrub $ZFSROOT/boot/grub/stage1 $ZFSROOT/boot/grub/stage2 $sbdev 281 fi 282 283 # all done 284 echo 285 echo "MilaX installation is complete." 286 287 } 288 289 # main procedure 290 main() { 291 292 clear 293 294 # Make sure only root can run our script 295 if [ "$(id -u)" != "0" ]; then 296 echo "This script must be run as root" 297 exit 1 298 fi 299 # 300 # Examine memory requirements 301 # 302 303 # get available virtual memory in megabytes 304 VIRTMEM=`/sbin/mem`; VIRTMEM=`expr $VIRTMEM / 1024` 305 306 # get total physical memory in megabytes 307 PHYSMEM=`/usr/sbin/prtconf | grep '^Memory size: ' | sed -e 's/^Memory size: //' -e 's/ .*$//' ` 308 309 MEMUNIT=`/usr/sbin/prtconf | grep '^Memory size: ' | sed -e 's/^Memory size: [0-9][0-9]* //' ` 310 311 case $MEMUNIT in 312 Kilobytes) PHYSMEM=`expr $PHYSMEM / 1024` ;; 313 Megabytes) ;; 314 Gigabytes) PHYSMEM=`expr $PHYSMEM \* 1024` ;; 315 Terabytes) PHYSMEM=`expr $PHYSMEM \* 1024 \* 1024` ;; 316 *) PHYSMEM=0 ;; 317 esac 318 319 export PHYSMEM 320 MIN_INSTALL_PHYSMEM=256 321 322 if [ "$PHYSMEM" -lt "$MIN_INSTALL_PHYSMEM" ] ; then 323 echo "This installer requires a minimum of $MIN_INSTALL_PHYSMEM MB of physical memory" 324 echo "to install. This system only has $PHYSMEM MB of physical memory." 325 echo 326 echo "Exiting to shell" 327 exit 328 fi 329 330 echo "Starting zfsinstall script which installs MilaX" 331 echo 332 333 334 335 # checking disks 336 HAVEDISK=$(echo q |format 2>&1 | egrep "[0-9]") 337 if [[ -z "$HAVEDISK" ]]; then 338 echo "No hard disk found." 339 exit 1 340 fi 341 342 # find target disk 343 echo "Found the following disks:" 344 i=0 345 for item in $(echo q | format -e 2>&1 | egrep "c[0-9]+" | nawk '{ print $2 }') 346 do 347 disk=/dev/rdsk/${item}p0 348 DISKLIST[$i]=$item 349 ((i++)) 350 fdisk -G $disk | tail -1 | nawk '{ 351 n=" '$i'" 352 disk="'$disk'" 353 ncyl=$2 354 nhead=$5 355 nsect=$6 356 secsz=$7 357 sectors=ncyl*nhead*nsect; 358 bytes=sectors/(1024/secsz); 359 printf("%d %7d MB %s\n",n, bytes/1024, disk); 360 }' 361 done 362 363 while read -p "On which disk do you want to install system: " choice 364 do 365 if [[ -z "${choice}" ]]; then 366 continue 367 fi 368 if [[ $choice -eq 0 ]] || [[ $choice -gt $i ]]; then 369 echo "$i Invalid choice" 370 continue 371 fi 372 break 373 done 374 375 i=0 376 for item in "${DISKLIST[@]}" 377 do 378 ((i++)) 379 if [[ $choice -eq $i ]]; then 380 dev=${item}p0 381 fi 382 done 383 384 if [[ ! -n "$dev" ]]; then 385 echo "Sorry, no disks selected" 386 exit 1 387 fi 388 389 # check and create Solaris2 partition 390 if ! checkpart $dev; then 391 echo "No solaris partition found on $dev" 392 echo "Use entire disk? (All data will be lost) [Yes|No]" 393 while read answer 394 do 395 case "$answer" in 396 Yes|yes|Y) 397 fdisk -B /dev/rdsk/$disk 398 break 399 ;; 400 No|no|N) 401 echo "You must create solaris partition manually" 402 echo "Press any key to run fdisk" 403 read 404 fdisk /dev/rdsk/$disk 405 break 406 ;; 407 *) 408 echo "Choices are Yes, No" 409 continue 410 ;; 411 esac 412 done 413 fi 414 415 # no partition 416 if ! checkpart $dev; then 417 echo "No solaris partition found on $dev, exiting" 418 exit 1 419 fi 420 421 # check active partition 422 partn=0 423 getpart $disk | while read Id Act Bhead Bsect Bcyl Ehead Esect Ecyl Rsect Numsect 424 do 425 let partn=$partn+1 426 if [[ $Id == 191 ]]; then 427 echo $Numsect > "$NUMSECT" 428 if [ $Act != 128 ]; then 429 echo 2 > "$SETACT" 430 echo $partn >> "$SETACT" 431 echo 5 >> "$SETACT" 432 fi 433 fi 434 done 435 436 # check partition size 437 numsect=$(cat "$NUMSECT") 438 rm -f "$NUMSECT" 439 psize=$(fdisk -G /dev/rdsk/$disk| tail -1 | awk "{print \$7*$numsect}") 440 let psize=$psize/1024/1024 441 if [[ "$psize" -lt "$MINIMAL_SIZE" ]];then 442 echo "$psize Not enough free space. At least 1GB required" 443 fi 444 445 if [[ -f "$SETACT" ]]; then 446 echo "Partition is not active. Activate? [Yes|No]" 447 while read answer 448 do 449 case "$answer" in 450 Yes|yes|Y] ) 451 cat "$SETACT" | fdisk /dev/rdsk/$dev 2>&1 >/dev/null 452 rm -f "$SETACT" 453 break 454 ;; 455 No|no|N] ) 456 echo "You must activate partition before reboot" 457 break 458 ;; 459 *) 460 echo "Choices are Yes, No" 461 continue 462 ;; 463 esac 464 done 465 fi 466 rm -f "$SETACT" 467 468 echo "System will be installed on $dev. Continue? [Yes|No]" 469 while read answer 470 do 471 case "$answer" in 472 Yes|yes|Y ) 473 zfsinstall $dev 474 break 475 ;; 476 No|no|N) 477 echo "Bye!" 478 exit 0 479 ;; 480 *) 481 echo "Choices are Yes, No" 482 continue 483 ;; 484 esac 485 done 486 exit 0 487 } 488 489 # call main procedure 490 main 491