/*+------------------------------------------------------------------+*/ /*| EXEC: CPFORMAT - wrapper around CPFMTXA to format many DASD |*/ /*| retVal: 0 - success |*/ /*| 1 - help was asked for or given |*/ /*| 2 - user is not sure |*/ /*| 3 - DASD (minidisk) range is not valid |*/ /*| 4 - at least one DASD (minidisk) is reserved to MAINT |*/ /*+------------------------------------------------------------------+*/ /* For details on how this EXEC is used, see one of the two books: "z/VM and Linux on IBM System z: The Virtualization Cookbook for SLES 10 SP2" on the Web at: http://www.redbooks.ibm.com/abstracts/SG247493.html -or- "z/VM and Linux on IBM System z: The Virtualization Cookbook for RHEL 5.2" on the Web at: http://www.redbooks.ibm.com/abstracts/SG247492.html */ /*------------------------------------------------------------------ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -------------------------------------------------------------------*/ firstChar = 'M' /* change this for an LPAR ID other than 'M' */ parse upper arg dasds "AS " type if ((dasds = '') | (dasds = '?')) then call help labelPrefix = getLabelPrefix(firstChar type) numDasd = parseDasd(dasds) answer = areYouSure(type) if (answer = 'Y') then /* the user is sure */ do formatted = "" retVal = doFormat(labelPrefix numDasd type) call doReport retVal end else retVal = 2 exit retVal /*+------------------------------------------------------------------+*/ help: procedure /*+------------------------------------------------------------------+*/ parse source . . fn . say '' say 'Synopsis:' say '' say ' Format one or a range of DASD as page, perm, spool or temp disk space' say ' The label written to each DASD is V where:' say ' is type - P (page), M (perm), S (spool) or T (Temp disk)' say ' is the 4 digit address' say '' say 'Syntax is:' say " .-PAGE-." say " >>--CPFORMAT--.-rdev--------------.--AS---+-PERM-+---------><" say " | <---------------< | '-SPOL-'" say " '-rdev1-rdev2-------' " say '' exit 1 /*+------------------------------------------------------------------+*/ areYouSure: procedure /*| Show minidisks, ask are you sure |*/ /*| parm 1: type - PERM, PAGE, or SPOL |*/ /*| retVal: firstChar - LPAR identifier, 'V' by default |*/ /*+------------------------------------------------------------------+*/ arg type say '' say 'WARNING - this will destroy data!' say 'ARE YOU SURE you want to format the DASD as' type 'space (y/n)?' parse upper pull answer return substr(answer, 1, 1) /* from areYouSure */ /*+------------------------------------------------------------------+*/ getLabelPrefix: procedure /*| Return first two chararcters of label |*/ /*| parm 1: firstChar - LPAR identifier, 'V' by default |*/ /*| retVal: the two character label prefix |*/ /*+------------------------------------------------------------------+*/ arg firstChar type select when (type = PERM) then labelPrefix = firstChar||'M' /* for VM Minidisk */ when (type = PAGE) then labelPrefix = firstChar||'P' /* for VM Page */ when (type = SPOL) then labelPrefix = firstChar||'S' /* for VM Spool */ otherwise do say 'Error: "AS" must be present, type must be PERM, PAGE or SPOL' call help end /* otherwise */ end /* select */ return labelPrefix /* from getLabelPrefix */ /*+------------------------------------------------------------------+*/ parseDasd: procedure expose dasdList. /*| parse all dasd into an array verifying all are attached |*/ /*| parm 1: dasds - the list of dasd passed in |*/ /*| retVal: number of DASD in dasdList |*/ /*+------------------------------------------------------------------+*/ arg dasds numDasd = 0 say '' say 'Format the following DASD:' do while (dasds <> '') parse upper var dasds dasd dasds dashPos = pos('-', dasd) if (dashPos = 0) then /* there is just one DASD */ do numDasd = numDasd + 1 dasdList.numDasd = dasd 'CP Q MDISK' dasdList.numDasd 'LOCATION' if (rc <> 0) then do say 'Return code from Q MDISK =' rc say 'Are all DASD ATTached?' exit 3 end call checkReserved(dasdList.numDasd) end /* do */ else /* process the range of DASD */ do startRange = substr(dasd, 1, dashPos - 1) endRange = substr(dasd, dashPos + 1, length(dasd) - dashPos) do i = x2d(startRange) to x2d(endRange) numDasd = numDasd + 1 dasdList.numDasd = d2x(i) 'CP Q MDISK' dasdList.numDasd 'LOCATION' if (rc <> 0) then do say 'Return code from Q MDISK =' rc exit 3 end call checkReserved(dasdList.numDasd) end /* do i */ end /* else */ end /* do while */ return numDasd /* from parseDasd */ /*+------------------------------------------------------------------+*/ doFormat: procedure expose dasdList. formatted /*| Format all DASD specified using CPFMTXA |*/ /*| parm 1: labelPrefix - the two character label prefix |*/ /*| parm 2: numDasd - number of DASD in the array dasdList |*/ /*| parm 3: type - the type of DASD format |*/ /*| retVal: 0 = success |*/ /*+------------------------------------------------------------------+*/ arg labelPrefix numDasd type 'CP TERM MORE 1 1' do i = 1 to numDasd label = getLabel(labelPrefix dasdList.i) retVal = formatOne(dasdList.i type label) if (retVal ^= 0) then do say "Error from CPFMTXA on DASD" label "rc =" retVal leave /* error - abort! */ end formatted = formatted label end /* do i = */ 'CP TERM MORE 50 10' return retVal /* from doFormat */ /*+------------------------------------------------------------------+*/ checkReserved: procedure /*| Try copying an already formatted DASD then relabelling it |*/ /*| parm 1: source |*/ /*| parm 2: target |*/ /*| parm 3: label |*/ /*+------------------------------------------------------------------+*/ arg dasd /* create a list of reserved dasd - this is somewhat hokey to be sure but it's better to be hokey than to format system minidisks! */ resvd1 = "0122 0123 0124 0125 0190 0191 0193 0194 019D 019E 0201 02A2" resvd2 = "02A4 02A6 02C2 02C4 02CC 02D2 0319 03A2 03A4 03A6 03B2 03C2" resvd3 = "03C4 03D2 0400 0401 0402 0405 0490 0493 049B 049E 04A2 04A4" resvd4 = "04A6 04B2 04C2 04C4 04D2 0500 051D 05A2 05A4 05A6 05B2 05C2" resvd5 = "05C4 05D2 05E5 05E6 06A2 06A4 06A6 06B2 06C2 06C4 06D2 07A2" resvd6 = "07A4 07A6 07B2 07C2 07C4 07D2 0CF1 0CF2 0CF3" reserved = resvd1 resvd2 resvd3 resvd4 resvd5 resvd6 if (index(reserved, dasd) <> 0) then /* MAINT minidisk - ABORT! */ do say 'Minidisk' dasd 'is a reserved MAINT minidisk' say 'This must be formatted manually using a different vaddr' exit 4 end /* if dasd is reserved */ return /* from checkReserved */ /*+------------------------------------------------------------------+*/ doReport: procedure expose dasds formatted /*| Report on the newly labelled DASD |*/ /*| parm 1: formatSuccess - 0=all is well, non-0= a format failed |*/ /*| retVal: 0 = success |*/ /*+------------------------------------------------------------------+*/ arg formatSuccess if (formatSuccess ^= 0) then say 'Error was encountered! retVal from CPFMTXA =' formatSuccess if (formatted = '') then say "No DASD were successfully formatted" else say "DASD successfully formatted:" formatted 'DETACH' dasds 'ATTACH' dasds '*' say '' say 'DASD status after:' 'CP Q MDISK' dasds 'LOCATION' return 0 /* from doReport */ /*+------------------------------------------------------------------+*/ formatOne: procedure /*| Format a DASD via DDR |*/ /*| parm 1: disk - the vaddr to be formatted |*/ /*| parm 2: type - PAGE, SPOL or PERM |*/ /*| parm 3: label - the six character label |*/ /*+------------------------------------------------------------------+*/ arg disk type label queue 'FORMAT' queue disk queue '0 END' queue label queue 'YES' queue type '0 END' queue 'END' 'CPFMTXA' retVal = rc return retVal /* from formatOne */ /*+------------------------------------------------------------------+*/ getLabel: procedure /*| Compose the six character label of a minidisk |*/ /*| parm 1: labelPrefix - first two characters of label |*/ /*| parm 2: disk - vaddr of length 1, 2, 3 or 4 |*/ /*| return: the 6 character label |*/ /*+------------------------------------------------------------------+*/ arg labelPrefix disk diskLen = length(disk) select when (diskLen = 1) then /* insert 3 zeros */ label = labelPrefix||'000'||disk when (diskLen = 2) then /* insert 2 zeros */ label = labelPrefix||'00'||disk when (diskLen = 3) then /* insert a zero */ label = labelPrefix||'0'||disk otherwise /* it must be length 4 or query would have failed */ label = labelPrefix||disk end /* select */ return label /* from getLabel */