#!/usr/bin/perl


# Copyright (C) 2002-2010 NEC Corporation
# All Rights Reserved.


sub readFile;
sub wrireFile;
sub lockFile;
sub getSectoreInfo2;

$LOGFILE = "/var/log/kdi.log";
$PATH = "/opt/nec/roma/etc";

system("echo kdi start > $LOGFILE");
system("date >> $LOGFILE");


$WBMC_LOCK_R_B = 1;	# 読み込みロック(ブロックモード)
$WBMC_LOCK_W_B = 2;	# 書き込みロック(ブロックモード)
$WBMC_LOCK_R_NB = 5;	# 読み込みロック(ノンブロックモード)
$WBMC_LOCK_W_NB = 6;	# 書き込みロック(ノンブロックモード)

require "/opt/nec/wbmc/lib/wbmc.pl";

#InterSecVM/CS判定フラグ取得
$N_code            = &get_N_code();
$InterSecVM_flag = "";
#CS400g以降の機種
$CS400g_flag = "";
if($N_code =~ /^UL\d+/){
        $InterSecVM_flag = "yes";
}elsif($N_code eq "N8100-1641" || $N_code eq "N8100-1703" || $N_code eq "NP8100-1808YPAY"){
        $CS400g_flag = "yes";
}

#Hyper-V対応 2011.06.09 higashi
($err,$dev,$ifcfg)=get_devifcfg();

#
# 名前
#	lockFile - 指定されたファイルにロックをかける
# 形式
#	lockFile($lockfile, $mode, *LOCK)
# 引数
#	$lockfile ロックファイル名(/var/opt/nec/wbmc/lock/の下に作成される)
#	$mode ロックのモード(下記の何れか)
#		$WBMC_LOCK_R_B  読み込みロック(ブロックモード)
#		$WBMC_LOCK_W_B  書き込みロック(ブロックモード)
#		$WBMC_LOCK_R_NB 読み込みロック(ノンブロックモード)
#		$WBMC_LOCK_W_NB 書き込みロック(ノンブロックモード)
#	*LOCK ファイルハンドラ
#		ロックを解除するにはこのファイルハンドラをcloseする
# 戻り値
#	成功のとき1
#	失敗のとき0
#
sub lockFile
{
    local($lockfile, $mode, *LOCK) = @_;

    my($ret);
    my($lockdir);

    $ret = 0;
    $lockdir = "$WBMC_VAR_DIR/lock";

    if ($lockfile eq "") {
	goto done;
    }

    # ロックファイル用のディレクトリを(無ければ)作成する
    if (! -d $lockdir) {
	if (!mkdir($lockdir, 0755)) {
		$body.="No.1";
	    goto done;
	}
    }

    # ロックファイルをオープンする
    if (!open(LOCK, "> $lockdir/$lockfile")) {
		$body.="No.2";
	goto done;
    }

    # ロックをかける
    if (!flock(LOCK, $mode)) {
		$body.="No.3";
	close(LOCK);
	goto done;
    }

    $ret = 1;

done:
    return($ret);
}

#
# 名前
#	readFile - ファイルを読んで内容を返す(ロック制御付き)
# 形式
#	readFile($filename, $lockfile, *line)
# 引数
#	$filename 読み込むファイル名
#	$lockfile ロックファイル名(/var/opt/nec/wbmc/lock/の下に作成される)
#	*line ファイルの内容を受け取る配列
# 戻り値
#	成功のとき1
#	失敗のとき0
#
sub readFile
{
    local($filename, $lockfile, *line) = @_;

    local(*LOCK);
    local(*IN);
    my($ret);
    my($lockfileflag);

    $ret = 0;
    $lockfileflag = 0;

    if ($filename eq "") {
	goto done;
    }

    if ($lockfile ne "") {
	# 読み込みロック(ブロックモード)をかける
	if (!&lockFile($lockfile, $WBMC_LOCK_R_B, *LOCK)) {
	    goto done;
	}
	$lockfileflag = 1;
    }

    # ファイルをオープンして読み込む
    if (!open(IN, $filename)) {
	goto done;
    }
    @line = <IN>;
    close(IN);

    $ret = 1;

done:
    if ($lockfileflag != 0) {
	close(LOCK);
    }

    return($ret);
}

#
# 名前
#	writeFile - 指定された内容をファイルに書き込む(ロック制御付き)
# 形式
#	writeFile($filename, $lockfile, @line)
# 引数
#	$filename 書き込むファイル名
#	$lockfile ロックファイル名(/var/opt/nec/wbmc/lock/の下に作成される)
#	@line ファイルに書き込む内容の配列
# 戻り値
#	成功のとき1
#	失敗のとき0
#
sub writeFile
{
    local($filename, $lockfile, @line) = @_;

    local(*LOCK);
    local(*OUT);
    my($ret);
    my($lockfileflag);
    my($tmpfile);
    my($filemode);

    $ret = 0;
    $lockfileflag = 0;
    $tmpfile = "$filename.$$";

    if ($filename eq "") {
	goto done;
    }

    if ($lockfile ne "") {
	# 書き込みロック(ブロックモード)をかける
	if (!&lockFile($lockfile, $WBMC_LOCK_W_B, *LOCK)) {
	    goto done;
	}
	$lockfileflag = 1;
    }

    # 作業ファイルをオープンして書き込む
    if (!open(OUT, "> $tmpfile")) {
	goto done;
    }
    if (!print(OUT @line)) {
	close(OUT);
	goto done;
    }
    close(OUT);

    # ファイルのモードを得る
    if (-e $filename) {
	$filemode = (stat($filename))[2];
    } else {
	$filemode = 0644;
    }

    # 正規のファイルにリネームする
    if (!rename($tmpfile, $filename)) {
	goto done;
    }

    # ファイルのモードを設定する
    chmod($filemode & 07777, $filename);

    $ret = 1;

done:
    if ($lockfileflag != 0) {
	close(LOCK);
    }

    if (-f $tmpfile) {
	unlink($tmpfile);
    }

    return($ret);
}

###################################
# sub routine. get sectore info.  #
###################################

#
#cf.http://linux.or.jp/JF/JFdocs/Large-Disk-HOWTO.txt 
#

sub getSectoreInfo{
  my($j,$k);

  $pt = 454;
  $start_save = 0;
  $num_save = 0;

#
# get master boot record.
#


  system("echo [$mydevice[$i] info.] >> $LOGFILE");

  system("dd if=$mydevice[$i] of=$PATH/tmp_mbr bs=512 count=1 > /dev/null");

  system("od -x $PATH/tmp_mbr >> $LOGFILE");

  if( !open(FH,"< $PATH/tmp_mbr")){
    system("echo read err >> $LOGFILE");
  }

#
# get partion table info
#   and calculate start and length.
#

  for($j=0; $j<4; $j++){
# 4 primary parttions.

   system(" echo $j th partition info.  >>$LOGFILE");

    for($k=0; $k<4; $k++){
#   0:start low 2byte,  1:upper 2byte,
#   2:length low 2byte, 3:upper 2byte.

      if(!seek(FH,$pt,0)){
        system("echo seek err >> $LOGFILE");
      }

      if(!read(FH,$buf,2)){
        system("echo read err >> $LOGFILE");
      }

      $data = unpack("v",$buf);

      if($k==0){
        $start_l = $data;
        system("echo  low  : $start_l >> $LOGFILE");
        $pt += 2;

      }elsif($k==1){
        $start = $data;
        system("echo  high : $start >> $LOGFILE");
        $start *= 65536;
        $start += $start_l;
        system("echo 'start -> $start' >>$LOGFILE");
        $pt += 2;

      }elsif($k==2){
        $num_l = $data;
        system("echo low  : $num_l >>$LOGFILE");
        $pt += 2;

      }elsif($k==3){

        $num = $data;
        system("echo high : $num >> $LOGFILE");
        $num *= 65536;
        $num += $num_l;
        system("echo 'num -> $num' >> $LOGFILE");
        $pt += 10;
      }
    }

    if($start_save < $start){
      $start_save = $start;
      $num_save = $num;
#      print "start is $start th sectore\n";
#      print "sectore num is $num\n";
    }



    $end_save = $start_save + $num_save -1;
    system("echo start point is $start_save >> $LOGFILE");
    system("echo sectore num is $num_save >> $LOGFILE");
    system("echo end point is $end_save >> $LOGFILE");
  }
  close (FH);
  system("rm -f $PATH/tmp_mbr");

#
# get toatal sectore num.
#
  $num_total = `blockdev --getsize $mydevice[$i]`;
  system("echo 'blockdev --getsize is $num_total' >> $LOGFILE");


#
# calculate cache area start and length.
#

  $reserve = 10;

  if($i==0){
    $cache_area_start = $start_save + $num_save + $reserve;
  }else{
    $cache_area_start = 8;
  }

  $cache_area_length = $num_total-$cache_area_start-$reserve;

  if($cache_area_length <= 0){
    system("echo fatal error - length is under 0");
  }

#   $mydevice[++$i] = $cache_area_start;
#   $mydevice[++$i] = $cache_area_length;

#
# join tag string, disc id, devicename, start sector, sector size. 
#
  $tmp_list[0] = "kernel_disk_information";
  $tmp_list[1] = $i;
  $tmp_list[2] = $mydevice[$i];
  $tmp_list[3] = $cache_area_start;
  $tmp_list[4] = $cache_area_length;
  $tmp_list[5] = "\n";


  $list[$i] = join ' ', @tmp_list;
  system("echo '$list[$i]' >> $LOGFILE");

  $i++;



}

###################################
# sub routine. get sectore info.  #
###################################

#
#
#

sub getSectoreInfo2{

#
#read device name of cache area form fstab
#

  my($k);

  $reserve = 10;

  $roma_cache_dev = "";
  $cache_area_start = 0;
  $cache_area_end = 0;
  $cache_area_length = 0;

#-1st HDD : Linux system & Cahe Area-----------------------------------------------
  if($i==0){

    if(open(IN,"/opt/nec/roma/etc/mount.roma_cache")){
      @line=<IN>;
      close (IN);

      for($k = 0; $k <= $#line; $k++){
        $_ = $line[$k];
        for($j = 0; $j < split(); $j++){
#         print $_[$j],"\n";
          if( "/mnt/sysimage/roma_cache" eq $_[$j] ){
            $roma_cache_partition=$_[0];
            $roma_cache_dev =$_[0];
            chop($roma_cache_dev);
          }
        }
      }
      # 1st HDD (sda限定)にキャッシュ領域が存在しない場合
      if( $roma_cache_dev !~ /$dev/){
        system("echo 1st HDD unknown >> $LOGFILE");
        $roma_cache_partition = "unknown";
        $roma_cache_dev = "/dev/".$dev; 
      }
      system("echo Cache area partition name is $roma_cache_partition >> $LOGFILE");
      system("echo Cache area device name is $roma_cache_dev >> $LOGFILE");
    }


#
#read cache area sector info. from fdisk -l -u
#
  if($roma_cache_dev) {
  open(IN,"/sbin/fdisk -l -u $roma_cache_dev |");
  @line=<IN>;
  close(IN);

  if ($#line <= 3){
      chop($roma_cache_dev);
      open(IN,"/sbin/fdisk -l -u $roma_cache_dev |");
      @line=<IN>;
      close(IN);
  }

  if ($#line <=3 ){
    system("echo fdisk -l err >> $LOGFILE");

  } else {
    if("unknown" eq $roma_cache_partition){
      # 1st HDD にキャッシュ領域が存在しない場合は1st HDDの最後の空き領域を
      # 使用する。
      system("echo 1st HDD unknown conf >> $LOGFILE");

      $num_total = `blockdev --getsize $roma_cache_dev`;
      $_ = $line[$#line]; #最終行
      s/'//;
      chop($_);
      system("echo '$_' >> $LOGFILE");
      s/\*/ /;
      for($j = 0; $j <= split(); $j++){
#        print $_[$j],"\n";

         $cache_area_start = @_[2] + $reserve ;
         $cache_area_length = $num_total - $cache_area_start - $reserve ;
         $cache_area_end = $cache_area_start + $cache_area_length ;
      }
    } else {
      $num_total = `blockdev --getsize $roma_cache_dev`;
      for($k = 0; $k <= $#line; $k++){
        $_ = $line[$k];
        s/'//;
        chop($_);
        system("echo '$_' >> $LOGFILE");
        s/\*/ /;
        for($j = 0; $j <= split(); $j++){
#          print $_[$j],"\n";

          if($roma_cache_partition eq @_[$j] ){
            $cache_area_start = @_[1] + $reserve ;

            if($InterSecVM_flag eq "yes") {
              #InterSecVMなら、1st HDDの末端まで使用する。
              $cache_area_length = $num_total - $cache_area_start - $reserve ;
              $cache_area_end = $cache_area_start + $cache_area_length ;
            } else {
              #InterSecなら、1st HDDの最後のパーティションを使用する。
              $cache_area_end = @_[2] - $reserve ;
              $cache_area_length = $cache_area_end - $cache_area_start;
            }
          }
        }
      }
    }
    system("echo 1st cache area device  start is $cache_area_start >> $LOGFILE");
    system("echo 1st cache area device end is $cache_area_end >> $LOGFILE");
    system("echo 1st cache area device length is $cache_area_length >> $LOGFILE");
  }
  }
}
#-2nd HDD : roma log & Cahe Area-----------------------------------------------

  if($i==1 && !$ary){

    if(open(IN,"/opt/nec/roma/etc/mount.roma_cache")){
      @line=<IN>;
      close (IN);

      for($k = 0; $k <= $#line; $k++){
        $_ = $line[$k];
        for($j = 0; $j < split(); $j++){
#         print $_[$j],"\n";
          if( "/mnt/sysimage/var/log/roma" eq $_[$j] ){
            $roma_log_partition=$_[0];
            $roma_cache_dev =$_[0];
            chop($roma_cache_dev);
          }
        }
      }
      system("echo roma log area partition name is $roma_log_partition >> $LOGFILE");
      system("echo roma log and cache area device name is $roma_cache_dev >> $LOGFILE");
    }


#
#read cache area sector info. from fdisk -l -u
#

  if($roma_cache_dev) {
  open(IN,"/sbin/fdisk -l -u $roma_cache_dev |");
  @line=<IN>;
  close(IN);

  if ($#line <= 3){
      chop($roma_cache_dev);
      open(IN,"/sbin/fdisk -l -u $roma_cache_dev |");
      @line=<IN>;
      close(IN);
  }

  if ($#line <=3 ){
    system("echo fdisk -l err >> $LOGFILE");

  } else {
    for($k = 0; $k <= $#line; $k++){
      $_ = $line[$k];
      s/'//;
      chop($_);
      system("echo '$_' >> $LOGFILE");
      s/\*/ /;
      for($j = 0; $j <= split(); $j++){
#        print $_[$j],"\n";
        # roma_log領域からディスクの終端までをキャッシュ領域として使用
        if($roma_log_partition eq @_[$j] ){
          $num_total = `blockdev --getsize $roma_cache_dev`;
          $cache_area_start = @_[2] + $reserve ;
          $cache_area_length = $num_total - $cache_area_start - $reserve;
          $cache_area_end = $cache_area_start + $cache_area_length ;
        }
      }
    }
    system("echo 2nd cache area device  start is $cache_area_start >> $LOGFILE");
    system("echo 2nd cache area device end is $cache_area_end >> $LOGFILE");
    system("echo 2nd cache area device end is $cache_area_length >> $LOGFILE");
  }
  }
}

#-3rd henceforth HDD : Cahe Area Only -----------------------------------------------

  if(($i>1)||($i==1 && $ary)){

    $cache_area_start = 8;
#   system("echo blockdev '$mydevice[$i]' '$i'");

    $num_total = `/sbin/blockdev --getsize $mydevice[$i]`;
#   system("echo '/sbin/blockdev --getsize is $num_total' >> $LOGFILE");

    $cache_area_length = $num_total-$cache_area_start-$reserve;

  }

  if($cache_area_length <= 0){
    system("echo fatal error - length is under  >> $LOGFILE");
  }
  else {
#
# join tag string, disc id, devicename, start sector, sector size. 
#

  $tmp_list[0] = "kernel_disk_information";
  $tmp_list[1] = $i;
  $tmp_list[2] = $mydevice[$i];
  $tmp_list[3] = $cache_area_start;
  $tmp_list[4] = $cache_area_length;
  $tmp_list[5] = "\n";

  $list[$i] = join ' ', @tmp_list;


#
# Exclude helix area.
#
  $devcount=0;
  $mydevice2 = $tmp_list[2];

  system("echo mydevice2 is '$mydevice2'  >> $LOGFILE");
  if(open(IN,"/sbin/fdisk -l '$mydevice2' |")){
    @line=<IN>; close (IN);
    if($ary){
      $mydevice2 = $mydevice2 . 'p';
    }
  system("echo mydevice21 is '$mydevice2'  >> $LOGFILE");
    for($k = 0; $k <= $#line; $k++){
      for($m=1; $m<10; $m++,chop $mydevice2){
        $mydevice2 = $mydevice2 . $m;
        if($line[$k] =~ /$mydevice2/){
          $devcount++;
        }
        system("echo mydevice is '$mydevice2'  >> $LOGFILE");
      }
    }
  }

system("echo devcount is '$devcount'  >> $LOGFILE");
  }

# 1st hdd - no operation.
  if($i==0){
  }

# 2nd hdd - /var/log/roma, cahe area & helix option(???).
  if($i==1){
    # 5GB over check
    if(( $ary) && ($devcount > 0)||
       ($cache_area_length < 10485760))
    {
      system("echo 2nd hdd not use  >> $LOGFILE");
      $list[$i] =~ s/kernel/#kernel/;
      $disknum[1]--;

    }
  }

# after 3rd hdd - cache area & helix option.
  if($i>1){
    # 5GB over check
    if(($devcount > 0)||
       ($cache_area_length < 10485760))
    {
      system("echo 3rd hdd not use  >> $LOGFILE");
      $list[$i] =~ s/kernel/#kernel/;
      $disknum[1]--;
  }
  }

  system("echo '$list[$i]' >> $LOGFILE");
  $i++;

}


#========================================================
# Main Routine
#========================================================

$m = 0; 
#@l = 0;
@disknum = ("kernel_disknum","0","\n");
$ary=0;
$sas_ary=0;

@DEVTABLE = ( 
"/dev/sda","/dev/sdb","/dev/sdc","/dev/sdd",
"/dev/sde","/dev/sdf","/dev/sdg","/dev/sdh",
"/dev/sdi","/dev/sdj","/dev/sdk","/dev/sdl",
"/dev/sdm","/dev/sdn","/dev/sdo","/dev/sdp",
"/dev/sdq","/dev/sdr","/dev/sds","/dev/sdt",
"/dev/sdu","/dev/sdv","/dev/sdw","/dev/sdx",
"/dev/sdy","/dev/sdz",
"/dev/hda","/dev/hdb","/dev/hdc","/dev/hdd",
"/dev/hde","/dev/hdf","/dev/hdg","/dev/hdh",
"/dev/hdi","/dev/hdj","/dev/hdk","/dev/hdl",
"/dev/hdm","/dev/hdn","/dev/hdo","/dev/hdp",
"/dev/hdq","/dev/hdr","/dev/hds","/dev/hdt",
"/dev/hdu","/dev/hdv","/dev/hdw","/dev/hdx",
"/dev/hdy","/dev/hdz","/dev/hd","/dev/hd",);

@ARRAYTABLE = (
"/dev/rd/c0d0","/dev/rd/c0d1", "/dev/rd/c0d2", 
"/dev/rd/c0d3","/dev/rd/c0d4", "/dev/rd/c0d5",
"/dev/rd/c0d6","/dev/rd/c0d7", "/dev/rd/c0d8", 
"/dev/rd/c0d9","/dev/rd/c1d0", "/dev/rd/c1d1", 
"/dev/rd/c1d2","/dev/rd/c1d3", "/dev/rd/c1d4", 
"/dev/rd/c1d5","/dev/rd/c1d6", "/dev/rd/c1d7",
"/dev/rd/c1d8","/dev/rd/c1d9");



#
# find device.
#

if(open(IN,"/sbin/fdisk -l |")){
  @line=<IN>;

  for($i = 0; $i <= $#line; $i++){
    $_ = $line[$i];
    if(s/:/ /){
      for($j = 0; $j <= split(); $j++){
        loop00:for($k = 0; $k < $#DEVTABLE; $k++){
          if( @DEVTABLE[$k] eq @_[$j] ){
            $mydevice[$l] = @_[$j];
            $l += 1;
            last loop00;
          }
        }
      }
    }
  }
  # sort device
  @mydevice_tmp = sort @mydevice;
  @mydevice = @mydevice_tmp;
} else {
  system("echo fdisk -l err >> $LOGFILE");
}

close(IN);

if($l == 0){
  outloop:for($h = 0; $h <= $#ARRAYTABLE; $h++){
    if(open(IN,"/sbin/fdisk -l $ARRAYTABLE[$h] |")){
      @line=<IN>;

      for($i = 0; $i <= $#line; $i++){
        $_ = $line[$i];
        if(s/:/ /){
          for($j = 0; $j <= split(); $j++){
 
             if( @ARRAYTABLE[$h] eq @_[$j] ){
                $mydevice[$l] = @_[$j];
                $l += 1;
                $ary++;
                last:outloop; 
              }
          }
        }
      }
    } else {
      system("echo fdisk -l (array) err >> $LOGFILE");
    }
  }
  close(IN);
}




if( $l == 0 ){
  system("echo no device >> $LOGFILE");

}else{


  $disknum[1] = $l;



#  for($i=0; $i < $l; $i++){
#    system("echo '===', '$mydevice[$i]', '$l'");
#  }

  for($i=0; $i < $l;){
#    system("echo blockdev 0 '$mydevice[$i]' '$i'");
    getSectoreInfo2(@mydevice,$i);
  }


}

#
# find SAS-RAID device.
#
if (`/sbin/lsmod | grep megaraid_sas`){
	$sas_ary=1;
	system("echo megaraid_sas >> $LOGFILE");
}

if(($sas_ary) || ($InterSecVM_flag eq "yes")){
	$disknum[1] = 1;
}

#
# read roma.conf
#

if (!&readFile("$PATH/roma.conf","roma.conf.lock",*line2)){
  system("echo readFile err > $LOGFILE");
}

#
# serch, delete, write kernel_disklnum.
#
$found_num = 0;

for ($cnt = 0; $cnt <= $#line2; $cnt++){
  if($line2[$cnt] =~ "\s*kernel_disknum" ){
     if($found_num == 0){
       $tmp[0] = join " ", @disknum; 
       splice @line2, $cnt,1,@tmp;
     }
     $found_num++;
  }
}

if($found_num == 0){
  $tmp[0] = join " ", @disknum; 
  $line2[$#line2 + 1] = $tmp[0]; 
#  $line2[0] = $tmp[0]; 
}




#
# search kernel_disk_information tag.
#
$m=0;
for ($cnt = 0; $cnt <= $#line2; $cnt++){
  if($line2[$cnt] =~ "\s*kernel_disk_information" ){
    $cnt_save[$m] = $cnt;
    $m++;
  }
}

#for ($cnt = 0; $cnt < $m; $cnt++){
#  print "find ", $cnt_save[$cnt], " ",$line2[$cnt_save[$cnt]];
#}


#
# write sectore info. and dummy string.
#

$tmp[0] = "#tmp_for_kernel_disk_information\n";

for ($cnt = 0; $cnt < $m ; $cnt++){
  if($cnt == $m - 1){
#   print "delete ",$cnt_save[$cnt]," ", $line2[$cnt_save[$cnt]], "\n";
#   print "add start", @list, "add end","\n";
   splice @line2, $cnt_save[$cnt],1,@list;

  }else{

#   print "delete ",$cnt_save[$cnt]," ", $line2[$cnt_save[$cnt]], "\n";
   splice @line2, $cnt_save[$cnt], 1,@tmp;

  }
}

if($m == 0){
  splice @line2,$#line2+2 , 1,@list;
}




#
# delete dummy string.
#

$num_line = $#line2;

for ($cnt = 0; $cnt <= $#line2; $cnt++){
  for($cnt2=0; $cnt2< $num_line; $cnt2++){
    if($line2[$cnt2] =~ "#tmp_for_kernel_disk_information" ){
      splice @line2, $cnt2, 1;
      $num_line -= 1;
      redo;
    }
  }
}

#CS400g以降の場合に行う
$phisicaldevicenumber = 0;
$raidlevel = 0;
$cachemode = 0;
if($CS400g_flag eq "yes"){
	# roma.confの値を一旦削除
	for($i=0;$i < @line2;$i++){
		if($line2[$i] =~ /^s*kernel_raid_capacity\s+/){
			splice @line2, $i, 1;
			$i--;
		}elsif($line2[$i] =~ /^s*kernel_raid_physical_device_number\s+/){
			splice @line2, $i, 1;
			$i--;
		}elsif($line2[$i] =~ /^s*kernel_raid_level\s+/){
			splice @line2, $i, 1;
			$i--;
		}
	}
	$capacity = 0;
	if(open(IN,"raidcmd property -tg=ld -c=1 -l=1 |")){
		@raidcmd = <IN>;
		close(IN);
		for($i=0;$i < @raidcmd;$i++){
			if($raidcmd[$i] =~ /\s*Capacity\s*:\s*([,\d]+)(.+)/){
				$capacity = $1;
				$byte = $2;
				$capacity =~ s/,//;
				if($byte =~ /TB/){
					$capacity = $capacity * 1024 * 1024 * 1024 * 1024;
				}elsif($byte =~ /GB/){
					$capacity = $capacity * 1024 * 1024 * 1024;
				}
			}elsif($raidcmd[$i] =~ /\s*Physical\s*Device\s*Number\s*:\s*(.+)/){
				$phisicaldevicenumber_line = $1;
				@phisicaldisknum = split(',',$phisicaldevicenumber_line);
				$phisicaldevicenumber = @phisicaldisknum;
			}elsif($raidcmd[$i] =~ /\s*RAID\s*Level\s*:\s*RAID\s*(.+)/){
				$raidlevel = $1;
			}elsif($raidcmd[$i] =~ /\s*Cache\s*Mode\s*\(Current\)\s*:\s*(.+)/){
				$cachemode = $1;
				$cachemode =~ s/^\s+//g;
				$cachemode =~ s/\s+$//g;
				if($cachemode =~ /Write\s*Back/i){
					$cachemode = 1;
				}elsif($cachemode =~ /Write\s*Through/i){
					$cachemode = 0;
				}
			}
		}
	}

	#物理ディスクの見え方が変わった場合
	if($phisicaldevicenumber eq "0"){
		$raidcmd=();
		if(open(IN,"raidcmd property -tg=da -c=1 |")){
			@raidcmd = <IN>;
			close(IN);
			for($i=0;$i < @raidcmd;$i++){
				if($raidcmd[$i] =~ /\s*Physical\s*Device\s*(\d+)\s*:/){
					$phisicaldevicenumber++;
				}
			}
		}
	}

	if(($capacity ne 0) && ($phisicaldevicenumber ne 0) && (($raidlevel eq 1) || ($raidlevel eq 5) || ($raidlevel eq 6))){
		push(@line2,"kernel_raid_capacity $capacity\n");
		push(@line2,"kernel_raid_physical_device_number $phisicaldevicenumber\n");
		push(@line2,"kernel_raid_level $raidlevel\n");
	}
}

#
# write roma.conf
#

writeFile("$PATH/roma.conf","roma.conf.lock",@line2);

#
#2002.11.18 Nines Honda edit
#Set kernel_objnum,kernel_objsize,kernel_metasize,kernel_metanum
#Set kernel_queuenr,kernel_iobuflen_shift,main_alert_dqmax

#for debug 1:on 0:off
$debug = 0;

#for test 1:on 0:off
$test = 0;

#SmartFilter status
$smartfilter_state = "off";

#Interscan status
$interscan_state = "off";

#Intersafe status
$intersafe_state = "off";

#IntersafeICAP status
$intersafeICAP_state = "off";

#streaming status
$streaming_state = "off";

#kernel_objsize
$kernel_objsize =0;

#kernel_objnum
$kernel_objnum =0;

#kernel_metanum
$kernel_metanum =0;

#kernel_metasize
$kernel_metasize =0;

#total memory
$memtotal = 0;

#device number
$dev_num = $l;

print "device number: $dev_num\n" if $debug;

#queuenr
$kernel_queuenr = 10;

#iobuflen_shift
$kernel_iobuflen_shift = 0;

#main_alert_dqmax
$main_alert_dqmax = 400;

#main_dqmax_change_flg
$main_dqmax_change_flg = 0;

#Interscan file Path
$InterscanFilePath = "/etc/opt/nec/wbmc/interscan.conf";
$InterscanFilePath_lock = "interscan.conf";

#Intersafe file Path
$IntersafeFilePath = "/etc/opt/nec/wbmc/InterSafe.conf";
$IntersafeFilePath_lock = "InterSafe.conf";

#IntersafeICAP file Path
$IntersafeICAPFilePath = "/etc/opt/nec/wbmc/InterSafeICAP.conf";
$IntersafeICAPFilePath_lock = "InterSafeICAP.conf";


#meminfo file Path
$meminfo_path = "/proc/meminfo";
$meminfo_path_lock = "meminfo";

#read roma.conf
@file_roma = ();
if (!&readFile("$PATH/roma.conf","roma.conf.lock",*file_roma)){
	system("echo read error roma.conf >> $LOGFILE");
}


#read interscan.conf
@file_interscan = ();
if (!&readFile("$InterscanFilePath","$InterscanFilePath_lock",*file_interscan)){
	system("echo read error interscan.conf >> $LOGFILE");
}


#read intersafe.conf
@file_intersafe = ();
if (!&readFile("$IntersafeFilePath","$IntersafeFilePath_lock",*file_intersafe)){
	system("echo read error intersafe.conf >> $LOGFILE");
}


#read intersafeICAP.conf
@file_intersafeICAP = ();
if (!&readFile("$IntersafeICAPFilePath","$IntersafeICAPFilePath_lock",*file_intersafeICAP)){
	system("echo read error intersafeICAP.conf >> $LOGFILE");
}


#
#get SmartFilter status
#
for($i=0;$i<@file_roma;$i++){
	if($file_roma[$i] =~ /^url_smartfilterstate\s+(\S+)/i){
		if($1 =~ /on/i){
			$smartfilter_state = "on";
		}
		else{
			$smartfilter_state = "off";
		}
		last;
	}
}

system("echo smartfilter status: $smartfilter_state >> $LOGFILE");
print "smartfilter status: $smartfilter_state\n" if $debug ;

#
#get Interscan status
#
for($i=0;$i<@file_interscan;$i++){
	if($file_interscan[$i] =~ /^Interscan_state\s+(\S+)/i){
		if($1 =~ /high/i || $1 =~ /low/i){
			$interscan_state = "on";
		}
		else{
			$interscan_state = "off";
		}
		last;
	}
}

system("echo interscan status: $interscan_state >> $LOGFILE");
print "interscan status: $interscan_state\n" if $debug;

#
#get Intersafe status
#
for($i=0;$i<@file_intersafe;$i++){
	if($file_intersafe[$i] =~ /^InterSafe_state\s+(\S+)/i){
		if($1 =~ /high/i || $1 =~ /low/i){
			$intersafe_state = "on";
		}
		else{
			$intersafe_state = "off";
		}
		last;
	}
}

system("echo intersafe status: $intersafe_state >> $LOGFILE");
print "intersafe status: $intersafe_state\n" if $debug;

#
#get IntersafeICAP status
#
for($i=0;$i<@file_intersafeICAP;$i++){
	if($file_intersafeICAP[$i] =~ /^InterSafeICAP_state\s+(\S+)/i){
		if($1 =~ /on/i){
			$intersafeICAP_state = "on";
		}
		else{
			$intersafeICAP_state = "off";
		}
		last;
	}
}

system("echo intersafeICAP status: $intersafeICAP_state >> $LOGFILE");
print "intersafeICAP status: $intersafeICAP_state\n" if $debug;

#
#get streaming status
#
if(-f "/etc/rc.d/init.d/rmproxy" || -f "/etc/rc.d/init.d/rmserver"){
	$streaming_state = "on";
}
else{
	$streaming_state = "off";
}

system("echo streaming status $streaming_state  >> $LOGFILE");
print "streaming status: $streaming_state\n" if $debug;

#
#get meminfo(total memory)
#
@meminfo = ();
$tmp="";
if(!&readFile("$meminfo_path","$meminfo_path_lock",*meminfo)){
	system("echo read error meminfo >> $LOGFILE");
}

for($i=0;$i<@meminfo;$i++){
	$tmp = &removeSpace($meminfo[$i]);
	@tmp = split(/\s+/,$meminfo[$i]);

	if($tmp[0] =~ /^MemTotal/i){
		$memtotal = $tmp[1]*1024;
		last;
	}
}
#
# If total memory is larger than 4.7,
# set the value as 4.7GB.
# --for CS300g,500g
#
if($memtotal >= 4.7*1024*1024*1024){
        system("echo memtotal larger than 4.7GB,so set as 4.7GB.");
        $memtotal = 4.7*1024*1024*1024;
}
$memtotal -= 20*1024*1024;
$memtotal = 256*1024*1024 if $test;
print "memtotal: $memtotal\n" if $debug;

#
#Set kernel_metasize
#

$kernel_metasize = 44;
print "set kernel_metasize: $kernel_metasize\n" if $debug;


#
#Set kernel_objsize
#

$kernel_objsize = 4096;
print "set kernel_objsize: $kernel_objsize\n" if $debug;


#
#Set kernel_metanum,kernel_objnum
#

#var init

$scale = 0; #倍率
$disk_management_mem_size = 0; #ディスク管理用メモリサイズ
$request_mlock_size = 0;#要求mlockサイズ
$usr_use_mem_size = 0;#ユーザ使用メモリ
$real_mlock_size = 0;#実mlockサイズ
$max_mlock_size = 0;#最大mlockサイズ
$referent_mlock_size = 0;#対象mlockサイズ
$final_mlock_size = 0;#最終mlockサイズ
$total_disk_size = 0;#総ディスクサイズ
$management_disk_size = 0;#管理ディスクサイズ

#get scale value
#

$scale = $memtotal / (256*1024*1024);
print "get scale: $scale\n" if $debug;


#get disk management memory size
#

#get total cache area
@tmp = ();
$total_cache_area = 0;

for($i=0;$i<@list;$i++){
	@tmp = split(/\s+/,$list[$i]);
	$total_cache_area += $tmp[4];
}
$total_cache_area=20*1024*1024*1024 if $test;
print "get total_cache_area: $total_cache_area\n" if $debug;

$disk_management_mem_size = int($total_cache_area / 8);
print "get disk_management_mem_size: $disk_management_mem_size\n" if $debug;


#get request mlock size
#

$request_mlock_size = 106*1024*1024*$scale;
print "get request_mlock_size: $request_mlock_size\n" if $debug;


#get user use memory size
#

$usr_use_mem_size = 189*1024*1024;

if($interscan_state eq "on"){
	$usr_use_mem_size += 106*1024*1024;
}
elsif($intersafe_state eq "on"){
	$usr_use_mem_size += 384*1024*1024;
}
elsif($intersafeICAP_state eq "on"){
	$usr_use_mem_size += 512*1024*1024;
}
elsif($smartfilter_state eq "on"){
	$usr_use_mem_size += 98*1024*1024;
}

if($streaming_state eq "on"){
	$usr_use_mem_size += 768*1024*1024;
}
print "get usr_use_mem_size: $usr_use_mem_size\n" if $debug;


#get real mlock size
#

$real_mlock_size = $memtotal - $usr_use_mem_size;
print "get real_mlock_size: $real_mlock_size\n" if $debug;

#get max_mlock_size
#

$max_mlock_size = int($memtotal/2);
print "get max_mlock_size: $max_mlock_size\n" if $debug;


#get referent mlock size
#
if($real_mlock_size > $max_mlock_size){
	$referent_mlock_size = $max_mlock_size;
}
else{
	$referent_mlock_size = $real_mlock_size;
}
print "get referent_mlock_size: $referent_mlock_size\n" if $debug;


#set kernel_metanum,kernel_objnum
#
if($referent_mlock_size <= ($request_mlock_size + $disk_management_mem_size)){
	$final_mlock_size = $request_mlock_size;
	$kernel_metanum = int(($final_mlock_size * 0.6) / 44);
	$kernel_objnum = int(($final_mlock_size * 0.4) / 4096);
}
else{
	$final_mlock_size = $referent_mlock_size - $disk_management_mem_size;
	$kernel_metanum = int(($final_mlock_size * 0.6) / 44);
	$kernel_objnum = int(($final_mlock_size * 0.4) / 4096);
}

print "get final_mlock_size: $final_mlock_size\n" if $debug;
print "set kernel_objnum: $kernel_objnum\n" if $debug;
print "set kernel_metanum: $kernel_metanum\n" if $debug;


#
#Set kernel_metanum,kernel_objnum
#

#get total disk size
#
$total_disk_size = $total_cache_area * 512;
print "get total_disk_size: $total_disk_size\n" if $debug;


#get management disk size
#
$management_disk_size = $kernel_metanum * 13 * 1024;
print "get management_disk_size: $management_disk_size\n" if $debug;


#if management disk size > total disk size , recalculate kernel_metanum and kernel_objnum
#

if($management_disk_size > $total_disk_size){
	$kernel_metanum = int($total_disk_size / (13*1024));
	$kernel_objnum = int(($final_mlock_size - ($kernel_metanum * 44)) / 4096);

	print "set kernel_metanum: $kernel_metanum\n" if $debug;
	print "set kernel_objnum: $kernel_objnum\n" if $debug;
}

# gシリーズ対応 2009.06 nakayama
if(($kernel_objnum * 4096) >= (2*1024*1024*1024)){
	$kernel_objnum = ((2*1024*1024*1024) / 4096) - 1;
}

#
#get kernel_queuenr,kernel_iobuflen_shift,main_alert_dqmax
#
for($i=0;$i<@file_roma;$i++){
	if($file_roma[$i] =~ /^kernel_queuenr\s*([0-9]*)/i){
		$kernel_queuenr = $1;
		print "get kernel_queuenr: $kernel_queuenr\n" if $debug;
	}
	if($file_roma[$i] =~ /^kernel_iobuflen_shift\s*([0-9]*)/i){
		$kernel_iobuflen_shift =$1;
		print "get kernel_iobuflen_shift: $kernel_iobuflen_shift\n" if $debug;
	}
	if($file_roma[$i] =~ /^main_alert_dqmax\s*([0-9]*)/i){
		$main_alert_dqmax =$1;
		print "get main_alert_dqmax: $main_alert_dqmax\n" if $debug;
	}
	if($file_roma[$i] =~ /^main_dqmax_change_flg\s*([0-9]*)/i){
		$main_dqmax_change_flg =$1;
		print "get main_dqmax_change_flg: $main_dqmax_change_flg\n" if $debug;
	}
}

#
#Set kernel_queuenr,kernel_iobuflen_shift,main_alert_dqmax
#
if($main_dqmax_change_flg eq "0"){
    if($InterSecVM_flag eq ""){
            if($sas_ary){
                    $kernel_iobuflen_shift = 4;
                    $kernel_queuenr = 10;
                    if($CS400g_flag eq "yes"){
                            if($cachemod eq "0"){
                                    $main_alert_dqmax = 800;
                            }else{
                                    $main_alert_dqmax = 1600;
                            }
                            if($raidlevel eq "1"){
                                    $main_alert_dqmax *= 1;
                            }elsif(($raidlevel eq "5") && ($phisicaldevicenumber ne "0")){
                                    $main_alert_dqmax *= ($phisicaldevicenumber - 1);
                            }elsif(($raidlevel eq "6") && ($phisicaldevicenumber ne "0")){
                                    $main_alert_dqmax *= ($phisicaldevicenumber - 2);
                            }
                    }else{
                            $main_alert_dqmax = 8000;
                    }
            }else{
                    $kernel_iobuflen_shift = 2;
                    $kernel_queuenr = 10;
                    $main_alert_dqmax = 1600;
            }
    }else{
            $kernel_iobuflen_shift = 2;
            $kernel_queuenr = 10;
            $main_alert_dqmax = 400;
    }
}

#
#Write kernelinfomation in the roma.conf
#
$metasizeOK=0;
$metanumOK=0;
$objsizeOK=0;
$objnumOK=0;
$queuenrOK=0;
$iobuflen_shiftOK=0;

#set kernelinfomation
for($i=0;$i<@file_roma;$i++){
	$tmp = &removeSpace($file_roma[$i]);
	if($tmp =~/^kernel_metasize/i){
		$file_roma[$i] = "kernel_metasize $kernel_metasize\n";
		$metasizeOK=1;
		next;
	}

	if($tmp =~/^kernel_metanum/i){
		$file_roma[$i] = "kernel_metanum $kernel_metanum\n";
		$metanumOK=1;
		next;
	}

	if($tmp =~/^kernel_objsize/i){
		$file_roma[$i] = "kernel_objsize $kernel_objsize\n";
		$objsizeOK=1;
		next;
	}

	if($tmp =~/^kernel_objnum/i){
		$file_roma[$i] = "kernel_objnum $kernel_objnum\n";
		$objnumOK=1;
		next;
	}
	
	if($tmp =~/^kernel_queuenr/i){
		$file_roma[$i] = "kernel_queuenr $kernel_queuenr\n";
		$queuenrOK=1;
		next;	
	}
        
        if($tmp =~/^kernel_iobuflen_shift/i){
		$file_roma[$i] = "kernel_iobuflen_shift $kernel_iobuflen_shift\n";
		$iobuflen_shiftOK=1;
                next;
        }
        
        if($tmp =~/^main_alert_dqmax/i){
		$file_roma[$i] = "main_alert_dqmax			$main_alert_dqmax\n";
                next;
        }
}

#Add kernelinfomation if these is not

$tun_flag=0;
@file_roma_head = ();
@file_roma_tail = ();

for($i=0;$i<@file_roma;$i++){
	if($tun_flag == 0){
		push(@file_roma_head,$file_roma[$i]);
	} else {
		push(@file_roma_tail,$file_roma[$i]);
	}
	$tmp = &removeSpace($file_roma[$i]);
	if($tmp =~/^#[-]*\s+Tuning Options/i){
		$tun_flag=1;
	}
}

if($tun_flag == 1){
	if(!$metasizeOK){
                push(@file_roma_head,"kernel_metasize $kernel_metasize\n");
        }
        if(!$metanumOK){
                push(@file_roma_head,"kernel_metanum $kernel_metanum\n");
        }
        if(!$objsizeOK){
                push(@file_roma_head,"kernel_objsize $kernel_objsize\n");
        }
        if(!$objnumOK){
                push(@file_roma_head,"kernel_objnum $kernel_objnum\n");
        }
        if(!$queuenrOK){
                push(@file_roma_head,"kernel_queuenr $kernel_queuenr\n");
        }
        if(!$iobuflen_shiftOK){
                push(@file_roma_head,"kernel_iobuflen_shift $kernel_iobuflen_shift\n");
        }
	
	if(!$metasizeOK || !$metanumOK || !$objsizeOK || !$objnumOK || !$queuenrOK || !$iobuflen_shiftOK){
		unshift(@file_roma_tail,"\n");
	}
	@file_roma = ();
	@file_roma = (@file_roma_head,@file_roma_tail);
} else {
	if(!$metasizeOK){
		push(@file_roma,"kernel_metasize $kernel_metasize\n");
	}
	if(!$metanumOK){
		push(@file_roma,"kernel_metanum $kernel_metanum\n");
	}
	if(!$objsizeOK){
		push(@file_roma,"kernel_objsize $kernel_objsize\n");
	}
	if(!$objnumOK){
		push(@file_roma,"kernel_objnum $kernel_objnum\n");
	}
	if(!$queuenrOK){
		push(@file_roma,"kernel_queuenr $kernel_queuenr\n");
	}
	if(!$iobuflen_shiftOK){
		push(@file_roma,"kernel_iobuflen_shift $kernel_iobuflen_shift\n");
	}
}

system("echo kernel_metasize $kernel_metasize  >> $LOGFILE");
system("echo kernel_metanum $kernel_metanum  >> $LOGFILE");
system("echo kernel_objsize $kernel_objsize  >> $LOGFILE");
system("echo kernel_objnum $kernel_objnum  >> $LOGFILE");
system("echo kernel_queuenr $kernel_queuenr  >> $LOGFILE");
system("echo kernel_iobuflen_shift $kernel_iobuflen_shift  >> $LOGFILE");
system("echo main_alert_dqmax $main_alert_dqmax  >> $LOGFILE");

#write roma.conf
if(!writeFile("$PATH/roma.conf","roma.conf.lock",@file_roma)){
        system("echo write  error roma.conf > $LOGFILE");
}

system("echo kdi end >> $LOGFILE");

sub removeSpace{
	local($wk) = @_;

	$wk =~ s/^\s+//g;
	$wk =~ s/\s+$//g;
	return $wk;
}

