Pages

Sunday, June 02, 2013

AS/400 Gets a Mention

My favorite radio show This American Life mentioned the AS/400, twice! (Be still my beating heart.) The name of this particular episode (#496) is When Patents Attack, Part 2 and the small mention is in 2nd half of the broadcast, which you can listen to at their website.

It starts around 38 minutes into the program. I was listening to the podcast when one of the commentators said "They decide they need a specific type of computer to backup all the data, something called an AS/400." I nearly fell off my chair. I don't know why, but I became not unlike a drooling fan-boy of an obscure band, and I've just heard my favorite song of theirs on the radio. It's too bad the AS/400 expert connected to the story is part of a patent troll operation, and one of the main subjects of the show. Despite all of that, I was giddy with delight and had to share.

Saturday, September 29, 2012

Sound and Fury

RPG

On May 16, 2012 Mel Beckman wrote a piece in iProDeveloper called "Is RPG Dead?" where he argued that it was. Readers of this blog will recall that it caused a huge firestorm within our community to the point that many were calling for Mel's head on a platter.

I was as shocked as the next RPG programmer that the language was dead, but all of the vociferous reactions left me cold. What was needed, I thought, were cooler heads and reasoned rebuttal; During this period a line from Macbeth, "full of sound and fury, signifying nothing", kept running through my head. One day a little poem came forth. I had originally posted it on Facebook on June 1st and now that the hub-bub has died down I thought I'd post it here:

There is much sound and fury in this tale whose hour upon the stage was spawned by Mel and the walking shadow RPG sits quietly in the mezzanine contemplating the maelstrom of which she is the subject. The poor players on the stage will strut and fret and expel their rage and in the end we all know that they will be heard no more, ultimately signifying nothing.

(Most of phrasing came from Macbeth's long winded response to the news, near the end of the play, that his wife was dead.)

Update 10/6/12

Once all of the initial shouting died down there were some very good posts written that rebutted Mel's assertions. I'd like to mention three of them here:

Thursday, September 27, 2012

Book of SBMJOB, Chapter on CMD

Read it here.

Years ago when I was a novice studying the liturgy of the 38 System, I started writing an early version of the book of SBMJOBALT simply because it annoyed me that I couldn't prompt its Request Data (RQSDTA) chapter. Apparently, the development angels of our lord Ib'm found this frustrating too, because when the new testament of the 400 was released, the book of the SBMJOB had a new chapter named CMD that allowed prompting. That wasn't all, of course. Our most holy lord Ib'm blessed us all with two other wonderful verses for this chapter:

  1. If a CL program submits a CALL command, the program it calls will appear on the Display Program References (DSPPGMREF) output for the submitting program.
  2. On the PARM parameter of those CALL commands, the CMD parameter can also handle data in CL variables so that you don't have to build a command string beforehand.

Hallelujah!

Of course, every far-reaching testament has some annoying errors of omission. At the following link I describe two of them and my simple solutions for both: Get the SBMJOB Command's CMD Parameter to Cooperate

Monday, June 25, 2012

Spammer is a Meathead

Of the many chores I do around the parish, one of them is dealing with the spam that comes across my desk. Of late I've been getting piles of stuff from what must be the most clueless spammer on record. My client won't display any of the contents because the entirety of each email is so malformed that it can't be deciphered. I have to edit it myself just to get SpamCop to interpret it. Check out this typical example of the piles of goo I've been getting from various locations around the world. (I've highlighted the most blatant bits of silliness):


From - Mon Jun 25 09:30:16 2012
X-Account-Key: account9
X-UIDL: 1896-1135197712
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:
Return-path: <clueless@spammer.com>
Received: from mta34.srv.hcvlny.nowhere.com
 (mta34.srv.hcvlny.nowhere.com [167.206.5.102]) by mstr13.srv.hcvlny.nowhere.com
 (Sun Java System Messaging Server 6.2-9.20 (built Jul 15 2010))
 with ESMTP id <0M6500F02Z6RUD90@mstr13.srv.hcvlny.nowhere.com> for
 no.one@nowhere.com; Mon, 25 Jun 2012 04:20:51 -0400 (EDT)
Received: from SEMA (95.9.36.33.static.ttnet.com.tr [95.9.36.33])
 by mta34.srv.hcvlny.nowhere.com
 (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007))
 with ESMTP id <0M6500J6JZ5K9TL0@mta34.srv.hcvlny.nowhere.com> for
 no.one@nowhere.com (ORCPT no.one@nowhere.com); Mon,
 25 Jun 2012 04:20:51 -0400 (EDT)
Received: (qmail 7526 by uid 670); Mon,
 25 Jun 2012 08:23:07 -0200From: "Enlargement pils Sample"
 <clueless@spammer.com>To: <formula1nut@nowhere.com>Subject: Thrill her more
 every nightDate: Mon,
 25 Jun 2012 08:06:40 -0200Message-ID: <005f01cd52c4$82452690$86cf73b0$@com>MIME-Version:
 1.0Content-Type: multipart/alternative;
 boundary="----=_NextPart_000_005E_01CD52C4.82452690"X-Mailer: Microsoft Office
 Outlook 12.0Thread-Index: AcjupAzv1ypgP1yJ50d8AifghGpFJw==Content-Language:
 en-usThis is a multipart message in MIME
 format.------=_NextPart_000_005E_01CD52C4.82452690Content-Type: text/plain;
 charset="us-ascii"Content-Transfer-Encoding: 7bitJay Leno found taking
 drugshttp://debatablecommerce.com/------=_NextPart_000_005E_01CD52C4.82452690Content-Type: text/html;
 charset="us-ascii"Content-Transfer-Encoding: quoted-printable<html
 xmlns:v=3D"urn:schemas-microsoft-com:vml"
 =xmlns:o=3D"urn:schemas-microsoft-com:office:office"
 =xmlns:w=3D"urn:schemas-microsoft-com:office:word"
 =xmlns:x=3D"urn:schemas-microsoft-com:office:excel"
 =xmlns:p=3D"urn:schemas-microsoft-com:office:powerpoint"
 =xmlns:a=3D"urn:schemas-microsoft-com:office:access"
 =xmlns:dt=3D"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
 =xmlns:s=3D"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
 =xmlns:rs=3D"urn:schemas-microsoft-com:rowset" xmlns:z=3D"#RowsetSchema"
 =xmlns:b=3D"urn:schemas-microsoft-com:office:publisher"
 =xmlns:ss=3D"urn:schemas-microsoft-com:office:spreadsheet"
 =xmlns:c=3D"urn:schemas-microsoft-com:office:component:spreadsheet"
 =xmlns:odc=3D"urn:schemas-microsoft-com:office:odc"
 =xmlns:oa=3D"urn:schemas-microsoft-com:office:activation"
 =xmlns:html=3D"http://www.w3.org/TR/REC-html40"
 =xmlns:q=3D"http://schemas.xmlsoap.org/soap/envelope/"
 =xmlns:rtc=3D"http://microsoft.com/officenet/conferencing" =xmlns:D=3D"DAV:"
 xmlns:Repl=3D"http://schemas.microsoft.com/repl/"
 =xmlns:mt=3D"http://schemas.microsoft.com/sharepoint/soap/meetings/"
 =xmlns:x2=3D"http://schemas.microsoft.com/office/excel/2003/xml"
 =xmlns:ppda=3D"http://www.passport.com/NameSpace.xsd"
 =xmlns:ois=3D"http://schemas.microsoft.com/sharepoint/soap/ois/"
 =xmlns:dir=3D"http://schemas.microsoft.com/sharepoint/soap/directory/"
 =xmlns:ds=3D"http://www.w3.org/2000/09/xmldsig#"
 =xmlns:dsp=3D"http://schemas.microsoft.com/sharepoint/dsp"
 =xmlns:udc=3D"http://schemas.microsoft.com/data/udc"
 =xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema"
 =xmlns:sub=3D"http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/"=
 xmlns:ec=3D"http://www.w3.org/2001/04/xmlenc#"
 =xmlns:sp=3D"http://schemas.microsoft.com/sharepoint/"
 =xmlns:sps=3D"http://schemas.microsoft.com/sharepoint/soap/"
 =xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance"
 =xmlns:udcs=3D"http://schemas.microsoft.com/data/udc/soap"
 =xmlns:udcxf=3D"http://schemas.microsoft.com/data/udc/xmlfile"
 =xmlns:udcp2p=3D"http://schemas.microsoft.com/data/udc/parttopart"
 =xmlns:wf=3D"http://schemas.microsoft.com/sharepoint/soap/workflow/"
 =xmlns:dsss=3D"http://schemas.microsoft.com/office/2006/digsig-setup"
 =xmlns:dssi=3D"http://schemas.microsoft.com/office/2006/digsig"
 =xmlns:mdssi=3D"http://schemas.openxmlformats.org/package/2006/digital-sig=nature"
 =xmlns:mver=3D"http://schemas.openxmlformats.org/markup-compatibility/2006="
 xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
 =xmlns:mrels=3D"http://schemas.openxmlformats.org/package/2006/relationshi=ps"
 xmlns:spwp=3D"http://microsoft.com/sharepoint/webpartpages"
 =xmlns:ex12t=3D"http://schemas.microsoft.com/exchange/services/2006/types"=
 =xmlns:ex12m=3D"http://schemas.microsoft.com/exchange/services/2006/messag=es"
 =xmlns:pptsl=3D"http://schemas.microsoft.com/sharepoint/soap/SlideLibrary/="
 =xmlns:spsl=3D"http://microsoft.com/webservices/SharePointPortalServer/Pub=lishedLinksService"
 xmlns:Z=3D"urn:schemas-microsoft-com:" =xmlns:st=3D"=01"
 xmlns=3D"http://www.w3.org/TR/REC-html40"><head><META
 HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =charset=3Dus-ascii"><meta
 name=3DGenerator content=3D"Microsoft Word 12 (filtered medium)"><style><!--
 /* Font Definitions */ @font-face=09{font-family:"Cambria Math";=09panose-1:2
 4 5 3 5 4 6 3 2 4;}@font-face=09{font-family:Calibri;=09panose-1:2 15 5 2 2 2
 4 3 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal,
 div.MsoNormal=09{margin:0in;=09margin-bottom:.0001pt;=09font-size:11.0pt;=09font-family:"Calibri","sans-serif";}a:link,
 span.MsoHyperlink=09{mso-style-priority:99;=09color:blue;=09text-decoration:underline;}a:visited,
 span.MsoHyperlinkFollowed=09{mso-style-priority:99;=09color:purple;=09text-decoration:underline;}span.EmailStyle17=09{mso-style-type:personal-compose;=09font-family:"Calibri","sans-serif";=09color:windowtext;}.MsoChpDefault=09{mso-style-type:export-only;}@page
 Section1=09{size:8.5in 11.0in;=09margin:1.0in 1.0in 1.0in
 1.0in;}div.Section1=09{page:Section1;}--></style><!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026"
 ></o:shapedefaults></xml><![endif]--><!--[if gte mso >9]><xml> <o:shapelayout
 v:ext=3D"edit">  <o:idmap v:ext=3D"edit" data=3D"1" ></o:idmap>
 </o:shapelayout</xml><![endif]--></head><body lang=3DEN-US link=3Dblue
 vlink=3Dpurple><div class=3DSection1><p class=3DMsoNormal><o:p>Jay Leno found
 taking drugs</o:p></p><p class=3DMsoNormal><o:p><a
 =href=3D"http://debatablecommerce.com/">http://debatablecommerce.com/</a></o:p></p></div></body></html>------=_NextPart_000_005E_01CD52C4.82452690--
Date: Mon, 25 Jun 2012 04:20:51 -0400 (EDT)
Date-warning: Date header was inserted by mta34.srv.hcvlny.nowhere.com
From: clueless@spammer.com
Message-id: <0M6500J6RZ5M9TL0@mta34.srv.hcvlny.nowhere.com>
Content-transfer-encoding: 7BIT
Sun-Java-System-SMTP-Warning: Lines longer than SMTP allows found and wrapped.
Original-recipient: rfc822;no.one@nowhere.com

See what I mean? There are no carriage-return/line-feeds (CRLF) before the header keywords (From:, To:, Subject:, X-Mailer:, etc.), the boundary separators, the envelope keywords, before the envelope's content, or most other areas that could benefit from a strategically placed CRLF. I haven't even bothered to try and figure out what's going on in the HTML envelope near the end, but it looks dreadful.

This has been going on for weeks and every email has a different link for a different "product". I can't believe this meat-head is actually getting paid for these malformed missives of debatable commerce. It has to be one person running some kind of scam and has no idea that almost none of it is actually being read by their "target audience".

Saturday, April 14, 2012

A Call for Prayers to Solve the Problem of List Parameters and Variables in CL

Feature Requests and Requirements
Greetings worshipers of our lord Ib'm and the most holy "i". Today I would like to talk about an issue that has been with us since the days of the old testament. Yes, I'm talking about a chapter in the story of the land of System/38 and king CPF.

Since those early days we who toiled in semi-darkness, right through to modern times, were bedeviled by specifying variables for list parameters in CL programs. For every other parameter on the system, if we needed to specify a variable we were good to go, but to this day, even with the most holy "i", we’ve never had a good way to specify a variable with list parameters.

I think I've hit upon what I consider to be a workable solution to this intractable conundrum, but it will require the minions of our lord Ib'm to make three changes. It will also require many prayers from the faithful to prod its angels to effect these modifications. Towards this end I recently wrote a piece for System i News called Solving the Problem with List Parameters and Variables in CL. If you agree with the arguments set forth in that post then please register your prayers for this change by going to the COMMON Feature Requests and Requirements page and voting for the following requirement requests:
  • Arrays in CL #212: "Problem: The CL language does not have array support, which is something that would be very useful." Regular readers of this blog might recognize this as requirement #4 in my blog post Top Ten Requirements for CL Enhancements.
  • Qualified data structures in CL #215: "Problem: Currently CL variables whose storage is defined inside another variable (known in RPG as a data structure) cannot be qualified to that variable. CL modules are getting more and more complex given the expanded features IBM has introduced. The number of variables are getting larger and so are the number of data structure sub-fields and they must have unique names within the module. It is getting harder and harder to devise self-documenting field names with only 10 characters to work with, which was the problem that RPG had for many years before IBM allowed for qualified data structures." Regular readers might also see some resemblance to requirement #10 in my aforementioned blog post Top Ten Requirements for CL Enhancements, but of course it's been somewhat improved.
  • List Parameters and Variables in CL #216: "Problem: ...(redundant verbiage redacted-see 2nd paragraph of this blog post)... If you specify one list element you're OK, but that's rarely what is needed. Often times one needs to specify multiple list elements and you can never be sure how many will be needed at execution time. The current design of the command processing environment makes this difficult."
You will also be able to vote for these requests at the COMMON Council of Anaheim gathering next month. Unfortunately I won't be able to attend, but I will be there with you in spirit.

In the name of the Corporation, the Power System, and holy "i", Amen.

Wednesday, April 11, 2012

Where in the name of Ib'm have I been...


Greetings fellow worshipers of Ib'm and its most holy "i".

I am writing today to explain my dearth of sermons of late, to expound on my general absence from the net-sphere (mostly blogs/Facebook/Twitter), and to make a confession of sorts. The truth be told my essays on this blog has been bereft because I have been submitting secular tomes for publication in another venue. The process of churning out said tomes, and other travails of life in 2011, has been arduous and has left little time for writing the free-wheeling missives that I've posted here over the years. While this state of affairs is rewarding, the blog, et al. has lain fallow.

I'm unhappy with this situation to say the least and I'm going to be making a concerted effort to post more on the net in the future. It is the age-old problem, post theological treatises here so that they're freely available to all, for very little remuneration. -or- Submit other content to a profit-making journalistic organization, for personal monetary gain. As so often happens, subjects that would be perfect for this blog end up not getting written because the siren song of the coin of the realm is hard to resist.

You might be asking yourself "which aforementioned organization does he shill for?" Well, to be blunt, my benefactor in this realm is the Penton Media Group, specifically System i News magazine, for whom I've written staid and professional sounding articles, tips, and (ironically) blog posts. Even more ironic is the fact that the writings on this particular blog that you're currently reading is what got me this great gig in the first place.

If the next thing you're asking is "wait, I don't remember seeing anything written by Joe Code in the magazine or website", then you'd be correct. Father Joe Code is of course the nom de plume that I adopted for the purposes of anonymity when I first started out with the blog. I didn't know how people would react to someone writing theological treatises on the monotheistic worship of our most holy "i".

Hello, my name is Inigo Montoya. You killed my father. Prepare to die.
The more I wrote professionally the more the anonymity started becoming a hindrance to actually posting on the blog. Also, I couldn't comment on my articles. The most I would say about them was submitting a tweet saying "my friend and colleague has posted ..." on my Twitter feed. Of course doing so has had the unintended result that this supposed secret identity is now about as secret as Silverlake was back in the 80's.

Believe it or not, the name Joe Code actually came from the Jargon File. (Also, I liked the sound of "Father Joe" better than say, "Father Steve".) For the record, my real name is Peter K. Levy and I've been programming computers, first in college and then as a career, since late 1978. If you click the link on my name it will take you to my web site. There you can click on the "Writings" link to view the secular articles that I've written to date.

The idea for an iSeries priest also came from the Jargon File. I did and do feel as if we alone know how to write the words that make the bits flip, the numbers crunch, the disks spin, and the great waste of paper. We are the select few, who wear the cassocks of our high office; muttering prayers and incantations in languages that only we understand; to do the things that will impress the board of deacons, scare the lesser priests, and confuse the parishioners.

The dialect of this blog will not change. I am a proud and humble priest of the church of our lord Ib'm and its most holy "i". I will not shirk my responsibility to enliven the ecclesiastic point of view that is so needed to enhance the meditative state necessary for enlightenment in our dank and fluorescent drenched cubicles.

Satire is important in all aspects of life and I should mention that in this blog I am not satirizing religion; I'm poking fun and satirizing our tendency as technicians to worship at the alter of one computer platform eschewing all other gods and idols. Many a flame war is the result of this tendency. We should all not judge those worshipers of false religions for they know not what they are missing out on.

Dominus, dominus, dominus, you're all Ib'm-ists now. Bless your heathen souls. May the most holy "i" reign supreme forever or, at the very least, long enough until we can all retire. ;-)

In the name of the Corporation, the Power System, and the holy "i", Amen

Friday, May 13, 2011

I Use the Ib'm i

It seems that I've been forever reading blog, forums, articles, and tweets arguing one way or the other about what to call the latest incarnation of the pantheon that we all worship. It's gotten so bad that Cardinal Klement had to write an encyclical to set some ground rules as to the proper terminology. I've been watching this argument go on and on and on with no end in sight and I don't for a minute think that this blog post will put an end to the oodles of disk storage dedicated to its living spirit, but I do hope that this story might have some bearing on it.

For years I was in the AS/400 camp. Meaning I was pissed off at our lord Ib'm for continually re-naming its liturgy and the damage it was continually causing to the AS/400 brand. That is, until I had a conversation with someone outside of our rarefied community. When he asked me what platform I worked on I told him it was the "Ib'm i". When he inevitably asked "what's that?" I told him it used to be called the AS/400. To which he asked: "Wasn't that the dinosaur platform that was supposed to be dead or dying?" I realized at that moment that the AS/400 brand was dead and it was never coming back. The whole world believes that the AS/400 is an old out-dated platform that is slowly withering away, like the HP 3000, or the DEC VAX.

Yes, I know they're wrong, but in a way they're also right, because while the AS/400 platform is alive and well, it's the AS/400 brand that is a dead-end. It belongs to the world of 5250 terminals, Twin-axial cables, Token-Ring networks, SNA, and SNADS. A world dominated by libraries, physical & logical files, OPM, RPG-III, CLP, EPM-C, SEU, SDA, RLU, out-files, and Net.Data.

Today there's a bright and shiny new brand that our lord Ib'm calls the "Power Systems running i", but since that's too much of a mouthful I like to use the much simplified version "Ib'm i". It belongs to a new world of PC clients, CAT5 cables, Ethernet & WiFi networks, TCP/IP, FTP, Apache, and NetServer. A world dominated by directories, relational databases (tables, indexes, views, triggers, constraints, etc.), SQL, ILE RPG (free-format), ILE CL, ILE C, C++, Java, API's, QSH, PASE, Eclipse, Rational, WebServices, XML, and PHP.

We're on the cusp of a new dawn and if we play our cards right it will flower into a beautiful meadow. When the outside world is invited to sees how wonderful it really is they don't need to be reminded of the dusty over grown field behind them that was repeatedly sown with salt. I'm never going to say to anyone again that I work on an AS/400 and I encourage everyone who reads this to do the same. The "Power Systems running i" or "Ib'm i" is the platform I use.

Say it with me now: "I used to use the AS/400, yes that old dinosaur. It's true; it's gone, but it's been replaced by something better, something called the Ib'm i." Amen.

Saturday, February 19, 2011

CL Program to Apply Technology Refresh PTF

I had a deep sense of foreboding when I found that a HIPER PTF I downloaded came with technology refresh PTF 5770999-MF99002. These things are a pain in the butt to apply as it requires one to do the following steps: 
  1. Perform a full system save, like GO SAVE, option 21.
  2. Apply all microcode PTFs permanently.
  3. Load the TR PTF and set it to be applied temporarily.
  4. IPL the system.
  5. Apply the TR PTF permanently.
On our system there were two pre-requisite PTFs that were downloaded with MF99002; plus we already had a number of microcode PTFs that were set to be applied during the next IPL. I didn't want to permanently apply these new microcode PTFs, so I took the following steps:
  1. Unloaded the microcode PTFs set for delayed apply, except for those that were pre-requisites to MF99002.
  2. Performed a full system save.
  3. IPLed the system to apply the pre-requiste microcode PTFs.
  4. Permanently applied all microcode PTFs.
  5. Loaded MF99002 and set it to delayed apply.
  6. IPLed the system.
  7. Permanently applied MF99002.
  8. Loaded the rest of the microcode PTFs and set them to delayed apply.
  9. IPLed the system.
Our weekly "full system save and IPL" is full automated, so I needed some way to insert a CL program into this mix that would do the job. After finishing it I realized that others might be able to use it as well. It was designed to run in the QSTRUPPGM program, before it actually starts anything. It's assumed that the very first IPL, after the full system save, would first apply any PTFs that were pre-requisites of the TR PTF. All pending microcode PTFs to be applied, including the TR, would remain in a "Save file only" un-loaded state.

After that first IPL it would find that the TR PTF wasn't loaded yet, so it would apply all microcode PTFs permanently, load the TR PTF, set it to delayed apply, and IPL. When the system came up again it would find that the TR PTF was applied. It would then permanently apply it, load the rest of the microcode PTFs sitting in *SERVICE, set them to be applied delayed, and IPL again.

I've included the code below:

/******************************************************************************/
/* Program....: APYTRPTF                                                      */
/* Description: Apply technology refresh PTF.                                 */
/* Author.....: Joe Code                                                      */
/* Date.......: 02/18/2011                                                    */
/*                                                                            */
/* Create                                                                     */
/* ------                                                                     */
/* CRTCLMOD DBGVIEW(*ALL)                                                     */
/* CRTPGM USRPRF(*OWNER) AUT(*EXCLUDE)                                        */
/* CHGOBJOWN OBJTYPE(*PGM) NEWOWN(QSECOFR)                                    */
/* GRTOBJAUT OBJTYPE(*PGM) USER(QPGMR) AUT(*USE)                              */
/*                                                                            */
/* License                                                                    */
/* -------                                                                    */
/* This library is free software; you can redistribute it and/or modify it    */
/* under the terms of the GNU Lesser General Public License as published by   */
/* the Free Software Foundation; either version 2.1 of the License, or (at    */
/* your option) any later version. (Unlike the normal GNU GPL, the "lesser"   */
/* GPL allows libraries to be used in commercial/proprietary software.)       */
/*                                                                            */
/* This library is distributed in the hope that it will be useful, but        */
/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT-       */
/* ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General    */
/* Public License for more details.                                           */
/*                                                                            */
/* You should have received a copy of the GNU Lesser General Public License   */
/* along with this library; if not, write to the Free Software Foundation,    */
/* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA           */
/* (http://www.gnu.org/licenses/lgpl.html#SEC3)                               */
/******************************************************************************/

PGM

   COPYRIGHT TEXT('Copyright (c) 2011 Joe Code')

   DCL VAR(&COUNT)     TYPE(*DEC)  LEN(3 0)
   DCL VAR(&ERROR)     TYPE(*LGL)          VALUE('0')
   DCL VAR(&RCVVARLEN) TYPE(*INT)  LEN(4)  VALUE(131)

   DCL VAR(&PTFINFO)   TYPE(*CHAR) LEN(50)
   DCL VAR(&PTFID)     TYPE(*CHAR) LEN(7)  STG(*DEFINED) DEFVAR(&PTFINFO  1)
   DCL VAR(&PRODID)    TYPE(*CHAR) LEN(7)  STG(*DEFINED) DEFVAR(&PTFINFO  8)
   DCL VAR(&RLSLVL)    TYPE(*CHAR) LEN(6)  STG(*DEFINED) DEFVAR(&PTFINFO 15)
   DCL VAR(&CCSID)     TYPE(*INT)  LEN(4)  STG(*DEFINED) DEFVAR(&PTFINFO 21)
   DCL VAR(&CLSPTFF)   TYPE(*CHAR) LEN(1)  STG(*DEFINED) DEFVAR(&PTFINFO 25)
   DCL VAR(&RESERVED)  TYPE(*CHAR) LEN(25) STG(*DEFINED) DEFVAR(&PTFINFO 26)

   DCL VAR(&RCVVAR)    TYPE(*CHAR) LEN(131)
   DCL VAR(&BYTESRTN)  TYPE(*INT)  LEN(4)  STG(*DEFINED) DEFVAR(&RCVVAR   1)
   DCL VAR(&BYTESAVL)  TYPE(*INT)  LEN(4)  STG(*DEFINED) DEFVAR(&RCVVAR   5)
   DCL VAR(&LOADEDSTS) TYPE(*CHAR) LEN(1)  STG(*DEFINED) DEFVAR(&RCVVAR  41)
   DCL VAR(&IPLACTION) TYPE(*CHAR) LEN(1)  STG(*DEFINED) DEFVAR(&RCVVAR  66)

   MONMSG MSGID(CPF0000 CEE0000 MCH0000) EXEC(GOTO CMDLBL(ERROR))

   QSYS/CHKOBJ OBJ(QGPL/APYTRPTF) OBJTYPE(*DTAARA)
   MONMSG MSGID(CPF9801) EXEC(QSYS/CRTDTAARA DTAARA(QGPL/APYTRPTF) +
      TYPE(*DEC) LEN(3 0) VALUE(0) TEXT('Stop infinite loop if error +
      applying TR PTF.'))

   QSYS/RTVDTAARA DTAARA(QGPL/APYTRPTF) RTNVAR(&COUNT)
   CHGVAR VAR(&COUNT) VALUE(&COUNT + 1)
   QSYS/CHGDTAARA DTAARA(QGPL/APYTRPTF) VALUE(&COUNT)

   CHGVAR VAR(&PTFID)    VALUE('MF99002')
   CHGVAR VAR(&PRODID)   VALUE('5770999')
   CHGVAR VAR(&RLSLVL)   VALUE('V7R1M0')
   CHGVAR VAR(&CCSID)    VALUE(0)   /* Use job's CCSID. */
   CHGVAR VAR(&CLSPTFF)  VALUE('0') /* Close PTF files afterwards. */
   CHGVAR VAR(&RESERVED) VALUE(' ')

   QSYS/CALL PGM(QSYS/QPZRTVFX) PARM(&RCVVAR &RCVVARLEN &PTFINFO +
      'PTFR0100' X'00000000')

   SELECT

      WHEN COND(&BYTESRTN < &RCVVARLEN *OR &BYTESAVL < &RCVVARLEN) +
         THEN(QSYS/SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('No data +
         returned') TOPGMQ(*PRV (*PGMBDY)) MSGTYPE(*ESCAPE))

      WHEN COND(&LOADEDSTS = '0') THEN(DO) /* Not loaded? */
         IF COND(&COUNT = 1) THEN(DO)
            QSYS/APYPTF LICPGM(5770999) APY(*PERM)
            MONMSG MSGID(CPF3660) /* No PTFs identified. */
            QSYS/LODPTF LICPGM(5770999) SELECT(MF99002)
            QSYS/APYPTF LICPGM(5770999) SELECT(MF99002) DELAYED(*YES)
            QSYS/PWRDWNSYS OPTION(*IMMED) RESTART(*YES) IPLSRC(B)
         ENDDO
      ENDDO

      WHEN COND(&LOADEDSTS = '1') THEN(DO) /* Loaded, but not applied? */
         IF COND(&COUNT = 1) THEN(DO)
            QSYS/APYPTF LICPGM(5770999) APY(*PERM)
            MONMSG MSGID(CPF3660) /* No PTFs identified. */
            IF COND(&IPLACTION = '0') THEN(QSYS/APYPTF LICPGM(5770999) +
               SELECT(MF99002) DELAYED(*YES)) /* IPL action isn't set? +
               Then set it. */
            QSYS/PWRDWNSYS OPTION(*IMMED) RESTART(*YES) IPLSRC(B)
         ENDDO
      ENDDO

      WHEN COND(&LOADEDSTS = '2') THEN(DO) /* Temporarily applied? */
         IF COND(&COUNT = 2) THEN(DO)
            QSYS/APYPTF LICPGM(5770999) SELECT(MF99002) APY(*PERM)
            QSYS/LODPTF LICPGM(5770999)
            MONMSG MSGID(CPF35A8) /* No PTFs to be loaded. */
            QSYS/APYPTF LICPGM(*ALL) DELAYED(*YES)
            MONMSG MSGID(CPF3660) /* No PTFs identified. */
            QSYS/PWRDWNSYS OPTION(*IMMED) RESTART(*YES) IPLSRC(B)
         ENDDO
      ENDDO

   ENDSELECT

   RETURN

/******************************************************************************/
       /*                                                                     */
ERROR: /* Global error handling section.                                      */
       /*                                                                     */
/******************************************************************************/

   IF COND(&ERROR) THEN(RETURN)  /* Prevents an infinite loop if an error     */
   CHGVAR VAR(&ERROR) VALUE('1') /* occurs within the error handling section. */

   QSYS/SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Unexpected error +
      occurred. See previous messages') TOPGMQ(*PRV (*PGMBDY)) MSGTYPE(*ESCAPE)

ENDPGM

On our small system this program added an extra two hours to the normal weekend backup/IPL. The only problem I ran into was that the microcode PTFs that I removed weren't loaded again. Apparently when you permanently remove a microcode PTF, it's also removed from the list of "*ALL PTFs in *SERVICE", meaning they can't be loaded when you specify LODPTF DEV(*SERVICE) SELECT(*ALL). You have to specifically name them in the SELECT parameter. Next week when I do this again I am going to load all of the microcode PTFs and leave the delayed apply flags shut off. (Except of course for the TR PTF's pre-requisites.)

Looking at the program again this morning I realized that if there was a subtle problem with applying the TR PTF then it might cause an infinite loop of IPLing, which would be very bad. I've since changed the program to include a safety valve in the form of a data area used to count the number of IPLs. If the count doesn't match up with what is supposed to happen then it doesn't do anymore IPLs. This amended version of the program compiles, but I haven't tested it yet. If you want to wait, it will be tested again next weekend when I apply the TR PTF to another system in our network. I will update this post with the results.

Update (2011-02-28): This version of the program did it's job and applied the TR PTF without error.

Update (2011-06-07): IBM has since issued PTFs to make this task easier, so it would seem that the program above is obsolete.

Monday, January 03, 2011

Parallel Lines

Had kind of a wild ride with this one liturgical conundrum, but I think it's resolved now. It was deep, but the ultimate solution was very simple.

The main program is written in ILE RPG and it does all of it's I/O using SQL. The main result set consists of multiple sub-selects that are UNIONed together into one giant pile. In the WHERE and HAVING clauses of most of these sub-selects it utilizes a user defined function (UDF) that does some data massaging.

This all ran perfectly fine on v5.4 of i5/OS, but after the upgrade to v7.1 of IBM i the job started behaving strangely. Sometimes it would work fine. Sometimes it would run inside the first FETCH statement all day long and take up huge amounts of CPU. Other times the UDF would function check because of invalid data in the strangest places, like on the RETURN statements.

To try and stem the function checking I added MONITOR/ENDMON blocks to all of the RETURN statements in the UDF. When an error occurred they would return *LOVAL instead. Then it started function checking on the statements that were calling the functions with the aforementioned function checking RETURN statements. It was very weird.

Over a two month period I was sending all kinds of traces, SERVICEDOCS, and job logs to Ib'm support angels. The last thing we did was set up a job watcher in iDoctor and the output found that when the FETCH was looping and it was doing so in one of the functions in the UDF. That's when they asked me if it the service program was specified to support multi-threading.

Doh!

As it turns out the SQL to create the functional stubs that called the RPG service program functions defaulted to PARALLEL while the program did not. So remember, if you're writing (or have written) an SQL UDF in a language other than SQL, don't forget that you might have to make your program or service program multi-thread capable. In RPG it means adding the keyword THREAD to the control specifications (aka H-specs) with either the *CONCURRENT or *SERIALIZE attribute. (THREAD(*CONCURRENT) did the trick for me.) Be sure also to thoroughly read the sections in the RPG and SQL manuals on multi-threaded processing.

Friday, November 26, 2010

Influencing the Heavens

While it's a lot of fun hanging out with fellow priests discussing liturgy, I think the most fun I've ever had was walking the hallways of mecca itself and getting to talk to the angels and minions of our lord Ib'm. (Especially building 20, which is a football field size room filled with our lord's most holy systems.) It's also very satisfying to know that you've had an influence in such an august environment. My instance of influence was tiny, but no less satisfying.

My support angel had arranged it all. I gave him a list of the subjects and problem areas I wanted to discuss and he set up all of the meetings. What I remember most clearly is that every angel or minion that I met said something along the lines of "this is great, we never get to speak to our ministerial brethren." After awhile I started to conclude that our lord Ib'm made it an unspoken policy to keep them all in darkness writing code away from the light of earthly interaction.

I talked to a lot of people that day and it was a whole lot of years ago, so I don't remember everything that was discussed or every person I met. I do remember speaking to angels and minions involved with PTFs, command definitions, message handling, journaling, work management, CL programming, and request message processing. There are several salient areas that stood out.

The Command Definition angel actually remembered my name because he'd worked on a lot of the PMR's I'd opened over the years. When I thought about it later I figured he was probably also the one that I had argued with on the phone for over an hour about a fix to command prompting that was made on the AS/400, but wasn't done quite as well on the System/38. (If you're reading this now, I'm sorry about that.)

At one point I walked past some cubicles talking with another minion when the hairiest angel I'd ever seen poked his head above the wall and exclaimed "you're a priest? I've never seen a priest before." (It was the theme du jour.) I felt a small pang of jealously because I of course had to cut my hair to get a job. He seemed so happy to see me I had to go over and shake his hand. He said he wrote microcode and judging from his appearance and general demeanor I have to admit that I wasn't the least bit surprised. I'll bet his code was tighter than most.

We'd been having a problem with Mimixing file records to another system. We were using commitment control and therefore everything was journaled, but we were only Mimixing a small subset of files to the other system. Consequently when Mimix was plowing through the journal receivers looking for something to replicate, it got down deep into the microcode, took over the CPU, and didn't come up for air very often. (The minions of our lord Ib'm closed my APAR on that issue as "working as designed".)

At that time a file could only be attached to one journal at a time and one of the requests I'd made of the journaling angel was for the ability to attach a file to more than one journal. With this feature we could journal those files being Mimixed to a 2nd journal and Mimix could then plow through that secondary journal and not take over the system. He said he thought it was a good idea, but he wouldn't say when or if it would ever be available.

In a subsequent release that feature was made available. However with that release the AS/400 also supported two-phase commit and this new feature was a side-effect of that support, so I can't say that I had any influence on the decision. The journaling angel probably knew this support was coming, but wasn't able to reveal it to me at that time.

I also remember speaking to an angel who was responsible for CL and Request Processing. I had designed a lot of applications that processed sub-file options using commands, so every program was a request processor similar QCL or QCMD. The problem I was having was that some commands had password parameters and I wasn't able to hide the parameter's contents using the QCMDEXC API in my request processors.

I asked him if a CL API could be created where I'd give it the message ID of a logged request message and it would handle the execution, prompting, and redaction of sensitive data. He too said he thought it was a good idea, but of course wouldn't commit to it. In a future release the QCAPCMD API appeared and it was exactly what I needed to resolve my issue. Of course that API does a great many different things with various CL environments so I can't be sure that my request had any influence.

The only request I made during that visit where I'm absolutely sure I had a direct influence was with the crew of Work Management minions that I met with. Unlike everyone else in the building they were all wearing ties. I couldn't resist asking them if their manager had made them put them on for my visit and they sheepishly admitted that he had. Meeting with them was fun and afterwards they took me on a tour of the fabled building 20.

One of the Work Management problems my shop was having was with duplicate job names. An operator would enter WRKJOB MYUSERID/MYJOBNAME and the system would send 25 or 50 messages listing all of the jobs whose name and user ID were MYUSERID/MYJOBNAME. Then they'd have to search through the job log and write down the job number (this was in the age of dumb tubes, so copy/paste wasn't possible) and enter it on the command to view the job. Since the messages didn't say anything about when those jobs had been started the operators would invariably pick the wrong job number, and so they'd have go through the list again and pick another one, and on, and on, ad infinitum. It was a pain in the butt.

The three of them didn't think there were any good solutions for this issue given how the commands were already set up. I asked if it was possible that when there were duplicate jobs the command could display a screen where the user could select the job they wanted from a list. One of them exclaimed "Oooh! That's a good idea" and immediately wrote it down. In the very next release the DSPJOB and WRKJOB commands both had a new parameter named DUPJOBOPT (Duplicate Job Option) whose default value was *SELECT. It's the only change to the system where I'm absolutely sure I had an influence.

Sociable