All Nag-Mon users. You can contact me if you have any question or problem with Nag-Mon tool.
My email address is "faktoriyel@yahoo.com". Thank you for your interesting.
vitaminikabugunda
8 Nisan 2016 Cuma
5 Ağustos 2013 Pazartesi
Nagios İçin Oracle ASM File System Disk Alanı Sorgulama
Merhaba;
Bu makalede Nagios için oluşturduğum Oracle Asm File Sytem üzerindeki disk grupların boş alan sorgusunu yapan program hakkında bilgi vermeye çalışacağım. Programı bu sefer shell script olarak yazdım. Basit olarak kontrol edilen sisteme bağlanıp çeşitili asm komutlarıyla disk sorgularını yaptıktan sonra verilen parametrelere göre kalan boş disk alanının değerlendirip gerekli alarm durumlarını Nagios'a bildiren bir program. Elbetteki birçok kullanıcı nagios'a direk olarak Oracle DBA kullanıcısı yapmak istemeyeceği için bu işlemleri sudo komutu yardımıyla gerçekleştirceğiz.
Öcelikle sistemin şu şekilde olduğunu varsayalım.
Sistemdeki Nagios kullanıcısı: nagiosadm
Sistemdeki ASM kullanıcısı: asmadmin
asmadmin için ORACLE_HOME klasörü: /home/asmadmin/
asm için instance name'i: ASMINS
Buna göre asm komutları nagios tarafından çalıştırılacağı için /etc/sudoers dosyasında aşağıdaki değişikliklerin de yapılması gerekmektedir.
sudoedit /etc/sudoers
komutuyla sudoers dosyasını açtıktan sonra aşağıdaki satırları ekliyoruz
cmnd_alias ASM_COMMANDS = /home/asmadmin/bin/asmcmd
##Bu satırla sudo kullanıcısının sadece asmcmd komutunu çalıştırma yetkisini vereceğiz
Defaults:nagiosadm !requiretty
##nagiosadm kullanıcısının herhangi bir tty kullanmadan sudo komutunu çalıştırmasına izin vereceğiz. Çünkü nagios komutları uzaktan çalıştırma yöntemini kullanıyor
Defaults:nagiosadm env_keep += "ORACLE_HOME ORACLE_SID PATH"
##nagios adm kullanıcısı sudo ile asmadmin kullanıcısına geçtiğinde bu shell değişkenlerine ihtiyaç duyacaktır.
nagiosadm ALL=(asmadmin) NOPASSWD: ASM_COMMANDS
##son olarak bu satırla nagios kullanıcısıın asm admin kullanıcısı olarak yalnızca ASM_COMMANDS alias'ında tanımlı /home/asmadmin/bin/asmcmd komutunu password kullanmadan çalıştırabileceğini belirtiyoruz. Bu sayede sizlere sudoers dosyasının nasıl çalıştığını da anlatmış oldum.
Güvenlik konusunu abartma isteyenler olursa nagios kullanıcısına password atamayarak bir adım daha ileri gideceğini söyleyebiliriz.
Bundan sonra aşağıdaki program kodunda gömüş olduğunuz ORACLE_SID=ASMINS, ORACLE_HOME=/home/asmadmin, PATH=$PATH:$ORACLE_HOME/bin, ORACLE_USER=asmadmin satırlarını kendi ortamınza göre güncellemeniz gerekecektir.
Daha sonra bu komutu /usr/local/nagios/libexec altına kopyaladıktan sonra /etc/nagios/nrpe.cfg dosyasına aşağıdaki satırı eklemelisiniz.
command[check_oracleasm_free_disk_test]=/usr/local/nagios/libexec/check_oracleasm_free_disk.sh -w 30 -c 10 TEST
Burada "-w 30 " warnnig alarm seviyesini "c 10" ciritcal alarm seviyesini TEST ise kontrol edilecek disk grubunu iafede etmektedir.
Bir önceki makalede anlatıldğı şekilde nagios server üzerindeki tanımları yaptıktan sonra kullanmaya başlayabilirsiniz.
Başka bir makalede görüşmek üzere...
#!/bin/sh
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User specific aliases and functions
export ORACLE_SID=ASMINS
export ORACLE_HOME=/home/asmadmin
export PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_USER=asmadmin
PROGNAME=`basename $0`
PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION=`echo '$Revision: 1.15 $' | sed -e 's/[^0-9.]//g'`
. $PROGPATH/utils.sh
if [ "$#" -eq 3 ]; then
FREE_DISK=$(sudo -u $ORACLE_USER $ORACLE_HOME/bin/asmcmd lsdg | grep -w $3| awk '{ print $8 }')
if [[ $FREE_DISK == "" ]];then
echo "Disk group name cannot found."
exit $STATE_UNKNOWN
fi
case $1 in
"-c")
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
echo "Free disk space is OK. $FREE_DISK MB."
exit $STATE_OK
fi
;;
"-w")
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is warning.$FREE_DISK MB."
exit $STATE_WARNING
else
echo "Free disk space is OK. $FREE_DISK MB."
exit $STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_OK
esac
elif [ "$#" -eq 5 ]; then
FREE_DISK=$(sudo -u $ORACLE_USER $ORACLE_HOME/bin/asmcmd lsdg | grep -w $5| awk '{ print $8 }')
if [[ $FREE_DISK == "" ]];then
echo "Disk group name cannot found."
exit $STATE_UNKNOWN
fi
case $1 in
"-c")
if [ $3 = "-w" ];then
if [ $2 -ge $4 ];then
echo " Error: Critical value must be lover than Warning value"
exit $STATE_UNKNOWN
fi
else
echo "Second parameter is wrong."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
EXITVAL=$STATE_OK
fi
;;
"-w")
if [ $3 = "-c" ];then
if [ $2 -le $4 ];then
echo " Error: Warning value must be greater than critical value"
exit $STATE_UNKNOWN
fi
else
echo "Second parameter is wrong."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $2 ] && [ $FREE_DISK -gt $4 ];then
echo "Free disk space warning. $FREE_DISK MB."
exit $STATE_WARNING
else
EXITVAL=$STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
esac
case $3 in
"-c")
if [ $4 -ge $2 ];then
echo " Error: Critical value must be lover than Warning value"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $4 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
EXITVAL=$STATE_OK
fi
;;
"-w")
if [ $4 -le $2 ];then
echo " Error: Warning value must be greater than critical value"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $4 ] && [ $FREE_DISK -gt $2 ];then
echo "Free disk space warning. $FREE_DISK MB."
exit $STATE_WARNING
else
EXITVAL=$STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_OK
esac
echo "Free disk space is OK. $FREE_DISK MB."
exit $EXITVAL
else
echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
Bu makalede Nagios için oluşturduğum Oracle Asm File Sytem üzerindeki disk grupların boş alan sorgusunu yapan program hakkında bilgi vermeye çalışacağım. Programı bu sefer shell script olarak yazdım. Basit olarak kontrol edilen sisteme bağlanıp çeşitili asm komutlarıyla disk sorgularını yaptıktan sonra verilen parametrelere göre kalan boş disk alanının değerlendirip gerekli alarm durumlarını Nagios'a bildiren bir program. Elbetteki birçok kullanıcı nagios'a direk olarak Oracle DBA kullanıcısı yapmak istemeyeceği için bu işlemleri sudo komutu yardımıyla gerçekleştirceğiz.
Öcelikle sistemin şu şekilde olduğunu varsayalım.
Sistemdeki Nagios kullanıcısı: nagiosadm
Sistemdeki ASM kullanıcısı: asmadmin
asmadmin için ORACLE_HOME klasörü: /home/asmadmin/
asm için instance name'i: ASMINS
Buna göre asm komutları nagios tarafından çalıştırılacağı için /etc/sudoers dosyasında aşağıdaki değişikliklerin de yapılması gerekmektedir.
sudoedit /etc/sudoers
komutuyla sudoers dosyasını açtıktan sonra aşağıdaki satırları ekliyoruz
cmnd_alias ASM_COMMANDS = /home/asmadmin/bin/asmcmd
##Bu satırla sudo kullanıcısının sadece asmcmd komutunu çalıştırma yetkisini vereceğiz
Defaults:nagiosadm !requiretty
##nagiosadm kullanıcısının herhangi bir tty kullanmadan sudo komutunu çalıştırmasına izin vereceğiz. Çünkü nagios komutları uzaktan çalıştırma yöntemini kullanıyor
Defaults:nagiosadm env_keep += "ORACLE_HOME ORACLE_SID PATH"
##nagios adm kullanıcısı sudo ile asmadmin kullanıcısına geçtiğinde bu shell değişkenlerine ihtiyaç duyacaktır.
nagiosadm ALL=(asmadmin) NOPASSWD: ASM_COMMANDS
##son olarak bu satırla nagios kullanıcısıın asm admin kullanıcısı olarak yalnızca ASM_COMMANDS alias'ında tanımlı /home/asmadmin/bin/asmcmd komutunu password kullanmadan çalıştırabileceğini belirtiyoruz. Bu sayede sizlere sudoers dosyasının nasıl çalıştığını da anlatmış oldum.
Güvenlik konusunu abartma isteyenler olursa nagios kullanıcısına password atamayarak bir adım daha ileri gideceğini söyleyebiliriz.
Bundan sonra aşağıdaki program kodunda gömüş olduğunuz ORACLE_SID=ASMINS, ORACLE_HOME=/home/asmadmin, PATH=$PATH:$ORACLE_HOME/bin, ORACLE_USER=asmadmin satırlarını kendi ortamınza göre güncellemeniz gerekecektir.
Daha sonra bu komutu /usr/local/nagios/libexec altına kopyaladıktan sonra /etc/nagios/nrpe.cfg dosyasına aşağıdaki satırı eklemelisiniz.
command[check_oracleasm_free_disk_test]=/usr/local/nagios/libexec/check_oracleasm_free_disk.sh -w 30 -c 10 TEST
Burada "-w 30 " warnnig alarm seviyesini "c 10" ciritcal alarm seviyesini TEST ise kontrol edilecek disk grubunu iafede etmektedir.
Bir önceki makalede anlatıldğı şekilde nagios server üzerindeki tanımları yaptıktan sonra kullanmaya başlayabilirsiniz.
Başka bir makalede görüşmek üzere...
#!/bin/sh
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User specific aliases and functions
export ORACLE_SID=ASMINS
export ORACLE_HOME=/home/asmadmin
export PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_USER=asmadmin
PROGNAME=`basename $0`
PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION=`echo '$Revision: 1.15 $' | sed -e 's/[^0-9.]//g'`
. $PROGPATH/utils.sh
if [ "$#" -eq 3 ]; then
FREE_DISK=$(sudo -u $ORACLE_USER $ORACLE_HOME/bin/asmcmd lsdg | grep -w $3| awk '{ print $8 }')
if [[ $FREE_DISK == "" ]];then
echo "Disk group name cannot found."
exit $STATE_UNKNOWN
fi
case $1 in
"-c")
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
echo "Free disk space is OK. $FREE_DISK MB."
exit $STATE_OK
fi
;;
"-w")
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is warning.$FREE_DISK MB."
exit $STATE_WARNING
else
echo "Free disk space is OK. $FREE_DISK MB."
exit $STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_OK
esac
elif [ "$#" -eq 5 ]; then
FREE_DISK=$(sudo -u $ORACLE_USER $ORACLE_HOME/bin/asmcmd lsdg | grep -w $5| awk '{ print $8 }')
if [[ $FREE_DISK == "" ]];then
echo "Disk group name cannot found."
exit $STATE_UNKNOWN
fi
case $1 in
"-c")
if [ $3 = "-w" ];then
if [ $2 -ge $4 ];then
echo " Error: Critical value must be lover than Warning value"
exit $STATE_UNKNOWN
fi
else
echo "Second parameter is wrong."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $2 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
EXITVAL=$STATE_OK
fi
;;
"-w")
if [ $3 = "-c" ];then
if [ $2 -le $4 ];then
echo " Error: Warning value must be greater than critical value"
exit $STATE_UNKNOWN
fi
else
echo "Second parameter is wrong."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $2 ] && [ $FREE_DISK -gt $4 ];then
echo "Free disk space warning. $FREE_DISK MB."
exit $STATE_WARNING
else
EXITVAL=$STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
esac
case $3 in
"-c")
if [ $4 -ge $2 ];then
echo " Error: Critical value must be lover than Warning value"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $4 ];then
echo "Free disk space is critical. $FREE_DISK MB."
exit $STATE_CRITICAL
else
EXITVAL=$STATE_OK
fi
;;
"-w")
if [ $4 -le $2 ];then
echo " Error: Warning value must be greater than critical value"
exit $STATE_UNKNOWN
fi
if [ $FREE_DISK -le $4 ] && [ $FREE_DISK -gt $2 ];then
echo "Free disk space warning. $FREE_DISK MB."
exit $STATE_WARNING
else
EXITVAL=$STATE_OK
fi
;;
*)
echo echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_OK
esac
echo "Free disk space is OK. $FREE_DISK MB."
exit $EXITVAL
else
echo "Wrong parameter."
echo "The usage is $PROGNAME -w MB -c MB DISKGROUPNAME"
exit $STATE_UNKNOWN
fi
17 Mayıs 2013 Cuma
Nagios için HP ILO check
Herkese Merhaba;
Uzun zaman sonra birşeyler yazmaya karar verdim. Bu sefer diğer makalelerden farklı bir konuya değineceğim. Nagios uygulaması için HP ILO yönetim arayüzüne sorgular gönderip donanım aygıtlarını sorgulayan ve herhangi bir arıza durumunda önceden belirlenmiş uyarılar oluşturan bir script/program geliştirdim. Program perl ile yazıldı. HP sunuculardaki ILO portları ile direk iletişim kurduğundan işletim sistemi bağımsız ve bağlantısız çalışmaktadır. Bu nedenle sunucu shutdown konumunda iken bile donanım üzerindeki kontrolleri gerçekleştirebilirsiniz. Öncelikle Nagios hakkında biraz bilgi paylaşmak istiyorum. Nagios GPL lisansı ile dağıtımı yapılan Open Source Infrastructure Monitoring yazılımıdır. Temel olarak agent server mantığı ile çalışır ve monitor edilen cihazlarda yüklü olan agent'lardan gelen bilgileri değerlendirerek gerekli durumlarda uyarılar oluşturur. Kurulumu, implementasyonu ve yönetimi hayli kolay olmakla bu konuya başka bir makalede değineceğiz. Yazdığım program temel olarak Nagios Agent'ı olarak çalışmaktadır. Ancak aslında bir program olduğu için komut saturundan da çalıştırılabilir. Komut dizilimi aşağıdaki gibidir.
check_hpilo.pl SERVERNAME ILO_IP_NUMBER USERNAME PASSWORD (DISK|POWER|FAN|TEMP_SENSOR) DEVICEORDER|ALL
Burada server name olarak kontrol edilen HP sunucunun adı belirtilmelidir. Bu isim yalnızca uyarı mesajlarında kullanılacağından gerçek hostname kullanılması zorunlu değildir. ILO_IP_NUMBER alanı ise bağlantı kurulacak ILO IP'sidir. USERNAME ve PASSWORD ise HP ilo üzerinde tanımlı ve geçerli kullanıcı bilgileri içindir. Bu kullanıcı için standart kullanıcılar kullanılabileceği gibi yalnızca okuma yetkisi olan bir kullanıcı da oluşturabilirsiniz. Bir sonraki alan ise kontol edilecek donanım bileşenini tanımlamaktadır. Bu bileşenler DISK, POWER, FAN ve TEMP_SENSOR olabilir. Aynı anda yanlızca tek tip donanım bileşenine ait bilgiler sorgulanabilir. Yani aynı komutta hem disk hemde powersupply için sorgulama yapmaz. DEVICEORDER ise hangi aygıtların sorgulanacağı bilgisini içerir. Örneğin sunucuda 8 adet disk yuvası var ve bunlardan 4 tanesinde disk bulunuyorsa 1 2 3 4 olarak belirtilmelidir. Eğer bütün aygıtlar kontrol edilecekse ALL oalrak belirtilmeldir. Aşağıda komut yazım örnekleri ve buna ilişkin ekran çıktılarını görebilirsiniz.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass TEMP_SENSOR ALL
Everything is OK
Eğer hiçbir sorun yoksa program yukarıdaki sonucu verir ve 0 değerini döndürür.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass POWER 1 2 3 4 5 6 7 8 9
Wrong power order for 9. Pelase check your power number.
Eğer var olmayan bir aygıt numarası girilirse program tarafından yukarıdaki uyarı verilir. ve UNKNOWN değeri döndürülür.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass DISK 1 2 3 4 5 6
DBSERVER sunucusundaki 5 6 numarali DISK(ler/lar) uyari vermistir. Lutfen kontrol edin!
eğer sorgulanan aygıtlar için hata alınmışsa yukarıdakine benzer bir hata mesajı oluşturulur ve CRITICAL değeri döndürülür. Bu durumda nagios tarafından Critical uyarı oluşturulur ve gerekli aksiyonlar alınır.
Bu eklentinin Nagios tarafında tanımlanması ise aşağıdaki gibi gerçekleştirilir. Öncelikle commands.cfg dosyasına aşağıdaki satır eklenmeldir.
define command{
command_name check_hpilo
command_line $USER1$/check_hpilo.pl $HOSTNAME$ $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$ $ARG9$ $ARG10$ $ARG11$ $ARG12$ $ARG13$ $ARG14$ $ARG15$ $ARG16$
}
Daha sonra kontrol edilecek host'a ait konfigürasyon dosyasında aşağıdaki gibi tanımlama yapılmalıdır.
define service{
use generic-service
host_name DBSRV
service_description DBSRV ILO POWER CHECK
check_command check_hpilo!"nagios"!"nagioapass"!"POWER"!"ALL"
contact_groups linux,linux_sms
service_groups hpilo_services
max_check_attempts 1
check_interval 30
retry_interval 15
}
daha sonra nagios servisi restart edilerek kullanıma başlanabilir.
Kolay gelsin.
Code:
#!/usr/bin/perl
## hardware query via ILO
## written by Cengizhan CANLI
use XML::Simple;
use Sys::Hostname;
#use IO::Socket::SSL qw(debug2);
use IO::Socket::SSL;
use Getopt::Long;
#use HTTP::Request::Common;
#use Term::ReadKey;
$return_text="";
$STATE_OK=0;
$STATE_WARNING=1;
$STATE_CRITICAL=2;
$STATE_UNKNOWN=3;
$STATE_DEPENDENT=4;
my $debug=1;
my $socket,$sendsize,$ln="",$xml_response_ref="",@xml_response="";
my $time = localtime time;
my $localhost = hostname() || 'localhost';
sub print_help
{
print "The usage is check_hpilo.pl SERVERNAME ILO_IP_NUMBER USERNAME PASSWORD (DISK|POWER|FAN|TEMP_SENSOR) DEVICEORDER|ALL\n";
print "Example: check_hpilo.pl DBSERVER 192.168.1.2 nagios 12ab34cd DISK 1 2 3 4\n";
exit 0;
}
sub if_debug()
{
if ($debug)
{
open (DEBUG_FILE, ">>/tmp/$ARGV[0].$ARGV[4].debug");
print DEBUG_FILE "";
print DEBUG_FILE "-----------" . $time . "-------------------\n";
print DEBUG_FILE "-----------DEBUG START-------------------\n";
}
}
sub generate_xml_str #create xml string to send ILO with SSL
{
my $xml_str='<RIBCL VERSION="2.21"><LOGIN USER_LOGIN="'. $username.'" ' . ' PASSWORD='.'"'. $password .'"><SERVER_INFO MODE="read"><GET_EMBEDDED_HEALTH/></SERVER_INFO></LOGIN></RIBCL>';
return $xml_str;
}
sub send_to_client
{
print $socket $_[1];
}
sub send_or_calculate
{
$sendsize = 0;
$sendsize = length($ln);
if ($_[0]==1)
{
print $socket $ln;
}
}
sub read_chunked_reply # used for iLO 3 and iLO 4 only
{
my $hide=1;
my $isSizeOfChunk=1;
my $chunkSize;
my $cache = 1;
$response = "";
$RIBCLbusy = 0;
while(1) {
$ln=<$socket>;
if (length($ln) == 0)
{
last;
}
if ($hide)
{
# Skip HTTP response headers and "\r\n"s preceding chunked responses
if (length($ln) <= 2)
{
$hide=0;
}
}
else {
# Process chunked responses
if ($isSizeOfChunk) {
chomp($ln);
$ln =~ s/\r|\n//g; # clean $ln up
$chunkSize=hex($ln);
$isSizeOfChunk=0;
next;
}
if ($chunkSize == 0) { #End of responses; Empty responses
last;
}
if ($chunkSize == length($ln)) {
$isSizeOfChunk=1;
$hide=1; #End of chunk; Skip next line
}
else {
if ($chunkSize > length($ln)) {
$chunkSize -= length($ln);
#$ln = substr($ln,0,length($ln));
}
else {
$isSizeOfChunk=1; #Next line is size of next chunk
$ln = substr($ln,0,$chunkSize);
}
}
#now, print or cache the response
if ($cache && $ln =~ m/MESSAGE/i) {
if ($ln =~ m/RIBCL parser is busy/i) {
$RIBCLbusy = 1;
}
else {
$cache = 0;
}
}
if ($cache) {
# This isn't really required, but it makes the output look nicer
$ln =~ s/<\/RIBCL>/<\/RIBCL>\n/g;
}
else {
# This isn't really required, but it makes the output look nicer
$ln =~ s/<\/RIBCL>/<\/RIBCL>\n/g;
$response=$response.$ln ;
}
}
}
if ($socket->error()) {
print "Error: connection error " . $socket->error() . "\n";
print DEBUG_FILE "Error: connection error " . $socket->error() . "\n" if $debug;
}
@xml_response=split(/\n/,$response);
print DEBUG_FILE "--------------". $time . "-------------------\n" if $debug;
print DEBUG_FILE "--------------XML FILE -------------------\n" if $debug;
print DEBUG_FILE $response ."\n" if $debug;
return(\@xml_response);
}
sub send_xml_query()
{
my $boundary;
my ($start_time, $end_time, $xml_str);
$RIBCLbusy = 0;
$retry = 0;
$start_time = 0;
$end_time = 0;
$response = "";
$ln = generate_xml_str;
send_or_calculate(0); # Calculate $sendsize
while (!$retry || $RIBCLbusy) {
if ($retry == 1) { # 1st retry
my ($sec,$min) = localtime(time);
$start_time = $min * 60 + $sec;
}
if ($retry > 1) {
my ($sec,$min) = localtime(time);
$end_time = $min * 60 + $sec;
if ($end_time-$start_time > RETRY_TIMEOUT) { # retry upto RETRY_TIMEOUT seconds
print "\n----- Retry timed out. Script sent unsuccessfully.\n" if ($verbose);
last;
}
}
if ($retry) {
#print "\n----- iLO is busy. Resending the script... (Attempt #$retry)\n" if ($verbose);
sleep(RETRY_DELAY); # delay RETRY_DELAY seconds
}
# Send the HTTP header and begin processing the file
send_to_client(0, "POST /ribcl HTTP/1.1\r\n");
send_to_client(0, "HOST: $localhost\r\n"); # Mandatory for http 1.1
send_to_client(0, "User-Agent: locfg-Perl-script/".VERSION."\r\n");
send_to_client(0, "TE: chunked\r\n");
send_to_client(0, "Connection: Close\r\n"); # Required
send_to_client(0, "Content-length: $sendsize\r\n"); # Mandatory for http 1.1
send_to_client(0, "\r\n");
send_or_calculate(1); #Send it to iLO
# Ok, now read the responses from iLO
$xml_response_ref=read_chunked_reply();
$retry++;
} # end while
make_xml_data($xml_response_ref);
return;
}
sub open_https_connection()
{
$ilo_ip .= ":443" unless ($ilo_ip =~ m/:/);
$socket = IO::Socket::SSL->new(PeerAddr => $ilo_ip, SSL_verify_mode => 0x00) || die $ConnectionErrorMessage;
return;
}
sub close_https_connection()
{
$socket->close();
return;
}
sub make_xml_data($)
{
my $i=0,$j=2,$line_count=0,$switch=0;
my $xml_response_ref=$_[0];
@xml_response=@$xml_response_ref;
$line_count = $#xml_response;
@ln=0;$ln=0;
$xml_data[0]='<?xml version="1.0"?>'."\n";
$xml_data[1]='<RIBCL VERSION="2.22">'."\n";
while ($i <= $line_count)
{
$ln=$xml_response[$i];
$search_string='<GET_EMBEDDED_HEALTH_DATA>';
if ($ln =~ /$search_string/)
{
$switch=1;
}
if ($switch==1) {
$xml_data[$j]=$ln . "\n";
$j++;
}
$search_string='</GET_EMBEDDED_HEALTH_DATA>';
if ($ln =~ /$search_string/)
{
$switch=0;
$i=$line_count;
}
$i++;
}
$xml_data[$j+1]='</RIBCL>'. "\n";
print DEBUG_FILE "----------------- Edited XML FILE START--------------\n" if ($debug);
print DEBUG_FILE "------------------- ". $time . " --------------\n" if ($debug);
print DEBUG_FILE @xml_data if ($debug);
print DEBUG_FILE "----------------- Edited XML FILE END --------------\n" if ($debug);
print DEBUG_FILE @xml_data if ($debug);
chomp(@xml_data);
$i=0;
while ($i <= $#xml_data)
{
$xml_string.=$xml_data[$i];
$i++;
}
$xml= new XML::Simple;
$xml_data = $xml->XMLin($xml_string) or die "XML Data Error";
}
sub get_disk_status($)
{
my (@result_sub) = 0;
my @control_order_sub=0, $control_order_ref=0, $disk_number=0,$disk_number_mod=0, $backplane_count, $disk_count, $backplane_number,$i=0,$status,$all_disks;
$control_order_ref = $_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
## how many backplane in server
$backplane_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}};
##how many disks in each backplane
$disk_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}->[0]->{STATUS}};
if ($control_order_sub[0] eq "ALL")
{
$all_disks = $backplane_count * $disk_count ;
$i=0;
while($i < $all_disks)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $disk_number (@control_order_sub)
{
$backplane_number=int(($disk_number-1)/$disk_count);
$disk_number_mod = ($disk_number - 1) % $disk_count;
if ($backplane_number < $backplane_count)
{
$status = $xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}->[$backplane_number]->{STATUS}->[$disk_number_mod]->{VALUE};
print DEBUG_FILE $time . " ". "$localhost" . " Read Disk Status : " . "$status" ." \n" if $debug;
if ($status eq "Ok")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong disk order for $disk_number. Pelase check your disk number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_power_status($)
{
my @control_order_sub=0,$control_order_ref=0;
my $power_number=0, $power_count,$i=0,$status;
my @result_sub = 0;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
my $i = 0;
$power_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{POWER_SUPPLIES}->{SUPPLY}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $power_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $power_number (@control_order_sub)
{
if ($power_number <= $power_count)
{
$status=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{POWER_SUPPLIES}->{SUPPLY}->[$power_number-1]->{STATUS}->{VALUE};
print DEBUG_FILE $time ." ". "$localhost" . " Read Power Status : " . "$status" ." \n" if $debug;
if ($status eq "OK")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong power order for $power_number. Pelase check your power number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_fan_status($)
{
my $i = 0;
my @result_sub = 0,$control_order_ref=0, @control_order_sub=0;
my $fan_number=o, $fan_count=0,$i=0,$status;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
$fan_count=@{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{FANS}->{FAN}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $fan_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $fan_number (@control_order_sub)
{
if ($fan_number <= $fan_count)
{
$status=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{FANS}->{FAN}->[$fan_number-1]->{STATUS}->{VALUE};
print DEBUG_FILE $time ." ". "$localhost" . " Read Fan Status : " . "$status" ." \n" if $debug;
if ($status eq "OK")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong fan order for $fan_number. Pelase check your fan number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_temperature_status($)
{
my $temperature_number=o, $temperature_count,$i=0,$status,$current,$warning,$critical;
my @result_sub = 0, @control_order_sub = 0, $control_order_ref = 0,$i = 0;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
$temperature_count=@{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $temperature_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $temperature_number (@control_order_sub)
{
if ($temperature_number <= $temperature_count)
{
$current=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CURRENTREADING}->{VALUE};
$warning=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CAUTION}->{VALUE};
$critical=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CRITICAL}->{VALUE};
print DEBUG_FILE $time ." " . "$localhost" . " Read Temperature Status : " ."Current: " . "$current" . " Warning: ". " $warning" . "Critical: " . "$critical". " \n" if $debug;
if ($current >= $critical )
{
$result_sub[$i] = 2;
}
elsif ( $current >= $warning )
{
$result_sub[$i] = 1;
}
else
{
$result_sub[$i] = 0;
}
$i++;
}
else
{
print "Wrong temperature sensor order for $temperature_number. Pelase check your temperature sensor number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub create_nagios_alarm($$$$)
{
my (@result_str) = 0;
my ($device_status_ref, $control_order_ref, $device_name_str, $server_name_str) = @_;
my (@device_status_sub) = @$device_status_ref;
my (@control_order_sub) = @$control_order_ref;
my ($n) = 0;
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i <= $#device_status_sub)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$result_str="$server_name_str" . " sunucusundaki " ;
$EXIT_STATE = $STATE_OK;
chomp(@device_status_sub);
while ($n <= $#device_status_sub)
{
if ($device_status_sub[$n] == 1)
{
$result_str= "$result_str" . "$control_order_sub[$n]" . " ";
$EXIT_STATE=$STATE_WARNING;
}
if ($device_status_sub[$n] == 2)
{
$result_str= "$result_str" . "$control_order_sub[$n]" . " ";
$EXIT_STATE=$STATE_CRITICAL;
}
$n++;
}
if ($EXIT_STATE == $STATE_OK)
{
$result_str = "Everything is OK";
} else
{
$result_str = "$result_str" . "numarali " . "$device_name_str" . "(ler/lar)" . " uyari vermistir. Lutfen kontrol edin!";
}
return ($result_str);
}
###Main#####
my $socket;
my ($numArgs) = 0;
my $numArgs=$#ARGV ;
if_debug();
#print "Arguments: @ARGV \n";
if (($ARGV[0] eq "-h") || ($ARGV[0] eq "--help"))
{
print_help;
exit 2;
}
if ($numArgs < 5)
{
print "wrong argument number:". ($numArgs + 1) ." \n";
print_help;
exit 2 ;
}
$server_name = $ARGV[0];
$ilo_ip = $ARGV[1];
$username=$ARGV[2];
$password=$ARGV[3];
$device_name = $ARGV[4];
$n=0;
foreach $argnum (5 .. $numArgs)
{
$control_order[$n] = $ARGV[$argnum];
$n++;
}
if ($device_name eq "DISK")
{
$result = get_disk_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "POWER")
{
$result = get_power_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "FAN")
{
$result = get_fan_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "TEMP_SENSOR")
{
$result = get_temperature_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
else
{
print "Wrong device name.\n";
print_help;
exit 2;
}
Uzun zaman sonra birşeyler yazmaya karar verdim. Bu sefer diğer makalelerden farklı bir konuya değineceğim. Nagios uygulaması için HP ILO yönetim arayüzüne sorgular gönderip donanım aygıtlarını sorgulayan ve herhangi bir arıza durumunda önceden belirlenmiş uyarılar oluşturan bir script/program geliştirdim. Program perl ile yazıldı. HP sunuculardaki ILO portları ile direk iletişim kurduğundan işletim sistemi bağımsız ve bağlantısız çalışmaktadır. Bu nedenle sunucu shutdown konumunda iken bile donanım üzerindeki kontrolleri gerçekleştirebilirsiniz. Öncelikle Nagios hakkında biraz bilgi paylaşmak istiyorum. Nagios GPL lisansı ile dağıtımı yapılan Open Source Infrastructure Monitoring yazılımıdır. Temel olarak agent server mantığı ile çalışır ve monitor edilen cihazlarda yüklü olan agent'lardan gelen bilgileri değerlendirerek gerekli durumlarda uyarılar oluşturur. Kurulumu, implementasyonu ve yönetimi hayli kolay olmakla bu konuya başka bir makalede değineceğiz. Yazdığım program temel olarak Nagios Agent'ı olarak çalışmaktadır. Ancak aslında bir program olduğu için komut saturundan da çalıştırılabilir. Komut dizilimi aşağıdaki gibidir.
check_hpilo.pl SERVERNAME ILO_IP_NUMBER USERNAME PASSWORD (DISK|POWER|FAN|TEMP_SENSOR) DEVICEORDER|ALL
Burada server name olarak kontrol edilen HP sunucunun adı belirtilmelidir. Bu isim yalnızca uyarı mesajlarında kullanılacağından gerçek hostname kullanılması zorunlu değildir. ILO_IP_NUMBER alanı ise bağlantı kurulacak ILO IP'sidir. USERNAME ve PASSWORD ise HP ilo üzerinde tanımlı ve geçerli kullanıcı bilgileri içindir. Bu kullanıcı için standart kullanıcılar kullanılabileceği gibi yalnızca okuma yetkisi olan bir kullanıcı da oluşturabilirsiniz. Bir sonraki alan ise kontol edilecek donanım bileşenini tanımlamaktadır. Bu bileşenler DISK, POWER, FAN ve TEMP_SENSOR olabilir. Aynı anda yanlızca tek tip donanım bileşenine ait bilgiler sorgulanabilir. Yani aynı komutta hem disk hemde powersupply için sorgulama yapmaz. DEVICEORDER ise hangi aygıtların sorgulanacağı bilgisini içerir. Örneğin sunucuda 8 adet disk yuvası var ve bunlardan 4 tanesinde disk bulunuyorsa 1 2 3 4 olarak belirtilmelidir. Eğer bütün aygıtlar kontrol edilecekse ALL oalrak belirtilmeldir. Aşağıda komut yazım örnekleri ve buna ilişkin ekran çıktılarını görebilirsiniz.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass TEMP_SENSOR ALL
Everything is OK
Eğer hiçbir sorun yoksa program yukarıdaki sonucu verir ve 0 değerini döndürür.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass POWER 1 2 3 4 5 6 7 8 9
Wrong power order for 9. Pelase check your power number.
Eğer var olmayan bir aygıt numarası girilirse program tarafından yukarıdaki uyarı verilir. ve UNKNOWN değeri döndürülür.
./check_hpilo.pl DBSERVER 192.168.1.1 nagios nagiospass DISK 1 2 3 4 5 6
DBSERVER sunucusundaki 5 6 numarali DISK(ler/lar) uyari vermistir. Lutfen kontrol edin!
eğer sorgulanan aygıtlar için hata alınmışsa yukarıdakine benzer bir hata mesajı oluşturulur ve CRITICAL değeri döndürülür. Bu durumda nagios tarafından Critical uyarı oluşturulur ve gerekli aksiyonlar alınır.
Bu eklentinin Nagios tarafında tanımlanması ise aşağıdaki gibi gerçekleştirilir. Öncelikle commands.cfg dosyasına aşağıdaki satır eklenmeldir.
define command{
command_name check_hpilo
command_line $USER1$/check_hpilo.pl $HOSTNAME$ $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$ $ARG9$ $ARG10$ $ARG11$ $ARG12$ $ARG13$ $ARG14$ $ARG15$ $ARG16$
}
Daha sonra kontrol edilecek host'a ait konfigürasyon dosyasında aşağıdaki gibi tanımlama yapılmalıdır.
define service{
use generic-service
host_name DBSRV
service_description DBSRV ILO POWER CHECK
check_command check_hpilo!"nagios"!"nagioapass"!"POWER"!"ALL"
contact_groups linux,linux_sms
service_groups hpilo_services
max_check_attempts 1
check_interval 30
retry_interval 15
}
daha sonra nagios servisi restart edilerek kullanıma başlanabilir.
Kolay gelsin.
Code:
#!/usr/bin/perl
## hardware query via ILO
## written by Cengizhan CANLI
use XML::Simple;
use Sys::Hostname;
#use IO::Socket::SSL qw(debug2);
use IO::Socket::SSL;
use Getopt::Long;
#use HTTP::Request::Common;
#use Term::ReadKey;
$return_text="";
$STATE_OK=0;
$STATE_WARNING=1;
$STATE_CRITICAL=2;
$STATE_UNKNOWN=3;
$STATE_DEPENDENT=4;
my $debug=1;
my $socket,$sendsize,$ln="",$xml_response_ref="",@xml_response="";
my $time = localtime time;
my $localhost = hostname() || 'localhost';
sub print_help
{
print "The usage is check_hpilo.pl SERVERNAME ILO_IP_NUMBER USERNAME PASSWORD (DISK|POWER|FAN|TEMP_SENSOR) DEVICEORDER|ALL\n";
print "Example: check_hpilo.pl DBSERVER 192.168.1.2 nagios 12ab34cd DISK 1 2 3 4\n";
exit 0;
}
sub if_debug()
{
if ($debug)
{
open (DEBUG_FILE, ">>/tmp/$ARGV[0].$ARGV[4].debug");
print DEBUG_FILE "";
print DEBUG_FILE "-----------" . $time . "-------------------\n";
print DEBUG_FILE "-----------DEBUG START-------------------\n";
}
}
sub generate_xml_str #create xml string to send ILO with SSL
{
my $xml_str='<RIBCL VERSION="2.21"><LOGIN USER_LOGIN="'. $username.'" ' . ' PASSWORD='.'"'. $password .'"><SERVER_INFO MODE="read"><GET_EMBEDDED_HEALTH/></SERVER_INFO></LOGIN></RIBCL>';
return $xml_str;
}
sub send_to_client
{
print $socket $_[1];
}
sub send_or_calculate
{
$sendsize = 0;
$sendsize = length($ln);
if ($_[0]==1)
{
print $socket $ln;
}
}
sub read_chunked_reply # used for iLO 3 and iLO 4 only
{
my $hide=1;
my $isSizeOfChunk=1;
my $chunkSize;
my $cache = 1;
$response = "";
$RIBCLbusy = 0;
while(1) {
$ln=<$socket>;
if (length($ln) == 0)
{
last;
}
if ($hide)
{
# Skip HTTP response headers and "\r\n"s preceding chunked responses
if (length($ln) <= 2)
{
$hide=0;
}
}
else {
# Process chunked responses
if ($isSizeOfChunk) {
chomp($ln);
$ln =~ s/\r|\n//g; # clean $ln up
$chunkSize=hex($ln);
$isSizeOfChunk=0;
next;
}
if ($chunkSize == 0) { #End of responses; Empty responses
last;
}
if ($chunkSize == length($ln)) {
$isSizeOfChunk=1;
$hide=1; #End of chunk; Skip next line
}
else {
if ($chunkSize > length($ln)) {
$chunkSize -= length($ln);
#$ln = substr($ln,0,length($ln));
}
else {
$isSizeOfChunk=1; #Next line is size of next chunk
$ln = substr($ln,0,$chunkSize);
}
}
#now, print or cache the response
if ($cache && $ln =~ m/MESSAGE/i) {
if ($ln =~ m/RIBCL parser is busy/i) {
$RIBCLbusy = 1;
}
else {
$cache = 0;
}
}
if ($cache) {
# This isn't really required, but it makes the output look nicer
$ln =~ s/<\/RIBCL>/<\/RIBCL>\n/g;
}
else {
# This isn't really required, but it makes the output look nicer
$ln =~ s/<\/RIBCL>/<\/RIBCL>\n/g;
$response=$response.$ln ;
}
}
}
if ($socket->error()) {
print "Error: connection error " . $socket->error() . "\n";
print DEBUG_FILE "Error: connection error " . $socket->error() . "\n" if $debug;
}
@xml_response=split(/\n/,$response);
print DEBUG_FILE "--------------". $time . "-------------------\n" if $debug;
print DEBUG_FILE "--------------XML FILE -------------------\n" if $debug;
print DEBUG_FILE $response ."\n" if $debug;
return(\@xml_response);
}
sub send_xml_query()
{
my $boundary;
my ($start_time, $end_time, $xml_str);
$RIBCLbusy = 0;
$retry = 0;
$start_time = 0;
$end_time = 0;
$response = "";
$ln = generate_xml_str;
send_or_calculate(0); # Calculate $sendsize
while (!$retry || $RIBCLbusy) {
if ($retry == 1) { # 1st retry
my ($sec,$min) = localtime(time);
$start_time = $min * 60 + $sec;
}
if ($retry > 1) {
my ($sec,$min) = localtime(time);
$end_time = $min * 60 + $sec;
if ($end_time-$start_time > RETRY_TIMEOUT) { # retry upto RETRY_TIMEOUT seconds
print "\n----- Retry timed out. Script sent unsuccessfully.\n" if ($verbose);
last;
}
}
if ($retry) {
#print "\n----- iLO is busy. Resending the script... (Attempt #$retry)\n" if ($verbose);
sleep(RETRY_DELAY); # delay RETRY_DELAY seconds
}
# Send the HTTP header and begin processing the file
send_to_client(0, "POST /ribcl HTTP/1.1\r\n");
send_to_client(0, "HOST: $localhost\r\n"); # Mandatory for http 1.1
send_to_client(0, "User-Agent: locfg-Perl-script/".VERSION."\r\n");
send_to_client(0, "TE: chunked\r\n");
send_to_client(0, "Connection: Close\r\n"); # Required
send_to_client(0, "Content-length: $sendsize\r\n"); # Mandatory for http 1.1
send_to_client(0, "\r\n");
send_or_calculate(1); #Send it to iLO
# Ok, now read the responses from iLO
$xml_response_ref=read_chunked_reply();
$retry++;
} # end while
make_xml_data($xml_response_ref);
return;
}
sub open_https_connection()
{
$ilo_ip .= ":443" unless ($ilo_ip =~ m/:/);
$socket = IO::Socket::SSL->new(PeerAddr => $ilo_ip, SSL_verify_mode => 0x00) || die $ConnectionErrorMessage;
return;
}
sub close_https_connection()
{
$socket->close();
return;
}
sub make_xml_data($)
{
my $i=0,$j=2,$line_count=0,$switch=0;
my $xml_response_ref=$_[0];
@xml_response=@$xml_response_ref;
$line_count = $#xml_response;
@ln=0;$ln=0;
$xml_data[0]='<?xml version="1.0"?>'."\n";
$xml_data[1]='<RIBCL VERSION="2.22">'."\n";
while ($i <= $line_count)
{
$ln=$xml_response[$i];
$search_string='<GET_EMBEDDED_HEALTH_DATA>';
if ($ln =~ /$search_string/)
{
$switch=1;
}
if ($switch==1) {
$xml_data[$j]=$ln . "\n";
$j++;
}
$search_string='</GET_EMBEDDED_HEALTH_DATA>';
if ($ln =~ /$search_string/)
{
$switch=0;
$i=$line_count;
}
$i++;
}
$xml_data[$j+1]='</RIBCL>'. "\n";
print DEBUG_FILE "----------------- Edited XML FILE START--------------\n" if ($debug);
print DEBUG_FILE "------------------- ". $time . " --------------\n" if ($debug);
print DEBUG_FILE @xml_data if ($debug);
print DEBUG_FILE "----------------- Edited XML FILE END --------------\n" if ($debug);
print DEBUG_FILE @xml_data if ($debug);
chomp(@xml_data);
$i=0;
while ($i <= $#xml_data)
{
$xml_string.=$xml_data[$i];
$i++;
}
$xml= new XML::Simple;
$xml_data = $xml->XMLin($xml_string) or die "XML Data Error";
}
sub get_disk_status($)
{
my (@result_sub) = 0;
my @control_order_sub=0, $control_order_ref=0, $disk_number=0,$disk_number_mod=0, $backplane_count, $disk_count, $backplane_number,$i=0,$status,$all_disks;
$control_order_ref = $_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
## how many backplane in server
$backplane_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}};
##how many disks in each backplane
$disk_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}->[0]->{STATUS}};
if ($control_order_sub[0] eq "ALL")
{
$all_disks = $backplane_count * $disk_count ;
$i=0;
while($i < $all_disks)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $disk_number (@control_order_sub)
{
$backplane_number=int(($disk_number-1)/$disk_count);
$disk_number_mod = ($disk_number - 1) % $disk_count;
if ($backplane_number < $backplane_count)
{
$status = $xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{DRIVES}->{BACKPLANE}->[$backplane_number]->{STATUS}->[$disk_number_mod]->{VALUE};
print DEBUG_FILE $time . " ". "$localhost" . " Read Disk Status : " . "$status" ." \n" if $debug;
if ($status eq "Ok")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong disk order for $disk_number. Pelase check your disk number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_power_status($)
{
my @control_order_sub=0,$control_order_ref=0;
my $power_number=0, $power_count,$i=0,$status;
my @result_sub = 0;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
my $i = 0;
$power_count = @{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{POWER_SUPPLIES}->{SUPPLY}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $power_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $power_number (@control_order_sub)
{
if ($power_number <= $power_count)
{
$status=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{POWER_SUPPLIES}->{SUPPLY}->[$power_number-1]->{STATUS}->{VALUE};
print DEBUG_FILE $time ." ". "$localhost" . " Read Power Status : " . "$status" ." \n" if $debug;
if ($status eq "OK")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong power order for $power_number. Pelase check your power number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_fan_status($)
{
my $i = 0;
my @result_sub = 0,$control_order_ref=0, @control_order_sub=0;
my $fan_number=o, $fan_count=0,$i=0,$status;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
$fan_count=@{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{FANS}->{FAN}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $fan_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $fan_number (@control_order_sub)
{
if ($fan_number <= $fan_count)
{
$status=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{FANS}->{FAN}->[$fan_number-1]->{STATUS}->{VALUE};
print DEBUG_FILE $time ." ". "$localhost" . " Read Fan Status : " . "$status" ." \n" if $debug;
if ($status eq "OK")
{
$result_sub[$i] = 0;
}
else
{
$result_sub[$i] = 2;
}
$i++;
}
else
{
print "Wrong fan order for $fan_number. Pelase check your fan number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub get_temperature_status($)
{
my $temperature_number=o, $temperature_count,$i=0,$status,$current,$warning,$critical;
my @result_sub = 0, @control_order_sub = 0, $control_order_ref = 0,$i = 0;
$control_order_ref = @_[0];
@control_order_sub = @$control_order_ref;
open_https_connection();
send_xml_query();
close_https_connection();
$temperature_count=@{$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}};
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i < $temperature_count)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$i=0;
foreach $temperature_number (@control_order_sub)
{
if ($temperature_number <= $temperature_count)
{
$current=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CURRENTREADING}->{VALUE};
$warning=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CAUTION}->{VALUE};
$critical=$xml_data->{'GET_EMBEDDED_HEALTH_DATA'}->{TEMPERATURE}->{TEMP}->[$temperature_number-1]->{CRITICAL}->{VALUE};
print DEBUG_FILE $time ." " . "$localhost" . " Read Temperature Status : " ."Current: " . "$current" . " Warning: ". " $warning" . "Critical: " . "$critical". " \n" if $debug;
if ($current >= $critical )
{
$result_sub[$i] = 2;
}
elsif ( $current >= $warning )
{
$result_sub[$i] = 1;
}
else
{
$result_sub[$i] = 0;
}
$i++;
}
else
{
print "Wrong temperature sensor order for $temperature_number. Pelase check your temperature sensor number.\n";
print_help;
exit 1;
}
}
return(\@result_sub);
}
sub create_nagios_alarm($$$$)
{
my (@result_str) = 0;
my ($device_status_ref, $control_order_ref, $device_name_str, $server_name_str) = @_;
my (@device_status_sub) = @$device_status_ref;
my (@control_order_sub) = @$control_order_ref;
my ($n) = 0;
if ($control_order_sub[0] eq "ALL") #means all device will be check
{
$i=0;
while($i <= $#device_status_sub)
{
$control_order_sub[$i]=$i+1;
$i++;
}
}
$result_str="$server_name_str" . " sunucusundaki " ;
$EXIT_STATE = $STATE_OK;
chomp(@device_status_sub);
while ($n <= $#device_status_sub)
{
if ($device_status_sub[$n] == 1)
{
$result_str= "$result_str" . "$control_order_sub[$n]" . " ";
$EXIT_STATE=$STATE_WARNING;
}
if ($device_status_sub[$n] == 2)
{
$result_str= "$result_str" . "$control_order_sub[$n]" . " ";
$EXIT_STATE=$STATE_CRITICAL;
}
$n++;
}
if ($EXIT_STATE == $STATE_OK)
{
$result_str = "Everything is OK";
} else
{
$result_str = "$result_str" . "numarali " . "$device_name_str" . "(ler/lar)" . " uyari vermistir. Lutfen kontrol edin!";
}
return ($result_str);
}
###Main#####
my $socket;
my ($numArgs) = 0;
my $numArgs=$#ARGV ;
if_debug();
#print "Arguments: @ARGV \n";
if (($ARGV[0] eq "-h") || ($ARGV[0] eq "--help"))
{
print_help;
exit 2;
}
if ($numArgs < 5)
{
print "wrong argument number:". ($numArgs + 1) ." \n";
print_help;
exit 2 ;
}
$server_name = $ARGV[0];
$ilo_ip = $ARGV[1];
$username=$ARGV[2];
$password=$ARGV[3];
$device_name = $ARGV[4];
$n=0;
foreach $argnum (5 .. $numArgs)
{
$control_order[$n] = $ARGV[$argnum];
$n++;
}
if ($device_name eq "DISK")
{
$result = get_disk_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "POWER")
{
$result = get_power_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "FAN")
{
$result = get_fan_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
elsif ($device_name eq "TEMP_SENSOR")
{
$result = get_temperature_status(\@control_order);
@result_array=@$result;
$return=create_nagios_alarm(\@result_array, \@control_order, $device_name, $server_name);
print" $return \n";
exit $EXIT_STATE;
}
else
{
print "Wrong device name.\n";
print_help;
exit 2;
}
10 Mayıs 2012 Perşembe
IBM P Series İçin VIOS Kurulumu ve Konfigürasyonu
Merhaba;
Bu makalede IBM P Series
sistemler için sıfırdan bir VIOS’un nasıl kurulacağını ve nasıl konfigüre
edileceğini aktarmaya çalışacağım. İlk olarak VIOS’un ne olduğunuaçıklamakla
başlayalım. VIOS (Virtual IO Server) IBM
P Series üzerinde çalışacak işletim sistemleri için geliştirilmiş bir sanallaştırma
ortamıdır. Temelde AIX üzerinde yapılan bazı modifikasyonlar sonucu
oluşturulmuş bir modifiye işletim sistemidir. Bu işletim sistemi Pseries
donanımı üzerinde çalışan Hypervisor ile birlikte çalışarak donanım üzerinde
çalışan diğer işletim sistemleri içi var olan fiziksel kaynakların
sanallaştırılmasında kullanılmaktadır. VIOS üzerinde oluşturulabilecek
kaynaklar genelede IO işlemleri için kullanılabilecek network, HBA ve disk
kaynaklarıdır. RAM ve CPU gibi
kaynakların sanallaştırıması Hypervisor tarafından gerçekleştirilmektedir.
İlk
olarak VIOS kurulumuna hazırlık işlemlerini açıklamaya çalışacağım. Kurulum için P series Hypervisor üzerinde HMC
ile yeni bir LPAR oluşturulmalıdır.
Burada
“Create Logical Partition” seçildikten sonra “VIO Server” seçeneği seçilerek
kuruluma başlanmalıdır. Eğer AIX, Linux veya I5 olarak kuruluma başlanırsa
işlem ilerleyen safhalarda hata oluşturacaktır.
“VIO
Server” seçeneği seçildikten sonra standart LPAR oluşturma adımlarını takip
ediyoruz.
İlk adıma “Partition name”i
verdikten sonra Next diyoruz. İkinci adımda hazılanacak donanım konfigürasyonu
için kullanılacak “Profile name” i belirtiyoruz. Farklı profiller
kullanmayacaksanız “default“ olarak belirleyebilirsiniz.
Bir sonraki adımda kullanılacak
CPU kaynaklarının “Shared” mı yoksa “Dedicated” mı olacağını belirliyoruz.
Kurulum yaptığınız donanımdaki kaynaklara veya VIOS üzerinde oluşabilecek
yüklere göre size uygun seçimi yapabilirsiniz. Shared seçilmesi durumunda ve
eğer “micro partitioning” lisansına da sahipseniz sisteme kullanım için 0,1 0,5
gibi ondalıklı CPU değerleri verebilirsiniz. Ve bu modda eğer uncapped olarak
kurulum yaparsanız sistem CPU’ları ihtiyaca göre diğer LPAR’ların kullanımı
için de atayabilir. Biz “Shared” seçerek Next diyoruz.
Bir sonraki ekranda sistemin
kullanacağı processing unit ve Virtual CPU değerlerini belirtiyoruz. Burada
“Processing Unit” kısmı sistemde gerçekte kullanılacak CPU değerleri için
kullanılacaktır. Min değeri sistemin “Power on “ durumuna geçebilmesi için
sisteme atanması gereken en az CPU miktarını belirtir. Ayrıca DLPAR
özelliklerini kullanarak bu LPAR’dan en fazla “Min Processing Unit” sayısına kadar CPU azaltma işlmei yapılabilir. Max processin
Unit değeri de yine Minimum a benzer amaçla kullanılabilir. “Desired Processing
Unit” değeri ise sistemin normal çalışması durumunda kullanacağı CPU sayısını
belirler. Bizim konfigürasyonumuza göre
VIOS sunucumuz 0,2 CPU ile açılacaktır.
Virtual Processor alanı ise
verilen CPU’ların işletim sistemi tarafından nasıl algılanacağının
belirtilmesine yarar. İşletim sistemi tarafında 0,1 CPU değerinin bir anlamı
olmayacağından bu alanlara tam sayı girilmesi gerekmektedir. Burada girilen
değerler işletim sisteminin üzerinde kaç core görüleceğini belirler. Örneğin
“Desired virtual processor” alanına 2 girilmesi işletim sisteminin kendini 2
core üzerinde çalıştığını sanmasını sağlar. Lsdev –Cc prcessor komutu ile
kontrol ettiğimizde sistemde 2 core bulunduğunu görebiliriz. Oysa ki sistem 0,2
core üzerinde çalışmaktadır.
Bu
ekranda ise VIOS tarafından kullanılacak Memory miktarını belirtiyoruz. CPU
konfigürasyonunda olduğu gibi “Minumun Memory” alanı sistemden DLPAR
özelliklerini kullanarak alınabilecek memory miktarının sınırını belirtmek
“Maximum Memory” ise DLPAR ile bu sistem atanabilecek en yüksek memory
miktarını belirleyebiliyoruz. “Desired Memory” ile sistemin default profil ile
Power on edildiğinde kullanılacak memory miktarını belirliyoruz.
Bu
değerleri girdikten sonra tekrar Next butonuna tıklıyoruz.
Bu
ekranda ise sistem üzerindeki tüm kaynakları görebiliriz. Bu LPAR tarafından
kullanılacak kaynakları bu ekranda seçmemiz gerekmektedir. Öncelikle işletim
sisteminin kurulacağı disk kaynağını seçtikten sonra sistemin IO işlemleri için
kullanacağı HBA ve network kart
bleşenlerini seçiyoruz. Seçim yaptıktan sonra yukarıda görülen “Add as required
“ veya “Add as desired” butonlarını kullanarak LPAR konfigürasyonumuza
istediğimiz donanımları ekliyoruz. İki seçenek arasındaki fark eğer ilgili
device “required” olarak eklenirse sistem power on duruma geçmek için o
device’ın konfigüre edilmiş olan LPAR’a atanmış olması gerekir. Eğer bu device
başka bir LPAR’a atanmışsa istem power on sürecinde hata verir. “Desired”
olarak atanan device’lar ise isteğe bağlıdır. Sistem power on duruma geçerken
bu device’ların varlığını kontrol etmez. Device’lar olmadan da LPAR power on
edilebilir.
Bu
işlemin ardından tekar Next’e tıklıyoruz.
Gelen
ekranda kullanılacak “Virtual Resource” ları seçmemiz gerekiyor. Buradaki
yapılacak değişikliklere değineceğiz Şimdilik sadece ”Maximum Virtual Adapter”
değerini 100 olarak belirliyoruz ve tekrar Next’ tıklıyoruz.
Bu ekranda ise kullanılabilecek
“Logical Host Ethernet Adapters” lar görülmektedir. LHEA’lar sistem üzerindeki
onboard ethernat kartlarını temsil ederler. Bu ethernet kartları üzerindeki
chipset sayesinde VIOS kullanmadan da sanal kartlar oluşturarak birden fazla
LPAR’a atanabilir. Bizim sistemimizde kullanılmayacağı için Next’e tıklayarak
bu adamı geçebiliriz. Bundan sonraki tüm adımları Next diyerek geçtikten sonra
LPAR oluşturma adımlarımızı tamamlamış oluyoruz. Bir sonraki adım olan
kurulum’a geçelim.
VIOS kurulumu standart AIX
kurulumundan farklı olarak gerçekleştirilir. Kurulum işleminden çok restore
işlemi desek daha doğru olur Çünkü kurulum media’larında VIOS için oluşturulmuş
mksysb formatında backup dosyası mevcuttur. Eğer DVD’den kurulum yapacaksanız DVD
ile boot edip restore işlemlerini adım adım takip edebilirsiniz. Ancak bu
makale de daha fazla konuya değinmek adına biz bu kurulumu NIM üzerinden
gerçekleştirceğiz. NIM’e kısaca değinmek gerekirse özellikle AIX ve linux sistemler için gerekli olabilecek
kurulum işlemlerin network üzerinden gerçekleştirilebilmesi için oluşturulmuş
bir sunucu yazılımıdır. NIM (Network Installation Manager) üzerinde tanımlanan
kaynaklar vasıtasıyla istemciler gerekli kurulumları gerçekleştirebilirler. Bu
kaynakların bazıları ve en önemlilerini açıklamaya çalışalım.
- Mksysb: Sistemde mksysb formatında oluşturulan kaynaktır. Bu kaynak NIM tarafından istenilen istemci üzerinde sistem backup’ı alınarak oluşturulabilir veya alınan mksysb yedek dosyasını restore etmek için kullanılabilir.
- Lpp_source: Birden fazla paketin bir araya getirilmesile oluşturulmuş bundle kurulum paketleridir.
- Spot: lpp_source lar kullanılarak oluşturulan ve üzerinde boot dosyaları ve temel konutların yer aldığı pakettir. Bir sunucu spot paketi vasıtasıyla network üzerinden boot edilebilmesi için ihtiyaç duyduğu tüm boot verileri ve komutlara (/usr file system’i) ulaşabilir.
NIM konusuna kısaca değindikten
sonra gelelim NIM kurulum dosyasının nasıl NIM’e kaynak paket olarak
gösterielceğine. Öncelikle makelenin başında belirttiğimiz gibi VIOS kurulumu
bir kurulum işleminden çok restore işlemidir. Bu nedenle tanımlayacağıız ilk
kaynak mksysb’dir. Bunun için IBM sitesinden download ettiğimiz NIM kurulum
dosyalarını kullanmalıyız.
Download edilen NIM kurulum
dosyaları iso formatındadır. Özeliikle sistem odası farklı lokasyonda bulunan
kurumlar için CD ile uğraşmak büyük bir dert olacağı için biz bütün kaynak
oluşturma işlemlerini network üzerinden yapmayı deneyeceğiz. Bunun için ISO
dünyalarnı herhangi bir Virtual Drive programı vasıtasıyla bilgisyarınıza mount
edip içersindeki mksysb_image dosyalarını bilgisyarımıza kopyalamalıyız. Bu
dosyalar her iki DVD’de aynı isimde olduğu için DVD1 ve DVD2 adında iki klasör
oluşturup kopyalamaları bu iki klasöre yapmak faydalı olacaktır. Kopayalama
sonrasında tüm dosyaların toplam boyutu 3,5 GB civarında olacaktır.
Kopyalanan bu dosyaları MIN
server üzerinde uygun bir klasöre kopyaladıktan sonra aşağıdaki komut ile 3
dosyası tek dosya halinde birleştiriyoruz.
cat mksysb_image2 >> mksysb_image
cat ../DVD2/mksysb_image >>
./mksysb_image
mv mksysb_image mksysb_VIOS_2_2_1
Birlerştirme
işleminden sonra NIM server üzerinde aşağıdaki komut ile kaynakla ilgili
tanımlamaları gerçekleştiriyoruz.
mkdir
/export/mksysb/mksysb_VIOS_2_2_1
mv ./mksysb_VIOS_2_2_1
/export/mksysb/mksysb_VIOS_2_2_1/
nim –o define –t mksysb-a server=master –a
location=/export/mksysb/mksysb_VIOS_2_2_1/mksysb_VIOS_2_2_1 mksysb_VIOS_2_2_1
Bu
komutlardan sonra aşağıdaki komut ile mksysb kaynağını kontrol edebiliriz.
lsnim –t mksysb | grep VIOS
mksysb_VIOS_2_2_1 resources mksysb
Oluştrulan yeni kaynağı kontrol
ettikten sonra sıra geldi spot oluşturmaya. Spot yukarıda belirtildiği gibi
LPAR’ın network üzerinden boot işlemini gerçekleştirebilmesi için oluşturulan
başka bir paket türüdür. Eğer bir kaynak için spot oluşturulmamışsa o kaynak
için boot işlemleri gerçekleştirilemez. Oluşturduğumuz mksysb kaynağından SPOT
oluşturmak için aşağıdaki komutu NIM server üzerinde kullanabiliriz.
mkdir /export/spot/spot_VIOS_2_2_1
nim –o define –t spot –a
source=mksysb_VIOS_2_2_1 –a server=master –a location=/export/spot/ spot_VIOS_2_2_1
Burada gözden kaçırılmaması
gereken çok önemli bir nokta var. NIM
mimarisi gereği oluşturulacak tüm kaynakların işletim sistemi versiyonları, NIM
uygulamasının çalıştığı işletim sistemi versiyonundan ya düşük ya da aynı
olmalıdır. Bu makalede
kullanılan VIOS 2.2.1 versiyonu AIX 6.1.7.3 versiyonundan türetildiği için
işlem yapılan NIM server işletim sistemi versiyonunun en az AIX 6.1.7.3 olması gerekir. Aksi
takdirde spot oluşturma işlemi sırasında hata alırsınız.
Başarılı bir işlem sonrası ekran
çıktısı yukarıdaki gibi olmalıdır. Bundan sonra NIM üzerinden istemci
tanımlaması yapmamız gerekir. Bunun için farklılık olması açısından smitty
kullanabiliriz.
smitty nim -> Perform NIM
Administration Tasks -> Manage Machines -> Define A Machine
Burada nim için kullanacağımız hostname girildikten sonra Enter’a basınız.
Burada yukarıda görünen
konfigürasyon değişikliklerini yaptıktan sonra tanımlanan bu sunucuya kaynak
ataması yapılmalıdır. Bu işlem için yine smitty’den faydalanalım.
smitty nim -> Perform NIM
Software Installation and Maintenance Tasks -> Install and Update Software -> Install the Base Operating System on
Standalone Clients
Gelen ekrandan kurulum yapılacak
sunucuyu seçmemiz gerekir.
Daha sonra geeln ekrandan
yüklenecek kaynak türünü seçmeliyiz. Yine makalenin başında da belirtildiği
gibi yapacağımız işlem restore işlemi olacağından burada mksysb seçilmelidir.
Daha sonra gelen ekrandan önceden hazırladığımız mksysb kaynağı seçilmelidir.
İşlem
tamamlandıktan sonra hazırladığımız VIOS LPAR’ını activate edebiliriz. Bunun için HMC arayüzünden VIOS1 LPAR’ının
üzerine sağ tıklayıp Activate -> Profile seçeneği seçilmelidir.
Açılan
terminal penceresindeki yönergeleri izleyip aşağıdaki bilgi ekranı göründüğünde
1 tuşuna basılarak SMS (Sytem Managment Service) menüsüne girilmelidir.
Gelen ekrandan ise hangi network
kartının kurulum işlemleri sırasında kullanılacağı belirtilir.
Daha sonra TCP/IP haberleşmesinin
hangi protokole göre yapılacağı seçilmelidir.
Daha sonra kurulumlar sırasında
hangi uygulanın kullanılacağı seçilmeldir.
Daha sonra gelen ekrandan seçilen
network kartı için IP adresi ataması ve NIM server IP adresi ataması yapılmalıdır.
Yukarıdaki ekranda istenen tüm
bilgiler girildiktan sonra konfigürasyonun doğruluğunu test etmek için
aşağıdaki menüden “3. Ping Test” seçilmelidir.
Ping işlemi aşağıdaki gibi
başarılı olduktan sonra kuruluma geçilebilir.
Daha sonra “1. Select
Install/Boot Device “ seçeneği seçilmelidir.
Gelen ekrandan ise “6. Network”
seçeneği seçilmelidir.
Gelen ekrandan BOOTP protokolü
seçilmelidir.
Gelen ekrandna kullanılacak ve
daha önce IP ataması yapılan network kartı seçilmelidir.
Son olarak “2. Normal Mode Boot”
seçilip seçimler onaylandıktan sonra işlem başlatılabilir.
Yükeleme işlemleri tamamlndıktan
sonra gelen ekrandan 1 ve Enter ile aktif konsol seçilmelidir.
Daha sonra gelen ekrandan kurulum
dili seçilmelidir.
Gelen ekrandan “2. Change/Show
Installation Settings and Install” seçilerek kurulum konfigürasyonu kontrol
edilmelidir.
Konfigürasyonu kontrol ettikten
sonra 0 ile kurulum işlemlerine başlanabilir.
Kurulum
sonrasıda açılan konsole’dan padmin kullanıcısı ile giriş yapabilirsiniz.
Default şifre herzamanki gibi “123456” dır.
Sisteme
giriş yaptıktan sonra VIOS için hazırlanan özel şele düşeriz. Bu shell’de
çalıştırılabilecek komutların listesini “help” komutu ile görebiliriz.
Hiçbir
işlem yapmadan önce VIOS için lisans sözleşmesini kabul etmemiz gerekiyor.
Bunun için aşağıdaki komutu kullanabiliriz.
license
Komutu yazdıktan sonra
sözleşmenin kabul edildiğine dair bir mesaj alacaksınız.
Bundan sonra yapılacak ilk iş
yeni kuruduğumuz VIOS’umuza yönetim işlemleri için bir IP adresi vermek olacak.
Ancak kurulum işlemlerini NIM üzerinden yürttüyseniz bu işlem adımlarını
gerçekleştirmenize gerek yoktur. NIM kurulumdan sonra client için tanımlanan IP
adresini client’e otomatik olarak atar. Eğer siz CD ile kurulum yaptıysanız
aşağıdaki adımları uygulamalısınız.
Bu işlemde AIX’de olduğu gibi mktcpip
komutundan faydalanıyoruz ancak komut flag’leri AIX’de olduğundan biraz farklı.
Kullanılacak komut dizilimi aşağıdaki gibi olmalıdır.
mktcpip -hostname
vios1 -inetaddr {ipaddress} -interface en0 -start -gateway {gateway} -nsrvaddr
{dns server} -nsrvdomain {domain ismi}
Komutu kullandıktan sonra
VIOS’umuza artık ssh ile bağlanabiliriz. İlk olarak başka LPAR’ların kullanımı
için sanal bir NIC (Network Interface Card) oluşturalım. Sanal NIC oluşturmak
için gerçek bir NIC’e ihtiyacımız olacak. Bunun için sisteme tanımladığımız diğer
network kartı olan ent1’i kullanabiliriz. Eğer tek bir NIC kartımız varsa aynı
karttan hem VIOS TCP/IP bağlantılarını gerçekleştirip hemde bu kartı üzerinde
sanal NIC’ler oluşturup diğer LPAR’ların kullanımına açabiliyoruz. Ancak burada
kullandığınız network toplojileri fazlasıyla önem kazanıyor. Eğer suncunuzun
bağlı bulunduğu switch üzerinde VLAN yapısı kullanıyorsanız network
konfigürasyonuna çok dikkat etmelisiniz. Tek network kartı olan
konfigürasyonlarda VIOS üzerinden vlan tanımlamaları yapmanız gerekecektir.
Kendi konfigürasyonumuzda fazladan bir NIC kartımız olduğu için biz bu konuya
girmeden devam ediyoruz.
Sanal NIC ataması basitçe
fiziksel bir NIC kartını sanal olarak atanan başka bir kart ile
ilişkilendirilerek LPAR’ların kullanımın sunma şeklinde özetlenebilir. Diğer
LPAR’ların kullanabileceği paylaşımlı bir sanal kaynağı aşağıdaki şekilde
oluşturabiliriz.
Öncelikle VIOS’umuzun donanım
profiline sanal kaynak eklemeliyiz. Manage Profile menüsünden aşağıdaki ekrana
ulaşabiliriz.
Burada var olan “Adapter ID”leri
not ettikten sonra Actions menüsünden “Create
Virtual Adapter” -> “Ethernet Adapter” menüsünden yeni bir virtual adapter
oluşturabiliriz.
Gelen ekranda aşağıdaki
düzenlemeleri yapmalıyız. Bütün konfigürasyonda bağlı bulunduğu switch üzerinde
VLAN kullanıldığını varsayıyoruz.
Burada doldurulan alanları
açıklamaya çalışalım. “Virtual Adapter ID” alanında bir önceki ekranda not
ettiğimiz Adapter ID’lerden farklı bir ID belirtmeliyiz. Burada “Maximum
Virtual Adapter” alanında belirtilen değerden daha büyük bir değer giremeyiz.
İkinci olarak Vswitch’i açıklayalım. LPAR’lar arasında haberleşme bağlı
bulundukları fiziksel switch üzerinden gerçekleşmektedir. Ancak VIOS kullanılan
ortamlarda LPAR’lar arası network trafiğinin fiziksel değil mantıksal olarak
oluşturulmuş sanal bir switch üzerinden dolaşması sağlanabilir. Böylelikle
LPAR’ların haberleşmesi performanslı olarak
gerçekleştirilebilir. Burada birden falza ”Virtual Switch”’ler
oluşturarak VLAN mantığına benzer bir yapı mantıksal olarak kurulabilir.
“VSwitch” alanı oluşturulan bu “Virtual Ethernet Adpater” ile haberleşmenin
hangi sanal switch üzerinden yapılacağını belirler. Bizim konfigürasyonumuzda
tek bir switch olduğundan bunu seçiyoruz.
“VLAN ID” alanı ise bu “Virtual
Ethernet” kartından çıkan trafikte default olarak hangi VLAN Tag’inin kullanılacağı
belirtilir. Tavsiyem bu alana switch üzerinden kullanılmayan bir Tag ID
girmeniz. Daha sonra Optional Settings’den IEE 802.1q aktif edilerek switch üzerindeki ve LPAR’lar tarafından
kullanılabilecek bütün VLAN tag’leri bu alana eklenmelidir.
LPAR’ların dış dünyaya erişimleri
bu “Virtual Adapter” üzerinden gerçekleşeceği için “Access external network”
seçeneği’de aktif edilmelidir. Bu seçenek aktif edilmezse shared ethernet
adapter oluştururken “The command's
response was not recognized. This may or
may not indicate a problem.” gibi bir hata alabilirsiniz.
Bütün bu konfügrasyon
tamamlandıktan sonra OK’e tıklayarak Virtual Ethernet Adapter’imizi donanım
profilimize ekliyoruz. Ancak profilede yapılan değişikliklerin LPAR tarafından
kullanılabilmesi için sunucu “Shutdown” edilip tekrar “PowerOn” edilmeidir.
Eğer istenirse bu değişikliler DLPAR özellikleri kullanarak kapatıp açmaya
gerek duymadan da yapılabilir ancak sunucu yeniden başlatıldığında yapılan tüm
değişiklikler kaybolur.
DLPAR kullanımı sonrasında
AIX’deki cfgmgr komutuna benzer şekilde “cfgdev” komutu kullanılabilir. Bu
komut cfgmgr ile aynı işleve sahiptir ve donanımda yapılan değişiklikleri
otomatik olarak tarayan bazı fonksiyonları çalıştırır.
Sistem yeniden açıldıktan sonra
lsdev ile var olan ve yeni eklenen donanım konfigürasyonunu kontrol edebiliriz.
“lsdev –type adapter” ile adapter aygıtları “lsdev –virtual” ile virtual aygıtları listeleyebiliriz. Burada yeni ekledeiğimiz “Virtual Ethernet Interface”i ent2 olarak görebiliyoruz.
Bir sonraki adımda sıra oluşturduğumuz
bu “Vitual Ethernet İnterface”den “Shared Ethernet Adapter”oluşturmaya geldi. LPAR’ların eğer sanal kaynaklar üzerinden
dış dünya ile haberleşmesi gerekiyorsa Shared Ethernet Adapter mutlaka
oluşturulmalıdır. Bu işlem sonunda fiziksel kart ile sanal kartlar
arasındaki ilişki oluşturulur. Shared Adapter oluşturma komutu aşağıdaki
gibidir.
mkvdev –sea ent1 –vadapter ent2 –default
ent2 –defaultid 99
Buarada ent1 bizim VIOS’umuzda
kullandığımız ikinci fiziksel network kartı, ent2 ise profile üzerinden
oluşturduğumuz Virtual Ethernet Adapter’dir. Komut sonucu aşağıdaki ekran
karşımıza çıkacaktır.
Buarada ent3 olarak yeni Virtual
Ethernet Adapter’imizi görebiliyoruz. Bununla beraber lsmap –net –all komutuyla
oluşturduğumuz yeni ayıtın detaylı bilgilerine ulaşabiliriz.
Şimdi erhangi bir LPAR’a
oluşturduğumuz bu Shared Ethernet Adapter yardımı ile sanal bir network kartı ekleme
işlemine geldi. Bunun için işlem yapılacak LPAR’ın harware profile’ını
düzenliyoruz. Burada Virtual Adpaters kısından “Create Ethenet Adapter”
diyoruz.
Daha sonra gelen ekrandan VLAN ID
kısmına kullanılacak IP için hazırlanan fiziksel switch’de konfigüre edilmiş VLAN
Tag ID sini giriyoruz.
İsterseniz bu ekranda “View
Virtual Network”e tıklayarak oluşturduğumuz VLAN ve SEA’lari
gözlemleyebilirsiniz.
Burada görüldüğü gibi 7 nolu VLAN
için atanan fiziksel adapter VIOS1 üzerindeki ent1’dir.
İşlem tamamlandıktan sonra
donanımı atadığımız LPAR’a bağlanıp lsdev komutu ile yeni eklediğimiz ethernet
kartnı görüntüleyebiliriz.
Daha sonra mktcpip komutu ile
konfigürasyon sırasında belirlediğimiz VLAN’a uygun bir ip adresi vererek
ethernet kartını kullanmaya başlayabiliriz.
İkinci olarak da LPAR’ların kullanımı için VIOS
üzerinden bir disk ataması yapalım. VIOS üzerinden disk ataması Logical Volume,
Physical Volume ve File olmak üzere üç şekilde gerçekleştirilir. İlk yöntemde
atanacak disk VIOS LVM’i tarafından yönetilir. Burada oluşturulan bir Logical
Volume sanal olarak LPAR’ın kullanımına sunulabilir. LPAR bu Logical Volume’ü
bir raw disk olarak algılar ve kullanır. İkinci yöntem ise direk atamadır. Bu
yöntemde VIOS üzerindeki disk araya LVM konulmaksızın raw olarak LPAR’ın
kullanımına sunulabilir. Biz ikinci yöntem üzerinden gideceğiz. Burada disk’in
SAN üzerinden VIOS1’e atandığını varsayıyor ve devam ediyoruz.
Sanal
disk ataması yapabilmek için VIOS profilimize sanal SCSI Adapter’ları eklememiz
gereklidir. Bu işlem için VIOS LPAR profilinde Add Virtual Resoource kısmından
aşağıdaki şekilde SCSI Adapter ekleyebiliriz.
Gelen
ekran aşağıdaki gibidir.
Bu
ekranda “Virtual SCSI Adapter” kısmında kullanılan ID’yi not etmemiz gerekir.
Bununla beraber oluşturulan Virtual SCSI Adapter’in hangi LPAR tarafındna kullanılacağı da
belirlenebilir. Bizim konfigürasyonumuzda bütün LPAR’lar bu kartı kullanabilir
şeklinde düzenlenecektir. Bu değişiklikler profil üzerinde gerçekleştirildiği
için VIOS LPAR’ının kapatılıp tekrar açılması gerekir. Eğer DLPAR özelliklerini
kullanarak değişiklikler gerçekleştirildiyse VIOS üzerinde cfgdev komutunun
çalıştırılması yeterlidir. İşlemler tamamlandıktan sonra lsdev –virtual komutu
ile yeni oluştuturulan vscsi ayıtlarını görüntüleyebiliriz.
Burada
dikkat çekecek nokta her sanal disk ataması yapılacak LPAR için farklı Virtual
SCSI adapter kullanılmasının daha mantıklı olacağıdır. Çünkü aynı VSCSI device
üzerinden map edilen diskler o scsi device’ın map edildiği tüm LPAR’lar
tarafından aynı anda kullanılabilir. Eğer yukarıdaki gibi birden fazla VSCSI
aygıtınız varsa hangi aygıtın hangi ID’yi kullandığını görmeniz gerekebilir. Bu
durum genelde aynı VSCSI device’ı kullanacak LPAR’a atama yaparken karşımıza
çıkar. Bunun için lsdev –vpd komutundan faydalanlır. Komut AIX’deki prtconf
benzeri şekilde çalışır ve sistemdeki donanım hakkında bize detaylı bilgi
verir. Komut çıktı incelenerek vhost’a ait bilgilere göz atıldığında aşağıdaki
sonuçla karşılaşılır.
Kırmızı
kutu içine alınan bilgiler o VSCSI device’a ait Adapter ID bilgisidir. Buna göre
örneğin bir LPAR’a vhost0 üzerinden disk
ataması yapılacaksa ilerde değineceğimiz gibi LPAR’a Virtual SCSI device
eklerken Adpater ID’ye 3 değerinin girilmesi gerekecektir.
VIOS üzeride
kullnılabilecek disklerin listesini görünülemek için lsdev –type disk komutunu
kullanabiliriz.
Burada “MPIO IBM 2145 FC Disk” satırından da anlaşılacağı üzere kullanacağımız hdisk2 IBM SVC üzerinden oluşturulup VIOS1’e map edilmiştir.
Ayrıca lspv
–free komutu ile herhangi bir LPAR’atanmamış disklerin listesini ve boyutlarını
görüntüleyebiliriz.
Yeni aygıt tanımlamaları tamamlandıktan ve gerekli kontroller gerçekleştirildikten sonra fiziksel disk ile VSCSI Adapter’i eşleştriebiliriz. Bunun için aşağıdaki komut kullanılabilir.
mkvdev –vdev hdisk2 –vadapter vhost0
Komut sonrası ekran çıktısı aşağıdaki gibi olacaktır.
Bu
işlemden sonra oluşturdğumuz sanal diskin LPAR tarafından kullanılabilmesi için
profile üzerinde yeni bir virtual device ekleme adımına gelip aşağıdaki
değişiklikleri yapıyoruz.
Burada
görüldüğü gibi “Server Adapter ID” alanına bir üst adımda not ettiğimiz VSCSI
Adapter ID’yi yazıyoruz. İşlem tamamlandıktan sonra sunucuyu kapatıp açarak
aşağıdaki gibi kontrollerimizi gerçekleştirebiliriz.
Şu
aşamaya kadar anlatılanlarla temel bir AIX kurulumu için gerekli kaynakların
tamamını (CPU ve RAM hariç) VIOS üzerinden atamanın nasıl yapılacağını
açıklamış olduk. Bundan sonra bir diğer sanallaştılırılmış kaynak olan Virtual
Fibre Channel Adapter’in nasıl oluşturulacağını açıklamaya çalışacağım. İlk
olarak bir önceki aşamalarda yaptığımıza benzer şekilde sanal bir FC Adapter
kaynağı oluşturmalıyız. Bunu yine VIOS üzerinden profile management üzerinden
aşağıdaki şekilde gerçekleştirebiliriz.
Diğer
sanal kaynaklardan farklı olarak Virtual FC Adapter oluştururken bu kaynağın
hangi LPAR için kullanılacağını da belirtmemiz gerekir
Daha
sonra LPAR üzerinden yine sanal kaynak ekleyerek aşağıdaki konfigürasyonu
gerçekleştiriyoruz. Burada “Vritual Channel adapter Adapter” alanına bir üst
adımda belirlediğimiz “Client adapter ID” alanında belirlediğimiz değeri
kullanıyoruz.
Sonra VIOS
üzerinden aşağdaki komutu kullanarak fiziksel FC ile Virtaul FC arasındaki
ilişkiyi kurabiliriz.
vfcmap -vadapter vfchost0 -fcp fcs0
Burada göz önünde bulundurulması gereken iki nokta.
İlki kullandığınız fiziksel FC Adapter’ın NPIV’yi desteklemesi gerekmektedir.
IBM Pserises sunucularda varolan 8Gbs FC
adapter’lerin çoğu NPIV’yi desteklemektedir. Eğer sunucunuzda 4Gbs FC kart
bulunuyorsa FC sanallaştırma özelliklerini kullanamazsanız. lsnports komutu ile
sisteminizde var olan ve NPIV uyumlu kartları görüntüleyebilirsiniz. İkinci
olarak da kullandığınız SAN Switch’in NPIV desteklemesi ve sunucunun bağlı
bulunduğu SAN portundan NPIV özelliğinin aktif edilmesi gerekmektedir. Nasıl
yapılacağı konusu bu makalenin konusunu çok genişleteceği için burada
değinmiyorum. Ancak konuyla ilgili aşağıdaki ekran görüntüsü nasıl yapılacağını
büyük oranda açıklayıcı olabilir.
İşlem tamamlandıktan sonra NPIV özelliği ile SAN
Switch üzerindeki bir portdan birden fazla WWN numarası register olabilir.
Sizde bu WWN’leri kullanarak gerekli zone’lamarı yapıp LPAR’ınıza storage
üzerinden volume’leri direk map edebilirsiniz.
Makale çok uzun olduğu için burada kesiyorum. Tek bir
makale üzerinde LPAR oluşturma NIM konfigüre etme VIOS kurulumu ve temel VIOS
konfigürasyonuna değinmiş olduk. Gerçekten faydalı bir makale olduğunu
düşünüyorum. Bununla beraber redundancy
gibi konulara bu makalede malesef değinemedik. Onuda bir sonraki
makalede anlatırız. Şimdilik hoşçakalın.
Etiketler:
AIX,
AIX kurulumu,
DLPAR,
Hypervisor,
IBM,
Linux,
LPAR,
mksysb,
Network,
NIM,
P series,
Sanallaştırma,
Shared Ethernet Adapter,
UNIX,
VIOS,
Virtual,
Virtual Ethernet,
Virtual IO Server,
Yedeklilik,
Yük paylaşımı
Kaydol:
Kayıtlar (Atom)