2012年6月25日月曜日

Linux CentOS 6.2 (x86_64) にて、KVM (Kernel-based Virtual Machine) の xml ファイルと仮想imgファイルをバックアップするスクリプト

1.「kvm-bkonevm.sh」スクリプト概要

Linux CentOS 6.2 (x86_64) にて、KVM (Kernel-based Virtual Machine) の xml ファイルフルパスを指定すると、その KVM の xml ファイル自体と仮想imgファイルをバックアップするスクリプトを作成しました。

  • 「指定された仮想マシンの電源を自動的にシャットダウン、仮想マシンの xml ファイルと仮想 HDD ファイルのバックアップ、バックアップ終了後に仮想マシンの電源をオン」という機能をひと通り備えています。

もちろん事前の動作確認や設定は必要ですが、「毎晩、とある重要な仮想マシン1台を、自動的にシャットダウン、バックアップ、電源をオンにする」という利用方法も可能です。

2.前準備

事前に、cpulimit というソフトをインストールしておく必要があります。

(参考) Linux (CentOS 6.2 x86_64) に、「cpulimit」をインストールして、実行する (= 絶対的な優先度を下げる) 手順

http://hachitaro.blogspot.jp/2012/06/linux-centos-62-x8664-cpulimit.html

3.「kvm-bkonevm.sh」スクリプト利用方法

「kvm-bkonevm.sh」スクリプトの利用方法は以下の通りです。

書式

(this scriptfile) (kvm xml file fullpath) (copy destination directory for copying kvm xml file and hd image file)

利用例

./kvm-bkonevm.sh /etc/libvirt/qemu/pc014.xml /mnt/pc079/d/bak/0101_phasedbak

上のとおりに実行すると、以下の処理を実行します。

  1. スクリプトは、「/etc/libvirt/qemu/pc014.xml」で指定されている仮想マシンの電源がオン(ON) の場合は、シャットダウン処理を開始します。

    kvm-bkonevm.sh を実行した後で「仮想マシンの電源がオンになっている」場合は、この kvm-bkonevm.sh スクリプトが仮想マシンに対してシャットダウン命令 (virsh shutdown) を発行します。

    仮想マシンが何らかの理由で自動的にシャットダウンしない場合は、手作業で仮想マシンをシャットダウン操作をする必要があります。

  2. スクリプトは、シャットダウン処理が完全に終了して、仮想マシンの電源がオフ(OFF) になるまで待機します。
  3. スクリプトは、xml ファイルと、仮想 HDD イメージファイルをバックアップ (コピー) します。

    xml ファイル、仮想 HDD イメージファイルいずれとも、できるかぎり元のディレクトリ構成を保ったままバックアップします。

    • xmlファイルのバックアップ先の例

      「/etc/libvirt/qemu/pc014.xml」

    • 仮想 HDD イメージファイルのバックアップ先の例

      「/var/lib/libvirt/images/pc014.img」

  4. スクリプトは、バックアップ終了後に仮想マシンの電源をオンにします。

4.「kvm-bkonevm.sh」スクリプト本体

「スクリプトご利用上の注意」をよくお読みの上、ご了承いただいた方はご利用下さい。

「kvm-bkonevm.sh」スクリプトは以下の通りです。

#!/bin/sh

# usage
# (this scriptfile) (kvm xml file fullpath) (copy destination directory for copying kvm xml file and hd image file)
# example
# ./kvm-bkonevm.sh /etc/libvirt/qemu/pc014.xml /mnt/pc079/d/bak/0101_phasedbak


function funcCPULimit() {
curdttm=`date +%Y%m%d%H%M%S`
msg="cpulimit -e qemu-kvm -l 5 &"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
cpulimit -e qemu-kvm -l 10 &

curdttm=`date +%Y%m%d%H%M%S`
msg="cpulimit -e rsync -l 10 &"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
cpulimit -e rsync -l 20 &

curdttm=`date +%Y%m%d%H%M%S`
msg="cpulimit -e mysqldump -l 5 &"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
cpulimit -e qemu-kvm -l 10 &

return 11
}


# パスの文字列に「//」のように不要な「/ (スラッシュ)」が入っている場合は
# 「//」を「/」へ置き換える。
function FuncReplaceDoubleSlashtoSingle() {
wstr=$1
retstr=`echo "${wstr}" | sed -e 's/\/\//\//g'`
echo ${retstr}
}

function FuncRemoveRightSlash() {
wstr=$1

# wstr の最後の一文字を抜き出す。
wstrlenall=`echo $((${#wstr}))`
lastchar=${wstr:${wstrlenall}:${wstrlenall}}

if [[ ${lastchar} = "/" ]]
then
# 一番右端の一文字が「/」なら
# 「/」を削除する。
retstr=${wstr##*/}
else
# 一番右端の一文字が「/」以外なら
# 削除処理は不要
retstr=${wstr}
fi

echo ${retstr}

}

function FuncAddRightSlash() {
wstr=$1

# wstr の最後の一文字を抜き出す。
wstrlenall=`echo $((${#wstr}))`
lastchar=${wstr:${wstrlenall}:${wstrlenall}}

if [[ ${lastchar} = "/" ]]
then
# 一番右端の一文字が「/」なら
# 「/」を追加する必要はない。
retstr=${wstr}
else
# 一番右端の一文字が「/」以外なら
# 「/」を追加する。
retstr=${wstr}'/'
fi

echo ${retstr}

}

function FuncGetStrQuotedWithDifferentStr() {

# getting kvm sv251.xml information
# wallstr=`virsh domxml-to-native qemu-argv /etc/libvirt/qemu/sv251.xml`

# 第1引数は、
# 「virsh domxml-to-native qemu-argv (kvm の xml ファイルフルパス)」
# の値。
# wallstr=$1
# wallstr=`virsh domxml-to-native qemu-argv /etc/libvirt/qemu/sv251.xml`

# echo '${1}..........'$1
wallstr=$1
# echo '${wallstr}..........'${wallstr}

wallstrlen=`echo ${#wallstr}`

# echo 'wallstrlen is '${wallstrlen}

# searchtarget_leftstr='-drive file='
searchtarget_leftstr=$2
searchtarget_leftstrlen=`echo ${#searchtarget_leftstr}`
# searchtarget_rightstr=','
searchtarget_rightstr=$3


tempstr[0]=`echo "${wallstr##*${searchtarget_leftstr}}"`
# echo '${tempstr[0]} is '${tempstr[0]}
tempstrlen[0]=`echo ${#tempstr[0]}`
# echo '${tempstrlen[0]} is '${tempstrlen[0]}

targetstr_startpos=`expr ${wallstrlen} - ${tempstrlen[0]}`
# echo '${targetstr_startpos} is '${targetstr_startpos}
targetstr_startpos_fixed=`expr ${targetstr_startpos} + 1`

tempstr[1]=`echo "${tempstr[0]#*${searchtarget_rightstr}}"`
# echo '${tempstr[1]} is '${tempstr[1]}
tempstrlen[1]=`echo ${#tempstr[1]}`
# echo '${tempstrlen[1} is '${tempstrlen[1]}

targetstr_endpos=`expr ${wallstrlen} - ${tempstrlen[1]}`
# echo '${targetstr_endpos} is '${targetstr_endpos}
targetstr_endpos_fixed=`expr ${targetstr_endpos} - 1`
# echo '${targetstr_endpos_fixed} is '${targetstr_endpos_fixed}


# retstr=`echo ${wallstr} | cut -c ${targetstr_startpos}-${targetstr_endpos_fixed}`
retstr=`echo ${wallstr} | cut -c ${targetstr_startpos_fixed}-${targetstr_endpos_fixed}`

echo ${retstr}


}


function funcGetKVMInfo() {
# getting KVM xml file copy source, destination,
# and getting KVM hd file copy source, destination

# getting KVM HDD information
# wstr=`virsh domxml-to-native qemu-argv /etc/libvirt/qemu/sv251.xml`


wstr=`virsh domxml-to-native qemu-argv ${kvmxml_fullpath_src}`

# KVM の 仮想マシン名を取得する。
# 左側が「'-name '」で、(一番右端に半角スペースを含める)
leftstr='-name '
# 右側が「' -uuid'」で、(一番左端に半角スペースを含める)
# rightstr=' -uuid'
rightstr=' '
# 囲まれた文字列を、${wstr} から探し出して、
# kvm_hd_fullpath_src に代入する。
# 引数 ${wstr} の内容が半角スペースを含むため、"" でくくる。
targetvmname=`FuncGetStrQuotedWithDifferentStr "${wstr}" "${leftstr}" "${rightstr}"`
# echo '${targetvmname} is "'${targetvmname}'"'

curdttm=`date +%Y%m%d%H%M%S`
msg='${targetvmname} is "'${targetvmname}'"'
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}


# KVM の 仮想 HDD のフルパスを取得する。
# 左側が「'-drive file='」で、
leftstr='-drive file='
# 右側が「','」で、
rightstr=','
# 囲まれた文字列を、${wstr} から探し出して、
# kvm_hd_fullpath_src に代入する。
# 引数 ${wstr} の内容が半角スペースを含むため、"" でくくる。
kvm_hd_fullpath_src=`FuncGetStrQuotedWithDifferentStr "${wstr}" "${leftstr}" "${rightstr}"`
# echo '${kvm_hd_fullpath_src} is '${kvm_hd_fullpath_src}
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvm_hd_fullpath_src} is '${kvm_hd_fullpath_src}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

# kvm_hd_dir_src=`echo ${kvm_hd_fullpath_src%/*}`
kvm_hd_dir_src=${kvm_hd_fullpath_src%/*}
# echo '${kvm_hd_dir_src} is '${kvm_hd_dir_src}
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvm_hd_dir_src} is '${kvm_hd_dir_src}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

# echo '${kvmxml_fullpath_src} is '${kvmxml_fullpath_src}
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvmxml_fullpath_src} is '${kvmxml_fullpath_src}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

kvm_xml_dir_src=${kvmxml_fullpath_src%/*}
# echo '${kvm_xml_dir_src} is '${kvm_xml_dir_src}
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvm_xml_dir_src} is '${kvm_xml_dir_src}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

# echo '${copybasedir_dest} is '${copybasedir_dest}
curdttm=`date +%Y%m%d%H%M%S`
msg='${copybasedir_dest} is '${copybasedir_dest}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
curdt=`date +%Y%m%d`

thispchostname=`hostname -s`

kvmxml_copydir_dest=`FuncAddRightSlash ${copybasedir_dest}`
# kvmxml_copydir_dest=${kvmxml_copydir_dest}`FuncAddRightSlash ${curdt}`
kvmxml_copydir_dest=${kvmxml_copydir_dest}`FuncAddRightSlash ${curdttm}`
kvmxml_copydir_dest=${kvmxml_copydir_dest}`FuncAddRightSlash ${thispchostname}`
kvmxml_copydir_dest=${kvmxml_copydir_dest}`FuncRemoveRightSlash ${kvm_xml_dir_src}`
kvmxml_copydir_dest=`FuncReplaceDoubleSlashtoSingle ${kvmxml_copydir_dest}`
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvmxml_copydir_dest} is '${kvmxml_copydir_dest}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
kvmhd_copydir_dest=`FuncAddRightSlash ${copybasedir_dest}`
# kvmhd_copydir_dest=${kvmhd_copydir_dest}`FuncAddRightSlash ${curdt}`
kvmhd_copydir_dest=${kvmhd_copydir_dest}`FuncAddRightSlash ${curdttm}`
kvmhd_copydir_dest=${kvmhd_copydir_dest}`FuncAddRightSlash ${thispchostname}`
kvmhd_copydir_dest=${kvmhd_copydir_dest}`FuncRemoveRightSlash ${kvm_hd_dir_src}`
kvmhd_copydir_dest=`FuncReplaceDoubleSlashtoSingle ${kvmhd_copydir_dest}`
# echo '${kvmhd_copydir_dest} is '${kvmhd_copydir_dest}
curdttm=`date +%Y%m%d%H%M%S`
msg='${kvmhd_copydir_dest} is '${kvmhd_copydir_dest}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

}

function funcWaitWithCountDown() {
wWaitSecCount=$1
wBaseMsg=$2
curdttm=`date +%Y%m%d%H%M%S`
msg="${wWaitSecCount} ${wBaseMsg}"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
until [ ${wWaitSecCount} -eq 0 ]
do
curdttm=`date +%Y%m%d%H%M%S`
msg="${wWaitSecCount}"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
wWaitSecCount=`expr ${wWaitSecCount} - 1`
sleep 1
done

}

function funcKVM_VM_PowerOnProcStart() {
# echo "now start vm "${targetvmname}
curdttm=`date +%Y%m%d%H%M%S`
msg="Now PowerOn the vm "${targetvmname}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
msg=`virsh start ${targetvmname}`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
msg="The PowerOn Process has finished. Please wait for OS to start."${targetvmname}
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

}

function funcKVM_VM_ShutdownStart() {
curdttm=`date +%Y%m%d%H%M%S`
msg="starting to shutdown ${targetvmname}..."
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
# echo ${targetvmname}"shutdown starting..."
# ssh -t -t root@${targetvmname} shutdown -h now
curdttm=`date +%Y%m%d%H%M%S`
# msg=`ssh -t -t root@${targetvmname} shutdown -h now`
msg=`virsh shutdown ${targetvmname}`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
msg="shutdown process of ${targetvmname} has started..."
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
}

function funcKVM_VM_ShutdownFinishWait() {
while [ 1 -eq 1 ]
do
curvmdomstat=`virsh domstate ${targetvmname}`
# echo "curent ${targetvmname} status is ${curvmdomstat}"
curdttm=`date +%Y%m%d%H%M%S`
msg="curent ${targetvmname} status is ${curvmdomstat}. Now waiting for shut off..."
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
sleep 1
if [ `echo ${curvmdomstat} | grep シャットオフ` ]; then
break
fi
if [ `echo ${curvmdomstat} | grep "shut off"` ]; then
break
fi
done

curdttm=`date +%Y%m%d%H%M%S`
msg="curent ${targetvmname} status is ${curvmdomstat}"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
curdttm=`date +%Y%m%d%H%M%S`
msg="Now ${targetvmname} is confirmed to be ${curvmdomstat}"
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

}


function funcKVM_VM_XML_backup() {
curdttm=`date +%Y%m%d%H%M%S`
msg=`mkdir -p -m +w ${kvmxml_copydir_dest} 2>&1`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
msg=`rsync -avvv --delete --timeout=3600 --bwlimit=8192 ${kvmxml_fullpath_src} ${kvmxml_copydir_dest} 2>&1`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
return 11
}

# rsync option
# --bwlimit=8192 --timeout=3600
# is added to avoid the following error
# rsync: connection unexpectedly closed
#
# reference
# http://kawama.jp/archives/2007/12/rsyncssh.html
function funcKVM_VM_HDImgFile_backup() {
curdttm=`date +%Y%m%d%H%M%S`
msg=`mkdir -p -m +w ${kvmhd_copydir_dest} 2>&1`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}

curdttm=`date +%Y%m%d%H%M%S`
msg=`rsync -avvv --delete --timeout=3600 --bwlimit=8192 ${kvm_hd_fullpath_src} ${kvmhd_copydir_dest} 2>&1`
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}


return 11
}

function funcDispFinishedMessage() {
curdttm=`date +%Y%m%d%H%M%S`
msg="${targetvmname} backup process has finished. Thank you for your cooperation."
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${logdirfilename}
return 11
}

function funcMainProc() {
# funcWaitWithCountDown 30 " now waiting for starting a process of KVM xml and hd file backup... If you want to stop, Ctrl+C"
funcCPULimit
funcGetKVMInfo
funcWaitWithCountDown 30 " now waiting for shutdown ${targetvmname}... If you want to stop, Ctrl+C"
funcKVM_VM_ShutdownStart
funcKVM_VM_ShutdownFinishWait
funcWaitWithCountDown 30 " now waiting for staring file copy of ${targetvmname} files... If you want to stop, Ctrl+C"
funcKVM_VM_XML_backup
funcKVM_VM_HDImgFile_backup
funcKVM_VM_PowerOnProcStart
funcDispFinishedMessage
}

function funcMain() {
funcMainProc
}


curdttm=`date +%Y%m%d%H%M%S`
curdt=`date +%Y%m%d`
# ログファイル名を決定する。
curdttmforlogfilename=${curdttm}
logdir='/var/log/1050/'
mkdir -p -m +w ${logdir} 2>&1
logfilename_suffix='_log_'
shfilename=`basename $0`
logfilename_ext='.txt'
quotstr='"'
logdirfilename=${logdir}${curdttmforlogfilename}${logfilename_suffix}${shfilename}${logfilename_ext}


kvmxml_fullpath_src=$1
copybasedir_dest=$2
# funcMain ${kvmxml_fullpath_src} ${copydir_dest}
funcMain ${kvmxml_fullpath_src} ${copydir_dest}

Linux (CentOS 6.2 x86_64 用) スクリプトご利用上の注意点、免責事項

このブログで公開されている、Linux (CentOS 6.2 x86_64 用) スクリプトをご利用になる場合の注意点、免責事項を以下のとおりお伝えいたします。

  • Linux (CentOS 6.2 x86_64 含む) で利用される場合は、以下のスクリプトをコピーしてテキストエディタに貼り付けて、「UTF-8(BOM無)」「改行コード(LFのみ)」でファイル名は「mybackup01.sh」と、拡張子は「.sh」にする点にご留意下さい。
  • 私のマシンでは特に問題なく動作していることを確認していますが、他のマシンでも必ず意図通りに動作するという保証はいたしかねます。
  • 以下のスクリプトを利用したことによるあらゆる障害 (データの消失、破損、時間的損害、金銭的損害につながる障害を含めた障害) が発生した場合、私は一切の責任を負いかねます。その点をご了承の上でご利用をお願い致します。
  • もし誤りやお気づきの点がありましたらお知らせくださると幸いです。
  • 恐れ入りますが、このスクリプトに関してのサポートは控えさせて頂きます。
  • 商用、非商用に限らずご利用はご自由にどうぞ。

linux (CentOS 6.2 x86_64) で、「cpulimit」と --bwlimit を使って、マシン負荷を減らしネットワーク負荷を減らして rsync を実行する方法

1.rsync の高負荷を減らすには

Linux の rsync (Windows の robocopy に相当) は非常に便利です。ただしマシンやネットワークにとって高い負荷がかかって困る場合もあります。

  • rsync を実行すると、マシンに高い負荷がかかりの動作が重たくなる
  • rsync を実行すると、ネットワークに高い負荷がかかり、Web サイトの読み込みが遅くなる、あるいはエラーが発生する。

ここでは、「Linux (CentOS 6.2 x86_64 ディストリビューション)」の場合を例に、「マシンにとって低負荷、ネットワークにとっても低負荷」な rsync を実行する手順を説明します。

2.前準備

事前に、cpulimit というソフトをインストールしておきます。

(参考) Linux (CentOS 6.2 x86_64) に、「cpulimit」をインストールして、実行する (= 絶対的な優先度を下げる) 手順

http://hachitaro.blogspot.jp/2012/06/linux-centos-62-x8664-cpulimit.html

3.rsync スクリプトの例

私が作成した、「マシンとネットワークに低負荷の rsync」スクリプトを以下に記します。

「スクリプトご利用上の注意」をよくお読みの上、ご了承いただいた方はご利用下さい。

「mybackup01.sh」

#!/bin/sh

# clamproc1501

# 実行中のスクリプトのディレクトリを取得
# CURDIR=`pwd`
CURDIR=`dirname $0`
# echo ${CURDIR}
thispchostname=`hostname -s`
echo ${thispchostname}


curdttmforlogfilename=`date +%Y%m%d%H%M%S`

logfilesdir='/var/log/1050/'
rsynclogdir='/var/log/1050/'
rsynclogfilename_suffix='rsynclog'

mkdir -m 777 -p ${logfilesdir}
mkdir -m 777 -p ${rsynclogdir}

shfilename=`basename $0`
logfilename_ext='.txt'
quotstr=



rsynclogdirfilename=${rsynclogdir}${curdttmforlogfilename}_${thispchostname}_${shfilename}_${rsynclogfilename_suffix}${logfilename_ext}


# 関数の戻り値
RETNOTSET=1
RETTRUE=11
RETFALSE=12

popd
wScriptDir=$(cd $(dirname $0) && pwd)
pushd

. ${wScriptDir}'/../0000_com/'com_proc.sh

PATH=/usr/bin:/bin


# syncing nas252 to nas253

func_check_other_proc() {
func_check_other_highload_process_running
rtn=$?
if [ "$rtn" -ne 11 ]
then
return ${rtn}
fi

return 11
}

func_rsync() {
# コピー元ディレクトリの指定
#
# 「hachitaro」ディレクトリごと、rsync するので、
# 「/mnt/nas123/usr/hachitaro/」
# ではなく
# 「/mnt/nas123/usr/hachitaro」
# を指定する。
rsync_sourcedir_file="mnt/nas123/usr/hachitaro"

# コピー先ディレクトリの指定
# rsync_dest_dir="/mnt/nas456/bk/server1001/pc/usr/"
rsync_dest_dir="/mnt/nas456/bk/server1001/pc/usr/"

# rsync の CPU 最大使用率を50%に制限。(CPUの優先度ではない)
cpulimit -e rsync -l 50 &

# rsync 実行
# rsync -avvv --stats ${rsync_sourcedir_file} ${rsync_dest_dir} | tee -a ${rsynclogdirfilename}

# rsync 実行
# --bwlimit=()KBytes
# 「 --bwlimit=1000」は、 1000KB/s (= 1MB/s) の意味
# 「 --bwlimit=10000」は、 10000KB/s (= 10MB/s) の意味
# 「 --bwlimit=50000」は、 20000KB/s (= 20MB/s) の意味
# 「 --bwlimit=50000」は、 50000KB/s (= 50MB/s) の意味
# 「--bwlimit=100000」は、100000KB/s (=100MB/s) の意味
rsync -avvv --stats --bwlimit=20000 ${rsync_sourcedir_file} ${rsync_dest_dir} | tee -a ${rsynclogdirfilename}


return 11
}


func_main() {
local -i rtn
rtn=1

func_check_other_proc
func_check_other_proc
rtn=$?
if [ "$rtn" -ne 11 ]; then return ${rtn}; fi


# rcync
func_rsync
rtn=$?
if [ "$rtn" -ne 11 ]; then return ${rtn}; fi

# すべての処理が終了して、ここまで処理がすすんだ場合、「処理はすべて正常終了」
# とみなす。

rtn=11
return ${rtn}


}



func_main
rtn=$?

curdttm=`date +%Y%m%d%H%M%S`
if [ "$rtn" -ne 11 ]
then
# 処理で以上が発生したため、これより以下の処理は続行はしない。
curdttm=`date +%Y%m%d%H%M%S`
msg="処理途中で異常が発生したため、処理を途中で中断しました。"' 2>&1'
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${thispchostname}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${clamproclogdirfilename}
else
# 処理が正常終了したため、次の処理へ進む
curdttm=`date +%Y%m%d%H%M%S`
msg="処理がすべて正常に終了しました。"' 2>&1'
echo "${quotstr}${curdttm}${quotstr} ${quotstr}${thispchostname}${quotstr} ${quotstr}${msg}${quotstr}" | tee -a ${clamproclogdirfilename}
fi


Linux (CentOS 6.2 x86_64) に、「cpulimit」をインストールして、実行する (= 絶対的な優先度を下げる) 手順

1.「cpulimit」概要 nice コマンドとは別の方法で優先度を強制的に下げるソフト

Linux には、nice コマンドを使って相対優先度を変更することができます。Windows 7 ではタスクマネージャーの「プロセス」タブの「基本優先度」 に相当するものです。(低、通常以下、通常、通常以上、高、リアルタイム)

Linux で 「nice コマンドを利用して、とあるプロセス (例えば rsync や FaHCore_a4.exe など) の優先度を可能な限り下げたけれども、マシンの動作が重たくて、kill をすると軽くなる」という場合があります。

この場合は、「cpulimit」というソフトをインストールすることで、その重たいプロセスの絶対的な優先度を下げることができます。

原理は単純で、cpulimit がそのプロセスを定期的に頻繁に sleep させるというものです。

Linux (CentOS などの Redhat Enterprise Linux 系ディストリビューション) で「nice コマンドをつかってもマシンが重たくて困っている」という方は、「cpulimit」をインストールする手順を説明します。

ちなみに、Ubuntu は、別のインストール手順があります。そちらは恐れ入りますが、別の Web ページをご参照をお願い致します。

2.「cpulimit」インストール

cpulimit インストールの手順です。インストールとは言ってもソースコードをダウンロードして make します。難しくはないかと思います。

ここでは「cpulimit-1.1」のバージョンを例に上げて説明します。もしバージョンの数値が変わったら数値を読み替えて実行して下さい。

# wget http://downloads.sourceforge.net/cpulimit/cpulimit-1.1.tar.gz
# tar zxvf cpulimit-1.1.tar.gz
# cd cpulimit-1.1
# make
# cp cpulimit /usr/bin/

以上でインストールが完了です。

3.「cpulimit」ごく簡単な実行例

rsync の CPU 最大使用率を 50% に制限する例です。

一番最後に「&」をつけるのをお忘れなく。

cpulimit -e rsync -l 50 &

2012年6月20日水曜日

ウィルコム WX01 キーロック ON/OFF (オン/オフ) の切替手順、利用するボタンはどれ

「ウィルコム WX01 キーロック ON/OFF (オン/オフ)の切替手順、利用するボタンはどれかわからない」と、お困りの方もいらっしゃるかと思います。

理由は 2 つです。

  1. 本体の箱に取扱説明書が入っていなかった。
  2. 説明書を、メーカーのサイトからダウンロードして説明書通りに「* ロック」キーを押しても、ロックされない

    まずは「*」キーに「ロック」と書かれていません。それならばと他のキーを探しても「ロック」と書かれてあるキーは見当たりません。「安全運転モード」キーは見つかりますが、キーロックとは別の機能です。

ボタンの表記と、実際の製品の表記が異なっています。表記だけではなく機能や手順も異なっているということです。

WX01 の出荷時期によって、仕様変更が行われているのかもしれません。

「WX01 を、取扱手順書通りに操作をしてもキーロックできない」方は、以下のいずれかでキーロックが出来ると思われます。一つずつ試すことをおすすめします。

  • 「* ロック」と書かれたボタンを長押しする

    操作手順書の 27 ページには、「* ロック」キーを長押しするようにと、説明が書かれています。

  • 「OK」と書かれたボタンを長押しする

    ウィルコムのページで紹介されている、WX01 には「OK」と書かれたボタンがあります。筆者の手元にある WX01 には、同じ位置にボタンはありますが「OK」とは書かれていません。

    出荷時期によって、ボタンの表記などに差異があるかもしれません。

  • 「(OKという文字が書かれていないが、上下左右を操作するキーの中央にあるキー)」を長押しする

    以下のキーです

以下、画面例です。

  1. 画面例その1.キーロックOFF (オフ) の状態の画面

    「キー」のアイコンが画面に表示されていない

    アイコンが、3つ表示されています。

    なお、「メールアイコン」、「『MENU』アイコン」、「電話帳アイコン」は、筆者が作成したいわゆる造語です。取扱説明書には特に説明が書かれていなかったため、説明の便宜上、名前を付けさせて頂きました。

  2. 画面例その2.キーロックON (オン) の状態の画面

    「キー」のアイコンが画面に表示されている

    以下は、上の拡大画像です。

ウィルコム WX01 マナーモード ON/OFF の切替手順、利用するボタンはどれ

ウィルコム WX01 マナーモード ON/OFF の切替手順、利用するボタンはどれか?

WX01UT の取扱説明書 (参照: ) 27ページの「マナーモード」の項目によると、以下のように説明されています。

「0(数字のゼロ) わ マナー」のボタンを長押しすれば、マナーモードに入ります。
(中略)
マナーモードを解除するには、もう一度「0(数字のゼロ) わ マナー」を押します。

これは、皆様が実際にお手持ちの WX01 の種類によって、若干異なる可能性があります。(私は WX01NX です)

「* マナー」というように、「とにかく『マナーと書かれたボタンを長押し』」すれば、マナーモードの ON/OFF を切り替えることができます。

2012年6月19日火曜日

ウィルコム WX01 製品情報、取扱説明書ダウンロードの URL

Google の検索のテキストボックスに「ウィルコム」と入力をすると「ウィルコム 解約」という検索候補が一番先頭に来るようになってどれくらいの時間がたったでしょうか・・・

このブログでは、ウィルコムの1ユーザーとして筆者が淡々とウィルコム(willcom) についても書いていきます。

ウィルコムの「もう1台無料」キャンペーンで「WX01 (機種名)」を入手された方もいらっしゃるかと思います。

「取扱説明書が同梱されていると外箱には記載されているのに同梱されていない」とお困りの方、ウィルコム WX01 製品情報、取扱説明書ダウンロードの URL は、以下の通りです。