Thursday, December 31, 2009

[Level 3] Clone ZFS Permissions

One day, someone ask me how to clone ZFS permissions from one ZFS file system to another ZFS file system.
It seems that zfs command doesnot support the permission like getfacl setfacl to clone the file system permissions.
Therefore I try to write a script to implement that,
please refer to the following code.

#!/usr/bin/bash
showUsage() {
  cat <<EOF
Usage:
  $0 source_zfs target_zfs
Ex.
  $0 rpool/fs1 karajon/fs2
EOF
}

##################################### main

sSZFS=$1
sTZFS=$2
declare -i fPermSet=0
declare -i fLocalPerm=0

zfs allow $sSZFS | while read s
do
  ( echo $s | grep "^---- Permissions on " > /dev/null ) && continue
  ( echo $s | grep "^Permission sets:$" > /dev/null ) && fPermSet=1 && fLocalPerm=0 && continue
  ( echo $s | grep "^Local+Descendent permissions:$" > /dev/null ) && fLocalPerm=1 && fPermSet=0 && continue
  if [ $fPermSet -eq 1 ]
  then
    echo "zfs allow -s $s $sTZFS"

    zfs allow -s $s $sTZFS

  elif [ $fLocalPerm -eq 1 ]
  then
    echo "zfs allow -u ${s#user } $sTZFS"

    zfs allow -u ${s#user } $sTZFS

  fi
done



Wish this helps.

regards,
Stanley Huang

Wednesday, December 30, 2009

[Level 2] MySQL Query with Regular Expression.

If you  want to let your query more powerful,
you can use regular expression to enhance your SQL query.

mysql> create table testRegExp (name varchar(32));
mysql> insert into testRegExp values('Stanley'),('Christy'),('Joseph'),('Chantelle');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from testRegExp where name regexp '^(S|C)';
+-----------+
| name      |
+-----------+
| Stanley   |
| Christy   |
| Chantelle |
+-----------+
3 rows in set (0.00 sec)

mysql> 


Ref:
http://dev.mysql.com/doc/refman/5.1/en/regexp.html

Wish this helps.

regards,
Stanley Huang

Sunday, December 27, 2009

[Level 2] MySQL XML Functions.

One day, a friends of mine asked me if MySQL support XML?
Actually, MySQL havs two XML functions, called "ExtractValue" and "UpdateValue".
You can use these two function as the following samples:


mysql> CREATE TABLE persons (
id int auto_increment primary key,
data text
);



mysql> INSERT INTO persons(data) values
('
<person>
  <name>stanley</name>
  <sex>m</sex>
  <addr>taipei</addr>
  <tels>
    <tel>12340001</tel>
    <tel>12340002</tel>
    <tel>12340003</tel>
  </tels>
</person>
'),
('
<person>
  <name>joseph</name>
  <sex>m</sex>
  <addr>taipei</addr>
  <tels>
    <tel>12350001</tel>
    <tel>12350002</tel>
    <tel>12350003</tel>
  </tels>
</person>
');


mysql> select
ExtractValue(data,'//person/tels/tel[1]'),
ExtractValue(data,'/person/tels/tel[2]'),
ExtractValue(data,'person/tels/tel[3]')
from persons
where id=1\G

*************************** 1. row ***************************
ExtractValue(data,'//person/tels/tel[1]'): 12340001
ExtractValue(data,'/person/tels/tel[2]'): 12340002
ExtractValue(data,'person/tels/tel[3]'): 12340003


mysql> select
data,
ExtractValue(data,'//person/name'),
UpdateXML(data,'//person/name','<name>christy</name>'),
ExtractValue(UpdateXML(data,'//person/name','<name>christy</name>'),'//person/name')
from persons
where id=1\G

*************************** 1. row ***************************
data: stanleymtaipei123400011234000212340003
ExtractValue(data,'//person/name'): stanley
UpdateXML(data,'//person/name','<name>christy</name>'): <name>christy</name>mtaipei123400011234000212340003
ExtractValue(UpdateXML(data,'//person/name','<name>christy</name>'),'//person/name'): christy





Ref:
http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html
http://www.w3.org/TR/xpath
http://www.zvon.org/xxl/XPathTutorial/General/examples.html

Wish this helps.

regards,
Stanley Huang

Friday, December 18, 2009

[Level 1] MySQL 5.5 new features -- Semisynchronous Replication.

MySQL 5.5 m2 has released.
In m2, MySQL 5.5 has a great called "Semisynchronous Replication".
How the semi works?

1. First, the client connect to server and be indicated that is semi or not.
2. If semi is enable on server site and there is at least one client and waits untilone semi client acknowledges that it has received.


please refer to the following link for more info.


Wish this helps.

regards,
Stanley Huang

Tuesday, December 15, 2009

[Level 3] Using DTrace for MySQL DB.

I'm glade to here that, in MySQL 5.4 beta, it supports that to use Solaris DTrace to monitor MySQL SQL statement.


About the probe for MySQL, please refer to the following link:
http://dev.mysql.com/doc/refman/5.4/en/dba-dtrace-mysqld-ref.html

I use one of the scripts to demo the result of DTrace,
http://dev.mysql.com/doc/refman/5.4/en/dba-dtrace-ref-query.html

The result as below:
Sessin 1:
[stanley@Stanley-NB]:/usr/mysql# mysql

Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.4.3-beta MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

stanley@localhost:stanley mysql> show tables;
Empty set (0.00 sec)

stanley@localhost:stanley mysql>



Sessin 2:
root@Stanley-NB:/tmp# ./MySQL_query.d

Who                  Database             Query                                    Time(ms)
stanley@localhost    stanley              select @@version_comment limit 1         0       
stanley@localhost    stanley              select USER()                            0       
stanley@localhost    stanley              show tables                              2       


Wish this helps.

regards,
Stanley Huang

Thursday, December 10, 2009

[Level 3] Script for clone VirtualBox 3.1.0 .

Before, I wrote a script to clone VirtualBox with ZFS technology.
After new VirtualBox release, because of the architecture and command changed,
the previous script will occur error while running.
Therefore, I modify the script for version 3.1.0 later of VirtualBox.

#!/usr/bin/bash
showUsage() {
  cat <<EOF
Usage:
  $0 [c]reate/[d]elete New_Machine_Name Source_Machine_Name interface begin_index end_index
Ex.
  $0 [c]reate OS128a_MySQL OS128a yge0 1 10
  $0 [d]elete OS128a_MySQL OS128a yge0 1 10
  $0 [d]elete OS128a_MySQL OS128a yge0
VMMachine:
`showVMS | sed -e 's/^/  /'`
EOF
}

## Usage:
##   setUUID vdi_file
## Ex.
##   setUUID /Karajon/VBoxes/Guest/guest.vdi
setUUID() {
  sVDI=$1
  VBoxManage -q internalcommands setvdiuuid $sVDI
}

## Usage:
##   createVM vm_name os_type.
## Ex.
##   createVM S10u8_MySQL Solaris_64
## PS.
##   OS Type: Solaris Solaris_64 OpenSolaris OpenSolaris_64
createVM() {
  sVMName=$1
  sOSType=$2
  /opt/VirtualBox/VBoxManage -q createvm \
    --name $sVMName \
    --ostype $sOSType \
    --register
}

## Usage:
##   modifyVMNIC vm_name source_vm interface
## Ex.
##   modifyVMNIC S10u8_MySQL S10u8_Source yukonx0
modifyVMNIC() {
  sTVMName=$1
  sSVMName=$2
  sIF="$3 - Ethernet"
  sAttachedTo=bridged
  sAdapterType=82540EM
  while read n
  do
    /opt/VirtualBox/VBoxManage -q modifyvm $sTVMName \
      --nic$n $sAttachedTo \
      --nictype$n $sAdapterType \
      --cableconnected$n on \
      --bridgeadapter$n "$sIF"
  done <<EOF
  `VBoxManage -q showvminfo $sSVMName | grep -v disabled | grep "^NIC [1-4]:" | cut -d: -f1 | awk '{print($2)}'`
EOF
}

## Usage:
##   cloneStorageController target_vm source_vm
## Ex.
##   cloneStorageController S10u8_MySQL S10u8_Source
cloneStorageController() {
  sTVMName=$1
  sSVMName=$2
  declare -a aSC
  declare -i nCount=0
 
  VBoxManage -q showvminfo $sSVMName | grep -i "^Storage Controller .*:" | while read x
  do
    aSC[$nCount]="`echo $x | cut -d: -f2 | sed -e 's/^[ ]*//'`"
    nCount=$nCount+1
    if [ $nCount -eq 5 ]
    then
      sCT=`echo ${aSC[0]} | awk '{print($1)}' | tr [A-Z] [a-z]`
      VBoxManage -q storagectl $sTVMName \
        --name "${aSC[0]}" \
        --add $sCT \
        --controller ${aSC[1]}
      nCount=0
    fi
  done
}

## Usage:
##   modifyVM vm_name hda seq_no
## Ex.
##   modifyVM S10u8_MySQL /Karajon/VBox/$sVMName/$sVDI $nSeq
modifyVM() {
  sVMName=$1
  declare -i nMemory=768
  sHDA=$2
  #sDVD_ISO=/Karajon/ISOs/osol-1002-125-ai-x86.iso
 
  declare -i nVRDPport=3390+$3

  /opt/VirtualBox/VBoxManage -q modifyvm $sVMName \
    --memory $nMemory \
    --hda $sHDA \
    --boot1 disk --boot2 dvd \
    --audio solaudio --audiocontroller ac97 \
    --vrdp on --vrdpport $nVRDPport
    ## --dvd $sDVD_ISO \
}

## Usage:
##   startVM vm_name
## Ex.
##   startVM S10_U8
startVM() {
  sVMName=$1
  /opt/VirtualBox/VBoxManage -q startvm $sVMName
}

showVMS() {
  VBoxManage -q list vms
}

## Usage:
##   getVMOSType vm_name
## Ex.
##   getVMOSType OS111b_MySQL
getVMOSType() {
  sVMName=$1
  sOSType=""
  sGuestOS=`VBoxManage -q showvminfo $sVMName | grep "^Guest OS:" | cut -d: -f2`
  sOS=`echo $sGuestOS | awk '{print($1)}'`
  declare -i nVer=`echo $sGuestOS | cut -d\( -f2 | cut -d' ' -f1`
  sOSType="$sOS"_"$nVer"
  echo "$sOSType"
}

## Usage:
##   getVMHDA vm_name
## Ex.
##   getVMHDA OS111b_MySQL
getVMHDA() {
  sHDAFilter='IDE Controller (0, 0):'
  sVMName=$1
  sHDA=`VBoxManage -q showvminfo $sVMName | grep "^$sHDAFilter" | cut -d: -f2 | awk '{print($1)}'`
  echo $sHDA
}

## Usage:
##   getZFS vdi_file
## Ex.
##   getZFS /Karajon/VBoxes/OS111b_MySQL/abc.vdi
getZFS() {
  sVDIFile=$1
  sVDIFolder=`dirname $sVDIFile`
  sZFS=`zfs list -H | grep $sVDIFolder$ | awk '{print($1)}'`
  echo $sZFS
}

## Usage:
##   cloneFS source_zfs target_name index
## Ex.
##   sCloneFS=`cloneZFS Karajon/VBoxes/OS111b_origin S10u8_MySQL_1`
## PS. use this function to get clone ZFS name
cloneZFS() {
  sSZFS=$1
  sSnapshotName=$2
  sTZFS=`echo $sSZFS | sed -e 's|/[^/]*$||'`/$sSnapshotName
  pfexec zfs snapshot $sSZFS@$sSnapshotName || exit 2
  pfexec zfs clone $sSZFS@$sSnapshotName $sTZFS || exit 2
  echo $sTZFS
}

## Ex.
##   checkVersion v1 v2
##   v1>v2,  return 1
##   v1==v2, return 0
##   v1
checkVersion() {
  sVar1=$1
  sVar2=$2
  nF1=0
  nF2=0
  sReturn=0
  declare -i nCount=1
  while true
  do
    n1=`echo $sVar1 | cut -d. -f$nCount` && [ -z $n1 ] && n1=0 && nF1=1
    n2=`echo $sVar2 | cut -d. -f$nCount` && [ -z $n2 ] && n2=0 && nF2=1
    if [ $nF1 -eq 1 ] && [ $nF2 -eq 1 ]
    then
      sReturn=0
    else
      if [ $n1 -gt $n2 ]
      then
        nF1=1
        nF2=1
        sReturn=1
      elif [ $n2 -gt $n1 ]
      then
        nF1=1
        nF2=1
        sReturn=255
      else
        sReturn=0
      fi
    fi
    [ $nF1 -eq 1 ] && [ $nF2 -eq 1 ] && break
    nCount=$nCount+1
  done
  return $sReturn
}

checkVBoxVer() {
  sVBoxMinVer=$1
  sCurrVer=`VBoxManage -v | cut -dr -f1`
  nReturn=0
  checkVersion $sCurrVer $sVBoxMinVer
  nResult=$?
  if [ $nResult -ne 255 ]
  then
    nReturn=0
  else
    nReturn=1
  fi
  echo $nReturn
  return $nReturn
}

########################################################### main

[ $# -lt 4 ] && echo "Error without enough parameters, exit program..." && showUsage && exit 1
sAct=$1
sNMN=$2
sSMN=$3
sIF=$4
declare    sVBoxMinVer=3.1.0
declare -i nStartMachine=$5
declare -i nEndMachine=$6 && [ $nEndMachine -eq 0 ] && nEndMachine=$nStartMachine

sOSType=`getVMOSType $sSMN`
sSHDA=`getVMHDA $sSMN`
sSZFS=`getZFS $sSHDA`
sCloneFS=""
sTHDA=""
sTZFS=""

##sDVD_ISO=/Karajon/ISOs/osol-1002-125-ai-x86.iso

if [ `checkVBoxVer $sVBoxMinVer` -ne 0 ]
then
  cat <<EOF
Current version of VirtualBox is `VBoxManage -v`.
And to run this script,
the version of VirtualBox must great than $sVBoxMinVer.
EOF
  exit 255
fi

case $sAct in
c|create)
  # set -vx
  declare -i nCount=$nStartMachine;
  while true
  do
    [ $nCount -gt $nEndMachine ] && break
    createVM "$sNMN"_"$nCount" $sOSType
    sCloneFS=`cloneZFS $sSZFS "$sSMN"_"$nCount"`
    sTHDADir=`zfs get -H mountpoint $sCloneFS | awk '{print($3)}'`
    sTHDA=$sTHDADir/`basename $sSHDA`
    setUUID $sTHDA

    ## rename vdi filename
    mv $sTHDA $sTHDADir/`basename $sSHDA | cut -d. -f1`_$nCount.`basename $sSHDA | cut -d. -f2-`
    sTHDA=$sTHDADir/`basename $sSHDA | cut -d. -f1`_$nCount.`basename $sSHDA | cut -d. -f2-`

    cloneStorageController "$sNMN"_"$nCount" $sSMN
    modifyVM "$sNMN"_"$nCount" $sTHDA $nCount
    modifyVMNIC "$sNMN"_"$nCount" $sSMN $sIF
    nCount=nCount+1
    sleep 1
  done
  # set +vx
  ;;
d|delete)
  # set -vx
  declare -i nCount=$nStartMachine;
  while true
  do
    [ $nCount -gt $nEndMachine ] && break
    sHDA=`getVMHDA "$sNMN"_"$nCount"`
    echo "deleting $sNMN"_"$nCount" ...
    VBoxManage -q modifyvm "$sNMN"_"$nCount" --hda none || exit 3
    VBoxManage -q unregistervm "$sNMN"_"$nCount" --delete || exit 3
    #VBoxManage -q list hdds ## list hdds info
    VBoxManage -q closemedium disk $sHDA # remove disk medium
    zfs list -t snapshot | grep $sSMN@"$sSMN"_"$nCount" | while read f x
    do
      pfexec zfs destroy -R $f
    done
    nCount=nCount+1
  done
  # set +vx
  ;;
*)
  echo "Error with wrong action($sAct), exit program..."
  showUsage
  exit 1
  ;;
esac





Wish this helps.

regards,
Stanley Huang

Sunday, December 6, 2009

Gnome-commander in OpenSolaris

If you like to use the utility on Windows called "Total Commander", you would like "Gnome-commander" in OpenSolaris.
You can download the Gnome-commander in opensolaris.org repository. The package name called "SUNWgnome-commander".

Wish this helps.

regards,
Stanley Huang

Friday, December 4, 2009

[Level 3] Get process pid which open port!

How to get your process that open port.
The following will help you to check it!

#!/usr/bin/bash
showUsage() {
  cat <<EOF
Usage:
  $0 [port/pid/program](sort column, default is sort by 'port'.)
Ex.
  $0 1/port
  $0 2/pid
  $0 3/program
EOF
}

####################################### main

typeset -i nSortKey
case $1 in
1|port|"")
  sFlag="-n"
  nSortKey=1
  ;;
2|pid)
  sFlag="-n"
  nSortKey=2
  ;;
3|program)
  nSortKey=3
  ;;
*)
  showUsage
  exit 0
  ;;
esac

echo "port\tpid\tcmd"
ps -eo pid,comm | while read pid cmd
do
  pfiles $pid 2> /dev/null | grep port: | awk "{printf(\"%s\t%s\t%s\n\",\$5,\"$pid\",\"$cmd\")}"
done | sort $sFlag -u -k $nSortKey 



Wish this helps.

regards,
Stanley Huang

Thursday, December 3, 2009

[Level 2] Enhance the performance with MySQL checksum table with MyISAM engine.

You can create MyISAM table with the option "checksum=1", to let MyISAM table store the checksum value. Otherwise, checksum table, will need to do a full table scan.
PS. This only support on MyISAM engine.

mysql> create table t (id int) engine=MyISAM checksum=1;
mysql> checksum table t;

Wish this helps.

regards,
Stanley Huang

Tuesday, December 1, 2009

VirtualBox 3.1 released

Sun Microsystems release VirtualBox 3.1 at 11/30. The new version has new features that people looking forward to:

1. Teleportaion (aka live migration): It supports that to let virtual machine to migration between different platform, it enhances the virtual server with HA and flexibility.
2. Snapshots flexibility: The guest can rollback from different revision, and also can have branched snapshots.
3. Network attachement on the fly: The guest can modify the network interace on line.

More information, please refer to:
http://www.virtualbox.org/wiki/Changelog





Wish this helps.

regards,
Stanley Huang

Monday, November 30, 2009

[Level 3] 1A2B shell game

Another game.

#!/usr/bin/bash
showUsage() {

  cat <<EOF

Usage:

  $0

Ex.

  $0

EOF

}



getNum() {

  #set -vx

  sNum="0|1|2|3|4|5|6|7|8|9"

  sAns=""

  declare -i n1=$RANDOM*10/32767+1

  declare -i n2=$RANDOM*9/32767+1

  declare -i n3=$RANDOM*8/32767+1

  declare -i n4=$RANDOM*7/32767+1

  s=`echo $sNum | cut -d'|' -f$n1` && sAns=$sAns$s && sNum=`echo $sNum | sed -e "s/$s//" | sed -e 's/||/|/g' | sed -e 's/^|//g' | sed -e s'/|$//'`

  s=`echo $sNum | cut -d'|' -f$n2` && sAns=$sAns$s && sNum=`echo $sNum | sed -e "s/$s//" | sed -e 's/||/|/g' | sed -e 's/^|//g' | sed -e s'/|$//'`

  s=`echo $sNum | cut -d'|' -f$n3` && sAns=$sAns$s && sNum=`echo $sNum | sed -e "s/$s//" | sed -e 's/||/|/g' | sed -e 's/^|//g' | sed -e s'/|$//'`

  s=`echo $sNum | cut -d'|' -f$n4` && sAns=$sAns$s && sNum=`echo $sNum | sed -e "s/$s//" | sed -e 's/||/|/g' | sed -e 's/^|//g' | sed -e s'/|$//'`

  echo $sAns

}



# check $sAns $sGuess

checkNum() {

  sAns=$1

  sGuess=$2

  declare -i A=0

  declare -i B=0

  sA1=`echo ${sAns:0:1}`

  sA2=`echo ${sAns:1:1}`

  sA3=`echo ${sAns:2:1}`

  sA4=`echo ${sAns:3:1}`

  sG1=`echo ${sGuess:0:1}`

  sG2=`echo ${sGuess:1:1}`

  sG3=`echo ${sGuess:2:1}`

  sG4=`echo ${sGuess:3:1}`

  if [ $sAns == $sGuess ]

  then

    echo "Bingo...($sOAns:$sGuess)" && return 0

  else

    [ "$sA1" == "$sG1" ] && A=$A+1 && sAns=`echo $sAns | sed -e "s/$sA1//"`

    [ "$sA2" == "$sG2" ] && A=$A+1 && sAns=`echo $sAns | sed -e "s/$sA2//"`

    [ "$sA3" == "$sG3" ] && A=$A+1 && sAns=`echo $sAns | sed -e "s/$sA3//"`

    [ "$sA4" == "$sG4" ] && A=$A+1 && sAns=`echo $sAns | sed -e "s/$sA4//"`

    echo $sAns | grep $sG1 >/dev/null && B=$B+1

    echo $sAns | grep $sG2 >/dev/null && B=$B+1

    echo $sAns | grep $sG3 >/dev/null && B=$B+1

    echo $sAns | grep $sG4 >/dev/null && B=$B+1

    echo $sGuess: $A"A"$B"B ..." >> $0.log

    cat $0.log

    return 1

  fi

}



######################################################## main



sOAns=`getNum`

#echo "sOAns=$sOAns"

declare -i nCount=0

cat /dev/null > $0.log

while true

do

  read -p "Please enter 4 digit number or quit (you have guess $nCount times): " sGuess

  [ `echo $sGuess | awk '{print(length($1))}'` -ne 4 ] && echo "shorter then 4 digits..." && continue

  [ $sGuess == "quit" ] && echo "The answer is: $sOAns" && break

  checkNum $sOAns $sGuess && break

  nCount=$nCount+1

done

rm $0.log


Wish this helps.

regards,
Stanley Huang

[Level 3] OX shell game.

Today, I deliver the shell programming course.
And I think, why not to write a simple shell script game.
The script should be to fun.

#!/usr/bin/bash
showUsage() {
  cat<<EOF
Usage:
  $0 init/load 0/X
Ex.
  $0 init 0/X
  $0 load O/X
EOF
}

checkLine() {
  sDisp=$1
  s1=`echo $sDisp | cut -d'|' -f1`
  s2=`echo $sDisp | cut -d'|' -f2`
  s3=`echo $sDisp | cut -d'|' -f3`
  s4=`echo $sDisp | cut -d'|' -f4`
  s5=`echo $sDisp | cut -d'|' -f5`
  s6=`echo $sDisp | cut -d'|' -f6`
  s7=`echo $sDisp | cut -d'|' -f7`
  s8=`echo $sDisp | cut -d'|' -f8`
  s9=`echo $sDisp | cut -d'|' -f9`
  if [ $s1 == $s2 ] && [ $s2 == $s3 ]
  then
    echo "$s1 wins..." && return 0
  elif [ $s4 == $s5 ] && [ $s5 == $s6 ]
  then
    echo "$s4 wins..." && return 0
  elif [ $s7 == $s8 ] && [ $s8 == $s9 ]
  then
    echo "$s7 wins..." && return 0
  elif [ $s1 == $s4 ] && [ $s4 == $s7 ]
  then
    echo "$s1 wins..." && return 0
  elif [ $s2 == $s5 ] && [ $s5 == $s8 ]
  then
    echo "$s2 wins..." && return 0
  elif [ $s3 == $s6 ] && [ $s6 == $s9 ]
  then
    echo "$s3 wins..." && return 0
  elif [ $s1 == $s5 ] && [ $s5 == $s9 ]
  then
    echo "$s1 wins..." && return 0
  elif [ $s3 == $s5 ] && [ $s5 == $s7 ]
  then
    echo "$s3 wins..." && return 0
  else
    return 1
  fi
}

checkDone() {
  sArea=`cat $0.area | sed -e 's/[ ]*//g'`
  sDisp=`cat $0.disp | sed -e 's/n//g' | sed -e 's/. - ./|/g' | sed -e 's/[ -.]*//g'`
  checkLine $sDisp && return 0
  [ `echo $sArea | grep -c "[1-9]"` -eq 0 ] && echo "even..." && return 0
  return 1
}

############################ main
sAct=${1:-init}
case $sAct in
init)
  sArea="1 2 3 4 5 6 7 8 9"
  echo $sArea > $0.area
  sDisp="1 | 2 | 3n- . - . -n4 | 5 | 6n- . - . -n7 | 8 | 9"
  echo $sDisp > $0.disp
  sOX=$2
  clear && echo $sDisp | sed -e 's|n|\\\\n|g' | xargs echo
  if [ "$sOX" == "X" ] || [ "$sOX" == "x" ]
  then
    sOX=X
  else
    sOX=O
  fi
  $0 load $sOX
  ;;
load)
  sOX=$2
  sArea=`cat $0.area`
  sDisp=`cat $0.disp`
  while true
  do
    read -p "Please enter your pos ($sOX): " nPos
    sNArea=`echo $sArea | sed -e "s/$nPos//"`
    [ "$sArea" != "$sNArea" ] && sArea=$sNArea && break
  done
  echo $sArea > $0.area
  sDisp=`echo $sDisp | sed -e "s/$nPos/$sOX/"`
  echo $sDisp > $0.disp
  clear && echo $sDisp | sed -e 's|n|\\\\n|g' | xargs echo
  checkDone && rm $0.area $0.disp && exit 0
  if [ $sOX == "O" ]
  then
    sOX=X
  else
    sOX=O
  fi
  $0 load $sOX
  ;;
*)
  showUsage
  exit 1
  ;;
esac





Wish this helps.

regards,
Stanley Huang

Friday, November 27, 2009

[Level 3] The script for demo creating mass zones on OpenSolaris

Days ago, my colleague will demo about the virtualization techniques on OpenSolari.
So I share the script for him to demo fast creating zones on OpenSolaris.
After test, my lap will create a zone per 3 seconds.
That impress him, and he decided to demo on that session.

The same script that I'd like to share to you, please refer the following script code.
Any question, and suggestion, please feel free to let me know.

#!/usr/bin/bash
showUsage() {
  cat<<EOF
Usage:
  $0 [c]reate  [original index] [start index] [end index]
  $0 [d]estroy [start index]    [end index]   [always yes]
  $0 [l]ist
Ex.
  $0 c 1 2 10   => create  zone2, zone3, ... ,zone10
  $0 c 1 3 8    => create  zone3, zone4, ... ,zone8
  $0 d 2 10 [F] => destroy zone2, zone3, ... ,zone10
  $0 l
PS.
  for solaris 11 only
  all indexes must greater then 1, less then 255
Zones:
`listZone`
EOF
}

createOriginZone() {
  echo "create Zone (zone$nOriginIndex)..."
  zfs create -p $sBaseZoneZFS/zone$nOriginIndex
  chmod 700 $sBaseZonePath/zone$nOriginIndex
  zonecfg -z zone$nOriginIndex <<EOF
create
set zonepath=$sBaseZonePath/zone$nOriginIndex
add net
set physical=$sIF
set address=$sClassIP.$nOriginIndex/$nNetmask
end
commit
EOF
  zoneadm -z zone$nOriginIndex install
}

## build snapshot by zoenadm, and create snapshot for every clone.
## case1 $@
case1() {
  declare -i nOriginIndex=${1:-1}
  declare -i count=${2:-0}
  declare -i nZones=${3:-254}
  while [ $count -le $nZones ]
  do
    echo "create zone$count ....."
    zonecfg -z zone$nOriginIndex export -f /tmp/zone$count.cfg
    perl -pi -e "s/zone$nOriginIndex/zone$count/g" /tmp/zone$count.cfg
    perl -pi -e "s|^set address=.*|set address=$sClassIP.$count/$nNetmask|g" /tmp/zone$count.cfg
    zonecfg -z zone$count < /tmp/zone$count.cfg
    zoneadm -z zone$count clone zone$nOriginIndex
    echo "create zone$count done!"
    count=$count+1
  done
}

## build snapshot manually, and use one snapshot.
## case2 $@
## not work in OpenSolaris...
case2() {
  declare -i nOriginIndex=${1:-1}
  declare -i count=${2:-0}
  declare -i nZones=${3:-254}
  ## create first clone zone and use it's snapshot for later...
  case1 $nOriginIndex $count $count
  sOriginSnapshot=`zfs get -H origin $sBaseZoneZFS/zone$count | cut -d'    ' -f3`
  ## zfs snapshot $sOriginZoneZFS@$sTimestamp # not work

  count=$count+1
  while [ $count -le $nZones ]
  do
    echo "create zone$count ....."
    zonecfg -z zone$nOriginIndex export -f /tmp/zone$count.cfg
    perl -pi -e "s/zone$nOriginIndex/zone$count/g" /tmp/zone$count.cfg
    perl -pi -e "s|^set address=.*|set address=$sClassIP.$count/$nNetmask|g" /tmp/zone$count.cfg
    zonecfg -z zone$count < /tmp/zone$count.cfg
    zoneadm -z zone$count clone -s $sOriginSnapshot zone$nOriginIndex
    echo "create zone$count done!"
    count=$count+1
  done
}

createMassZones() {
  declare -i nOriginIndex=${1:-1}
  declare -i count=${2:-0}
  declare -i nZones=${3:-254}
  nSleep=5
  sTimestamp=`date "+%Y%m%d%H%M%S"`
 
  if [ `zoneadm list -cv | grep -wc zone$nOriginIndex` -eq 0 ]
  then
    read -p "Do you want to create the zone (zone$nOriginIndex)? (y/N):" yN
    if [ "$yN" == "Y" ] || [ "$yN" == "y" ]
    then
      createOriginZone
      zoneadm -z zone$nOriginIndex boot
      zlogin -C zone$nOriginIndex
    else
      echo "Exit program..."
      exit 1
    fi
  fi
 
  zlogin zone$nOriginIndex init 5
  sleep $nSleep
 
  case1 $@
  #case2 $@
}

destroyMassZones() {
  declare -i count=${1:-0}
  declare -i nZones=${2:-254}
  declare    sF=$3
  declare    sOrigSnap=""
  if [ "$sF" == "F" ] || [ "$sF" == "f" ]
  then
    sF="-F"
  else
    sF=""
  fi

  while [ $count -le $nZones ]
  do
    echo "destroy zone$count ....."
    zoneadm -z zone$count halt
    zoneadm -z zone$count uninstall $sF
    zonecfg -z zone$count delete $sF

    ## auto delete snapshot/clone after zoneadm -z zone$count uninstall
    #sOrigSnap=`zfs get -H origin $sBaseZoneZFS/zone$count/ROOT/zbe | awk '{print($3)}'`
    #zfs destroy -R $sOrigSnap
    #echo "zfs destroy -R $sOrigSnap"

    echo "destroy zone$count done!"
    count=$count+1
  done
}

listZone() {
  zoneadm list -iv
}
######################################################## main
sVersion="5.11"
sIF=yukonx0
sClassIP=172.31.248
nNetmask=24
sBaseZoneZFS=rpool/zones
sBaseZonePath=/export/home/zones
zfs create -o mountpoint=$sBaseZonePath -p $sBaseZoneZFS
chmod 700 $sBaseZonePath

[ `uname -r` != "$sVersion" ] && echo "For Solaris 11 only, exit program..." && exit 3
case $1 in
c|create)
  [ $# -lt 4 ] && echo "Error without enough parameters, exit program..." && showUsage && exit 1
  shift
  createMassZones $@
  ;;
d|delete)
  [ $# -lt 3 ] && echo "Error without enough parameters, exit program..." && showUsage && exit 1
  shift
  destroyMassZones $@
  ;;
l|list)
  listZone
  ;;
*)
  echo "Error with wrong action($1), exit program..." && showUsage && exit 2
  ;;
esac



Wish this helps.

regards,

Stanley Huang

Wednesday, November 25, 2009

[Level 3] Script for create VirtualBox VM quickly.

This script is for quickly create VirtualBox VM,
it base on ZFS snapshot/clone technique.
The description for the script is as the following:

The step as below:
1. create a ZFS filesystem first.
Ex. # zfs create -p rpool/vbox/sourceOS
2. create a VirtualBox VM for source and put the vdi on the above ZFS filesystem.
3. use the script:
Usage:
  $0 create New_Machine_Name Source_Machine_Name interface begin_index end_index
Ex.
  ./createVBoxClientByClone.sh create NewVM SourceVM yukonx0 3 5
the above command will create 3 VMs (NewVM_3, NewVM_4, NewVM_5):
The actions of create are,
. snapshot origin ZFS
. clone from origin ZFS snapshot to new ZFS
. re-new vdi uuid on new ZFS
. create new vm
. modify new vm
. modify new vm nic
4. If you want to delete VMs, use the command as below:
Usage:
  $0 delete New_Machine_Name Source_Machine_Name interface begin_index end_index
Ex.
  ./createVBoxClientByClone.sh delete NewVM SourceVM yukonx0 3 5
Above comand will delete 3 VMs (NewVM_3, NewVM_4, NewVM_5),
The actions of delete are:
. modify new vm (detach disk)
. unregister new vm
. destroy snapshot and new build-ed ZFS

The script as blow:

#!/usr/bin/bash
showUsage() {
  cat <<EOF
Usage:
  $0 create New_Machine_Name Source_Machine_Name interface begin_index end_index
Ex.
  $0 create OS111b_MySQL OS111b_origin yukonx0 1 10
  $0 delete OS111b_MySQL OS111b_origin yukonx0 1 10
VMMachine:
`showVMS | sed -e 's/^/  /'`
EOF
}

## Usage:
##   setUUID vdi_file
## Ex.
##   setUUID /Karajon/VBoxes/Guest/guest.vdi
setUUID() {
  sVDI=$1
  VBoxManage -q internalcommands setvdiuuid $sVDI
}

## Usage:
##   createVM vm_name os_type.
## Ex.
##   createVM S10u8_MySQL Solaris_64
## PS.
##   OS Type: Solaris Solaris_64 OpenSolaris OpenSolaris_64
createVM() {
  sVMName=$1
  sOSType=$2
  /opt/VirtualBox/VBoxManage -q createvm \
    --name $sVMName \
    --ostype $sOSType \
    --register
}

## Usage:
##   modifyVMNIC vm_name source_vm interface
## Ex.
##   modifyVMNIC S10u8_MySQL S10u8_Source yukonx0
modifyVMNIC() {
  sTVMName=$1
  sSVMName=$2
  sIF="$3 - Ethernet"
  sAttachedTo=bridged
  sAdapterType=82540EM
  while read n
  do
    /opt/VirtualBox/VBoxManage -q modifyvm $sTVMName \
      --nic$n $sAttachedTo \
      --nictype$n $sAdapterType \
      --cableconnected$n on \
      --bridgeadapter$n "$sIF"
  done <
<EOF
  `VBoxManage -q showvminfo $sSVMName | grep "^NIC [1-4]:" | cut -d: -f1 | awk '{print($2)}'`
EOF
}

## Usage:
##   modifyVM vm_name hda seq_no
## Ex.
##   modifyVM S10u8_MySQL /Karajon/VBox/$sVMName/$sVDI $nSeq
modifyVM() {
  sVMName=$1
  declare -i nMemory=768
  sHDA=$2
  sDVD_ISO=/Karajon/ISOs/osol-1002-125-ai-x86.iso
  declare -i nVRDPport=3390+$3

  /opt/VirtualBox/VBoxManage -q modifyvm $sVMName \
    --memory $nMemory \
    --hda $sHDA \
    --boot1 disk --boot2 dvd \
    --dvd $sDVD_ISO \
    --audio solaudio --audiocontroller ac97 \
    --vrdp on --vrdpport $nVRDPport
}

## Usage:
##   startVM vm_name
## Ex.
##   startVM S10_U8
startVM() {
  sVMName=$1
  /opt/VirtualBox/VBoxManage -q startvm $sVMName
}

showVMS() {
  VBoxManage -q list vms
}

## Usage:
##   getVMOSType vm_name
## Ex.
##   getVMOSType OS111b_MySQL
getVMOSType() {
  sVMName=$1
  sOSType=""
  sGuestOS=`VBoxManage -q showvminfo $sVMName | grep "^Guest OS:" | cut -d: -f2`
  sOS=`echo $sGuestOS | awk '{print($1)}'`
  declare -i nVer=`echo $sGuestOS | cut -d\( -f2 | cut -d' ' -f1`
  sOSType="$sOS"_"$nVer"
  echo "$sOSType"
}

## Usage:
##   getVMHDA vm_name
## Ex.
##   getVMHDA OS111b_MySQL
getVMHDA() {
  sVMName=$1
  sHDA=`VBoxManage -q showvminfo $sVMName | grep "^Primary master:" | cut -d: -f2 | awk '{print($1)}'`
  echo $sHDA
}

## Usage:
##   getZFS vdi_file
## Ex.
##   getZFS /Karajon/VBoxes/OS111b_MySQL/abc.vdi
getZFS() {
  sVDIFile=$1
  sVDIFolder=`dirname $sVDIFile`
  sZFS=`zfs list | grep $sVDIFolder$ | awk '{print($1)}'`
  echo $sZFS
}

## Usage:
##   cloneFS source_zfs target_name
## Ex.
##   sCloneFS=`cloneZFS Karajon/VBoxes/OS111b_origin S10u8_MySQL_1`
## PS. use this function to get clone ZFS name
cloneZFS() {
  sSZFS=$1
  sSnapshotName=$2
  sTZFS=`echo $sSZFS | sed -e 's|/[^/]*$||'`/$sSnapshotName
  pfexec zfs snapshot $sSZFS@$sSnapshotName || exit 2
  pfexec zfs clone $sSZFS@$sSnapshotName $sTZFS || exit 2
  echo $sTZFS
}

########################################################### main

[ $# -lt 6 ] && echo "Error without enough parameters, exit program..." && showUsage && exit 1
sAct=$1
sNMN=$2
sSMN=$3
sIF=$4
declare -i nStartMachine=$5
declare -i nEndMachine=$6

sOSType=`getVMOSType $sSMN`
sSHDA=`getVMHDA $sSMN`
sSZFS=`getZFS $sSHDA`
sCloneFS=""
sTHDA=""
sTZFS=""

case $sAct in
create)
  # set -vx
  declare -i nCount=$nStartMachine;
  while true
  do
    [ $nCount -gt $nEndMachine ] && break
    createVM "$sNMN"_"$nCount" $sOSType
    sCloneFS=`cloneZFS $sSZFS "$sSMN"_"$nCount"`
    sTHDA=`zfs get -H mountpoint $sCloneFS | awk '{print($3)}'`/`basename $sSHDA`
    setUUID $sTHDA
    modifyVM "$sNMN"_"$nCount" $sTHDA $nCount
    modifyVMNIC "$sNMN"_"$nCount" $sSMN $sIF
    nCount=nCount+1
    sleep 1
  done
  # set +vx
  ;;
delete)
  # set -vx
  declare -i nCount=$nStartMachine;
  while true
  do
    [ $nCount -gt $nEndMachine ] && break
    VBoxManage -q modifyvm "$sNMN"_"$nCount" --hda none || exit 3
    VBoxManage -q unregistervm "$sNMN"_"$nCount" --delete || exit 3
    zfs list -t snapshot | grep $sSMN@"$sSMN"_"$nCount" | while read f x
    do
      pfexec zfs destroy -R $f
    done
    nCount=nCount+1
  done
  # set +vx
  ;;
*)
  echo "Error with wrong action($sAct), exit program..."
  showUsage
  exit 1
esac







Wish this helps.

regards,
Stanley Huang

Thursday, November 19, 2009

[Level 2] How to get ZFS clone file system?

Now I have use VirtualBox with ZFS clone file system.
So sometimes, I have to figure out which file system is native, which file system is clone.
Therefore, I write a script to list the ZFS clone file system.

#!/usr/bin/bash
showUsage() {
  cat <
<EOF
Usage:
  $0 pool_name
Ex.
  $0 rpool
EOF
}

######################################################## main

[ $# -lt 1 ] && echo "Error without parameters, exit program..." && showUsage && exit 1
sPoolname=$1 #sPoolname=${1:-rpool}
echo "get pool($sPoolname)..."
zfs get -r origin $sPoolname | egrep -v -- 'origin[ ]+-[ ]+-$'


The you can use the command to find out the clone file system.
# getCloneFS.sh rpool

get pool(rpool)...
NAME                                          PROPERTY  VALUE                                         SOURCE
rpool/ROOT/opensolaris                        origin    rpool/ROOT/opensolaris-1@2009-11-18-05:46:35  -
#





Wish this helps.

regards,
Stanley Huang

[Level 1] Install freemind on OpenSolaris

These days, my colleague want to find the freemind tool which can run on OpenSolaris,
finally, we got one.
And you can download it from the following link:

http://freemind.sourceforge.net/wiki/index.php/Download

After downloaded, you can got a zip file. then de-compress it.

# cd /src

# mkdir freemind
# cd freemind; unzip ../freemind-bin-max-0_8_1.zip
< lengthy output omitted >
# chmod u+x ./freedmind.sh
# ./freemind.sh
# ps -ef | grep freemind
 stanley  1155   810   0 14:25:00 pts/2       0:05 /usr/java/bin/java -Dfreemind.base.dir=. -cp ::./lib/freemind.jar:./lib/ant/lib


Wish this helps.

regards,
Stanley Huang

[Level 2] Tips on ZFS.

1. Is that possible to migrate root filesytem from smaller hard disk to larger one without shutdown the operation system? The answer is "Yes", if you use OpenSolaris.
You can use a larger disk to attach into the pool and make the hard disk be a part of mirror disk of the root file system. After join the pool, the zfs pool will reslivering the data from origin one to new hard disk. After reslivered, then deatch the old hard disk, then the zfs capacity will also increased.
The simulation output as the following.

# mkdir /temp

# mkfile 128m /temp/128m
# mkfile 256m /temp/256m
# ls /temp/*m
-rw-------   1 stanley  staff    134217728 Nov 19 09:06 /temp/128m
-rw-------   1 stanley  staff    268435456 Nov 19 09:06 /temp/256m
#

# pfexec zpool create myPool /temp/128m
# zpool status myPool
  pool: myPool
 state: ONLINE
 scrub: none requested
config:

    NAME          STATE     READ WRITE CKSUM
    myPool        ONLINE       0     0     0
      /temp/128m  ONLINE       0     0     0

errors: No known data errors

# zfs list myPool
NAME     USED  AVAIL  REFER  MOUNTPOINT
myPool  68.5K  90.9M    19K  /myPool

#

# pfexec zpool attach myPool /temp/128m /temp/256m
# zpool status myPool
  pool: myPool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Thu Nov 19 09:09:26 2009
config:

    NAME            STATE     READ WRITE CKSUM
    myPool          ONLINE       0     0     0
      mirror        ONLINE       0     0     0
        /temp/128m  ONLINE       0     0     0
        /temp/256m  ONLINE       0     0     0  71.5K resilvered


errors: No known data errors

# zfs list myPool
NAME     USED  AVAIL  REFER  MOUNTPOINT
myPool  80.5K  90.9M    19K  /myPool

#

# pfexec zpool detach myPool /temp/128mb
# zpool status myPool
  pool: myPool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Thu Nov 19 09:09:26 2009
config:

    NAME          STATE     READ WRITE CKSUM
    myPool        ONLINE       0     0     0
      /temp/256m  ONLINE       0     0     0  71.5K resilvered

errors: No known data errors

# zfs list myPool
NAME     USED  AVAIL  REFER  MOUNTPOINT
myPool    82K   219M    19K  /myPool



2. How to shrink virtual disk of VirtualBox?
Virtual disk will not shrink even you delete data in the virtual machine. So, is that possible to shrink the virtual disk of VirtualBox? The answer is yes, if your virtual disk is on ZFS file system.
The steps as the following.
a. Create a virtual disk with dynamic disk type.
b. Add virtual disk to the virtual machine.
c. Attach the new virtual to the old one, and make them be a mirror disk.
d. After disk reslivered, detach the old disk from the mirror.

The same way can may your disk from fix disk size type to dynamic disk size type.

Wish this helps.

regards,
Stanley Huang

Tuesday, November 10, 2009

[Leve 1] Use usb to com to connect SPARC machine in OpenSolaris.

Today, I try to use my colleage's usb to com cable, to connect SPARC machine.
1. check /dev/term folder first.
# ls -al /dev/term
total 8
drwxr-xr-x   2 root root   2 2009-11-10 18:20 .
drwxr-xr-x 252 root sys  252 2009-11-10 18:20 ..

2. connect cable then try again.
# ls -al /dev/term
total 9
drwxr-xr-x   3 root root   3 2009-11-10 18:00 .
drwxr-xr-x 253 root sys  253 2009-11-10 18:00 ..
lrwxrwxrwx   1 root root  48 2009-11-10 18:00 0 -> ../../devices/pci@0,0/pci1043,8263@1d/device@1:0

3. use tip command to connect SPRAC machine.
PS. you have to set baud rate to 9600.
# tip -9600 /dev/term/0

4. Start the SPARC machine then you will get the console.

Wish this helps.

regards,
Stanley Huang

Friday, October 30, 2009

[Level 1] How to let our source code display with colors in Vim.

In TWOSUG , someone ask about how to display colors in shell.
1. Setting TERM variables.
# export TERM=xterm-color;
2. Use Vim to open the source.
# vim ./test.c;
3. Turn on the syntax mode in Vim.
In last line mode, type the following command.
:syntax on

Wish this helps.

regards,
Stanley Huang

Thursday, October 29, 2009

[Level 3] Clone multi-server on VirtualBox guest by ZFS clone.

How to save your disk space while you need multi VirtualBox guest?
You can use ZFS clone to clone ZFS filesystem.
But while you import the vdi, you willgot an error message with duplicated disk uuid.
So you need to modify the disk uuid by command VBoxManage.
The complete steps as the following:

1. create zfs pool for VirtualBox VDI.
# zpool create vdiPool c1t0d0s0; # default folder is /vdiPool

2. create zfs filesystem for Source VDI.
# zfs create vdiPool/vdiSource; # default folder is /vdiPool/vdiSource

3. create VirtualBox guest, and create vdi on /vdiPool/vdiSource/OpenSolaris.vdi

4. clone vdi source
# zfs snapshot vdiPool/vdiSource@installed
# zfs clone vdiPool/vdiSource@installed vdiPool/vdiTarget1

# VBoxManage internalcommands setvdiuuid /vdiPool/vdiTarget1/OpenSolaris.vdi


Wish this helps.

regards,
Stanley Huang

chm reader in OpenSolaris

If you want to install chm reader on OpenSolaris,
you can install xchm from Blastwave repository.

Wish this helps.

regards,
Stanley Huang

Thursday, October 22, 2009

ScaleDB storage engine for MySQL.

Here comes a new commercial storage engine for MySQL called "ScaleDB".
The architecture ScaleDB just similar like "Oracle RAC",
but now, ScaleDB only support Linux and Windows.
All the db instant are active and supports shared storage.
Expecting the storage engine be mature.

PS. If you don't have shared storage, and you just use VirtualBox as I do,
you can use "DRBD" to simulate the shared storage,
but now, DRDB only supoort Linux.

The architecture of SacleDB as below. (All pictures rights belows to www.scaledb.com)





Ref:
http://www.scaledb.com

The DRDB architecture as below. (All picture rights below to DRDB.org)


Ref:
http://www.drbd.org

Wish this helps.

regards,
Stanley Huang

Tuesday, October 20, 2009

[Level 3] Solaris 10 Technical Conference ( 2009/10/25,11/13,12/4 ) -- Advanced ZFS hands-on lab

The following is my lab file, please refer to it. 

Wish this helps.

regards,
Stanley Huang

****************************************************************************************************
The purpose of this lab is to let you have advanced ZFS filesystem administration skill. And then you will have the following capabilities.
Lab 1:
* replace zpool disk.
Lab 2:
* take ZFS filesystem snapshot, rollback ZFS filesystem.
* clone ZFS filesystem.
Lab 3:
* use ZFS L2ARC
* use ZFS ZIL



Lab 1:
1. replace zpool disk.
# cd /labs/ZFS/files;
# zpool create mypool mirror `pwd`/f1 `pwd`/f2 spare `pwd`/f3;
# zpool replace mypool `pwd`/f2 `pwd`/f3;

# zpool status mypool;
-------------------------------------------------------------------------------
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Oct 18 11:13:15 2009
config:

    NAME            STATE     READ WRITE CKSUM
    mypool                 ONLINE       0     0     0
      /lab/ZFS/files/f1    ONLINE       0     0     0
      spare                ONLINE       0     0     0
        /lab/ZFS/files/f2  ONLINE       0     0     0
        /lab/ZFS/files/f3  ONLINE       0     0     0  47.5K resilvered
    spares
      /lab/ZFS/files/f3    INUSE     currently in use

errors: No known data errors
-------------------------------------------------------------------------------

# zpool replace mypool `pwd`/f2 `pwd`/f8;

# zpool status mypool;
-------------------------------------------------------------------------------
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Sun Oct 18 11:20:55 2009
config:

    NAME          STATE     READ WRITE CKSUM
    mypool               ONLINE       0     0     0
      /lab/ZFS/files/f1  ONLINE       0     0     0
      /lab/ZFS/files/f8  ONLINE       0     0     0  57.5K resilvered
    spares
      /lab/ZFS/files/f3  AVAIL

errors: No known data errors
-------------------------------------------------------------------------------



Lab 2:
1. ZFS filesystem snapshot/rollback.
# zfs create mypool/myfs1;
# cp /etc/hosts /mypool/myfs1/hosts;
# ls -l /mypool/myfs1/hosts;
------------------------------------------------------------
-r--r--r-- 1 root root 4925 Oct 18 11:35 /mypool/myfs1/hosts
------------------------------------------------------------

# zfs snapshot mypool/myfs1@s1;
# cat /dev/null > /mypool/myfs1/hosts;
# ls -l /mypool/myfs1/hosts;
------------------------------------------------------------
-r--r--r-- 1 root root 0 Oct 18 11:36 /mypool/myfs1/hosts
------------------------------------------------------------

# zfs rollback mypool/myfs1@s1;
# ls -l /mypool/myfs1/hosts;
------------------------------------------------------------
-r--r--r-- 1 root root 4925 Oct 18 11:35 /mypool/myfs1/hosts
------------------------------------------------------------

2. clone ZFS filesystem, then promote it.
# zfs clone mypool/myfs1@s1 mypool/clonefs;
# zfs list -t all -r mypool;
-----------------------------------------------------
NAME              USED  AVAIL  REFER  MOUNTPOINT
mypool            218K  90.8M    24K  /mypool
mypool/clonefs     21K  90.8M    25K  /mypool/clonefs
mypool/myfs1       25K  90.8M    25K  /mypool/myfs1
mypool/myfs1@s1      0      -    25K  -
-----------------------------------------------------

# zfs get -r origin mypool;
--------------------------------------------------
NAME             PROPERTY  VALUE            SOURCE
mypool           origin    -                -
mypool/clonefs   origin    mypool/myfs1@s1  -
mypool/myfs1     origin    -                -
mypool/myfs1@s1  origin    -                -
--------------------------------------------------

# cd /mypool/clonefs/;
# ls -al;
----------------------------------------------
total 9
drwxr-xr-x 2 root root    3 Oct 18 11:35 .
drwxr-xr-x 6 root root    6 Oct 18 11:39 ..
-r--r--r-- 1 root root 4925 Oct 18 11:35 hosts
----------------------------------------------

# echo "192.168.100.1 host1" >> ./hosts;
# echo "192.168.100.2 host2" >> ./hosts;
# echo "192.168.100.3 host3" >> ./hosts;
# ls -l ./hosts;
------------------------------------------------
-r--r--r-- 1 root root 4985 Oct 18 11:44 ./hosts
------------------------------------------------

# tail -3 ./hosts;
-------------------
192.168.100.1 host1
192.168.100.2 host2
192.168.100.3 host3
-------------------

# cd /;
# zfs promote mypool/clonefs
# zfs get -r origin mypool;
------------------------------------------------------
NAME               PROPERTY  VALUE              SOURCE
mypool             origin    -                  -
mypool/clonefs     origin    -                  -
mypool/clonefs@s1  origin    -                  -
mypool/myfs1       origin    mypool/clonefs@s1  -
------------------------------------------------------

# zfs destroy -r mypool/clonefs@s1;
cannot destroy 'mypool/clonefs@s1': snapshot is cloned
no snapshots destroyed
# zfs destroy -R mypool/clonefs@s1;
# zfs rename mypool/clonefs mypool/fs1
root@Stanley-NB:/# zfs get -r origin mypool;
------------------------------------
NAME        PROPERTY  VALUE   SOURCE
mypool      origin    -       -
mypool/fs1  origin    -       -
------------------------------------

Lab 3:
# cd /labs/ZFS/files;
# zpool add mypool log `pwd`/f9;
# zpool status mypool;
-------------------------------------------------------------------------------
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Wed Oct 18 11:22:13 2009
config:

    NAME                 STATE     READ WRITE CKSUM
    mypool               ONLINE       0     0     0
      /lab/ZFS/files/f1  ONLINE       0     0     0
      /lab/ZFS/files/f8  ONLINE       0     0     0  57.5K resilvered
    logs                 ONLINE       0     0     0
      /lab/ZFS/files/f9  ONLINE       0     0     0
    spares
      /lab/ZFS/files/f3  AVAIL  

errors: No known data errors
-------------------------------------------------------------------------------

# lofiadm -a `pwd`/f10; # cache only support vdev, so have to create vdev first.
/dev/lofi/1
# zfs add mypool cache /dev/lofi/1;
# zpool status mypool;
-------------------------------------------------------------------------------
  pool: mypool
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Wed Oct 18 11:24:33 2009
config:

    NAME                 STATE     READ WRITE CKSUM
    mypool               ONLINE       0     0     0
      /lab/ZFS/files/f1  ONLINE       0     0     0
      /lab/ZFS/files/f8  ONLINE       0     0     0  57.5K resilvered
    logs                 ONLINE       0     0     0
      /lab/ZFS/files/f9  ONLINE       0     0     0
    cache
      /dev/lofi/1        ONLINE       0     0     0
    spares
      /lab/ZFS/files/f3  AVAIL  

errors: No known data errors
-------------------------------------------------------------------------------


[Level 2] Solaris 10 Technical Conference ( 2009/10/25,11/13,12/4 ) -- Basic ZFS hands-on lab

The following is my lab file, please refer to it. 

Wish this helps.

regards,
Stanley Huang


****************************************************************************************************

The purpose of this lab is to let you have basic ZFS administration skill. And then you will have the following capabilities.
Lab 1:
* create ZFS pool.
* check ZFS pool status.
* set ZFS pool properties.
* destroy ZFS pool.
Lab 2:
* create ZFS filesystem.
* check ZFS filesystem status.
* set ZFS filesystem properties.
* destroy ZFS filesystem.




Lab 1:
1. prepare files with command mkfile.
# mkdir -p /labs/ZFS/files;
# cd /labs/ZFS/files;
# mkfile 128m f1 f2 f3 f4 f5 f6 f7 f8 f9;

2. create ZFS pool.
# zpool create mypool mirror `pwd`/f1 `pwd`/f2 spare `pwd`/f3;
# zpool create myraidz raidz `pwd`/f4 `pwd`/f5 `pwd`/f6 spare `pwd`/f7;

3. list ZFS pools, and check pool status.
# zpool list;
---------------------------------------------------
# zpool list mypool;
NAME      SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
mypool    123M  77.5K   123M     0%  ONLINE  -
myraidz   370M   149K   370M     0%  ONLINE  -
---------------------------------------------------

# zpool status mypool;
---------------------------------------------------
  pool: mypool
 state: ONLINE
 scrub: none requested
config:

    NAME        STATE     READ WRITE CKSUM
    mypool      ONLINE       0     0     0
      /temp/f1  ONLINE       0     0     0
      /temp/f2  ONLINE       0     0     0
    spares
      /temp/f3  AVAIL  
---------------------------------------------------

# zpool status myraidz;
------------------------------------------------
  pool: myraidz
 state: ONLINE
 scrub: none requested
config:

    NAME          STATE     READ WRITE CKSUM
    myraidz       ONLINE       0     0     0
      raidz1      ONLINE       0     0     0
        /temp/f4  ONLINE       0     0     0
        /temp/f5  ONLINE       0     0     0
        /temp/f6  ONLINE       0     0     0
    spares
      /temp/f7    AVAIL  

errors: No known data errors
------------------------------------------------

4. list zpool properties.
# zpool get all mypool;
--------------------------------------------------
NAME    PROPERTY       VALUE       SOURCE
mypool  size           246M        -
mypool  used           76K         -
mypool  available      246M        -
mypool  capacity       0%          -
mypool  altroot        -           default
mypool  health         ONLINE      -
mypool  guid           9946812783950608926  default
mypool  version        14          default
mypool  bootfs         -           default
mypool  delegation     on          default
mypool  autoreplace    off         default
mypool  cachefile      -           default
mypool  failmode       wait        default
mypool  listsnapshots  off         default
--------------------------------------------------

5. change mypool pool property 'autoreplace'.
# zpool set autoreplace=on mypool;

6. export pool.
# zpool export mypool;

7. import pool.
# zpool import -d ./ mypool;

8. destroy pool.
# zpool destroy mypool;
# zpool destroy myraidz;



Lab 2:
1. create ZFS filesystem.
# zfs create mypool/myfs1;
# zfs create -p mypool/myfs1/myfs2/myfs3;

2. list ZFS filesystemsA.
# zfs list mypool/myfs1;
# zfs list -r mypool;

3. list zpool properties.
# zfs get all mypool/myfs1;
PS. Partial sample properties.
------------------------------------------------------------------
NAME          PROPERTY              VALUE                  SOURCE
mypool/myfs1  compressratio         1.00x                  -
mypool/myfs1  mountpoint            /mypool/myfs1          default
mypool/myfs1  compression           off                    default
mypool/myfs1  copies                1                      default
...
------------------------------------------------------------------

4. change mypool filesystem properties.
# zfs set mountpoint=/mnt/mypool mypool;

5. change myfs1 filesystem properties.
# zfs set compression=on mypool/myfs1;
# zfs set copies=2 mypool/myfs1/myfs2;

6. list properties.
# zfs get -r mountpoint mypool;
--------------------------------------------------------------------------------
NAME                      PROPERTY    VALUE                          SOURCE
mypool                    mountpoint  /mnt/mypool                    local
mypool/myfs1              mountpoint  /mnt/mypool/myfs1              inherited from mypool
mypool/myfs1/myfs2        mountpoint  /mnt/mypool/myfs1/myfs2        inherited from mypool
mypool/myfs1/myfs2/myfs3  mountpoint  /mnt/mypool/myfs1/myfs2/myfs3  inherited from mypool
--------------------------------------------------------------------------------

# zfs get -r compression mypool;
--------------------------------------------------------------------------------
NAME                      PROPERTY     VALUE     SOURCE
mypool                    compression  off       default
mypool/myfs1              compression  on        local
mypool/myfs1/myfs2        compression  on        inherited from mypool/myfs1
mypool/myfs1/myfs2/myfs3  compression  on        inherited from mypool/myfs1
--------------------------------------------------------------------------------

# zfs get -r compressratio mypool;
--------------------------------------------------------------------------------
NAME                      PROPERTY       VALUE  SOURCE
mypool                    compressratio  1.00x  -
mypool/myfs1              compressratio  1.00x  -
mypool/myfs1/myfs2        compressratio  1.00x  -
mypool/myfs1/myfs2/myfs3  compressratio  1.00x  -
--------------------------------------------------------------------------------

# zfs get -r copies mypool;
--------------------------------------------------------------------------------
NAME                      PROPERTY  VALUE   SOURCE
mypool                    copies    1       default
mypool/myfs1              copies    1       default
mypool/myfs1/myfs2        copies    2       local
mypool/myfs1/myfs2/myfs3  copies    2       inherited from mypool/myfs1/myfs2
--------------------------------------------------------------------------------

7. reset properties default values.
# zfs inherit -r mountpoint mypool;
# zfs inherit -r compression mypool;
# zfs inherit -r copies mypool;

8. destroy all ZFS filesystem.
# zfs destroy mypool/myfs1/myfs2/myfs3;
# zfs destroy -r mypool/myfs1;