How do I use updated libraries in the linklst?… and then whoops

I have an updated C run time library. How do I test it on z/OS, bearing in mind the libraries are in the linklist (dataset available to every one), and I want to use them from Unix.

You can refresh the Linklist, by creating a new definition using console commands, and activating it.

Because you may need to update more that one library as part of the update, you update the definitions, then activate them. If you update linklist one data set at a time, you could get inconsistent libraries in the link list for a short period.

You have one active (current list) and can have multiple other list definitions.

You can

  • copy the current definitions
  • add data sets
  • remove data sets
  • activate a definition

To display what is in the current link list you can use the SDSF option LNK, or use the operator command D PROG,LNKLST

D PROG,LNKLST                               
CSV470I 12.06.05 LNKLST DISPLAY 605
LNKLST SET LNKLST00 LNKAUTH=LNKLST
ENTRY APF VOLUME DSNAME
1 A B3RES1 SYS1.LINKLIB
2 A B3RES1 SYS1.MIGLIB
3 A B3RES1 SYS1.CSSLIB
4 A B3RES1 SYS1.SIEALNKE
5 A B3RES1 SYS1.SIEAMIGE
6 A B3RES1 SYS1.SHASLNKE
7 A B3RES1 SYS1.SERBLNKE
8 A B3RES1 SYS1.SGRBLINK
9 A B3RES1 SYS1.SHASMIG
10 B3RES1 SYS1.SCBDHENU
...

Note: Some of these are APF authorised.

You can display what lists are active using the command

D PROG,LNKLST,NAMES

This gave

CSV472I 19.25.26 LNKLST DISPLAY 848             
LNKLST SET LNKLST SET LNKLST SET LNKLST SET
LNKLST00 COLIN

To create a new definition called MY based on my current defintion; and activate it

SETPROG LNKLST,DEFINE,NAME=MY,COPYFROM=CURRENT
bSETPROG LNKLST,ADD,NAME=MY,DSN=CEE.SCEERUN.NEW
SETPROG LNKLST,delete,NAME=MY,dsname=CEE.SCEERUN
SETPROG LNKLST,ADD,NAME=MY,DSN=CEE.SCEERUN2.NEW
SETPROG LNKLST,delete,NAME=MY,dsname=CEE.SCEERUN2
SETPROG LNKLST,ACTIVATE,NAME=MY

You can put these statements in a parmlib member PROGxx see here, and then activate them using the operator command

t prog=xx

How do jobs get the new libraries

This is a more subtle than I first thought.

From my TSO userid COLIN, I went into Unix and issued a Python command, and the command now worked, so I was picking up the libraries. Round of applause – job done.

I then checked my ISPF session. The command ISRDDN displays the datasets allocated to ISPF. The lnk command, shows what is defined in the lnklst. This showed

B3RES1              >    LINKLIST SYS1.LINKLIB               
B3RES1 > SYS1.MIGLIB
...
B3RES2 > CEE.SCEERUN
...
B3RES2 > CEE.SCEERUN2

so my main ISPF task was unchanged.

I used the command

setprog LNKLST,UPDATE,JOB=COLIN
CSV504I JOB COLIN IS NOW USING THE CURRENT LNKLST SET

to update the COLIN job, and then the ISRDDN LNK gave

B3PRD1              >    LINKLIST FAN140.SEAGLMD        
...
USER08 *SMS > CEE.SCEERUN.NEW
B3USR1 *SMS > CEE.SCEERUN2.NEW

which has update the COLIN job.

Logging on with a different userid, it got the updated definitions.

I tried to logon using SSH, and this failed with messages on the console

BPXP024I BPXAS INITIATOR STARTED ON BEHALF OF JOB SSHD1 RUNNING I
004B
ICH408I USER(OMVSKERN) GROUP(OMVSGRP ) NAME(OMVSKERN )
CSFIQA CL(CSFSERV )
WARNING: INSUFFICIENT AUTHORITY - TEMPORARY ACCESS ALLOWED
FROM CSF* (G)
ACCESS INTENT(READ ) ACCESS ALLOWED(NONE )
ICH420I PROGRAM CEEBINIT FROM LIBRARY CEE.SCEERUN.NEW CAUSED THE
ENVIRONMENT TO BECOME UNCONTROLLED.
BPXP014I ENVIRONMENT MUST BE CONTROLLED FOR DAEMON (BPX.DAEMON)
PROCESSING.
ICH420I PROGRAM CEEBINIT FROM LIBRARY CEE.SCEERUN.NEW CAUSED THE
ENVIRONMENT TO BECOME UNCONTROLLED.
BPXP014I ENVIRONMENT MUST BE CONTROLLED FOR DAEMON (BPX.DAEMON)
PROCESSING.

This is because the CEE.SCEERUN was APF authorised, and CEE.SCEERUN.NEW was not APF authorised.

I dynamically APF authorised them

SETPROG APF,add,DSN=CEE.SCEERUN2.NEW,SMS 
SETPROG APF,add,DSN=CEE.SCEERUN.NEW,SMS

SSH failed the same way.

The easiest thing for me to do on my system was Re-IPL.

Once you’ve done the activate

Thanks to Todd Burch  for reminding me that you need to refresh the Link List Lookaside(LLA).

f lla,refresh

Any new jobs will use the updated LNKLST.

Previously running jobs will continue to use the old LNKLST, unless you tell the the jobs, they can use the new LNKLIST, with the UPDATE option.

 setprog LNKLST,UPDATE,JOB=* 

It is still not that simple…

Todd Birch told me

The process documented by IBM leaves some room for interpretation, unfortunately. After a COPYFROM=CURRENT, I DELETE the old DSNAME and then ADD the new DSNAME. I prefer to use BEFORE or AFTER to put the new DSNAME back in the same place, otherwise, the ADD defaults to the end of the linklist concat.

Also, we use shared dasd, so we tend to use the same dataset names when we delete and re-add. Our process is to IEBCOPY w/replace the old library from our build system (via shared dasd), then on the testing system, stop LLA, define a new LL with COPYFROM=CURRENT, then delete the old DSNAME lib, then re-add the same name using BEFORE or AFTER to keep the concatenation as before**, and then activate and update and then restart LLA.

**it’s typical for us to have both a test library allocated just prior to a production library, akin to

MY.TEST.PRODUCT.LIB
MY.PROD.PRODUCT.LIB

and since we are testing a new test lib, we delete MY.TEST.PRODUCT.LIB and then add it back BEFORE MY.PROD.PRODUCT.LIB.

I had to go back 30 years to get a big screen 3270 for ISPF.

I’ve been trying to set up a new Stock Image (replacement for ZD&T) and had many problems.

One of the problems I had was I could only get screen size of 80 columns and 24 rows, despite configuring everything I could think of to be larger.

The solution

Background

3270 Screens used to be 80 characters wide, with 24 lines. (Going back to the start they were 80 wide, 12 lines deep!) Then there were 3278 model 5’s which were 132 characters wide, 27 lines deep. Skipping a few decades, you can get 3270 emulators which you can configure to have what ever size you want. For example 160 characters wide and 60 lines deep. For these you either need very good eyesight, or a very large screen.

I typically work with 132 wide, 43 lines deep.

With early 3270’s you had to configure the host system with the characteristics of the terminal, for example giving the screen size (80 * 24) it has an alternate screens (132 * 43), and what character sets etc it used.

Later models had a “query” capability. When queried, the 3270 can return its characteristics. This made configuring the host much easier, because you just defined it as query-able.

Configuring MVS

You have to define each locally attached device to MVS. For example address 0700 to 0720 are 3270s’.

Then you had to defined the devices to VTAM (this was the days before TCPIP).

For example

 LOCAL700 LBUILD                               
****** LOCAL NON-SNA TERMINALS 701-71F ****
*
L700 LOCAL CUADDR=700,
DLOGMOD=DYNAMICB,
MODETAB=OLDINCLM,
TERM=3277,
ISTATUS=ACTIVE,
USSTAB=USSTABVS
L701 LOCAL TERM=3277,DLOGMOD=NSX32702,
CUADDR=701,USSTAB=USSTAB,
ISTATUS=ACTIVE,
FEATUR2=(MODEL2)
  • For device L700,
    • this is a TERM=3277 on ControlUnitAddress=0700.
    • When you make it active it displays a Welcome screen called USSTAB=USSTABVS
    • The define characteristics are defined in a table (the MODETAB=OLDINCLM) with label DLOGMOD=DYNAMICB.
  • For device L701
    • this is a TERM=3277 on ControlUnitAddress=0701.
    • When you make it active it displays a Welcome screen called USSTAB=USSTAB
    • The define characteristics are defined in a table (it defaults of MODETAB=ISTINCLM) with label DLOGMOD=NSX32702
    • The default logmode table ISTINCLM is here. You create it with Assembler macros.

The entry for NSX32702 has

**********************************************************************
* LOGMODE TABLE ENTRY FOR NON-SNA 3270 DEVICES WITH *
* EXTENDED DATA STREAMS (3278 OR 3279). *
* SCREEN SIZE IS 24 X 80. *
**********************************************************************
NSX32702 MODEENT LOGMODE=NSX32702,FMPROF=X'02',TSPROF=X'02', *
PRIPROT=X'71',SECPROT=X'40',COMPROT=X'2000', *
RUSIZES=X'0000', *
PSERVIC=X'008000000000185000007E00', *
APPNCOS=#CONNECT

A screen using this has just s 24 * 80 screen size.

The next entry has

         TITLE 'NSX32703'
**********************************************************************
* LOGMODE TABLE ENTRY FOR NON-SNA 3270 DEVICES WITH *
* EXTENDED DATA STREAMS (3278 OR 3279). *
* PRIMARY SCREEN 24 X 80 *
* ALTERNATE SCREEN 32 X 80 *
**********************************************************************
....

so you could use this one to get 24 or 32 lines deep.

The definition for D4A32XX3 says

PRIMARY SCREEN 24 X 80 (1920) ALTERNATE SCREEN TO BE DETERMINED BY APPLICATION

I could not get this to work.

Linux definition

I created my Linux 3270 session using

x3270 -model 5 tso70@localhost:3270 &

Where the model 5 is 132 wide, 43 deep.

When I used the DLOGMOD=DYNAMICB, I logged on OK.

Configure ISPF

In ISPF, using the SETTINGS command. Scroll down to Terminal settings.

I did this and got a big screen.

At the top of the screen is

Select Environ, 1. Environ settings, Terminal status 2, Query terminal information.

Mine gave

Change the VTAM setup

In ADCD.Z31B.VTAM.SOURCE(ISTINCLM) on my old zD&T system, it defines

MODEENT LOGMODE=DYNAMICB,

I copied the load module ADCD.Z31B.VTAMLIB(ISTINCLM) to SYS1.VTAMLIB(OLDINCLM)

I defined the terminal definition SYS1.VTAMLST(LOC700) to have

LOCAL700 LBUILD 
L700 LOCAL CUADDR=700, *
DLOGMOD=DYNAMICB, *
MODETAB=OLDINCLM, *
TERM=3277, X
ISTATUS=ACTIVE, X
USSTAB=USSTABVS

and activated it

v net,act,id=loc700

Unix services automount is a blessing and curse.

If someone logs on to z/OS and uses Unix Services they need a home directory. By default it may be /u. This is not a good idea because they could fill up the disk space and prevent other people from doing any work in /u. Automount can create a ZFS for a directory if the directory such as /u/colin does not exist.

Lionel Dyck has a good write up on automount.

The blessing

With automount you can configure a file which says when I logon with a home directory of /u/colin, and this does not exist then allocate a dataset and mount it. For example it allocated a ZFS called OMVS.USER.COLIN.ZFS. You can control the name and size of the ZFS.

The curse

I wanted to mount an existing ZFS on /u/zopen. I created /u/zopen, then mounted the file system on it – but it said /u/zopen as in use!

I had a BPXPRMUS member in parmlib which mounted my file systems.

MOUNT TYPE(ZFS) 
MODE(RDWR)
NOAUTOMOVE
MOUNTPOINT('/u/tmp')
FILESYSTEM('COLIN.ZFS2')

MOUNT FILESYSTEM('COLIN.ZFS.ZOWE.PROD') TYPE(ZFS)
MOUNTPOINT('/u/tmp/zowep') MODE(RDWR)
PARM('AGGRGROW') AUTOMOVE

MOUNT FILESYSTEM('COLIN.ZOPEN.ZFS') TYPE(ZFS)
MOUNTPOINT('/u/zopen') MODE(RDWR)
PARM('AGGRGROW') AUTOMOVE

When I activated this member with

T OMVS=(US)

I got

BPXO032I THE SET OMVS COMMAND WAS SUCCESSFUL.             
BPXF236I FILE SYSTEM COLIN.ZFS2 WAS NOT MOUNTED.
THE MOUNT POINT SPECIFIED IN BPXPRMUS ALREADY HAS
FILE SYSTEM OMVS.USER.TMP.ZFS MOUNTED ON IT.

BPXF236I FILE SYSTEM COLIN.ZOPEN.ZFS WAS NOT MOUNTED.
THE MOUNT POINT SPECIFIED IN BPXPRMUS ALREADY HAS
FILE SYSTEM OMVS.USER.ZOPEN.ZFS MOUNTED ON IT.

I could not mount under /u – because it created the file systems.

The ZOWE file system did mount, because it was mounted under /u/tmp which was not covered by automount.

What controls it?

There is a file /etc/auto.master which controls what directories are automounted.

Mine ( a very simple one) has

/u /etc/auto.map 

Which says for the /u directory enable automount and see the file /etc/auto.map. This file has

name * 
type ZFS 
filesystem OMVS.USER.<uc_name>.ZFS 
mode rdwr 
delay 0 
duration 5 
parm FSFULL(50,5) 
allocany space(20,50) cyl vol(XXXVS1) pathperm(755) euid 

Where

  • name * is a generic (or specific) file
  • delay 0 The minimum amount of time in minutes to leave the file system mounted after the duration expires and the file system is no longer in use. The default is 10 minutes.
  • duration 5 the minimum amount of time in minutes to leave the file system mounted. The default is nolimit.
  • <uc_name> is used to represent the name in uppercase characters. This creates COLIN from “colin”
  • <asis_name>used to represent the name exactly, as is.

Turning it off

Lionel’s document explains how to enable it.

I tried changed the file /etc/auto.master to have a different directory to /u, which mostly worked. Some tasks depending on the auto-mount behaviour, and didn’t work.

I compromised. I used automount, but instead of using the /u/zopen directory, I used /u/tmp/zopen etc and the mounts worked.

ISRDDN – That’s wrong – no, that’s new!

I’ve just started using a new system, and I’ve been looking around.

I used ISRDDN to display the allocations for ISPF. It gives

if I put B in front of USER.CLIST I get

When I browse the top member, I get member data set SYS1.DGTCLIB(ACBQVAO4). This is not in USER.CLIST. What is going on ?

If you look at the output of USER.CLIST is has Lib:8. This means the 8th library in the list of SYSPROC.

Member ADDVOL is in library 1 which really is USER.CLIST

if you browse any other data set under the SYSPROC it has

without the Lib.

Now I understand what is happening, I think it is pretty nifty!

Updating the I/O configuration for zD&T (zPDT)

Initial comments

As part of the move from the ADCD provided systems to the standard image, I found that existing device map with not migrated to the new system. This challenge gave me the opportunity to learn about configuring the I/O subsystem and Hardware Configuration Definition (HCD) for ZD&T, zPDT and the standard image.

Concepts

The I/O configuration is pointed to by the LOAD member in SYS1.IPLPARM or SYS0.IPLPARM

For example

*---+----1----+----2----+----3----+-
IODF 05 PROV DEFAULT 00
...

Where the columns are important. This would use dataset PROV.IODF05 and look for system DEFAULT.

The names of the production IODFs are id.IODFnn where nn is 00 to 99

You can display the currently active HCD by using operator command

Activate test

To configure the HCD you use ISPF. On my system to get to the HCD application you need option 12;2

  • 12 z/OS System z/OS system programmer applications
  • 2 HCD HCD I/O configuration

When working with HCD you cannot update the currently active, you use a working dataset, and create a new IODF image at the end.

With input fields ending in a +, you can use PF4 to display the available options.

Basic configuration

You define a device range, for example 0700 for 16 units; and the device type 3277.
For these to be visible in z/OS the devices must be connected to an operating system definition. I spent many an hour trying to work out why my newly configured DASD was not in my z/OS system – it was because I had not connected the devices.

Print the configuration

Once you have made changes, you should print the configuration and check they are as you expect, for example the devices are connected to the operating system.

//IBMHCD JOB MSGCLASS=H 
//GCREP EXEC PGM=CBDMGHCP, 
// PARM='REPORT,CSMEN,,,,,00' 
//HCDIODFS DD DISP=SHR,DSN=PROV.IODF06 
//* DIODFS DD DSN=PROV.IODF05,DISP=SHR 
//HCDRPT DD SYSOUT=H, 
//    DCB=(RECFM=FBA,LRECL=200,BLKSIZE=6400) 
//HCDMLOG DD SYSOUT=H, 
//   DCB=(RECFM=FBA,LRECL=200,BLKSIZE=6400) 

The output is like

                                        DEVICE SUMMARY REPORT             
--- DEVICE --- DEVICE
NUMBER,RANGE TYPE-MODEL ATTACHING CONTROL UNITS
______________ _____________ |____|____|____|____|____|____|____|____|
0700,64 3277-2
0A80,64 3390
0AA0,64 3390
...
OPERATING SYSTEM SUMMARY REPORT
OPERATING D/R
SYSTEM ID TYPE GEN DESCRIPTION OS I
_________ ________ ___ ________________________________ ____
DEFAULT MVS Default OS Config
MVS DEVICE REPORT
OPERATING SYSTEM CONFIGURATION ID: DEFAULT
DEV#,RANGE TYPE-MODEL SS BASE UCB-TYPE ...
__________ _____________ __ ____ ________ ...
0700,64 3277-2 0 12001009 ...
0AA0,64 3390 0 3030200F ...

and note device range 0A80 for 64 is not in the DEFAULT system configuration. At IPL this range of devices will not be there.

What is my current configuration?

The operator command ACTIVATE TEST gives

activate test                                                           
...                             
IEF196I IEF285I   PROV.IODF05                                  KEPT     
IEF196I IEF285I   VOL SER NOS= OPEVS1.                                  
IEF196I IEF285I   PROV.IODF05                                  KEPT     
IEF196I IEF285I   VOL SER NOS= OPEVS1.                                  

Configuring the HCD

ISPF 12;2 gave me

                           Hardware Configuration                   
                                                                    
Select one of the following.                                        
                                                                    
1   0.  Edit profile options and policies                           
    1.  Define, modify, or view configuration data                  
    2.  Activate or process configuration data                      
    3.  Print or compare configuration data                         
    4.  Create or view graphical configuration report               
    5.  Migrate configuration data                                  
    6.  Maintain I/O definition files                               
    7.  Query supported hardware and installed UIMs                 
    8.  Getting started with this dialog                            
    9.  What's new in this release                                  
                                                                    
For options 1 to 5, specify the name of the IODF to be used.        
                                                                    
I/O definition file . . . 'PROV.IODF04'____                   +  
  • At the bottom, I/O Definition file – put the cursor in the input field and press PF4, to display the available files.
  • Select 1 Define, modify, or view configuration data.

This gives lines with

  • The start address, and count. For example DE00, for 41 ( so address range DE00 to DE40)
  • The device type: 3390
  • OS 1… connected to the 1st system definition. If this is blank it is not connected,
  • Press PF11 to add a device (or put D in the line command for an entry to delete an entry). This may display

This is creating a work file, so you do not update the currently active one. Specify the volser

You will get

Specify an address, and a count of addresses. Put the cursor in the Device type input file and press PF4 ( as indicated by the + sign at the end of the field).

This gives

This is the list of systems you can connect the I/O devices to. Put a / in front of the config id (DEFAULT) and press enter. This gives

Select 1 because you want to connect the device to the DEFAULT system.

This gives

You can customise the options. Each device type has different options. Press enter till you get back to the I/O Device List (with your address range added).

Generate the production IOCD

From the initial panel select option 2. Activate or process configuration data, and specify the work dataset.

The I/O definition dataset name at the bottom should be the one you are currently working with. You can use PF4 to display the datasets names you have worked with.

Enter a new data set name, such as PROD.IODF08, and the volume serial. (I think this is the same volume as your SYSn.IPLPARM dataset.

Press enter for

Print the IODF using the JCL above.

Update your LOADXX member with the new number, and when you next IPL the changes should be active. ( I created a new LOADYY member, so I could go back to the old IODF if I had problems.)

What systems and consoles are defined?

You can define consoles in the IOCD – you still need to have the z/OS CONSOLE definition.

From the HCD main panel, select

  • 1. Define, modify, or view configuration data
  • 1. Operating system configurations

if you select the default configiguration with / and press enter it gives

You can either select by number, or note the letter at the end of the line. Work with console -> n.

You can specify this command (‘n’) in

to go directly to the console definitions.

This gives

so you can see there are two console defined. One at address 0060, the other at address 0061.

The old zD&T IODF

The IODF from the ZD&T IODF is below. Ive simplified it – replacing 0700,1; 0701,1; 0702,1 etc with 0700,64.

----------Device------ --#--- --------Control Unit Numbers + --------      

 / Number   Type +       CSS OS 1---
 _ 000C     2540                 ____
 _ 000C     2540R-1           1  ____
 _ 000E,2   1403-N1           1  ____
 _ 0120     3380             64  ____
 _ 01C0,64  3390                 ____
 _ 0240,32  3380                 ____
 _ 0260,32  3390                 ____
 _ 0300,25  3390              1  0300
 _ 0400,16  OSA               1  ____
 _ 0550,16  3420-8            1  ____
 _ 0560,16  3480              1  ____
 _ 0580,16  3490              1  0580
 _ 0590,16  3590              1  0590
 _ 0600,16  3390              1  ____
 _ 0900     3270-X           32  ____
 _ 0A80     3390             64  ____
 _ 0E20     CTC               4  ____
 _ 0E40     CTC               4  0E40
 _ 1A00,256 3390              1  ____
 _ 2A00,256 3390              1  ____
 _ 3A00,256 3390              1  ____

Do I really want to restore these datasets? – let me check first.

I needed to restore a product which had shipped files in ADRDSSU BACKUP format.

Before following the instructions and creating lots of files, I thought it would be useful to see what’s going to happen. You can do this by specifying

//S2 EXEC PGM=ADRDSSU,REGION=0M,PARM='TYPRUN=NORUN'

This shows you what will happen, but does not do any of the work.

My JCL was originally

//S1      EXEC PGM=AMATERSE,PARM=UNPACK 
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DISP=SHR,DSN=COLIN.PROD.TRS
//SYSUT2 DD DSN=&&TEMP,SPACE=(CYL,(500,500)),DISP=(,PASS)
//*

//S2 EXEC PGM=ADRDSSU,REGION=0M,PARM='TYPRUN=NORUN'
//SYSPRINT DD SYSOUT=*
//DD1 DD DISP=SHR,DSN=*.S1.SYSUT2
//SYSIN DD *
RESTORE -
IMPORT -
INDDNAME(DD1) -
CANCELERROR -
DATASET(INCLUDE(**)) -
RENAMEU( -
(**.PRODANLC,COLIN.PRODANLC) -
(**.PRODANLE,COLIN.PRODANLE) -

...

The output had

ADR489I (001)-TDLOG(01), DATA SET COLIN.PRODANLC WAS SELECTED         
ADR489I (001)-TDLOG(01), DATA SET COLIN.PRODANLE WAS SELECTED


This would create datasets like COLIN.PRODANLC which I did not want to use.
I wanted to include the version and release so I used

(**.PRODANLC,COLIN.PROD321.PRODANLC) - 
(**.PRODANLE,COLIN.PROD321.PRODANLE) -

and my files came out COLIN.PROD321.PRODANLC etc.

This saved me a lot of time – having to delete many data sets with the wrong name.

Whoops – I should have defined a security profile.

When I restored from the backup, the output included

ADR755W (001)-PROTD(01), SOURCE DATA SET BETA.PROD.OUT.PRODANLC WAS GENERICALLY PROTECTED. THE TARGET DATA SET COLIN.PROD321.PRODANLC IS NOT PROTECTED BY ANY PROFILE                                        

I defined a RACF profile

tso addsd 'COLIN.PROD321.**' uacc(NONE)  

and when I retested it I did not get the ADR755W messages.

You should define the profile before you restore the files. If you do not, there is a small chance that someone could change the unprotected file. If you define the profile first – the file is protected from the moment it is created.

My Unix Services shell is yucky – how do I change it?

You can get into Unix Services from TSO OMVS, or you can use SSH to get directly into a Unix Services session (without access to ISPF). I was interested in using SSH. At first glance it works just like a Linux command window.

My first experience was the keys did not behave as I expected, and how can I change this.

Why do I care which shell I am using?

On Linux I can type the first part of a file name, press the tab key, and it either completes the name of the file (if there was only one) or lists the names of the possible matching files. This is known as autocomplete.

I tried this in an SSH session on z/OS, and this did not work. I was using the default shell, which does not have this support. I needed to use the bash shell or the zsh shell. Note the zsh was developed on Unix and ported to z/OS, it is not a z/OS special.

How do I use a different shell?

The first question is, “is the shell available on my system?”, to which the answer is maybe.

  • z/OS ships with the default shell in /bin/sh.
  • You can get a free version of bash for z/OS. My ADCD based system does not have Bash pre-installed. I believe you can get it for free from Rocket.
  • My ADCD system has zsh installed (but not configured).

Your default shell

This is set in the in your RACF OMVS segment PROGRAM field . To display it, use

TSO LU COLIN OMVS

This gave me

OMVS INFORMATION
----------------
UID= 0000990021
HOME= /u/colin
PROGRAM= /bin/sh
...

Once you logon to your shell various profiles may be executed if they exist for example for the default shell

  • /etc/profile and ~/.profile where ~ is your default home directory (see HOME= in the output of the LU command, above;

Typically the profile script will set the environment variable SHELL.
I put the following in my ~/.profile so my SSH sessions get the zsh shell.

#!/bin/sh 

if [[ -z "$SSH_CLIENT" ]]
then
# dummy
xxx="$SSH_CLIENT"
else
# SSH_CLIENT has a value ... so an SSH terminal
#cho "using the zsh shell"
zsh="/bin/zsh"
echo "shell $SHELL zsh $zsh"
if [[ $SHELL != $zsh ]]
then
echo "using the zsh shell"
export SHELL="$zsh"
exec "$zsh"
fi
fi


zsh is documented in the UNIX System Services Command Reference. This is a big book, so I extracted the section of zsh using

pdftk USSCommand_v3r1.pdf cat 899-1071 output zsh.pdf

zsh education

I found https://thevaluable.dev/zsh-completion-guide-examples/ was a good source of information about zsh.

If zsh has been installed properly you should have an environment variable $ZDOTDIR defined. If this is missing then $HOME is used instead.

There are files

  • $ZDOTDIR/.zshenv
  • $ZDOTDIR/.zprofile
  • $ZDOTDIR/.zshrc
  • $ZDOTDIR/.zlogin
  • $ZDOTDIR/.zlogout

Which should contain configuration information

There are comment on the IBM community about the poor documention of zsh on z/OS, an how you can get started. It gives hints on setting up colours etc.

The IBM documentation says

  • Commands are first read from /etc/zshenv; this cannot be overridden. …
  • Commands are then read from $ZDOTDIR/.zshenv.
    • If the shell is a login shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zprofile.
    • Then, if the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc.
    • Finally, if the shell is a login shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.
  • When a login shell exits, the files $ZDOTDIR/.zlogout and then /etc/zlogout are read. This happens with either an explicit exit via the exit or logout commands, or an implicit exit by reading end-of-file from the terminal

If you start with the system shell, then invoke the zsf shell, the PATH and LIBPATH statements etc will be inherited from the system shell.
If you go directly to the zsh you’ll need to set up a profile based on the system profile. ( or just invoke the existing profile).

You may want to set up a profile to set the command prompt for example the default is

$LOGNAME:$PWD:

You can set it with

export prompt='%n:%/'

to give

COLIN:/u/colin

Changing what keys do … getting the delete key to work as expected

This took a while to understand see Linux mapping the keyboard and on z/OS SSH.

Installing useful commands

I installed zopen. zopen provides lots of Unix-like packages on z/OS. Its home page says

The zopen community is here to provide popular Open Source tools and to encourage z/OS Open Source tools development. We currently host 200+ z/OS Open Source projects and we’re looking for more!

See installing zopen. I then installed the less command , and openssl. See installing packages.

Oh s**T, I cannot boot Ubuntu – I’ve lost my gnome

The problem

I installed some software on Ubuntu, which I had not realised was very back level. It prompted and said

The following packages will be REMOVED:
fuse3 gnome-remote-desktop gnome-shell-extension-desktop-icons-ng gvfs-fuse nautilus
ntfs-3g shfs ubuntu-desktop-minimal ubuntu-session xdg-desktop-portal xdg-desktop-portal-gnome xdg-desktop-portal-gtk

Do you want to continue? [Y/n]

I blindly replied y – as I always do.
The next IPL failed to start, and left me in a command window with strange messages.

The cure

I rebooted, and selected a kernel with recovery mode.
This displayed a menu with

resume   Resume normal boot
...
network Enable networking
root Drop into root shell mode
...

I selected network. This gave a window with

Continuing will remount your / filesystem in read/write mode.  Do you wish to continue?

I clicked on <yes> .

Some status messages were displayed at the bottom of the screen, and it returned to the original menu.

At the menu I selected root. This gave me a command window with access to the network.

The magic command to restore Gnome was

sudo apt install gnome-desktop

This installed various packages.

I then issued

sudo shutdown now -r

and my Ubuntu came up as if nothing had happened.

Lessons learned

After I had recovered my Ubuntu, I remember doing this recovery before. Unfortunately I had written the recovery instructions in a file under my userid, but I could not find them during recovery. The wise thing to do is print off the instructions and keep a copy in my desk – or blog them as I’ve just done.

zopen: installing packages

zopen provides lots of Unix-like packages on z/OS. Its home page says

The zopen community is here to provide popular Open Source tools and to encourage z/OS Open Source tools development. We currently host 200+ z/OS Open Source projects and we’re looking for more!

I wanted to install some packages to make my SSH shell on z/OS look like the Linux shell I know and love. This was easy, but not entirely straight forward.

You can list all the packages available using

zopen query –list

Install less

less pages through the content of a file.

I used

zopen install less

Once I had installed it and tried to use it, I got

WARNING: terminal is not fully functional
Press RETURN to continue 

I had to install ncurses, a programming library for creating textual user interfaces (TUIs) that work across a wide variety of terminals.

zopen install ncurses

and it worked.

Not for humans, but for search engines z/OS Unix messages

WARNING: terminal is not fully functional Press RETURN to continue

After I installed zopen:less I got this message.

Action: use zopen install ncurses

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1019)

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1019)

I was doing Python pip install and got these messages. I had to bodge a certificate package from Linux. See here.