Get raid information from a Fujitsu RX200S8/Rx300S8 via BMC

With the S8 generation of Fujtitus RX300/200 servers, which use the iRMC S4 ,Fujitsu implementent the ability to poll SNMP-data from the BMC (iRMC). To enable the ability to poll data the BMC has to be flashed with an up to date Firmware version and SNMP-polling has to be enableed in the iRMC-web-GUI. I’ve tested it with 7.69F from Dec. 2014 .
The first shippings of the rx300/200 servers came with an older firmeware version which did not implment the needed Fujitsuu MIBs to query HW-status (see http://manuals.ts.fujitsu.com/file/11470/irmc-s4-ug-en.pdf Page: 18 for details about the supported MIBs).
The problem is, that there is no possibility to query the status of the Raid controller and its disks via SNMP (or I haven’t found it till now) but it’s displayed on the iRMC web-GUI. So I wrote a script which extracts the useful informations (controller status, disk status + details and logical drive status) from the web-interface.

Atm. it’s just an alpha release but I’ll modify the script to be used by Zabbix for an auto discovery and push all the data into Zabbix:

Source:

[pastacode lang=”php” message=”web-iRMCS RAID-query” highlight=”” provider=”manual”]

#!/usr/bin/php
<?php
/****************************************
################################################################
#   DESCRIPTION: Script to query RAID-Informations from the Fujitsu iRMC S4 webinterface.
#   COPYRIGHT ©: 2015 by fawcs, GPL freeware
#        AUTHOR: fawcs, weixeflo@fawcs.info
#       LICENSE: GPL freeware
# CREATION DATE: 2015-Mar-19
################################################################
*****************************************/
$username="admin";
$password="admin";
$host="127.0.0.1";

$siteIDs=array('controller'=>87,'disks'=>88,'logicalVolumes'=>89);
//get Raid-Controller-Data
//$returnController=getWebsiteContent($host."/".$siteIDs['controller'],$username,$password,true);
$returnDisks=getWebsiteContent($host."/".$siteIDs['disks'],$username,$password,true);
//$returnVolumes=getWebsiteContent($host."/".$siteIDs['logicalVolumes'],$username,$password,true);
//$id['controller']=parseWebSiteToIDs($returnController);
$id['disks']=parseWebSiteToIDs($returnDisks);
//$id['logicalVolumes']=parseWebSiteToIDs($returnVolumes);
//print_r($id);


$ctrl=$id['disks'][0]['id'][1];
foreach($id['disks'][0]['data'] AS $disk)
{
	//print_r($disk);
	$diskWebContent=getWebsiteContent($host."/pdrive?ctrl=".$ctrl."&pd=".$disk['detailID'][1],$username,$password,true);
	//print_r($diskWebContent);
	$diskTableArray=parseWebSiteToIDs($diskWebContent);
	print_r($diskTableArray);	
}
/**/

/**
retrieves an html-site
	
	@return: String -> whole HTML site
**/
function getWebsiteContent($url,$username,$password,$measuretime=false)
{
	if($measuretime===true) 
	{
		$timer=microtime(true);
	}
	$process = curl_init($url);
	curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);  
	curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: application/xml'));
	curl_setopt($process, CURLOPT_HEADER, 1);
	curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
	curl_setopt($process, CURLOPT_TIMEOUT, 30);
	curl_setopt($process, CURLOPT_POST, 1);
	//curl_setopt($process, CURLOPT_POSTFIELDS, $payloadName);
	curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
	$return = curl_exec($process);
	curl_close($process);
	if($measuretime===true) 
	{
		echo "Content for ".$url." retrieved in ".round(microtime(true)-$timer,3)."s".chr(10);
	}
	return $return;
}

/**
retrieves the table-content of an IRMC Site / parses the listed sites for interesting data
possible sites are:
	http://$host/87 -> Controller Infos
	http://$host/88 -> Physical Disks
	http://$host/89 -> Logical Drives
	
	@return -> 	array which contains the ID of the controller, disks, LVs
				the table headings
				the table data
**/


function parseWebSiteToIDs($return)
{
	$ret=array(); 
	$cutFrom=strpos($return,"<!-- Menu end-->");
	$cutTo=strpos($return,'<div id="bottom">');
	$return=str_replace('</td>','</td>'.chr(10),substr($return,$cutFrom,$cutTo-$cutFrom));
	$return=str_replace('</th>','</th>'.chr(10),$return);
	$Loop=$return;
	
	//echo $table;
	$count=0;
	//go through all tatles which are found in the passed web-content-string & extract the tables 
	while(strpos($Loop,'<table')!==false)
	{
		
		//$table[]=substr($return, strpos($return,"<table"),strpos($return,"</table>")-strpos($return,"<table>"));
		$Loop=substr($Loop, strpos($Loop,'<table'),strlen($Loop)-strpos($Loop,'<table'));
		//get the table id
		$id=substr($Loop,strpos($Loop,"summary=\"")+9,strpos($Loop,"\">")-(strpos($Loop,"summary=\"")+9));
		$ret[$count]['id']=explode("_",$id);
		$Loop=substr($Loop, strpos($Loop,'<tr'),strlen($Loop)-strpos($Loop,'<tr'));
		//save just the html-table to the var & add ***###*** as a delimitter after every tablerow
		$currentTable=str_replace("</tr>","</tr>***###***",substr($Loop,0,strpos($Loop,"</table>")));
		$currentTable=substr($currentTable,0,strlen($currentTable)-9);
		//explode all table rows by the added delimiter
		$rows=explode("***###***",$currentTable);
		$count2=0;
		//iterate through the table rows and extract useful information
		foreach($rows AS $row)
		{
			unset($detailID);
			//check if submit button for details is listed in the table - if yes - get the submit-value for correct id -> is appended to the URL when querying the details page
			if(strpos($row,'<input class="submit" type="submit" value="Details"')!==false)
			{
				$detailID=trim(substr($row,strpos($row,'<input class="submit" type="submit" value="Details"')+strlen('<input class="submit" type="submit" value="Details"'),strpos(strtolower($row),'onclick=')-(strpos($row,'<input class="submit" type="submit" value="Details"')+strlen('<input class="submit" type="submit" value="Details"'))));
				//eg: extracted name="pd_10" from row
				$detailID=str_replace("\"","",$detailID);
				$detailID=explode("=",$detailID);
				$detailID=$detailID[1];
			}
			$row=trim(strip_tags($row));
			//if $count==0 -> first table row which stores only the headings/descriptions -> are saved in a seperate node in the array
			if($count2==0)
			{
				$ret[$count]["description"]=explode(chr(10),$row);
			} else {
			//all the other rows contain data -> also store the in the array
				$rowArray=explode(chr(10),$row);
				$ret[$count]["data"][]=$rowArray;
				if(isset($detailID))
				{
					$ret[$count]["data"][$rowArray[0]]["detailID"]=explode("_",$detailID);
				}
			}
			$count2++;
		}	
		$count++;
	}
	return $ret;
}



?>

[/pastacode]

UNIX/DOS-encoding – ^M

Ever had the problem that you tried running a script on a linux-machine and got an error message like the following one?
-bash: ./getRaidFromIrmc.php: /usr/bin/php^M: bad interpreter: No such file or directory

The ^M indicatees that e file you are trying to run is DOS-encoded. This means that its using a CHAR 13 instead of CHAR 10 for a line break and Linux does not like that kind of line break. That often happens if you are writing a script or config file on a Windows machine and transfer it to a Linux machine.
If you try to run/parse the file in linux -> wrong encoding and BAM

The first time I ran into this problem was while deploying a RHEL machine with a faulty kickstart file, but if you know what the problem is it’s quite easy to fix it. Just run “dos2unix” over your file and everything should work again as it should work.

If you often have to modify Linux-files on widows machines I’ld recommend you to use Notepadd++, because it has a feature implemented to set the correct EOL-conversion and lots of more cool and useful plugins like the built in FTP/SFTP-plugin.

Windows performance counters and zabbix

There already quite a lot of blog posts out there which describe how to add performance counters to zabbix. In fact – its not that hard – the tricky thing is, to have one template which gets performance counters from systems wich have different languages installed.

In this case it’s a good idea to use the index of a counter. Indexes of all performance counters can be obtained from teh registry.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows NT\CurrentVersion\Perflib
In this path there should be a key named “009” (would be englisch, “007” german) or similar, which contains all the key-value pairs.
The easiest way is to copy everything to an editor and look up the keys you need.

I tried to verify the counter ids by using them with “typeperf” – eg: typeperf \234(_Total)\202 but most times the result was:
Error: No valid counters.
If i used the names instead of the keys everything worked fine.

Atm I still don’t know what the reason for this error is, but, if you try it with  zabbix_get everything works fine.
zabbix_get -s server-01 -k “perf_counter[\234(_Total)\202]”
0.000000

Further details about performance counters in Zabbix can be found at:
https://www.packtpub.com/books/content/monitoring-windows-zabbix-18

Unable to mount the WIM, so the update process cannot continue.

I got the following Error after installing the MDT on my system and trying to update a Deploymentsahre which is located on my NAS.

On technet i read a tipp about restarting the machine after installing the MS AIK but that didn’t fix my problem. After another 5 mins of investigations I found out that wrong permissions could also be the reaseon for the error.

As I’m using the MDT on my private PC which has a non Admin user as default user I retried it with admin rights and now it works.
So if you’r also encountering this error – check your permissions.

Useful tools for PXE

In this post a collection of useful tools which can be used in PXE is introduced.

Continue reading Useful tools for PXE

PXE-Boot on a Vigor2130/on your local network

Today I wanted to configure my router to support PXE-booting in my homenetwork.  Herefore the following components are requeired:

  • DHCP-server configured to distribute Bootserver
  • TFTP-Server which provides the PXE

Continue reading PXE-Boot on a Vigor2130/on your local network