Feb 23

Latest release of RAP is covered in IT Jungle


IT Jungle just posted the announcement of the latest release of RAP. This release brings RAP into the HA category in terms of functionality due to the addition of new replication features and tools.

This is the content published by ITJ

Shield Adds IFS Replication to HA Offering
Published: February 23, 2010
by Alex Woodie
i/OS shops using Shield Advanced Solutions’ Receiver Apply Program (RAP) to replicate data and objects between System i servers will now be able to replicate data housed in their System i servers’ Integrated File System (IFS) as the result of new RAP features unveiled yesterday.
The addition of IFS support is one of the final major features needed for RAP to be considered an HA product, says Chris Hird, president of Shield Advanced Solutions, which is based near Toronto, Canada. “Having been involved in the HA market space for 20 years, I believe the product now provides the essential requirements for an HA solution,” Hird says.
When Shield launched RAP in 2007, the product provided a bare bones framework to replicate DB2/400 data using the journaling and remote journaling technology that IBM builds into the i/OS operating system. (Actually, remote journaling resides below the operating system level, but that’s a topic for another story.)
Shield gradually added more capabilities over the years, including automated synchronization, auditing, user profile replication, automated role-swaps, support for independent auxiliary storage pools (iASPs), and automation of object replication.
With this week’s launch, the product gains full status as an HA product, according to Hird. “We have added many new features in this release that now put the product in the High Availability (HA) Solution category,” he says.
Support for IFS replication and a more efficient method of i/OS object replication were the big new features in this release, Hird says.
Other notable new RAP features include: support for “active job snapshots,” which create a copy of the WRKACTJOB screens for viewing on the remote system; improved flexibility for the configuration of remote journals and receiver libraries; new journal management tools for handling receiver changes using the IBM job scheduler; and improved role swap programs that include built-in restart capabilities.
The features were added as a program temporary fix (PTF) to RAP V4R1, which Shield launched 10 months ago. The company decided not to issue a new version or release number because it is a significant new release that adds a lot of features, and it wanted to streamline the upgrade process for existing customers, Hird says.
Pricing, which is tier based, starts at $3,500 and has not changed. For more information, visit Shield’s recently refurbished Web site at www.shield.on.ca.

If you are interested in a free trial or would like to discuss your High Availablity requirements give us a call.

Chris…

Feb 20

Setting up SSHD for access IBM’i’ with Zend Studio


One of the problems with the Zend Studio is the problems encountered when accessing the IBM ‘i’ using the FTP or mapped drive methods. I had a lot of problems getting the FTP server to connect the even more problems keeping the connection established while developing the code.

I decided to look at the SSH connectivity, the first thing you need to do is set up the SSHD server there are plenty on links out there which show you how to do this. The one I settled on using is IBM ‘i’ SSHD This link explains the installation process very well but the one problem I came across with all of the instructions I found was the set up of the keys required for SSH. All of the notes I found suggested using the following.


ssh-keygen -t rsa1 -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.5p1/etc/ssh_host_key -N “”
ssh-keygen -t dsa -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.5p1/etc/ssh_host_dsa_key -N “”
ssh-keygen -t rsa -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.5p1/etc/ssh_host_rsa_key -N “”

The problem is they do not reflect the OS installation level!

Here is the note at the bottom of the IBM installation instructions which sorted it out for me..

For V5R3 and V5R4 the OpenSSH version is 3.5p1 and is located in directory /QOpenSys/QIBM/ProdData/SC1/OpenSSH/openssh-3.5p1/
For V6R1 the OpenSSH version is 3.8.1p1 and is located in directory /QOpenSys/QIBM/ProdData/SC1/OpenSSH/openssh-3.8.1p1/

The above code to create the keys has to be changed to reflect the correct path ie 6.1 should be:

ssh-keygen -t rsa1 -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.8.1p1/etc/ssh_host_key -N “”
ssh-keygen -t dsa -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.8.1p1/etc/ssh_host_dsa_key -N “”
ssh-keygen -t rsa -f /QOpenSys/QIBM/UserData/SC1/OpenSSH/openssh-3.8.1p1/etc/ssh_host_rsa_key -N “”

I hope that helps others..

Chris…

Feb 20

5733SC1 for V6R1


IBM has changed how they ship the 5733SC1 LPP, for V6R1 it is included on the B29xx_02 CD and not shipped as on a separate CD. Another problem is the installation Menu Option 11 does not provide you with the option to install the product even though it is now included in the standard CD shipment.

Perhaps if everyone asks, IBM will add the program to the install option list when taking option 11? I have not tried installing by taking option 1 (install all).

Chris…

Feb 12

Replicate system using RAP utilities


We are in the process of building our new i520 ready to take over the development role from the old 520. One of the problems we came across was the use of the virtual images we have been using for the daily saves, unfortunately the FTP transfers always set the CCSID to 00819 event though we were requesting binary transfers? This rendered the objects unusable for some reason when we tried to attach them back to the Image Catalog, we will take a look at how that needs to be handled later!

So we were stuck with a problem, we ordered the new system without a tape drive as we have never used them on any of the other systems and IBM was loading up a $3,000 option. We do have a DVD RW on the new system but not on the old ones so even CRTDUPOPT will not work. So we decided to install RAP for the transfer process. We have developed a number of tools for RAP which allow objects to be copied between the systems.

Once we had installed the product we set up a couple of PDM options to allow the RAP commands to be called. First of all we needed to replicate the save files between the systems so we created an SS Option SYNCOBJ OBJ(&N) TYPE(&T) LIB(&L) this will be used to transfer individual objects and specifically save files between the systems. Next we wanted to be able to replicate entire libraries without having to save each object individually, we could have done a SAVLIB to a save file and transfered it, but the RAP process saves selected objects from a library to a save file which is replicated to the target system where the objects are restored. One issue we did come across was Logical files (LF comes before PF) so if any errors were logged we simply went back into the library after it had been replicated and took an SS option against each of the offending files. We don’t have cross library logicals so this was a fairly easy task. Before we can replicate the contents of the library we needed to create the library first, we have a RAP command to create the remote library so we added a RL PDM entry CRTRMTLIB LIB(&N) and a LS PDM option to replicate all the objects in the library SYNCOBJ OBJ(*ALL) TYPE(*ALL) LIB(&N).

The process was fairly simple, RAP was running on the target system so we used WRKLIBPDM *ALLUSR to list all of the user libraries on the source, a RL against each of the libraries we wanted to create then a LS to sync the entire content of the library. Any problems we cleared up with the SS option against the offending objects. And that was it, we replicated all of the development libraries to the new system in approximately 45 minutes.

Next is the IFS, that will be just as simple because RAP comes with new IFS replication features as well.

If you are interested in RAP for your high availability solution gives us a call.

Chris…

Feb 10

PHP for ‘i’ #6


Last part of the C for ‘i’ project added the ability to add new records into the database. The following shows how to add the same functionality to the PHP project.

The code shows how to carry out the process using the i5Toolkit API’s, the use of the db2_ functions will be covered at a later date. Just as an aside, the i5_pconnect() function does have a few problems which despite requests on the Zend Forums have not been cleared up. I think this is because the functions are created outside of Zend itself which could explain why they have little interest in responding to posts about them? The main issue is the use of the options which can be passed into the i5_pconnect() function, I was particularly interested in using the I5_OPTIONS_IDLE_TIMEOUT option which should terminate a persistent connection after a period of time. The documentation shows the option should be coded as I5_OPTIONS_IDLE_TIMEOUT=>120 to give a time out value of 120 seconds, if this is coded in this manner the connection fails because it cannot find a connection to use? I assume this is because the manual states the connection will be terminated after this period of time by the next connection request? I assume the code is looking for an existing connection and when it does not find one it fails? If I code it I5_OPTIONS_IDLE_TIMEOUT=>’120′ the connection is made, it never dies but it is made. I assume the connection would be dropped after the next connection request beyond the timeout value?? There is an option to build a PRIVATE persistent connection which apparently works to some degree? I have yet to play with it to find out what it actually does?

The following code has the I5_OPTIONS_IDLE_TIMEOUT=>’120′ coded for completeness but I have yet to prove either way if the connection is terminated?
This is new code for the index.php which simply adds a link to the page which carries the input form.

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML><HEAD>
<META content=”text/html; charset=iso-8859-1″ http-equiv=Content-Type></HEAD>
<BODY>
<?php
//include(“i5toolkit/Toolkit_classes.php”);
// include the file which holds the user info
include(“../scripts/config.php”);
// connect to the i5
$options = array(I5_OPTIONS_JOBNAME => “PHPPROJ”, I5_OPTIONS_IDLE_TIMEOUT =>’120′);
$conn = i5_pconnect($server,$usr,$pwd,$options);
// check that we connected OK or die()
if (is_bool ( $conn ) && $conn == FALSE) {
die (“No Connection : ” .i5_errormsg() );
}
// open the file if not opened return the error
$file = i5_open(‘CPROJDTA/USERS’,I5_OPEN_READ,$conn);
if ($file === false) {
$tab = i5_error();
echo(var_dump($tab));
}
// list out the fields as the headers could just use text
// if cannot just dump and exit
$list = i5_list_fields($file);
if ($list ==! false) { ?>
<table>
<tr><td><?php echo($list[0]); ?></td><td><?php echo($list[1]);?></td></tr><?php
}
else {
$tab = i5_error();
echo(var_dump($tab));
exit();
}
// loop through the entries in the file and display
do {
$rec = i5_fetch_row($file,I5_READ_NEXT);
if($rec) { ?>
<tr><td><a href=”dspdet.php?id=<?php echo(i5_bookmark($file)); ?>”>Details</a></td><td><?php echo($rec[0]); ?></td><td><?php echo($rec[1]);?></td></tr><?php
}
} while($rec);
// close the file and free resource
i5_free_file($file);
?>
</table>
<a href=”getdets.php”>Add Record</a>
</body></html>

The input form is very simply at this stage, we will change it later to function as an update form.


<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
<HEAD>
<META content=”text/html; charset=iso-8859-1″ http-equiv=Content-Type>
</HEAD>
<body>
<form name=”getdets” method=”post” action=”../scripts/storedets.php”>
<table>
<tr><td><label>First Name</label></td><td><input name=”firstname” type=”text” size=”35″ maxlength=”20″></td></tr>
<tr><td><label>Last Name</label></td><td><input name=”lastname” type=”text” size=”35″ maxlength=”20″></td></tr>
<tr><td><label>Address</label></td><td><input name=”addr1″ type=”text” size=”35″ maxlength=”25″></td></tr>
<tr><td><label>Address</label></td><td><input name=”addr2″ type=”text” size=”35″ maxlength=”25″></td></tr>
<tr><td><label>City</label></td><td><input name=”city” type=”text” size=”35″ maxlength=”15″></td></tr>
<tr><td><label>State</label></td><td><input name=”state” type=”text” size=”35″ maxlength=”15″></td></tr>
<tr><td><label>Zip Code</label></td><td><input name=”zip” type=”text” size=”35″ maxlength=”10″></td></tr>
<tr><td><label>Country</label></td><td><input name=”country” type=”text” size=”35″ maxlength=”15″></td></tr>
<tr><td><label>Telephone</label></td><td><input name=”telnum” type=”text” size=”35″ maxlength=”15″></td></tr>
<tr><td><label>Email</label></td><td><input name=”email” type=”text” size=”35″ maxlength=”35″></td></tr>
<tr><td colspan=”2″><input type=”submit” name=”submit” value=”Submit”></input></td></tr>
</table>
</form>
</body>
</HTML>

The processing part of the code is in storedets.php, this page will be called when the submit button is pressed on the input form. We are using POST variables for all of the variables to be written to the file. The first part sets up an array which will be passed into the i5_new_record() function, we are simply mapping the input fields to the file record fields. We have a different layout in the DB file to the POST array so it is very important we map them correctly.

You will also notice we have an i5_pconnect() function at the start of the script but not at the end, this will pick up the existing connection we used in the index.php file making the i5_functions run at an acceptable speed. If we were using the db2_ functions which are faster than the i5_ functions, using a standard db2_connect() and closing with a db2_close() would work without slowing things down between pages.


<?php
//include(“i5toolkit/Toolkit_classes.php”);
// include the file which holds the user info
include(“../scripts/config.php”);
// store the data ready to write to file
$data = array($_POST['lastname'],$_POST['firstname'],$_POST['addr1'],$_POST['addr2'],$_POST['city'],
$_POST['state'],$_POST['zip'],$_POST['country'],$_POST['telnum'],$_POST['email']);
// connect to the i5
$conn = i5_pconnect($server,$usr,$pwd,array (I5_OPTIONS_JOBNAME => “PHPPROJ” ));
// check that we connected OK or die()
if (is_bool ( $conn ) && $conn == FALSE) {
die ( i5_errormsg () );
}
// open the file if not opened return the error
$file = i5_open(‘CPROJDTA/USERS’,I5_OPEN_READWRITE,$conn);
if ($file === false) {
$tab = i5_error();
echo(var_dump($tab));
}
$rec = i5_new_record($file,$data);
if(!$rec) {
$tab = i5_error();
echo(var_dump($tab));
}
header(“Location: /index.php”);
exit();
?>

Thats all there is to it, try it out..

Chris…

Feb 05

PHP for ‘i’ #5


The last post PHP for ‘i’ #4 showed how you could use the i5_ functions to display the details of a record in an additional page. We have also posted about how to use the db2_ functions to get a faster response as we found the i5_ functions were very slow (the i5_pconnect() functioned cleared this up but we are still looking at how to correctly code the use of the function). The documentation for any of the IBM ‘i’ related PHP functionality is ver poor at best, so we could not find a method to extract the RRN from a file read which would allow us to read from the file again using the rrn associated with each record.

We asked about the db2_ functions which are controlled by IBM so we expect changes will be hard to get implemented. Our thoughts were to have the RRN returned within the array for every access. Then we posted to the Zend Forums to find out if anyone else had coded around the issue and if so how did they do it. We had one response which talked about using the rrn() function within SQL? We searched for documentation for the function but only found an article in the ITJungle. It was looking at incrementing a number which didn’t seem to fit the bill, but testing proved that the function exists and it does return the RRN as expected.

We have changed the file names to allow us to run two page threads, one using the i5_ functionality from the i5ToolKit the other using the IBM db2_ functions. Here is the initial page (db2test.php) which will display a list of users in a table, we have published part of this code before showing how to publish the list but added the code to allow a link to the details page for each line.


<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML><HEAD>
<META content=”text/html; charset=iso-8859-1″ http-equiv=Content-Type></HEAD>
<BODY>
<?php
//include(“i5toolkit/Toolkit_classes.php”);
// include the file which holds the user info
include(“../scripts/config.php”);
// connect to the i5
$options = array(“i5_lib”=>”cprojdta”,”cursor”=>DB2_SCROLLABLE);
$conn = db2_connect(“”,””,””,$options);
if (is_bool ( $conn ) && $conn == FALSE) {
die ( i5_errormsg () );
}
$result = db2_exec($conn,”select rrn(a), a.* from users a”); ?>
<table border=”1″>
<tr><td width=”100″> <td width=”150″>First Name</td><td width=”150″>Last Name</td></tr><?php
while ($row = db2_fetch_both($result)) {
echo(“<tr><td><a href=dspdetsdb2.php?id=” .$row[0] .”>Details</a></td><td>”.$row['FIRSTNAME'] .”</td><td>” .$row['LASTNAME'] .”</td></tr><br />”);
}
db2_free_result($result);
db2_close($conn);
?>
</table>
</BODY>
</HTML>

The code is quite simple to understand, the only change to the previous code is the addition of the link to the dspdetsdb2.php page which is added to every line.

The dspdetsdb2.php page is called with the rrn for each entry, this is used to get the record back from the database. We have read that the DB2 engine has two methods of reading the files, one will read through all of the entries even after finding the correct entry, the other will stop once it has found the correct entry. It says the engine called cannot be determined ahead of time so we are unsure just how much impact this will have on a large file using this technique? Using a unique index may be a better solution, but that is for a later phase.. Here is the code we created.


<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
<HEAD>
<META content=”text/html; charset=iso-8859-1″ http-equiv=Content-Type>
</HEAD>
<BODY>
<?php
//include(“i5toolkit/Toolkit_classes.php”);
// include the file which holds the user info
include(“../scripts/config.php”);
// connect to the i5
$options = array(“i5_lib”=>”cprojdta”,”cursor”=>DB2_SCROLLABLE);
$conn = db2_connect(“”,””,””,$options);
if (is_bool ( $conn ) && $conn == FALSE) {
die ( i5_errormsg () );
}
$query = “select * from users where rrn(users)=” .$_REQUEST['id'];
$result = db2_exec($conn,$query);
if(!$result) {
db2_stmt_errormsg($result);
exit();
}
$rec = db2_fetch_both($result);
?>

<table>
<tr>
<td><a href=”db2test.php”>Return to list</a></td>
</tr>
<tr>
<td><label>First Name</label></td>
<td><?php echo($rec["FIRSTNAME"]); ?></td>
</tr>
<tr>
<td><label>Last Name</label></td>
<td><?php echo($rec["LASTNAME"]); ?></td>
</tr>
<tr>
<td><label>Address</label></td>
<td><?php echo($rec["ADDR1"]); ?></td>
</tr>
<tr>
<td><label>Address</label></td>
<td><?php echo($rec["ADDR2"]); ?></td>
</tr>
<tr>
<td><label>City</label></td>
<td><?php echo($rec["CITY"]); ?></td>
</tr>
<tr>
<td><label>State</label></td>
<td><?php echo($rec["STATE"]); ?></td>
</tr>
<tr>
<td><label>Zip Code</label></td>
<td><?php echo($rec["ZIP"]); ?></td>
</tr>
<tr>
<td><label>Country</label></td>
<td><?php echo($rec["COUNTRY"]); ?></td>
</tr>
<tr>
<td><label>Telephone</label></td>
<td><?php echo($rec["TELNUM"]); ?></td>
</tr>
<tr>
<td><label>Email</label></td>
<td><?php echo($rec["EMAIL"]); ?></td>
</tr>
</table>
<?php
// close the file and free resource
db2_free_result($result);
db2_close($conn);
?>
</BODY>
</HTML>

The pages load very quickly but we are only looking at a few records, once the record count grows I am not sure how this technique will scale. The benefit we see is we can implement a page size limit which will help with scaling, the use of the rrn() function will allow us the control this very easily or by using the cursor within the file.

Thats it for this post, let us know if you have any questions.

Chris…

Feb 04

China – When did that happen?


I have ordered a new 520 system which we will use for our development and testing. I placed the order as usual through IBM in Canada and received a notification of how to track the shipment in due course. I checked the shipment details on the 1st February and to my shock it said it has shipped already! I checked the dates and it said it was requested for delivery on the 4th Feb but the expected delivery was the 15th Feb? I thought OK I will check it in a few days to see if it changes, it did not. I sent a quick note off to the IBM rep asking if the delivery date was factual as I want to be sure we are ready for its delivery.

His response shocked me! He said that yes the 15th Feb was probably factual as it was shipping from China! When did Rochester move manufacturing to China? I have not heard that anywhere?? I know Lenovo is all in China but when did the Power Systems manufacturing move there? I am shocked… I must have slept through a major event somewhere along the line…

Anyhow the source of the hardware shouldn’t worry me I suppose. The OS is what makes the difference. (Thats is still developed in Rochester isn’t it!)

Chris..

Feb 03

Setup ZendCore as a FastCGI implementation

We have moved all of our PHP installations to the new ZendServer installs and removed the old ZendCore product. The new ZendServer install no longer requires an additional PASE HTTP Server as Proxy for PHP requests but uses FastCGI technology to service those PHP requests. The page responses using this method are greatly improved over the old PASE method.

If you are in a position where you want to use the FastCGI technology but are unable to replace the existing ZendCore install you can set up the existing ZendCore install to use FastCGI technology. To do so you need to follow the directions which can be found at this link. The ZendServer does have a few issues which are under investigation, you may experience similar problems when moving to the FastCGI technology as we are not sure if the problems are due to the FastCGI technology or other changes within the Zend programs?

Chris…

Feb 01

i5_pconnect() resolves the speed issue!

I was browsing the ZendServer forums looking for a solution to the speed issue we have commented on when using the i5_connect() function. There were a number of others who have noticed the dire speed issue when using the i5_toolkit API’s. Zend responded with a note saying that using the i5_pconnect() function would resolve the issue as it is a much faster method than using the i5_connect() functions.

At first we came back with the same results, the page still took 5-7 seconds to load with 6 records being displayed! We thought that i5_pconnect() was therefore just as slow as the i5_connect() function and recorded that information back on the forum post. Then we started to look at how we could create the i5_bookmark() functionality using the db2_ functions, this is important as we are trying to provide the same functionality within the PHP program as we did on the C program. We noticed that the i5_connect function was still showing in the file? The save of the file did not work! Studio does have a few peculiar traits especially if using the FTP connections, the file would look like it had saved but closing it and re-opening showed it had not. This could be due to the Windows7 64bit install we have but at this time we have not investigated further.

After entering the correct function call the page is now displayed just as fast (maybe even faster?) as when we used the db2_ calls.

To change your programs to use the i5_pconnect() function all you have to do is change i5_connect to i5_pconnect in the dspdet.php and index.php files, all of the parameters can stay the same.

Chris…