Dec 18

New features added to HA4i

A couple of new features have been added to the HA4i product as a result of customer requests. Auditing is one area where HA4i has always been well supported but as customers get used to the product they find areas they would like to have some adjustments. The object auditing process was one such area, the client was happy that the results of the audits were correct but asked if we could selectively determine which attributes of an object are to be audited as they have some results which while they are correct are not important to them.

The existing process was a good place to start so we decided to use this as the base but while were making changes improve the audit to bring in more attributes to be checked. We determined a totally new set of programs would be required which would include new commands and interfaces, this would allow the existing audit process to remain intact where clients have already programmed them into their schedulers and programs. The new audits would run by retrieving the list of parameters to be checked from a control file and only compare configured parameters. The results have been tested by the client and he has given us the nod to say this meets with his approval. We also added new recovery features which allow out of sync objects to be fully repaired more effectively.

Another client approached us with a totally different problem, they were having problems with errors being logged from the journal apply process due to developers saving and restoring journaled objects from the production environment into test libraries on the production system. This caused a problem because the objects are automatically journaled to the production journal when they are restored, so when the apply process finds the entry in the remote journal it tries to create the object on the target system and fails because the library does not exist. To overcome this we amended the code which supports the re-direction technology for the remote apply process (It allows journal entries for objects in one library to be applied to objects in another library) to support a new keyword *IGNORE. When the apply process finds these definitions it will automatically ignore any requests for objects in the defined library. NOTE:- The best solution would have been to move the developers off the production systems and develop more HA friendly approaches to making production data available, but in this case that was not an option.

We are always learning and adding new features into HA4i, many of them from customer requirements or suggestions. Being a small organization allows us to react very quickly to these requirements and provide our clients with a High Availability Solution that meets their needs. If you are looking for an Affordable High Availability or Disaster Recovery Solution or would like to ask about replacing an existing solution give us a call. We are always happy to look at your needs and see if HA4i will fit your solution requirements and budget.

Chris…

Dec 13

Linking IBMi data to a Gauge in PHP

We were thinking about how to create a new interface for one of our old utilities using PHP and decided that using a JavaScript based gauge would probably be a good start. There are plenty of free and chargeable JavaScript utilities out there that would do what we wanted, the one we settled on was a HTML5 Canvas implementation developed by Mykhailo Stadnyk. He has placed the code on the web and agreed to anyone running the code under a MIT license which basically allows you to copy and use the code where ever you want. If you would like to use the code it is available here, simply copy the javascript file into your directory structure and include.

We made a couple changes to the javascript code as it calls a remote HTTP server to pull back a font so we found a substitute font and installed it on the PC. There are a couple of examples available which can be used to demonstrate the gauge in action which again we used as the basis for our test. The only other point we should mention is that the demo does rely on HTML5 and canvas, if it is not supported in your browser the test will not work!

The method used to get the data from the IBMi is to call a Service Program through the i5_program_call available in the Aura i5_toolkit. Below is the C Program to return the information, it just calls the QWCRSSTS API and returns the Pct_Processing_Unit_Used value as can be seen in the code below.


#include <stdio.h> /* Standard I/O */
#include <stdlib.h> /* Standard library */
#include <string.h> /* String handlers */
#include <qusec.h> /* Error Code */
#include <errno.h> /* Error Num Conversion */
#include <decimal.h> /* Decimal support */
#include <qusec.h> /* Error Code */
#include <qwcrssts.h> /* System Status */
#pragma comment(copyright,"Copyright @ Shield Advanced Solutions Ltd 1998-2001")

typedef _Packed struct EC_x{
Qus_EC_t EC;
char Exception_Data[1024];
} EC_t;

int Get_Svr_Status(char *CPU_Util,char *reset) {
double Cpu_Pct;
char Reset[10] = "*NO "; /* Reset CPU % */
Qwc_SSTS0200_t Buf; /* System Status Struct */
EC_t Error_Code = {0}; /* Error Code Struct */

Error_Code.EC.Bytes_Provided = sizeof(Error_Code);
// reset the CPU Utilization?
if(*reset == 'Y')
memcpy(Reset,"*YES ",10);
QWCRSSTS(&Buf,
sizeof(Buf),
"SSTS0200",
Reset,
&Error_Code);
if(Error_Code.EC.Bytes_Available > 0) {
sprintf(CPU_Util,"99999");
return -1;
}
// Just set up the CPU Utilization here
Cpu_Pct = (double)Buf.Pct_Processing_Unit_Used / 10;
sprintf(CPU_Util,"%f",Cpu_Pct);
return 1;
}

The web page is generated using the following code.


<?php
/*
Copyright © 2010, Shield Advanced Solutions Ltd
All rights reserved.

http://www.shieldadvanced.ca/

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Neither the name of the Shield Advanced Solutions, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/
// start the session to allow session variables to be stored and addressed
session_start();
require_once("scripts/functions.php");
// load up the config data
if(!isset($_SESSION['server'])) {
load_config();
}
$conn = 0;
$_SESSION['conn_type'] = 'non_encrypted';
if(!connect($conn)) {
if(isset($_SESSION['Err_Msg'])) {
echo($_SESSION['Err_Msg']);
$_SESSION['Err_Msg'] = "";
}
echo("Failed to connect");
}
// get the information
get_cpu_util($conn);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html style="width:100%;height:100%">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Gauge Test</title>
<script src="jscripts/gauge.js"></script>
<style>body{padding:0;margin:0;background:#222}</style>
</head>
<body style="width:100%;height:100%">
<canvas id="gauge"></canvas>
<div id="console"></div>
<script>
var gauge = new Gauge({
renderTo : 'gauge',
width : document.body.offsetWidth,
height : document.body.offsetHeight,
glow : true,
units : 'Cpu Utilization',
title : false,
minValue : 0,
maxValue : 110,
majorTicks : ['0','10','20','30','40','50','60','70','80','90','100','110'],
minorTicks : 2,
strokeTicks : false,
highlights : [
{ from : 0, to : 50, color : 'rgba(240, 230, 140, .25)' },
{ from : 50, to : 70, color : 'rgba(255, 215, 0, .45)' },
{ from : 70, to : 90, color : 'rgba(255, 165, 0, .65)' },
{ from : 90, to : 100, color : 'rgba(255, 0, 0, .85)' },
{ from : 100, to : 110, color : 'rgba(178, 34, 34, .99)' }
],
colors : {
plate : '#fff',
majorTicks : '#f5f5f5',
minorTicks : '#ddd',
title : '#fff',
units : '#0bb',
numbers : '#0aa',
needle : { start : 'rgba(240, 128, 128, 1)', end : 'rgba(255, 160, 122, .9)' }
}
});
gauge.onready = function() {
gauge.setValue( <?php echo($_SESSION['CPU_Util']); ?> );
};

gauge.draw();

window.onresize= function() {
gauge.updateConfig({
width : document.body.offsetWidth,
height : document.body.offsetHeight
});
};
</script>
<?php ?>
</html>

To call the Service Program we created a function ‘get_cpu_util()’ which is called every time the page is refreshed. Here is the code for the get_cpu_util function.


function get_cpu_util($conn) {
$desc = array (array ("Name" => "CPU_Util", "io" => I5_INOUT, "type" => I5_TYPE_CHAR, "length" => "5"),
array ("Name" => "Reset_Status", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "1") );
$prog = i5_program_prepare("PHPTSTSRV(Get_Svr_Status)", $desc,$conn);
if ($prog == FALSE) {
$errorTab = i5_error ();
echo "Program prepare failed Display_Server_Status <br>";
var_dump($errorTab);
var_dump($conn);
die ();
}
$parmOut = array("CPU_Util" => "cpu_util");
$parameter = array("CPU_UTIL" => "", "Reset_Status" => "N");
$ret = i5_program_call($prog, $parameter, $parmOut);
if (!$ret) {
throw_error("i5_program_call failed Retrieve_Status <br>");
exit();
}
// close the program call
i5_program_close($prog);
$_SESSION['CPU_Util'] = $cpu_util;

return 1;
}

The majority of the work is done in the Javascript section above with just the data extraction from the IBMi being carried out using the i5_toolkit. We have used the same connection function that we used in our other tests but instead of asking for the profile and password we added it to the config file so no sign on screen is presented before the connection is made.

The above code resulted in the following output on our systems. The actual CPU utilization differs because it is near impossible to request the page and refresh the 5250 screen at the same time. We also noticed that the returned value is always greater than the actual value shown in the WRKACTJOB screens, but the test was more about showing the gauge working using IBMi data than ensuring we saw the same data in both interfaces.

5250 Work with Active Jobs

5250 Work with Active Jobs

Gauge showing CPU Utilization %

Gauge showing CPU Utilization %

We feel this is where modernization of the IBMi and its applications should begin, making simple tools and utilities that use the IBMi data and display it in a web based interface means you can access those interfaces from many devices. We only show the output in a PC based browser but with some simple CSS and checking code you could make sure it is correctly displayed on most devices.

Happy PHP’ing.

Chris..

Dec 07

Adding configuration Capabilities to the HA4i PHP Interfaces

We have been developing the management interface for HA4i our High Availability product in PHP for some time, but we had not got round to looking at how we could extend that interface to allow us configure the various elements of HA4i. While the existing 5250 (Green Screen) configuration panels are very effective in what they do but we wanted bring that capability into the PHP interface.

Until now, to view or update the existing configurations you needed to sign onto each system and go through each individual panel group to update the various elements that configure HA4i. We wanted to pull all of that information into a single screen where you could view the existing configuration and select a particular element to be updated.

The first panel displays the existing configuration with links (buttons) to allow you to update the particular configuration.

Here is a sample of the initial page.

New Configuration Screen

New Configuration Screen

The above screen allows each of the elements which can be updated, if a change occurs which requires the configuration to be replicated between the systems it is automatically handled in the same manner it was with the 5250 screens. We like the fact that we can now update any configuration and restart the processes all from one interface. Selecting the option to update the remote journal configuration will display a list of all available remote journals as can be seen in the sample display below.

Remote Journals available for configuration

Remote Journals available for configuration

As you can see from the display, if the journal is already configured it will be identified and a remove button provided, if it is not already configured a button allows it to be added. Because the remove button simply removes the configuration data it does not need any additional panels, but to Configure requires some of the parameters to be presented so they can be changed if required as can be seen in the sample display below.

Configure a new Remote Journal

Configure a new remote journal

Once submit is pressed on this page the remote journal is added to the configuration and the relevant objects created to allow processing by HA4i. Once this completes the list of configured remote journals is displayed again with the new journal correctly identified.

HA4i Object replication is simply a list of libraries that are to be monitored for changes, we decided to use a selection list to allow the required libraries to be configured and a list of existing configurations. You can select as many libraries as you wish in a single request which are automatically added to the configured list and all objects in the requested libraries marked for auditing so that any changes to the objects are captured and replicated. The display below shows the currently configured library plus a scrollable selection list of those libraries which are not.

Configure the libraries Object Replication

Configure the libraries for Object Replication

Output Queues have a similar interface which lists all available out queues for configuration in the same manner as the list of libraries. The following is a sample display from our test system.

Configure Outq's

Configure Outq'

The default configuration is unique to each system so there are two buttons one for each system to allow the configuration to be updated, we provided drop down options for some of the parameters to ensure the data entered is correct plus any parameters which are restricted are set to be read only. This is what our test configuration looks like.

Configure default settings

Configure default settings

That is all you need to configure HA4i, we do have a couple of filter options and IFS replication at the object level which need some attention but in the main this new interface allows you to configure, control and monitor HA4i from a single interface. The biggest gain for us was the speed at which we could implement changes using PHP and Easycom, when we developed the UIM based interfaces it would take us days just to create a single configuration interface. With Easycom and PHP we managed to build the configuration interface in just over a day.

HA4i is a premier High Availability Solution, we are constantly improving the product and interfaces making it simpler to manage and providing many new features. If you are looking at a new High Availability implementation or would like to discuss replacing an existing solution let us know, you may be surprised at just how easy and affordable our High Availability Solution can be.

Chris…

Dec 05

New and improved RTVDIRSZ utility

We were recently working with a partner who needed to asses the size of the IFS directories in preparation for replication with HA4i. Before he could start to plan he needed to understand just how large the IFS objects would be and how many objects would need to be journaled. One of the problems he faced was the save of the IFS had been removed from the normal save because it was so large and took too long to carry out.

We had provided the RTVDIRSZ utility sometime ago which would walk through the IFS from a given path and report back to the screen the number of objects found and the total size of those objects. Running the original RTVDIRSZ request took a number of hours to complete and while it gave him the total numbers he would have liked to see a bit more detail in how the directories were constructed.
So we decided to change the programs a little bit and instead or writing the data back out to the screen we would write it to an IFS directory file which could be viewed at leisure and analyzed further should it be required. As part of the update we also changed the information which would be stored in the file, we added a process to show the directory being processed and what size the directory was as well as the number of objects in that directory. Once all of the information had been collected we wrote out the total data just as we had previously.

Here is a sample of the output generated from our test system.

Browse : /home/rtvdirsz/log/dir.dta
Record : 1 of 432 by 18 Column : 1 144 by 131
Control :

….+….1….+….2….+….3….+….4….+….5….+….6….+….7….+….8….+….9….+….0….+….1….+….2….+….3.
************Beginning of data**************
Directory Entered = /home
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/.manager objects = 4 size = 178.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/manifests objects = 83 size = 57.8kB
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/33/1/.cp/nl/es objects = 5 si
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/33/1/.cp/nl objects = 0 size
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/33/1/.cp objects = 0 size = 0
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/33/1 objects = 0 size = 0.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/33 objects = 0 size = 0.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/36/1/.cp/nl/hr objects = 2 si
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/36/1/.cp/nl objects = 0 size
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/36/1/.cp objects = 0 size = 0
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/36/1 objects = 0 size = 0.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/36 objects = 0 size = 0.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/37/1/.cp/nl/hu objects = 2 si
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/37/1/.cp/nl objects = 0 size
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/37/1/.cp objects = 0 size = 0
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/37/1 objects = 0 size = 0.0B
Directory = /home/QIBMHELP/.eclipse/org.eclipse.platform_3.2.2/configuration/org.eclipse.osgi/bundles/37 objects = 0 size = 0.0B
…….
Directory = /home/ha4itst/exclude/dir1 objects = 3 size = 39.0B
Directory = /home/ha4itst/exclude objects = 1 size = 29.0B
Directory = /home/ha4itst/newdir1/newdir2 objects = 2 size = 1.9kB
Directory = /home/ha4itst/newdir1 objects = 0 size = 0.0B
Directory = /home/ha4itst objects = 1 size = 16.5kB
Directory = /home/QWEBQRYADM objects = 1 size = 18.0B
Directory = /home/ftptest/NEWDIR/test1 objects = 0 size = 0.0B
Directory = /home/ftptest/NEWDIR objects = 0 size = 0.0B
Directory = /home/ftptest objects = 0 size = 0.0B
Directory = /home/jsdecpy/log objects = 1 size = 237.0kB
Directory = /home/jsdecpy objects = 0 size = 0.0B
Directory = /home/rtvdirsz/log objects = 1 size = 49.9kB
Directory = /home/rtvdirsz objects = 0 size = 0.0B
Directory = /home objects = 0 size = 0.0B
Successfully collected data
Size = 442.3MB Objects = 1541 Directories = 427
Took 0 seconds to run

************End of Data********************

Unfortunately the screen output cannot contain all of the data but you get the idea.. Now you can export that data to a CSV file or something and do some analysis on the results found (finding the directory with the most objects or the biggest size etc.)

The utility is up on our remote site at the moment, if I get chance I will move it to the downloads site.
If you are looking at HA and would like to use the utility to understand your IFS better let me know. we can arrange for copies to be emailed to you.

Chris…