Memory usage

Recently I experienced the memory problem on my box, hosting the SIMH with the OpenVMS on board.
So, it was the beginning of the road to understand and know the memory issues within my OpenVMS 7.3 on VAX.

My VAX machine was allocated with 64MB of memory.

$ grep -A1 mem vax.ini
; This virtual machine has 64M memory
set cpu 64m

I tried to verify what is te current consumption of this resource.

% in:="sys$input"
% pi sh mem | sea 'in phy,main

Physical Memory Usage (pages):     Total        Free      In Use    Modified
  Main Memory (64.00Mb)           131072       97050       32505        1517

Of the physical pages in use, 20737 pages are permanently allocated to OpenVMS.

Searching the HP OpenVMS Systems Documentations gave me the solution how to print the results already counted in Bytes:

The display is shown as blocks or bytes depending on the current default setting. You can use SHOW PROCESS/UNITS to display the current default. To change the default, execute the DCL command SET PROCESS/UNITS=BYTES or SET PROCESS/UNITS=BLOCKS.

% set proc/units=bytes
%DCL-W-IVQUAL, unrecognized qualifier - check validity, spelling, and placement
 \UNITS\

but unfortunately it not works on 7.3 and/or VAX platform.

As I’ve figured out already the page of memory, and page on disk is 512 bytes.

% pagesize = f$getsyi("page_size")
% sh sym pagesize
  PAGESIZE = 512   Hex = 00000200  Octal = 00000001000

So, the total and in-use memory values are respectively 64 and 15 MB.

% total=pagesize*131072/1048576
% inuse=pagesize*32505/1048576
% sh sym total
  TOTAL = 64   Hex = 00000040  Octal = 00000000100
% sh sym inuse
  INUSE = 15   Hex = 0000000F  Octal = 00000000017

How to disable password expiration

During the summer months I had switched all my strength and time to the unix platforms. But I am back.
I will try to keep this blog alive because I would not allow my OpenVMS knowledge to wither. And of course
I do not want to deprive readers reading.

After a few times the account had been locked on my testing environment I have decided to block permanently the password lifetime verification. This can be achieved by setting the /PWDLIFETIME option to “NONE”. The default value for this variable is set to 90 days for regular, and 30 days for system account.

% r authorize
UAF> modify wisnios /pwdlifetime=none
%%%%%%%%%%%  OPCOM  13-SEP-2010 09:52:33.13  %%%%%%%%%%%
Message from user AUDIT$SERVER on EYE0
Security alarm (SECURITY) and security audit (SECURITY) on EYE0, system id: 1025
Auditable event:          System UAF record modification
Event time:               13-SEP-2010 09:52:33.13
PID:                      00000227
Process name:             SYSTEM
Username:                 SYSTEM
Process owner:            [SYSTEM]
Terminal name:            OPA0:
Image name:               EYE0$DUA0:[SYS0.SYSCOMMON.][SYSEXE]AUTHORIZE.EXE
Object class name:        FILE
Object name:              SYS$COMMON:[SYSEXE]SYSUAF.DAT;1
User record:              WISNIOS
Flags:                    New:      DISFORCE
                          Original: DISFORCE
Password Lifetime:        New:      (none)
                          Original:   90 00:00

%UAF-I-MDFYMSG, user record(s) updated
UAF> modify system /pwdlifetime=none
%%%%%%%%%%%  OPCOM  13-SEP-2010 09:54:45.11  %%%%%%%%%%%
Message from user AUDIT$SERVER on EYE0
Security alarm (SECURITY) and security audit (SECURITY) on EYE0, system id: 1025
Auditable event:          System UAF record modification
Event time:               13-SEP-2010 09:54:45.10
PID:                      00000227
Process name:             SYSTEM
Username:                 SYSTEM
Process owner:            [SYSTEM]
Terminal name:            OPA0:
Image name:               EYE0$DUA0:[SYS0.SYSCOMMON.][SYSEXE]AUTHORIZE.EXE
Object class name:        FILE
Object name:              SYS$COMMON:[SYSEXE]SYSUAF.DAT;1
User record:              SYSTEM
Flags:                    New:      DISFORCE
                          Original: PWD_EXPIRED,DISFORCE
Password Lifetime:        New:      (none)
                          Original:   30 00:00

%UAF-I-MDFYMSG, user record(s) updated
UAF>

ACP could not mark file for deletion

During my romping with an OpenVMS I had experienced difficulties with a directory removal.
Firstly I thought that I forgot again the syntax of delete command. Secondly I remembered that I had not changed directory permissions to RWED for the owner. But it was also not the issue. Despite the permission correction there was still the same message:

% del SOME.DIR;1
%DELETE-W-FILNOTDEL, error deleting DUB0:[000000.PATH]SOME.DIR;1
-RMS-E-MKD, ACP could not mark file for deletion
-SYSTEM-F-DIRNOTEMPTY, directory file is not empty

Listing the contents of the directory did not give results, but a grand_total told something else:

% dir/grand SOME.DIR;1

Grand total of 1 directory, 1 file.

I had even no option to set it as a default:

% set def [.SOME]
%RMS-F-DIR, error in directory name

I have killed the beast with the blade of SET FILE/NODIRECTORY.

Use with extreme caution. Requires SYSPRV (system privilege).
Removes the directory attributes of a file and allows you to
delete the corrupted directory file even if other files are
contained in the directory. When you delete a corrupted directory
file, the files contained within it are lost.
Use ANALYZE/DISK_STRUCTURE/REPAIR to place the lost files in
[SYSLOST]. You can then copy the lost files to a new directory.

% set file/nodir SOME.DIR;1
% del SOME.DIR;1
%

I know, I know… it was bad, not clean, not professional.
But I would like to show the way… maybe it is way down to hell, but it is.

For those who are forced to salve the directory contents there is, possibly, a cure. As it was cited above – in the case of such failure, you ought to play with the ANALYZE/DISK_STRUCTURE/REPAIR

…but do not underestimate the power of the dark side:

% anal/disk/repair EYE0$DUB0:
%ANALDISK-F-GETDVI, error getting device characteristics, RVN 1
-SYSTEM-F-WRONGACP, wrong ACP for device

How to use the F$GETJPI from inside the COBOL code?

To get the username of the current process, from the level of DCL, you could invoke the command:

$ write sys$output f$getjpi("", "USERNAME")
WISNIOS
$

But it is not so obvious to implement this in the COBOL code.
The function as it is called from DCL would be replaced by run-time library rutine.
The prefix of function – F$ – would be replaced by LIB$ routine prefix.

LIB$ ones are the routines that handle I/O data type convertion, resource allocation, signal exceptions, and system information obtainance (for others see the HP COBOL User Manual).

The Get Job/Process Information routine provides a simplified interface to the $GETJPI system service. It provides accounting, status, and identification information about a specified process.

To get the proper CALL invocation I look to HP OpenVMS RTL Library (LIB$) Manual.
The $GETJPI routine has the following format:

LIB$GETJPI item-code [,process-id] [,process-name] [,resultant-value] [,resultant-string] [,resultant-length]

where the item-code is the only required argument and should be requested by reference:

item-code

OpenVMS usage:  longword_signed 
type:  longword (signed) 
access:  read only 
mechanism: by reference 


Item identifier code specifying the item of information you are requesting. The item-code argument is the address of a signed longword containing the item code. You may request only one item in each call to LIB$GETJPI.
LIB$GETJPI accepts all $GETJPI item codes. These names begin with JPI$_ and are defined in symbol libraries in module $JPIDEF supplied by HP.

So, sample code [username.cob] might look like:

identification division.
program-id. USERNAME.

data division.
working-storage section.
01      item-code       pic s9(9) comp value external jpi$_username.
01      result          pic x(9).

procedure division.
username-begin.
        call "LIB$GETJPI"
                using by reference item-code
                by descriptor result.

        display "LIB$GETJPI(jpi$_username): " result.

username-end.
        stop run.

But despite a fact that the other arguments – process-id, process-name, resultant-value are optional,
the returned string is empty.

% cobol username
% link username
% run username
LIB$GETJPI(jpi$_username):

To let the code to do its work we have to add the omitted keywords in place of optionals arguments.
The corrected CALL invocation:

        call "LIB$GETJPI"
                using by reference item-code,
                omitted,
                omitted,
                omitted,
                by descriptor result.

Quick test and voilĂ :

% cob username
% link username
% r username
LIB$GETJPI(jpi$_username): WISNIOS

Final notes
The PIC S9(9) is used for item-code variable because it is a pointer to object.
Am I right?

Compilation errors
Error related to the lack of COMP data declaration:

% cobo hello.cob
    6         01  item-code       pic s9(9) value external jpi$_username.
                  1
%COBOL-E-ERROR  435, (1) VALUE EXTERNAL clause ignored - valid only on COMP data
-item under 10 digits

Solution:

01      item-code       pic s9(9) comp value external jpi$_username.

How to install from a saveset?

Thanks to Tim I finally managed to install the COBOL on my OpenVMS system.

Here you are a few “screen shots”.

Unzipping the archive.

$ set def dua2:[cobol]
$ unzip cobol057.zip
Archive:  DUA2:[COBOL]COBOL057.ZIP;1
  inflating: cobol057.a
  inflating: cobol057.b
  inflating: cobol057.c

Loading the license.

$ license load cobol
%LICENSE-I-LOADED, DEC COBOL was successfully loaded with 0 units
$ lic lis cobol
License Management Facility  V1.2

License Database File:       SYS$COMMON:[SYSEXE]LMF$LICENSE.LDB;1
Created on:                  15-MAR-2010
Created by user:             SYSTEM
Created by LMF Version:      V1.2

-----------------------------------
COBOL                        DEC
[End Of List]

Proceeding with the installation.

$ set def sys$update
$ @vmsinstal cobol057 dua2:[cobol]


        OpenVMS VAX Software Product Installation Procedure V7.3


It is 21-JUN-2010 at 15:25.

Enter a question mark (?) at any time for help.

%VMSINSTAL-W-ACTIVE, The following processes are still active:
        TCPIP$FTP_1
* Do you want to continue anyway [NO]? yes
* Are you satisfied with the backup of your system disk [YES]?


The following products will be processed:

  COBOL V5.7


        Beginning installation of COBOL V5.7 at 15:25

%VMSINSTAL-I-RESTORE, Restoring product save set A ...
[...]
* Do you want to install only the COBRTL [NO]?


        Product:      COBOL
        Producer:     COMPAQ
        Version:      5.7
        Release Date: 23-OCT-2000


* Does this product have an authorization key registered and loaded? yes

        The ANSI/Terminal-Format REFORMAT Utility may optionally be installed.

* Do you want the REFORMAT Utility installed  [YES]?
* Do you want to save the COBOL message file for modification  [NO]?
[...]
* Do you want to purge files replaced by this installation [YES]?
[...]
%VMSINSTAL-I-RESTORE, Restoring product save set B ...
[...]
%VMSINSTAL-I-RESTORE, Restoring product save set C ...
[...]

        Successful test of Compaq COBOL V5.7-63

        Installation of COBOL V5.7 completed at 15:27

    Adding history entry in VMI$ROOT:[SYSUPD]VMSINSTAL.HISTORY


        VMSINSTAL procedure done at 15:27


$

How to change the default DCL prompt

As I wrote in my previous post I have got the common problem with the recognition of terminal session of specific operation sysem. In accordance with the comment which has been left by Ian Miller I have made the quick research of prompt replacement method.
SET PROMPT does the magic.

$ set prompt="% "
% set prompt
$

When is being called without the argument SET PROMPT replaces the customized prompt string with the default one ($ ).

Where am I?

A few consoles are opened. Every one with a dollar prompt sign. Where am I? Is this Unix or OpenVMS.
The quickest way to check this is the CTRL/T function (imo).
Unix reply with a ^T:

$ ^T

but OpenVMS displays a line of statistics:

$
EYE0::WISNIOS 14:24:46   (DCL)   CPU=00:00:12.36 PF=23473 IO=19066 MEM=220
$

To achieve this goal the option of SET TERMINAL/BROADCAST has to be set. It allows the reception of broadcast messages. If you do not want to receive any kind of the broadcast messages (mail, shutdown, etc.) set the BROADCAST type to DCL.

$ SET BROADCAST=DCL

To disable the control functions (CTRL/Y and CTRL/T) use the SET NOCONTROL syntax.
You could alse specify the option of single function (respectively, with Y for CTRL/Y and with T for CTRL/T).

$ SET NOCONTROL=T

How to constantly trace the packets

Today I debug the problem with ftp session. I still do not found the source of the failures, but I had to trace the packets exchanged during the connection. I had run the TCPTRACE utility, but it stopped to work everytime when I had watched just a few packets. To be more precise – it was always the ten packets.

The reason of such behaviour is the default setting of TCPTRACE /PACKETS option. It is set to 10 (by default), which means the only first ten packets, from the begining of tracing, would be displayed.

Setting this to 0 (zero) let you finish your investigation by displaying the endless stream of information.

How to add the additional port to network service

$ tcpip set service telnet22 /port=22 /file=TCPIP$TELNET.EXE /flags=(Listen,Rtty)
%TCPIP-E-SERVERROR, cannot process service request
-TCPIP-E-QUALREQ, qualifier value for PROCESS is required
$ tcpip set service telnet22 /port=22 /file=TCPIP$TELNET.EXE /flags=(Listen,Rtty) /process_name=""
%TCPIP-E-SERVERROR, cannot process service request
-TCPIP-E-QUALREQ, qualifier value for USER_NAME is required
$
$ tcpip set service telnet22 /port=22 /file=TCPIP$TELNET.EXE /flags=(Listen,Rtty) /process_name="" /user_name=""

Verification process:

$ tcpip show service telnet22

Service             Port  Proto    Process          Address            State

TELNET22              22  TCP      not defined      0.0.0.0             Disabled
$ tcpip enable service telnet22
$ tcpip show service telnet22

Service             Port  Proto    Process          Address            State

TELNET22              22  TCP      not defined      0.0.0.0             Enabled
$ pipe netstat -an | sea sys$input 22
tcp        0      0  *.22                      *.*                       LISTEN
$ telnet localhost 22
%TELNET-I-TRYING, Trying ... 127.0.0.1
%TELNET-I-SESSION, Session 01, host localhost, port 22
-TELNET-I-ESCAPE, Escape character is ^]
        Welcome to The Dead Systems
             OpenVMS VAX V7.3

Username: wisnios
Password:
 Welcome to OpenVMS (TM) VAX Operating System, Version V7.3
    Last interactive login on Wednesday, 26-MAY-2010 08:49
    Last non-interactive login on Wednesday, 19-MAY-2010 08:35
$ logout
  WISNIOS      logged out at 26-MAY-2010 09:02:53.11
%TELNET-S-REMCLOSED, Remote connection closed
-TELNET-I-SESSION, Session 01, host localhost, port 22

The Flags setting has been taken from the output of:

$ tcpip show service telnet /full

Service: TELNET
[...]
Flags:        Listen Rtty IPv6
[...]

Removal of additional service:

$ tcpip disable service telnet22
$ tcpip set noservice telnet22

Service             Port  Proto    Process          Address

TELNET22              22  TCP                       0.0.0.0
Remove? [N]:y

Due to fact the title of this post says about the addition of additional port I had tried, but failed to proceed:

$ tcpip set service telnethigh /port=(1023,2023) -
_$ /file=tcpip$telnet.exe /flags=(listen,rtty) -
_$ /process="" /user=""
%CLI-W-ONEVAL, list of values not allowed - check use of comma (,)
 \2023)\
$ tcpip set service telnethigh /port=1023 /port=2023 -
_$ /file=tcpip$telnet.exe /flags=(listen,rtty) -
_$ /process="" /user=""
$ tcpip show service telnethigh

Service             Port  Proto    Process          Address            State

TELNETHIGH          2023  TCP      not defined      0.0.0.0             Disabled

Only one port per service is allowed. At least on my system.

$ tcpip show version

  Compaq TCP/IP Services for OpenVMS VAX Version V5.1
  on a VAXserver 3900 Series running OpenVMS V7.3

How to change the welcome message

The one of steps to prepare the system for being public is change of its welcome banner.
Taking the unix systems method as an example I made the chase for parts of default message:

 Welcome to OpenVMS (TM) VAX Operating System, Version V7.3
$ pipe dir dua0:[000000...]*.*;* | search sys$input Welcome
VMSIMAGES.DAT;1     WELCOME.TEMPLATE;1  WELCOME.TXT;1
VMSIMAGES.DAT;1     WELCOME.TEMPLATE;1  WELCOME.TXT;1
$ pipe dir/full dua0:[000000...]welcome.txt;* | search sys$input Directory
Directory DUA0:[SYS0.SYSCOMMON.SYSMGR]
Directory DUA0:[VMS$COMMON.SYSMGR]
$ set def DUA0:[VMS$COMMON.SYSMGR]
$ type welcome.txt
        Welcome to OpenVMS VAX V7.3

It does not look like the one I know from login prompt.
But I gave it the chance.

$ edit welcome.txt
$ type welcome.txt
        Welcome to The Dead Systems
             OpenVMS VAX V7.3

$ logout

No results. So, the change in the file is not automatically included.

$ sys$system:shutdown

Still no visible results.

The additional research of web have given the answer.
There is the logical name SYS$ANNOUNCE, holding the current announcement message.

$ sh log sys$announce
   "SYS$ANNOUNCE" = " Welcome to OpenVMS (TM) VAX Operating System, Version V7.3    " (LNM$SYSTEM_TABLE)

To change it temporary (not persistently across reboots) issue the command:

$ define/system sys$announce "Welcome to The Dead Systems"
%DCL-I-SUPERSEDE, previous value of SYS$ANNOUNCE has been superseded

To make the change permanent, it is sufficient to include the above command in SYSTARTUP_VMS.COM.
There is also an option of printing the message directly from file:

$ DEFINE/SYSTEM SYS$ANNOUNCE "@SYS$MANAGER:WELCOME.TXT" 

Final test, through the telnet session:

$ telnet eye0
Trying 78.47.45.154...
Connected to eye0.deadsystems.com.
Escape character is '^]'.

        Welcome to The Dead Systems
             OpenVMS VAX V7.3

Username: wisnios
Password: