670 typeset disk=$1
671 typeset slice=$2
672 if [[ -z $disk || -z $slice ]] ; then
673 log_fail "The disk name or slice number is unspecified."
674 fi
675
676 disk=${disk#/dev/dsk/}
677 disk=${disk#/dev/rdsk/}
678 disk=${disk%s*}
679
680 typeset -i ratio=0
681 ratio=$($PRTVTOC /dev/rdsk/${disk}s2 | \
682 $GREP "sectors\/cylinder" | \
683 $AWK '{print $2}')
684
685 if ((ratio == 0)); then
686 return
687 fi
688
689 typeset -i endcyl=$($PRTVTOC -h /dev/rdsk/${disk}s2 |
690 $NAWK -v token="$slice" '{if ($1==token) print $6}')
691
692 ((endcyl = (endcyl + 1) / ratio))
693 echo $endcyl
694 }
695
696
697 #
698 # Given a size,disk and total slice number, this function formats the
699 # disk slices from 0 to the total slice number with the same specified
700 # size.
701 #
702 function partition_disk #<slice_size> <whole_disk_name> <total_slices>
703 {
704 typeset -i i=0
705 typeset slice_size=$1
706 typeset disk_name=$2
707 typeset total_slices=$3
708 typeset cyl
709
710 zero_partitions $disk_name
1330 log_must $ZPOOL import $search_path $pool
1331
1332 $ZDB -cudi $filesys > $zdbout 2>&1
1333 if [[ $? != 0 ]]; then
1334 log_note "Output: $ZDB -cudi $filesys"
1335 $CAT $zdbout
1336 log_fail "$ZDB detected errors with: '$filesys'"
1337 fi
1338
1339 log_must $ZFS mount -a
1340 log_must $RM -rf $zdbout
1341 }
1342
1343 #
1344 # Given a pool, and this function list all disks in the pool
1345 #
1346 function get_disklist # pool
1347 {
1348 typeset disklist=""
1349
1350 disklist=$($ZPOOL iostat -v $1 | $NAWK '(NR >4) {print $1}' | \
1351 $GREP -v "\-\-\-\-\-" | \
1352 $EGREP -v -e "^(mirror|raidz1|raidz2|spare|log|cache)$")
1353
1354 $ECHO $disklist
1355 }
1356
1357 #
1358 # Destroy all existing metadevices and state database
1359 #
1360 function destroy_metas
1361 {
1362 typeset metad
1363
1364 for metad in $($METASTAT -p | $AWK '{print $1}'); do
1365 log_must $METACLEAR -rf $metad
1366 done
1367
1368 for metad in $($METADB | $CUT -f6 | $GREP dev | $UNIQ); do
1369 log_must $METADB -fd $metad
1370 done
1452 cur_state=$(get_device_state $pool $disk)
1453
1454 if [[ $state != ${cur_state} ]]; then
1455 return 1
1456 fi
1457 return 0
1458 }
1459
1460 #
1461 # Check the output of 'zpool status -v <pool>',
1462 # and to see if the content of <token> contain the <keyword> specified.
1463 #
1464 # Return 0 is contain, 1 otherwise
1465 #
1466 function check_pool_status # pool token keyword
1467 {
1468 typeset pool=$1
1469 typeset token=$2
1470 typeset keyword=$3
1471
1472 $ZPOOL status -v "$pool" 2>/dev/null | $NAWK -v token="$token:" '
1473 ($1==token) {print $0}' \
1474 | $GREP -i "$keyword" > /dev/null 2>&1
1475
1476 return $?
1477 }
1478
1479 #
1480 # These 5 following functions are instance of check_pool_status()
1481 # is_pool_resilvering - to check if the pool is resilver in progress
1482 # is_pool_resilvered - to check if the pool is resilver completed
1483 # is_pool_scrubbing - to check if the pool is scrub in progress
1484 # is_pool_scrubbed - to check if the pool is scrub completed
1485 # is_pool_scrub_stopped - to check if the pool is scrub stopped
1486 #
1487 function is_pool_resilvering #pool
1488 {
1489 check_pool_status "$1" "scan" "resilver in progress since "
1490 return $?
1491 }
1492
1673 #
1674 # @return a string containing the list of available disks
1675 #*/
1676 function find_disks
1677 {
1678 sfi=/tmp/swaplist.$$
1679 msi=/tmp/metastat.$$
1680 dmpi=/tmp/dumpdev.$$
1681 max_finddisksnum=${MAX_FINDDISKSNUM:-6}
1682
1683 $SWAP -l > $sfi
1684 $METASTAT -c > $msi 2>/dev/null
1685 $DUMPADM > $dmpi 2>/dev/null
1686
1687 # write an awk script that can process the output of format
1688 # to produce a list of disks we know about. Note that we have
1689 # to escape "$2" so that the shell doesn't interpret it while
1690 # we're creating the awk script.
1691 # -------------------
1692 $CAT > /tmp/find_disks.awk <<EOF
1693 #!/bin/nawk -f
1694 BEGIN { FS="."; }
1695
1696 /^Specify disk/{
1697 searchdisks=0;
1698 }
1699
1700 {
1701 if (searchdisks && \$2 !~ "^$"){
1702 split(\$2,arr," ");
1703 print arr[1];
1704 }
1705 }
1706
1707 /^AVAILABLE DISK SELECTIONS:/{
1708 searchdisks=1;
1709 }
1710 EOF
1711 #---------------------
1712
1713 $CHMOD 755 /tmp/find_disks.awk
2310 # Get cksum of file
2311 # #1 file path
2312 #
2313 function checksum
2314 {
2315 typeset cksum
2316 cksum=$($CKSUM $1 | $AWK '{print $1}')
2317 $ECHO $cksum
2318 }
2319
2320 #
2321 # Get the given disk/slice state from the specific field of the pool
2322 #
2323 function get_device_state #pool disk field("", "spares","logs")
2324 {
2325 typeset pool=$1
2326 typeset disk=${2#/dev/dsk/}
2327 typeset field=${3:-$pool}
2328
2329 state=$($ZPOOL status -v "$pool" 2>/dev/null | \
2330 $NAWK -v device=$disk -v pool=$pool -v field=$field \
2331 'BEGIN {startconfig=0; startfield=0; }
2332 /config:/ {startconfig=1}
2333 (startconfig==1) && ($1==field) {startfield=1; next;}
2334 (startfield==1) && ($1==device) {print $2; exit;}
2335 (startfield==1) &&
2336 ($1==field || $1 ~ "^spares$" || $1 ~ "^logs$") {startfield=0}')
2337 echo $state
2338 }
2339
2340
2341 #
2342 # print the given directory filesystem type
2343 #
2344 # $1 directory name
2345 #
2346 function get_fstype
2347 {
2348 typeset dir=$1
2349
2350 if [[ -z $dir ]]; then
2454 if (($? == 0)); then
2455 rootpool=`$ECHO $rootfs | awk -F\/ '{print $1}'`
2456 $ECHO $rootpool
2457 else
2458 log_fail "This is not a zfsroot system."
2459 fi
2460 }
2461
2462 #
2463 # Get the sub string from specified source string
2464 #
2465 # $1 source string
2466 # $2 start position. Count from 1
2467 # $3 offset
2468 #
2469 function get_substr #src_str pos offset
2470 {
2471 typeset pos offset
2472
2473 $ECHO $1 | \
2474 $NAWK -v pos=$2 -v offset=$3 '{print substr($0, pos, offset)}'
2475 }
2476
2477 #
2478 # Check if the given device is physical device
2479 #
2480 function is_physical_device #device
2481 {
2482 typeset device=${1#/dev/dsk/}
2483 device=${device#/dev/rdsk/}
2484
2485 $ECHO $device | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
2486 return $?
2487 }
2488
2489 #
2490 # Get the directory path of given device
2491 #
2492 function get_device_dir #device
2493 {
2494 typeset device=$1
|
670 typeset disk=$1
671 typeset slice=$2
672 if [[ -z $disk || -z $slice ]] ; then
673 log_fail "The disk name or slice number is unspecified."
674 fi
675
676 disk=${disk#/dev/dsk/}
677 disk=${disk#/dev/rdsk/}
678 disk=${disk%s*}
679
680 typeset -i ratio=0
681 ratio=$($PRTVTOC /dev/rdsk/${disk}s2 | \
682 $GREP "sectors\/cylinder" | \
683 $AWK '{print $2}')
684
685 if ((ratio == 0)); then
686 return
687 fi
688
689 typeset -i endcyl=$($PRTVTOC -h /dev/rdsk/${disk}s2 |
690 $AWK -v token="$slice" '{if ($1==token) print $6}')
691
692 ((endcyl = (endcyl + 1) / ratio))
693 echo $endcyl
694 }
695
696
697 #
698 # Given a size,disk and total slice number, this function formats the
699 # disk slices from 0 to the total slice number with the same specified
700 # size.
701 #
702 function partition_disk #<slice_size> <whole_disk_name> <total_slices>
703 {
704 typeset -i i=0
705 typeset slice_size=$1
706 typeset disk_name=$2
707 typeset total_slices=$3
708 typeset cyl
709
710 zero_partitions $disk_name
1330 log_must $ZPOOL import $search_path $pool
1331
1332 $ZDB -cudi $filesys > $zdbout 2>&1
1333 if [[ $? != 0 ]]; then
1334 log_note "Output: $ZDB -cudi $filesys"
1335 $CAT $zdbout
1336 log_fail "$ZDB detected errors with: '$filesys'"
1337 fi
1338
1339 log_must $ZFS mount -a
1340 log_must $RM -rf $zdbout
1341 }
1342
1343 #
1344 # Given a pool, and this function list all disks in the pool
1345 #
1346 function get_disklist # pool
1347 {
1348 typeset disklist=""
1349
1350 disklist=$($ZPOOL iostat -v $1 | $AWK '(NR >4) {print $1}' | \
1351 $GREP -v "\-\-\-\-\-" | \
1352 $EGREP -v -e "^(mirror|raidz1|raidz2|spare|log|cache)$")
1353
1354 $ECHO $disklist
1355 }
1356
1357 #
1358 # Destroy all existing metadevices and state database
1359 #
1360 function destroy_metas
1361 {
1362 typeset metad
1363
1364 for metad in $($METASTAT -p | $AWK '{print $1}'); do
1365 log_must $METACLEAR -rf $metad
1366 done
1367
1368 for metad in $($METADB | $CUT -f6 | $GREP dev | $UNIQ); do
1369 log_must $METADB -fd $metad
1370 done
1452 cur_state=$(get_device_state $pool $disk)
1453
1454 if [[ $state != ${cur_state} ]]; then
1455 return 1
1456 fi
1457 return 0
1458 }
1459
1460 #
1461 # Check the output of 'zpool status -v <pool>',
1462 # and to see if the content of <token> contain the <keyword> specified.
1463 #
1464 # Return 0 is contain, 1 otherwise
1465 #
1466 function check_pool_status # pool token keyword
1467 {
1468 typeset pool=$1
1469 typeset token=$2
1470 typeset keyword=$3
1471
1472 $ZPOOL status -v "$pool" 2>/dev/null | $AWK -v token="$token:" '
1473 ($1==token) {print $0}' \
1474 | $GREP -i "$keyword" > /dev/null 2>&1
1475
1476 return $?
1477 }
1478
1479 #
1480 # These 5 following functions are instance of check_pool_status()
1481 # is_pool_resilvering - to check if the pool is resilver in progress
1482 # is_pool_resilvered - to check if the pool is resilver completed
1483 # is_pool_scrubbing - to check if the pool is scrub in progress
1484 # is_pool_scrubbed - to check if the pool is scrub completed
1485 # is_pool_scrub_stopped - to check if the pool is scrub stopped
1486 #
1487 function is_pool_resilvering #pool
1488 {
1489 check_pool_status "$1" "scan" "resilver in progress since "
1490 return $?
1491 }
1492
1673 #
1674 # @return a string containing the list of available disks
1675 #*/
1676 function find_disks
1677 {
1678 sfi=/tmp/swaplist.$$
1679 msi=/tmp/metastat.$$
1680 dmpi=/tmp/dumpdev.$$
1681 max_finddisksnum=${MAX_FINDDISKSNUM:-6}
1682
1683 $SWAP -l > $sfi
1684 $METASTAT -c > $msi 2>/dev/null
1685 $DUMPADM > $dmpi 2>/dev/null
1686
1687 # write an awk script that can process the output of format
1688 # to produce a list of disks we know about. Note that we have
1689 # to escape "$2" so that the shell doesn't interpret it while
1690 # we're creating the awk script.
1691 # -------------------
1692 $CAT > /tmp/find_disks.awk <<EOF
1693 #!/usr/xpg4/bin/awk -f
1694 BEGIN { FS="."; }
1695
1696 /^Specify disk/{
1697 searchdisks=0;
1698 }
1699
1700 {
1701 if (searchdisks && \$2 !~ "^$"){
1702 split(\$2,arr," ");
1703 print arr[1];
1704 }
1705 }
1706
1707 /^AVAILABLE DISK SELECTIONS:/{
1708 searchdisks=1;
1709 }
1710 EOF
1711 #---------------------
1712
1713 $CHMOD 755 /tmp/find_disks.awk
2310 # Get cksum of file
2311 # #1 file path
2312 #
2313 function checksum
2314 {
2315 typeset cksum
2316 cksum=$($CKSUM $1 | $AWK '{print $1}')
2317 $ECHO $cksum
2318 }
2319
2320 #
2321 # Get the given disk/slice state from the specific field of the pool
2322 #
2323 function get_device_state #pool disk field("", "spares","logs")
2324 {
2325 typeset pool=$1
2326 typeset disk=${2#/dev/dsk/}
2327 typeset field=${3:-$pool}
2328
2329 state=$($ZPOOL status -v "$pool" 2>/dev/null | \
2330 $AWK -v device=$disk -v pool=$pool -v field=$field \
2331 'BEGIN {startconfig=0; startfield=0; }
2332 /config:/ {startconfig=1}
2333 (startconfig==1) && ($1==field) {startfield=1; next;}
2334 (startfield==1) && ($1==device) {print $2; exit;}
2335 (startfield==1) &&
2336 ($1==field || $1 ~ "^spares$" || $1 ~ "^logs$") {startfield=0}')
2337 echo $state
2338 }
2339
2340
2341 #
2342 # print the given directory filesystem type
2343 #
2344 # $1 directory name
2345 #
2346 function get_fstype
2347 {
2348 typeset dir=$1
2349
2350 if [[ -z $dir ]]; then
2454 if (($? == 0)); then
2455 rootpool=`$ECHO $rootfs | awk -F\/ '{print $1}'`
2456 $ECHO $rootpool
2457 else
2458 log_fail "This is not a zfsroot system."
2459 fi
2460 }
2461
2462 #
2463 # Get the sub string from specified source string
2464 #
2465 # $1 source string
2466 # $2 start position. Count from 1
2467 # $3 offset
2468 #
2469 function get_substr #src_str pos offset
2470 {
2471 typeset pos offset
2472
2473 $ECHO $1 | \
2474 $AWK -v pos=$2 -v offset=$3 '{print substr($0, pos, offset)}'
2475 }
2476
2477 #
2478 # Check if the given device is physical device
2479 #
2480 function is_physical_device #device
2481 {
2482 typeset device=${1#/dev/dsk/}
2483 device=${device#/dev/rdsk/}
2484
2485 $ECHO $device | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
2486 return $?
2487 }
2488
2489 #
2490 # Get the directory path of given device
2491 #
2492 function get_device_dir #device
2493 {
2494 typeset device=$1
|